@@ -172,7 +172,7 @@
Hello,
-You have been invited by user foo-usr
to join The Things Network .
+You have been invited to join The Things Network .
You can now visit this link to register your user account.
diff --git a/pkg/email/templates/testdata/invitation.body.golden.txt b/pkg/email/templates/testdata/invitation.body.golden.txt
index 5f7c57dc0f..4300e12462 100644
--- a/pkg/email/templates/testdata/invitation.body.golden.txt
+++ b/pkg/email/templates/testdata/invitation.body.golden.txt
@@ -1,6 +1,6 @@
Hello,
-You have been invited by user foo-usr to join The Things Network.
+You have been invited to join The Things Network.
You can now go to https://eu1.cloud.thethings.network/oauth/register?invitation_token=TOKEN to register your user account.
diff --git a/pkg/email/templates/testdata/user_requested.body.golden.html b/pkg/email/templates/testdata/user_requested.body.golden.html
index 34793ef0b3..b9dc565814 100644
--- a/pkg/email/templates/testdata/user_requested.body.golden.html
+++ b/pkg/email/templates/testdata/user_requested.body.golden.html
@@ -172,23 +172,10 @@
Dear John Doe,
-A new user just registered on The Things Network .
+A new user with ID foo-usr
just registered on The Things Network .
Since user registration requires admin approval, you need to approve this user before they can login.
-
-User ID: foo-usr
-
-
-Name: Foo User
-
-
-Description: Foo User Description
-
-
-Email Address: foo@example.com
-
-
You can review this user in the Console .
diff --git a/pkg/email/templates/testdata/user_requested.body.golden.txt b/pkg/email/templates/testdata/user_requested.body.golden.txt
index 8c4bba4fdb..6eb8c27dd7 100644
--- a/pkg/email/templates/testdata/user_requested.body.golden.txt
+++ b/pkg/email/templates/testdata/user_requested.body.golden.txt
@@ -1,11 +1,6 @@
Dear John Doe,
-A new user just registered on The Things Network.
+A new user with with ID foo-usr just registered on The Things Network.
Since user registration requires admin approval, you need to approve this user before they can login.
-User ID: foo-usr
-Name: Foo User
-Description: Foo User Description
-Email Address: foo@example.com
-
You can go to https://console.cloud.thethings.network/admin-panel/user-management/foo-usr to review this user in the Console.
diff --git a/pkg/email/templates/testdata/validate.body.golden.html b/pkg/email/templates/testdata/validate.body.golden.html
index 0cf6204da5..6e34ea322e 100644
--- a/pkg/email/templates/testdata/validate.body.golden.html
+++ b/pkg/email/templates/testdata/validate.body.golden.html
@@ -175,7 +175,7 @@
Please confirm your email address for The Things Network.
-Your email address "john.doe@example.com" will be used by user foo-usr
.
+Your email address will be linked to user foo-usr
.
You can now visit this link to confirm your email address.
diff --git a/pkg/email/templates/testdata/validate.body.golden.txt b/pkg/email/templates/testdata/validate.body.golden.txt
index e5b2da8b07..e5b2af998c 100644
--- a/pkg/email/templates/testdata/validate.body.golden.txt
+++ b/pkg/email/templates/testdata/validate.body.golden.txt
@@ -2,7 +2,7 @@ Hello,
Please confirm your email address for The Things Network.
-Your email address "john.doe@example.com" will be used by user "foo-usr".
+Your email address will be linked to user "foo-usr".
You can go to https://eu1.cloud.thethings.network/oauth/validate?reference=ID&token=TOKEN to confirm your email address.
Alternatively, you can use the reference "ID" and confirmation token "TOKEN" directly.
diff --git a/pkg/email/templates/user_requested.html.tmpl b/pkg/email/templates/user_requested.html.tmpl
index bc8caf9b9f..31327970c1 100644
--- a/pkg/email/templates/user_requested.html.tmpl
+++ b/pkg/email/templates/user_requested.html.tmpl
@@ -11,23 +11,10 @@ Your review is required for a newly registered user.
Dear {{ .ReceiverName }},
-A new user just registered on {{ .Network.Name }} .
+A new user with ID {{ .User.Ids.IDString }}
just registered on {{ .Network.Name }} .
Since user registration requires admin approval, you need to approve this user before they can login.
-
-User ID: {{ .User.Ids.IDString }}
-
-
-Name: {{ with .User.Name }}{{ . }}{{ else }}none {{ end }}
-
-
-Description: {{ with .User.Description }}{{ . }}{{ else }}none {{ end }}
-
-
-Email Address: {{ with .User.PrimaryEmailAddress }}{{ . }}{{ else }}none {{ end }}
-
-
You can review this user in the Console .
{{- end -}}
diff --git a/pkg/email/templates/user_requested.txt.tmpl b/pkg/email/templates/user_requested.txt.tmpl
index 20b4f009e7..495f106d00 100644
--- a/pkg/email/templates/user_requested.txt.tmpl
+++ b/pkg/email/templates/user_requested.txt.tmpl
@@ -1,11 +1,6 @@
Dear {{ .ReceiverName }},
-A new user just registered on {{ .Network.Name }}.
+A new user with with ID {{ .User.Ids.IDString }} just registered on {{ .Network.Name }}.
Since user registration requires admin approval, you need to approve this user before they can login.
-User ID: {{ .User.Ids.IDString }}
-Name: {{ with .User.Name }}{{ . }}{{ else }}(none){{ end }}
-Description: {{ with .User.Description }}{{ . }}{{ else }}(none){{ end }}
-Email Address: {{ with .User.PrimaryEmailAddress }}{{ . }}{{ else }}(none){{ end }}
-
You can go to {{ .ConsoleURL }} to review this user in the Console.
diff --git a/pkg/email/templates/validate.html.tmpl b/pkg/email/templates/validate.html.tmpl
index 1bd37a04bd..4c2832de3e 100644
--- a/pkg/email/templates/validate.html.tmpl
+++ b/pkg/email/templates/validate.html.tmpl
@@ -14,7 +14,7 @@ Hello,
Please confirm your email address for {{ .Network.Name }}.
-Your email address "{{ .Receiver.PrimaryEmailAddress }}" will be used by {{ .EntityType }} {{ .IDString }}
.
+Your email address will be linked to {{ .EntityType }} {{ .IDString }}
.
You can now visit this link to confirm your email address.
diff --git a/pkg/email/templates/validate.txt.tmpl b/pkg/email/templates/validate.txt.tmpl
index 413d3b609f..2f725d966c 100644
--- a/pkg/email/templates/validate.txt.tmpl
+++ b/pkg/email/templates/validate.txt.tmpl
@@ -2,7 +2,7 @@ Hello,
Please confirm your email address for {{ .Network.Name }}.
-Your email address "{{ .Receiver.PrimaryEmailAddress }}" will be used by {{ .EntityType }} "{{ .IDString }}".
+Your email address will be linked to {{ .EntityType }} "{{ .IDString }}".
You can go to {{ .Network.IdentityServerURL }}/validate?reference={{ .ID }}&token={{ .Token }} to confirm your email address.
Alternatively, you can use the reference "{{ .ID }}" and confirmation token "{{ .Token }}" directly.
diff --git a/pkg/encoding/lorawan/mac.go b/pkg/encoding/lorawan/mac.go
index 2c7ae3152c..ece8e44004 100644
--- a/pkg/encoding/lorawan/mac.go
+++ b/pkg/encoding/lorawan/mac.go
@@ -904,6 +904,568 @@ var DefaultMACCommands = MACCommandSpec{
return nil
}),
},
+
+ ttnpb.MACCommandIdentifier_CID_RELAY_CONF: &MACCommandDescriptor{
+ InitiatedByDevice: false,
+
+ UplinkLength: 1,
+ AppendUplink: func(phy band.Band, b []byte, cmd *ttnpb.MACCommand) ([]byte, error) {
+ pld := cmd.GetRelayConfAns()
+ var status byte
+ if pld.SecondChannelFrequencyAck {
+ status |= 1
+ }
+ if pld.SecondChannelAckOffsetAck {
+ status |= (1 << 1)
+ }
+ if pld.SecondChannelDataRateIndexAck {
+ status |= (1 << 2)
+ }
+ if pld.SecondChannelIndexAck {
+ status |= (1 << 3)
+ }
+ if pld.DefaultChannelIndexAck {
+ status |= (1 << 4)
+ }
+ if pld.CadPeriodicityAck {
+ status |= (1 << 5)
+ }
+ b = append(b, status)
+ return b, nil
+ },
+ UnmarshalUplink: newMACUnmarshaler(
+ ttnpb.MACCommandIdentifier_CID_RELAY_CONF,
+ "RelayConfAns",
+ 1,
+ func(phy band.Band, b []byte, cmd *ttnpb.MACCommand) error {
+ cmd.Payload = &ttnpb.MACCommand_RelayConfAns_{
+ RelayConfAns: &ttnpb.MACCommand_RelayConfAns{
+ SecondChannelFrequencyAck: b[0]&1 == 1,
+ SecondChannelAckOffsetAck: (b[0]>>1)&1 == 1,
+ SecondChannelDataRateIndexAck: (b[0]>>2)&1 == 1,
+ SecondChannelIndexAck: (b[0]>>3)&1 == 1,
+ DefaultChannelIndexAck: (b[0]>>4)&1 == 1,
+ CadPeriodicityAck: (b[0]>>5)&1 == 1,
+ },
+ }
+ return nil
+ },
+ ),
+
+ DownlinkLength: 5,
+ AppendDownlink: func(phy band.Band, b []byte, cmd *ttnpb.MACCommand) ([]byte, error) {
+ pld := cmd.GetRelayConfReq()
+ conf := pld.GetConfiguration()
+ if conf == nil {
+ b = append(b, 0x00, 0x00, 0x00, 0x00, 0x00)
+ return b, nil
+ }
+ var chSettings uint16
+ chSettings |= 1 << 13 // StartStop
+ if conf.CadPeriodicity > 5 {
+ return nil, errExpectedLowerOrEqual("CADPeriodicity", 5)(conf.CadPeriodicity)
+ }
+ chSettings |= uint16(conf.CadPeriodicity&0x7) << 10
+ if conf.DefaultChannelIndex > 1 {
+ return nil, errExpectedLowerOrEqual("DefaultChannelIndex", 1)(conf.DefaultChannelIndex)
+ }
+ chSettings |= uint16(conf.DefaultChannelIndex&0x1) << 9
+ var secondChFrequency uint64
+ if secondCh := conf.SecondChannel; secondCh != nil {
+ chSettings |= 1 << 7 // SecondChannelIndex
+ if secondCh.DataRateIndex > 15 {
+ return nil, errExpectedLowerOrEqual("SecondChannelDataRateIndex", 15)(secondCh.DataRateIndex)
+ }
+ chSettings |= uint16(secondCh.DataRateIndex&0xf) << 3
+ if secondCh.AckOffset > 5 {
+ return nil, errExpectedLowerOrEqual("SecondChannelAckOffset", 5)(secondCh.AckOffset)
+ }
+ chSettings |= uint16(secondCh.AckOffset & 0x7)
+ if secondCh.Frequency < 100000 || secondCh.Frequency > byteutil.MaxUint24*phy.FreqMultiplier {
+ return nil, errExpectedBetween(
+ "SecondChannelFrequency", 100000, byteutil.MaxUint24*phy.FreqMultiplier,
+ )(secondCh.Frequency)
+ }
+ secondChFrequency = secondCh.Frequency
+ }
+ b = byteutil.AppendUint16(b, chSettings, 2)
+ b = byteutil.AppendUint64(b, secondChFrequency/phy.FreqMultiplier, 3)
+ return b, nil
+ },
+ UnmarshalDownlink: newMACUnmarshaler(
+ ttnpb.MACCommandIdentifier_CID_RELAY_CONF,
+ "RelayConfReq",
+ 5,
+ func(phy band.Band, b []byte, cmd *ttnpb.MACCommand) error {
+ payload := &ttnpb.MACCommand_RelayConfReq_{
+ RelayConfReq: &ttnpb.MACCommand_RelayConfReq{},
+ }
+ cmd.Payload = payload
+ chSettings := byteutil.ParseUint16(b[0:2])
+ if chSettings&(1<<13) == 0 {
+ return nil
+ }
+ conf := &ttnpb.MACCommand_RelayConfReq_Configuration{
+ SecondChannel: nil,
+ DefaultChannelIndex: uint32(chSettings>>9) & 0x1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity(chSettings>>10) & 0x7,
+ }
+ if chSettings&(1<<7) != 0 {
+ conf.SecondChannel = &ttnpb.RelaySecondChannel{
+ Frequency: byteutil.ParseUint64(b[2:5]) * phy.FreqMultiplier,
+ AckOffset: ttnpb.RelaySecondChAckOffset(chSettings) & 0x7,
+ DataRateIndex: ttnpb.DataRateIndex(chSettings>>3) & 0xf,
+ }
+ }
+ payload.RelayConfReq.Configuration = conf
+ return nil
+ },
+ ),
+ },
+ ttnpb.MACCommandIdentifier_CID_RELAY_END_DEVICE_CONF: &MACCommandDescriptor{
+ InitiatedByDevice: false,
+
+ UplinkLength: 1,
+ AppendUplink: func(phy band.Band, b []byte, cmd *ttnpb.MACCommand) ([]byte, error) {
+ pld := cmd.GetRelayEndDeviceConfAns()
+ var status byte
+ if pld.SecondChannelFrequencyAck {
+ status |= 1
+ }
+ if pld.SecondChannelDataRateIndexAck {
+ status |= (1 << 1)
+ }
+ if pld.SecondChannelIndexAck {
+ status |= (1 << 2)
+ }
+ if pld.BackoffAck {
+ status |= (1 << 3)
+ }
+ b = append(b, status)
+ return b, nil
+ },
+ UnmarshalUplink: newMACUnmarshaler(
+ ttnpb.MACCommandIdentifier_CID_RELAY_END_DEVICE_CONF,
+ "RelayEndDeviceConfAns",
+ 1,
+ func(phy band.Band, b []byte, cmd *ttnpb.MACCommand) error {
+ cmd.Payload = &ttnpb.MACCommand_RelayEndDeviceConfAns_{
+ RelayEndDeviceConfAns: &ttnpb.MACCommand_RelayEndDeviceConfAns{
+ SecondChannelFrequencyAck: b[0]&1 == 1,
+ SecondChannelDataRateIndexAck: (b[0]>>1)&1 == 1,
+ SecondChannelIndexAck: (b[0]>>2)&1 == 1,
+ BackoffAck: (b[0]>>3)&1 == 1,
+ },
+ }
+ return nil
+ },
+ ),
+
+ DownlinkLength: 6,
+ AppendDownlink: func(phy band.Band, b []byte, cmd *ttnpb.MACCommand) ([]byte, error) {
+ pld := cmd.GetRelayEndDeviceConfReq()
+ conf := pld.GetConfiguration()
+ if conf == nil {
+ b = append(b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
+ return b, nil
+ }
+ var mode byte
+ switch conf.Mode.(type) {
+ case *ttnpb.MACCommand_RelayEndDeviceConfReq_Configuration_Always:
+ mode |= 1 << 2
+ case *ttnpb.MACCommand_RelayEndDeviceConfReq_Configuration_Dynamic:
+ mode |= 2 << 2
+ smartEnableLevel := conf.GetDynamic().GetSmartEnableLevel()
+ if smartEnableLevel > 3 {
+ return nil, errExpectedLowerOrEqual("SmartEnableLevel", 3)(smartEnableLevel)
+ }
+ mode |= byte(conf.GetDynamic().GetSmartEnableLevel() & 0x3)
+ case *ttnpb.MACCommand_RelayEndDeviceConfReq_Configuration_EndDeviceControlled:
+ mode |= 3 << 2
+ default:
+ return nil, errExpectedLengthLowerOrEqual("mode", 3)(conf.Mode)
+ }
+ b = append(b, mode)
+ var chSettings uint16
+ if conf.Backoff > 63 {
+ return nil, errExpectedLowerOrEqual("Backoff", 63)(conf.Backoff)
+ }
+ chSettings |= uint16(conf.Backoff&0x3f) << 9
+ var secondChFrequency uint64
+ if secondCh := conf.SecondChannel; secondCh != nil {
+ chSettings |= 1 << 7 // SecondChannelIndex
+ if secondCh.DataRateIndex > 15 {
+ return nil, errExpectedLowerOrEqual("SecondChannelDataRateIndex", 15)(secondCh.DataRateIndex)
+ }
+ chSettings |= uint16(secondCh.DataRateIndex&0xf) << 3
+ if secondCh.Frequency < 100000 || secondCh.Frequency > byteutil.MaxUint24*phy.FreqMultiplier {
+ return nil, errExpectedBetween(
+ "SecondChannelFrequency", 100000, byteutil.MaxUint24*phy.FreqMultiplier,
+ )(secondCh.Frequency)
+ }
+ if secondCh.AckOffset > 5 {
+ return nil, errExpectedLowerOrEqual("SecondChannelAckOffset", 5)(secondCh.AckOffset)
+ }
+ chSettings |= uint16(secondCh.AckOffset & 0x7)
+ secondChFrequency = secondCh.Frequency
+ }
+ b = byteutil.AppendUint16(b, chSettings, 2)
+ b = byteutil.AppendUint64(b, secondChFrequency/phy.FreqMultiplier, 3)
+ return b, nil
+ },
+ UnmarshalDownlink: newMACUnmarshaler(
+ ttnpb.MACCommandIdentifier_CID_RELAY_END_DEVICE_CONF,
+ "RelayEndDeviceConfReq",
+ 6,
+ func(phy band.Band, b []byte, cmd *ttnpb.MACCommand) error {
+ payload := &ttnpb.MACCommand_RelayEndDeviceConfReq_{
+ RelayEndDeviceConfReq: &ttnpb.MACCommand_RelayEndDeviceConfReq{},
+ }
+ cmd.Payload = payload
+ var conf *ttnpb.MACCommand_RelayEndDeviceConfReq_Configuration
+ switch mode := b[0] >> 2; mode {
+ case 0:
+ return nil
+ case 1:
+ conf = &ttnpb.MACCommand_RelayEndDeviceConfReq_Configuration{
+ Mode: &ttnpb.MACCommand_RelayEndDeviceConfReq_Configuration_Always{},
+ }
+ case 2:
+ conf = &ttnpb.MACCommand_RelayEndDeviceConfReq_Configuration{
+ Mode: &ttnpb.MACCommand_RelayEndDeviceConfReq_Configuration_Dynamic{
+ Dynamic: &ttnpb.RelayEndDeviceDynamicMode{
+ SmartEnableLevel: ttnpb.RelaySmartEnableLevel(b[0] & 0x3),
+ },
+ },
+ }
+ case 3:
+ conf = &ttnpb.MACCommand_RelayEndDeviceConfReq_Configuration{
+ Mode: &ttnpb.MACCommand_RelayEndDeviceConfReq_Configuration_EndDeviceControlled{},
+ }
+ default:
+ return errExpectedLengthLowerOrEqual("mode", 3)(mode)
+ }
+ payload.RelayEndDeviceConfReq.Configuration = conf
+ chSettings := byteutil.ParseUint16(b[1:3])
+ conf.Backoff = uint32(chSettings>>9) & 0x3f
+ if chSettings&(1<<7) != 0 {
+ conf.SecondChannel = &ttnpb.RelaySecondChannel{
+ Frequency: byteutil.ParseUint64(b[3:6]) * phy.FreqMultiplier,
+ AckOffset: ttnpb.RelaySecondChAckOffset(chSettings) & 0x7,
+ DataRateIndex: ttnpb.DataRateIndex(chSettings>>3) & 0xf,
+ }
+ }
+ return nil
+ }),
+ },
+ ttnpb.MACCommandIdentifier_CID_RELAY_UPDATE_UPLINK_LIST: &MACCommandDescriptor{
+ InitiatedByDevice: false,
+
+ UplinkLength: 0,
+ AppendUplink: func(phy band.Band, b []byte, cmd *ttnpb.MACCommand) ([]byte, error) {
+ return b, nil
+ },
+ UnmarshalUplink: newMACUnmarshaler(
+ ttnpb.MACCommandIdentifier_CID_RELAY_UPDATE_UPLINK_LIST,
+ "RelayUpdateUplinkListAns",
+ 0,
+ func(phy band.Band, b []byte, cmd *ttnpb.MACCommand) error {
+ cmd.Payload = &ttnpb.MACCommand_RelayUpdateUplinkListAns_{
+ RelayUpdateUplinkListAns: &ttnpb.MACCommand_RelayUpdateUplinkListAns{},
+ }
+ return nil
+ },
+ ),
+
+ DownlinkLength: 26,
+ AppendDownlink: func(phy band.Band, b []byte, cmd *ttnpb.MACCommand) ([]byte, error) {
+ pld := cmd.GetRelayUpdateUplinkListReq()
+ if pld.RuleIndex > 15 {
+ return nil, errExpectedLowerOrEqual("RuleIndex", 15)(pld.RuleIndex)
+ }
+ b = append(b, byte(pld.RuleIndex))
+ var uplinkLimit byte = 0x3f
+ if limits := pld.ForwardLimits; limits != nil {
+ if limits.BucketSize > 3 {
+ return nil, errExpectedLowerOrEqual("BucketSize", 3)(limits.BucketSize)
+ }
+ uplinkLimit = byte(limits.BucketSize&0x3) << 6
+ if limits.ReloadRate > 62 {
+ return nil, errExpectedLowerOrEqual("ReloadRate", 62)(limits.ReloadRate)
+ }
+ uplinkLimit |= byte(limits.ReloadRate)
+ }
+ b = append(b, uplinkLimit)
+ if n := len(pld.DevAddr); n != 4 {
+ return nil, errExpectedLengthEncodedEqual("DevAddr", 4)(n)
+ }
+ devAddr := make([]byte, 4)
+ copyReverse(devAddr, pld.DevAddr)
+ b = append(b, devAddr...)
+ b = byteutil.AppendUint32(b, pld.WFCnt, 4)
+ if n := len(pld.RootWorSKey); n != 16 {
+ return nil, errExpectedLengthEncodedEqual("RootWorSKey", 16)(n)
+ }
+ b = append(b, pld.RootWorSKey...)
+ return b, nil
+ },
+ UnmarshalDownlink: newMACUnmarshaler(
+ ttnpb.MACCommandIdentifier_CID_RELAY_UPDATE_UPLINK_LIST,
+ "RelayUpdateUplinkListReq",
+ 26,
+ func(phy band.Band, b []byte, cmd *ttnpb.MACCommand) error {
+ req := &ttnpb.MACCommand_RelayUpdateUplinkListReq{
+ DevAddr: make([]byte, 4),
+ }
+ cmd.Payload = &ttnpb.MACCommand_RelayUpdateUplinkListReq_{
+ RelayUpdateUplinkListReq: req,
+ }
+ req.RuleIndex = uint32(b[0])
+ if req.RuleIndex > 7 {
+ return errExpectedLowerOrEqual("RuleIndex", 7)(req.RuleIndex)
+ }
+ uplinkLimit := b[1]
+ if (uplinkLimit & 0x3f) != 0x3f {
+ req.ForwardLimits = &ttnpb.RelayUplinkForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize(uplinkLimit >> 6),
+ ReloadRate: uint32(uplinkLimit & 0x3f),
+ }
+ }
+ copyReverse(req.DevAddr[:], b[2:6])
+ req.WFCnt = byteutil.ParseUint32(b[6:10])
+ req.RootWorSKey = b[10:26]
+ return nil
+ },
+ ),
+ },
+ ttnpb.MACCommandIdentifier_CID_RELAY_CTRL_UPLINK_LIST: &MACCommandDescriptor{
+ InitiatedByDevice: false,
+
+ UplinkLength: 5,
+ AppendUplink: func(phy band.Band, b []byte, cmd *ttnpb.MACCommand) ([]byte, error) {
+ pld := cmd.GetRelayCtrlUplinkListAns()
+ var status byte
+ if pld.RuleIndexAck {
+ status |= 1
+ }
+ b = append(b, status)
+ b = byteutil.AppendUint32(b, pld.WFCnt, 4)
+ return b, nil
+ },
+ UnmarshalUplink: newMACUnmarshaler(
+ ttnpb.MACCommandIdentifier_CID_RELAY_CTRL_UPLINK_LIST,
+ "RelayCtrlUplinkListAns",
+ 5,
+ func(phy band.Band, b []byte, cmd *ttnpb.MACCommand) error {
+ cmd.Payload = &ttnpb.MACCommand_RelayCtrlUplinkListAns_{
+ RelayCtrlUplinkListAns: &ttnpb.MACCommand_RelayCtrlUplinkListAns{
+ RuleIndexAck: b[0]&1 == 1,
+ WFCnt: byteutil.ParseUint32(b[1:5]),
+ },
+ }
+ return nil
+ },
+ ),
+
+ DownlinkLength: 1,
+ AppendDownlink: func(phy band.Band, b []byte, cmd *ttnpb.MACCommand) ([]byte, error) {
+ req := cmd.GetRelayCtrlUplinkListReq()
+ if req.RuleIndex > 15 {
+ return nil, errExpectedLowerOrEqual("RuleIndex", 7)(req.RuleIndex)
+ }
+ var action byte
+ action |= byte(req.RuleIndex) & 0xf
+ if req.Action > 1 {
+ return nil, errExpectedLowerOrEqual("Action", 1)(req.Action)
+ }
+ action |= byte(req.Action&0x1) << 4
+ b = append(b, action)
+ return b, nil
+ },
+ UnmarshalDownlink: newMACUnmarshaler(
+ ttnpb.MACCommandIdentifier_CID_RELAY_CTRL_UPLINK_LIST,
+ "RelayCtrlUplinkListReq",
+ 1,
+ func(phy band.Band, b []byte, cmd *ttnpb.MACCommand) error {
+ cmd.Payload = &ttnpb.MACCommand_RelayCtrlUplinkListReq_{
+ RelayCtrlUplinkListReq: &ttnpb.MACCommand_RelayCtrlUplinkListReq{
+ RuleIndex: uint32(b[0] & 0xf),
+ Action: ttnpb.RelayCtrlUplinkListAction(b[0] >> 4),
+ },
+ }
+ return nil
+ },
+ ),
+ },
+ ttnpb.MACCommandIdentifier_CID_RELAY_CONFIGURE_FWD_LIMIT: &MACCommandDescriptor{
+ InitiatedByDevice: false,
+
+ UplinkLength: 0,
+ AppendUplink: func(phy band.Band, b []byte, cmd *ttnpb.MACCommand) ([]byte, error) {
+ return b, nil
+ },
+ UnmarshalUplink: newMACUnmarshaler(
+ ttnpb.MACCommandIdentifier_CID_RELAY_CONFIGURE_FWD_LIMIT,
+ "RelayConfigureFwdLimitAns",
+ 0,
+ func(phy band.Band, b []byte, cmd *ttnpb.MACCommand) error {
+ cmd.Payload = &ttnpb.MACCommand_RelayConfigureFwdLimitAns_{
+ RelayConfigureFwdLimitAns: &ttnpb.MACCommand_RelayConfigureFwdLimitAns{},
+ }
+ return nil
+ },
+ ),
+
+ DownlinkLength: 5,
+ AppendDownlink: func(phy band.Band, b []byte, cmd *ttnpb.MACCommand) ([]byte, error) {
+ pld := cmd.GetRelayConfigureFwdLimitReq()
+ if pld.ResetLimitCounter > 3 {
+ return nil, errExpectedLowerOrEqual("ResetLimitCounter", 3)(pld.ResetLimitCounter)
+ }
+ var overallReloadRate byte = 0x7f
+ var overallBucketSize byte
+ if overall := pld.OverallLimits; overall != nil {
+ if overall.ReloadRate > 126 {
+ return nil, errExpectedLowerOrEqual("ReloadRate", 126)(overall.ReloadRate)
+ }
+ overallReloadRate = byte(overall.ReloadRate & 0x7f)
+ if overall.BucketSize > 3 {
+ return nil, errExpectedLowerOrEqual("BucketSize", 3)(overall.BucketSize)
+ }
+ overallBucketSize = byte(overall.BucketSize & 0x3)
+ }
+ var globalUplinkReloadRate byte = 0x7f
+ var globalUplinkBucketSize byte
+ if global := pld.GlobalUplinkLimits; global != nil {
+ if global.ReloadRate > 126 {
+ return nil, errExpectedLowerOrEqual("ReloadRate", 126)(global.ReloadRate)
+ }
+ globalUplinkReloadRate = byte(global.ReloadRate & 0x7f)
+ if global.BucketSize > 3 {
+ return nil, errExpectedLowerOrEqual("BucketSize", 3)(global.BucketSize)
+ }
+ globalUplinkBucketSize = byte(global.BucketSize & 0x3)
+ }
+ var notifyReloadRate byte = 0x7f
+ var notifyBucketSize byte
+ if notify := pld.NotifyLimits; notify != nil {
+ if notify.ReloadRate > 126 {
+ return nil, errExpectedLowerOrEqual("ReloadRate", 126)(notify.ReloadRate)
+ }
+ notifyReloadRate = byte(notify.ReloadRate & 0x7f)
+ if notify.BucketSize > 3 {
+ return nil, errExpectedLowerOrEqual("BucketSize", 3)(notify.BucketSize)
+ }
+ notifyBucketSize = byte(notify.BucketSize & 0x3)
+ }
+ var joinRequestLimits byte = 0x7f
+ var joinRequestBucketSize byte
+ if joinReq := pld.JoinRequestLimits; joinReq != nil {
+ if joinReq.ReloadRate > 126 {
+ return nil, errExpectedLowerOrEqual("ReloadRate", 126)(joinReq.ReloadRate)
+ }
+ joinRequestLimits = byte(joinReq.ReloadRate & 0x7f)
+ if joinReq.BucketSize > 3 {
+ return nil, errExpectedLowerOrEqual("BucketSize", 3)(joinReq.BucketSize)
+ }
+ joinRequestBucketSize = byte(joinReq.BucketSize & 0x3)
+ }
+ var reloadRate uint32
+ reloadRate |= uint32(overallReloadRate)
+ reloadRate |= uint32(globalUplinkReloadRate) << 7
+ reloadRate |= uint32(notifyReloadRate) << 14
+ reloadRate |= uint32(joinRequestLimits) << 21
+ reloadRate |= uint32(pld.ResetLimitCounter&0x3) << 28
+ b = byteutil.AppendUint32(b, reloadRate, 4)
+ var bucketSize byte
+ bucketSize |= overallBucketSize
+ bucketSize |= globalUplinkBucketSize << 2
+ bucketSize |= notifyBucketSize << 4
+ bucketSize |= joinRequestBucketSize << 6
+ b = append(b, bucketSize)
+ return b, nil
+ },
+ UnmarshalDownlink: newMACUnmarshaler(
+ ttnpb.MACCommandIdentifier_CID_RELAY_CONFIGURE_FWD_LIMIT,
+ "RelayConfigureFwdLimitReq",
+ 5,
+ func(phy band.Band, b []byte, cmd *ttnpb.MACCommand) error {
+ req := &ttnpb.MACCommand_RelayConfigureFwdLimitReq{}
+ cmd.Payload = &ttnpb.MACCommand_RelayConfigureFwdLimitReq_{
+ RelayConfigureFwdLimitReq: req,
+ }
+ bucketSize, reloadRate := b[4], byteutil.ParseUint32(b[0:4])
+ req.ResetLimitCounter = ttnpb.RelayResetLimitCounter((reloadRate >> 28) & 0x3)
+ if reloadRate := reloadRate & 0x7f; reloadRate != 0x7f {
+ req.OverallLimits = &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize(bucketSize & 0x3),
+ ReloadRate: reloadRate,
+ }
+ }
+ if reloadRate := (reloadRate >> 7) & 0x7f; reloadRate != 0x7f {
+ req.GlobalUplinkLimits = &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize((bucketSize >> 2) & 0x3),
+ ReloadRate: reloadRate,
+ }
+ }
+ if reloadRate := (reloadRate >> 14) & 0x7f; reloadRate != 0x7f {
+ req.NotifyLimits = &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize((bucketSize >> 4) & 0x3),
+ ReloadRate: reloadRate,
+ }
+ }
+ if reloadRate := (reloadRate >> 21) & 0x7f; reloadRate != 0x7f {
+ req.JoinRequestLimits = &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize((bucketSize >> 6) & 0x3),
+ ReloadRate: reloadRate,
+ }
+ }
+ return nil
+ },
+ ),
+ },
+ ttnpb.MACCommandIdentifier_CID_RELAY_NOTIFY_NEW_END_DEVICE: &MACCommandDescriptor{
+ InitiatedByDevice: true,
+
+ UplinkLength: 6,
+ AppendUplink: func(phy band.Band, b []byte, cmd *ttnpb.MACCommand) ([]byte, error) {
+ pld := cmd.GetRelayNotifyNewEndDeviceReq()
+ var powerLevel uint16
+ if pld.Snr < -20 || pld.Snr > 11 {
+ return nil, errExpectedBetween("SNR", -20, 11)(pld.Snr)
+ }
+ powerLevel |= uint16(pld.Snr+20) & 0x1f
+ if pld.Rssi < -142 || pld.Rssi > -15 {
+ return nil, errExpectedBetween("RSSI", -142, -15)(pld.Rssi)
+ }
+ powerLevel |= uint16(-pld.Rssi-15) & 0x7f << 5
+ b = byteutil.AppendUint16(b, powerLevel, 2)
+ if n := len(pld.DevAddr); n != 4 {
+ return nil, errExpectedLengthEncodedEqual("DevAddr", 4)(n)
+ }
+ devAddr := make([]byte, 4)
+ copyReverse(devAddr, pld.DevAddr)
+ b = append(b, devAddr...)
+ return b, nil
+ },
+ UnmarshalUplink: newMACUnmarshaler(
+ ttnpb.MACCommandIdentifier_CID_RELAY_NOTIFY_NEW_END_DEVICE,
+ "RelayNotifyNewEndDeviceReq",
+ 6,
+ func(phy band.Band, b []byte, cmd *ttnpb.MACCommand) error {
+ req := &ttnpb.MACCommand_RelayNotifyNewEndDeviceReq{}
+ cmd.Payload = &ttnpb.MACCommand_RelayNotifyNewEndDeviceReq_{
+ RelayNotifyNewEndDeviceReq: req,
+ }
+ powerLevel := byteutil.ParseUint16(b[0:2])
+ req.Snr = int32(powerLevel&0x1f) - 20
+ req.Rssi = -int32(powerLevel>>5&0x7f) - 15
+ req.DevAddr = make([]byte, 4)
+ copyReverse(req.DevAddr, b[2:6])
+ return nil
+ },
+ ),
+ },
}
var (
diff --git a/pkg/encoding/lorawan/mac_test.go b/pkg/encoding/lorawan/mac_test.go
index 4aa93b00fb..189fd73fc9 100644
--- a/pkg/encoding/lorawan/mac_test.go
+++ b/pkg/encoding/lorawan/mac_test.go
@@ -372,6 +372,234 @@ func TestLoRaWANEncodingMAC(t *testing.T) {
[]byte{0x20, 0x02},
false,
},
+
+ {
+ "RelayConfReqDisabled",
+ &ttnpb.MACCommand_RelayConfReq{},
+ []byte{0x40, 0x00, 0x00, 0x00, 0x00, 0x00},
+ false,
+ },
+ {
+ "RelayConfReqNoSecondCh",
+ &ttnpb.MACCommand_RelayConfReq{
+ Configuration: &ttnpb.MACCommand_RelayConfReq_Configuration{
+ SecondChannel: nil,
+ DefaultChannelIndex: 0x01,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_100_MILLISECONDS,
+ },
+ },
+ []byte{0x40, 0x00, 0x2e, 0x00, 0x00, 0x00},
+ false,
+ },
+ {
+ "RelayConfReqSecondCh",
+ &ttnpb.MACCommand_RelayConfReq{
+ Configuration: &ttnpb.MACCommand_RelayConfReq_Configuration{
+ SecondChannel: &ttnpb.RelaySecondChannel{
+ AckOffset: ttnpb.RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_200,
+ Frequency: 868100000,
+ DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1,
+ },
+ DefaultChannelIndex: 0x01,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_100_MILLISECONDS,
+ },
+ },
+ []byte{0x40, 0x89, 0x2e, 0x28, 0x76, 0x84},
+ false,
+ },
+ {
+ "RelayConfAns",
+ &ttnpb.MACCommand_RelayConfAns{
+ SecondChannelFrequencyAck: true,
+ SecondChannelAckOffsetAck: false,
+ SecondChannelDataRateIndexAck: true,
+ SecondChannelIndexAck: false,
+ DefaultChannelIndexAck: true,
+ CadPeriodicityAck: true,
+ },
+ []byte{0x40, 0x35},
+ true,
+ },
+ {
+ "EndDeviceConfReqDisabled",
+ &ttnpb.MACCommand_RelayEndDeviceConfReq{},
+ []byte{0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+ false,
+ },
+ {
+ "EndDeviceConfReqNoSecondCh",
+ &ttnpb.MACCommand_RelayEndDeviceConfReq{
+ Configuration: &ttnpb.MACCommand_RelayEndDeviceConfReq_Configuration{
+ Mode: &ttnpb.MACCommand_RelayEndDeviceConfReq_Configuration_Dynamic{
+ Dynamic: &ttnpb.RelayEndDeviceDynamicMode{
+ SmartEnableLevel: ttnpb.RelaySmartEnableLevel_RELAY_SMART_ENABLE_LEVEL_64,
+ },
+ },
+ Backoff: 48,
+ },
+ },
+ []byte{0x41, 0x0b, 0x00, 0x60, 0x00, 0x00, 0x00},
+ false,
+ },
+ {
+ "EndDeviceConfReqSecondCh",
+ &ttnpb.MACCommand_RelayEndDeviceConfReq{
+ Configuration: &ttnpb.MACCommand_RelayEndDeviceConfReq_Configuration{
+ Mode: &ttnpb.MACCommand_RelayEndDeviceConfReq_Configuration_EndDeviceControlled{},
+ Backoff: 48,
+ SecondChannel: &ttnpb.RelaySecondChannel{
+ AckOffset: ttnpb.RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_200,
+ Frequency: 868100000,
+ DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1,
+ },
+ },
+ },
+ []byte{0x41, 0x0c, 0x89, 0x60, 0x28, 0x76, 0x84},
+ false,
+ },
+ {
+ "EndDeviceConfAns",
+ &ttnpb.MACCommand_RelayEndDeviceConfAns{
+ SecondChannelFrequencyAck: true,
+ SecondChannelDataRateIndexAck: true,
+ SecondChannelIndexAck: false,
+ BackoffAck: true,
+ },
+ []byte{0x41, 0x0b},
+ true,
+ },
+ {
+ "UpdateUplinkListReqNoForwardLimits",
+ &ttnpb.MACCommand_RelayUpdateUplinkListReq{
+ RuleIndex: 1,
+ DevAddr: []byte{0x41, 0x42, 0x43, 0x44},
+ WFCnt: 0x00be00ef,
+ RootWorSKey: []byte{
+ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
+ },
+ },
+ []byte{
+ 0x43, // CID
+ 0x01, // RuleIndex
+ 0x3f, // No limits
+ 0x44, 0x43, 0x42, 0x41, // DevAddr
+ 0xef, 0x00, 0xbe, 0x00, // WFCnt
+ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, // RootWorSKey
+ },
+ false,
+ },
+ {
+ "UpdateUplinkListReqForwardLimits",
+ &ttnpb.MACCommand_RelayUpdateUplinkListReq{
+ RuleIndex: 1,
+ ForwardLimits: &ttnpb.RelayUplinkForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_2,
+ ReloadRate: 48,
+ },
+ DevAddr: []byte{0x41, 0x42, 0x43, 0x44},
+ WFCnt: 0x00be00ef,
+ RootWorSKey: []byte{
+ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
+ },
+ },
+ []byte{
+ 0x43, // CID
+ 0x01, // RuleIndex
+ 0x70, // BucketSize = 2, ReloadRate = 48
+ 0x44, 0x43, 0x42, 0x41, // DevAddr
+ 0xef, 0x00, 0xbe, 0x00, // WFCnt
+ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, // RootWorSKey
+ },
+ false,
+ },
+ {
+ "UpdateUplinkListAns",
+ &ttnpb.MACCommand_RelayUpdateUplinkListAns{},
+ []byte{0x43},
+ true,
+ },
+ {
+ "RelayCtrlUplinkListReqRemoveTrustedEndDevice",
+ &ttnpb.MACCommand_RelayCtrlUplinkListReq{
+ RuleIndex: 2,
+ Action: ttnpb.RelayCtrlUplinkListAction_RELAY_CTRL_UPLINK_LIST_ACTION_REMOVE_TRUSTED_END_DEVICE,
+ },
+ []byte{0x44, 0x12},
+ false,
+ },
+ {
+ "RelayCtrlUplinkListReqReadWFCnt",
+ &ttnpb.MACCommand_RelayCtrlUplinkListReq{
+ RuleIndex: 3,
+ Action: ttnpb.RelayCtrlUplinkListAction_RELAY_CTRL_UPLINK_LIST_ACTION_READ_W_F_CNT,
+ },
+ []byte{0x44, 0x03},
+ false,
+ },
+ {
+ "RelayCtrlUplinkListAnsAccept",
+ &ttnpb.MACCommand_RelayCtrlUplinkListAns{
+ RuleIndexAck: true,
+ WFCnt: 0x11223344,
+ },
+ []byte{0x44, 0x01, 0x44, 0x33, 0x22, 0x11},
+ true,
+ },
+ {
+ "RelayCtrlUplinkListAnsReject",
+ &ttnpb.MACCommand_RelayCtrlUplinkListAns{
+ RuleIndexAck: false,
+ WFCnt: 0,
+ },
+ []byte{0x44, 0x00, 0x00, 0x00, 0x00, 0x00},
+ true,
+ },
+ {
+ "ConfigureFwdLimitReqNoLimits",
+ &ttnpb.MACCommand_RelayConfigureFwdLimitReq{},
+ []byte{0x45, 0xff, 0xff, 0xff, 0x0f, 0x00},
+ false,
+ },
+ {
+ "ConfigureFwdLimitReqLimits",
+ &ttnpb.MACCommand_RelayConfigureFwdLimitReq{
+ ResetLimitCounter: ttnpb.RelayResetLimitCounter_RELAY_RESET_LIMIT_COUNTER_NO_RESET,
+ JoinRequestLimits: &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_1,
+ ReloadRate: 12,
+ },
+ NotifyLimits: &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_2,
+ ReloadRate: 23,
+ },
+ GlobalUplinkLimits: &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_4,
+ ReloadRate: 34,
+ },
+ OverallLimits: &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_12,
+ ReloadRate: 45,
+ },
+ },
+ []byte{0x45, 0x2d, 0xd1, 0x85, 0x31, 0x1b},
+ false,
+ },
+ {
+ "ConfigureFwdLimitAns",
+ &ttnpb.MACCommand_RelayConfigureFwdLimitAns{},
+ []byte{0x45},
+ true,
+ },
+ {
+ "NotifyNewEndDeviceReq",
+ &ttnpb.MACCommand_RelayNotifyNewEndDeviceReq{
+ DevAddr: []byte{0x41, 0x42, 0x43, 0x44},
+ Snr: 6,
+ Rssi: -64,
+ },
+ []byte{0x46, 0x3a, 0x06, 0x44, 0x43, 0x42, 0x41},
+ true,
+ },
} {
t.Run(tc.Name, func(t *testing.T) {
a := assertions.New(t)
diff --git a/pkg/encoding/lorawan/relay.go b/pkg/encoding/lorawan/relay.go
new file mode 100644
index 0000000000..b6620652dd
--- /dev/null
+++ b/pkg/encoding/lorawan/relay.go
@@ -0,0 +1,91 @@
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package lorawan
+
+import (
+ "go.thethings.network/lorawan-stack/v3/pkg/band"
+ "go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
+ "go.thethings.network/lorawan-stack/v3/pkg/util/byteutil"
+)
+
+// MarshalRelayForwardDownlinkReq marshals a RelayForwardDownlinkReq.
+func MarshalRelayForwardDownlinkReq(req *ttnpb.RelayForwardDownlinkReq) ([]byte, error) {
+ if len(req.RawPayload) == 0 {
+ return nil, errMissing("RawPayload")
+ }
+ return req.RawPayload, nil
+}
+
+// UnmarshalRelayForwardDownlinkReq unmarshals b into req.
+func UnmarshalRelayForwardDownlinkReq(b []byte, req *ttnpb.RelayForwardDownlinkReq) error {
+ if len(b) == 0 {
+ return errMissing("RawPayload")
+ }
+ req.RawPayload = b
+ return nil
+}
+
+// MarshalRelayForwardUplinkReq marshals a RelayForwardUplinkReq.
+func MarshalRelayForwardUplinkReq(phy *band.Band, req *ttnpb.RelayForwardUplinkReq) ([]byte, error) {
+ if len(req.RawPayload) == 0 {
+ return nil, errMissing("RawPayload")
+ }
+ var uplinkMetadata uint32
+ if req.WorChannel > 1 {
+ return nil, errExpectedLowerOrEqual("WORChannel", 1)(req.WorChannel)
+ }
+ uplinkMetadata |= uint32(req.WorChannel&0x3) << 16
+ if req.Rssi < -142 || req.Rssi > -15 {
+ return nil, errExpectedBetween("RSSI", -142, -15)(req.Rssi)
+ }
+ uplinkMetadata |= uint32(-(req.Rssi+15)&0x7f) << 9
+ if req.Snr < -20 || req.Snr > 11 {
+ return nil, errExpectedBetween("SNR", -20, 11)(req.Snr)
+ }
+ uplinkMetadata |= uint32((req.Snr+20)&0x1f) << 4
+ drIdx, _, found := phy.FindUplinkDataRate(req.DataRate)
+ if !found {
+ return nil, errMissing("DataRate")
+ }
+ uplinkMetadata |= uint32(drIdx & 0xf)
+ b := make([]byte, 0, 6+len(req.RawPayload))
+ b = byteutil.AppendUint32(b, uplinkMetadata, 3)
+ b = byteutil.AppendUint64(b, req.Frequency/phy.FreqMultiplier, 3)
+ if n := len(req.RawPayload); n == 0 {
+ return nil, errExpectedLengthHigherOrEqual("RawPayload", 1)(n)
+ }
+ b = append(b, req.RawPayload...)
+ return b, nil
+}
+
+// UnmarshalRelayForwardUplinkReq unmarshals b into req.
+func UnmarshalRelayForwardUplinkReq(phy *band.Band, b []byte, req *ttnpb.RelayForwardUplinkReq) error {
+ if n := len(b); n < 6 {
+ return errExpectedLengthHigherOrEqual("RawPayload", 6)(n)
+ }
+ uplinkMetadata := byteutil.ParseUint32(b[:3])
+ req.WorChannel = ttnpb.RelayWORChannel(uplinkMetadata>>16) & 0x3
+ req.Rssi = -int32(uplinkMetadata>>9&0x7f) - 15
+ req.Snr = int32(uplinkMetadata>>4&0x1f) - 20
+ drIdx := ttnpb.DataRateIndex(uplinkMetadata & 0xf)
+ dataRate, ok := phy.DataRates[drIdx]
+ if !ok {
+ return errMissing("DataRate")
+ }
+ req.DataRate = dataRate.Rate
+ req.Frequency = byteutil.ParseUint64(b[3:6]) * phy.FreqMultiplier
+ req.RawPayload = b[6:]
+ return nil
+}
diff --git a/pkg/encoding/lorawan/relay_test.go b/pkg/encoding/lorawan/relay_test.go
new file mode 100644
index 0000000000..ce9af13ced
--- /dev/null
+++ b/pkg/encoding/lorawan/relay_test.go
@@ -0,0 +1,148 @@
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package lorawan_test
+
+import (
+ "testing"
+
+ "github.com/smarty/assertions"
+ "go.thethings.network/lorawan-stack/v3/pkg/band"
+ "go.thethings.network/lorawan-stack/v3/pkg/encoding/lorawan"
+ "go.thethings.network/lorawan-stack/v3/pkg/errors"
+ "go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
+ "go.thethings.network/lorawan-stack/v3/pkg/util/test/assertions/should"
+)
+
+func TestMarshalRelayForwardDownlinkReq(t *testing.T) {
+ t.Parallel()
+
+ a := assertions.New(t)
+
+ _, err := lorawan.MarshalRelayForwardDownlinkReq(&ttnpb.RelayForwardDownlinkReq{})
+ a.So(err, should.NotBeNil)
+
+ b, err := lorawan.MarshalRelayForwardDownlinkReq(&ttnpb.RelayForwardDownlinkReq{
+ RawPayload: []byte{0x01, 0x02, 0x03},
+ })
+ if a.So(err, should.BeNil) {
+ a.So(b, should.Resemble, []byte{0x01, 0x02, 0x03})
+ }
+}
+
+func TestUnmarshalRelayForwardDownlinkReq(t *testing.T) {
+ t.Parallel()
+
+ a := assertions.New(t)
+
+ err := lorawan.UnmarshalRelayForwardDownlinkReq(nil, &ttnpb.RelayForwardDownlinkReq{})
+ a.So(err, should.NotBeNil)
+
+ var req ttnpb.RelayForwardDownlinkReq
+ err = lorawan.UnmarshalRelayForwardDownlinkReq([]byte{0x01, 0x02, 0x03}, &req)
+ if a.So(err, should.BeNil) {
+ a.So(req.RawPayload, should.Resemble, []byte{0x01, 0x02, 0x03})
+ }
+}
+
+func TestMarshalRelayForwardUplinkReq(t *testing.T) {
+ t.Parallel()
+
+ a, phy := assertions.New(t), &band.EU_863_870_RP2_V1_0_4
+ for _, tc := range []struct {
+ Name string
+ Request *ttnpb.RelayForwardUplinkReq
+ }{
+ {
+ Name: "InvalidWORChannel",
+ Request: &ttnpb.RelayForwardUplinkReq{
+ WorChannel: 2,
+ },
+ },
+ {
+ Name: "InvalidRSSI",
+ Request: &ttnpb.RelayForwardUplinkReq{
+ WorChannel: ttnpb.RelayWORChannel_RELAY_WOR_CHANNEL_DEFAULT,
+ Rssi: -143,
+ },
+ },
+ {
+ Name: "InvalidSNR",
+ Request: &ttnpb.RelayForwardUplinkReq{
+ WorChannel: ttnpb.RelayWORChannel_RELAY_WOR_CHANNEL_DEFAULT,
+ Rssi: -64,
+ Snr: -21,
+ },
+ },
+ {
+ Name: "InvalidDataRateIndex",
+ Request: &ttnpb.RelayForwardUplinkReq{
+ WorChannel: ttnpb.RelayWORChannel_RELAY_WOR_CHANNEL_DEFAULT,
+ Rssi: -64,
+ Snr: 5,
+ DataRate: &ttnpb.DataRate{},
+ },
+ },
+ {
+ Name: "InvalidRawPayload",
+ Request: &ttnpb.RelayForwardUplinkReq{
+ WorChannel: ttnpb.RelayWORChannel_RELAY_WOR_CHANNEL_DEFAULT,
+ Rssi: -64,
+ Snr: 5,
+ DataRate: phy.DataRates[ttnpb.DataRateIndex_DATA_RATE_1].Rate,
+ },
+ },
+ } {
+ tc := tc
+ t.Run(tc.Name, func(t *testing.T) {
+ t.Parallel()
+
+ a := assertions.New(t)
+ _, err := lorawan.MarshalRelayForwardUplinkReq(phy, tc.Request)
+ a.So(errors.IsInvalidArgument(err), should.BeTrue)
+ })
+ }
+
+ b, err := lorawan.MarshalRelayForwardUplinkReq(phy, &ttnpb.RelayForwardUplinkReq{
+ WorChannel: ttnpb.RelayWORChannel_RELAY_WOR_CHANNEL_SECONDARY,
+ Rssi: -64,
+ Snr: 5,
+ DataRate: phy.DataRates[ttnpb.DataRateIndex_DATA_RATE_1].Rate,
+ Frequency: 868100000,
+ RawPayload: []byte{0x01, 0x02, 0x03},
+ })
+ if a.So(err, should.BeNil) {
+ a.So(b, should.Resemble, []byte{0x91, 0x63, 0x01, 0x28, 0x76, 0x84, 0x01, 0x02, 0x03})
+ }
+}
+
+func TestUnmarshalRelayForwardUplinkReq(t *testing.T) {
+ t.Parallel()
+
+ a, phy := assertions.New(t), &band.EU_863_870_RP2_V1_0_4
+
+ err := lorawan.UnmarshalRelayForwardUplinkReq(phy, nil, &ttnpb.RelayForwardUplinkReq{})
+ a.So(err, should.NotBeNil)
+
+ var req ttnpb.RelayForwardUplinkReq
+ err = lorawan.UnmarshalRelayForwardUplinkReq(phy, []byte{0x91, 0x63, 0x01, 0x28, 0x76, 0x84, 0x01, 0x02, 0x03}, &req)
+ if a.So(err, should.BeNil) {
+ a.So(req.WorChannel, should.Equal, ttnpb.RelayWORChannel_RELAY_WOR_CHANNEL_SECONDARY)
+ a.So(req.Rssi, should.Equal, -64)
+ a.So(req.Snr, should.Equal, 5)
+ a.So(req.DataRate, should.Resemble, phy.DataRates[ttnpb.DataRateIndex_DATA_RATE_1].Rate)
+ a.So(req.Frequency, should.Equal, 868100000)
+ a.So(req.RawPayload, should.Resemble, []byte{0x01, 0x02, 0x03})
+ }
+}
diff --git a/pkg/events/batch/batch.go b/pkg/events/batch/batch.go
index 86ed535a6c..dbbabf7abb 100644
--- a/pkg/events/batch/batch.go
+++ b/pkg/events/batch/batch.go
@@ -41,7 +41,7 @@ func (bp *batchPublisher) process(ctx context.Context) error {
flushed := false
for n := len(batch); n >= lowerBound; n = len(batch) {
toFlush := n
- if upperBound := 2 * lowerBound; n > upperBound {
+ if upperBound := 2 * bp.targetSize; n > upperBound {
toFlush = upperBound
}
select {
diff --git a/pkg/events/grpc/grpc.go b/pkg/events/grpc/grpc.go
index 0de69e6009..be250151c4 100644
--- a/pkg/events/grpc/grpc.go
+++ b/pkg/events/grpc/grpc.go
@@ -19,9 +19,6 @@ package grpc
import (
"context"
"os"
- "regexp"
- "sort"
- "strings"
"time"
grpc_runtime "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
@@ -65,58 +62,6 @@ type EventsServer struct {
definedNames map[string]struct{}
}
-var (
- errInvalidRegexp = errors.DefineInvalidArgument("invalid_regexp", "invalid regexp")
- errNoMatchingEvents = errors.DefineInvalidArgument("no_matching_events", "no matching events for regexp `{regexp}`")
- errUnknownEventName = errors.DefineInvalidArgument("unknown_event_name", "unknown event `{name}`")
-)
-
-func (srv *EventsServer) processNames(names ...string) ([]string, error) {
- if len(names) == 0 {
- return nil, nil
- }
- nameMap := make(map[string]struct{})
- for _, name := range names {
- if strings.HasPrefix(name, "/") && strings.HasSuffix(name, "/") {
- re, err := regexp.Compile(strings.Trim(name, "/"))
- if err != nil {
- return nil, errInvalidRegexp.WithCause(err)
- }
- var found bool
- for defined := range srv.definedNames {
- if re.MatchString(defined) {
- nameMap[defined] = struct{}{}
- found = true
- }
- }
- if !found {
- return nil, errNoMatchingEvents.WithAttributes("regexp", re.String())
- }
- } else {
- var found bool
- for defined := range srv.definedNames {
- if name == defined {
- nameMap[name] = struct{}{}
- found = true
- break
- }
- }
- if !found {
- return nil, errUnknownEventName.WithAttributes("name", name)
- }
- }
- }
- if len(nameMap) == 0 {
- return nil, nil
- }
- out := make([]string, 0, len(nameMap))
- for name := range nameMap {
- out = append(out, name)
- }
- sort.Strings(out)
- return out, nil
-}
-
var errNoIdentifiers = errors.DefineInvalidArgument("no_identifiers", "no identifiers")
// Stream implements the EventsServer interface.
@@ -125,7 +70,7 @@ func (srv *EventsServer) Stream(req *ttnpb.StreamEventsRequest, stream ttnpb.Eve
return errNoIdentifiers.New()
}
- names, err := srv.processNames(req.Names...)
+ names, err := events.NamesFromPatterns(srv.definedNames, req.Names)
if err != nil {
return err
}
diff --git a/pkg/events/pattern.go b/pkg/events/pattern.go
new file mode 100644
index 0000000000..bb3d5389c3
--- /dev/null
+++ b/pkg/events/pattern.go
@@ -0,0 +1,77 @@
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package events
+
+import (
+ "regexp"
+ "sort"
+ "strings"
+
+ "go.thethings.network/lorawan-stack/v3/pkg/errors"
+)
+
+var (
+ errInvalidRegexp = errors.DefineInvalidArgument("invalid_regexp", "invalid regexp")
+ errNoMatchingEvents = errors.DefineInvalidArgument("no_matching_events", "no matching events for regexp `{regexp}`")
+ errUnknownEventName = errors.DefineInvalidArgument("unknown_event_name", "unknown event `{name}`")
+)
+
+// NamesFromPatterns returns the event names which match the given patterns.
+// The defined names are a set of event names which are used to match the patterns.
+func NamesFromPatterns(definedNames map[string]struct{}, patterns []string) ([]string, error) {
+ if len(patterns) == 0 {
+ return nil, nil
+ }
+ nameMap := make(map[string]struct{})
+ for _, name := range patterns {
+ if strings.HasPrefix(name, "/") && strings.HasSuffix(name, "/") {
+ re, err := regexp.Compile(strings.Trim(name, "/"))
+ if err != nil {
+ return nil, errInvalidRegexp.WithCause(err)
+ }
+ var found bool
+ for defined := range definedNames {
+ if re.MatchString(defined) {
+ nameMap[defined] = struct{}{}
+ found = true
+ }
+ }
+ if !found {
+ return nil, errNoMatchingEvents.WithAttributes("regexp", re.String())
+ }
+ } else {
+ var found bool
+ for defined := range definedNames {
+ if name == defined {
+ nameMap[name] = struct{}{}
+ found = true
+ break
+ }
+ }
+ if !found {
+ return nil, errUnknownEventName.WithAttributes("name", name)
+ }
+ }
+ }
+ if len(nameMap) == 0 {
+ return nil, nil
+ }
+ out := make([]string, 0, len(nameMap))
+ for name := range nameMap {
+ out = append(out, name)
+ }
+ sort.Strings(out)
+ return out, nil
+}
diff --git a/pkg/events/redis/store.go b/pkg/events/redis/store.go
index abf59ae03d..3421ab4002 100644
--- a/pkg/events/redis/store.go
+++ b/pkg/events/redis/store.go
@@ -20,6 +20,7 @@ import (
"errors"
"hash/fnv"
"math/rand"
+ "slices"
"strconv"
"strings"
"sync"
@@ -34,7 +35,6 @@ import (
"go.thethings.network/lorawan-stack/v3/pkg/task"
"go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
"go.thethings.network/lorawan-stack/v3/pkg/unique"
- "golang.org/x/exp/slices"
)
const ttlJitter = 0.01
diff --git a/pkg/experimental/experimental_test.go b/pkg/experimental/experimental_test.go
index ed18f25be3..5af0a94ced 100644
--- a/pkg/experimental/experimental_test.go
+++ b/pkg/experimental/experimental_test.go
@@ -24,6 +24,8 @@ import (
)
func TestExperimentalFeatures(t *testing.T) {
+ t.Parallel()
+
a := assertions.New(t)
r := NewRegistry()
@@ -32,21 +34,21 @@ func TestExperimentalFeatures(t *testing.T) {
feature := DefineFeature("experimental.feature", false)
a.So(feature.GetValue(ctx), should.BeFalse)
- a.So(AllFeatures(ctx), should.Resemble, map[string]bool{"experimental.feature": false})
+ a.So(AllFeatures(ctx)["experimental.feature"], should.BeFalse)
a.So(feature.GetValue(context.Background()), should.BeFalse)
- a.So(AllFeatures(context.Background()), should.Resemble, map[string]bool{"experimental.feature": false})
+ a.So(AllFeatures(context.Background())["experimental.feature"], should.BeFalse)
r.EnableFeatures("experimental.feature")
a.So(feature.GetValue(ctx), should.BeTrue)
- a.So(AllFeatures(ctx), should.Resemble, map[string]bool{"experimental.feature": true})
+ a.So(AllFeatures(ctx)["experimental.feature"], should.BeTrue)
a.So(feature.GetValue(context.Background()), should.BeFalse)
- a.So(AllFeatures(context.Background()), should.Resemble, map[string]bool{"experimental.feature": false})
+ a.So(AllFeatures(context.Background())["experimental.feature"], should.BeFalse)
EnableFeatures("experimental.feature")
r.DisableFeatures("experimental.feature")
a.So(feature.GetValue(ctx), should.BeFalse)
- a.So(AllFeatures(ctx), should.Resemble, map[string]bool{"experimental.feature": false})
+ a.So(AllFeatures(ctx)["experimental.feature"], should.BeFalse)
a.So(feature.GetValue(context.Background()), should.BeTrue)
- a.So(AllFeatures(context.Background()), should.Resemble, map[string]bool{"experimental.feature": true})
+ a.So(AllFeatures(context.Background())["experimental.feature"], should.BeTrue)
}
diff --git a/pkg/fetch/basepath_test.go b/pkg/fetch/basepath_test.go
index 6ccd67a8de..a660f1fa3a 100644
--- a/pkg/fetch/basepath_test.go
+++ b/pkg/fetch/basepath_test.go
@@ -15,12 +15,12 @@
package fetch_test
import (
+ "slices"
"testing"
"github.com/smarty/assertions"
"go.thethings.network/lorawan-stack/v3/pkg/fetch"
"go.thethings.network/lorawan-stack/v3/pkg/util/test/assertions/should"
- "golang.org/x/exp/slices"
)
type MockInterface struct {
diff --git a/pkg/frequencyplans/frequencyplans.go b/pkg/frequencyplans/frequencyplans.go
index 41e42b0222..647de475ad 100644
--- a/pkg/frequencyplans/frequencyplans.go
+++ b/pkg/frequencyplans/frequencyplans.go
@@ -519,6 +519,8 @@ type FrequencyPlanDescription struct {
ID string `yaml:"id"`
// BaseID is the ID of the base frequency plan that this frequency plan extends (optional).
BaseID string `yaml:"base-id,omitempty"`
+ // BandID is the ID of the band that this frequency plan uses.
+ BandID string `yaml:"band-id,omitempty"`
// Name is a human readable name of the frequency plan.
Name string `yaml:"name"`
// BaseFrequency is the base frequency of the frequency plan (i.e. 868, 915)
diff --git a/pkg/frequencyplans/rpc.go b/pkg/frequencyplans/rpc.go
index 9349a4676f..ee1766e44f 100644
--- a/pkg/frequencyplans/rpc.go
+++ b/pkg/frequencyplans/rpc.go
@@ -39,8 +39,12 @@ func (s *RPCServer) ListFrequencyPlans(ctx context.Context, req *ttnpb.ListFrequ
if req.BaseFrequency != 0 && uint16(req.BaseFrequency) != desc.BaseFrequency {
continue
}
+ if req.BandId != "" && req.BandId != desc.BandID {
+ continue
+ }
res.FrequencyPlans = append(res.FrequencyPlans, &ttnpb.FrequencyPlanDescription{
Id: desc.ID,
+ BandId: desc.BandID,
BaseId: desc.BaseID,
Name: desc.Name,
BaseFrequency: uint32(desc.BaseFrequency),
diff --git a/pkg/frequencyplans/rpc_test.go b/pkg/frequencyplans/rpc_test.go
index 2d645dfcd9..47bd61ef1f 100644
--- a/pkg/frequencyplans/rpc_test.go
+++ b/pkg/frequencyplans/rpc_test.go
@@ -26,18 +26,22 @@ import (
)
func TestRPCServer(t *testing.T) {
+ t.Parallel()
a := assertions.New(t)
store := frequencyplans.NewStore(fetch.NewMemFetcher(map[string][]byte{
"frequency-plans.yml": []byte(`- id: A
+ band-id: EU_863_870
description: Frequency Plan A
base-frequency: 868
file: A.yml
- id: B
+ band-id: AS_923
base-id: A
description: Frequency Plan B
file: B.yml
- id: C
+ band-id: US_902_928
description: Frequency Plan C
base-frequency: 915
file: C.yml`),
@@ -45,13 +49,41 @@ func TestRPCServer(t *testing.T) {
server := frequencyplans.NewRPCServer(store)
- all, err := server.ListFrequencyPlans(context.Background(), &ttnpb.ListFrequencyPlansRequest{})
+ expectedAll := []*ttnpb.FrequencyPlanDescription{
+ {
+ Id: "A",
+ BandId: "EU_863_870",
+ BaseFrequency: 868,
+ },
+ {
+ Id: "B",
+ BaseId: "A",
+ BaseFrequency: 868,
+ BandId: "AS_923",
+ },
+ {
+ Id: "C",
+ BaseFrequency: 915,
+ BandId: "US_902_928",
+ },
+ }
+
+ actualAll, err := server.ListFrequencyPlans(context.Background(), &ttnpb.ListFrequencyPlansRequest{})
a.So(err, should.BeNil)
- a.So(all.FrequencyPlans, should.HaveLength, 3)
+ a.So(actualAll.FrequencyPlans, should.HaveLength, 3)
+ a.So(actualAll.FrequencyPlans[0], should.Resemble, expectedAll[0])
base915, err := server.ListFrequencyPlans(context.Background(), &ttnpb.ListFrequencyPlansRequest{
BaseFrequency: 868,
})
a.So(err, should.BeNil)
a.So(base915.FrequencyPlans, should.HaveLength, 2)
+ a.So(base915.FrequencyPlans, should.Resemble, expectedAll[:2])
+
+ bandAS, err := server.ListFrequencyPlans(context.Background(), &ttnpb.ListFrequencyPlansRequest{
+ BandId: "AS_923",
+ })
+ a.So(err, should.BeNil)
+ a.So(bandAS.FrequencyPlans, should.HaveLength, 1)
+ a.So(bandAS.FrequencyPlans[0], should.Resemble, expectedAll[1])
}
diff --git a/pkg/gatewayconfigurationserver/http.go b/pkg/gatewayconfigurationserver/http.go
index d5578d8c97..3912548da6 100644
--- a/pkg/gatewayconfigurationserver/http.go
+++ b/pkg/gatewayconfigurationserver/http.go
@@ -38,8 +38,8 @@ func (s *Server) RegisterRoutes(server *web.Server) {
router := server.Prefix(ttnpb.HTTPAPIPrefix + "/gcs/gateways/{gateway_id}/").Subrouter()
router.Use(
mux.MiddlewareFunc(webmiddleware.Namespace("gatewayconfigurationserver")),
- ratelimit.HTTPMiddleware(s.Component.RateLimiter(), "http:gcs"),
mux.MiddlewareFunc(webmiddleware.Metadata("Authorization")),
+ ratelimit.HTTPMiddleware(s.Component.RateLimiter(), "http:gcs"),
validateAndFillIDs,
)
if s.config.RequireAuth {
diff --git a/pkg/gatewayconfigurationserver/v2/server.go b/pkg/gatewayconfigurationserver/v2/server.go
index c7b5bb66f2..87acf0f9d7 100644
--- a/pkg/gatewayconfigurationserver/v2/server.go
+++ b/pkg/gatewayconfigurationserver/v2/server.go
@@ -84,9 +84,9 @@ func (s *Server) RegisterRoutes(server *web.Server) {
middleware := []webmiddleware.MiddlewareFunc{
webmiddleware.Namespace("gatewayconfigurationserver/v2"),
- ratelimit.HTTPMiddleware(s.component.RateLimiter(), "http:gcs"),
rewriteAuthorization,
webmiddleware.Metadata("Authorization"),
+ ratelimit.HTTPMiddleware(s.component.RateLimiter(), "http:gcs"),
}
router.Handle(
diff --git a/pkg/gatewayserver/gatewayserver.go b/pkg/gatewayserver/gatewayserver.go
index 450bf831c5..804cef400f 100644
--- a/pkg/gatewayserver/gatewayserver.go
+++ b/pkg/gatewayserver/gatewayserver.go
@@ -450,6 +450,11 @@ type connectionEntry struct {
tasksDone *sync.WaitGroup
}
+// AssertGatewayRights checks that the caller has the required rights over the provided gateway identifiers.
+func (gs *GatewayServer) AssertGatewayRights(ctx context.Context, ids *ttnpb.GatewayIdentifiers, rights ...ttnpb.Right) error {
+ return gs.entityRegistry.AssertGatewayRights(ctx, ids, rights...)
+}
+
// Connect connects a gateway by its identifiers to the Gateway Server, and returns a io.Connection for traffic and
// control.
func (gs *GatewayServer) Connect(
@@ -459,7 +464,7 @@ func (gs *GatewayServer) Connect(
addr *ttnpb.GatewayRemoteAddress,
opts ...io.ConnectionOption,
) (*io.Connection, error) {
- if err := gs.entityRegistry.AssertGatewayRights(ctx, ids, ttnpb.Right_RIGHT_GATEWAY_LINK); err != nil {
+ if err := gs.AssertGatewayRights(ctx, ids, ttnpb.Right_RIGHT_GATEWAY_LINK); err != nil {
return nil, err
}
@@ -486,6 +491,7 @@ func (gs *GatewayServer) Connect(
"enforce_duty_cycle",
"frequency_plan_id",
"frequency_plan_ids",
+ "gateway_server_address",
"location_public",
"require_authenticated_connection",
"schedule_anytime_delay",
@@ -611,7 +617,8 @@ func requireDisconnect(connected, current *ttnpb.Gateway) bool {
connected.StatusPublic != current.StatusPublic ||
connected.UpdateLocationFromStatus != current.UpdateLocationFromStatus ||
connected.FrequencyPlanId != current.FrequencyPlanId ||
- len(connected.FrequencyPlanIds) != len(current.FrequencyPlanIds) {
+ len(connected.FrequencyPlanIds) != len(current.FrequencyPlanIds) ||
+ connected.GatewayServerAddress != current.GatewayServerAddress {
return true
}
for i := range connected.FrequencyPlanIds {
@@ -646,6 +653,7 @@ func (gs *GatewayServer) startDisconnectOnChangeTask(conn connectionEntry) {
"enforce_duty_cycle",
"frequency_plan_id",
"frequency_plan_ids",
+ "gateway_server_address",
"location_public",
"require_authenticated_connection",
"schedule_anytime_delay",
diff --git a/pkg/gatewayserver/io/io.go b/pkg/gatewayserver/io/io.go
index 276a40291e..3659ba02c4 100644
--- a/pkg/gatewayserver/io/io.go
+++ b/pkg/gatewayserver/io/io.go
@@ -60,8 +60,11 @@ type Server interface {
GetBaseConfig(ctx context.Context) config.ServiceBase
// FillGatewayContext fills the given context and identifiers.
// This method should only be used for request contexts.
- FillGatewayContext(ctx context.Context,
- ids *ttnpb.GatewayIdentifiers) (context.Context, *ttnpb.GatewayIdentifiers, error)
+ FillGatewayContext(
+ ctx context.Context, ids *ttnpb.GatewayIdentifiers,
+ ) (context.Context, *ttnpb.GatewayIdentifiers, error)
+ // AssertGatewayRights checks that the caller has the required rights over the provided gateway identifiers.
+ AssertGatewayRights(ctx context.Context, ids *ttnpb.GatewayIdentifiers, required ...ttnpb.Right) error
// Connect connects a gateway by its identifiers to the Gateway Server, and returns a Connection for traffic and
// control.
Connect(
@@ -109,7 +112,7 @@ type Connection struct {
frontend Frontend
gateway *ttnpb.Gateway
gatewayPrimaryFP *frequencyplans.FrequencyPlan
- gatewayFPs map[string]*frequencyplans.FrequencyPlan
+ gatewayFPs []*frequencyplans.FrequencyPlan
band *band.Band
fps *frequencyplans.Store
scheduler *scheduling.Scheduler
@@ -178,13 +181,17 @@ func NewConnection(
opt(connectionOptions)
}
- gatewayFPs := make(map[string]*frequencyplans.FrequencyPlan, len(gateway.FrequencyPlanIds))
+ gatewayFPLen := len(gateway.FrequencyPlanIds)
+ if gatewayFPLen == 0 {
+ gatewayFPLen = 1
+ }
+ gatewayFPs := make([]*frequencyplans.FrequencyPlan, gatewayFPLen)
fp0ID := gateway.FrequencyPlanId
fp0, err := fps.GetByID(fp0ID)
if err != nil {
return nil, err
}
- gatewayFPs[fp0ID] = fp0
+ gatewayFPs[0] = fp0
phy, err := band.GetLatest(fp0.BandID)
if err != nil {
return nil, err
@@ -202,7 +209,7 @@ func NewConnection(
if fpn.BandID != fp0.BandID {
return nil, errFrequencyPlansNotFromSameBand.New()
}
- gatewayFPs[gateway.FrequencyPlanIds[i]] = fpn
+ gatewayFPs[i] = fpn
}
}
@@ -530,16 +537,13 @@ func (c *Connection) ScheduleDown(path *ttnpb.DownlinkPath, msg *ttnpb.DownlinkM
var fp *frequencyplans.FrequencyPlan
fpID := request.GetFrequencyPlanId()
if fpID != "" {
- fp = c.gatewayFPs[fpID]
- if fp == nil {
- // The requested frequency plan is not configured for the gateway. Load the plan and enforce that it's in the same band.
- fp, err = c.fps.GetByID(fpID)
- if err != nil {
- return false, false, 0, errFrequencyPlanNotConfigured.WithCause(err).WithAttributes("id", request.FrequencyPlanId)
- }
- if fp.BandID != c.band.ID {
- return false, false, 0, errFrequencyPlansNotFromSameBand.New()
- }
+ // Load the plan and enforce that it's in the same band.
+ fp, err = c.fps.GetByID(fpID)
+ if err != nil {
+ return false, false, 0, errFrequencyPlanNotConfigured.WithCause(err).WithAttributes("id", request.FrequencyPlanId)
+ }
+ if fp.BandID != c.band.ID {
+ return false, false, 0, errFrequencyPlansNotFromSameBand.New()
}
} else {
// Backwards compatibility. If there's no FrequencyPlanID in the TxRequest, then there must be only one Frequency
@@ -863,7 +867,7 @@ func (c *Connection) Stats() (*ttnpb.GatewayConnectionStats, []string) {
}
// FrequencyPlans returns the frequency plans for the gateway.
-func (c *Connection) FrequencyPlans() map[string]*frequencyplans.FrequencyPlan { return c.gatewayFPs }
+func (c *Connection) FrequencyPlans() []*frequencyplans.FrequencyPlan { return c.gatewayFPs }
// PrimaryFrequencyPlan returns the primary frequency plan of the gateway.
func (c *Connection) PrimaryFrequencyPlan() *frequencyplans.FrequencyPlan { return c.gatewayPrimaryFP }
diff --git a/pkg/gatewayserver/io/mock/server.go b/pkg/gatewayserver/io/mock/server.go
index 083d05ff09..080e1da0cc 100644
--- a/pkg/gatewayserver/io/mock/server.go
+++ b/pkg/gatewayserver/io/mock/server.go
@@ -76,6 +76,11 @@ func (s *server) FillGatewayContext(ctx context.Context, ids *ttnpb.GatewayIdent
return ctx, ids, nil
}
+// AssertRights implements io.Server.
+func (*server) AssertGatewayRights(ctx context.Context, ids *ttnpb.GatewayIdentifiers, required ...ttnpb.Right) error {
+ return rights.RequireGateway(ctx, ids, required...)
+}
+
// Connect implements io.Server.
func (s *server) Connect(
ctx context.Context,
@@ -84,7 +89,7 @@ func (s *server) Connect(
addr *ttnpb.GatewayRemoteAddress,
opts ...io.ConnectionOption,
) (*io.Connection, error) {
- if err := rights.RequireGateway(ctx, ids, ttnpb.Right_RIGHT_GATEWAY_LINK); err != nil {
+ if err := s.AssertGatewayRights(ctx, ids, ttnpb.Right_RIGHT_GATEWAY_LINK); err != nil {
return nil, err
}
gtw, err := s.identityStore.GatewayRegistry().Get(ctx, &ttnpb.GetGatewayRequest{GatewayIds: ids})
diff --git a/pkg/gatewayserver/io/udp/udp.go b/pkg/gatewayserver/io/udp/udp.go
index e394520dfb..45a0c003f2 100644
--- a/pkg/gatewayserver/io/udp/udp.go
+++ b/pkg/gatewayserver/io/udp/udp.go
@@ -18,6 +18,7 @@ import (
"context"
"encoding/binary"
"net"
+ "slices"
"sync"
"sync/atomic"
"time"
@@ -34,7 +35,6 @@ import (
"go.thethings.network/lorawan-stack/v3/pkg/types"
"go.thethings.network/lorawan-stack/v3/pkg/unique"
"go.thethings.network/lorawan-stack/v3/pkg/workerpool"
- "golang.org/x/exp/slices"
"google.golang.org/protobuf/types/known/timestamppb"
)
diff --git a/pkg/gatewayserver/io/ws/format.go b/pkg/gatewayserver/io/ws/format.go
index 34ba32ddc2..d8c59a9162 100644
--- a/pkg/gatewayserver/io/ws/format.go
+++ b/pkg/gatewayserver/io/ws/format.go
@@ -41,12 +41,22 @@ type Formatter interface {
Endpoints() Endpoints
// HandleConnectionInfo handles connection information requests from web socket based protocols.
// This function returns a byte stream that contains connection information (ex: scheme, host, port etc) or an error if applicable.
- HandleConnectionInfo(ctx context.Context, raw []byte, server io.Server, serverInfo ServerInfo, receivedAt time.Time) []byte
+ HandleConnectionInfo(
+ ctx context.Context,
+ raw []byte,
+ server io.Server,
+ serverInfo ServerInfo,
+ assertAuth func(context.Context, *ttnpb.GatewayIdentifiers) error,
+ ) []byte
// HandleUp handles upstream messages from web socket based gateways.
// This function optionally returns a byte stream to be sent as response to the upstream message.
- HandleUp(ctx context.Context, raw []byte, ids *ttnpb.GatewayIdentifiers, conn *io.Connection, receivedAt time.Time) ([]byte, error)
+ HandleUp(
+ ctx context.Context, raw []byte, ids *ttnpb.GatewayIdentifiers, conn *io.Connection, receivedAt time.Time,
+ ) ([]byte, error)
// FromDownlink generates a downlink byte stream that can be sent over the WS connection.
FromDownlink(ctx context.Context, down *ttnpb.DownlinkMessage, bandID string, dlTime time.Time) ([]byte, error)
// TransferTime generates a spurious time transfer message for a particular server time.
- TransferTime(ctx context.Context, serverTime time.Time, gpsTime *time.Time, concentratorTime *scheduling.ConcentratorTime) ([]byte, error)
+ TransferTime(
+ ctx context.Context, serverTime time.Time, gpsTime *time.Time, concentratorTime *scheduling.ConcentratorTime,
+ ) ([]byte, error)
}
diff --git a/pkg/gatewayserver/io/ws/lbslns/discover.go b/pkg/gatewayserver/io/ws/lbslns/discover.go
index c2601930dc..5400eea70c 100644
--- a/pkg/gatewayserver/io/ws/lbslns/discover.go
+++ b/pkg/gatewayserver/io/ws/lbslns/discover.go
@@ -18,7 +18,6 @@ import (
"context"
"encoding/json"
"fmt"
- "time"
"go.thethings.network/lorawan-stack/v3/pkg/errors"
"go.thethings.network/lorawan-stack/v3/pkg/gatewayserver/io"
@@ -32,7 +31,13 @@ import (
var errEmptyGatewayEUI = errors.DefineFailedPrecondition("empty_gateway_eui", "empty gateway EUI")
// HandleConnectionInfo implements Formatter.
-func (f *lbsLNS) HandleConnectionInfo(ctx context.Context, raw []byte, server io.Server, info ws.ServerInfo, receivedAt time.Time) []byte {
+func (f *lbsLNS) HandleConnectionInfo(
+ ctx context.Context,
+ raw []byte,
+ server io.Server,
+ info ws.ServerInfo,
+ assertAuth func(ctx context.Context, ids *ttnpb.GatewayIdentifiers) error,
+) []byte {
var req DiscoverQuery
if err := json.Unmarshal(raw, &req); err != nil {
@@ -52,6 +57,10 @@ func (f *lbsLNS) HandleConnectionInfo(ctx context.Context, raw []byte, server io
}
ctx = filledCtx
+ if err := assertAuth(ctx, ids); err != nil {
+ return logAndWrapDiscoverError(ctx, err, fmt.Sprintf("Unauthorized"))
+ }
+
euiWithPrefix := fmt.Sprintf("eui-%s", types.MustEUI64(ids.Eui).OrZero().String())
res := DiscoverResponse{
EUI: req.EUI,
diff --git a/pkg/gatewayserver/io/ws/lbslns/discover_test.go b/pkg/gatewayserver/io/ws/lbslns/discover_test.go
index 12c3f6a27b..bc7e4c998b 100644
--- a/pkg/gatewayserver/io/ws/lbslns/discover_test.go
+++ b/pkg/gatewayserver/io/ws/lbslns/discover_test.go
@@ -18,7 +18,6 @@ import (
"context"
"encoding/json"
"testing"
- "time"
"github.com/smarty/assertions"
"go.thethings.network/lorawan-stack/v3/pkg/gatewayserver/io/ws"
@@ -69,9 +68,11 @@ func TestDiscover(t *testing.T) {
t.Run(tc.Name, func(t *testing.T) {
msg, err := json.Marshal(tc.Query)
a.So(err, should.BeNil)
- resp := lbsLNS.HandleConnectionInfo(ctx, msg, mockServer, info, time.Now())
+ resp := lbsLNS.HandleConnectionInfo(ctx, msg, mockServer, info, noopAssertRights)
expected, _ := json.Marshal(tc.ExpectedResponse)
a.So(string(resp), should.Equal, string(expected))
})
}
}
+
+func noopAssertRights(context.Context, *ttnpb.GatewayIdentifiers) error { return nil }
diff --git a/pkg/gatewayserver/io/ws/lbslns/discover_util_test.go b/pkg/gatewayserver/io/ws/lbslns/discover_util_test.go
index 19743b5693..e8e62e96e8 100644
--- a/pkg/gatewayserver/io/ws/lbslns/discover_util_test.go
+++ b/pkg/gatewayserver/io/ws/lbslns/discover_util_test.go
@@ -37,6 +37,10 @@ func (srv mockServer) FillGatewayContext(ctx context.Context, ids *ttnpb.Gateway
return ctx, srv.ids, nil
}
+func (mockServer) AssertGatewayRights(context.Context, *ttnpb.GatewayIdentifiers, ...ttnpb.Right) error {
+ return nil
+}
+
func (mockServer) Connect(
context.Context, io.Frontend, *ttnpb.GatewayIdentifiers, *ttnpb.GatewayRemoteAddress, ...io.ConnectionOption,
) (*io.Connection, error) {
diff --git a/pkg/gatewayserver/io/ws/lbslns/version.go b/pkg/gatewayserver/io/ws/lbslns/version.go
index d3dd7db1c4..f86eafc187 100644
--- a/pkg/gatewayserver/io/ws/lbslns/version.go
+++ b/pkg/gatewayserver/io/ws/lbslns/version.go
@@ -64,7 +64,7 @@ func (*lbsLNS) GetRouterConfig(
ctx context.Context,
msg []byte,
bandID string,
- fps map[string]*frequencyplans.FrequencyPlan,
+ fps []*frequencyplans.FrequencyPlan,
antennaGain int,
receivedAt time.Time,
) (context.Context, []byte, *ttnpb.GatewayStatus, error) {
diff --git a/pkg/gatewayserver/io/ws/ws.go b/pkg/gatewayserver/io/ws/ws.go
index 41834ef38f..225ae1fe01 100644
--- a/pkg/gatewayserver/io/ws/ws.go
+++ b/pkg/gatewayserver/io/ws/ws.go
@@ -117,6 +117,18 @@ func (s *srv) handleConnectionInfo(w http.ResponseWriter, r *http.Request) {
"remote_addr", r.RemoteAddr,
))
logger := log.FromContext(ctx)
+
+ assertAuth := func(ctx context.Context, ids *ttnpb.GatewayIdentifiers) error {
+ ctx, hasAuth := withForwardedAuth(ctx, ids, r.Header.Get("Authorization"))
+ if !hasAuth {
+ if !s.cfg.AllowUnauthenticated {
+ return errNoAuthProvided.WithAttributes("uid", unique.ID(ctx, ids))
+ }
+ return nil
+ }
+ return s.server.AssertGatewayRights(ctx, ids, ttnpb.Right_RIGHT_GATEWAY_LINK)
+ }
+
ws, err := s.upgrader.Upgrade(w, r, nil)
if err != nil {
logger.WithError(err).Debug("Failed to upgrade request to websocket connection")
@@ -154,7 +166,7 @@ func (s *srv) handleConnectionInfo(w http.ResponseWriter, r *http.Request) {
Address: net.JoinHostPort(host, port),
}
- resp := s.formatter.HandleConnectionInfo(ctx, data, s.server, info, time.Now())
+ resp := s.formatter.HandleConnectionInfo(ctx, data, s.server, info, assertAuth)
if err := ws.WriteMessage(websocket.TextMessage, resp); err != nil {
logger.WithError(err).Warn("Failed to write connection info response message")
return
@@ -202,47 +214,12 @@ func (s *srv) handleTraffic(w http.ResponseWriter, r *http.Request) (err error)
uid := unique.ID(ctx, ids)
ctx = log.NewContextWithField(ctx, "gateway_uid", uid)
- var md metadata.MD
-
- if auth != "" {
- if !strings.HasPrefix(auth, "Bearer ") {
- auth = fmt.Sprintf("Bearer %s", auth)
- }
- md = metadata.New(map[string]string{
- "id": ids.GatewayId,
- "authorization": auth,
- })
- }
-
- if ctxMd, ok := metadata.FromIncomingContext(ctx); ok {
- md = metadata.Join(ctxMd, md)
- }
- ctx = metadata.NewIncomingContext(ctx, md)
- // If a fallback frequency is defined in the server context, inject it into local the context.
- if fallback, ok := frequencyplans.FallbackIDFromContext(s.ctx); ok {
- ctx = frequencyplans.WithFallbackID(ctx, fallback)
- }
-
- var hasAuth bool
- if auth != "" {
- if !strings.HasPrefix(auth, "Bearer ") {
- auth = fmt.Sprintf("Bearer %s", auth)
- }
- md = metadata.New(map[string]string{
- "authorization": auth,
- })
- hasAuth = true
- }
-
- if ctxMd, ok := metadata.FromIncomingContext(ctx); ok {
- md = metadata.Join(ctxMd, md)
- }
- ctx = metadata.NewIncomingContext(ctx, md)
// If a fallback frequency is defined in the server context, inject it into local the context.
if fallback, ok := frequencyplans.FallbackIDFromContext(s.ctx); ok {
ctx = frequencyplans.WithFallbackID(ctx, fallback)
}
+ ctx, hasAuth := withForwardedAuth(ctx, ids, auth)
if !hasAuth {
if !s.cfg.AllowUnauthenticated {
// We error here directly as there is no auth.
@@ -416,3 +393,24 @@ func (s *srv) handleTraffic(w http.ResponseWriter, r *http.Request) (err error)
}
}
}
+
+func withForwardedAuth(ctx context.Context, ids *ttnpb.GatewayIdentifiers, auth string) (context.Context, bool) {
+ var md metadata.MD
+ var hasAuth bool
+ if auth != "" {
+ if !strings.HasPrefix(auth, "Bearer ") {
+ auth = fmt.Sprintf("Bearer %s", auth)
+ }
+ m := map[string]string{"authorization": auth}
+ if ids != nil {
+ m["id"] = ids.GatewayId
+ }
+ md = metadata.New(m)
+ if ctxMd, ok := metadata.FromIncomingContext(ctx); ok {
+ md = metadata.Join(ctxMd, md)
+ }
+ ctx = metadata.NewIncomingContext(ctx, md)
+ hasAuth = true
+ }
+ return ctx, hasAuth
+}
diff --git a/pkg/gatewayserver/scheduling/scheduler.go b/pkg/gatewayserver/scheduling/scheduler.go
index e574bc8f92..88cf0d90a1 100644
--- a/pkg/gatewayserver/scheduling/scheduler.go
+++ b/pkg/gatewayserver/scheduling/scheduler.go
@@ -81,7 +81,7 @@ var (
// If no time source is specified, the system time is used.
func NewScheduler(
ctx context.Context,
- fps map[string]*frequencyplans.FrequencyPlan,
+ fps []*frequencyplans.FrequencyPlan,
enforceDutyCycle bool,
dutyCycleStyle DutyCycleStyle,
scheduleAnytimeDelay *time.Duration,
@@ -188,7 +188,7 @@ func NewScheduler(
// Scheduler is a packet scheduler that takes time conflicts and sub-band restrictions into account.
type Scheduler struct {
clock *RolloverClock
- fps map[string]*frequencyplans.FrequencyPlan
+ fps []*frequencyplans.FrequencyPlan
timeOffAir frequencyplans.TimeOffAir
timeSource TimeSource
subBands []*SubBand
diff --git a/pkg/gatewayserver/scheduling/scheduler_test.go b/pkg/gatewayserver/scheduling/scheduler_test.go
index c7297f87c6..557862a1d8 100644
--- a/pkg/gatewayserver/scheduling/scheduler_test.go
+++ b/pkg/gatewayserver/scheduling/scheduler_test.go
@@ -35,7 +35,7 @@ import (
func TestScheduleAtWithBandDutyCycle(t *testing.T) {
a := assertions.New(t)
ctx := test.Context()
- fps := map[string]*frequencyplans.FrequencyPlan{test.EUFrequencyPlanID: {
+ fps := []*frequencyplans.FrequencyPlan{{
BandID: band.EU_863_870,
TimeOffAir: frequencyplans.TimeOffAir{
Duration: time.Second,
@@ -350,7 +350,7 @@ func TestScheduleAtWithBandDutyCycle(t *testing.T) {
func TestScheduleAtWithFrequencyPlanDutyCycle(t *testing.T) {
a := assertions.New(t)
ctx := test.Context()
- fps := map[string]*frequencyplans.FrequencyPlan{test.EUFrequencyPlanID: {
+ fps := []*frequencyplans.FrequencyPlan{{
BandID: band.EU_863_870,
SubBands: []frequencyplans.SubBandParameters{
{
@@ -438,7 +438,7 @@ func TestScheduleAtWithFrequencyPlanDutyCycle(t *testing.T) {
func TestScheduleAnytime(t *testing.T) {
a := assertions.New(t)
ctx := test.Context()
- fps := map[string]*frequencyplans.FrequencyPlan{test.EUFrequencyPlanID: {
+ fps := []*frequencyplans.FrequencyPlan{{
BandID: band.EU_863_870,
TimeOffAir: frequencyplans.TimeOffAir{
Duration: time.Second,
@@ -552,7 +552,7 @@ func TestScheduleAnytime(t *testing.T) {
func TestScheduleAnytimeShort(t *testing.T) {
a := assertions.New(t)
ctx := test.Context()
- fps := map[string]*frequencyplans.FrequencyPlan{test.EUFrequencyPlanID: {
+ fps := []*frequencyplans.FrequencyPlan{{
BandID: band.EU_863_870,
TimeOffAir: frequencyplans.TimeOffAir{
Duration: time.Second,
@@ -752,7 +752,7 @@ func TestScheduleAnytimeShort(t *testing.T) {
func TestScheduleAnytimeClassC(t *testing.T) {
a := assertions.New(t)
ctx := test.Context()
- fps := map[string]*frequencyplans.FrequencyPlan{test.EUFrequencyPlanID: {
+ fps := []*frequencyplans.FrequencyPlan{{
BandID: band.EU_863_870,
TimeOffAir: frequencyplans.TimeOffAir{
Duration: time.Second,
@@ -843,14 +843,14 @@ func TestSchedulerWithMultipleFrequencyPlans(t *testing.T) {
ctx := test.Context()
for _, tc := range []struct {
Name string
- FrequencyPlans map[string]*frequencyplans.FrequencyPlan
+ FrequencyPlans []*frequencyplans.FrequencyPlan
ExpectedSubBandCount int
ErrorAssertion func(error) bool
}{
{
Name: "RepeatedNoOverlap",
- FrequencyPlans: map[string]*frequencyplans.FrequencyPlan{
- test.EUFrequencyPlanID: {
+ FrequencyPlans: []*frequencyplans.FrequencyPlan{
+ {
BandID: band.EU_863_870,
TimeOffAir: frequencyplans.TimeOffAir{
Duration: time.Second,
@@ -860,7 +860,7 @@ func TestSchedulerWithMultipleFrequencyPlans(t *testing.T) {
Duration: durationPtr(2 * time.Second),
},
},
- "EU_863_870_Custom": {
+ {
BandID: band.EU_863_870,
TimeOffAir: frequencyplans.TimeOffAir{
Duration: time.Second,
@@ -875,8 +875,8 @@ func TestSchedulerWithMultipleFrequencyPlans(t *testing.T) {
},
{
Name: "UnionOfNonOverlapping",
- FrequencyPlans: map[string]*frequencyplans.FrequencyPlan{
- test.EUFrequencyPlanID: {
+ FrequencyPlans: []*frequencyplans.FrequencyPlan{
+ {
BandID: band.EU_863_870,
TimeOffAir: frequencyplans.TimeOffAir{
Duration: time.Second,
@@ -895,7 +895,7 @@ func TestSchedulerWithMultipleFrequencyPlans(t *testing.T) {
},
},
},
- "EU_863_870_Custom": {
+ {
BandID: band.EU_863_870,
TimeOffAir: frequencyplans.TimeOffAir{
Duration: time.Second,
@@ -910,8 +910,8 @@ func TestSchedulerWithMultipleFrequencyPlans(t *testing.T) {
},
{
Name: "MismatchedTimeOffAir",
- FrequencyPlans: map[string]*frequencyplans.FrequencyPlan{
- test.EUFrequencyPlanID: {
+ FrequencyPlans: []*frequencyplans.FrequencyPlan{
+ {
BandID: band.EU_863_870,
TimeOffAir: frequencyplans.TimeOffAir{
Duration: 2 * time.Second,
@@ -921,7 +921,7 @@ func TestSchedulerWithMultipleFrequencyPlans(t *testing.T) {
Duration: durationPtr(2 * time.Second),
},
},
- "EU_863_870_Custom": {
+ {
BandID: band.EU_863_870,
TimeOffAir: frequencyplans.TimeOffAir{
Duration: time.Second,
@@ -938,8 +938,8 @@ func TestSchedulerWithMultipleFrequencyPlans(t *testing.T) {
},
{
Name: "OverlappingSubBands",
- FrequencyPlans: map[string]*frequencyplans.FrequencyPlan{
- test.EUFrequencyPlanID: {
+ FrequencyPlans: []*frequencyplans.FrequencyPlan{
+ {
BandID: band.EU_863_870,
TimeOffAir: frequencyplans.TimeOffAir{
Duration: time.Second,
@@ -958,7 +958,7 @@ func TestSchedulerWithMultipleFrequencyPlans(t *testing.T) {
},
},
},
- "EU_863_870_Custom": {
+ {
BandID: band.EU_863_870,
TimeOffAir: frequencyplans.TimeOffAir{
Duration: time.Second,
@@ -975,8 +975,8 @@ func TestSchedulerWithMultipleFrequencyPlans(t *testing.T) {
},
{
Name: "OverlappingSubBandsFromBand",
- FrequencyPlans: map[string]*frequencyplans.FrequencyPlan{
- "AS_923": {
+ FrequencyPlans: []*frequencyplans.FrequencyPlan{
+ {
// This is a fictional test case since currently we don't support mix-band frequency plans (https://github.com/TheThingsNetwork/lorawan-stack/issues/1394).
BandID: band.AS_923,
TimeOffAir: frequencyplans.TimeOffAir{
@@ -987,7 +987,7 @@ func TestSchedulerWithMultipleFrequencyPlans(t *testing.T) {
Duration: durationPtr(2 * time.Second),
},
},
- "AU_915_928": {
+ {
BandID: band.AU_915_928,
TimeOffAir: frequencyplans.TimeOffAir{
Duration: time.Second,
@@ -1029,8 +1029,8 @@ func TestSchedulerWithMultipleFrequencyPlans(t *testing.T) {
func TestSchedulingWithMultipleFrequencyPlans(t *testing.T) {
a := assertions.New(t)
ctx := test.Context()
- fps := map[string]*frequencyplans.FrequencyPlan{
- test.EUFrequencyPlanID: {
+ fps := []*frequencyplans.FrequencyPlan{
+ {
BandID: band.EU_863_870,
TimeOffAir: frequencyplans.TimeOffAir{
Duration: time.Second,
@@ -1049,7 +1049,7 @@ func TestSchedulingWithMultipleFrequencyPlans(t *testing.T) {
},
},
},
- "EU_863_870_Custom": {
+ {
BandID: band.EU_863_870,
TimeOffAir: frequencyplans.TimeOffAir{
Duration: time.Second,
@@ -1140,7 +1140,7 @@ func TestSchedulingWithMultipleFrequencyPlans(t *testing.T) {
func TestScheduleSyncViaUplinkToken(t *testing.T) {
a := assertions.New(t)
ctx := test.Context()
- fps := map[string]*frequencyplans.FrequencyPlan{test.EUFrequencyPlanID: {
+ fps := []*frequencyplans.FrequencyPlan{{
BandID: band.EU_863_870,
TimeOffAir: frequencyplans.TimeOffAir{
Duration: time.Second,
diff --git a/pkg/httpclient/http.go b/pkg/httpclient/http.go
index 94d5ec6b8d..0e6fe3b7bf 100644
--- a/pkg/httpclient/http.go
+++ b/pkg/httpclient/http.go
@@ -23,12 +23,16 @@ import (
"time"
"github.com/gregjones/httpcache"
+ "github.com/klauspost/compress/gzhttp"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
"go.thethings.network/lorawan-stack/v3/pkg/config/tlsconfig"
+ "go.thethings.network/lorawan-stack/v3/pkg/experimental"
"go.thethings.network/lorawan-stack/v3/pkg/telemetry/tracing"
"go.thethings.network/lorawan-stack/v3/pkg/version"
)
+var transportCompressionFeatureFlag = experimental.DefineFeature("http.client.transport.compression", true)
+
// defaultHTTPClientTimeout is the default timeout for the HTTP client.
const defaultHTTPClientTimeout = 10 * time.Second
@@ -95,11 +99,14 @@ func (p *provider) HTTPClient(ctx context.Context, opts ...Option) (*http.Client
transport := http.DefaultTransport.(*http.Transport).Clone()
transport.TLSClientConfig = options.tlsConfig
- otelTransport := otelhttp.NewTransport(transport,
+ var rt http.RoundTripper = transport
+ if transportCompressionFeatureFlag.GetValue(ctx) {
+ rt = gzhttp.Transport(rt)
+ }
+ rt = otelhttp.NewTransport(
+ rt,
otelhttp.WithTracerProvider(tracing.FromContext(ctx)),
)
-
- rt := http.RoundTripper(otelTransport)
if options.cache {
rt = &httpcache.Transport{
Transport: rt,
diff --git a/pkg/i18n/i18n.go b/pkg/i18n/i18n.go
index f731b361eb..34460cc6f3 100644
--- a/pkg/i18n/i18n.go
+++ b/pkg/i18n/i18n.go
@@ -19,6 +19,7 @@ import (
"bytes"
"encoding/json"
"fmt"
+ "maps"
"os"
"path/filepath"
"runtime"
@@ -27,7 +28,6 @@ import (
"sync"
"github.com/gotnospirit/messageformat"
- "golang.org/x/exp/maps"
)
const defaultLanguage = "en" // The language of the messages written in Go files.
diff --git a/pkg/identityserver/gateway_access.go b/pkg/identityserver/gateway_access.go
index 5229fb4eaa..5c4ad4c6d0 100644
--- a/pkg/identityserver/gateway_access.go
+++ b/pkg/identityserver/gateway_access.go
@@ -537,7 +537,7 @@ type gatewayBatchAccess struct {
}
var (
- errEmtpyRequest = errors.DefineInvalidArgument(
+ errEmptyRequest = errors.DefineInvalidArgument(
"empty_request",
"empty request",
)
@@ -555,7 +555,7 @@ func (gba *gatewayBatchAccess) AssertRights(
// Sanitize request.
required := req.Required.Unique()
if len(required.GetRights()) == 0 {
- return nil, errEmtpyRequest.New()
+ return nil, errEmptyRequest.New()
}
// Check that the request is checking only gateway rights.
diff --git a/pkg/identityserver/gateway_access_test.go b/pkg/identityserver/gateway_access_test.go
index a305e19729..b666c731e0 100644
--- a/pkg/identityserver/gateway_access_test.go
+++ b/pkg/identityserver/gateway_access_test.go
@@ -589,16 +589,30 @@ func TestGatewayBatchAccess(t *testing.T) {
locUserKey, _ := p.NewAPIKey(locUser.GetEntityIdentifiers(), ttnpb.Right_RIGHT_ALL)
locUserCreds := rpcCreds(locUserKey)
- testWithIdentityServer(t, func(is *IdentityServer, cc *grpc.ClientConn) {
- is.config.AdminRights.All = true
+ dualMembershipUser := p.NewUser()
+ dualMembershipUserKey, _ := p.NewAPIKey(dualMembershipUser.GetEntityIdentifiers(), ttnpb.Right_RIGHT_ALL)
+ dualMembershipUserCreds := rpcCreds(dualMembershipUserKey)
+ p.NewMembership(
+ dualMembershipUser.GetOrganizationOrUserIdentifiers(),
+ gtw3.GetEntityIdentifiers(),
+ ttnpb.Right_RIGHT_GATEWAY_ALL,
+ )
+ org1 := p.NewOrganization(dualMembershipUser.GetOrganizationOrUserIdentifiers())
+ p.NewMembership(
+ org1.GetOrganizationOrUserIdentifiers(),
+ gtw3.GetEntityIdentifiers(),
+ ttnpb.Right_RIGHT_GATEWAY_ALL,
+ )
+ testWithIdentityServer(t, func(is *IdentityServer, cc *grpc.ClientConn) {
reg := ttnpb.NewGatewayBatchAccessClient(cc)
for _, tc := range []struct {
- Name string
- Credentials grpc.CallOption
- Request *ttnpb.AssertGatewayRightsRequest
- ErrorAssertion func(error) bool
+ Name string
+ Credentials grpc.CallOption
+ Request *ttnpb.AssertGatewayRightsRequest
+ ErrorAssertion func(error) bool
+ LimitedAdminRights bool
}{
{
Name: "Empty request",
@@ -771,6 +785,20 @@ func TestGatewayBatchAccess(t *testing.T) {
Credentials: collaboratorCreds,
ErrorAssertion: errors.IsPermissionDenied,
},
+ {
+ Name: "Universal rights for admin",
+ Request: &ttnpb.AssertGatewayRightsRequest{
+ GatewayIds: []*ttnpb.GatewayIdentifiers{
+ gtw3.GetIds(),
+ },
+ Required: &ttnpb.Rights{
+ Rights: []ttnpb.Right{
+ ttnpb.Right_RIGHT_GATEWAY_SETTINGS_API_KEYS,
+ },
+ },
+ },
+ Credentials: adminCreds,
+ },
{
Name: "Limited rights for admin",
Request: &ttnpb.AssertGatewayRightsRequest{
@@ -783,8 +811,9 @@ func TestGatewayBatchAccess(t *testing.T) {
},
},
},
- Credentials: adminCreds,
- ErrorAssertion: errors.IsNotFound,
+ Credentials: adminCreds,
+ ErrorAssertion: errors.IsPermissionDenied,
+ LimitedAdminRights: true,
},
{
Name: "Read Stats Failure",
@@ -942,9 +971,25 @@ func TestGatewayBatchAccess(t *testing.T) {
},
Credentials: usr1Creds,
},
+ {
+ Name: "Dual membership user",
+ Request: &ttnpb.AssertGatewayRightsRequest{
+ GatewayIds: []*ttnpb.GatewayIdentifiers{
+ gtw3.GetIds(),
+ },
+ Required: &ttnpb.Rights{
+ Rights: []ttnpb.Right{
+ ttnpb.Right_RIGHT_GATEWAY_ALL,
+ },
+ },
+ },
+ Credentials: dualMembershipUserCreds,
+ },
} {
tc := tc
t.Run(tc.Name, func(t *testing.T) {
+ is.config.AdminRights.All = !tc.LimitedAdminRights
+
_, err := reg.AssertRights(ctx, tc.Request, tc.Credentials)
if err != nil {
if tc.ErrorAssertion == nil || !a.So(tc.ErrorAssertion(err), should.BeTrue) {
diff --git a/pkg/identityserver/identityserver.go b/pkg/identityserver/identityserver.go
index 896ed0d2a2..c068ae877b 100644
--- a/pkg/identityserver/identityserver.go
+++ b/pkg/identityserver/identityserver.go
@@ -88,14 +88,17 @@ func (is *IdentityServer) configFromContext(ctx context.Context) *Config {
// GenerateCSPString returns a Content-Security-Policy header value
// for OAuth and Account app template.
func GenerateCSPString(config *oauth.Config, nonce string) string {
+ baseURLs := webui.RewriteSchemes(
+ webui.WebsocketSchemeRewrites,
+ config.UI.StackConfig.IS.BaseURL,
+ )
return webui.ContentSecurityPolicy{
- ConnectionSource: []string{
+ ConnectionSource: append([]string{
"'self'",
- config.UI.StackConfig.IS.BaseURL,
config.UI.SentryDSN,
"gravatar.com",
"www.gravatar.com",
- },
+ }, baseURLs...),
StyleSource: []string{
"'self'",
config.UI.AssetsBaseURL,
diff --git a/pkg/identityserver/rights.go b/pkg/identityserver/rights.go
index 6850da8e7b..b021745dfd 100644
--- a/pkg/identityserver/rights.go
+++ b/pkg/identityserver/rights.go
@@ -20,7 +20,6 @@ import (
"go.thethings.network/lorawan-stack/v3/pkg/errors"
"go.thethings.network/lorawan-stack/v3/pkg/identityserver/store"
"go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
- "go.thethings.network/lorawan-stack/v3/pkg/unique"
)
func allPotentialRights(eIDs *ttnpb.EntityIdentifiers, rights *ttnpb.Rights) *ttnpb.Rights {
@@ -252,13 +251,16 @@ func (is *IdentityServer) assertGatewayRights( // nolint:gocyclo
return errInsufficientRights.New()
}
+ // If the caller has specified the identifiers multiple times, deduplicate them.
+ gtwIDs = uniqueIdentifiers(gtwIDs)
+
return is.store.Transact(ctx, func(ctx context.Context, st store.Store) error {
gtws, err := st.FindGateways(ctx, gtwIDs, []string{"ids", "status_public", "location_public"})
if err != nil {
return err
}
if len(gtws) != len(gtwIDs) {
- if is.IsAdmin(ctx) {
+ if authInfo.IsAdmin {
// Return the cause only to the admin.
// This follows the same logic as in ListRights.
return errSomeGatewaysNotFound.New()
@@ -289,21 +291,21 @@ func (is *IdentityServer) assertGatewayRights( // nolint:gocyclo
if bothStatsAndLocation {
for _, gtw := range gtws {
if gtw.StatusPublic && gtw.LocationPublic {
- publicGatewayIds[unique.ID(ctx, gtw.Ids)] = struct{}{}
+ publicGatewayIds[gtw.IDString()] = struct{}{}
}
}
} else {
if onlyPublicStats {
for _, gtw := range gtws {
if gtw.StatusPublic {
- publicGatewayIds[unique.ID(ctx, gtw.Ids)] = struct{}{}
+ publicGatewayIds[gtw.IDString()] = struct{}{}
}
}
}
if onlyPublicLocation {
for _, gtw := range gtws {
if gtw.LocationPublic {
- publicGatewayIds[unique.ID(ctx, gtw.Ids)] = struct{}{}
+ publicGatewayIds[gtw.IDString()] = struct{}{}
}
}
}
@@ -311,11 +313,19 @@ func (is *IdentityServer) assertGatewayRights( // nolint:gocyclo
entityIDs := make([]string, 0, len(gtwIDs))
for _, gtwID := range gtwIDs {
- if _, ok := publicGatewayIds[unique.ID(ctx, gtwID)]; ok {
+ if _, ok := publicGatewayIds[gtwID.IDString()]; ok {
continue
}
entityIDs = append(entityIDs, gtwID.GetEntityIdentifiers().IDString())
}
+ if len(entityIDs) == 0 {
+ return nil
+ }
+ if authInfo.IsAdmin {
+ if authInfo.GetUniversalRights().IncludesAll(requiredGatewayRights.GetRights()...) {
+ return nil
+ }
+ }
membershipChains, err := st.FindAccountMembershipChains(
ctx,
ouID,
@@ -325,19 +335,30 @@ func (is *IdentityServer) assertGatewayRights( // nolint:gocyclo
if err != nil {
return err
}
- if len(membershipChains) != len(entityIDs) {
- // Some memberships were not found.
- if is.IsAdmin(ctx) {
- return errSomeGatewaysNotFound.New()
- }
- return errInsufficientRights.New()
- }
+ entityRights := make(map[string]*ttnpb.Rights, len(membershipChains))
for _, chain := range membershipChains {
+ id := chain.EntityIdentifiers.IDString()
+ entityRights[id] = entityRights[id].Union(chain.GetRights())
+ }
+ for _, entityID := range entityIDs {
// Make sure that there are no extra rights requested.
- if !chain.GetRights().IncludesAll(requiredGatewayRights.GetRights()...) {
+ if !entityRights[entityID].IncludesAll(requiredGatewayRights.GetRights()...) {
return errInsufficientRights.New()
}
}
return nil
})
}
+
+func uniqueIdentifiers[T ttnpb.IDStringer](ids []T) []T {
+ m := make(map[string]struct{}, len(ids))
+ result := make([]T, 0, len(ids))
+ for _, id := range ids {
+ if _, ok := m[id.IDString()]; ok {
+ continue
+ }
+ m[id.IDString()] = struct{}{}
+ result = append(result, id)
+ }
+ return result
+}
diff --git a/pkg/messageprocessors/javascript/javascript.go b/pkg/messageprocessors/javascript/javascript.go
index bdf2b5e008..81219b288f 100644
--- a/pkg/messageprocessors/javascript/javascript.go
+++ b/pkg/messageprocessors/javascript/javascript.go
@@ -56,9 +56,10 @@ type encodeDownlinkOutput struct {
}
var (
- errInput = errors.DefineInvalidArgument("input", "invalid input")
- errOutput = errors.Define("output", "invalid output")
- errOutputErrors = errors.DefineAborted("output_errors", "{errors}")
+ errInput = errors.DefineInvalidArgument("input", "invalid input")
+ errOutput = errors.Define("output", "invalid output")
+ errOutputErrors = errors.DefineAborted("output_errors", "{errors}")
+ errOutputEncoding = errors.DefineInvalidArgument("output_encoding", "{errors}")
)
func wrapDownlinkEncoderScript(script string) string {
@@ -309,6 +310,10 @@ func (*host) decodeUplink(
if err != nil {
return errOutput.WithCause(err)
}
+ if errs := goproto.ValidateStruct(decodedPayload); len(errs) > 0 {
+ return errOutputEncoding.WithAttributes("errors", strings.Join(errs, ", "))
+ }
+
msg.DecodedPayload, msg.DecodedPayloadWarnings = decodedPayload, output.Decoded.Warnings
msg.NormalizedPayload, msg.NormalizedPayloadWarnings = nil, nil
@@ -380,14 +385,6 @@ func (*host) decodeUplink(
}
}
- // Roundtrip the message in order to convert special number values such as NaN and Infinity to their string form.
- // TODO: Clean up the message and emit warning (https://github.com/TheThingsNetwork/lorawan-stack/issues/6128).
- msg.DecodedPayload, err = structpb.NewStruct(decodedPayload.AsMap())
- if err != nil {
- return errOutput.WithCause(err)
- }
- msg.DecodedPayloadWarnings = append(msg.DecodedPayloadWarnings, goproto.ValidateStruct(decodedPayload)...)
-
return nil
}
@@ -487,16 +484,12 @@ func (*host) decodeDownlink(
if err != nil {
return errOutput.WithCause(err)
}
+ if errs := goproto.ValidateStruct(s); len(errs) > 0 {
+ return errOutputEncoding.WithAttributes("errors", strings.Join(errs, ", "))
+ }
+
msg.DecodedPayload = s
msg.DecodedPayloadWarnings = output.Warnings
- // Roundtrip the message in order to convert special number values such as NaN and Infinity to their string form.
- // TODO: Clean up the message and emit warning (https://github.com/TheThingsNetwork/lorawan-stack/issues/6128).
- msg.DecodedPayload, err = structpb.NewStruct(s.AsMap())
- if err != nil {
- return errOutput.WithCause(err)
- }
- msg.DecodedPayloadWarnings = append(msg.DecodedPayloadWarnings, goproto.ValidateStruct(s)...)
-
return nil
}
diff --git a/pkg/networkserver/downlink.go b/pkg/networkserver/downlink.go
index a2379869dc..686e6a23c4 100644
--- a/pkg/networkserver/downlink.go
+++ b/pkg/networkserver/downlink.go
@@ -35,6 +35,7 @@ import (
"go.thethings.network/lorawan-stack/v3/pkg/networkserver/mac"
"go.thethings.network/lorawan-stack/v3/pkg/packetbroker"
"go.thethings.network/lorawan-stack/v3/pkg/specification/macspec"
+ "go.thethings.network/lorawan-stack/v3/pkg/specification/relayspec"
"go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
"go.thethings.network/lorawan-stack/v3/pkg/types"
"go.thethings.network/lorawan-stack/v3/pkg/unique"
@@ -204,9 +205,10 @@ func (ns *NetworkServer) generateDataDownlink(ctx context.Context, dev *ttnpb.En
maxDownPayloadLen := maxDownLen
var (
- fPending bool
- genState generateDownlinkState
- cmdBuf []byte
+ fPending bool
+ genState generateDownlinkState
+ cmdBuf []byte
+ relayPayload []byte
)
if class == ttnpb.Class_CLASS_A {
spec := lorawan.DefaultMACCommands
@@ -238,6 +240,18 @@ func (ns *NetworkServer) generateDataDownlink(ctx context.Context, dev *ttnpb.En
dev.MacState.QueuedResponses = nil
dev.MacState.PendingRequests = dev.MacState.PendingRequests[:0]
+ if relayDownlink := dev.MacState.PendingRelayDownlink; relayDownlink != nil {
+ // NOTE: We attempt to enqueue the pending relay downlink if the already
+ // enqueued MAC command responses fit into FOpts and the relay payload
+ // is smaller than the remaining space.
+ queuedResponsesLen := maxDownPayloadLen - maxDownLen
+ relayPayloadLen := uint16(len(relayDownlink.RawPayload))
+ if queuedResponsesLen <= fOptsCapacity && relayPayloadLen <= maxDownLen {
+ relayPayload = relayDownlink.RawPayload
+ maxDownLen = fOptsCapacity - queuedResponsesLen
+ }
+ }
+
enqueuers := []func(context.Context, *ttnpb.EndDevice, uint16, uint16) mac.EnqueueState{
mac.EnqueueDutyCycleReq,
func(ctx context.Context, dev *ttnpb.EndDevice, maxDownLen uint16, maxUpLen uint16) mac.EnqueueState {
@@ -273,6 +287,13 @@ func (ns *NetworkServer) generateDataDownlink(ctx context.Context, dev *ttnpb.En
func(ctx context.Context, dev *ttnpb.EndDevice, maxDownLen uint16, maxUpLen uint16) mac.EnqueueState {
return mac.EnqueueDevStatusReq(ctx, dev, maxDownLen, maxUpLen, ns.defaultMACSettings, transmitAt)
},
+ mac.EnqueueRelayConfReq,
+ mac.EnqueueRelayEndDeviceConfReq,
+ func(ctx context.Context, dev *ttnpb.EndDevice, maxDownLen uint16, maxUpLen uint16) mac.EnqueueState {
+ return mac.EnqueueRelayUpdateUplinkListReq(ctx, dev, maxDownLen, maxUpLen, ns.relayKeyService())
+ },
+ mac.EnqueueRelayCtrlUplinkListReq,
+ mac.EnqueueRelayConfigureFwdLimitReq,
}
for _, f := range enqueuers {
@@ -302,6 +323,10 @@ func (ns *NetworkServer) generateDataDownlink(ctx context.Context, dev *ttnpb.En
cmdBuf = b
}
ctx = log.NewContext(ctx, logger)
+
+ for i, req := range dev.MacState.PendingRequests {
+ dev.MacState.PendingRequests[i] = req.Sanitized()
+ }
}
var needsDownlink bool
@@ -347,7 +372,7 @@ func (ns *NetworkServer) generateDataDownlink(ctx context.Context, dev *ttnpb.En
ctx = log.NewContext(ctx, logger)
cmdsInFOpts := len(cmdBuf) <= fOptsCapacity
- if cmdsInFOpts {
+ if cmdsInFOpts && len(relayPayload) == 0 {
appDowns := dev.Session.QueuedApplicationDownlinks[:0:0]
outer:
for i, down := range dev.Session.QueuedApplicationDownlinks {
@@ -465,7 +490,7 @@ func (ns *NetworkServer) generateDataDownlink(ctx context.Context, dev *ttnpb.En
mType = ttnpb.MType_CONFIRMED_DOWN
}
- case len(cmdBuf) > 0, needsDownlink:
+ case len(cmdBuf) > 0, len(relayPayload) > 0, needsDownlink:
pld.FullFCnt = func() uint32 {
for i := len(dev.MacState.RecentDownlinks) - 1; i >= 0; i-- {
down := dev.MacState.RecentDownlinks[i]
@@ -495,6 +520,25 @@ func (ns *NetworkServer) generateDataDownlink(ctx context.Context, dev *ttnpb.En
}
return 0
}()
+ if len(relayPayload) > 0 {
+ logger.Debug("Add relay downlink to buffer")
+ if dev.GetSession().GetKeys().GetNwkSEncKey() == nil {
+ return nil, genState, errUnknownNwkSEncKey.New()
+ }
+ key, err := cryptoutil.UnwrapAES128Key(ctx, dev.Session.Keys.NwkSEncKey, ns.KeyService())
+ if err != nil {
+ logger.WithField("kek_label", dev.Session.Keys.NwkSEncKey.KekLabel).WithError(err).Warn("Failed to unwrap NwkSEncKey")
+ return nil, genState, err
+ }
+ encPayload, err := crypto.EncryptDownlink(
+ key, types.MustDevAddr(dev.Session.DevAddr).OrZero(), pld.FullFCnt, relayPayload,
+ )
+ if err != nil {
+ return nil, genState, errEncryptMAC.WithCause(err)
+ }
+ pld.FPort = relayspec.FPort
+ pld.FrmPayload = encPayload
+ }
default:
return nil, genState, errNoDownlink.New()
@@ -694,6 +738,9 @@ func downlinkPathsFromMetadata(
case md.PacketBroker != nil:
path.GatewayIdentifiers = packetbroker.GatewayIdentifiers
tail = append(tail, path)
+ case md.Relay != nil:
+ path.GatewayIdentifiers = relayspec.GatewayIdentifiers
+ tail = append(tail, path)
default:
path.GatewayIdentifiers = md.GatewayIds
switch md.DownlinkPathConstraint {
@@ -891,6 +938,12 @@ func (ns *NetworkServer) scheduleDownlinkByPaths(
continue
}
target = &packetBrokerDownlinkTarget{peer: peer}
+ case proto.Equal(path.GatewayIdentifiers, relayspec.GatewayIdentifiers):
+ target = &relayDownlinkTarget{
+ servedEndDeviceIDs: req.EndDeviceIdentifiers,
+ servedSessionKeyID: req.SessionKeyID,
+ patchServingDevice: ns.relayPatchServingDevice,
+ }
default:
logger := logger.WithFields(log.Fields(
"target", "gateway_server",
@@ -1398,10 +1451,12 @@ func (ns *NetworkServer) attemptClassADataDownlink(ctx context.Context, dev *ttn
ctx = events.ContextWithCorrelationID(ctx, slot.Uplink.CorrelationIds...)
if !dev.MacState.RxWindowsAvailable {
log.FromContext(ctx).Error("RX windows not available, skip class A downlink slot")
+ dev.MacState.PendingRelayDownlink = nil
dev.MacState.QueuedResponses = nil
dev.MacState.RxWindowsAvailable = false
return downlinkAttemptResult{
SetPaths: []string{
+ "mac_state.pending_relay_downlink",
"mac_state.queued_responses",
"mac_state.rx_windows_available",
},
@@ -1432,10 +1487,12 @@ func (ns *NetworkServer) attemptClassADataDownlink(ctx context.Context, dev *ttn
)
queuedEvents = append(queuedEvents, rxParametersEvents...)
if err != nil {
+ dev.MacState.PendingRelayDownlink = nil
dev.MacState.QueuedResponses = nil
dev.MacState.RxWindowsAvailable = false
return downlinkAttemptResult{
SetPaths: []string{
+ "mac_state.pending_relay_downlink",
"mac_state.queued_responses",
"mac_state.rx_windows_available",
},
@@ -1448,10 +1505,12 @@ func (ns *NetworkServer) attemptClassADataDownlink(ctx context.Context, dev *ttn
attemptRX2 = rxParameters.attemptRX2
)
if !attemptRX1 && !attemptRX2 {
+ dev.MacState.PendingRelayDownlink = nil
dev.MacState.QueuedResponses = nil
dev.MacState.RxWindowsAvailable = false
return downlinkAttemptResult{
SetPaths: []string{
+ "mac_state.pending_relay_downlink",
"mac_state.queued_responses",
"mac_state.rx_windows_available",
},
@@ -1496,11 +1555,13 @@ func (ns *NetworkServer) attemptClassADataDownlink(ctx context.Context, dev *ttn
attemptRX2 = len(genDown.RawPayload) <= int(rxParameters.rx2MaxMACPayloadSize)+5
if !attemptRX1 && !attemptRX2 {
log.FromContext(ctx).Error("Generated downlink payload size does not fit neither RX1, nor RX2, skip class A downlink slot")
+ dev.MacState.PendingRelayDownlink = nil
dev.MacState.QueuedResponses = nil
dev.MacState.RxWindowsAvailable = false
return downlinkAttemptResult{
DownlinkTaskUpdateStrategy: nextDownlinkTask,
SetPaths: ttnpb.AddFields(sets,
+ "mac_state.pending_relay_downlink",
"mac_state.queued_responses",
"mac_state.rx_windows_available",
),
@@ -1554,10 +1615,12 @@ func (ns *NetworkServer) attemptClassADataDownlink(ctx context.Context, dev *ttn
if genState.ApplicationDownlink != nil {
dev.Session.QueuedApplicationDownlinks = append([]*ttnpb.ApplicationDownlink{genState.ApplicationDownlink}, dev.Session.QueuedApplicationDownlinks...)
}
+ dev.MacState.PendingRelayDownlink = nil
dev.MacState.QueuedResponses = nil
dev.MacState.RxWindowsAvailable = false
return downlinkAttemptResult{
SetPaths: ttnpb.AddFields(sets,
+ "mac_state.pending_relay_downlink",
"mac_state.queued_responses",
"mac_state.rx_windows_available",
),
@@ -1572,11 +1635,13 @@ func (ns *NetworkServer) attemptClassADataDownlink(ctx context.Context, dev *ttn
dev.Session.QueuedApplicationDownlinks = dev.Session.QueuedApplicationDownlinks[:0:0]
}
recordDataDownlink(dev, genState, genDown.NeedsMACAnswer, down, ns.defaultMACSettings)
+ dev.MacState.PendingRelayDownlink = nil
return downlinkAttemptResult{
SetPaths: ttnpb.AddFields(sets,
"mac_state.last_confirmed_downlink_at",
"mac_state.last_downlink_at",
"mac_state.pending_application_downlink",
+ "mac_state.pending_relay_downlink",
"mac_state.pending_requests",
"mac_state.queued_responses",
"mac_state.recent_downlinks",
@@ -1979,6 +2044,7 @@ func (ns *NetworkServer) processDownlinkTask(ctx context.Context, consumerID str
&scheduleRequest{
TxRequest: req,
EndDeviceIdentifiers: dev.Ids,
+ SessionKeyID: dev.PendingMacState.QueuedJoinAccept.Keys.SessionKeyId,
RawPayload: dev.PendingMacState.QueuedJoinAccept.Payload,
Payload: &ttnpb.Message{
MHdr: &ttnpb.MHDR{
diff --git a/pkg/networkserver/grpc.go b/pkg/networkserver/grpc.go
index dac4c4d99c..e49535dfed 100644
--- a/pkg/networkserver/grpc.go
+++ b/pkg/networkserver/grpc.go
@@ -79,6 +79,8 @@ func (ns *NetworkServer) GetDefaultMACSettings(ctx context.Context, req *ttnpb.G
UplinkDwellTime: mac.DeviceUplinkDwellTime(nil, phy, ns.defaultMACSettings),
DownlinkDwellTime: mac.DeviceDownlinkDwellTime(nil, phy, ns.defaultMACSettings),
ScheduleDownlinks: &ttnpb.BoolValue{Value: mac.DeviceScheduleDownlinks(nil, ns.defaultMACSettings)},
+ Relay: mac.DeviceDefaultRelayParameters(nil, ns.defaultMACSettings),
+ DesiredRelay: mac.DeviceDesiredRelayParameters(nil, ns.defaultMACSettings),
}
return settings, nil
}
diff --git a/pkg/networkserver/grpc_asns.go b/pkg/networkserver/grpc_asns.go
index a91accfcac..acd2ee4236 100644
--- a/pkg/networkserver/grpc_asns.go
+++ b/pkg/networkserver/grpc_asns.go
@@ -40,14 +40,11 @@ type ApplicationUplinkQueue interface {
// Implementations must ensure that Add returns fast.
Add(ctx context.Context, ups ...*ttnpb.ApplicationUp) error
- // Dispatch dispatches the tasks in the queue.
- Dispatch(ctx context.Context, consumerID string) error
-
- // PopApplication calls f on the most recent application uplink task in the schedule, for which timestamp is in range [0, time.Now()],
- // if such is available, otherwise it blocks until it is.
+ // Pop groups up to limit most recent application uplinks in the queue
+ // by their application ID and calls f on each group.
// Context passed to f must be derived from ctx.
// Implementations must respect ctx.Done() value on best-effort basis.
- Pop(ctx context.Context, consumerID string, f func(context.Context, *ttnpb.ApplicationIdentifiers, ApplicationUplinkQueueDrainFunc) (time.Time, error)) error
+ Pop(ctx context.Context, consumerID string, limit int, f func(context.Context, []*ttnpb.ApplicationUp) error) error
}
func applicationJoinAcceptWithoutAppSKey(pld *ttnpb.ApplicationJoinAccept) *ttnpb.ApplicationJoinAccept {
@@ -99,29 +96,23 @@ func (ns *NetworkServer) createProcessApplicationUplinkTask(consumerID string) f
}
func (ns *NetworkServer) processApplicationUplinkTask(ctx context.Context, consumerID string) error {
- return ns.applicationUplinks.Pop(ctx, consumerID, func(ctx context.Context, appID *ttnpb.ApplicationIdentifiers, drain ApplicationUplinkQueueDrainFunc) (time.Time, error) {
- conn, err := ns.GetPeerConn(ctx, ttnpb.ClusterRole_APPLICATION_SERVER, nil)
- if err != nil {
- log.FromContext(ctx).WithError(err).Warn("Failed to get Application Server peer")
- return time.Now().Add(applicationUplinkTaskRetryInterval), nil
- }
-
- cl := ttnpb.NewNsAsClient(conn)
- var sendErr bool
- if err := drain(applicationUplinkLimit, func(ups ...*ttnpb.ApplicationUp) error {
- err := ns.sendApplicationUplinks(ctx, cl, ups...)
+ return ns.applicationUplinks.Pop(ctx, consumerID, applicationUplinkLimit,
+ func(ctx context.Context, ups []*ttnpb.ApplicationUp) error {
+ conn, err := ns.GetPeerConn(ctx, ttnpb.ClusterRole_APPLICATION_SERVER, nil)
if err != nil {
- sendErr = true
+ log.FromContext(ctx).WithError(err).Warn("Failed to get Application Server peer")
+ return err
}
- return err
- }); err != nil {
- if !sendErr {
- log.FromContext(ctx).WithError(err).Error("Failed to drain application uplinks")
+ cl := ttnpb.NewNsAsClient(conn)
+ if err := ns.sendApplicationUplinks(ctx, cl, ups...); err != nil {
+ log.FromContext(ctx).WithError(err).Warn("Failed to send application uplinks")
+ if !retryableUplinkError(err) {
+ return nil
+ }
+ return err
}
- return time.Now().Add(applicationUplinkTaskRetryInterval), nil
- }
- return time.Time{}, nil
- })
+ return nil
+ })
}
func minAFCntDown(session *ttnpb.Session, macState *ttnpb.MACState) (uint32, error) {
diff --git a/pkg/networkserver/grpc_deviceregistry.go b/pkg/networkserver/grpc_deviceregistry.go
index c0e84fcfc9..7861882413 100644
--- a/pkg/networkserver/grpc_deviceregistry.go
+++ b/pkg/networkserver/grpc_deviceregistry.go
@@ -613,6 +613,29 @@ var (
"pending_mac_state.current_parameters.ping_slot_frequency",
"pending_mac_state.current_parameters.rejoin_count_periodicity",
"pending_mac_state.current_parameters.rejoin_time_periodicity",
+ "pending_mac_state.current_parameters.relay.mode.served.backoff",
+ "pending_mac_state.current_parameters.relay.mode.served.mode.always",
+ "pending_mac_state.current_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "pending_mac_state.current_parameters.relay.mode.served.mode.end_device_controlled",
+ "pending_mac_state.current_parameters.relay.mode.served.second_channel.ack_offset",
+ "pending_mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index",
+ "pending_mac_state.current_parameters.relay.mode.served.second_channel.frequency",
+ "pending_mac_state.current_parameters.relay.mode.served.serving_device_id",
+ "pending_mac_state.current_parameters.relay.mode.serving.cad_periodicity",
+ "pending_mac_state.current_parameters.relay.mode.serving.default_channel_index",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.reset_behavior",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "pending_mac_state.current_parameters.relay.mode.serving.second_channel.ack_offset",
+ "pending_mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "pending_mac_state.current_parameters.relay.mode.serving.second_channel.frequency",
+ "pending_mac_state.current_parameters.relay.mode.serving.uplink_forwarding_rules",
"pending_mac_state.current_parameters.rx1_data_rate_offset",
"pending_mac_state.current_parameters.rx1_delay",
"pending_mac_state.current_parameters.rx2_data_rate_index",
@@ -632,6 +655,29 @@ var (
"pending_mac_state.desired_parameters.ping_slot_frequency",
"pending_mac_state.desired_parameters.rejoin_count_periodicity",
"pending_mac_state.desired_parameters.rejoin_time_periodicity",
+ "pending_mac_state.desired_parameters.relay.mode.served.backoff",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode.always",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode.end_device_controlled",
+ "pending_mac_state.desired_parameters.relay.mode.served.second_channel.ack_offset",
+ "pending_mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index",
+ "pending_mac_state.desired_parameters.relay.mode.served.second_channel.frequency",
+ "pending_mac_state.desired_parameters.relay.mode.served.serving_device_id",
+ "pending_mac_state.desired_parameters.relay.mode.serving.cad_periodicity",
+ "pending_mac_state.desired_parameters.relay.mode.serving.default_channel_index",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.reset_behavior",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "pending_mac_state.desired_parameters.relay.mode.serving.second_channel.ack_offset",
+ "pending_mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "pending_mac_state.desired_parameters.relay.mode.serving.second_channel.frequency",
+ "pending_mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules",
"pending_mac_state.desired_parameters.rx1_data_rate_offset",
"pending_mac_state.desired_parameters.rx1_delay",
"pending_mac_state.desired_parameters.rx2_data_rate_index",
@@ -697,7 +743,99 @@ var (
ifNotZeroThenZeroFields = map[string][]string{
"multicast": {
+ "mac_settings.desired_relay.mode.served.backoff",
+ "mac_settings.desired_relay.mode.served.mode.always",
+ "mac_settings.desired_relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_settings.desired_relay.mode.served.mode.end_device_controlled",
+ "mac_settings.desired_relay.mode.served.second_channel.ack_offset",
+ "mac_settings.desired_relay.mode.served.second_channel.data_rate_index",
+ "mac_settings.desired_relay.mode.served.second_channel.frequency",
+ "mac_settings.desired_relay.mode.served.serving_device_id",
+ "mac_settings.desired_relay.mode.serving.cad_periodicity",
+ "mac_settings.desired_relay.mode.serving.default_channel_index",
+ "mac_settings.desired_relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_settings.desired_relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_settings.desired_relay.mode.serving.limits.notifications.bucket_size",
+ "mac_settings.desired_relay.mode.serving.limits.notifications.reload_rate",
+ "mac_settings.desired_relay.mode.serving.limits.overall.bucket_size",
+ "mac_settings.desired_relay.mode.serving.limits.overall.reload_rate",
+ "mac_settings.desired_relay.mode.serving.limits.reset_behavior",
+ "mac_settings.desired_relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_settings.desired_relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_settings.desired_relay.mode.serving.second_channel.ack_offset",
+ "mac_settings.desired_relay.mode.serving.second_channel.data_rate_index",
+ "mac_settings.desired_relay.mode.serving.second_channel.frequency",
+ "mac_settings.desired_relay.mode.serving.uplink_forwarding_rules",
+ "mac_settings.relay.mode.served.backoff",
+ "mac_settings.relay.mode.served.mode.always",
+ "mac_settings.relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_settings.relay.mode.served.mode.end_device_controlled",
+ "mac_settings.relay.mode.served.second_channel.ack_offset",
+ "mac_settings.relay.mode.served.second_channel.data_rate_index",
+ "mac_settings.relay.mode.served.second_channel.frequency",
+ "mac_settings.relay.mode.served.serving_device_id",
+ "mac_settings.relay.mode.serving.cad_periodicity",
+ "mac_settings.relay.mode.serving.default_channel_index",
+ "mac_settings.relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_settings.relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_settings.relay.mode.serving.limits.notifications.bucket_size",
+ "mac_settings.relay.mode.serving.limits.notifications.reload_rate",
+ "mac_settings.relay.mode.serving.limits.overall.bucket_size",
+ "mac_settings.relay.mode.serving.limits.overall.reload_rate",
+ "mac_settings.relay.mode.serving.limits.reset_behavior",
+ "mac_settings.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_settings.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_settings.relay.mode.serving.second_channel.ack_offset",
+ "mac_settings.relay.mode.serving.second_channel.data_rate_index",
+ "mac_settings.relay.mode.serving.second_channel.frequency",
+ "mac_settings.relay.mode.serving.uplink_forwarding_rules",
"mac_settings.schedule_downlinks.value",
+ "mac_state.current_parameters.relay.mode.served.backoff",
+ "mac_state.current_parameters.relay.mode.served.mode.always",
+ "mac_state.current_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_state.current_parameters.relay.mode.served.mode.end_device_controlled",
+ "mac_state.current_parameters.relay.mode.served.second_channel.ack_offset",
+ "mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index",
+ "mac_state.current_parameters.relay.mode.served.second_channel.frequency",
+ "mac_state.current_parameters.relay.mode.served.serving_device_id",
+ "mac_state.current_parameters.relay.mode.serving.cad_periodicity",
+ "mac_state.current_parameters.relay.mode.serving.default_channel_index",
+ "mac_state.current_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.limits.reset_behavior",
+ "mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.second_channel.ack_offset",
+ "mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "mac_state.current_parameters.relay.mode.serving.second_channel.frequency",
+ "mac_state.current_parameters.relay.mode.serving.uplink_forwarding_rules",
+ "mac_state.desired_parameters.relay.mode.served.backoff",
+ "mac_state.desired_parameters.relay.mode.served.mode.always",
+ "mac_state.desired_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_state.desired_parameters.relay.mode.served.mode.end_device_controlled",
+ "mac_state.desired_parameters.relay.mode.served.second_channel.ack_offset",
+ "mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index",
+ "mac_state.desired_parameters.relay.mode.served.second_channel.frequency",
+ "mac_state.desired_parameters.relay.mode.served.serving_device_id",
+ "mac_state.desired_parameters.relay.mode.serving.cad_periodicity",
+ "mac_state.desired_parameters.relay.mode.serving.default_channel_index",
+ "mac_state.desired_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.limits.reset_behavior",
+ "mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel.ack_offset",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel.frequency",
+ "mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules",
"mac_state.last_adr_change_f_cnt_up",
"mac_state.last_confirmed_downlink_at",
"mac_state.last_dev_status_f_cnt_up",
@@ -905,6 +1043,28 @@ var (
"mac_state.current_parameters.ping_slot_frequency",
"mac_state.current_parameters.rejoin_count_periodicity",
"mac_state.current_parameters.rejoin_time_periodicity",
+ "mac_state.current_parameters.relay.mode.served.backoff",
+ "mac_state.current_parameters.relay.mode.served.mode.always",
+ "mac_state.current_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_state.current_parameters.relay.mode.served.mode.end_device_controlled",
+ "mac_state.current_parameters.relay.mode.served.second_channel.ack_offset",
+ "mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index",
+ "mac_state.current_parameters.relay.mode.served.second_channel.frequency",
+ "mac_state.current_parameters.relay.mode.serving.cad_periodicity",
+ "mac_state.current_parameters.relay.mode.serving.default_channel_index",
+ "mac_state.current_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.limits.reset_behavior",
+ "mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.second_channel.ack_offset",
+ "mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "mac_state.current_parameters.relay.mode.serving.second_channel.frequency",
+ "mac_state.current_parameters.relay.mode.serving.uplink_forwarding_rules",
"mac_state.current_parameters.rx1_data_rate_offset",
"mac_state.current_parameters.rx1_delay",
"mac_state.current_parameters.rx2_data_rate_index",
@@ -924,6 +1084,28 @@ var (
"mac_state.desired_parameters.ping_slot_frequency",
"mac_state.desired_parameters.rejoin_count_periodicity",
"mac_state.desired_parameters.rejoin_time_periodicity",
+ "mac_state.desired_parameters.relay.mode.served.backoff",
+ "mac_state.desired_parameters.relay.mode.served.mode.always",
+ "mac_state.desired_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_state.desired_parameters.relay.mode.served.mode.end_device_controlled",
+ "mac_state.desired_parameters.relay.mode.served.second_channel.ack_offset",
+ "mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index",
+ "mac_state.desired_parameters.relay.mode.served.second_channel.frequency",
+ "mac_state.desired_parameters.relay.mode.serving.cad_periodicity",
+ "mac_state.desired_parameters.relay.mode.serving.default_channel_index",
+ "mac_state.desired_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.limits.reset_behavior",
+ "mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel.ack_offset",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel.frequency",
+ "mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules",
"mac_state.desired_parameters.rx1_data_rate_offset",
"mac_state.desired_parameters.rx1_delay",
"mac_state.desired_parameters.rx2_data_rate_index",
@@ -948,40 +1130,39 @@ var (
legacyADRSettingsFields = []string{
"mac_settings.adr_margin",
- "mac_settings.use_adr",
"mac_settings.use_adr.value",
+ "mac_settings.use_adr",
}
adrSettingsFields = []string{
- "mac_settings.adr",
- "mac_settings.adr.mode",
"mac_settings.adr.mode.disabled",
- "mac_settings.adr.mode.dynamic",
- "mac_settings.adr.mode.dynamic.channel_steering",
- "mac_settings.adr.mode.dynamic.channel_steering.mode",
"mac_settings.adr.mode.dynamic.channel_steering.mode.disabled",
"mac_settings.adr.mode.dynamic.channel_steering.mode.lora_narrow",
+ "mac_settings.adr.mode.dynamic.channel_steering.mode",
+ "mac_settings.adr.mode.dynamic.channel_steering",
"mac_settings.adr.mode.dynamic.margin",
- "mac_settings.adr.mode.dynamic.max_data_rate_index",
"mac_settings.adr.mode.dynamic.max_data_rate_index.value",
+ "mac_settings.adr.mode.dynamic.max_data_rate_index",
"mac_settings.adr.mode.dynamic.max_nb_trans",
"mac_settings.adr.mode.dynamic.max_tx_power_index",
- "mac_settings.adr.mode.dynamic.min_data_rate_index",
"mac_settings.adr.mode.dynamic.min_data_rate_index.value",
+ "mac_settings.adr.mode.dynamic.min_data_rate_index",
"mac_settings.adr.mode.dynamic.min_nb_trans",
"mac_settings.adr.mode.dynamic.min_tx_power_index",
- "mac_settings.adr.mode.static",
+ "mac_settings.adr.mode.dynamic",
"mac_settings.adr.mode.static.data_rate_index",
"mac_settings.adr.mode.static.nb_trans",
"mac_settings.adr.mode.static.tx_power_index",
+ "mac_settings.adr.mode.static",
+ "mac_settings.adr.mode",
+ "mac_settings.adr",
}
dynamicADRSettingsFields = []string{
- "mac_settings.adr.mode.dynamic",
- "mac_settings.adr.mode.dynamic.channel_steering",
- "mac_settings.adr.mode.dynamic.channel_steering.mode",
"mac_settings.adr.mode.dynamic.channel_steering.mode.disabled",
"mac_settings.adr.mode.dynamic.channel_steering.mode.lora_narrow",
+ "mac_settings.adr.mode.dynamic.channel_steering.mode",
+ "mac_settings.adr.mode.dynamic.channel_steering",
"mac_settings.adr.mode.dynamic.margin",
"mac_settings.adr.mode.dynamic.max_data_rate_index.value",
"mac_settings.adr.mode.dynamic.max_nb_trans",
@@ -989,6 +1170,7 @@ var (
"mac_settings.adr.mode.dynamic.min_data_rate_index.value",
"mac_settings.adr.mode.dynamic.min_nb_trans",
"mac_settings.adr.mode.dynamic.min_tx_power_index",
+ "mac_settings.adr.mode.dynamic",
}
)
@@ -1244,55 +1426,73 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest
if st.HasSetField(
"frequency_plan_id",
"lorawan_phy_version",
- "mac_settings.adr",
- "mac_settings.adr.mode",
"mac_settings.adr.mode.disabled",
- "mac_settings.adr.mode.dynamic",
- "mac_settings.adr.mode.dynamic.channel_steering",
- "mac_settings.adr.mode.dynamic.channel_steering.mode",
"mac_settings.adr.mode.dynamic.channel_steering.mode.disabled",
"mac_settings.adr.mode.dynamic.channel_steering.mode.lora_narrow",
+ "mac_settings.adr.mode.dynamic.channel_steering.mode",
+ "mac_settings.adr.mode.dynamic.channel_steering",
"mac_settings.adr.mode.dynamic.margin",
- "mac_settings.adr.mode.dynamic.max_data_rate_index",
"mac_settings.adr.mode.dynamic.max_data_rate_index.value",
+ "mac_settings.adr.mode.dynamic.max_data_rate_index",
"mac_settings.adr.mode.dynamic.max_nb_trans",
"mac_settings.adr.mode.dynamic.max_tx_power_index",
- "mac_settings.adr.mode.dynamic.min_data_rate_index",
"mac_settings.adr.mode.dynamic.min_data_rate_index.value",
+ "mac_settings.adr.mode.dynamic.min_data_rate_index",
"mac_settings.adr.mode.dynamic.min_nb_trans",
"mac_settings.adr.mode.dynamic.min_tx_power_index",
- "mac_settings.adr.mode.static",
+ "mac_settings.adr.mode.dynamic",
"mac_settings.adr.mode.static.data_rate_index",
"mac_settings.adr.mode.static.nb_trans",
"mac_settings.adr.mode.static.tx_power_index",
+ "mac_settings.adr.mode.static",
+ "mac_settings.adr.mode",
+ "mac_settings.adr",
+ "mac_settings.desired_ping_slot_data_rate_index.value",
+ "mac_settings.desired_relay.mode.served.second_channel.data_rate_index",
+ "mac_settings.desired_relay.mode.serving.default_channel_index",
+ "mac_settings.desired_relay.mode.serving.second_channel.data_rate_index",
+ "mac_settings.desired_rx2_data_rate_index.value",
+ "mac_settings.downlink_dwell_time.value",
"mac_settings.factory_preset_frequencies",
+ "mac_settings.ping_slot_data_rate_index.value",
"mac_settings.ping_slot_frequency.value",
- "mac_settings.use_adr.value",
+ "mac_settings.relay.mode.served.second_channel.data_rate_index",
+ "mac_settings.relay.mode.serving.default_channel_index",
+ "mac_settings.relay.mode.serving.second_channel.data_rate_index",
"mac_settings.rx2_data_rate_index.value",
- "mac_settings.desired_rx2_data_rate_index.value",
- "mac_settings.ping_slot_data_rate_index.value",
- "mac_settings.desired_ping_slot_data_rate_index.value",
"mac_settings.uplink_dwell_time.value",
- "mac_settings.downlink_dwell_time.value",
+ "mac_settings.use_adr.value",
"mac_state.current_parameters.adr_data_rate_index",
"mac_state.current_parameters.adr_tx_power_index",
"mac_state.current_parameters.channels",
"mac_state.current_parameters.ping_slot_data_rate_index_value.value",
+ "mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index",
+ "mac_state.current_parameters.relay.mode.serving.default_channel_index",
+ "mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index",
"mac_state.current_parameters.rx2_data_rate_index",
"mac_state.desired_parameters.adr_data_rate_index",
"mac_state.desired_parameters.adr_tx_power_index",
"mac_state.desired_parameters.channels",
"mac_state.desired_parameters.ping_slot_data_rate_index_value.value",
+ "mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index",
+ "mac_state.desired_parameters.relay.mode.serving.default_channel_index",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index",
"mac_state.desired_parameters.rx2_data_rate_index",
"pending_mac_state.current_parameters.adr_data_rate_index",
"pending_mac_state.current_parameters.adr_tx_power_index",
"pending_mac_state.current_parameters.channels",
"pending_mac_state.current_parameters.ping_slot_data_rate_index_value.value",
+ "pending_mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index",
+ "pending_mac_state.current_parameters.relay.mode.serving.default_channel_index",
+ "pending_mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index",
"pending_mac_state.current_parameters.rx2_data_rate_index",
"pending_mac_state.desired_parameters.adr_data_rate_index",
"pending_mac_state.desired_parameters.adr_tx_power_index",
"pending_mac_state.desired_parameters.channels",
"pending_mac_state.desired_parameters.ping_slot_data_rate_index_value.value",
+ "pending_mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index",
+ "pending_mac_state.desired_parameters.relay.mode.serving.default_channel_index",
+ "pending_mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index",
"pending_mac_state.desired_parameters.rx2_data_rate_index",
"supports_class_b",
) {
@@ -1333,18 +1533,8 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest
"frequency_plan_id",
"lorawan_phy_version",
)
-
- hasSetFieldWithFallback := func(field, fallbackField string) (fieldToRetrieve string, validate bool) {
- if st.HasSetField(field) {
- return field, true
- }
- return fallbackField, hasPHYUpdate
- }
hasSetField := func(field string) (fieldToRetrieve string, validate bool) {
- return hasSetFieldWithFallback(field, field)
- }
- hasSetADRField := func(field string) (fieldToRetrieve string, validate bool) {
- return hasSetFieldWithFallback(field, "mac_settings.adr.mode")
+ return field, st.HasSetField(field) || hasPHYUpdate
}
setFields := func(fields ...string) []string {
@@ -1449,7 +1639,61 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest
return nil, err
}
}
- if field, validate := hasSetADRField("mac_settings.adr.mode.dynamic.max_data_rate_index.value"); validate {
+ if field, validate := hasSetField("mac_settings.desired_relay.mode.served.second_channel.data_rate_index"); validate {
+ if err := st.WithField(func(dev *ttnpb.EndDevice) error {
+ return withPHY(func(phy *band.Band, _ *frequencyplans.FrequencyPlan) error {
+ if dev.GetMacSettings().GetDesiredRelay().GetServed().GetSecondChannel() == nil {
+ return nil
+ }
+ _, ok := phy.DataRates[dev.MacSettings.DesiredRelay.GetServed().SecondChannel.DataRateIndex]
+ if !ok {
+ return newInvalidFieldValueError(field)
+ }
+ return nil
+ })
+ },
+ field,
+ ); err != nil {
+ return nil, err
+ }
+ }
+ if field, validate := hasSetField("mac_settings.desired_relay.mode.serving.default_channel_index"); validate {
+ if err := st.WithField(func(dev *ttnpb.EndDevice) error {
+ return withPHY(func(phy *band.Band, _ *frequencyplans.FrequencyPlan) error {
+ if dev.GetMacSettings().GetDesiredRelay().GetServing() == nil {
+ return nil
+ }
+ chIdx := dev.MacSettings.DesiredRelay.GetServing().DefaultChannelIndex
+ if chIdx >= uint32(len(phy.Relay.WORChannels)) {
+ return newInvalidFieldValueError(field)
+ }
+ return nil
+ })
+ },
+ field,
+ ); err != nil {
+ return nil, err
+ }
+ }
+ if field, validate := hasSetField("mac_settings.desired_relay.mode.serving.second_channel.data_rate_index"); validate {
+ if err := st.WithField(func(dev *ttnpb.EndDevice) error {
+ return withPHY(func(phy *band.Band, _ *frequencyplans.FrequencyPlan) error {
+ if dev.GetMacSettings().GetDesiredRelay().GetServing().GetSecondChannel() == nil {
+ return nil
+ }
+ _, ok := phy.DataRates[dev.MacSettings.DesiredRelay.GetServing().SecondChannel.DataRateIndex]
+ if !ok {
+ return newInvalidFieldValueError(field)
+ }
+ return nil
+ })
+ },
+ field,
+ ); err != nil {
+ return nil, err
+ }
+ }
+ if field, validate := hasSetField("mac_settings.adr.mode.dynamic.max_data_rate_index.value"); validate {
if err := st.WithField(func(dev *ttnpb.EndDevice) error {
return withPHY(func(phy *band.Band, _ *frequencyplans.FrequencyPlan) error {
if dev.GetMacSettings().GetAdr().GetDynamic().GetMaxDataRateIndex() == nil {
@@ -1468,7 +1712,7 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest
return nil, err
}
}
- if field, validate := hasSetADRField("mac_settings.adr.mode.dynamic.min_data_rate_index.value"); validate {
+ if field, validate := hasSetField("mac_settings.adr.mode.dynamic.min_data_rate_index.value"); validate {
if err := st.WithField(func(dev *ttnpb.EndDevice) error {
return withPHY(func(phy *band.Band, _ *frequencyplans.FrequencyPlan) error {
if dev.GetMacSettings().GetAdr().GetDynamic().GetMinDataRateIndex() == nil {
@@ -1487,7 +1731,7 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest
return nil, err
}
}
- if field, validate := hasSetADRField("mac_settings.adr.mode.dynamic.max_tx_power_index"); validate {
+ if field, validate := hasSetField("mac_settings.adr.mode.dynamic.max_tx_power_index"); validate {
if err := st.WithField(func(dev *ttnpb.EndDevice) error {
return withPHY(func(phy *band.Band, _ *frequencyplans.FrequencyPlan) error {
if dev.GetMacSettings().GetAdr().GetDynamic().GetMaxTxPowerIndex() == nil {
@@ -1504,7 +1748,7 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest
return nil, err
}
}
- if field, validate := hasSetADRField("mac_settings.adr.mode.dynamic.min_tx_power_index"); validate {
+ if field, validate := hasSetField("mac_settings.adr.mode.dynamic.min_tx_power_index"); validate {
if err := st.WithField(func(dev *ttnpb.EndDevice) error {
return withPHY(func(phy *band.Band, _ *frequencyplans.FrequencyPlan) error {
if dev.GetMacSettings().GetAdr().GetDynamic().GetMinTxPowerIndex() == nil {
@@ -1544,7 +1788,7 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest
return nil, err
}
}
- if field, validate := hasSetADRField("mac_settings.adr.mode.static.data_rate_index"); validate {
+ if field, validate := hasSetField("mac_settings.adr.mode.static.data_rate_index"); validate {
if err := st.WithField(func(dev *ttnpb.EndDevice) error {
return withPHY(func(phy *band.Band, _ *frequencyplans.FrequencyPlan) error {
if dev.GetMacSettings().GetAdr().GetStatic() == nil {
@@ -1562,7 +1806,7 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest
return nil, err
}
}
- if field, validate := hasSetADRField("mac_settings.adr.mode.static.tx_power_index"); validate {
+ if field, validate := hasSetField("mac_settings.adr.mode.static.tx_power_index"); validate {
if err := st.WithField(func(dev *ttnpb.EndDevice) error {
return withPHY(func(phy *band.Band, _ *frequencyplans.FrequencyPlan) error {
if dev.GetMacSettings().GetAdr().GetStatic() == nil {
@@ -1613,6 +1857,60 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest
return nil, err
}
}
+ if field, validate := hasSetField("mac_settings.relay.mode.served.second_channel.data_rate_index"); validate {
+ if err := st.WithField(func(dev *ttnpb.EndDevice) error {
+ return withPHY(func(phy *band.Band, _ *frequencyplans.FrequencyPlan) error {
+ if dev.GetMacSettings().GetRelay().GetServed().GetSecondChannel() == nil {
+ return nil
+ }
+ _, ok := phy.DataRates[dev.MacSettings.Relay.GetServed().SecondChannel.DataRateIndex]
+ if !ok {
+ return newInvalidFieldValueError(field)
+ }
+ return nil
+ })
+ },
+ field,
+ ); err != nil {
+ return nil, err
+ }
+ }
+ if field, validate := hasSetField("mac_settings.relay.mode.serving.default_channel_index"); validate {
+ if err := st.WithField(func(dev *ttnpb.EndDevice) error {
+ return withPHY(func(phy *band.Band, _ *frequencyplans.FrequencyPlan) error {
+ if dev.GetMacSettings().GetRelay().GetServing() == nil {
+ return nil
+ }
+ chIdx := dev.MacSettings.Relay.GetServing().DefaultChannelIndex
+ if chIdx >= uint32(len(phy.Relay.WORChannels)) {
+ return newInvalidFieldValueError(field)
+ }
+ return nil
+ })
+ },
+ field,
+ ); err != nil {
+ return nil, err
+ }
+ }
+ if field, validate := hasSetField("mac_settings.relay.mode.serving.second_channel.data_rate_index"); validate {
+ if err := st.WithField(func(dev *ttnpb.EndDevice) error {
+ return withPHY(func(phy *band.Band, _ *frequencyplans.FrequencyPlan) error {
+ if dev.GetMacSettings().GetRelay().GetServing().GetSecondChannel() == nil {
+ return nil
+ }
+ _, ok := phy.DataRates[dev.MacSettings.Relay.GetServing().SecondChannel.DataRateIndex]
+ if !ok {
+ return newInvalidFieldValueError(field)
+ }
+ return nil
+ })
+ },
+ field,
+ ); err != nil {
+ return nil, err
+ }
+ }
if field, validate := hasSetField("mac_state.current_parameters.rx2_data_rate_index"); validate {
if err := st.WithField(func(dev *ttnpb.EndDevice) error {
if dev.GetMacState() == nil {
@@ -1649,6 +1947,60 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest
return nil, err
}
}
+ if field, validate := hasSetField("pending_mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index"); validate {
+ if err := st.WithField(func(dev *ttnpb.EndDevice) error {
+ return withPHY(func(phy *band.Band, _ *frequencyplans.FrequencyPlan) error {
+ if dev.GetPendingMacState().GetCurrentParameters().GetRelay().GetServed().GetSecondChannel() == nil {
+ return nil
+ }
+ _, ok := phy.DataRates[dev.PendingMacState.CurrentParameters.Relay.GetServed().SecondChannel.DataRateIndex]
+ if !ok {
+ return newInvalidFieldValueError(field)
+ }
+ return nil
+ })
+ },
+ field,
+ ); err != nil {
+ return nil, err
+ }
+ }
+ if field, validate := hasSetField("pending_mac_state.current_parameters.relay.mode.serving.default_channel_index"); validate {
+ if err := st.WithField(func(dev *ttnpb.EndDevice) error {
+ return withPHY(func(phy *band.Band, _ *frequencyplans.FrequencyPlan) error {
+ if dev.GetPendingMacState().GetCurrentParameters().GetRelay().GetServing() == nil {
+ return nil
+ }
+ chIdx := dev.PendingMacState.CurrentParameters.Relay.GetServing().DefaultChannelIndex
+ if chIdx >= uint32(len(phy.Relay.WORChannels)) {
+ return newInvalidFieldValueError(field)
+ }
+ return nil
+ })
+ },
+ field,
+ ); err != nil {
+ return nil, err
+ }
+ }
+ if field, validate := hasSetField("pending_mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index"); validate {
+ if err := st.WithField(func(dev *ttnpb.EndDevice) error {
+ return withPHY(func(phy *band.Band, _ *frequencyplans.FrequencyPlan) error {
+ if dev.GetPendingMacState().GetCurrentParameters().GetRelay().GetServing().GetSecondChannel() == nil {
+ return nil
+ }
+ _, ok := phy.DataRates[dev.PendingMacState.CurrentParameters.Relay.GetServing().SecondChannel.DataRateIndex]
+ if !ok {
+ return newInvalidFieldValueError(field)
+ }
+ return nil
+ })
+ },
+ field,
+ ); err != nil {
+ return nil, err
+ }
+ }
if field, validate := hasSetField("pending_mac_state.current_parameters.rx2_data_rate_index"); validate {
if err := st.WithField(func(dev *ttnpb.EndDevice) error {
if dev.GetPendingMacState() == nil {
@@ -1667,6 +2019,60 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest
return nil, err
}
}
+ if field, validate := hasSetField("pending_mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index"); validate {
+ if err := st.WithField(func(dev *ttnpb.EndDevice) error {
+ return withPHY(func(phy *band.Band, _ *frequencyplans.FrequencyPlan) error {
+ if dev.GetPendingMacState().GetDesiredParameters().GetRelay().GetServed().GetSecondChannel() == nil {
+ return nil
+ }
+ _, ok := phy.DataRates[dev.PendingMacState.DesiredParameters.Relay.GetServed().SecondChannel.DataRateIndex]
+ if !ok {
+ return newInvalidFieldValueError(field)
+ }
+ return nil
+ })
+ },
+ field,
+ ); err != nil {
+ return nil, err
+ }
+ }
+ if field, validate := hasSetField("pending_mac_state.desired_parameters.relay.mode.serving.default_channel_index"); validate {
+ if err := st.WithField(func(dev *ttnpb.EndDevice) error {
+ return withPHY(func(phy *band.Band, _ *frequencyplans.FrequencyPlan) error {
+ if dev.GetPendingMacState().GetDesiredParameters().GetRelay().GetServing() == nil {
+ return nil
+ }
+ chIdx := dev.PendingMacState.DesiredParameters.Relay.GetServing().DefaultChannelIndex
+ if chIdx >= uint32(len(phy.Relay.WORChannels)) {
+ return newInvalidFieldValueError(field)
+ }
+ return nil
+ })
+ },
+ field,
+ ); err != nil {
+ return nil, err
+ }
+ }
+ if field, validate := hasSetField("pending_mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index"); validate {
+ if err := st.WithField(func(dev *ttnpb.EndDevice) error {
+ return withPHY(func(phy *band.Band, _ *frequencyplans.FrequencyPlan) error {
+ if dev.GetPendingMacState().GetDesiredParameters().GetRelay().GetServing().GetSecondChannel() == nil {
+ return nil
+ }
+ _, ok := phy.DataRates[dev.PendingMacState.DesiredParameters.Relay.GetServing().SecondChannel.DataRateIndex]
+ if !ok {
+ return newInvalidFieldValueError(field)
+ }
+ return nil
+ })
+ },
+ field,
+ ); err != nil {
+ return nil, err
+ }
+ }
if field, validate := hasSetField("pending_mac_state.desired_parameters.rx2_data_rate_index"); validate {
if err := st.WithField(func(dev *ttnpb.EndDevice) error {
if dev.GetPendingMacState() == nil {
@@ -1703,6 +2109,60 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest
return nil, err
}
}
+ if field, validate := hasSetField("mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index"); validate {
+ if err := st.WithField(func(dev *ttnpb.EndDevice) error {
+ return withPHY(func(phy *band.Band, _ *frequencyplans.FrequencyPlan) error {
+ if dev.GetMacState().GetCurrentParameters().GetRelay().GetServed().GetSecondChannel() == nil {
+ return nil
+ }
+ _, ok := phy.DataRates[dev.MacState.CurrentParameters.Relay.GetServed().SecondChannel.DataRateIndex]
+ if !ok {
+ return newInvalidFieldValueError(field)
+ }
+ return nil
+ })
+ },
+ field,
+ ); err != nil {
+ return nil, err
+ }
+ }
+ if field, validate := hasSetField("mac_state.current_parameters.relay.mode.serving.default_channel_index"); validate {
+ if err := st.WithField(func(dev *ttnpb.EndDevice) error {
+ return withPHY(func(phy *band.Band, _ *frequencyplans.FrequencyPlan) error {
+ if dev.GetMacState().GetCurrentParameters().GetRelay().GetServing() == nil {
+ return nil
+ }
+ chIdx := dev.MacState.CurrentParameters.Relay.GetServing().DefaultChannelIndex
+ if chIdx >= uint32(len(phy.Relay.WORChannels)) {
+ return newInvalidFieldValueError(field)
+ }
+ return nil
+ })
+ },
+ field,
+ ); err != nil {
+ return nil, err
+ }
+ }
+ if field, validate := hasSetField("mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index"); validate {
+ if err := st.WithField(func(dev *ttnpb.EndDevice) error {
+ return withPHY(func(phy *band.Band, _ *frequencyplans.FrequencyPlan) error {
+ if dev.GetMacState().GetCurrentParameters().GetRelay().GetServing().GetSecondChannel() == nil {
+ return nil
+ }
+ _, ok := phy.DataRates[dev.MacState.CurrentParameters.Relay.GetServing().SecondChannel.DataRateIndex]
+ if !ok {
+ return newInvalidFieldValueError(field)
+ }
+ return nil
+ })
+ },
+ field,
+ ); err != nil {
+ return nil, err
+ }
+ }
if field, validate := hasSetField("mac_state.desired_parameters.ping_slot_data_rate_index_value.value"); validate {
if err := st.WithField(func(dev *ttnpb.EndDevice) error {
if dev.GetMacState() == nil || dev.MacState.DesiredParameters.PingSlotDataRateIndexValue == nil {
@@ -1721,6 +2181,60 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest
return nil, err
}
}
+ if field, validate := hasSetField("mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index"); validate {
+ if err := st.WithField(func(dev *ttnpb.EndDevice) error {
+ return withPHY(func(phy *band.Band, _ *frequencyplans.FrequencyPlan) error {
+ if dev.GetMacState().GetDesiredParameters().GetRelay().GetServed().GetSecondChannel() == nil {
+ return nil
+ }
+ _, ok := phy.DataRates[dev.MacState.DesiredParameters.Relay.GetServed().SecondChannel.DataRateIndex]
+ if !ok {
+ return newInvalidFieldValueError(field)
+ }
+ return nil
+ })
+ },
+ field,
+ ); err != nil {
+ return nil, err
+ }
+ }
+ if field, validate := hasSetField("mac_state.desired_parameters.relay.mode.serving.default_channel_index"); validate {
+ if err := st.WithField(func(dev *ttnpb.EndDevice) error {
+ return withPHY(func(phy *band.Band, _ *frequencyplans.FrequencyPlan) error {
+ if dev.GetMacState().GetDesiredParameters().GetRelay().GetServing() == nil {
+ return nil
+ }
+ chIdx := dev.MacState.DesiredParameters.Relay.GetServing().DefaultChannelIndex
+ if chIdx >= uint32(len(phy.Relay.WORChannels)) {
+ return newInvalidFieldValueError(field)
+ }
+ return nil
+ })
+ },
+ field,
+ ); err != nil {
+ return nil, err
+ }
+ }
+ if field, validate := hasSetField("mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index"); validate {
+ if err := st.WithField(func(dev *ttnpb.EndDevice) error {
+ return withPHY(func(phy *band.Band, _ *frequencyplans.FrequencyPlan) error {
+ if dev.GetMacState().GetDesiredParameters().GetRelay().GetServing().GetSecondChannel() == nil {
+ return nil
+ }
+ _, ok := phy.DataRates[dev.MacState.DesiredParameters.Relay.GetServing().SecondChannel.DataRateIndex]
+ if !ok {
+ return newInvalidFieldValueError(field)
+ }
+ return nil
+ })
+ },
+ field,
+ ); err != nil {
+ return nil, err
+ }
+ }
if field, validate := hasSetField("pending_mac_state.current_parameters.ping_slot_data_rate_index_value.value"); validate {
if err := st.WithField(func(dev *ttnpb.EndDevice) error {
@@ -2137,7 +2651,7 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest
"pending_mac_state.queued_join_accept.payload": func() bool { return len(st.Device.PendingMacState.QueuedJoinAccept.Payload) == 0 },
"pending_mac_state.queued_join_accept.dev_addr": types.MustDevAddr(
st.Device.PendingMacState.QueuedJoinAccept.DevAddr,
- ).IsZero,
+ ).OrZero().IsZero,
} {
p, isZero := p, isZero
if err := st.ValidateSetField(func() bool { return !isZero() }, p); err != nil {
@@ -2316,6 +2830,29 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest
"mac_state.current_parameters.ping_slot_frequency",
"mac_state.current_parameters.rejoin_count_periodicity",
"mac_state.current_parameters.rejoin_time_periodicity",
+ "mac_state.current_parameters.relay.mode.served.backoff",
+ "mac_state.current_parameters.relay.mode.served.mode.always",
+ "mac_state.current_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_state.current_parameters.relay.mode.served.mode.end_device_controlled",
+ "mac_state.current_parameters.relay.mode.served.second_channel.ack_offset",
+ "mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index",
+ "mac_state.current_parameters.relay.mode.served.second_channel.frequency",
+ "mac_state.current_parameters.relay.mode.served.serving_device_id",
+ "mac_state.current_parameters.relay.mode.serving.cad_periodicity",
+ "mac_state.current_parameters.relay.mode.serving.default_channel_index",
+ "mac_state.current_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.limits.reset_behavior",
+ "mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.second_channel.ack_offset",
+ "mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "mac_state.current_parameters.relay.mode.serving.second_channel.frequency",
+ "mac_state.current_parameters.relay.mode.serving.uplink_forwarding_rules",
"mac_state.current_parameters.rx1_data_rate_offset",
"mac_state.current_parameters.rx1_delay",
"mac_state.current_parameters.rx2_data_rate_index",
@@ -2335,6 +2872,29 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest
"mac_state.desired_parameters.ping_slot_frequency",
"mac_state.desired_parameters.rejoin_count_periodicity",
"mac_state.desired_parameters.rejoin_time_periodicity",
+ "mac_state.desired_parameters.relay.mode.served.backoff",
+ "mac_state.desired_parameters.relay.mode.served.mode.always",
+ "mac_state.desired_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_state.desired_parameters.relay.mode.served.mode.end_device_controlled",
+ "mac_state.desired_parameters.relay.mode.served.second_channel.ack_offset",
+ "mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index",
+ "mac_state.desired_parameters.relay.mode.served.second_channel.frequency",
+ "mac_state.desired_parameters.relay.mode.served.serving_device_id",
+ "mac_state.desired_parameters.relay.mode.serving.cad_periodicity",
+ "mac_state.desired_parameters.relay.mode.serving.default_channel_index",
+ "mac_state.desired_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.limits.reset_behavior",
+ "mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel.ack_offset",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel.frequency",
+ "mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules",
"mac_state.desired_parameters.rx1_data_rate_offset",
"mac_state.desired_parameters.rx1_delay",
"mac_state.desired_parameters.rx2_data_rate_index",
@@ -2356,6 +2916,8 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest
"mac_state.pending_application_downlink.frm_payload",
"mac_state.pending_application_downlink.priority",
"mac_state.pending_application_downlink.session_key_id",
+ "mac_state.pending_relay_downlink.raw_payload",
+ "mac_state.pending_relay_downlink",
"mac_state.pending_requests",
"mac_state.ping_slot_periodicity.value",
"mac_state.queued_responses",
@@ -2530,6 +3092,29 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest
"pending_mac_state.current_parameters.ping_slot_frequency",
"pending_mac_state.current_parameters.rejoin_count_periodicity",
"pending_mac_state.current_parameters.rejoin_time_periodicity",
+ "pending_mac_state.current_parameters.relay.mode.served.backoff",
+ "pending_mac_state.current_parameters.relay.mode.served.mode.always",
+ "pending_mac_state.current_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "pending_mac_state.current_parameters.relay.mode.served.mode.end_device_controlled",
+ "pending_mac_state.current_parameters.relay.mode.served.second_channel.ack_offset",
+ "pending_mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index",
+ "pending_mac_state.current_parameters.relay.mode.served.second_channel.frequency",
+ "pending_mac_state.current_parameters.relay.mode.served.serving_device_id",
+ "pending_mac_state.current_parameters.relay.mode.serving.cad_periodicity",
+ "pending_mac_state.current_parameters.relay.mode.serving.default_channel_index",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.reset_behavior",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "pending_mac_state.current_parameters.relay.mode.serving.second_channel.ack_offset",
+ "pending_mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "pending_mac_state.current_parameters.relay.mode.serving.second_channel.frequency",
+ "pending_mac_state.current_parameters.relay.mode.serving.uplink_forwarding_rules",
"pending_mac_state.current_parameters.rx1_data_rate_offset",
"pending_mac_state.current_parameters.rx1_delay",
"pending_mac_state.current_parameters.rx2_data_rate_index",
@@ -2549,6 +3134,29 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest
"pending_mac_state.desired_parameters.ping_slot_frequency",
"pending_mac_state.desired_parameters.rejoin_count_periodicity",
"pending_mac_state.desired_parameters.rejoin_time_periodicity",
+ "pending_mac_state.desired_parameters.relay.mode.served.backoff",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode.always",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode.end_device_controlled",
+ "pending_mac_state.desired_parameters.relay.mode.served.second_channel.ack_offset",
+ "pending_mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index",
+ "pending_mac_state.desired_parameters.relay.mode.served.second_channel.frequency",
+ "pending_mac_state.desired_parameters.relay.mode.served.serving_device_id",
+ "pending_mac_state.desired_parameters.relay.mode.serving.cad_periodicity",
+ "pending_mac_state.desired_parameters.relay.mode.serving.default_channel_index",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.reset_behavior",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "pending_mac_state.desired_parameters.relay.mode.serving.second_channel.ack_offset",
+ "pending_mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "pending_mac_state.desired_parameters.relay.mode.serving.second_channel.frequency",
+ "pending_mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules",
"pending_mac_state.desired_parameters.rx1_data_rate_offset",
"pending_mac_state.desired_parameters.rx1_delay",
"pending_mac_state.desired_parameters.rx2_data_rate_index",
@@ -2632,6 +3240,29 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest
"mac_state.current_parameters.ping_slot_frequency",
"mac_state.current_parameters.rejoin_count_periodicity",
"mac_state.current_parameters.rejoin_time_periodicity",
+ "mac_state.current_parameters.relay.mode.served.backoff",
+ "mac_state.current_parameters.relay.mode.served.mode.always",
+ "mac_state.current_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_state.current_parameters.relay.mode.served.mode.end_device_controlled",
+ "mac_state.current_parameters.relay.mode.served.second_channel.ack_offset",
+ "mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index",
+ "mac_state.current_parameters.relay.mode.served.second_channel.frequency",
+ "mac_state.current_parameters.relay.mode.served.serving_device_id",
+ "mac_state.current_parameters.relay.mode.serving.cad_periodicity",
+ "mac_state.current_parameters.relay.mode.serving.default_channel_index",
+ "mac_state.current_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.limits.reset_behavior",
+ "mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.second_channel.ack_offset",
+ "mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "mac_state.current_parameters.relay.mode.serving.second_channel.frequency",
+ "mac_state.current_parameters.relay.mode.serving.uplink_forwarding_rules",
"mac_state.current_parameters.rx1_data_rate_offset",
"mac_state.current_parameters.rx1_delay",
"mac_state.current_parameters.rx2_data_rate_index",
@@ -2651,6 +3282,29 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest
"mac_state.desired_parameters.ping_slot_frequency",
"mac_state.desired_parameters.rejoin_count_periodicity",
"mac_state.desired_parameters.rejoin_time_periodicity",
+ "mac_state.desired_parameters.relay.mode.served.backoff",
+ "mac_state.desired_parameters.relay.mode.served.mode.always",
+ "mac_state.desired_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_state.desired_parameters.relay.mode.served.mode.end_device_controlled",
+ "mac_state.desired_parameters.relay.mode.served.second_channel.ack_offset",
+ "mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index",
+ "mac_state.desired_parameters.relay.mode.served.second_channel.frequency",
+ "mac_state.desired_parameters.relay.mode.served.serving_device_id",
+ "mac_state.desired_parameters.relay.mode.serving.cad_periodicity",
+ "mac_state.desired_parameters.relay.mode.serving.default_channel_index",
+ "mac_state.desired_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.limits.reset_behavior",
+ "mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel.ack_offset",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel.frequency",
+ "mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules",
"mac_state.desired_parameters.rx1_data_rate_offset",
"mac_state.desired_parameters.rx1_delay",
"mac_state.desired_parameters.rx2_data_rate_index",
@@ -2682,7 +3336,14 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest
}
var evt events.Event
- dev, ctx, err := ns.devices.SetByID(ctx, st.Device.Ids.ApplicationIds, st.Device.Ids.DeviceId, st.GetFields(), st.SetFunc(func(ctx context.Context, stored *ttnpb.EndDevice) error {
+ dev, ctx, err := ns.devices.SetByID(ctx, st.Device.Ids.ApplicationIds, st.Device.Ids.DeviceId, ttnpb.EndDeviceFieldPathsTopLevel, st.SetFunc(func(ctx context.Context, stored *ttnpb.EndDevice) error {
+ if nonZeroFields := ttnpb.NonZeroFields(stored, st.GetFields()...); len(nonZeroFields) > 0 {
+ newStored := &ttnpb.EndDevice{}
+ if err := newStored.SetFields(stored, nonZeroFields...); err != nil {
+ return err
+ }
+ stored = newStored
+ }
if hasSession {
macVersion := stored.GetMacState().GetLorawanVersion()
if stored.GetMacState() == nil && !st.HasSetField("mac_state") {
diff --git a/pkg/networkserver/grpc_gsns.go b/pkg/networkserver/grpc_gsns.go
index 707991fa7f..8420594734 100644
--- a/pkg/networkserver/grpc_gsns.go
+++ b/pkg/networkserver/grpc_gsns.go
@@ -19,6 +19,7 @@ import (
"context"
"fmt"
"runtime/trace"
+ "slices"
clusterauth "go.thethings.network/lorawan-stack/v3/pkg/auth/cluster"
"go.thethings.network/lorawan-stack/v3/pkg/band"
@@ -32,11 +33,12 @@ import (
"go.thethings.network/lorawan-stack/v3/pkg/networkserver/internal/time"
"go.thethings.network/lorawan-stack/v3/pkg/networkserver/mac"
"go.thethings.network/lorawan-stack/v3/pkg/specification/macspec"
+ "go.thethings.network/lorawan-stack/v3/pkg/specification/relayspec"
+ "go.thethings.network/lorawan-stack/v3/pkg/task"
"go.thethings.network/lorawan-stack/v3/pkg/toa"
"go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
"go.thethings.network/lorawan-stack/v3/pkg/types"
"go.thethings.network/lorawan-stack/v3/pkg/unique"
- "golang.org/x/exp/slices"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/durationpb"
"google.golang.org/protobuf/types/known/emptypb"
@@ -57,19 +59,26 @@ const (
// This parameter is separated from the uplink collection period since the JoinRequest may have to be
// served by a Join Server which is either geographically far away, or simply slow to respond.
joinRequestCollectionWindow = 6 * time.Second
+
+ // DeduplicationLimit is the number of metadata to deduplicate for a single transmission.
+ deduplicationLimit = 50
)
// UplinkDeduplicator represents an entity, that deduplicates uplinks and accumulates metadata.
type UplinkDeduplicator interface {
// DeduplicateUplink deduplicates an uplink message for specified time.Duration, in the provided round.
// DeduplicateUplink returns true if the uplink is not a duplicate or false and error, if any, otherwise.
- DeduplicateUplink(ctx context.Context, up *ttnpb.UplinkMessage, window time.Duration, round uint64) (first bool, err error)
+ DeduplicateUplink(
+ ctx context.Context, up *ttnpb.UplinkMessage, window time.Duration, limit int, round uint64,
+ ) (first bool, err error)
// AccumulatedMetadata returns accumulated metadata for specified uplink message in the provided round and error, if any.
AccumulatedMetadata(ctx context.Context, up *ttnpb.UplinkMessage, round uint64) (mds []*ttnpb.RxMetadata, err error)
}
-func (ns *NetworkServer) deduplicateUplink(ctx context.Context, up *ttnpb.UplinkMessage, window time.Duration, round uint64) (bool, error) {
- ok, err := ns.uplinkDeduplicator.DeduplicateUplink(ctx, up, window, round)
+func (ns *NetworkServer) deduplicateUplink(
+ ctx context.Context, up *ttnpb.UplinkMessage, window time.Duration, limit int, round uint64,
+) (bool, error) {
+ ok, err := ns.uplinkDeduplicator.DeduplicateUplink(ctx, up, window, limit, round)
if err != nil {
log.FromContext(ctx).WithError(err).Error("Failed to deduplicate uplink")
return false, err
@@ -605,6 +614,18 @@ macLoop:
evs, err = mac.HandleBeaconFreqAns(ctx, dev, cmd.GetBeaconFreqAns())
case ttnpb.MACCommandIdentifier_CID_DEVICE_MODE:
evs, err = mac.HandleDeviceModeInd(ctx, dev, cmd.GetDeviceModeInd())
+ case ttnpb.MACCommandIdentifier_CID_RELAY_CONF:
+ evs, err = mac.HandleRelayConfAns(ctx, dev, cmd.GetRelayConfAns())
+ case ttnpb.MACCommandIdentifier_CID_RELAY_END_DEVICE_CONF:
+ evs, err = mac.HandleRelayEndDeviceConfAns(ctx, dev, cmd.GetRelayEndDeviceConfAns())
+ case ttnpb.MACCommandIdentifier_CID_RELAY_UPDATE_UPLINK_LIST:
+ evs, err = mac.HandleRelayUpdateUplinkListAns(ctx, dev, cmd.GetRelayUpdateUplinkListAns())
+ case ttnpb.MACCommandIdentifier_CID_RELAY_CTRL_UPLINK_LIST:
+ evs, err = mac.HandleRelayCtrlUplinkListAns(ctx, dev, cmd.GetRelayCtrlUplinkListAns())
+ case ttnpb.MACCommandIdentifier_CID_RELAY_CONFIGURE_FWD_LIMIT:
+ evs, err = mac.HandleRelayConfigureFwdLimitAns(ctx, dev, cmd.GetRelayConfigureFwdLimitAns())
+ case ttnpb.MACCommandIdentifier_CID_RELAY_NOTIFY_NEW_END_DEVICE:
+ evs, err = mac.HandleRelayNotifyNewEndDeviceReq(ctx, dev, cmd.GetRelayNotifyNewEndDeviceReq())
default:
_, known := lorawan.DefaultMACCommands[cmd.Cid]
logger.WithField("known", known).Debug("Unknown MAC command received")
@@ -641,6 +662,7 @@ macLoop:
// TODO: Notify AS of session recovery(https://github.com/TheThingsNetwork/lorawan-stack/issues/594)
}
dev.MacState.PendingJoinRequest = nil
+ dev.MacState.PendingRelayDownlink = nil
dev.PendingMacState = nil
dev.PendingSession = nil
@@ -746,9 +768,14 @@ func toMACStateRxMetadata(mds []*ttnpb.RxMetadata) []*ttnpb.MACState_UplinkMessa
if md.PacketBroker != nil {
pbMD = &ttnpb.MACState_UplinkMessage_RxMetadata_PacketBrokerMetadata{}
}
+ var relayMD *ttnpb.MACState_UplinkMessage_RxMetadata_RelayMetadata
+ if md.Relay != nil {
+ relayMD = &ttnpb.MACState_UplinkMessage_RxMetadata_RelayMetadata{}
+ }
recentMDs = append(recentMDs, &ttnpb.MACState_UplinkMessage_RxMetadata{
GatewayIds: md.GatewayIds,
PacketBroker: pbMD,
+ Relay: relayMD,
ChannelRssi: md.ChannelRssi,
Snr: md.Snr,
DownlinkPathConstraint: md.DownlinkPathConstraint,
@@ -790,10 +817,17 @@ func appendRecentUplink(
up *ttnpb.UplinkMessage,
window int,
) []*ttnpb.MACState_UplinkMessage {
+ ups := toMACStateUplinkMessages(up)
if n := len(recent); n > 0 {
recent[n-1].CorrelationIds = nil
+ if len(downlinkPathsFromRecentUplinks(ups...)) > 0 {
+ for _, md := range recent[n-1].RxMetadata {
+ md.UplinkToken = nil
+ md.DownlinkPathConstraint = ttnpb.DownlinkPathConstraint_DOWNLINK_PATH_CONSTRAINT_NEVER
+ }
+ }
}
- recent = append(recent, toMACStateUplinkMessages(up)...)
+ recent = append(recent, ups...)
if extra := len(recent) - window; extra > 0 {
recent = recent[extra:]
}
@@ -880,7 +914,7 @@ func (ns *NetworkServer) handleDataUplink(ctx context.Context, up *ttnpb.UplinkM
"uplink_f_cnt", pld.FHdr.FCnt,
))
- ok, err := ns.deduplicateUplink(ctx, up, ns.collectionWindow(ctx), initialDeduplicationRound)
+ ok, err := ns.deduplicateUplink(ctx, up, ns.collectionWindow(ctx), deduplicationLimit, initialDeduplicationRound)
if err != nil {
return err
}
@@ -1081,7 +1115,25 @@ func (ns *NetworkServer) handleDataUplink(ctx context.Context, up *ttnpb.UplinkM
}
if !matched.IsRetransmission {
var frmPayload []byte
- if pld.FPort != 0 {
+ switch pld.FPort {
+ case 0:
+ case relayspec.FPort:
+ relayUp, relayEvents, err := handleRelayForwardingProtocol(
+ ctx, matched.Device, matched.FullFCnt, matched.phy, up, ns.KeyService(),
+ )
+ queuedEvents = append(queuedEvents, relayEvents...)
+ if err != nil {
+ log.FromContext(ctx).WithError(err).Warn("Failed to handle relay forwarding protocol")
+ } else {
+ ns.StartTask(&task.Config{
+ Context: ns.FromRequestContext(ctx),
+ ID: "loopback_relay_uplink",
+ Func: relayLoopbackFunc(ns.LoopbackConn(), relayUp, ns.WithClusterAuth()),
+ Restart: task.RestartNever,
+ Backoff: task.DefaultBackoffConfig,
+ })
+ }
+ default:
frmPayload = pld.FrmPayload
}
queuedApplicationUplinks = append(queuedApplicationUplinks, &ttnpb.ApplicationUp{
@@ -1175,7 +1227,7 @@ func (ns *NetworkServer) handleJoinRequest(ctx context.Context, up *ttnpb.Uplink
"join_eui", types.MustEUI64(pld.JoinEui).OrZero(),
))
- ok, err := ns.deduplicateUplink(ctx, up, joinRequestCollectionWindow, initialDeduplicationRound)
+ ok, err := ns.deduplicateUplink(ctx, up, joinRequestCollectionWindow, deduplicationLimit, initialDeduplicationRound)
if err != nil {
return err
}
@@ -1337,6 +1389,10 @@ func (ns *NetworkServer) handleJoinRequest(ctx context.Context, up *ttnpb.Uplink
macState.RxWindowsAvailable = true
ctx = events.ContextWithCorrelationID(ctx, resp.CorrelationIds...)
+ if err := ns.deliverRelaySessionKeys(ctx, matched, keys.SessionKeyId); err != nil {
+ return err
+ }
+
publishEvents(ctx, queuedEvents...)
queuedEvents = nil
up = ttnpb.Clone(up)
@@ -1389,7 +1445,7 @@ func (ns *NetworkServer) handleJoinRequest(ctx context.Context, up *ttnpb.Uplink
return nil
}
-var errRejoinRequest = errors.DefineUnimplemented("rejoin_request", "rejoin-request handling is not implemented")
+var errRejoinRequest = errors.DefineUnavailable("rejoin_request", "rejoin-request handling is not implemented")
func (ns *NetworkServer) handleRejoinRequest(ctx context.Context, up *ttnpb.UplinkMessage) error {
defer trace.StartRegion(ctx, "handle rejoin request").End()
diff --git a/pkg/networkserver/grpc_gsns_internal_test.go b/pkg/networkserver/grpc_gsns_internal_test.go
index 2452eb8eee..0318dc935b 100644
--- a/pkg/networkserver/grpc_gsns_internal_test.go
+++ b/pkg/networkserver/grpc_gsns_internal_test.go
@@ -26,15 +26,30 @@ import (
)
func TestAppendRecentUplink(t *testing.T) {
+ t.Parallel()
+ dataRate := (&ttnpb.LoRaDataRate{
+ SpreadingFactor: uint32(7),
+ Bandwidth: 125_000,
+ CodingRate: "4/5",
+ }).DataRate()
+ macSettings := &ttnpb.MACState_UplinkMessage_TxSettings{
+ DataRate: dataRate,
+ }
+ settings := &ttnpb.TxSettings{
+ DataRate: dataRate,
+ }
ups := [...]*ttnpb.MACState_UplinkMessage{
{
DeviceChannelIndex: 1,
+ Settings: macSettings,
},
{
DeviceChannelIndex: 2,
+ Settings: macSettings,
},
{
DeviceChannelIndex: 3,
+ Settings: macSettings,
},
}
for _, tc := range []struct {
@@ -46,6 +61,7 @@ func TestAppendRecentUplink(t *testing.T) {
{
Up: &ttnpb.UplinkMessage{
DeviceChannelIndex: 1,
+ Settings: settings,
},
Window: 1,
Expected: ups[:1],
@@ -54,6 +70,7 @@ func TestAppendRecentUplink(t *testing.T) {
Recent: ups[:1],
Up: &ttnpb.UplinkMessage{
DeviceChannelIndex: 2,
+ Settings: settings,
},
Window: 1,
Expected: ups[1:2],
@@ -62,6 +79,7 @@ func TestAppendRecentUplink(t *testing.T) {
Recent: ups[:2],
Up: &ttnpb.UplinkMessage{
DeviceChannelIndex: 3,
+ Settings: settings,
},
Window: 1,
Expected: ups[2:3],
@@ -70,6 +88,7 @@ func TestAppendRecentUplink(t *testing.T) {
Recent: ups[:1],
Up: &ttnpb.UplinkMessage{
DeviceChannelIndex: 2,
+ Settings: settings,
},
Window: 2,
Expected: ups[:2],
@@ -78,6 +97,7 @@ func TestAppendRecentUplink(t *testing.T) {
Recent: ups[:2],
Up: &ttnpb.UplinkMessage{
DeviceChannelIndex: 3,
+ Settings: settings,
},
Window: 2,
Expected: ups[1:3],
diff --git a/pkg/networkserver/internal/test/shared/application_uplink_queue.go b/pkg/networkserver/internal/test/shared/application_uplink_queue.go
deleted file mode 100644
index fc809fee2d..0000000000
--- a/pkg/networkserver/internal/test/shared/application_uplink_queue.go
+++ /dev/null
@@ -1,402 +0,0 @@
-// Copyright © 2019 The Things Network Foundation, The Things Industries B.V.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package test
-
-import (
- "bytes"
- "context"
- "testing"
- "time"
-
- "github.com/smarty/assertions"
- "go.thethings.network/lorawan-stack/v3/pkg/errors"
- . "go.thethings.network/lorawan-stack/v3/pkg/networkserver"
- "go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
- "go.thethings.network/lorawan-stack/v3/pkg/util/test"
- "go.thethings.network/lorawan-stack/v3/pkg/util/test/assertions/should"
- "google.golang.org/protobuf/proto"
-)
-
-// handleApplicationUplinkQueueTest runs a test suite on q.
-func handleApplicationUplinkQueueTest(ctx context.Context, q ApplicationUplinkQueue, consumerIDs []string) {
- assertAdd := func(ctx context.Context, ups ...*ttnpb.ApplicationUp) bool {
- t, a := test.MustNewTFromContext(ctx)
- t.Helper()
-
- errCh := make(chan error, 1)
- go func() {
- errCh <- q.Add(ctx, ups...)
- }()
- select {
- case <-ctx.Done():
- t.Error("Timed out while waiting for Add to return")
- return false
-
- case err := <-errCh:
- return a.So(err, should.BeNil)
- }
- }
-
- assertDrainApplication := func(ctx context.Context, withError bool, expected ...*ttnpb.ApplicationUp) bool {
- t, a := test.MustNewTFromContext(ctx)
- t.Helper()
-
- dispatchErrCh := make(chan error, len(consumerIDs))
-
- dispatchCtx, cancelDispatchCtx := context.WithCancel(ctx)
- defer cancelDispatchCtx()
- for _, consumerID := range consumerIDs {
- go func(consumerID string) {
- select {
- case <-ctx.Done():
- case dispatchErrCh <- q.Dispatch(dispatchCtx, consumerID):
- }
- }(consumerID)
- }
- defer func() {
- cancelDispatchCtx()
-
- for range consumerIDs {
- select {
- case <-ctx.Done():
- case err := <-dispatchErrCh:
- a.So(errors.IsCanceled(err), should.BeTrue)
- }
- }
- }()
-
- type popFuncReq struct {
- Context context.Context
- ApplicationIdentifiers *ttnpb.ApplicationIdentifiers
- Func ApplicationUplinkQueueDrainFunc
- Response chan<- TaskPopFuncResponse
- }
- reqCh := make(chan popFuncReq, 1)
- errCh := make(chan error, 1)
- popCtx, cancelPopCtx := context.WithCancel(ctx)
- defer cancelPopCtx()
- for _, consumerID := range consumerIDs {
- go func(consumerID string) {
- errCh <- q.Pop(popCtx, consumerID, func(ctx context.Context, appID *ttnpb.ApplicationIdentifiers, f ApplicationUplinkQueueDrainFunc) (time.Time, error) {
- respCh := make(chan TaskPopFuncResponse, 1)
- select {
- case <-popCtx.Done():
- return time.Time{}, popCtx.Err()
- case reqCh <- popFuncReq{
- Context: ctx,
- ApplicationIdentifiers: appID,
- Func: f,
- Response: respCh,
- }:
- }
- select {
- case <-popCtx.Done():
- return time.Time{}, popCtx.Err()
- case resp := <-respCh:
- return resp.Time, resp.Error
- }
- })
- }(consumerID)
- }
-
- var collected []*ttnpb.ApplicationUp
- var requests int
- for ; len(collected) < len(expected); requests++ {
- select {
- case <-ctx.Done():
- t.Error("Timed out while waiting for Pop callback to be called")
- return false
-
- case req := <-reqCh:
- if !test.AllTrue(
- a.So(req.Context, should.HaveParentContextOrEqual, ctx),
- a.So(req.ApplicationIdentifiers, should.Resemble, expected[0].EndDeviceIds.ApplicationIds),
- ) {
- t.Error("Pop callback assertion failed")
- return false
- }
-
- if withError {
- if !a.So(req.Func(2, func(ups ...*ttnpb.ApplicationUp) error {
- a.So(ups, should.NotBeEmpty)
- return test.ErrInternal
- }), should.HaveSameErrorDefinitionAs, test.ErrInternal) {
- return false
- }
- }
-
- if !a.So(req.Func(2, func(ups ...*ttnpb.ApplicationUp) error {
- a.So(ups, should.NotBeEmpty)
- collected = append(collected, ups...)
- return nil
- }), should.BeNil) {
- return false
- }
- close(req.Response)
- }
- }
-
- for i := 0; i < requests; i++ {
- select {
- case <-ctx.Done():
- t.Error("Timed out while waiting for Pop to return")
- return false
- case err := <-errCh:
- if !a.So(err, should.BeNil) {
- return false
- }
- }
- }
-
- cancelPopCtx()
-
- for i := requests; i < len(consumerIDs); i++ {
- select {
- case <-ctx.Done():
- t.Error("Timed out while waiting for Pop to return")
- return false
- case err := <-errCh:
- if !a.So(errors.IsCanceled(err), should.BeTrue) {
- return false
- }
- }
- }
-
- if a.So(len(collected), should.Equal, len(expected)) {
- for _, ex := range expected {
- expectedB, err := proto.Marshal(ex)
- if !a.So(err, should.BeNil) {
- return false
- }
-
- var found bool
- for _, coll := range collected {
- collectedB, err := proto.Marshal(coll)
- if !a.So(err, should.BeNil) {
- return false
- }
-
- if bytes.Equal(expectedB, collectedB) {
- found = true
- }
- }
-
- if !a.So(found, should.BeTrue) {
- return false
- }
- }
- }
-
- return true
- }
-
- appID1 := &ttnpb.ApplicationIdentifiers{
- ApplicationId: "application-uplink-queue-app-1",
- }
-
- appID2 := &ttnpb.ApplicationIdentifiers{
- ApplicationId: "application-uplink-queue-app-2",
- }
-
- invalidations := [...]*ttnpb.ApplicationUp{
- {
- EndDeviceIds: &ttnpb.EndDeviceIdentifiers{
- ApplicationIds: appID1,
- DeviceId: "test-dev2",
- },
- CorrelationIds: []string{"invalidations[0]"},
- Up: &ttnpb.ApplicationUp_DownlinkQueueInvalidated{
- DownlinkQueueInvalidated: &ttnpb.ApplicationInvalidatedDownlinks{},
- },
- },
- {
- EndDeviceIds: &ttnpb.EndDeviceIdentifiers{
- ApplicationIds: appID1,
- DeviceId: "test-dev2",
- },
- CorrelationIds: []string{"invalidations[1]"},
- Up: &ttnpb.ApplicationUp_DownlinkQueueInvalidated{
- DownlinkQueueInvalidated: &ttnpb.ApplicationInvalidatedDownlinks{},
- },
- },
- }
- joinAccepts := [...]*ttnpb.ApplicationUp{
- {
- EndDeviceIds: &ttnpb.EndDeviceIdentifiers{
- ApplicationIds: appID1,
- DeviceId: "test-dev",
- },
- CorrelationIds: []string{"joinAccepts[0]"},
- Up: &ttnpb.ApplicationUp_JoinAccept{
- JoinAccept: &ttnpb.ApplicationJoinAccept{},
- },
- },
- {
- EndDeviceIds: &ttnpb.EndDeviceIdentifiers{
- ApplicationIds: appID1,
- DeviceId: "test-dev2",
- },
- CorrelationIds: []string{"joinAccepts[1]"},
- Up: &ttnpb.ApplicationUp_JoinAccept{
- JoinAccept: &ttnpb.ApplicationJoinAccept{},
- },
- },
- }
- genericApp1Ups := [...]*ttnpb.ApplicationUp{
- {
- EndDeviceIds: &ttnpb.EndDeviceIdentifiers{
- ApplicationIds: appID1,
- DeviceId: "test-dev",
- },
- CorrelationIds: []string{"genericApp1Ups[0]"},
- Up: &ttnpb.ApplicationUp_DownlinkFailed{
- DownlinkFailed: &ttnpb.ApplicationDownlinkFailed{},
- },
- },
- {
- EndDeviceIds: &ttnpb.EndDeviceIdentifiers{
- ApplicationIds: appID1,
- DeviceId: "test-dev",
- },
- CorrelationIds: []string{"genericApp1Ups[1]"},
- Up: &ttnpb.ApplicationUp_LocationSolved{
- LocationSolved: &ttnpb.ApplicationLocation{},
- },
- },
- {
- EndDeviceIds: &ttnpb.EndDeviceIdentifiers{
- ApplicationIds: appID1,
- DeviceId: "test-dev2",
- },
- CorrelationIds: []string{"genericApp1Ups[2]"},
- Up: &ttnpb.ApplicationUp_DownlinkFailed{
- DownlinkFailed: &ttnpb.ApplicationDownlinkFailed{},
- },
- },
- {
- EndDeviceIds: &ttnpb.EndDeviceIdentifiers{
- ApplicationIds: appID1,
- DeviceId: "test-dev",
- },
- CorrelationIds: []string{"genericApp1Ups[3]"},
- Up: &ttnpb.ApplicationUp_DownlinkAck{
- DownlinkAck: &ttnpb.ApplicationDownlink{},
- },
- },
- {
- EndDeviceIds: &ttnpb.EndDeviceIdentifiers{
- ApplicationIds: appID1,
- DeviceId: "test-dev2",
- },
- CorrelationIds: []string{"genericApp1Ups[4]"},
- Up: &ttnpb.ApplicationUp_DownlinkAck{
- DownlinkAck: &ttnpb.ApplicationDownlink{},
- },
- },
- }
-
- genericApp2Ups := [...]*ttnpb.ApplicationUp{
- {
- EndDeviceIds: &ttnpb.EndDeviceIdentifiers{
- ApplicationIds: appID2,
- DeviceId: "test-dev2",
- },
- CorrelationIds: []string{"genericApp2Ups[0]"},
- Up: &ttnpb.ApplicationUp_LocationSolved{
- LocationSolved: &ttnpb.ApplicationLocation{},
- },
- },
- {
- EndDeviceIds: &ttnpb.EndDeviceIdentifiers{
- ApplicationIds: appID2,
- DeviceId: "test-dev",
- },
- CorrelationIds: []string{"genericApp2Ups[1]"},
- Up: &ttnpb.ApplicationUp_DownlinkFailed{
- DownlinkFailed: &ttnpb.ApplicationDownlinkFailed{},
- },
- },
- }
-
- _, a := test.MustNewTFromContext(ctx)
- switch {
- case
- !a.So(assertAdd(ctx,
- genericApp1Ups[0],
- ), should.BeTrue),
- !a.So(assertDrainApplication(ctx, false,
- genericApp1Ups[0],
- ), should.BeTrue),
-
- !a.So(assertAdd(ctx,
- genericApp2Ups[0],
- ), should.BeTrue),
- !a.So(assertAdd(ctx,
- genericApp2Ups[1],
- ), should.BeTrue),
- !a.So(assertDrainApplication(ctx, true,
- genericApp2Ups[0],
- genericApp2Ups[1],
- ), should.BeTrue),
-
- !a.So(assertAdd(ctx,
- genericApp1Ups[1],
- genericApp1Ups[2],
- invalidations[0],
- genericApp1Ups[3],
- invalidations[1],
- joinAccepts[0],
- ), should.BeTrue),
- !a.So(assertAdd(ctx,
- genericApp1Ups[4],
- joinAccepts[1],
- ), should.BeTrue),
- !a.So(assertDrainApplication(ctx, false,
- joinAccepts[0],
- joinAccepts[1],
- invalidations[0],
- invalidations[1],
- genericApp1Ups[1],
- genericApp1Ups[2],
- genericApp1Ups[3],
- genericApp1Ups[4],
- ), should.BeTrue):
- }
-}
-
-// HandleApplicationUplinkQueueTest runs a ApplicationUplinkQueue test suite on reg.
-func HandleApplicationUplinkQueueTest(t *testing.T, q ApplicationUplinkQueue, consumerIDs []string) {
- t.Helper()
- test.RunTest(t, test.TestConfig{
- Func: func(ctx context.Context, a *assertions.Assertion) {
- t.Helper()
- test.RunSubtestFromContext(ctx, test.SubtestConfig{
- Name: "1st run",
- Func: func(ctx context.Context, t *testing.T, a *assertions.Assertion) {
- handleApplicationUplinkQueueTest(ctx, q, consumerIDs)
- },
- })
- if t.Failed() {
- t.Skip("Skipping 2nd run")
- }
- test.RunSubtestFromContext(ctx, test.SubtestConfig{
- Name: "2nd run",
- Func: func(ctx context.Context, t *testing.T, a *assertions.Assertion) {
- handleApplicationUplinkQueueTest(ctx, q, consumerIDs)
- },
- })
- },
- })
-}
diff --git a/pkg/networkserver/internal/test/shared/device_registry.go b/pkg/networkserver/internal/test/shared/device_registry.go
index bc99b37aac..558778ef9f 100644
--- a/pkg/networkserver/internal/test/shared/device_registry.go
+++ b/pkg/networkserver/internal/test/shared/device_registry.go
@@ -150,6 +150,16 @@ func handleDeviceRegistryTest(ctx context.Context, reg DeviceRegistry) {
return false
}
+ batchStored, err := reg.BatchGetByID(
+ ctx, pb.Ids.ApplicationIds, []string{pb.Ids.DeviceId}, ttnpb.EndDeviceFieldPathsTopLevel,
+ )
+ if !test.AllTrue(
+ a.So(err, should.BeNil) || a.So(errors.Stack(err), should.BeEmpty),
+ a.So(batchStored, should.HaveLength, 1) && a.So(batchStored[0], should.BeNil),
+ ) {
+ t.Error("BatchGetByID assertion failed with empty registry")
+ }
+
stored, storedCtx, err = reg.GetByEUI(
ctx,
types.MustEUI64(pb.Ids.JoinEui).OrZero(),
@@ -222,6 +232,17 @@ func handleDeviceRegistryTest(ctx context.Context, reg DeviceRegistry) {
}
ctx = storedCtx
+ batchStored, err := reg.BatchGetByID(
+ ctx, pb.Ids.ApplicationIds, []string{pb.Ids.DeviceId}, ttnpb.EndDeviceFieldPathsTopLevel,
+ )
+ if !test.AllTrue(
+ a.So(err, should.BeNil) || a.So(errors.Stack(err), should.BeEmpty),
+ a.So(batchStored, should.HaveLength, 1) && a.So(batchStored[0], should.Resemble, pb),
+ ) {
+ t.Error("BatchGetByID assertion failed with non-empty registry")
+ return false
+ }
+
stored, storedCtx, err = reg.GetByEUI(
ctx,
types.MustEUI64(pb.Ids.JoinEui).OrZero(),
diff --git a/pkg/networkserver/internal/test/shared/redis.go b/pkg/networkserver/internal/test/shared/redis.go
index fb40f1102b..5ffccf960a 100644
--- a/pkg/networkserver/internal/test/shared/redis.go
+++ b/pkg/networkserver/internal/test/shared/redis.go
@@ -36,7 +36,7 @@ func testStreamBlockLimit() time.Duration {
func NewRedisApplicationUplinkQueue(ctx context.Context) (ApplicationUplinkQueue, func()) {
tb := test.MustTBFromContext(ctx)
cl, flush := test.NewRedis(ctx, append(redisNamespace[:], "application-uplinks")...)
- q := redis.NewApplicationUplinkQueue(cl, 100, redisConsumerGroup, 0, testStreamBlockLimit())
+ q := redis.NewApplicationUplinkQueue(cl, 100, redisConsumerGroup, 0)
if err := q.Init(ctx); err != nil {
tb.Fatalf("Failed to initialize Redis application uplink queue: %s", test.FormatError(err))
}
diff --git a/pkg/networkserver/internal/utils.go b/pkg/networkserver/internal/utils.go
index 90fcde3c5b..3d09fd1f1e 100644
--- a/pkg/networkserver/internal/utils.go
+++ b/pkg/networkserver/internal/utils.go
@@ -109,10 +109,12 @@ func RXMetadataStats(ctx context.Context, mds []*ttnpb.RxMetadata) (gateways int
md.PacketBroker.ForwarderNetId,
md.PacketBroker.ForwarderTenantId,
)] = struct{}{}
+ case md.Relay != nil:
+ gtws[fmt.Sprintf("relay:%s", md.Relay.DeviceId)] = struct{}{}
case md.GatewayIds != nil:
gtws[unique.ID(ctx, md.GatewayIds)] = struct{}{}
default:
- continue // Metadata without PB or Gateway IDs should be invalid so skipping.
+ continue // Metadata without PB, Relay or Gateway IDs should be invalid so skipping.
}
if md.Snr > maxSNR {
maxSNR = md.Snr
diff --git a/pkg/networkserver/mac/rekey.go b/pkg/networkserver/mac/rekey.go
index cba67a0923..0561c33bbe 100644
--- a/pkg/networkserver/mac/rekey.go
+++ b/pkg/networkserver/mac/rekey.go
@@ -42,10 +42,12 @@ func HandleRekeyInd(ctx context.Context, dev *ttnpb.EndDevice, pld *ttnpb.MACCom
evs := events.Builders{
EvtReceiveRekeyIndication.With(events.WithData(pld)),
}
- if !dev.SupportsJoin {
+ if !dev.SupportsJoin || !macspec.UseRekeyInd(dev.LorawanVersion) {
return evs, nil
}
- if dev.PendingSession != nil && dev.MacState.PendingJoinRequest != nil && types.MustDevAddr(dev.PendingSession.DevAddr).OrZero().Equal(devAddr) {
+ if dev.PendingSession != nil &&
+ dev.MacState.PendingJoinRequest != nil &&
+ types.MustDevAddr(dev.PendingSession.DevAddr).OrZero().Equal(devAddr) {
dev.Ids.DevAddr = dev.PendingSession.DevAddr
dev.Session = dev.PendingSession
}
diff --git a/pkg/networkserver/mac/rekey_test.go b/pkg/networkserver/mac/rekey_test.go
index 7c976167fa..9fe3d1a584 100644
--- a/pkg/networkserver/mac/rekey_test.go
+++ b/pkg/networkserver/mac/rekey_test.go
@@ -28,6 +28,7 @@ import (
)
func TestHandleRekeyInd(t *testing.T) {
+ t.Parallel()
for _, tc := range []struct {
Name string
Device, Expected *ttnpb.EndDevice
@@ -48,8 +49,9 @@ func TestHandleRekeyInd(t *testing.T) {
{
Name: "empty queue/original",
Device: &ttnpb.EndDevice{
- SupportsJoin: true,
- Ids: &ttnpb.EndDeviceIdentifiers{},
+ LorawanVersion: ttnpb.MACVersion_MAC_V1_1,
+ SupportsJoin: true,
+ Ids: &ttnpb.EndDeviceIdentifiers{},
PendingSession: &ttnpb.Session{
DevAddr: test.DefaultDevAddr.Bytes(),
LastFCntUp: 42,
@@ -62,7 +64,8 @@ func TestHandleRekeyInd(t *testing.T) {
},
},
Expected: &ttnpb.EndDevice{
- SupportsJoin: true,
+ LorawanVersion: ttnpb.MACVersion_MAC_V1_1,
+ SupportsJoin: true,
Ids: &ttnpb.EndDeviceIdentifiers{
DevAddr: test.DefaultDevAddr.Bytes(),
},
@@ -95,7 +98,8 @@ func TestHandleRekeyInd(t *testing.T) {
{
Name: "empty queue/retransmission/non-matching pending session",
Device: &ttnpb.EndDevice{
- SupportsJoin: true,
+ LorawanVersion: ttnpb.MACVersion_MAC_V1_1,
+ SupportsJoin: true,
Ids: &ttnpb.EndDeviceIdentifiers{
DevAddr: test.DefaultDevAddr.Bytes(),
},
@@ -116,7 +120,8 @@ func TestHandleRekeyInd(t *testing.T) {
},
},
Expected: &ttnpb.EndDevice{
- SupportsJoin: true,
+ LorawanVersion: ttnpb.MACVersion_MAC_V1_1,
+ SupportsJoin: true,
Ids: &ttnpb.EndDeviceIdentifiers{
DevAddr: test.DefaultDevAddr.Bytes(),
},
@@ -149,7 +154,8 @@ func TestHandleRekeyInd(t *testing.T) {
{
Name: "empty queue/retransmission/no pending session",
Device: &ttnpb.EndDevice{
- SupportsJoin: true,
+ LorawanVersion: ttnpb.MACVersion_MAC_V1_1,
+ SupportsJoin: true,
Ids: &ttnpb.EndDeviceIdentifiers{
DevAddr: test.DefaultDevAddr.Bytes(),
},
@@ -161,7 +167,8 @@ func TestHandleRekeyInd(t *testing.T) {
MacState: &ttnpb.MACState{},
},
Expected: &ttnpb.EndDevice{
- SupportsJoin: true,
+ LorawanVersion: ttnpb.MACVersion_MAC_V1_1,
+ SupportsJoin: true,
Ids: &ttnpb.EndDeviceIdentifiers{
DevAddr: test.DefaultDevAddr.Bytes(),
},
@@ -194,8 +201,9 @@ func TestHandleRekeyInd(t *testing.T) {
{
Name: "non-empty queue",
Device: &ttnpb.EndDevice{
- SupportsJoin: true,
- Ids: &ttnpb.EndDeviceIdentifiers{},
+ LorawanVersion: ttnpb.MACVersion_MAC_V1_1,
+ SupportsJoin: true,
+ Ids: &ttnpb.EndDeviceIdentifiers{},
PendingSession: &ttnpb.Session{
DevAddr: test.DefaultDevAddr.Bytes(),
LastFCntUp: 42,
@@ -212,7 +220,8 @@ func TestHandleRekeyInd(t *testing.T) {
},
},
Expected: &ttnpb.EndDevice{
- SupportsJoin: true,
+ LorawanVersion: ttnpb.MACVersion_MAC_V1_1,
+ SupportsJoin: true,
Ids: &ttnpb.EndDeviceIdentifiers{
DevAddr: test.DefaultDevAddr.Bytes(),
},
diff --git a/pkg/networkserver/mac/relay.go b/pkg/networkserver/mac/relay.go
new file mode 100644
index 0000000000..ea32f2f604
--- /dev/null
+++ b/pkg/networkserver/mac/relay.go
@@ -0,0 +1,152 @@
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package mac
+
+import (
+ "context"
+ "fmt"
+
+ "go.thethings.network/lorawan-stack/v3/pkg/log"
+ "go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
+ "go.thethings.network/lorawan-stack/v3/pkg/types"
+)
+
+// RelayKeyService provides common relay related cryptographic operations.
+type RelayKeyService interface {
+ // BatchDeriveRootWorSKey derives the RootWorSKey for the provided end devices.
+ // For devices with a pending session, the derived RootWorSKey is derived rom the
+ // pending NwkSEncKey. For devices with an active session, the derived RootWorSKey
+ // is derived from the active NwkSEncKey.
+ BatchDeriveRootWorSKey(
+ ctx context.Context, appID *ttnpb.ApplicationIdentifiers, deviceIDs []string, sessionKeyIDs [][]byte,
+ ) (devAddrs []*types.DevAddr, keys []*types.AES128Key, err error)
+}
+
+func secondChFields(secondCh *ttnpb.RelaySecondChannel) []any {
+ if secondCh == nil {
+ return nil
+ }
+ return []any{
+ "relay_second_ch_ack_offset", secondCh.AckOffset,
+ "relay_second_ch_data_rate_index", secondCh.DataRateIndex,
+ "relay_second_ch_frequency", secondCh.Frequency,
+ }
+}
+
+func servingRelayFields(serving *ttnpb.ServingRelayParameters) log.Fielder {
+ if serving == nil {
+ return log.Fields()
+ }
+ return log.Fields(
+ append(
+ secondChFields(serving.SecondChannel),
+ "relay_default_ch_index", serving.DefaultChannelIndex,
+ "relay_cad_periodicity", serving.CadPeriodicity,
+ )...,
+ )
+}
+
+func relayForwardLimitsFields(limits *ttnpb.RelayForwardLimits, prefix string) []any {
+ if limits == nil {
+ return nil
+ }
+ return []any{
+ fmt.Sprintf("relay_%v_limit_bucket_size", prefix), limits.BucketSize,
+ fmt.Sprintf("relay_%v_limit_reload_rate", prefix), limits.ReloadRate,
+ }
+}
+
+func relayConfigureForwardLimitsFields(limits *ttnpb.ServingRelayForwardingLimits) log.Fielder {
+ if limits == nil {
+ return log.Fields()
+ }
+ fields := []any{"relay_limit_reset_behavior", limits.ResetBehavior}
+ fields = append(fields, relayForwardLimitsFields(limits.JoinRequests, "join_requests")...)
+ fields = append(fields, relayForwardLimitsFields(limits.Notifications, "notifications")...)
+ fields = append(fields, relayForwardLimitsFields(limits.UplinkMessages, "uplink_messages")...)
+ fields = append(fields, relayForwardLimitsFields(limits.Overall, "overall")...)
+ return log.Fields(fields...)
+}
+
+func servedRelayFields(served *ttnpb.ServedRelayParameters) log.Fielder {
+ if served == nil {
+ return log.Fields()
+ }
+ fields := []any{}
+ switch {
+ case served.GetAlways() != nil:
+ fields = append(fields, "relay_mode", "always")
+ case served.GetDynamic() != nil:
+ fields = append(
+ fields,
+ "relay_mode", "dynamic",
+ "relay_smart_enable_level", served.GetDynamic().SmartEnableLevel,
+ )
+ case served.GetEndDeviceControlled() != nil:
+ fields = append(fields, "relay_mode", "end_device_controlled")
+ default:
+ panic("unreachable")
+ }
+ fields = append(fields, "relay_backoff", served.Backoff)
+ fields = append(fields, secondChFields(served.SecondChannel)...)
+ return log.Fields(fields...)
+}
+
+func relayUpdateUplinkListReqFields(req *ttnpb.MACCommand_RelayUpdateUplinkListReq) log.Fielder {
+ fields := []any{
+ "relay_rule_index", req.RuleIndex,
+ "relay_served_dev_addr", types.MustDevAddr(req.DevAddr),
+ "relay_served_w_f_cnt", req.WFCnt,
+ "relay_served_session_key_id", req.SessionKeyId,
+ }
+ if limits := req.ForwardLimits; limits != nil {
+ fields = append(fields,
+ "relay_served_bucket_size", limits.BucketSize,
+ "relay_served_reload_rate", limits.ReloadRate,
+ )
+ }
+ return log.Fields(fields...)
+}
+
+func relayCtrlUplinkListReqFields(req *ttnpb.MACCommand_RelayCtrlUplinkListReq) log.Fielder {
+ return log.Fields(
+ "relay_rule_index", req.RuleIndex,
+ "relay_ctrl_action", req.Action,
+ )
+}
+
+// DeviceDefaultRelayParameters returns the default relay parameters for the given device.
+func DeviceDefaultRelayParameters(dev *ttnpb.EndDevice, defaults *ttnpb.MACSettings) *ttnpb.RelayParameters {
+ switch {
+ case dev.GetMacSettings().GetRelay() != nil:
+ return dev.MacSettings.Relay
+ case defaults.Relay != nil:
+ return defaults.Relay
+ default:
+ return nil
+ }
+}
+
+// DeviceDesiredRelayParameters returns the desired relay parameters for the given device.
+func DeviceDesiredRelayParameters(dev *ttnpb.EndDevice, defaults *ttnpb.MACSettings) *ttnpb.RelayParameters {
+ switch {
+ case dev.GetMacSettings().GetDesiredRelay() != nil:
+ return dev.MacSettings.DesiredRelay
+ case defaults.DesiredRelay != nil:
+ return defaults.DesiredRelay
+ default:
+ return DeviceDefaultRelayParameters(dev, defaults)
+ }
+}
diff --git a/pkg/networkserver/mac/relay_conf.go b/pkg/networkserver/mac/relay_conf.go
new file mode 100644
index 0000000000..73ad57f131
--- /dev/null
+++ b/pkg/networkserver/mac/relay_conf.go
@@ -0,0 +1,164 @@
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package mac
+
+import (
+ "context"
+
+ "go.thethings.network/lorawan-stack/v3/pkg/events"
+ "go.thethings.network/lorawan-stack/v3/pkg/log"
+ "go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
+ "google.golang.org/protobuf/proto"
+)
+
+var (
+ // EvtEnqueueRelayConfRequest is emitted when a relay configuration request is enqueued.
+ EvtEnqueueRelayConfRequest = defineEnqueueMACRequestEvent(
+ "relay_conf", "relay configuration",
+ events.WithDataType(&ttnpb.MACCommand_RelayConfReq{}),
+ )()
+ // EvtReceiveRelayConfAccept is emitted when a relay configuration request is accepted.
+ EvtReceiveRelayConfAccept = defineReceiveMACAcceptEvent(
+ "relay_conf", "relay configuration",
+ events.WithDataType(&ttnpb.MACCommand_RelayConfAns{}),
+ )()
+ // EvtReceiveRelayConfReject is emitted when a relay configuration request is rejected.
+ EvtReceiveRelayConfReject = defineReceiveMACRejectEvent(
+ "relay_conf", "relay configuration",
+ events.WithDataType(&ttnpb.MACCommand_RelayConfAns{}),
+ )()
+)
+
+// DeviceNeedsRelayConfReq returns true iff the device needs a relay configuration request.
+func DeviceNeedsRelayConfReq(dev *ttnpb.EndDevice) bool {
+ if dev.GetMulticast() || dev.GetMacState() == nil {
+ return false
+ }
+ currentServing := dev.MacState.GetCurrentParameters().GetRelay().GetServing()
+ desiredServing := dev.MacState.GetDesiredParameters().GetRelay().GetServing()
+ if desiredServing == nil && currentServing == nil {
+ return false
+ }
+ if (desiredServing == nil) != (currentServing == nil) {
+ return true
+ }
+ // NOTE: The forwarding rules are handled by UpdateUplinkListReq, not RelayConfReq.
+ // NOTE: The limits are handled by ConfigureFwdLimitReq, not RelayConfReq.
+ return !proto.Equal(&ttnpb.ServingRelayParameters{
+ SecondChannel: desiredServing.SecondChannel,
+ DefaultChannelIndex: desiredServing.DefaultChannelIndex,
+ CadPeriodicity: desiredServing.CadPeriodicity,
+ }, &ttnpb.ServingRelayParameters{
+ SecondChannel: currentServing.SecondChannel,
+ DefaultChannelIndex: currentServing.DefaultChannelIndex,
+ CadPeriodicity: currentServing.CadPeriodicity,
+ })
+}
+
+// EnqueueRelayConfReq enqueues a relay configuration request if needed.
+func EnqueueRelayConfReq(ctx context.Context, dev *ttnpb.EndDevice, maxDownLen, maxUpLen uint16) EnqueueState {
+ if !DeviceNeedsRelayConfReq(dev) {
+ return EnqueueState{
+ MaxDownLen: maxDownLen,
+ MaxUpLen: maxUpLen,
+ Ok: true,
+ }
+ }
+ var st EnqueueState
+ dev.MacState.PendingRequests, st = enqueueMACCommand(
+ ttnpb.MACCommandIdentifier_CID_RELAY_CONF,
+ maxDownLen, maxUpLen,
+ func(nDown, nUp uint16) ([]*ttnpb.MACCommand, uint16, events.Builders, bool) {
+ if nDown < 1 || nUp < 1 {
+ return nil, 0, nil, false
+ }
+ desiredServing := dev.MacState.GetDesiredParameters().GetRelay().GetServing()
+ req := &ttnpb.MACCommand_RelayConfReq{}
+ if desiredServing != nil {
+ req.Configuration = &ttnpb.MACCommand_RelayConfReq_Configuration{
+ CadPeriodicity: desiredServing.CadPeriodicity,
+ DefaultChannelIndex: desiredServing.DefaultChannelIndex,
+ SecondChannel: desiredServing.SecondChannel,
+ }
+ }
+ log.FromContext(ctx).WithFields(servingRelayFields(desiredServing)).Debug("Enqueued RelayConfReq")
+ return []*ttnpb.MACCommand{
+ req.MACCommand(),
+ },
+ 1,
+ events.Builders{
+ EvtEnqueueRelayConfRequest.With(events.WithData(req)),
+ },
+ true
+ },
+ dev.MacState.PendingRequests...,
+ )
+ return st
+}
+
+// HandleRelayConfAns handles a relay configuration answer.
+func HandleRelayConfAns(
+ _ context.Context, dev *ttnpb.EndDevice, pld *ttnpb.MACCommand_RelayConfAns,
+) (events.Builders, error) {
+ if pld == nil {
+ return nil, ErrNoPayload.New()
+ }
+ rejected := !pld.SecondChannelFrequencyAck ||
+ !pld.SecondChannelAckOffsetAck ||
+ !pld.SecondChannelDataRateIndexAck ||
+ !pld.SecondChannelIndexAck ||
+ !pld.DefaultChannelIndexAck ||
+ !pld.CadPeriodicityAck
+ var err error
+ dev.MacState.PendingRequests, err = handleMACResponse(
+ ttnpb.MACCommandIdentifier_CID_RELAY_CONF,
+ false,
+ func(cmd *ttnpb.MACCommand) error {
+ if rejected {
+ return nil
+ }
+ req := cmd.GetRelayConfReq()
+ currentParameters := dev.MacState.CurrentParameters
+ if req.Configuration == nil {
+ currentParameters.Relay = nil
+ return nil
+ }
+ relay := currentParameters.Relay
+ if relay == nil {
+ relay = &ttnpb.RelayParameters{}
+ currentParameters.Relay = relay
+ }
+ serving := relay.GetServing()
+ if serving == nil {
+ serving = &ttnpb.ServingRelayParameters{}
+ relay.Mode = &ttnpb.RelayParameters_Serving{
+ Serving: serving,
+ }
+ }
+ serving.CadPeriodicity = req.Configuration.CadPeriodicity
+ serving.DefaultChannelIndex = req.Configuration.DefaultChannelIndex
+ serving.SecondChannel = req.Configuration.SecondChannel
+ return nil
+ },
+ dev.MacState.PendingRequests...,
+ )
+ ev := EvtReceiveRelayConfAccept
+ if rejected {
+ ev = EvtReceiveRelayConfReject
+ }
+ return events.Builders{
+ ev.With(events.WithData(pld)),
+ }, err
+}
diff --git a/pkg/networkserver/mac/relay_conf_test.go b/pkg/networkserver/mac/relay_conf_test.go
new file mode 100644
index 0000000000..898c32b134
--- /dev/null
+++ b/pkg/networkserver/mac/relay_conf_test.go
@@ -0,0 +1,911 @@
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package mac_test
+
+import (
+ "context"
+ "testing"
+
+ "github.com/smarty/assertions"
+ "go.thethings.network/lorawan-stack/v3/pkg/events"
+ "go.thethings.network/lorawan-stack/v3/pkg/networkserver/mac"
+ "go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
+ "go.thethings.network/lorawan-stack/v3/pkg/util/test"
+ "go.thethings.network/lorawan-stack/v3/pkg/util/test/assertions/should"
+)
+
+func TestDeviceNeedsRelayConfReq(t *testing.T) {
+ t.Parallel()
+ for _, tc := range []struct {
+ Name string
+ InputDevice *ttnpb.EndDevice
+ Needs bool
+ }{
+ {
+ Name: "no MAC state",
+ InputDevice: &ttnpb.EndDevice{},
+ },
+ {
+ Name: "no relay",
+ InputDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{},
+ DesiredParameters: &ttnpb.MACParameters{},
+ },
+ },
+ },
+ {
+ Name: "disable serving",
+ InputDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{},
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{},
+ },
+ },
+ Needs: true,
+ },
+ {
+ Name: "enable serving",
+ InputDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{},
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{},
+ },
+ },
+ },
+ },
+ },
+ Needs: true,
+ },
+ {
+ Name: "enable second channel",
+ InputDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{},
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ SecondChannel: &ttnpb.RelaySecondChannel{
+ AckOffset: ttnpb.RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_1600,
+ DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1,
+ Frequency: 123,
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ Needs: true,
+ },
+ {
+ Name: "no change",
+ InputDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ SecondChannel: &ttnpb.RelaySecondChannel{
+ AckOffset: ttnpb.RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_1600,
+ DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1,
+ Frequency: 123,
+ },
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_100_MILLISECONDS,
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ SecondChannel: &ttnpb.RelaySecondChannel{
+ AckOffset: ttnpb.RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_1600,
+ DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1,
+ Frequency: 123,
+ },
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_100_MILLISECONDS,
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ } {
+ tc := tc
+ test.RunSubtest(t, test.SubtestConfig{
+ Name: tc.Name,
+ Parallel: true,
+ Func: func(ctx context.Context, t *testing.T, a *assertions.Assertion) {
+ t.Helper()
+ dev := ttnpb.Clone(tc.InputDevice)
+ res := mac.DeviceNeedsRelayConfReq(dev)
+ if tc.Needs {
+ a.So(res, should.BeTrue)
+ } else {
+ a.So(res, should.BeFalse)
+ }
+ a.So(dev, should.Resemble, tc.InputDevice)
+ },
+ })
+ }
+}
+
+func TestEnqueueRelayConfReq(t *testing.T) {
+ t.Parallel()
+ for _, tc := range []struct {
+ Name string
+ InputDevice, ExpectedDevice *ttnpb.EndDevice
+ MaxDownlinkLength uint16
+ MaxUplinkLength uint16
+ State mac.EnqueueState
+ }{
+ {
+ Name: "enable serving",
+ InputDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{},
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ SecondChannel: &ttnpb.RelaySecondChannel{
+ AckOffset: ttnpb.RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_1600,
+ DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1,
+ Frequency: 123,
+ },
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_100_MILLISECONDS,
+ },
+ },
+ },
+ },
+ },
+ },
+ ExpectedDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{},
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ SecondChannel: &ttnpb.RelaySecondChannel{
+ AckOffset: ttnpb.RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_1600,
+ DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1,
+ Frequency: 123,
+ },
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_100_MILLISECONDS,
+ },
+ },
+ },
+ },
+ PendingRequests: []*ttnpb.MACCommand{
+ (&ttnpb.MACCommand_RelayConfReq{
+ Configuration: &ttnpb.MACCommand_RelayConfReq_Configuration{
+ SecondChannel: &ttnpb.RelaySecondChannel{
+ AckOffset: ttnpb.RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_1600,
+ DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1,
+ Frequency: 123,
+ },
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_100_MILLISECONDS,
+ },
+ }).MACCommand(),
+ },
+ },
+ },
+ MaxDownlinkLength: 50,
+ MaxUplinkLength: 50,
+ State: mac.EnqueueState{
+ MaxDownLen: 44,
+ MaxUpLen: 48,
+ QueuedEvents: events.Builders{
+ mac.EvtEnqueueRelayConfRequest.With(events.WithData(&ttnpb.MACCommand_RelayConfReq{
+ Configuration: &ttnpb.MACCommand_RelayConfReq_Configuration{
+ SecondChannel: &ttnpb.RelaySecondChannel{
+ AckOffset: ttnpb.RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_1600,
+ DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1,
+ Frequency: 123,
+ },
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_100_MILLISECONDS,
+ },
+ })),
+ },
+ Ok: true,
+ },
+ },
+ {
+ Name: "disable serving",
+ InputDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ SecondChannel: &ttnpb.RelaySecondChannel{
+ AckOffset: ttnpb.RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_1600,
+ DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1,
+ Frequency: 123,
+ },
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_100_MILLISECONDS,
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{},
+ },
+ },
+ ExpectedDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ SecondChannel: &ttnpb.RelaySecondChannel{
+ AckOffset: ttnpb.RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_1600,
+ DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1,
+ Frequency: 123,
+ },
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_100_MILLISECONDS,
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{},
+ PendingRequests: []*ttnpb.MACCommand{
+ (&ttnpb.MACCommand_RelayConfReq{
+ Configuration: nil,
+ }).MACCommand(),
+ },
+ },
+ },
+ MaxDownlinkLength: 50,
+ MaxUplinkLength: 50,
+ State: mac.EnqueueState{
+ MaxDownLen: 44,
+ MaxUpLen: 48,
+ QueuedEvents: events.Builders{
+ mac.EvtEnqueueRelayConfRequest.With(events.WithData(&ttnpb.MACCommand_RelayConfReq{
+ Configuration: nil,
+ })),
+ },
+ Ok: true,
+ },
+ },
+ {
+ Name: "disable second channel",
+ InputDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ SecondChannel: &ttnpb.RelaySecondChannel{
+ AckOffset: ttnpb.RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_1600,
+ DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1,
+ Frequency: 123,
+ },
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_100_MILLISECONDS,
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_100_MILLISECONDS,
+ },
+ },
+ },
+ },
+ },
+ },
+ ExpectedDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ SecondChannel: &ttnpb.RelaySecondChannel{
+ AckOffset: ttnpb.RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_1600,
+ DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1,
+ Frequency: 123,
+ },
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_100_MILLISECONDS,
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_100_MILLISECONDS,
+ },
+ },
+ },
+ },
+ PendingRequests: []*ttnpb.MACCommand{
+ (&ttnpb.MACCommand_RelayConfReq{
+ Configuration: &ttnpb.MACCommand_RelayConfReq_Configuration{
+ SecondChannel: nil,
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_100_MILLISECONDS,
+ },
+ }).MACCommand(),
+ },
+ },
+ },
+ MaxDownlinkLength: 50,
+ MaxUplinkLength: 50,
+ State: mac.EnqueueState{
+ MaxDownLen: 44,
+ MaxUpLen: 48,
+ QueuedEvents: events.Builders{
+ mac.EvtEnqueueRelayConfRequest.With(events.WithData(&ttnpb.MACCommand_RelayConfReq{
+ Configuration: &ttnpb.MACCommand_RelayConfReq_Configuration{
+ SecondChannel: nil,
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_100_MILLISECONDS,
+ },
+ })),
+ },
+ Ok: true,
+ },
+ },
+ {
+ Name: "enable second channel",
+ InputDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_100_MILLISECONDS,
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ SecondChannel: &ttnpb.RelaySecondChannel{
+ AckOffset: ttnpb.RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_1600,
+ DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1,
+ Frequency: 123,
+ },
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_100_MILLISECONDS,
+ },
+ },
+ },
+ },
+ },
+ },
+ ExpectedDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_100_MILLISECONDS,
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ SecondChannel: &ttnpb.RelaySecondChannel{
+ AckOffset: ttnpb.RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_1600,
+ DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1,
+ Frequency: 123,
+ },
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_100_MILLISECONDS,
+ },
+ },
+ },
+ },
+ PendingRequests: []*ttnpb.MACCommand{
+ (&ttnpb.MACCommand_RelayConfReq{
+ Configuration: &ttnpb.MACCommand_RelayConfReq_Configuration{
+ SecondChannel: &ttnpb.RelaySecondChannel{
+ AckOffset: ttnpb.RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_1600,
+ DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1,
+ Frequency: 123,
+ },
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_100_MILLISECONDS,
+ },
+ }).MACCommand(),
+ },
+ },
+ },
+ MaxDownlinkLength: 50,
+ MaxUplinkLength: 50,
+ State: mac.EnqueueState{
+ MaxDownLen: 44,
+ MaxUpLen: 48,
+ QueuedEvents: events.Builders{
+ mac.EvtEnqueueRelayConfRequest.With(events.WithData(&ttnpb.MACCommand_RelayConfReq{
+ Configuration: &ttnpb.MACCommand_RelayConfReq_Configuration{
+ SecondChannel: &ttnpb.RelaySecondChannel{
+ AckOffset: ttnpb.RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_1600,
+ DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1,
+ Frequency: 123,
+ },
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_100_MILLISECONDS,
+ },
+ })),
+ },
+ Ok: true,
+ },
+ },
+ } {
+ tc := tc
+ test.RunSubtest(t, test.SubtestConfig{
+ Name: tc.Name,
+ Parallel: true,
+ Func: func(ctx context.Context, t *testing.T, a *assertions.Assertion) {
+ t.Helper()
+ dev := ttnpb.Clone(tc.InputDevice)
+ st := mac.EnqueueRelayConfReq(ctx, dev, tc.MaxDownlinkLength, tc.MaxUplinkLength)
+ a.So(dev, should.Resemble, tc.ExpectedDevice)
+ a.So(st.QueuedEvents, should.ResembleEventBuilders, tc.State.QueuedEvents)
+ st.QueuedEvents = tc.State.QueuedEvents
+ a.So(st, should.Resemble, tc.State)
+ },
+ })
+ }
+}
+
+func TestHandleRelayConfAns(t *testing.T) {
+ t.Parallel()
+ for _, tc := range []struct {
+ Name string
+ Device, Expected *ttnpb.EndDevice
+ Payload *ttnpb.MACCommand_RelayConfAns
+ Events events.Builders
+ Error error
+ }{
+ {
+ Name: "reject serving",
+ Device: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{},
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ SecondChannel: &ttnpb.RelaySecondChannel{
+ AckOffset: ttnpb.RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_3200,
+ DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1,
+ Frequency: 123,
+ },
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_1_SECOND,
+ },
+ },
+ },
+ },
+ PendingRequests: []*ttnpb.MACCommand{
+ (&ttnpb.MACCommand_RelayConfReq{
+ Configuration: &ttnpb.MACCommand_RelayConfReq_Configuration{
+ SecondChannel: &ttnpb.RelaySecondChannel{
+ AckOffset: ttnpb.RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_3200,
+ DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1,
+ Frequency: 123,
+ },
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_1_SECOND,
+ },
+ }).MACCommand(),
+ },
+ },
+ },
+ Expected: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{},
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ SecondChannel: &ttnpb.RelaySecondChannel{
+ AckOffset: ttnpb.RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_3200,
+ DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1,
+ Frequency: 123,
+ },
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_1_SECOND,
+ },
+ },
+ },
+ },
+ },
+ },
+ Payload: &ttnpb.MACCommand_RelayConfAns{},
+ Events: events.Builders{
+ mac.EvtReceiveRelayConfReject.With(events.WithData(&ttnpb.MACCommand_RelayConfAns{})),
+ },
+ },
+ {
+ Name: "enable serving",
+ Device: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{},
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ SecondChannel: &ttnpb.RelaySecondChannel{
+ AckOffset: ttnpb.RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_3200,
+ DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1,
+ Frequency: 123,
+ },
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_1_SECOND,
+ },
+ },
+ },
+ },
+ PendingRequests: []*ttnpb.MACCommand{
+ (&ttnpb.MACCommand_RelayConfReq{
+ Configuration: &ttnpb.MACCommand_RelayConfReq_Configuration{
+ SecondChannel: &ttnpb.RelaySecondChannel{
+ AckOffset: ttnpb.RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_3200,
+ DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1,
+ Frequency: 123,
+ },
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_1_SECOND,
+ },
+ }).MACCommand(),
+ },
+ },
+ },
+ Expected: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ SecondChannel: &ttnpb.RelaySecondChannel{
+ AckOffset: ttnpb.RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_3200,
+ DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1,
+ Frequency: 123,
+ },
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_1_SECOND,
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ SecondChannel: &ttnpb.RelaySecondChannel{
+ AckOffset: ttnpb.RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_3200,
+ DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1,
+ Frequency: 123,
+ },
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_1_SECOND,
+ },
+ },
+ },
+ },
+ },
+ },
+ Payload: &ttnpb.MACCommand_RelayConfAns{
+ SecondChannelFrequencyAck: true,
+ SecondChannelAckOffsetAck: true,
+ SecondChannelDataRateIndexAck: true,
+ SecondChannelIndexAck: true,
+ DefaultChannelIndexAck: true,
+ CadPeriodicityAck: true,
+ },
+ Events: events.Builders{
+ mac.EvtReceiveRelayConfAccept.With(events.WithData(&ttnpb.MACCommand_RelayConfAns{
+ SecondChannelFrequencyAck: true,
+ SecondChannelAckOffsetAck: true,
+ SecondChannelDataRateIndexAck: true,
+ SecondChannelIndexAck: true,
+ DefaultChannelIndexAck: true,
+ CadPeriodicityAck: true,
+ })),
+ },
+ },
+ {
+ Name: "disable serving",
+ Device: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ SecondChannel: &ttnpb.RelaySecondChannel{
+ AckOffset: ttnpb.RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_3200,
+ DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1,
+ Frequency: 123,
+ },
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_1_SECOND,
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{},
+ PendingRequests: []*ttnpb.MACCommand{(&ttnpb.MACCommand_RelayConfReq{}).MACCommand()},
+ },
+ },
+ Expected: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{},
+ DesiredParameters: &ttnpb.MACParameters{},
+ },
+ },
+ Payload: &ttnpb.MACCommand_RelayConfAns{
+ SecondChannelFrequencyAck: true,
+ SecondChannelAckOffsetAck: true,
+ SecondChannelDataRateIndexAck: true,
+ SecondChannelIndexAck: true,
+ DefaultChannelIndexAck: true,
+ CadPeriodicityAck: true,
+ },
+ Events: events.Builders{
+ mac.EvtReceiveRelayConfAccept.With(events.WithData(&ttnpb.MACCommand_RelayConfAns{
+ SecondChannelFrequencyAck: true,
+ SecondChannelAckOffsetAck: true,
+ SecondChannelDataRateIndexAck: true,
+ SecondChannelIndexAck: true,
+ DefaultChannelIndexAck: true,
+ CadPeriodicityAck: true,
+ })),
+ },
+ },
+ {
+ Name: "enable second channel",
+ Device: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_1_SECOND,
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ SecondChannel: &ttnpb.RelaySecondChannel{
+ AckOffset: ttnpb.RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_3200,
+ DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1,
+ Frequency: 123,
+ },
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_1_SECOND,
+ },
+ },
+ },
+ },
+ PendingRequests: []*ttnpb.MACCommand{
+ (&ttnpb.MACCommand_RelayConfReq{
+ Configuration: &ttnpb.MACCommand_RelayConfReq_Configuration{
+ SecondChannel: &ttnpb.RelaySecondChannel{
+ AckOffset: ttnpb.RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_3200,
+ DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1,
+ Frequency: 123,
+ },
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_1_SECOND,
+ },
+ }).MACCommand(),
+ },
+ },
+ },
+ Expected: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ SecondChannel: &ttnpb.RelaySecondChannel{
+ AckOffset: ttnpb.RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_3200,
+ DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1,
+ Frequency: 123,
+ },
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_1_SECOND,
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ SecondChannel: &ttnpb.RelaySecondChannel{
+ AckOffset: ttnpb.RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_3200,
+ DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1,
+ Frequency: 123,
+ },
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_1_SECOND,
+ },
+ },
+ },
+ },
+ },
+ },
+ Payload: &ttnpb.MACCommand_RelayConfAns{
+ SecondChannelFrequencyAck: true,
+ SecondChannelAckOffsetAck: true,
+ SecondChannelDataRateIndexAck: true,
+ SecondChannelIndexAck: true,
+ DefaultChannelIndexAck: true,
+ CadPeriodicityAck: true,
+ },
+ Events: events.Builders{
+ mac.EvtReceiveRelayConfAccept.With(events.WithData(&ttnpb.MACCommand_RelayConfAns{
+ SecondChannelFrequencyAck: true,
+ SecondChannelAckOffsetAck: true,
+ SecondChannelDataRateIndexAck: true,
+ SecondChannelIndexAck: true,
+ DefaultChannelIndexAck: true,
+ CadPeriodicityAck: true,
+ })),
+ },
+ },
+ {
+ Name: "disable second channel",
+ Device: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ SecondChannel: &ttnpb.RelaySecondChannel{
+ AckOffset: ttnpb.RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_3200,
+ DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1,
+ Frequency: 123,
+ },
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_1_SECOND,
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_1_SECOND,
+ },
+ },
+ },
+ },
+ PendingRequests: []*ttnpb.MACCommand{
+ (&ttnpb.MACCommand_RelayConfReq{
+ Configuration: &ttnpb.MACCommand_RelayConfReq_Configuration{
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_1_SECOND,
+ },
+ }).MACCommand(),
+ },
+ },
+ },
+ Expected: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_1_SECOND,
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ DefaultChannelIndex: 1,
+ CadPeriodicity: ttnpb.RelayCADPeriodicity_RELAY_CAD_PERIODICITY_1_SECOND,
+ },
+ },
+ },
+ },
+ },
+ },
+ Payload: &ttnpb.MACCommand_RelayConfAns{
+ SecondChannelFrequencyAck: true,
+ SecondChannelAckOffsetAck: true,
+ SecondChannelDataRateIndexAck: true,
+ SecondChannelIndexAck: true,
+ DefaultChannelIndexAck: true,
+ CadPeriodicityAck: true,
+ },
+ Events: events.Builders{
+ mac.EvtReceiveRelayConfAccept.With(events.WithData(&ttnpb.MACCommand_RelayConfAns{
+ SecondChannelFrequencyAck: true,
+ SecondChannelAckOffsetAck: true,
+ SecondChannelDataRateIndexAck: true,
+ SecondChannelIndexAck: true,
+ DefaultChannelIndexAck: true,
+ CadPeriodicityAck: true,
+ })),
+ },
+ },
+ } {
+ tc := tc
+ test.RunSubtest(t, test.SubtestConfig{
+ Name: tc.Name,
+ Parallel: true,
+ Func: func(ctx context.Context, t *testing.T, a *assertions.Assertion) {
+ t.Helper()
+ dev := ttnpb.Clone(tc.Device)
+ evs, err := mac.HandleRelayConfAns(ctx, dev, tc.Payload)
+ if tc.Error != nil && !a.So(err, should.EqualErrorOrDefinition, tc.Error) ||
+ tc.Error == nil && !a.So(err, should.BeNil) {
+ t.FailNow()
+ }
+ a.So(dev, should.Resemble, tc.Expected)
+ a.So(evs, should.ResembleEventBuilders, tc.Events)
+ },
+ })
+ }
+}
diff --git a/pkg/networkserver/mac/relay_configure_fwd_limit.go b/pkg/networkserver/mac/relay_configure_fwd_limit.go
new file mode 100644
index 0000000000..1064f649fb
--- /dev/null
+++ b/pkg/networkserver/mac/relay_configure_fwd_limit.go
@@ -0,0 +1,159 @@
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package mac
+
+import (
+ "context"
+
+ "go.thethings.network/lorawan-stack/v3/pkg/events"
+ "go.thethings.network/lorawan-stack/v3/pkg/log"
+ "go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
+ "google.golang.org/protobuf/proto"
+)
+
+var (
+ // defaultRelayForwardingLimits is the default relay forward limits, based on the contents of the
+ // relay specification.
+ defaultRelayForwardingLimits = &ttnpb.ServingRelayForwardingLimits{
+ JoinRequests: &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_2,
+ ReloadRate: 4,
+ },
+ Notifications: &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_2,
+ ReloadRate: 4,
+ },
+ UplinkMessages: &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_2,
+ ReloadRate: 8,
+ },
+ Overall: &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_2,
+ ReloadRate: 8,
+ },
+ }
+
+ // EvtEnqueueRelayConfigureFwdLimitRequest is emitted when a relay forward limits configuration request is enqueued.
+ EvtEnqueueRelayConfigureFwdLimitRequest = defineEnqueueMACRequestEvent(
+ "relay_configure_fwd_limit", "relay configure forward limit",
+ events.WithDataType(&ttnpb.MACCommand_RelayConfigureFwdLimitReq{}),
+ )()
+ // EvtReceiveRelayConfigureFwdLimitAnswer is emitted when a relay forward limits configuration request is answered.
+ EvtReceiveRelayConfigureFwdLimitAnswer = defineReceiveMACAnswerEvent(
+ "relay_configure_fwd_limit", "relay configure forward limit",
+ events.WithDataType(&ttnpb.MACCommand_RelayConfigureFwdLimitAns{}),
+ )()
+)
+
+// DeviceNeedsRelayConfigureFwdLimitReq returns true iff the device needs a relay forward limits configuration request.
+func DeviceNeedsRelayConfigureFwdLimitReq(dev *ttnpb.EndDevice) bool {
+ if dev.GetMulticast() || dev.GetMacState() == nil {
+ return false
+ }
+ currentLimits := dev.MacState.GetCurrentParameters().GetRelay().GetServing().GetLimits()
+ desiredLimits := dev.MacState.GetDesiredParameters().GetRelay().GetServing().GetLimits()
+ if desiredLimits == nil && currentLimits == nil {
+ return false
+ }
+ if currentLimits == nil {
+ currentLimits = defaultRelayForwardingLimits
+ }
+ if desiredLimits == nil {
+ desiredLimits = defaultRelayForwardingLimits
+ }
+ return !proto.Equal(desiredLimits, currentLimits)
+}
+
+// EnqueueRelayConfigureFwdLimitReq enqueues a relay forward limits configuration request if needed.
+func EnqueueRelayConfigureFwdLimitReq(
+ ctx context.Context, dev *ttnpb.EndDevice, maxDownLen, maxUpLen uint16,
+) EnqueueState {
+ if !DeviceNeedsRelayConfigureFwdLimitReq(dev) {
+ return EnqueueState{
+ MaxDownLen: maxDownLen,
+ MaxUpLen: maxUpLen,
+ Ok: true,
+ }
+ }
+ var st EnqueueState
+ dev.MacState.PendingRequests, st = enqueueMACCommand(
+ ttnpb.MACCommandIdentifier_CID_RELAY_CONFIGURE_FWD_LIMIT,
+ maxDownLen, maxUpLen,
+ func(nDown, nUp uint16) ([]*ttnpb.MACCommand, uint16, events.Builders, bool) {
+ if nDown < 1 || nUp < 1 {
+ return nil, 0, nil, false
+ }
+ desiredLimits := dev.MacState.GetDesiredParameters().GetRelay().GetServing().GetLimits()
+ if desiredLimits == nil {
+ desiredLimits = defaultRelayForwardingLimits
+ }
+ req := &ttnpb.MACCommand_RelayConfigureFwdLimitReq{
+ ResetLimitCounter: desiredLimits.ResetBehavior,
+ JoinRequestLimits: desiredLimits.JoinRequests,
+ NotifyLimits: desiredLimits.Notifications,
+ GlobalUplinkLimits: desiredLimits.UplinkMessages,
+ OverallLimits: desiredLimits.Overall,
+ }
+ log.FromContext(ctx).WithFields(relayConfigureForwardLimitsFields(desiredLimits)).
+ Debug("Enqueued RelayConfigureFwdLimitReq")
+ return []*ttnpb.MACCommand{
+ req.MACCommand(),
+ },
+ 1,
+ events.Builders{
+ EvtEnqueueRelayConfigureFwdLimitRequest.With(events.WithData(req)),
+ },
+ true
+ },
+ dev.MacState.PendingRequests...,
+ )
+ return st
+}
+
+// HandleRelayConfigureFwdLimitAns handles a relay forward limits configuration answer.
+func HandleRelayConfigureFwdLimitAns(
+ _ context.Context, dev *ttnpb.EndDevice, pld *ttnpb.MACCommand_RelayConfigureFwdLimitAns,
+) (events.Builders, error) {
+ if pld == nil {
+ return nil, ErrNoPayload.New()
+ }
+ var err error
+ dev.MacState.PendingRequests, err = handleMACResponse(
+ ttnpb.MACCommandIdentifier_CID_RELAY_CONFIGURE_FWD_LIMIT,
+ false,
+ func(cmd *ttnpb.MACCommand) error {
+ req := cmd.GetRelayConfigureFwdLimitReq()
+ currentServing := dev.MacState.GetCurrentParameters().GetRelay().GetServing()
+ if currentServing == nil {
+ // NOTE: EnqueueRelayConfigureFwdLimitReq is optimistic and assumes that EnqueueRelayConfReq
+ // has enqueued the desired relay parameters, and that the end device will accept them. If
+ // either of these conditions is not true, the current serving parameters will be nil.
+ return nil
+ }
+ currentServing.Limits = &ttnpb.ServingRelayForwardingLimits{
+ ResetBehavior: req.ResetLimitCounter,
+ JoinRequests: req.JoinRequestLimits,
+ Notifications: req.NotifyLimits,
+ UplinkMessages: req.GlobalUplinkLimits,
+ Overall: req.OverallLimits,
+ }
+ return nil
+ },
+ dev.MacState.PendingRequests...,
+ )
+ return events.Builders{
+ EvtReceiveRelayConfigureFwdLimitAnswer.With(events.WithData(pld)),
+ }, err
+}
diff --git a/pkg/networkserver/mac/relay_configure_fwd_limit_test.go b/pkg/networkserver/mac/relay_configure_fwd_limit_test.go
new file mode 100644
index 0000000000..ef541b4886
--- /dev/null
+++ b/pkg/networkserver/mac/relay_configure_fwd_limit_test.go
@@ -0,0 +1,519 @@
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package mac_test
+
+import (
+ "context"
+ "testing"
+
+ "github.com/smarty/assertions"
+ "go.thethings.network/lorawan-stack/v3/pkg/events"
+ "go.thethings.network/lorawan-stack/v3/pkg/networkserver/mac"
+ "go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
+ "go.thethings.network/lorawan-stack/v3/pkg/util/test"
+ "go.thethings.network/lorawan-stack/v3/pkg/util/test/assertions/should"
+)
+
+func TestDeviceNeedsRelayConfigureFwdLimitReq(t *testing.T) {
+ t.Parallel()
+ for _, tc := range []struct {
+ Name string
+ InputDevice *ttnpb.EndDevice
+ Needs bool
+ }{
+ {
+ Name: "no MAC state",
+ InputDevice: &ttnpb.EndDevice{},
+ },
+ {
+ Name: "no relay",
+ InputDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{},
+ DesiredParameters: &ttnpb.MACParameters{},
+ },
+ },
+ },
+ {
+ Name: "no limits",
+ InputDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{},
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ Limits: &ttnpb.ServingRelayForwardingLimits{},
+ },
+ },
+ },
+ },
+ },
+ },
+ Needs: true,
+ },
+ {
+ Name: "some limits",
+ InputDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{},
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ Limits: &ttnpb.ServingRelayForwardingLimits{
+ JoinRequests: &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_2,
+ ReloadRate: 12,
+ },
+ Overall: &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_4,
+ ReloadRate: 23,
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ Needs: true,
+ },
+ {
+ Name: "no change",
+ InputDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ Limits: &ttnpb.ServingRelayForwardingLimits{
+ JoinRequests: &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_2,
+ ReloadRate: 12,
+ },
+ Overall: &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_4,
+ ReloadRate: 23,
+ },
+ },
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ Limits: &ttnpb.ServingRelayForwardingLimits{
+ JoinRequests: &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_2,
+ ReloadRate: 12,
+ },
+ Overall: &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_4,
+ ReloadRate: 23,
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ } {
+ tc := tc
+ test.RunSubtest(t, test.SubtestConfig{
+ Name: tc.Name,
+ Parallel: true,
+ Func: func(ctx context.Context, t *testing.T, a *assertions.Assertion) {
+ t.Helper()
+ dev := ttnpb.Clone(tc.InputDevice)
+ res := mac.DeviceNeedsRelayConfigureFwdLimitReq(dev)
+ if tc.Needs {
+ a.So(res, should.BeTrue)
+ } else {
+ a.So(res, should.BeFalse)
+ }
+ a.So(dev, should.Resemble, tc.InputDevice)
+ },
+ })
+ }
+}
+
+func TestEnqueueRelayConfigureFwdLimitReq(t *testing.T) {
+ t.Parallel()
+ for _, tc := range []struct {
+ Name string
+ InputDevice, ExpectedDevice *ttnpb.EndDevice
+ MaxDownlinkLength uint16
+ MaxUplinkLength uint16
+ State mac.EnqueueState
+ }{
+ {
+ Name: "no limits",
+ InputDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{},
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ Limits: &ttnpb.ServingRelayForwardingLimits{},
+ },
+ },
+ },
+ },
+ },
+ },
+ ExpectedDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{},
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ Limits: &ttnpb.ServingRelayForwardingLimits{},
+ },
+ },
+ },
+ },
+ PendingRequests: []*ttnpb.MACCommand{
+ (&ttnpb.MACCommand_RelayConfigureFwdLimitReq{}).MACCommand(),
+ },
+ },
+ },
+ MaxDownlinkLength: 50,
+ MaxUplinkLength: 50,
+ State: mac.EnqueueState{
+ MaxDownLen: 44,
+ MaxUpLen: 49,
+ QueuedEvents: events.Builders{
+ mac.EvtEnqueueRelayConfigureFwdLimitRequest.With(events.WithData(
+ &ttnpb.MACCommand_RelayConfigureFwdLimitReq{},
+ )),
+ },
+ Ok: true,
+ },
+ },
+ {
+ Name: "some limits",
+ InputDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{},
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ Limits: &ttnpb.ServingRelayForwardingLimits{
+ JoinRequests: &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_2,
+ ReloadRate: 12,
+ },
+ Overall: &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_4,
+ ReloadRate: 23,
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ ExpectedDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{},
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ Limits: &ttnpb.ServingRelayForwardingLimits{
+ JoinRequests: &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_2,
+ ReloadRate: 12,
+ },
+ Overall: &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_4,
+ ReloadRate: 23,
+ },
+ },
+ },
+ },
+ },
+ },
+ PendingRequests: []*ttnpb.MACCommand{
+ (&ttnpb.MACCommand_RelayConfigureFwdLimitReq{
+ JoinRequestLimits: &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_2,
+ ReloadRate: 12,
+ },
+ OverallLimits: &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_4,
+ ReloadRate: 23,
+ },
+ }).MACCommand(),
+ },
+ },
+ },
+ MaxDownlinkLength: 50,
+ MaxUplinkLength: 50,
+ State: mac.EnqueueState{
+ MaxDownLen: 44,
+ MaxUpLen: 49,
+ QueuedEvents: events.Builders{
+ mac.EvtEnqueueRelayConfigureFwdLimitRequest.With(events.WithData(
+ &ttnpb.MACCommand_RelayConfigureFwdLimitReq{
+ JoinRequestLimits: &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_2,
+ ReloadRate: 12,
+ },
+ OverallLimits: &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_4,
+ ReloadRate: 23,
+ },
+ },
+ )),
+ },
+ Ok: true,
+ },
+ },
+ } {
+ tc := tc
+ test.RunSubtest(t, test.SubtestConfig{
+ Name: tc.Name,
+ Parallel: true,
+ Func: func(ctx context.Context, t *testing.T, a *assertions.Assertion) {
+ t.Helper()
+ dev := ttnpb.Clone(tc.InputDevice)
+ st := mac.EnqueueRelayConfigureFwdLimitReq(ctx, dev, tc.MaxDownlinkLength, tc.MaxUplinkLength)
+ a.So(dev, should.Resemble, tc.ExpectedDevice)
+ a.So(st.QueuedEvents, should.ResembleEventBuilders, tc.State.QueuedEvents)
+ st.QueuedEvents = tc.State.QueuedEvents
+ a.So(st, should.Resemble, tc.State)
+ },
+ })
+ }
+}
+
+func TestHandleRelayConfigureFwdLimitAns(t *testing.T) {
+ t.Parallel()
+ for _, tc := range []struct {
+ Name string
+ Device, Expected *ttnpb.EndDevice
+ Payload *ttnpb.MACCommand_RelayConfigureFwdLimitAns
+ Events events.Builders
+ Error error
+ }{
+ {
+ Name: "no limits",
+ Device: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{},
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ Limits: &ttnpb.ServingRelayForwardingLimits{},
+ },
+ },
+ },
+ },
+ PendingRequests: []*ttnpb.MACCommand{
+ (&ttnpb.MACCommand_RelayConfigureFwdLimitReq{}).MACCommand(),
+ },
+ },
+ },
+ Expected: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ Limits: &ttnpb.ServingRelayForwardingLimits{},
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ Limits: &ttnpb.ServingRelayForwardingLimits{},
+ },
+ },
+ },
+ },
+ },
+ },
+ Payload: &ttnpb.MACCommand_RelayConfigureFwdLimitAns{},
+ Events: events.Builders{
+ mac.EvtReceiveRelayConfigureFwdLimitAnswer.With(events.WithData(
+ &ttnpb.MACCommand_RelayConfigureFwdLimitAns{},
+ )),
+ },
+ },
+ {
+ Name: "some limits",
+ Device: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{},
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ Limits: &ttnpb.ServingRelayForwardingLimits{
+ JoinRequests: &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_2,
+ ReloadRate: 12,
+ },
+ Overall: &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_4,
+ ReloadRate: 23,
+ },
+ },
+ },
+ },
+ },
+ },
+ PendingRequests: []*ttnpb.MACCommand{
+ (&ttnpb.MACCommand_RelayConfigureFwdLimitReq{
+ JoinRequestLimits: &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_2,
+ ReloadRate: 12,
+ },
+ OverallLimits: &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_4,
+ ReloadRate: 23,
+ },
+ }).MACCommand(),
+ },
+ },
+ },
+ Expected: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ Limits: &ttnpb.ServingRelayForwardingLimits{
+ JoinRequests: &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_2,
+ ReloadRate: 12,
+ },
+ Overall: &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_4,
+ ReloadRate: 23,
+ },
+ },
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ Limits: &ttnpb.ServingRelayForwardingLimits{
+ JoinRequests: &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_2,
+ ReloadRate: 12,
+ },
+ Overall: &ttnpb.RelayForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_4,
+ ReloadRate: 23,
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ Payload: &ttnpb.MACCommand_RelayConfigureFwdLimitAns{},
+ Events: events.Builders{
+ mac.EvtReceiveRelayConfigureFwdLimitAnswer.With(events.WithData(
+ &ttnpb.MACCommand_RelayConfigureFwdLimitAns{},
+ )),
+ },
+ },
+ } {
+ tc := tc
+ test.RunSubtest(t, test.SubtestConfig{
+ Name: tc.Name,
+ Parallel: true,
+ Func: func(ctx context.Context, t *testing.T, a *assertions.Assertion) {
+ t.Helper()
+ dev := ttnpb.Clone(tc.Device)
+ evs, err := mac.HandleRelayConfigureFwdLimitAns(ctx, dev, tc.Payload)
+ if tc.Error != nil && !a.So(err, should.EqualErrorOrDefinition, tc.Error) ||
+ tc.Error == nil && !a.So(err, should.BeNil) {
+ t.FailNow()
+ }
+ a.So(dev, should.Resemble, tc.Expected)
+ a.So(evs, should.ResembleEventBuilders, tc.Events)
+ },
+ })
+ }
+}
diff --git a/pkg/networkserver/mac/relay_ctrl_uplink_list.go b/pkg/networkserver/mac/relay_ctrl_uplink_list.go
new file mode 100644
index 0000000000..448aea44c4
--- /dev/null
+++ b/pkg/networkserver/mac/relay_ctrl_uplink_list.go
@@ -0,0 +1,171 @@
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package mac
+
+import (
+ "context"
+
+ "go.thethings.network/lorawan-stack/v3/pkg/events"
+ "go.thethings.network/lorawan-stack/v3/pkg/log"
+ "go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
+ "google.golang.org/protobuf/proto"
+)
+
+var (
+ // EvtEnqueueRelayCtrlUplinkListRequest is emitted when a relay control uplink list request is enqueued.
+ EvtEnqueueRelayCtrlUplinkListRequest = defineEnqueueMACRequestEvent(
+ "relay_ctrl_uplink_list", "relay control uplink list",
+ events.WithDataType(&ttnpb.MACCommand_RelayCtrlUplinkListReq{}),
+ )()
+ // EvtReceiveRelayCtrlUplinkListAccept is emitted when a relay control uplink list request is accepted.
+ EvtReceiveRelayCtrlUplinkListAccept = defineReceiveMACAcceptEvent(
+ "relay_ctrl_uplink_list", "relay control uplink list",
+ events.WithDataType(&ttnpb.MACCommand_RelayCtrlUplinkListAns{}),
+ )()
+ // EvtReceiveRelayCtrlUplinkListReject is emitted when a relay control uplink list request is rejected.
+ EvtReceiveRelayCtrlUplinkListReject = defineReceiveMACRejectEvent(
+ "relay_ctrl_uplink_list", "relay control uplink list",
+ events.WithDataType(&ttnpb.MACCommand_RelayCtrlUplinkListAns{}),
+ )()
+)
+
+// DeviceNeedsRelayCtrlUplinkListReqAtIndex returns true iff the device needs a relay
+// control uplink list request at the given index.
+func DeviceNeedsRelayCtrlUplinkListReqAtIndex(dev *ttnpb.EndDevice, i int) bool {
+ currentRules := dev.GetMacState().GetCurrentParameters().GetRelay().GetServing().GetUplinkForwardingRules()
+ desiredRules := dev.GetMacState().GetDesiredParameters().GetRelay().GetServing().GetUplinkForwardingRules()
+ switch {
+ case i >= len(currentRules) && i >= len(desiredRules):
+ case i >= len(desiredRules), proto.Equal(desiredRules[i], emptyRelayUplinkForwardingRule):
+ // A rule is desired to be deleted.
+ return !proto.Equal(currentRules[i], emptyRelayUplinkForwardingRule)
+ case i >= len(currentRules), proto.Equal(currentRules[i], emptyRelayUplinkForwardingRule):
+ // A rule is desired to be created.
+ // NOTE: CtrlUplinkListReq cannot delete a forwarding rule.
+ default:
+ // NOTE: CtrlUplinkListReq cannot update a forwarding rule.
+ }
+ return false
+}
+
+// DeviceNeedsRelayCtrlUplinkListReq returns true iff the device needs a relay control uplink list request.
+func DeviceNeedsRelayCtrlUplinkListReq(dev *ttnpb.EndDevice) bool {
+ if dev.GetMulticast() || dev.GetMacState() == nil {
+ return false
+ }
+ currentServing := dev.MacState.GetCurrentParameters().GetRelay().GetServing()
+ desiredServing := dev.MacState.GetDesiredParameters().GetRelay().GetServing()
+ if desiredServing == nil {
+ return false
+ }
+ for i := range currentServing.GetUplinkForwardingRules() {
+ if DeviceNeedsRelayCtrlUplinkListReqAtIndex(dev, i) {
+ return true
+ }
+ }
+ return false
+}
+
+// EnqueueRelayCtrlUplinkListReq enqueues a relay control uplink list request.
+func EnqueueRelayCtrlUplinkListReq(
+ ctx context.Context, dev *ttnpb.EndDevice, maxDownLen, maxUpLen uint16,
+) EnqueueState {
+ if !DeviceNeedsRelayCtrlUplinkListReq(dev) {
+ return EnqueueState{
+ MaxDownLen: maxDownLen,
+ MaxUpLen: maxUpLen,
+ Ok: true,
+ }
+ }
+ var st EnqueueState
+ dev.MacState.PendingRequests, st = enqueueMACCommand(
+ ttnpb.MACCommandIdentifier_CID_RELAY_CTRL_UPLINK_LIST,
+ maxDownLen, maxUpLen,
+ func(nDown, nUp uint16) ([]*ttnpb.MACCommand, uint16, events.Builders, bool) {
+ if nDown < 1 || nUp < 1 {
+ return nil, 0, nil, false
+ }
+ currentRules := dev.MacState.GetCurrentParameters().GetRelay().GetServing().GetUplinkForwardingRules()
+ desiredRules := dev.MacState.DesiredParameters.Relay.GetServing().UplinkForwardingRules
+ var reqs []*ttnpb.MACCommand_RelayCtrlUplinkListReq
+ for i := 0; i < len(currentRules); i++ {
+ switch {
+ case !DeviceNeedsRelayCtrlUplinkListReqAtIndex(dev, i):
+ case i >= len(desiredRules), proto.Equal(desiredRules[i], emptyRelayUplinkForwardingRule):
+ reqs = append(reqs, &ttnpb.MACCommand_RelayCtrlUplinkListReq{
+ RuleIndex: uint32(i),
+ Action: ttnpb.RelayCtrlUplinkListAction_RELAY_CTRL_UPLINK_LIST_ACTION_REMOVE_TRUSTED_END_DEVICE,
+ })
+ }
+ }
+ cmds := make([]*ttnpb.MACCommand, 0, len(reqs))
+ evs := make(events.Builders, 0, len(reqs))
+ for _, req := range reqs {
+ if nDown < 1 || nUp < 1 {
+ return cmds, uint16(len(cmds)), evs, false
+ }
+ nDown--
+ nUp--
+ log.FromContext(ctx).WithFields(relayCtrlUplinkListReqFields(req)).
+ Debug("Enqueued RelayCtrlUplinkListReq")
+ cmds = append(cmds, req.MACCommand())
+ evs = append(evs, EvtEnqueueRelayCtrlUplinkListRequest.With(events.WithData(req)))
+ }
+ return cmds, uint16(len(cmds)), evs, true
+ },
+ dev.MacState.PendingRequests...,
+ )
+ return st
+}
+
+// HandleRelayCtrlUplinkListAns handles a relay control uplink list answer.
+func HandleRelayCtrlUplinkListAns(
+ _ context.Context, dev *ttnpb.EndDevice, pld *ttnpb.MACCommand_RelayCtrlUplinkListAns,
+) (events.Builders, error) {
+ if pld == nil {
+ return nil, ErrNoPayload.New()
+ }
+ var err error
+ dev.MacState.PendingRequests, err = handleMACResponse(
+ ttnpb.MACCommandIdentifier_CID_RELAY_CTRL_UPLINK_LIST,
+ false,
+ func(cmd *ttnpb.MACCommand) error {
+ if !pld.RuleIndexAck {
+ return nil
+ }
+ req := cmd.GetRelayCtrlUplinkListReq()
+ currentServing := dev.MacState.GetCurrentParameters().GetRelay().GetServing()
+ if currentServing == nil || req.RuleIndex >= uint32(len(currentServing.UplinkForwardingRules)) {
+ return nil
+ }
+ switch req.Action {
+ case ttnpb.RelayCtrlUplinkListAction_RELAY_CTRL_UPLINK_LIST_ACTION_READ_W_F_CNT:
+ case ttnpb.RelayCtrlUplinkListAction_RELAY_CTRL_UPLINK_LIST_ACTION_REMOVE_TRUSTED_END_DEVICE:
+ currentServing.UplinkForwardingRules[req.RuleIndex] = &ttnpb.RelayUplinkForwardingRule{}
+ default:
+ panic("unreachable")
+ }
+ return nil
+ },
+ dev.MacState.PendingRequests...,
+ )
+ ev := EvtReceiveRelayCtrlUplinkListAccept
+ if !pld.RuleIndexAck {
+ ev = EvtReceiveRelayCtrlUplinkListReject
+ }
+ return []events.Builder{
+ ev.With(events.WithData(pld)),
+ }, err
+}
diff --git a/pkg/networkserver/mac/relay_ctrl_uplink_list_test.go b/pkg/networkserver/mac/relay_ctrl_uplink_list_test.go
new file mode 100644
index 0000000000..135c33fd76
--- /dev/null
+++ b/pkg/networkserver/mac/relay_ctrl_uplink_list_test.go
@@ -0,0 +1,451 @@
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package mac_test
+
+import (
+ "context"
+ "testing"
+
+ "github.com/smarty/assertions"
+ "go.thethings.network/lorawan-stack/v3/pkg/events"
+ "go.thethings.network/lorawan-stack/v3/pkg/networkserver/mac"
+ "go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
+ "go.thethings.network/lorawan-stack/v3/pkg/util/test"
+ "go.thethings.network/lorawan-stack/v3/pkg/util/test/assertions/should"
+)
+
+func TestDeviceNeedsRelayCtrlUplinkListReq(t *testing.T) {
+ t.Parallel()
+ for _, tc := range []struct {
+ Name string
+ InputDevice *ttnpb.EndDevice
+ Needs bool
+ }{
+ {
+ Name: "no MAC state",
+ InputDevice: &ttnpb.EndDevice{},
+ },
+ {
+ Name: "no relay",
+ InputDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{},
+ DesiredParameters: &ttnpb.MACParameters{},
+ },
+ },
+ },
+ {
+ Name: "add rule",
+ InputDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{},
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ UplinkForwardingRules: []*ttnpb.RelayUplinkForwardingRule{
+ {
+ LastWFCnt: 42,
+
+ DeviceId: "foo",
+ SessionKeyId: []byte{0x01, 0x02, 0x03},
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ Name: "update rule",
+ InputDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ UplinkForwardingRules: []*ttnpb.RelayUplinkForwardingRule{
+ {
+ LastWFCnt: 12,
+
+ DeviceId: "foo",
+ SessionKeyId: []byte{0x03, 0x04, 0x05},
+ },
+ },
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ UplinkForwardingRules: []*ttnpb.RelayUplinkForwardingRule{
+ {
+ Limits: &ttnpb.RelayUplinkForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_12,
+ ReloadRate: 24,
+ },
+ LastWFCnt: 42,
+
+ DeviceId: "foo",
+ SessionKeyId: []byte{0x01, 0x02, 0x03},
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ Name: "remove rule",
+ InputDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ UplinkForwardingRules: []*ttnpb.RelayUplinkForwardingRule{
+ {
+ LastWFCnt: 12,
+
+ DeviceId: "foo",
+ SessionKeyId: []byte{0x03, 0x04, 0x05},
+ },
+ {
+ LastWFCnt: 12,
+
+ DeviceId: "bar",
+ SessionKeyId: []byte{0x02, 0x03, 0x04},
+ },
+ },
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ UplinkForwardingRules: []*ttnpb.RelayUplinkForwardingRule{
+ {},
+ {
+ LastWFCnt: 12,
+
+ DeviceId: "bar",
+ SessionKeyId: []byte{0x02, 0x03, 0x04},
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ Needs: true,
+ },
+ } {
+ tc := tc
+ test.RunSubtest(t, test.SubtestConfig{
+ Name: tc.Name,
+ Parallel: true,
+ Func: func(ctx context.Context, t *testing.T, a *assertions.Assertion) {
+ t.Helper()
+ dev := ttnpb.Clone(tc.InputDevice)
+ res := mac.DeviceNeedsRelayCtrlUplinkListReq(dev)
+ if tc.Needs {
+ a.So(res, should.BeTrue)
+ } else {
+ a.So(res, should.BeFalse)
+ }
+ a.So(dev, should.Resemble, tc.InputDevice)
+ },
+ })
+ }
+}
+
+func TestEnqueueRelayCtrlUplinkListReq(t *testing.T) {
+ t.Parallel()
+ for _, tc := range []struct {
+ Name string
+ InputDevice, ExpectedDevice *ttnpb.EndDevice
+ MaxDownlinkLength uint16
+ MaxUplinkLength uint16
+ State mac.EnqueueState
+ }{
+ {
+ Name: "remove rule",
+ InputDevice: &ttnpb.EndDevice{
+ Ids: test.MakeEndDeviceIdentifiers(),
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ UplinkForwardingRules: []*ttnpb.RelayUplinkForwardingRule{
+ {
+ LastWFCnt: 42,
+
+ DeviceId: "foo",
+ SessionKeyId: []byte{0x01, 0x02, 0x03},
+ },
+ {
+ LastWFCnt: 24,
+
+ DeviceId: "bar",
+ SessionKeyId: []byte{0x02, 0x03, 0x04},
+ },
+ },
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ UplinkForwardingRules: []*ttnpb.RelayUplinkForwardingRule{
+ {},
+ {
+ LastWFCnt: 42,
+
+ DeviceId: "bar",
+ SessionKeyId: []byte{0x02, 0x03, 0x04},
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ ExpectedDevice: &ttnpb.EndDevice{
+ Ids: test.MakeEndDeviceIdentifiers(),
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ UplinkForwardingRules: []*ttnpb.RelayUplinkForwardingRule{
+ {
+ LastWFCnt: 42,
+
+ DeviceId: "foo",
+ SessionKeyId: []byte{0x01, 0x02, 0x03},
+ },
+ {
+ LastWFCnt: 24,
+
+ DeviceId: "bar",
+ SessionKeyId: []byte{0x02, 0x03, 0x04},
+ },
+ },
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ UplinkForwardingRules: []*ttnpb.RelayUplinkForwardingRule{
+ {},
+ {
+ LastWFCnt: 42,
+
+ DeviceId: "bar",
+ SessionKeyId: []byte{0x02, 0x03, 0x04},
+ },
+ },
+ },
+ },
+ },
+ },
+ PendingRequests: []*ttnpb.MACCommand{
+ (&ttnpb.MACCommand_RelayCtrlUplinkListReq{
+ RuleIndex: 0,
+ Action: ttnpb.RelayCtrlUplinkListAction_RELAY_CTRL_UPLINK_LIST_ACTION_REMOVE_TRUSTED_END_DEVICE,
+ }).MACCommand(),
+ },
+ },
+ },
+ MaxDownlinkLength: 50,
+ MaxUplinkLength: 50,
+ State: mac.EnqueueState{
+ MaxDownLen: 48,
+ MaxUpLen: 44,
+ QueuedEvents: events.Builders{
+ mac.EvtEnqueueRelayCtrlUplinkListRequest.With(events.WithData(
+ &ttnpb.MACCommand_RelayCtrlUplinkListReq{
+ RuleIndex: 0,
+ Action: ttnpb.RelayCtrlUplinkListAction_RELAY_CTRL_UPLINK_LIST_ACTION_REMOVE_TRUSTED_END_DEVICE,
+ },
+ )),
+ },
+ Ok: true,
+ },
+ },
+ } {
+ tc := tc
+ test.RunSubtest(t, test.SubtestConfig{
+ Name: tc.Name,
+ Parallel: true,
+ Func: func(ctx context.Context, t *testing.T, a *assertions.Assertion) {
+ t.Helper()
+ dev := ttnpb.Clone(tc.InputDevice)
+ st := mac.EnqueueRelayCtrlUplinkListReq(ctx, dev, tc.MaxDownlinkLength, tc.MaxUplinkLength)
+ a.So(dev, should.Resemble, tc.ExpectedDevice)
+ a.So(st.QueuedEvents, should.ResembleEventBuilders, tc.State.QueuedEvents)
+ st.QueuedEvents = tc.State.QueuedEvents
+ a.So(st, should.Resemble, tc.State)
+ },
+ })
+ }
+}
+
+func TestHandleRelayCtrlUplinkListAns(t *testing.T) {
+ t.Parallel()
+ for _, tc := range []struct {
+ Name string
+ Device, Expected *ttnpb.EndDevice
+ Payload *ttnpb.MACCommand_RelayCtrlUplinkListAns
+ Events events.Builders
+ Error error
+ }{
+ {
+ Name: "remove rule",
+ Device: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ UplinkForwardingRules: []*ttnpb.RelayUplinkForwardingRule{
+ {
+ LastWFCnt: 42,
+
+ DeviceId: "foo",
+ SessionKeyId: []byte{0x01, 0x02, 0x03},
+ },
+ {
+ LastWFCnt: 42,
+
+ DeviceId: "bar",
+ SessionKeyId: []byte{0x02, 0x03, 0x04},
+ },
+ },
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ UplinkForwardingRules: []*ttnpb.RelayUplinkForwardingRule{
+ {},
+ {
+ LastWFCnt: 42,
+
+ DeviceId: "bar",
+ SessionKeyId: []byte{0x02, 0x03, 0x04},
+ },
+ },
+ },
+ },
+ },
+ },
+ PendingRequests: []*ttnpb.MACCommand{
+ (&ttnpb.MACCommand_RelayCtrlUplinkListReq{
+ RuleIndex: 0,
+ Action: ttnpb.RelayCtrlUplinkListAction_RELAY_CTRL_UPLINK_LIST_ACTION_REMOVE_TRUSTED_END_DEVICE,
+ }).MACCommand(),
+ },
+ },
+ },
+ Expected: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ UplinkForwardingRules: []*ttnpb.RelayUplinkForwardingRule{
+ {},
+ {
+ LastWFCnt: 42,
+
+ DeviceId: "bar",
+ SessionKeyId: []byte{0x02, 0x03, 0x04},
+ },
+ },
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ UplinkForwardingRules: []*ttnpb.RelayUplinkForwardingRule{
+ {},
+ {
+ LastWFCnt: 42,
+
+ DeviceId: "bar",
+ SessionKeyId: []byte{0x02, 0x03, 0x04},
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ Payload: &ttnpb.MACCommand_RelayCtrlUplinkListAns{
+ RuleIndexAck: true,
+ WFCnt: 0x11223344,
+ },
+ Events: events.Builders{
+ mac.EvtReceiveRelayCtrlUplinkListAccept.With(events.WithData(
+ &ttnpb.MACCommand_RelayCtrlUplinkListAns{
+ RuleIndexAck: true,
+ WFCnt: 0x11223344,
+ },
+ )),
+ },
+ },
+ } {
+ tc := tc
+ test.RunSubtest(t, test.SubtestConfig{
+ Name: tc.Name,
+ Parallel: true,
+ Func: func(ctx context.Context, t *testing.T, a *assertions.Assertion) {
+ t.Helper()
+ dev := ttnpb.Clone(tc.Device)
+ evs, err := mac.HandleRelayCtrlUplinkListAns(ctx, dev, tc.Payload)
+ if tc.Error != nil && !a.So(err, should.EqualErrorOrDefinition, tc.Error) ||
+ tc.Error == nil && !a.So(err, should.BeNil) {
+ t.FailNow()
+ }
+ a.So(dev, should.Resemble, tc.Expected)
+ a.So(evs, should.ResembleEventBuilders, tc.Events)
+ },
+ })
+ }
+}
diff --git a/pkg/networkserver/mac/relay_end_device_conf.go b/pkg/networkserver/mac/relay_end_device_conf.go
new file mode 100644
index 0000000000..0af64f6ba7
--- /dev/null
+++ b/pkg/networkserver/mac/relay_end_device_conf.go
@@ -0,0 +1,190 @@
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package mac
+
+import (
+ "context"
+
+ "go.thethings.network/lorawan-stack/v3/pkg/events"
+ "go.thethings.network/lorawan-stack/v3/pkg/log"
+ "go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
+ "google.golang.org/protobuf/proto"
+)
+
+var (
+ // EvtEnqueueRelayEndDeviceConfRequest is emitted when a relay end device configuration request is enqueued.
+ EvtEnqueueRelayEndDeviceConfRequest = defineEnqueueMACRequestEvent(
+ "relay_end_device_conf", "relay end device configuration",
+ events.WithDataType(&ttnpb.MACCommand_RelayEndDeviceConfReq{}),
+ )()
+ // EvtReceiveRelayEndDeviceConfAccept is emitted when a relay end device configuration request is accepted.
+ EvtReceiveRelayEndDeviceConfAccept = defineReceiveMACAcceptEvent(
+ "relay_end_device_conf", "relay end device configuration",
+ events.WithDataType(&ttnpb.MACCommand_RelayEndDeviceConfAns{}),
+ )()
+ // EvtReceiveRelayEndDeviceConfReject is emitted when a relay end device configuration request is rejected.
+ EvtReceiveRelayEndDeviceConfReject = defineReceiveMACRejectEvent(
+ "relay_end_device_conf", "relay end device configuration",
+ events.WithDataType(&ttnpb.MACCommand_RelayEndDeviceConfAns{}),
+ )()
+)
+
+// DeviceNeedsRelayEndDeviceConfReq returns true iff the device needs a relay end device configuration request.
+func DeviceNeedsRelayEndDeviceConfReq(dev *ttnpb.EndDevice) bool {
+ if dev.GetMulticast() || dev.GetMacState() == nil {
+ return false
+ }
+ currentServed := dev.MacState.GetCurrentParameters().GetRelay().GetServed()
+ desiredServed := dev.MacState.GetDesiredParameters().GetRelay().GetServed()
+ return !proto.Equal(
+ &ttnpb.ServedRelayParameters{
+ Mode: desiredServed.GetMode(),
+ Backoff: desiredServed.GetBackoff(),
+ SecondChannel: desiredServed.GetSecondChannel(),
+ },
+ &ttnpb.ServedRelayParameters{
+ Mode: currentServed.GetMode(),
+ Backoff: currentServed.GetBackoff(),
+ SecondChannel: currentServed.GetSecondChannel(),
+ },
+ )
+}
+
+// EnqueueRelayEndDeviceConfReq enqueues a relay end device configuration request if needed.
+func EnqueueRelayEndDeviceConfReq(ctx context.Context, dev *ttnpb.EndDevice, maxDownLen, maxUpLen uint16) EnqueueState {
+ if !DeviceNeedsRelayEndDeviceConfReq(dev) {
+ return EnqueueState{
+ MaxDownLen: maxDownLen,
+ MaxUpLen: maxUpLen,
+ Ok: true,
+ }
+ }
+ var st EnqueueState
+ dev.MacState.PendingRequests, st = enqueueMACCommand(
+ ttnpb.MACCommandIdentifier_CID_RELAY_END_DEVICE_CONF,
+ maxDownLen, maxUpLen,
+ func(nDown, nUp uint16) ([]*ttnpb.MACCommand, uint16, events.Builders, bool) {
+ if nDown < 1 || nUp < 1 {
+ return nil, 0, nil, false
+ }
+ desiredServed := dev.MacState.GetDesiredParameters().GetRelay().GetServed()
+ req := &ttnpb.MACCommand_RelayEndDeviceConfReq{}
+ if desiredServed != nil {
+ req.Configuration = &ttnpb.MACCommand_RelayEndDeviceConfReq_Configuration{
+ Backoff: desiredServed.Backoff,
+ SecondChannel: desiredServed.SecondChannel,
+ ServingDeviceId: desiredServed.ServingDeviceId,
+ }
+ switch {
+ case desiredServed.GetAlways() != nil:
+ req.Configuration.Mode = &ttnpb.MACCommand_RelayEndDeviceConfReq_Configuration_Always{
+ Always: desiredServed.GetAlways(),
+ }
+ case desiredServed.GetDynamic() != nil:
+ req.Configuration.Mode = &ttnpb.MACCommand_RelayEndDeviceConfReq_Configuration_Dynamic{
+ Dynamic: desiredServed.GetDynamic(),
+ }
+ case desiredServed.GetEndDeviceControlled() != nil:
+ req.Configuration.Mode = &ttnpb.MACCommand_RelayEndDeviceConfReq_Configuration_EndDeviceControlled{
+ EndDeviceControlled: desiredServed.GetEndDeviceControlled(),
+ }
+ default:
+ panic("unreachable")
+ }
+ }
+ log.FromContext(ctx).WithFields(servedRelayFields(desiredServed)).Debug("Enqueued RelayEndDeviceConfReq")
+ return []*ttnpb.MACCommand{
+ req.MACCommand(),
+ },
+ 1,
+ events.Builders{
+ EvtEnqueueRelayEndDeviceConfRequest.With(events.WithData(req)),
+ },
+ true
+ },
+ dev.MacState.PendingRequests...,
+ )
+ return st
+}
+
+// HandleRelayEndDeviceConfAns handles a relay end device configuration answer.
+func HandleRelayEndDeviceConfAns(
+ _ context.Context, dev *ttnpb.EndDevice, pld *ttnpb.MACCommand_RelayEndDeviceConfAns,
+) (events.Builders, error) {
+ if pld == nil {
+ return nil, ErrNoPayload.New()
+ }
+ rejected := !pld.SecondChannelFrequencyAck ||
+ // NOTE: SecondChannelAckOffsetAck is not defined in the specification.
+ !pld.SecondChannelDataRateIndexAck ||
+ !pld.SecondChannelIndexAck ||
+ !pld.BackoffAck
+ var err error
+ dev.MacState.PendingRequests, err = handleMACResponse(
+ ttnpb.MACCommandIdentifier_CID_RELAY_END_DEVICE_CONF,
+ false,
+ func(cmd *ttnpb.MACCommand) error {
+ if rejected {
+ return nil
+ }
+ conf := cmd.GetRelayEndDeviceConfReq().Configuration
+ currentParameters := dev.MacState.CurrentParameters
+ if conf == nil {
+ currentParameters.Relay = nil
+ return nil
+ }
+ relay := currentParameters.Relay
+ if relay == nil {
+ relay = &ttnpb.RelayParameters{}
+ currentParameters.Relay = relay
+ }
+ served := relay.GetServed()
+ if served == nil {
+ served = &ttnpb.ServedRelayParameters{}
+ relay.Mode = &ttnpb.RelayParameters_Served{
+ Served: served,
+ }
+ }
+ switch {
+ case conf.GetAlways() != nil:
+ served.Mode = &ttnpb.ServedRelayParameters_Always{
+ Always: conf.GetAlways(),
+ }
+ case conf.GetDynamic() != nil:
+ served.Mode = &ttnpb.ServedRelayParameters_Dynamic{
+ Dynamic: conf.GetDynamic(),
+ }
+ case conf.GetEndDeviceControlled() != nil:
+ served.Mode = &ttnpb.ServedRelayParameters_EndDeviceControlled{
+ EndDeviceControlled: conf.GetEndDeviceControlled(),
+ }
+ default:
+ panic("unreachable")
+ }
+ served.Backoff = conf.Backoff
+ served.SecondChannel = conf.SecondChannel
+ served.ServingDeviceId = conf.ServingDeviceId
+ return nil
+ },
+ dev.MacState.PendingRequests...,
+ )
+ ev := EvtReceiveRelayEndDeviceConfAccept
+ if rejected {
+ ev = EvtReceiveRelayEndDeviceConfReject
+ }
+ return events.Builders{
+ ev.With(events.WithData(pld)),
+ }, err
+}
diff --git a/pkg/networkserver/mac/relay_end_device_conf_test.go b/pkg/networkserver/mac/relay_end_device_conf_test.go
new file mode 100644
index 0000000000..d9699ae5cd
--- /dev/null
+++ b/pkg/networkserver/mac/relay_end_device_conf_test.go
@@ -0,0 +1,495 @@
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package mac_test
+
+import (
+ "context"
+ "testing"
+
+ "github.com/smarty/assertions"
+ "go.thethings.network/lorawan-stack/v3/pkg/events"
+ "go.thethings.network/lorawan-stack/v3/pkg/networkserver/mac"
+ "go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
+ "go.thethings.network/lorawan-stack/v3/pkg/util/test"
+ "go.thethings.network/lorawan-stack/v3/pkg/util/test/assertions/should"
+)
+
+func TestDeviceNeedsRelayEndDeviceConfReq(t *testing.T) {
+ t.Parallel()
+ for _, tc := range []struct {
+ Name string
+ InputDevice *ttnpb.EndDevice
+ Needs bool
+ }{
+ {
+ Name: "no MAC state",
+ InputDevice: &ttnpb.EndDevice{},
+ },
+ {
+ Name: "no relay",
+ InputDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{},
+ DesiredParameters: &ttnpb.MACParameters{},
+ },
+ },
+ },
+ {
+ Name: "disable served",
+ InputDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Served{
+ Served: &ttnpb.ServedRelayParameters{
+ Mode: &ttnpb.ServedRelayParameters_Always{
+ Always: &ttnpb.RelayEndDeviceAlwaysMode{},
+ },
+ ServingDeviceId: "foo",
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{},
+ },
+ },
+ Needs: true,
+ },
+ {
+ Name: "enable served",
+ InputDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{},
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Served{
+ Served: &ttnpb.ServedRelayParameters{
+ Mode: &ttnpb.ServedRelayParameters_Always{
+ Always: &ttnpb.RelayEndDeviceAlwaysMode{},
+ },
+ ServingDeviceId: "foo",
+ },
+ },
+ },
+ },
+ },
+ },
+ Needs: true,
+ },
+ {
+ Name: "always to dynamic mode",
+ InputDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Served{
+ Served: &ttnpb.ServedRelayParameters{
+ Mode: &ttnpb.ServedRelayParameters_Always{
+ Always: &ttnpb.RelayEndDeviceAlwaysMode{},
+ },
+ ServingDeviceId: "foo",
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Served{
+ Served: &ttnpb.ServedRelayParameters{
+ Mode: &ttnpb.ServedRelayParameters_Dynamic{
+ Dynamic: &ttnpb.RelayEndDeviceDynamicMode{
+ SmartEnableLevel: ttnpb.RelaySmartEnableLevel_RELAY_SMART_ENABLE_LEVEL_32,
+ },
+ },
+ ServingDeviceId: "foo",
+ },
+ },
+ },
+ },
+ },
+ },
+ Needs: true,
+ },
+ } {
+ tc := tc
+ test.RunSubtest(t, test.SubtestConfig{
+ Name: tc.Name,
+ Parallel: true,
+ Func: func(ctx context.Context, t *testing.T, a *assertions.Assertion) {
+ t.Helper()
+ dev := ttnpb.Clone(tc.InputDevice)
+ res := mac.DeviceNeedsRelayEndDeviceConfReq(dev)
+ if tc.Needs {
+ a.So(res, should.BeTrue)
+ } else {
+ a.So(res, should.BeFalse)
+ }
+ a.So(dev, should.Resemble, tc.InputDevice)
+ },
+ })
+ }
+}
+
+func TestEnqueueRelayEndDeviceConfReq(t *testing.T) {
+ t.Parallel()
+ for _, tc := range []struct {
+ Name string
+ InputDevice, ExpectedDevice *ttnpb.EndDevice
+ MaxDownlinkLength uint16
+ MaxUplinkLength uint16
+ State mac.EnqueueState
+ }{
+ {
+ Name: "enable served",
+ InputDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{},
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Served{
+ Served: &ttnpb.ServedRelayParameters{
+ Mode: &ttnpb.ServedRelayParameters_Always{
+ Always: &ttnpb.RelayEndDeviceAlwaysMode{},
+ },
+ ServingDeviceId: "foo",
+ },
+ },
+ },
+ },
+ },
+ },
+ ExpectedDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{},
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Served{
+ Served: &ttnpb.ServedRelayParameters{
+ Mode: &ttnpb.ServedRelayParameters_Always{
+ Always: &ttnpb.RelayEndDeviceAlwaysMode{},
+ },
+ ServingDeviceId: "foo",
+ },
+ },
+ },
+ },
+ PendingRequests: []*ttnpb.MACCommand{
+ (&ttnpb.MACCommand_RelayEndDeviceConfReq{
+ Configuration: &ttnpb.MACCommand_RelayEndDeviceConfReq_Configuration{
+ Mode: &ttnpb.MACCommand_RelayEndDeviceConfReq_Configuration_Always{
+ Always: &ttnpb.RelayEndDeviceAlwaysMode{},
+ },
+ ServingDeviceId: "foo",
+ },
+ }).MACCommand(),
+ },
+ },
+ },
+ MaxDownlinkLength: 50,
+ MaxUplinkLength: 50,
+ State: mac.EnqueueState{
+ MaxDownLen: 43,
+ MaxUpLen: 48,
+ QueuedEvents: events.Builders{
+ mac.EvtEnqueueRelayEndDeviceConfRequest.With(events.WithData(&ttnpb.MACCommand_RelayEndDeviceConfReq{
+ Configuration: &ttnpb.MACCommand_RelayEndDeviceConfReq_Configuration{
+ Mode: &ttnpb.MACCommand_RelayEndDeviceConfReq_Configuration_Always{
+ Always: &ttnpb.RelayEndDeviceAlwaysMode{},
+ },
+ ServingDeviceId: "foo",
+ },
+ })),
+ },
+ Ok: true,
+ },
+ },
+ {
+ Name: "disable served",
+ InputDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Served{
+ Served: &ttnpb.ServedRelayParameters{
+ Mode: &ttnpb.ServedRelayParameters_Always{
+ Always: &ttnpb.RelayEndDeviceAlwaysMode{},
+ },
+ ServingDeviceId: "foo",
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{},
+ },
+ },
+ ExpectedDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Served{
+ Served: &ttnpb.ServedRelayParameters{
+ Mode: &ttnpb.ServedRelayParameters_Always{
+ Always: &ttnpb.RelayEndDeviceAlwaysMode{},
+ },
+ ServingDeviceId: "foo",
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{},
+ PendingRequests: []*ttnpb.MACCommand{
+ (&ttnpb.MACCommand_RelayEndDeviceConfReq{}).MACCommand(),
+ },
+ },
+ },
+ MaxDownlinkLength: 50,
+ MaxUplinkLength: 50,
+ State: mac.EnqueueState{
+ MaxDownLen: 43,
+ MaxUpLen: 48,
+ QueuedEvents: events.Builders{
+ mac.EvtEnqueueRelayEndDeviceConfRequest.With(events.WithData(&ttnpb.MACCommand_RelayEndDeviceConfReq{})),
+ },
+ Ok: true,
+ },
+ },
+ } {
+ tc := tc
+ test.RunSubtest(t, test.SubtestConfig{
+ Name: tc.Name,
+ Parallel: true,
+ Func: func(ctx context.Context, t *testing.T, a *assertions.Assertion) {
+ t.Helper()
+ dev := ttnpb.Clone(tc.InputDevice)
+ st := mac.EnqueueRelayEndDeviceConfReq(ctx, dev, tc.MaxDownlinkLength, tc.MaxUplinkLength)
+ a.So(dev, should.Resemble, tc.ExpectedDevice)
+ a.So(st.QueuedEvents, should.ResembleEventBuilders, tc.State.QueuedEvents)
+ st.QueuedEvents = tc.State.QueuedEvents
+ a.So(st, should.Resemble, tc.State)
+ },
+ })
+ }
+}
+
+func TestHandleRelayEndDeviceConfAns(t *testing.T) {
+ t.Parallel()
+ for _, tc := range []struct {
+ Name string
+ Device, Expected *ttnpb.EndDevice
+ Payload *ttnpb.MACCommand_RelayEndDeviceConfAns
+ Events events.Builders
+ Error error
+ }{
+ {
+ Name: "reject served",
+ Device: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{},
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Served{
+ Served: &ttnpb.ServedRelayParameters{
+ Mode: &ttnpb.ServedRelayParameters_Always{
+ Always: &ttnpb.RelayEndDeviceAlwaysMode{},
+ },
+ ServingDeviceId: "foo",
+ },
+ },
+ },
+ },
+ PendingRequests: []*ttnpb.MACCommand{
+ (&ttnpb.MACCommand_RelayEndDeviceConfReq{
+ Configuration: &ttnpb.MACCommand_RelayEndDeviceConfReq_Configuration{
+ Mode: &ttnpb.MACCommand_RelayEndDeviceConfReq_Configuration_Always{
+ Always: &ttnpb.RelayEndDeviceAlwaysMode{},
+ },
+ ServingDeviceId: "foo",
+ },
+ }).MACCommand(),
+ },
+ },
+ },
+ Expected: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{},
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Served{
+ Served: &ttnpb.ServedRelayParameters{
+ Mode: &ttnpb.ServedRelayParameters_Always{
+ Always: &ttnpb.RelayEndDeviceAlwaysMode{},
+ },
+ ServingDeviceId: "foo",
+ },
+ },
+ },
+ },
+ },
+ },
+ Payload: &ttnpb.MACCommand_RelayEndDeviceConfAns{
+ SecondChannelFrequencyAck: true,
+ // NOTE: SecondChannelAckOffsetAck is not defined in the specification.
+ SecondChannelDataRateIndexAck: false,
+ SecondChannelIndexAck: true,
+ BackoffAck: false,
+ },
+ Events: events.Builders{
+ mac.EvtReceiveRelayEndDeviceConfReject.With(events.WithData(&ttnpb.MACCommand_RelayEndDeviceConfAns{
+ SecondChannelFrequencyAck: true,
+ // NOTE: SecondChannelAckOffsetAck is not defined in the specification.
+ SecondChannelDataRateIndexAck: false,
+ SecondChannelIndexAck: true,
+ BackoffAck: false,
+ })),
+ },
+ },
+ {
+ Name: "enable served",
+ Device: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{},
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Served{
+ Served: &ttnpb.ServedRelayParameters{
+ Mode: &ttnpb.ServedRelayParameters_Always{
+ Always: &ttnpb.RelayEndDeviceAlwaysMode{},
+ },
+ ServingDeviceId: "foo",
+ },
+ },
+ },
+ },
+ PendingRequests: []*ttnpb.MACCommand{
+ (&ttnpb.MACCommand_RelayEndDeviceConfReq{
+ Configuration: &ttnpb.MACCommand_RelayEndDeviceConfReq_Configuration{
+ Mode: &ttnpb.MACCommand_RelayEndDeviceConfReq_Configuration_Always{
+ Always: &ttnpb.RelayEndDeviceAlwaysMode{},
+ },
+ ServingDeviceId: "foo",
+ },
+ }).MACCommand(),
+ },
+ },
+ },
+ Expected: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Served{
+ Served: &ttnpb.ServedRelayParameters{
+ Mode: &ttnpb.ServedRelayParameters_Always{
+ Always: &ttnpb.RelayEndDeviceAlwaysMode{},
+ },
+ ServingDeviceId: "foo",
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Served{
+ Served: &ttnpb.ServedRelayParameters{
+ Mode: &ttnpb.ServedRelayParameters_Always{
+ Always: &ttnpb.RelayEndDeviceAlwaysMode{},
+ },
+ ServingDeviceId: "foo",
+ },
+ },
+ },
+ },
+ },
+ },
+ Payload: &ttnpb.MACCommand_RelayEndDeviceConfAns{
+ SecondChannelFrequencyAck: true,
+ // NOTE: SecondChannelAckOffsetAck is not defined in the specification.
+ SecondChannelDataRateIndexAck: true,
+ SecondChannelIndexAck: true,
+ BackoffAck: true,
+ },
+ Events: events.Builders{
+ mac.EvtReceiveRelayEndDeviceConfAccept.With(events.WithData(&ttnpb.MACCommand_RelayEndDeviceConfAns{
+ SecondChannelFrequencyAck: true,
+ // NOTE: SecondChannelAckOffsetAck is not defined in the specification.
+ SecondChannelDataRateIndexAck: true,
+ SecondChannelIndexAck: true,
+ BackoffAck: true,
+ })),
+ },
+ },
+ {
+ Name: "disable served",
+ Device: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Served{
+ Served: &ttnpb.ServedRelayParameters{
+ Mode: &ttnpb.ServedRelayParameters_Always{
+ Always: &ttnpb.RelayEndDeviceAlwaysMode{},
+ },
+ ServingDeviceId: "foo",
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{},
+ PendingRequests: []*ttnpb.MACCommand{
+ (&ttnpb.MACCommand_RelayEndDeviceConfReq{}).MACCommand(),
+ },
+ },
+ },
+ Expected: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{},
+ DesiredParameters: &ttnpb.MACParameters{},
+ },
+ },
+ Payload: &ttnpb.MACCommand_RelayEndDeviceConfAns{
+ SecondChannelFrequencyAck: true,
+ // NOTE: SecondChannelAckOffsetAck is not defined in the specification.
+ SecondChannelDataRateIndexAck: true,
+ SecondChannelIndexAck: true,
+ BackoffAck: true,
+ },
+ Events: events.Builders{
+ mac.EvtReceiveRelayEndDeviceConfAccept.With(events.WithData(&ttnpb.MACCommand_RelayEndDeviceConfAns{
+ SecondChannelFrequencyAck: true,
+ // NOTE: SecondChannelAckOffsetAck is not defined in the specification.
+ SecondChannelDataRateIndexAck: true,
+ SecondChannelIndexAck: true,
+ BackoffAck: true,
+ })),
+ },
+ },
+ } {
+ tc := tc
+ test.RunSubtest(t, test.SubtestConfig{
+ Name: tc.Name,
+ Parallel: true,
+ Func: func(ctx context.Context, t *testing.T, a *assertions.Assertion) {
+ t.Helper()
+ dev := ttnpb.Clone(tc.Device)
+ evs, err := mac.HandleRelayEndDeviceConfAns(ctx, dev, tc.Payload)
+ if tc.Error != nil && !a.So(err, should.EqualErrorOrDefinition, tc.Error) ||
+ tc.Error == nil && !a.So(err, should.BeNil) {
+ t.FailNow()
+ }
+ a.So(dev, should.Resemble, tc.Expected)
+ a.So(evs, should.ResembleEventBuilders, tc.Events)
+ },
+ })
+ }
+}
diff --git a/pkg/networkserver/mac/relay_notify_new_end_device.go b/pkg/networkserver/mac/relay_notify_new_end_device.go
new file mode 100644
index 0000000000..d43a358951
--- /dev/null
+++ b/pkg/networkserver/mac/relay_notify_new_end_device.go
@@ -0,0 +1,40 @@
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package mac
+
+import (
+ "context"
+
+ "go.thethings.network/lorawan-stack/v3/pkg/events"
+ "go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
+)
+
+// EvtReceiveRelayNotifyNewEndDeviceIndication is emitted when a relay notify new end device
+// indication is received.
+var EvtReceiveRelayNotifyNewEndDeviceIndication = defineReceiveMACIndicationEvent(
+ "relay_notify_new_end_device", "relay notify new end device",
+)()
+
+// HandleRelayNotifyNewEndDeviceReq handles a relay notify new end device request.
+func HandleRelayNotifyNewEndDeviceReq(
+ _ context.Context, _ *ttnpb.EndDevice, pld *ttnpb.MACCommand_RelayNotifyNewEndDeviceReq,
+) (events.Builders, error) {
+ if pld == nil {
+ return nil, ErrNoPayload.New()
+ }
+ return events.Builders{
+ EvtReceiveRelayNotifyNewEndDeviceIndication.With(events.WithData(pld)),
+ }, nil
+}
diff --git a/pkg/networkserver/mac/relay_update_uplink_list.go b/pkg/networkserver/mac/relay_update_uplink_list.go
new file mode 100644
index 0000000000..f6bb1c5104
--- /dev/null
+++ b/pkg/networkserver/mac/relay_update_uplink_list.go
@@ -0,0 +1,201 @@
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package mac
+
+import (
+ "context"
+
+ "go.thethings.network/lorawan-stack/v3/pkg/events"
+ "go.thethings.network/lorawan-stack/v3/pkg/log"
+ "go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
+ "google.golang.org/protobuf/proto"
+)
+
+var (
+ emptyRelayUplinkForwardingRule = &ttnpb.RelayUplinkForwardingRule{}
+
+ // EvtEnqueueRelayUpdateUplinkListRequest is emitted when a relay update uplink list request is enqueued.
+ EvtEnqueueRelayUpdateUplinkListRequest = defineEnqueueMACRequestEvent(
+ "relay_update_uplink_list", "relay update uplink list",
+ events.WithDataType(&ttnpb.MACCommand_RelayUpdateUplinkListReq{}),
+ )()
+ // EvtReceiveRelayUpdateUplinkListAnswer is emitted when a relay update uplink list request is answered.
+ EvtReceiveRelayUpdateUplinkListAnswer = defineReceiveMACAnswerEvent(
+ "relay_update_uplink_list", "relay update uplink list",
+ events.WithDataType(&ttnpb.MACCommand_RelayUpdateUplinkListAns{}),
+ )()
+)
+
+// DeviceNeedsRelayUpdateUplinkListReqAtIndex returns true iff the device needs a relay
+// update uplink list request at the given index.
+func DeviceNeedsRelayUpdateUplinkListReqAtIndex(dev *ttnpb.EndDevice, i int) bool {
+ currentRules := dev.GetMacState().GetCurrentParameters().GetRelay().GetServing().GetUplinkForwardingRules()
+ desiredRules := dev.GetMacState().GetDesiredParameters().GetRelay().GetServing().GetUplinkForwardingRules()
+ switch {
+ case i >= len(currentRules) && i >= len(desiredRules):
+ case i >= len(desiredRules), proto.Equal(desiredRules[i], emptyRelayUplinkForwardingRule):
+ // A rule is desired to be deleted.
+ // NOTE: UpdateUplinkListReq cannot delete a forwarding rule.
+ case i >= len(currentRules), proto.Equal(currentRules[i], emptyRelayUplinkForwardingRule):
+ // A rule is desired to be created.
+ return true
+ default:
+ // A rule is desired to be updated.
+ return !proto.Equal(desiredRules[i], currentRules[i])
+ }
+ return false
+}
+
+// DeviceNeedsRelayUpdateUplinkListReq returns true iff the device needs a relay update uplink list request.
+func DeviceNeedsRelayUpdateUplinkListReq(dev *ttnpb.EndDevice) bool {
+ if dev.GetMulticast() || dev.GetMacState() == nil {
+ return false
+ }
+ currentServing := dev.MacState.GetCurrentParameters().GetRelay().GetServing()
+ desiredServing := dev.MacState.GetDesiredParameters().GetRelay().GetServing()
+ if desiredServing == nil {
+ return false
+ }
+ if len(desiredServing.GetUplinkForwardingRules()) > len(currentServing.GetUplinkForwardingRules()) {
+ return true
+ }
+ for i := range desiredServing.GetUplinkForwardingRules() {
+ if DeviceNeedsRelayUpdateUplinkListReqAtIndex(dev, i) {
+ return true
+ }
+ }
+ return false
+}
+
+// EnqueueRelayUpdateUplinkListReq enqueues a relay update uplink list request.
+func EnqueueRelayUpdateUplinkListReq(
+ ctx context.Context, dev *ttnpb.EndDevice, maxDownLen, maxUpLen uint16, keyService RelayKeyService,
+) EnqueueState {
+ if !DeviceNeedsRelayUpdateUplinkListReq(dev) {
+ return EnqueueState{
+ MaxDownLen: maxDownLen,
+ MaxUpLen: maxUpLen,
+ Ok: true,
+ }
+ }
+ var st EnqueueState
+ dev.MacState.PendingRequests, st = enqueueMACCommand(
+ ttnpb.MACCommandIdentifier_CID_RELAY_UPDATE_UPLINK_LIST,
+ maxDownLen, maxUpLen,
+ func(nDown, nUp uint16) ([]*ttnpb.MACCommand, uint16, events.Builders, bool) {
+ if nDown < 1 || nUp < 1 {
+ return nil, 0, nil, false
+ }
+ currentRules := dev.MacState.GetCurrentParameters().GetRelay().GetServing().GetUplinkForwardingRules()
+ desiredRules := dev.MacState.DesiredParameters.Relay.GetServing().UplinkForwardingRules
+ pendingRuleIndices := make([]int, 0, len(desiredRules))
+ pendingDeviceIDs := make([]string, 0, len(desiredRules))
+ pendingSessionKeyIDs := make([][]byte, 0, len(desiredRules))
+ var reqs []*ttnpb.MACCommand_RelayUpdateUplinkListReq
+ for i := 0; i < len(desiredRules) || i < len(currentRules); i++ {
+ if DeviceNeedsRelayUpdateUplinkListReqAtIndex(dev, i) {
+ pendingRuleIndices = append(pendingRuleIndices, i)
+ pendingDeviceIDs = append(pendingDeviceIDs, desiredRules[i].DeviceId)
+ pendingSessionKeyIDs = append(pendingSessionKeyIDs, desiredRules[i].SessionKeyId)
+ }
+ }
+ devAddrs, keys, err := keyService.BatchDeriveRootWorSKey(
+ ctx, dev.Ids.ApplicationIds, pendingDeviceIDs, pendingSessionKeyIDs,
+ )
+ if err != nil {
+ log.FromContext(ctx).WithError(err).Warn("Root relay session keys derivation failed")
+ return nil, 0, nil, true
+ }
+ for i, ruleIdx := range pendingRuleIndices {
+ if devAddrs[i] == nil || keys[i] == nil {
+ continue
+ }
+ desiredRule := desiredRules[ruleIdx]
+ reqs = append(reqs, &ttnpb.MACCommand_RelayUpdateUplinkListReq{
+ RuleIndex: uint32(ruleIdx),
+ ForwardLimits: desiredRule.Limits,
+ DevAddr: devAddrs[i][:],
+ WFCnt: desiredRule.LastWFCnt,
+ RootWorSKey: keys[i][:],
+
+ DeviceId: desiredRule.DeviceId,
+ SessionKeyId: desiredRule.SessionKeyId,
+ })
+ }
+ cmds := make([]*ttnpb.MACCommand, 0, len(reqs))
+ evs := make(events.Builders, 0, len(reqs))
+ for _, req := range reqs {
+ if nDown < 1 || nUp < 1 {
+ return cmds, uint16(len(cmds)), evs, false
+ }
+ nDown--
+ nUp--
+ log.FromContext(ctx).WithFields(relayUpdateUplinkListReqFields(req)).
+ Debug("Enqueued RelayUpdateUplinkListReq")
+ cmds = append(cmds, req.MACCommand())
+ evs = append(evs, EvtEnqueueRelayUpdateUplinkListRequest.With(events.WithData(req.Sanitized())))
+ }
+ return cmds, uint16(len(cmds)), evs, true
+ },
+ dev.MacState.PendingRequests...,
+ )
+ return st
+}
+
+// HandleRelayUpdateUplinkListAns handles a relay update uplink list answer.
+func HandleRelayUpdateUplinkListAns(
+ _ context.Context, dev *ttnpb.EndDevice, pld *ttnpb.MACCommand_RelayUpdateUplinkListAns,
+) (events.Builders, error) {
+ if pld == nil {
+ return nil, ErrNoPayload.New()
+ }
+ var err error
+ dev.MacState.PendingRequests, err = handleMACResponse(
+ ttnpb.MACCommandIdentifier_CID_RELAY_UPDATE_UPLINK_LIST,
+ false,
+ func(cmd *ttnpb.MACCommand) error {
+ req := cmd.GetRelayUpdateUplinkListReq()
+ currentServing := dev.MacState.GetCurrentParameters().GetRelay().GetServing()
+ if currentServing == nil {
+ // NOTE: EnqueueRelayUpdateUplinkListReq is optimistic and assumes that EnqueueRelayConfReq
+ // has enqueued the desired relay parameters, and that the end device will accept them. If
+ // either of these conditions is not true, the current serving parameters will be nil.
+ return nil
+ }
+ if n := len(currentServing.UplinkForwardingRules); uint(req.RuleIndex) >= uint(n) {
+ currentServing.UplinkForwardingRules = append(
+ currentServing.UplinkForwardingRules,
+ make(
+ []*ttnpb.RelayUplinkForwardingRule,
+ 1+int(req.RuleIndex-uint32(n)),
+ )...,
+ )
+ for i := n; i < len(currentServing.UplinkForwardingRules); i++ {
+ currentServing.UplinkForwardingRules[i] = &ttnpb.RelayUplinkForwardingRule{}
+ }
+ }
+ rule := currentServing.UplinkForwardingRules[req.RuleIndex]
+ rule.Limits = req.ForwardLimits
+ rule.LastWFCnt = req.WFCnt
+ rule.DeviceId = req.DeviceId
+ rule.SessionKeyId = req.SessionKeyId
+ return nil
+ },
+ dev.MacState.PendingRequests...,
+ )
+ return []events.Builder{
+ EvtReceiveRelayUpdateUplinkListAnswer.With(events.WithData(pld)),
+ }, err
+}
diff --git a/pkg/networkserver/mac/relay_update_uplink_list_test.go b/pkg/networkserver/mac/relay_update_uplink_list_test.go
new file mode 100644
index 0000000000..32a7bdb9bd
--- /dev/null
+++ b/pkg/networkserver/mac/relay_update_uplink_list_test.go
@@ -0,0 +1,670 @@
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package mac_test
+
+import (
+ "context"
+ "testing"
+
+ "github.com/smarty/assertions"
+ "go.thethings.network/lorawan-stack/v3/pkg/events"
+ "go.thethings.network/lorawan-stack/v3/pkg/networkserver/mac"
+ "go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
+ "go.thethings.network/lorawan-stack/v3/pkg/types"
+ "go.thethings.network/lorawan-stack/v3/pkg/util/test"
+ "go.thethings.network/lorawan-stack/v3/pkg/util/test/assertions/should"
+)
+
+type relayKeyServiceFunc func(
+ context.Context, *ttnpb.ApplicationIdentifiers, []string, [][]byte,
+) ([]*types.DevAddr, []*types.AES128Key, error)
+
+var _ (mac.RelayKeyService) = relayKeyServiceFunc(nil)
+
+// BatchDeriveRootWorSKey implements mac.RelayKeyService.
+func (f relayKeyServiceFunc) BatchDeriveRootWorSKey(
+ ctx context.Context, appID *ttnpb.ApplicationIdentifiers, deviceIDs []string, sessionKeyIDs [][]byte,
+) ([]*types.DevAddr, []*types.AES128Key, error) {
+ return f(ctx, appID, deviceIDs, sessionKeyIDs)
+}
+
+func TestDeviceNeedsRelayUpdateUplinkListReq(t *testing.T) {
+ t.Parallel()
+ for _, tc := range []struct {
+ Name string
+ InputDevice *ttnpb.EndDevice
+ Needs bool
+ }{
+ {
+ Name: "no MAC state",
+ InputDevice: &ttnpb.EndDevice{},
+ },
+ {
+ Name: "no relay",
+ InputDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{},
+ DesiredParameters: &ttnpb.MACParameters{},
+ },
+ },
+ },
+ {
+ Name: "add rule",
+ InputDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{},
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ UplinkForwardingRules: []*ttnpb.RelayUplinkForwardingRule{
+ {
+ LastWFCnt: 42,
+
+ DeviceId: "foo",
+ SessionKeyId: []byte{0x01, 0x02, 0x03},
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ Needs: true,
+ },
+ {
+ Name: "update rule",
+ InputDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ UplinkForwardingRules: []*ttnpb.RelayUplinkForwardingRule{
+ {
+ LastWFCnt: 12,
+
+ DeviceId: "foo",
+ SessionKeyId: []byte{0x03, 0x04, 0x05},
+ },
+ },
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ UplinkForwardingRules: []*ttnpb.RelayUplinkForwardingRule{
+ {
+ Limits: &ttnpb.RelayUplinkForwardLimits{
+ BucketSize: ttnpb.RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_12,
+ ReloadRate: 24,
+ },
+ LastWFCnt: 42,
+
+ DeviceId: "foo",
+ SessionKeyId: []byte{0x01, 0x02, 0x03},
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ Needs: true,
+ },
+ {
+ Name: "remove rule",
+ InputDevice: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ UplinkForwardingRules: []*ttnpb.RelayUplinkForwardingRule{
+ {
+ LastWFCnt: 12,
+
+ DeviceId: "foo",
+ SessionKeyId: []byte{0x03, 0x04, 0x05},
+ },
+ {
+ LastWFCnt: 12,
+
+ DeviceId: "bar",
+ SessionKeyId: []byte{0x02, 0x03, 0x04},
+ },
+ },
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ UplinkForwardingRules: []*ttnpb.RelayUplinkForwardingRule{
+ {},
+ {
+ LastWFCnt: 12,
+
+ DeviceId: "bar",
+ SessionKeyId: []byte{0x02, 0x03, 0x04},
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ } {
+ tc := tc
+ test.RunSubtest(t, test.SubtestConfig{
+ Name: tc.Name,
+ Parallel: true,
+ Func: func(ctx context.Context, t *testing.T, a *assertions.Assertion) {
+ t.Helper()
+ dev := ttnpb.Clone(tc.InputDevice)
+ res := mac.DeviceNeedsRelayUpdateUplinkListReq(dev)
+ if tc.Needs {
+ a.So(res, should.BeTrue)
+ } else {
+ a.So(res, should.BeFalse)
+ }
+ a.So(dev, should.Resemble, tc.InputDevice)
+ },
+ })
+ }
+}
+
+func TestEnqueueRelayUpdateUplinkListReq(t *testing.T) {
+ t.Parallel()
+ for _, tc := range []struct {
+ Name string
+ InputDevice, ExpectedDevice *ttnpb.EndDevice
+ MaxDownlinkLength uint16
+ MaxUplinkLength uint16
+ RelayKeyService relayKeyServiceFunc
+ State mac.EnqueueState
+ }{
+ {
+ Name: "add rule",
+ InputDevice: &ttnpb.EndDevice{
+ Ids: test.MakeEndDeviceIdentifiers(),
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{},
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ UplinkForwardingRules: []*ttnpb.RelayUplinkForwardingRule{
+ {
+ LastWFCnt: 42,
+
+ DeviceId: "foo",
+ SessionKeyId: []byte{0x01, 0x02, 0x03},
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ ExpectedDevice: &ttnpb.EndDevice{
+ Ids: test.MakeEndDeviceIdentifiers(),
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{},
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ UplinkForwardingRules: []*ttnpb.RelayUplinkForwardingRule{
+ {
+ LastWFCnt: 42,
+
+ DeviceId: "foo",
+ SessionKeyId: []byte{0x01, 0x02, 0x03},
+ },
+ },
+ },
+ },
+ },
+ },
+ PendingRequests: []*ttnpb.MACCommand{
+ (&ttnpb.MACCommand_RelayUpdateUplinkListReq{
+ RuleIndex: 0,
+ DevAddr: types.DevAddr{0x42, 0x43, 0x44, 0x45}.Bytes(),
+ WFCnt: 42,
+ RootWorSKey: types.AES128Key{0x01, 0x02, 0x03, 0x04}.Bytes(),
+
+ DeviceId: "foo",
+ SessionKeyId: []byte{0x01, 0x02, 0x03},
+ }).MACCommand(),
+ },
+ },
+ },
+ MaxDownlinkLength: 50,
+ MaxUplinkLength: 50,
+ RelayKeyService: func(
+ context.Context, *ttnpb.ApplicationIdentifiers, []string, [][]byte,
+ ) ([]*types.DevAddr, []*types.AES128Key, error) {
+ return []*types.DevAddr{{0x42, 0x43, 0x44, 0x45}}, []*types.AES128Key{{0x01, 0x02, 0x03, 0x04}}, nil
+ },
+ State: mac.EnqueueState{
+ MaxDownLen: 23,
+ MaxUpLen: 49,
+ QueuedEvents: events.Builders{
+ mac.EvtEnqueueRelayUpdateUplinkListRequest.With(events.WithData(
+ &ttnpb.MACCommand_RelayUpdateUplinkListReq{
+ RuleIndex: 0,
+ DevAddr: types.DevAddr{0x42, 0x43, 0x44, 0x45}.Bytes(),
+ WFCnt: 42,
+
+ DeviceId: "foo",
+ SessionKeyId: []byte{0x01, 0x02, 0x03},
+ },
+ )),
+ },
+ Ok: true,
+ },
+ },
+ {
+ Name: "update rule",
+ InputDevice: &ttnpb.EndDevice{
+ Ids: test.MakeEndDeviceIdentifiers(),
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ UplinkForwardingRules: []*ttnpb.RelayUplinkForwardingRule{
+ {
+ LastWFCnt: 42,
+
+ DeviceId: "foo",
+ SessionKeyId: []byte{0x01, 0x02, 0x03},
+ },
+ {
+ LastWFCnt: 24,
+
+ DeviceId: "bar",
+ SessionKeyId: []byte{0x02, 0x03, 0x04},
+ },
+ },
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ UplinkForwardingRules: []*ttnpb.RelayUplinkForwardingRule{
+ {
+ LastWFCnt: 42,
+
+ DeviceId: "foo",
+ SessionKeyId: []byte{0x01, 0x02, 0x03},
+ },
+ {
+ LastWFCnt: 42,
+
+ DeviceId: "foobar",
+ SessionKeyId: []byte{0x03, 0x04, 0x05},
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ ExpectedDevice: &ttnpb.EndDevice{
+ Ids: test.MakeEndDeviceIdentifiers(),
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ UplinkForwardingRules: []*ttnpb.RelayUplinkForwardingRule{
+ {
+ LastWFCnt: 42,
+
+ DeviceId: "foo",
+ SessionKeyId: []byte{0x01, 0x02, 0x03},
+ },
+ {
+ LastWFCnt: 24,
+
+ DeviceId: "bar",
+ SessionKeyId: []byte{0x02, 0x03, 0x04},
+ },
+ },
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ UplinkForwardingRules: []*ttnpb.RelayUplinkForwardingRule{
+ {
+ LastWFCnt: 42,
+
+ DeviceId: "foo",
+ SessionKeyId: []byte{0x01, 0x02, 0x03},
+ },
+ {
+ LastWFCnt: 42,
+
+ DeviceId: "foobar",
+ SessionKeyId: []byte{0x03, 0x04, 0x05},
+ },
+ },
+ },
+ },
+ },
+ },
+ PendingRequests: []*ttnpb.MACCommand{
+ (&ttnpb.MACCommand_RelayUpdateUplinkListReq{
+ RuleIndex: 1,
+ DevAddr: types.DevAddr{0x43, 0x44, 0x45, 0x46}.Bytes(),
+ WFCnt: 42,
+ RootWorSKey: types.AES128Key{0x02, 0x03, 0x04, 0x05}.Bytes(),
+
+ DeviceId: "foobar",
+ SessionKeyId: []byte{0x03, 0x04, 0x05},
+ }).MACCommand(),
+ },
+ },
+ },
+ MaxDownlinkLength: 50,
+ MaxUplinkLength: 50,
+ RelayKeyService: func(
+ context.Context, *ttnpb.ApplicationIdentifiers, []string, [][]byte,
+ ) ([]*types.DevAddr, []*types.AES128Key, error) {
+ return []*types.DevAddr{{0x43, 0x44, 0x45, 0x46}}, []*types.AES128Key{{0x02, 0x03, 0x04, 0x05}}, nil
+ },
+ State: mac.EnqueueState{
+ MaxDownLen: 23,
+ MaxUpLen: 49,
+ QueuedEvents: events.Builders{
+ mac.EvtEnqueueRelayUpdateUplinkListRequest.With(events.WithData(
+ &ttnpb.MACCommand_RelayUpdateUplinkListReq{
+ RuleIndex: 1,
+ DevAddr: types.DevAddr{0x43, 0x44, 0x45, 0x46}.Bytes(),
+ WFCnt: 42,
+
+ DeviceId: "foobar",
+ SessionKeyId: []byte{0x03, 0x04, 0x05},
+ },
+ )),
+ },
+ Ok: true,
+ },
+ },
+ } {
+ tc := tc
+ test.RunSubtest(t, test.SubtestConfig{
+ Name: tc.Name,
+ Parallel: true,
+ Func: func(ctx context.Context, t *testing.T, a *assertions.Assertion) {
+ t.Helper()
+ dev := ttnpb.Clone(tc.InputDevice)
+ st := mac.EnqueueRelayUpdateUplinkListReq(
+ ctx, dev, tc.MaxDownlinkLength, tc.MaxUplinkLength, tc.RelayKeyService,
+ )
+ a.So(dev, should.Resemble, tc.ExpectedDevice)
+ a.So(st.QueuedEvents, should.ResembleEventBuilders, tc.State.QueuedEvents)
+ st.QueuedEvents = tc.State.QueuedEvents
+ a.So(st, should.Resemble, tc.State)
+ },
+ })
+ }
+}
+
+func TestHandleRelayUpdateUplinkListAns(t *testing.T) {
+ t.Parallel()
+ for _, tc := range []struct {
+ Name string
+ Device, Expected *ttnpb.EndDevice
+ Payload *ttnpb.MACCommand_RelayUpdateUplinkListAns
+ Events events.Builders
+ Error error
+ }{
+ {
+ Name: "add rule",
+ Device: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{},
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ UplinkForwardingRules: []*ttnpb.RelayUplinkForwardingRule{
+ {
+ LastWFCnt: 42,
+
+ DeviceId: "foo",
+ SessionKeyId: []byte{0x01, 0x02, 0x03},
+ },
+ },
+ },
+ },
+ },
+ },
+ PendingRequests: []*ttnpb.MACCommand{
+ (&ttnpb.MACCommand_RelayUpdateUplinkListReq{
+ RuleIndex: 0,
+ DevAddr: types.DevAddr{0x42, 0x43, 0x44, 0x45}.Bytes(),
+ WFCnt: 42,
+
+ DeviceId: "foo",
+ SessionKeyId: []byte{0x01, 0x02, 0x03},
+ }).MACCommand(),
+ },
+ },
+ },
+ Expected: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ UplinkForwardingRules: []*ttnpb.RelayUplinkForwardingRule{
+ {
+ LastWFCnt: 42,
+
+ DeviceId: "foo",
+ SessionKeyId: []byte{0x01, 0x02, 0x03},
+ },
+ },
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ UplinkForwardingRules: []*ttnpb.RelayUplinkForwardingRule{
+ {
+ LastWFCnt: 42,
+
+ DeviceId: "foo",
+ SessionKeyId: []byte{0x01, 0x02, 0x03},
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ Payload: &ttnpb.MACCommand_RelayUpdateUplinkListAns{},
+ Events: events.Builders{
+ mac.EvtReceiveRelayUpdateUplinkListAnswer.With(events.WithData(
+ &ttnpb.MACCommand_RelayUpdateUplinkListAns{},
+ )),
+ },
+ },
+ {
+ Name: "update rule",
+ Device: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ UplinkForwardingRules: []*ttnpb.RelayUplinkForwardingRule{
+ {
+ LastWFCnt: 42,
+
+ DeviceId: "foo",
+ SessionKeyId: []byte{0x01, 0x02, 0x03},
+ },
+ {
+ LastWFCnt: 24,
+
+ DeviceId: "bar",
+ SessionKeyId: []byte{0x02, 0x03, 0x04},
+ },
+ },
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ UplinkForwardingRules: []*ttnpb.RelayUplinkForwardingRule{
+ {
+ LastWFCnt: 42,
+
+ DeviceId: "foo",
+ SessionKeyId: []byte{0x01, 0x02, 0x03},
+ },
+ {
+ LastWFCnt: 42,
+
+ DeviceId: "foobar",
+ SessionKeyId: []byte{0x03, 0x04, 0x05},
+ },
+ },
+ },
+ },
+ },
+ },
+ PendingRequests: []*ttnpb.MACCommand{
+ (&ttnpb.MACCommand_RelayUpdateUplinkListReq{
+ RuleIndex: 1,
+ DevAddr: types.DevAddr{0x43, 0x44, 0x45, 0x46}.Bytes(),
+ WFCnt: 42,
+
+ DeviceId: "foobar",
+ SessionKeyId: []byte{0x03, 0x04, 0x05},
+ }).MACCommand(),
+ },
+ },
+ },
+ Expected: &ttnpb.EndDevice{
+ MacState: &ttnpb.MACState{
+ CurrentParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ UplinkForwardingRules: []*ttnpb.RelayUplinkForwardingRule{
+ {
+ LastWFCnt: 42,
+
+ DeviceId: "foo",
+ SessionKeyId: []byte{0x01, 0x02, 0x03},
+ },
+ {
+ LastWFCnt: 42,
+
+ DeviceId: "foobar",
+ SessionKeyId: []byte{0x03, 0x04, 0x05},
+ },
+ },
+ },
+ },
+ },
+ },
+ DesiredParameters: &ttnpb.MACParameters{
+ Relay: &ttnpb.RelayParameters{
+ Mode: &ttnpb.RelayParameters_Serving{
+ Serving: &ttnpb.ServingRelayParameters{
+ UplinkForwardingRules: []*ttnpb.RelayUplinkForwardingRule{
+ {
+ LastWFCnt: 42,
+
+ DeviceId: "foo",
+ SessionKeyId: []byte{0x01, 0x02, 0x03},
+ },
+ {
+ LastWFCnt: 42,
+
+ DeviceId: "foobar",
+ SessionKeyId: []byte{0x03, 0x04, 0x05},
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ Payload: &ttnpb.MACCommand_RelayUpdateUplinkListAns{},
+ Events: events.Builders{
+ mac.EvtReceiveRelayUpdateUplinkListAnswer.With(events.WithData(
+ &ttnpb.MACCommand_RelayUpdateUplinkListAns{},
+ )),
+ },
+ },
+ } {
+ tc := tc
+ test.RunSubtest(t, test.SubtestConfig{
+ Name: tc.Name,
+ Parallel: true,
+ Func: func(ctx context.Context, t *testing.T, a *assertions.Assertion) {
+ t.Helper()
+ dev := ttnpb.Clone(tc.Device)
+ evs, err := mac.HandleRelayUpdateUplinkListAns(ctx, dev, tc.Payload)
+ if tc.Error != nil && !a.So(err, should.EqualErrorOrDefinition, tc.Error) ||
+ tc.Error == nil && !a.So(err, should.BeNil) {
+ t.FailNow()
+ }
+ a.So(dev, should.Resemble, tc.Expected)
+ a.So(evs, should.ResembleEventBuilders, tc.Events)
+ },
+ })
+ }
+}
diff --git a/pkg/networkserver/mac/utils.go b/pkg/networkserver/mac/utils.go
index 50269c9331..922fc5c227 100644
--- a/pkg/networkserver/mac/utils.go
+++ b/pkg/networkserver/mac/utils.go
@@ -18,6 +18,7 @@ import (
"context"
"fmt"
"math"
+ "slices"
"go.thethings.network/lorawan-stack/v3/pkg/band"
"go.thethings.network/lorawan-stack/v3/pkg/crypto"
@@ -31,7 +32,6 @@ import (
"go.thethings.network/lorawan-stack/v3/pkg/specification/macspec"
"go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
"go.thethings.network/lorawan-stack/v3/pkg/types"
- "golang.org/x/exp/slices"
)
func channelDataRateRange(
@@ -713,6 +713,7 @@ func NewState(dev *ttnpb.EndDevice, fps *frequencyplans.Store, defaults *ttnpb.M
AdrAckLimitExponent: &ttnpb.ADRAckLimitExponentValue{Value: phy.ADRAckLimit},
AdrAckDelayExponent: &ttnpb.ADRAckDelayExponentValue{Value: phy.ADRAckDelay},
PingSlotDataRateIndexValue: DeviceDefaultPingSlotDataRateIndexValue(dev, phy, defaults),
+ Relay: DeviceDefaultRelayParameters(dev, defaults),
}
desired := current
if !dev.Multicast {
@@ -735,6 +736,7 @@ func NewState(dev *ttnpb.EndDevice, fps *frequencyplans.Store, defaults *ttnpb.M
AdrAckLimitExponent: DeviceDesiredADRAckLimitExponent(dev, phy, defaults),
AdrAckDelayExponent: DeviceDesiredADRAckDelayExponent(dev, phy, defaults),
PingSlotDataRateIndexValue: DeviceDesiredPingSlotDataRateIndexValue(dev, phy, fp, defaults),
+ Relay: DeviceDesiredRelayParameters(dev, defaults),
}
}
// TODO: Support rejoins. (https://github.com/TheThingsNetwork/lorawan-stack/issues/8)
diff --git a/pkg/networkserver/networkserver.go b/pkg/networkserver/networkserver.go
index 8ff73d33ea..306df5244b 100644
--- a/pkg/networkserver/networkserver.go
+++ b/pkg/networkserver/networkserver.go
@@ -20,7 +20,6 @@ import (
"crypto/rand"
"fmt"
"os"
- "sync"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"go.thethings.network/lorawan-stack/v3/pkg/cluster"
@@ -167,7 +166,6 @@ type NetworkServer struct {
newDevAddr newDevAddrFunc
devAddrPrefixes devAddrPrefixesFunc
- applicationServers *sync.Map // string -> *applicationUpStream
applicationUplinks ApplicationUplinkQueue
downlinkTasks DownlinkTaskQueue
@@ -282,7 +280,6 @@ func New(c *component.Component, conf *Config, opts ...Option) (*NetworkServer,
clusterID: conf.ClusterID,
newDevAddr: makeNewDevAddrFunc(devAddrPrefixes...),
devAddrPrefixes: makeDevAddrPrefixesFunc(devAddrPrefixes...),
- applicationServers: &sync.Map{},
applicationUplinks: conf.ApplicationUplinkQueue.Queue,
deduplicationWindow: makeWindowDurationFunc(conf.DeduplicationWindow),
collectionWindow: makeWindowDurationFunc(conf.DeduplicationWindow + conf.CooldownWindow),
@@ -349,8 +346,7 @@ func New(c *component.Component, conf *Config, opts ...Option) (*NetworkServer,
for id, dispatcher := range map[string]interface {
Dispatch(context.Context, string) error
}{
- downlinkDispatchTaskName: ns.downlinkTasks,
- applicationUplinkDispatchTaskName: ns.applicationUplinks,
+ downlinkDispatchTaskName: ns.downlinkTasks,
} {
dispatcher := dispatcher
ns.RegisterTask(&task.Config{
diff --git a/pkg/networkserver/networkserver_util_internal_test.go b/pkg/networkserver/networkserver_util_internal_test.go
index 4c615527ed..dd7f1dc7cc 100644
--- a/pkg/networkserver/networkserver_util_internal_test.go
+++ b/pkg/networkserver/networkserver_util_internal_test.go
@@ -2523,6 +2523,12 @@ type MockDeviceRegistry struct {
paths []string,
f func(context.Context, *ttnpb.EndDevice) (*ttnpb.EndDevice, []string, error),
) (*ttnpb.EndDevice, context.Context, error)
+ BatchGetByIDFunc func(
+ ctx context.Context,
+ appIDs *ttnpb.ApplicationIdentifiers,
+ devIDs []string,
+ paths []string,
+ ) ([]*ttnpb.EndDevice, error)
BatchDeleteFunc func(
ctx context.Context,
appIDs *ttnpb.ApplicationIdentifiers,
@@ -2561,6 +2567,16 @@ func (m MockDeviceRegistry) Range(ctx context.Context, paths []string, f func(co
panic("Range must not be called")
}
+// BatchGetByID panics.
+func (m MockDeviceRegistry) BatchGetByID(
+ ctx context.Context, appID *ttnpb.ApplicationIdentifiers, devIDs []string, paths []string,
+) ([]*ttnpb.EndDevice, error) {
+ if m.BatchGetByIDFunc == nil {
+ panic("BatchGetByIDFunc called, but not set")
+ }
+ return m.BatchGetByIDFunc(ctx, appID, devIDs, paths)
+}
+
// GetByID calls GetByIDFunc if set and panics otherwise.
func (m MockDeviceRegistry) BatchDelete(
ctx context.Context,
diff --git a/pkg/networkserver/observability.go b/pkg/networkserver/observability.go
index d2f3acbeb6..53777c2743 100644
--- a/pkg/networkserver/observability.go
+++ b/pkg/networkserver/observability.go
@@ -56,6 +56,16 @@ var (
Up: &ttnpb.ApplicationUp_UplinkMessage{UplinkMessage: &ttnpb.ApplicationUplink{}},
}),
)
+ evtDropRelayUplink = events.Define(
+ "ns.up.relay.drop", "drop relay message",
+ events.WithVisibility(ttnpb.Right_RIGHT_APPLICATION_TRAFFIC_READ),
+ events.WithErrorDataType(),
+ )
+ evtProcessRelayUplink = events.Define(
+ "ns.up.relay.process", "successfully processed relay message",
+ events.WithVisibility(ttnpb.Right_RIGHT_APPLICATION_TRAFFIC_READ),
+ events.WithDataType(&ttnpb.UplinkMessage{}),
+ )
evtScheduleDataDownlinkAttempt = events.Define(
"ns.down.data.schedule.attempt", "schedule data downlink for transmission on Gateway Server",
events.WithVisibility(ttnpb.Right_RIGHT_APPLICATION_TRAFFIC_READ),
diff --git a/pkg/networkserver/redis/application_uplink_queue.go b/pkg/networkserver/redis/application_uplink_queue.go
index 87630eca76..ec9042ab8a 100644
--- a/pkg/networkserver/redis/application_uplink_queue.go
+++ b/pkg/networkserver/redis/application_uplink_queue.go
@@ -16,51 +16,59 @@ package redis
import (
"context"
+ "sync"
"github.com/redis/go-redis/v9"
"go.thethings.network/lorawan-stack/v3/pkg/errors"
- "go.thethings.network/lorawan-stack/v3/pkg/networkserver"
+ "go.thethings.network/lorawan-stack/v3/pkg/log"
"go.thethings.network/lorawan-stack/v3/pkg/networkserver/internal/time"
ttnredis "go.thethings.network/lorawan-stack/v3/pkg/redis"
"go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
"go.thethings.network/lorawan-stack/v3/pkg/unique"
)
-type ApplicationUplinkQueue struct {
- applicationQueue *ttnredis.TaskQueue
-
- redis *ttnredis.Client
- maxLen int64
- group string
- key string
- minIdle time.Duration
+type contextualUplinkBatch struct {
+ ctx context.Context
+ confirmIDs []string
+ uplinks []*ttnpb.ApplicationUp
}
const (
- payloadKey = "payload"
+ payloadKey = "payload"
+ payloadUIDKey = "uid"
+)
+
+var (
+ errMissingPayload = errors.DefineDataLoss("missing_payload", "missing payload")
+ errInvalidPayload = errors.DefineCorruption("invalid_payload", "invalid payload")
+ errMissingUID = errors.DefineDataLoss("missing_uid", "missing UID")
+ errInvalidUID = errors.DefineCorruption("invalid_uid", "invalid UID")
)
+// ApplicationUplinkQueue is an implementation of ApplicationUplinkQueue.
+type ApplicationUplinkQueue struct {
+ redis *ttnredis.Client
+ maxLen int64
+ groupID string
+ streamID string
+ minIdle time.Duration
+ consumers sync.Map
+}
+
// NewApplicationUplinkQueue returns new application uplink queue.
func NewApplicationUplinkQueue(
cl *ttnredis.Client,
maxLen int64,
- group string,
+ groupID string,
minIdle time.Duration,
- streamBlockLimit time.Duration,
) *ApplicationUplinkQueue {
return &ApplicationUplinkQueue{
- applicationQueue: &ttnredis.TaskQueue{
- Redis: cl,
- MaxLen: maxLen,
- Group: group,
- Key: cl.Key("application"),
- StreamBlockLimit: streamBlockLimit,
- },
- redis: cl,
- maxLen: maxLen,
- group: group,
- key: cl.Key("application-uplink"),
- minIdle: minIdle,
+ redis: cl,
+ maxLen: maxLen,
+ groupID: groupID,
+ streamID: cl.Key("uplinks"),
+ minIdle: minIdle,
+ consumers: sync.Map{},
}
}
@@ -68,68 +76,48 @@ func ApplicationUplinkQueueUIDGenericUplinkKey(r keyer, uid string) string {
return ttnredis.Key(UIDKey(r, uid), "uplinks")
}
-func (q *ApplicationUplinkQueue) uidGenericUplinkKey(uid string) string {
- return ApplicationUplinkQueueUIDGenericUplinkKey(q.redis, uid)
-}
-
-func (q *ApplicationUplinkQueue) uidInvalidationKey(uid string) string {
- return ttnredis.Key(q.uidGenericUplinkKey(uid), "invalidation")
-}
-
-func (q *ApplicationUplinkQueue) uidJoinAcceptKey(uid string) string {
- return ttnredis.Key(q.uidGenericUplinkKey(uid), "join-accept")
-}
-
// Init initializes the ApplicationUplinkQueue.
func (q *ApplicationUplinkQueue) Init(ctx context.Context) error {
- return q.applicationQueue.Init(ctx)
+ cmd := q.redis.XGroupCreateMkStream(ctx, q.streamID, q.groupID, "0")
+ if err := cmd.Err(); err != nil && !ttnredis.IsConsumerGroupExistsErr(err) {
+ return ttnredis.ConvertError(err)
+ }
+ return nil
}
-// Close closes the ApplicationUplinkQueue.
+// Close removes all consumers from the consumer group.
func (q *ApplicationUplinkQueue) Close(ctx context.Context) error {
- return q.applicationQueue.Close(ctx)
+ pipeline := q.redis.Pipeline()
+ q.consumers.Range(func(key, value any) bool {
+ pipeline.XGroupDelConsumer(ctx, q.streamID, q.groupID, key.(string))
+ return true
+ })
+ if _, err := pipeline.Exec(ctx); err != nil {
+ return ttnredis.ConvertError(err)
+ }
+ return nil
}
+// Add implements ApplicationUplinkQueue interface.
func (q *ApplicationUplinkQueue) Add(ctx context.Context, ups ...*ttnpb.ApplicationUp) error {
if len(ups) == 0 {
return nil
}
_, err := q.redis.Pipelined(ctx, func(p redis.Pipeliner) error {
- now := time.Now()
- taskMap := map[string]time.Time{}
for _, up := range ups {
- uid := unique.ID(ctx, up.EndDeviceIds.ApplicationIds)
-
s, err := ttnredis.MarshalProto(up)
if err != nil {
return err
}
-
- var uidStreamID string
- switch up.Up.(type) {
- case *ttnpb.ApplicationUp_JoinAccept:
- uidStreamID = q.uidJoinAcceptKey(uid)
- case *ttnpb.ApplicationUp_DownlinkQueueInvalidated:
- uidStreamID = q.uidInvalidationKey(uid)
- default:
- uidStreamID = q.uidGenericUplinkKey(uid)
- }
p.XAdd(ctx, &redis.XAddArgs{
- Stream: uidStreamID,
+ Stream: q.streamID,
MaxLen: q.maxLen,
Approx: true,
Values: map[string]any{
- payloadKey: s,
+ payloadUIDKey: unique.ID(ctx, up.EndDeviceIds),
+ payloadKey: s,
},
})
- if _, ok := taskMap[uid]; !ok {
- taskMap[uid] = now
- }
- }
- for uid, t := range taskMap {
- if err := q.applicationQueue.Add(ctx, p, uid, t, false); err != nil {
- return err
- }
}
return nil
})
@@ -139,83 +127,111 @@ func (q *ApplicationUplinkQueue) Add(ctx context.Context, ups ...*ttnpb.Applicat
return nil
}
-var (
- errInvalidPayload = errors.DefineCorruption("invalid_payload", "invalid payload")
- errMissingPayload = errors.DefineDataLoss("missing_payload", "missing payload")
-)
+func uidStrFrom(values map[string]any) (string, error) {
+ uidValue, ok := values[payloadUIDKey]
+ if !ok {
+ return "", errMissingUID.New()
+ }
+ uid, ok := uidValue.(string)
+ if !ok {
+ return "", errInvalidUID.New()
+ }
+ return uid, nil
+}
+
+func applicationUpFrom(values map[string]any) (*ttnpb.ApplicationUp, error) {
+ payloadValue, ok := values[payloadKey]
+ if !ok {
+ return nil, errMissingPayload.New()
+ }
+ payload, ok := payloadValue.(string)
+ if !ok {
+ return nil, errInvalidPayload.New()
+ }
+ up := &ttnpb.ApplicationUp{}
+ if err := ttnredis.UnmarshalProto(payload, up); err != nil {
+ return nil, errInvalidPayload.WithCause(err)
+ }
+ return up, nil
+}
-func (q *ApplicationUplinkQueue) Dispatch(ctx context.Context, consumerID string) error {
- return q.applicationQueue.Dispatch(ctx, consumerID, nil)
+func addToBatch(
+ ctx context.Context,
+ m map[string]*contextualUplinkBatch,
+ confirmID string,
+ uid string,
+ up *ttnpb.ApplicationUp,
+) error {
+ ctx, err := unique.WithContext(ctx, uid)
+ if err != nil {
+ return errInvalidUID.WithCause(err)
+ }
+ ids, err := unique.ToDeviceID(uid)
+ if err != nil {
+ return errInvalidUID.WithCause(err)
+ }
+ key := unique.ID(ctx, ids.ApplicationIds)
+ batch, ok := m[key]
+ if !ok {
+ batch = &contextualUplinkBatch{
+ ctx: ctx,
+ confirmIDs: make([]string, 0),
+ uplinks: make([]*ttnpb.ApplicationUp, 0),
+ }
+ m[key] = batch
+ }
+ batch.uplinks = append(batch.uplinks, up)
+ batch.confirmIDs = append(batch.confirmIDs, confirmID)
+ return nil
}
-func (q *ApplicationUplinkQueue) Pop(ctx context.Context, consumerID string, f func(context.Context, *ttnpb.ApplicationIdentifiers, networkserver.ApplicationUplinkQueueDrainFunc) (time.Time, error)) error {
- return q.applicationQueue.Pop(ctx, consumerID, nil, func(p redis.Pipeliner, uid string, _ time.Time) error {
- appID, err := unique.ToApplicationID(uid)
+func (*ApplicationUplinkQueue) processMessages(
+ ctx context.Context,
+ msgs []redis.XMessage,
+ ack func(...string) error,
+ f func(context.Context, []*ttnpb.ApplicationUp) error,
+) error {
+ batches := map[string]*contextualUplinkBatch{}
+ for _, msg := range msgs {
+ uid, err := uidStrFrom(msg.Values)
if err != nil {
return err
}
- ctx, err := unique.WithContext(ctx, uid)
+ up, err := applicationUpFrom(msg.Values)
if err != nil {
return err
}
- joinAcceptUpStream := q.uidJoinAcceptKey(uid)
- invalidationUpStream := q.uidInvalidationKey(uid)
- genericUpStream := q.uidGenericUplinkKey(uid)
-
- streams := [...]string{
- joinAcceptUpStream,
- invalidationUpStream,
- genericUpStream,
- }
-
- cmds, err := q.redis.Pipelined(ctx, func(pp redis.Pipeliner) error {
- for _, stream := range streams {
- pp.XGroupCreateMkStream(ctx, stream, q.group, "0")
- }
- return nil
- })
- if err != nil && !ttnredis.IsConsumerGroupExistsErr(err) {
- return ttnredis.ConvertError(err)
- }
- var initErr error
- for i, cmd := range cmds {
- if err := cmd.Err(); err != nil && !ttnredis.IsConsumerGroupExistsErr(err) {
- initErr = err
- continue
- }
- p.XGroupDelConsumer(ctx, streams[i], q.group, consumerID)
+ if err := addToBatch(ctx, batches, msg.ID, uid, up); err != nil {
+ return err
}
- if initErr != nil {
- return ttnredis.ConvertError(initErr)
+ }
+ processedIDs := make([]string, 0, len(msgs))
+ for _, batch := range batches {
+ if err := f(batch.ctx, batch.uplinks); err != nil {
+ log.FromContext(ctx).WithError(err).Warn("Failed to process uplink batch")
+ continue // Do not confirm messages that failed to process.
}
+ processedIDs = append(processedIDs, batch.confirmIDs...)
+ }
+ return ack(processedIDs...)
+}
- t, err := f(ctx, appID, func(limit int, g func(...*ttnpb.ApplicationUp) error) error {
- ups := make([]*ttnpb.ApplicationUp, 0, limit)
-
- processMessages := func(stream string, msgs ...redis.XMessage) error {
- ups = ups[:0]
- for _, msg := range msgs {
- v, ok := msg.Values[payloadKey]
- if !ok {
- return errMissingPayload.New()
- }
- s, ok := v.(string)
- if !ok {
- return errInvalidPayload.New()
- }
- up := &ttnpb.ApplicationUp{}
- if err = ttnredis.UnmarshalProto(s, up); err != nil {
- return err
- }
- ups = append(ups, up)
- }
- return g(ups...)
- }
- return ttnredis.RangeStreams(ctx, q.redis, q.group, consumerID, int64(limit), q.minIdle, processMessages, streams[:]...)
- })
- if err != nil || t.IsZero() {
- return err
- }
- return q.applicationQueue.Add(ctx, p, uid, t, true)
- })
+// Pop implements ApplicationUplinkQueue interface.
+func (q *ApplicationUplinkQueue) Pop(
+ ctx context.Context, consumerID string, limit int,
+ f func(context.Context, []*ttnpb.ApplicationUp) error,
+) error {
+ q.consumers.Store(consumerID, struct{}{})
+ return ttnredis.RangeStreams(
+ ctx,
+ q.redis,
+ q.groupID,
+ consumerID,
+ int64(limit),
+ q.minIdle,
+ func(_ string, ack func(...string) error, msgs ...redis.XMessage) error {
+ return q.processMessages(ctx, msgs, ack, f)
+ },
+ q.streamID,
+ )
}
diff --git a/pkg/networkserver/redis/application_uplink_queue_test.go b/pkg/networkserver/redis/application_uplink_queue_test.go
index 4b5adc0a04..f66834ebca 100644
--- a/pkg/networkserver/redis/application_uplink_queue_test.go
+++ b/pkg/networkserver/redis/application_uplink_queue_test.go
@@ -15,28 +15,417 @@
package redis_test
import (
+ "context"
"fmt"
+ "sync"
"testing"
+ "time"
+ "github.com/redis/go-redis/v9"
+ "github.com/smarty/assertions"
"go.thethings.network/lorawan-stack/v3/pkg/networkserver"
- . "go.thethings.network/lorawan-stack/v3/pkg/networkserver/internal/test/shared"
- . "go.thethings.network/lorawan-stack/v3/pkg/networkserver/redis"
+ nsredis "go.thethings.network/lorawan-stack/v3/pkg/networkserver/redis"
+ ttnredis "go.thethings.network/lorawan-stack/v3/pkg/redis"
+ "go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
+ "go.thethings.network/lorawan-stack/v3/pkg/unique"
"go.thethings.network/lorawan-stack/v3/pkg/util/test"
+ "go.thethings.network/lorawan-stack/v3/pkg/util/test/assertions/should"
)
-var _ networkserver.ApplicationUplinkQueue = &ApplicationUplinkQueue{}
-
-func TestApplicationUplinkQueue(t *testing.T) {
- for _, consumers := range []int{1, 2, 4, 8} {
- t.Run(fmt.Sprintf("Consumers=%d", consumers), func(t *testing.T) {
- _, ctx := test.New(t)
- consumerIDs := make([]string, 0, consumers)
- for i := 0; i < consumers; i++ {
- consumerIDs = append(consumerIDs, fmt.Sprintf("consumer-%d-%d", consumers, i))
- }
- q, closeFn := NewRedisApplicationUplinkQueue(ctx)
- defer closeFn()
- HandleApplicationUplinkQueueTest(t, q, consumerIDs)
- })
+var _ networkserver.ApplicationUplinkQueue = &nsredis.ApplicationUplinkQueue{}
+
+var (
+ redisNamespace = [...]string{
+ "redis_test_uplink_queue",
+ }
+ readLimit = 7
+ maxLen = int64(100)
+ groupID = "ns-test"
+ minIdle = (1 << 8) * test.Delay
+
+ appCount = 5
+ devCountPerApp = 3
+)
+
+func setupRedisApplicationUplinkQueue(
+ t *testing.T, cl *ttnredis.Client, minIdle time.Duration,
+) (*nsredis.ApplicationUplinkQueue, func()) {
+ t.Helper()
+
+ _, ctx := test.New(t)
+
+ q := nsredis.NewApplicationUplinkQueue(cl, maxLen, groupID, minIdle)
+
+ return q, func() {
+ if err := q.Close(ctx); err != nil {
+ t.Errorf("Failed to close Redis application uplink queue: %s", err)
+ }
+ }
+}
+
+func TestApplicationUplinkQueueInit(t *testing.T) {
+ t.Parallel()
+ a, ctx := test.New(t)
+
+ cl, redisCloseFn := test.NewRedis(ctx, append(redisNamespace[:], "init")...)
+ t.Cleanup(redisCloseFn)
+
+ q, qCloseFn := setupRedisApplicationUplinkQueue(t, cl, minIdle)
+ t.Cleanup(qCloseFn)
+
+ if !a.So(q.Init(ctx), should.BeNil) {
+ t.FailNow()
+ }
+
+ streamID := cl.Key("uplinks")
+ groups, err := cl.XInfoGroups(ctx, streamID).Result()
+ if !a.So(err, should.BeNil) {
+ t.FailNow()
+ }
+ a.So(groups, should.HaveLength, 1)
+ a.So(groups[0].Name, should.Equal, groupID)
+ a.So(groups[0].Consumers, should.Equal, 0)
+}
+
+func TestApplicationUplinkQueueClose(t *testing.T) {
+ t.Parallel()
+ a, ctx := test.New(t)
+
+ cl, redisCloseFn := test.NewRedis(ctx, append(redisNamespace[:], "close")...)
+ t.Cleanup(redisCloseFn)
+
+ q, _ := setupRedisApplicationUplinkQueue(t, cl, minIdle)
+
+ if !a.So(q.Init(ctx), should.BeNil) {
+ t.FailNow()
+ }
+
+ consumerIDs := []string{"test-consumer-1", "test-consumer-2"}
+ up := &ttnpb.ApplicationUp{
+ EndDeviceIds: &ttnpb.EndDeviceIdentifiers{
+ DeviceId: "test-device",
+ ApplicationIds: &ttnpb.ApplicationIdentifiers{
+ ApplicationId: "test-application",
+ },
+ },
+ }
+ for _, consumerID := range consumerIDs {
+ if err := q.Add(ctx, up); !a.So(err, should.BeNil) {
+ t.FailNow()
+ }
+ if err := q.Pop(ctx, consumerID, 1, func(ctx context.Context, ups []*ttnpb.ApplicationUp) error {
+ return nil
+ }); !a.So(err, should.BeNil) {
+ t.FailNow()
+ }
+ }
+
+ streamID := cl.Key("uplinks")
+ consumers, err := cl.XInfoConsumers(ctx, streamID, groupID).Result()
+ if !a.So(err, should.BeNil) {
+ t.FailNow()
+ }
+ a.So(consumers, should.HaveLength, 2)
+
+ if !a.So(q.Close(ctx), should.BeNil) {
+ t.FailNow()
+ }
+
+ consumers, err = cl.XInfoConsumers(ctx, streamID, groupID).Result()
+ if !a.So(err, should.BeNil) {
+ t.FailNow()
+ }
+ a.So(consumers, should.HaveLength, 0)
+}
+
+func generateRandomUplinks(t *testing.T, applicationCount, deviceCount int) []*ttnpb.ApplicationUp {
+ t.Helper()
+
+ ups := make([]*ttnpb.ApplicationUp, 0, applicationCount*deviceCount)
+ for i := 0; i < applicationCount; i++ {
+ applicationID := fmt.Sprintf("test-application-%d", i)
+ for j := 0; j < deviceCount; j++ {
+ deviceID := fmt.Sprintf("test-device-%d", j)
+ ups = append(ups, &ttnpb.ApplicationUp{
+ EndDeviceIds: &ttnpb.EndDeviceIdentifiers{
+ ApplicationIds: &ttnpb.ApplicationIdentifiers{
+ ApplicationId: applicationID,
+ },
+ DeviceId: deviceID,
+ },
+ })
+ }
+ }
+ return ups
+}
+
+func assertAllEqualAppIDs(t *testing.T, ups []*ttnpb.ApplicationUp) {
+ t.Helper()
+
+ a := assertions.New(t)
+ if !a.So(ups, should.NotBeEmpty) {
+ t.FailNow()
+ }
+
+ expected := ups[0].EndDeviceIds.ApplicationIds
+ for _, up := range ups[1:] {
+ actual := up.EndDeviceIds.ApplicationIds
+ if !a.So(actual, should.Resemble, expected) {
+ t.FailNow()
+ }
+ }
+}
+
+func assertStreamUplinkCount(t *testing.T, cl *ttnredis.Client, expected int) {
+ t.Helper()
+
+ a, ctx := test.New(t)
+ streamID := cl.Key("uplinks")
+ entries, err := cl.XRange(ctx, streamID, "-", "+").Result()
+ if !a.So(err, should.BeNil) {
+ t.FailNow()
+ }
+ a.So(entries, should.HaveLength, expected)
+}
+
+func TestApplicationUplinkQueueAdd(t *testing.T) {
+ t.Parallel()
+ a, ctx := test.New(t)
+
+ cl, redisCloseFn := test.NewRedis(ctx, append(redisNamespace[:], "add")...)
+ t.Cleanup(redisCloseFn)
+
+ q, qCloseFn := setupRedisApplicationUplinkQueue(t, cl, minIdle)
+ t.Cleanup(qCloseFn)
+
+ if !a.So(q.Init(ctx), should.BeNil) {
+ t.FailNow()
+ }
+
+ expectedUps := generateRandomUplinks(t, appCount, devCountPerApp)
+ expectedUIDs := make([]string, 0, len(expectedUps))
+ for _, up := range expectedUps {
+ expectedUIDs = append(expectedUIDs, unique.ID(ctx, up.EndDeviceIds))
}
+
+ if err := q.Add(ctx, expectedUps...); !a.So(err, should.BeNil) {
+ t.FailNow()
+ }
+
+ streamID := cl.Key("uplinks")
+ entries, err := cl.XRange(ctx, streamID, "-", "+").Result()
+ if !a.So(err, should.BeNil) {
+ t.FailNow()
+ }
+ if !a.So(entries, should.HaveLength, len(expectedUps)) {
+ t.FailNow()
+ }
+
+ actualUIDs := make([]string, 0, len(entries))
+ actualUps := make([]*ttnpb.ApplicationUp, 0, 4)
+ for _, entry := range entries {
+ a.So(entry.Values, should.HaveLength, 2)
+ a.So(entry.Values["payload"], should.NotBeEmpty)
+ a.So(entry.Values["uid"], should.NotBeEmpty)
+ actualUIDs = append(actualUIDs, entry.Values["uid"].(string))
+ up := &ttnpb.ApplicationUp{}
+ if err := ttnredis.UnmarshalProto(entry.Values["payload"].(string), up); !a.So(err, should.BeNil) {
+ t.FailNow()
+ }
+ actualUps = append(actualUps, up)
+ }
+ a.So(actualUIDs, should.HaveSameElementsDeep, expectedUIDs)
+ a.So(actualUps, should.HaveSameElementsDeep, expectedUps)
+}
+
+func TestApplicationUplinkQueuePopAll(t *testing.T) {
+ t.Parallel()
+ a, ctx := test.New(t)
+
+ cl, redisCloseFn := test.NewRedis(ctx, append(redisNamespace[:], "pop_all")...)
+ t.Cleanup(redisCloseFn)
+
+ q, qCloseFn := setupRedisApplicationUplinkQueue(t, cl, minIdle)
+ t.Cleanup(qCloseFn)
+
+ if !a.So(q.Init(ctx), should.BeNil) {
+ t.FailNow()
+ }
+
+ expected := generateRandomUplinks(t, appCount, devCountPerApp)
+ if err := q.Add(ctx, expected...); !a.So(err, should.BeNil) {
+ t.FailNow()
+ }
+
+ consumerCount := 3
+ uplinkCh := make(chan []*ttnpb.ApplicationUp, consumerCount*appCount)
+ wg := sync.WaitGroup{}
+
+ for i := 0; i < consumerCount; i++ {
+ consumerID := fmt.Sprintf("test-consumer-%d", i)
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+
+ a.So(q.Pop(ctx, consumerID, readLimit, func(ctx context.Context, ups []*ttnpb.ApplicationUp) error {
+ assertAllEqualAppIDs(t, ups)
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ case uplinkCh <- ups:
+ }
+ return nil
+ }), should.BeNil)
+ }()
+ }
+ wg.Wait()
+
+ actual := make([]*ttnpb.ApplicationUp, 0, len(expected))
+outer:
+ for {
+ select {
+ case <-ctx.Done():
+ break outer
+ case ups := <-uplinkCh:
+ actual = append(actual, ups...)
+ default:
+ break outer
+ }
+ }
+
+ a.So(actual, should.HaveLength, len(expected))
+ assertStreamUplinkCount(t, cl, 0)
+}
+
+func TestApplicationUplinkQueuePopErr(t *testing.T) {
+ t.Parallel()
+ a, ctx := test.New(t)
+
+ cl, redisCloseFn := test.NewRedis(ctx, append(redisNamespace[:], "pop_err")...)
+ t.Cleanup(redisCloseFn)
+
+ q, qCloseFn := setupRedisApplicationUplinkQueue(t, cl, minIdle)
+ t.Cleanup(qCloseFn)
+
+ if !a.So(q.Init(ctx), should.BeNil) {
+ t.FailNow()
+ }
+
+ generateError := func(ups []*ttnpb.ApplicationUp) error {
+ appID := ups[0].EndDeviceIds.ApplicationIds.ApplicationId
+ if appID == "test-application-1" || appID == "test-application-2" {
+ return fmt.Errorf("test error")
+ }
+ return nil
+ }
+
+ expected := generateRandomUplinks(t, appCount, devCountPerApp)
+ if err := q.Add(ctx, expected...); !a.So(err, should.BeNil) {
+ t.FailNow()
+ }
+
+ consumerCount := 3
+ uplinkCh := make(chan []*ttnpb.ApplicationUp, consumerCount*appCount)
+ wg := sync.WaitGroup{}
+
+ for i := 0; i < consumerCount; i++ {
+ consumerID := fmt.Sprintf("test-consumer-%d", i)
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+
+ a.So(q.Pop(ctx, consumerID, readLimit, func(ctx context.Context, ups []*ttnpb.ApplicationUp) error {
+ assertAllEqualAppIDs(t, ups)
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ case uplinkCh <- ups:
+ }
+ return generateError(ups)
+ }), should.BeNil)
+ }()
+ }
+ wg.Wait()
+
+ actual := make([]*ttnpb.ApplicationUp, 0, len(expected))
+outer:
+ for {
+ select {
+ case <-ctx.Done():
+ break outer
+ case ups := <-uplinkCh:
+ actual = append(actual, ups...)
+ default:
+ break outer
+ }
+ }
+
+ expectedFailCount := devCountPerApp * 2
+
+ a.So(actual, should.HaveLength, len(expected)) // All uplinks should have been processed
+ assertStreamUplinkCount(t, cl, expectedFailCount) // Only failed uplinks should remain in the stream
+}
+
+func TestApplicationUplinkQueueClaiming(t *testing.T) {
+ t.Parallel()
+ a, ctx := test.New(t)
+
+ cl, redisCloseFn := test.NewRedis(ctx, append(redisNamespace[:], "claiming")...)
+ t.Cleanup(redisCloseFn)
+
+ q, qCloseFn := setupRedisApplicationUplinkQueue(t, cl, 0)
+ t.Cleanup(qCloseFn)
+
+ if !a.So(q.Init(ctx), should.BeNil) {
+ t.FailNow()
+ }
+
+ expected := generateRandomUplinks(t, appCount, devCountPerApp)
+ totalCount := len(expected)
+ subsetCount := totalCount / 2
+ subset, rest := expected[:subsetCount], expected[subsetCount:]
+
+ if err := q.Add(ctx, subset...); !a.So(err, should.BeNil) {
+ t.FailNow()
+ }
+
+ consumerID1 := fmt.Sprintf("test-consumer-%d", 1)
+ err := q.Pop(ctx, consumerID1, totalCount, func(ctx context.Context, ups []*ttnpb.ApplicationUp) error {
+ return fmt.Errorf("consumer error")
+ })
+ if !a.So(err, should.BeNil) {
+ t.FailNow()
+ }
+
+ streamID := cl.Key("uplinks")
+ pending, err := cl.XPendingExt(ctx, &redis.XPendingExtArgs{
+ Stream: streamID,
+ Group: groupID,
+ Start: "-",
+ End: "+",
+ Count: int64(totalCount),
+ }).Result()
+ if !a.So(err, should.BeNil) {
+ t.FailNow()
+ }
+ a.So(len(pending), should.Equal, subsetCount)
+
+ if err := q.Add(ctx, rest...); !a.So(err, should.BeNil) {
+ t.FailNow()
+ }
+
+ actual := make([]*ttnpb.ApplicationUp, 0, len(expected))
+ consumerID2 := fmt.Sprintf("test-consumer-%d", 2)
+ err = q.Pop(ctx, consumerID2, 100, func(ctx context.Context, ups []*ttnpb.ApplicationUp) error {
+ assertAllEqualAppIDs(t, ups)
+ actual = append(actual, ups...)
+ return nil
+ })
+ if !a.So(err, should.BeNil) {
+ t.FailNow()
+ }
+
+ a.So(err, should.BeNil)
+ a.So(actual, should.HaveLength, len(expected))
+ assertStreamUplinkCount(t, cl, 0)
}
diff --git a/pkg/networkserver/redis/registry.go b/pkg/networkserver/redis/registry.go
index 6efbc2e99b..f6661b536c 100644
--- a/pkg/networkserver/redis/registry.go
+++ b/pkg/networkserver/redis/registry.go
@@ -30,6 +30,7 @@ import (
"go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
"go.thethings.network/lorawan-stack/v3/pkg/types"
"go.thethings.network/lorawan-stack/v3/pkg/unique"
+ "golang.org/x/exp/maps"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/timestamppb"
)
@@ -38,6 +39,8 @@ var (
errInvalidFieldmask = errors.DefineInvalidArgument("invalid_fieldmask", "invalid fieldmask")
errInvalidIdentifiers = errors.DefineInvalidArgument("invalid_identifiers", "invalid identifiers")
errReadOnlyField = errors.DefineInvalidArgument("read_only_field", "read-only field `{field}`")
+
+ errRelayServed = errors.DefineAlreadyExists("relay_served", "`{served}` is already served by `{serving}`")
)
// DeviceSchemaVersion is the Network Server database schema version regarding the devices namespace.
@@ -78,6 +81,34 @@ func (r *DeviceRegistry) euiKey(joinEUI, devEUI types.EUI64) string {
return r.Redis.Key("eui", joinEUI.String(), devEUI.String())
}
+func (r *DeviceRegistry) relayRulesMapping(ctx context.Context, dev *ttnpb.EndDevice) map[string]string {
+ m := make(map[string]string)
+ add := func(rules []*ttnpb.RelayUplinkForwardingRule) {
+ for _, rule := range rules {
+ if rule.GetDeviceId() == "" {
+ continue
+ }
+ servedUID := unique.ID(ctx, &ttnpb.EndDeviceIdentifiers{
+ ApplicationIds: dev.Ids.ApplicationIds,
+ DeviceId: rule.DeviceId,
+ })
+ path := r.Redis.Key("relay", "rules", servedUID)
+ m[path] = servedUID
+ }
+ }
+ for _, rules := range [][]*ttnpb.RelayUplinkForwardingRule{
+ dev.GetMacSettings().GetRelay().GetServing().GetUplinkForwardingRules(),
+ dev.GetMacSettings().GetDesiredRelay().GetServing().GetUplinkForwardingRules(),
+ dev.GetMacState().GetCurrentParameters().GetRelay().GetServing().GetUplinkForwardingRules(),
+ dev.GetMacState().GetDesiredParameters().GetRelay().GetServing().GetUplinkForwardingRules(),
+ dev.GetPendingMacState().GetCurrentParameters().GetRelay().GetServing().GetUplinkForwardingRules(),
+ dev.GetPendingMacState().GetDesiredParameters().GetRelay().GetServing().GetUplinkForwardingRules(),
+ } {
+ add(rules)
+ }
+ return m
+}
+
// GetByID gets device by appID, devID.
func (r *DeviceRegistry) GetByID(ctx context.Context, appID *ttnpb.ApplicationIdentifiers, devID string, paths []string) (*ttnpb.EndDevice, context.Context, error) {
defer trace.StartRegion(ctx, "get end device by id").End()
@@ -101,6 +132,48 @@ func (r *DeviceRegistry) GetByID(ctx context.Context, appID *ttnpb.ApplicationId
return pb, ctx, nil
}
+// BatchGetByID gets devices by appID, deviceIDs.
+func (r *DeviceRegistry) BatchGetByID(
+ ctx context.Context, appID *ttnpb.ApplicationIdentifiers, deviceIDs []string, paths []string,
+) ([]*ttnpb.EndDevice, error) {
+ defer trace.StartRegion(ctx, "batch get end device by id").End()
+
+ keys := make([]string, len(deviceIDs))
+ for i, devID := range deviceIDs {
+ ids := &ttnpb.EndDeviceIdentifiers{
+ ApplicationIds: appID,
+ DeviceId: devID,
+ }
+ if err := ids.ValidateContext(ctx); err != nil {
+ return nil, err
+ }
+ keys[i] = r.uidKey(unique.ID(ctx, ids))
+ }
+
+ results, err := r.Redis.MGet(ctx, keys...).Result()
+ if err != nil {
+ return nil, ttnredis.ConvertError(err)
+ }
+
+ protos := make([]*ttnpb.EndDevice, len(deviceIDs))
+ for i, result := range results {
+ switch cmd := result.(type) {
+ case nil:
+ case string:
+ dev := &ttnpb.EndDevice{}
+ if err := ttnredis.UnmarshalProto(cmd, dev); err != nil {
+ return nil, err
+ }
+ dev, err = ttnpb.FilterGetEndDevice(dev, paths...)
+ if err != nil {
+ return nil, err
+ }
+ protos[i] = dev
+ }
+ }
+ return protos, nil
+}
+
// GetByEUI gets device by joinEUI, devEUI.
func (r *DeviceRegistry) GetByEUI(ctx context.Context, joinEUI, devEUI types.EUI64, paths []string) (*ttnpb.EndDevice, context.Context, error) {
defer trace.StartRegion(ctx, "get end device by eui").End()
@@ -658,6 +731,9 @@ func (r *DeviceRegistry) SetByID(ctx context.Context, appID *ttnpb.ApplicationId
uid,
)
}
+ if relayRulesMapping := r.relayRulesMapping(ctx, stored); len(relayRulesMapping) > 0 {
+ p.Del(ctx, maps.Keys(relayRulesMapping)...)
+ }
return nil
}
@@ -689,6 +765,28 @@ func (r *DeviceRegistry) SetByID(ctx context.Context, appID *ttnpb.ApplicationId
return registry.UniqueEUIViolationErr(ctx, joinEUI, devEUI, storedUIDStr)
}
}
+ if relayRulesMapping := r.relayRulesMapping(ctx, pb); len(relayRulesMapping) > 0 {
+ keys := maps.Keys(relayRulesMapping)
+ if err := tx.Watch(ctx, keys...).Err(); err != nil {
+ return err
+ }
+ ruleUIDs, err := tx.MGet(ctx, keys...).Result()
+ if err != nil {
+ return err
+ }
+ for i, ruleUID := range ruleUIDs {
+ switch ruleUID := ruleUID.(type) {
+ case nil:
+ case string:
+ return errRelayServed.WithAttributes(
+ "served", relayRulesMapping[keys[i]],
+ "serving", ruleUID,
+ )
+ default:
+ panic("unreachable")
+ }
+ }
+ }
} else {
if ttnpb.HasAnyField(sets, "ids.application_ids.application_id") && pb.Ids.ApplicationIds.ApplicationId != stored.Ids.ApplicationIds.ApplicationId {
return errReadOnlyField.WithAttributes("field", "ids.application_ids.application_id")
@@ -848,6 +946,56 @@ func (r *DeviceRegistry) SetByID(ctx context.Context, appID *ttnpb.ApplicationId
}
}
+ storedRelayRulesMapping := r.relayRulesMapping(ctx, stored)
+ updatedRelayRulesMapping := r.relayRulesMapping(ctx, updated)
+ if !maps.Equal(storedRelayRulesMapping, updatedRelayRulesMapping) {
+ storedRelayRulesKeys := maps.Keys(storedRelayRulesMapping)
+ updatedRelayRulesKeys := maps.Keys(updatedRelayRulesMapping)
+ if err := tx.Watch(ctx, append(storedRelayRulesKeys, updatedRelayRulesKeys...)...).Err(); err != nil {
+ return err
+ }
+
+ removed := make([]string, 0, len(storedRelayRulesKeys))
+ for _, storedKey := range storedRelayRulesKeys {
+ if _, ok := updatedRelayRulesMapping[storedKey]; !ok {
+ removed = append(removed, storedKey)
+ }
+ }
+ if len(removed) > 0 {
+ p.Del(ctx, removed...)
+ }
+
+ added := make([]string, 0, len(updatedRelayRulesKeys))
+ for _, updatedKey := range updatedRelayRulesKeys {
+ if _, ok := storedRelayRulesMapping[updatedKey]; !ok {
+ added = append(added, updatedKey)
+ }
+ }
+ if len(added) > 0 {
+ ruleUIDs, err := tx.MGet(ctx, added...).Result()
+ if err != nil {
+ return err
+ }
+ for i, ruleUID := range ruleUIDs {
+ switch ruleUID := ruleUID.(type) {
+ case nil:
+ case string:
+ return errRelayServed.WithAttributes(
+ "served", updatedRelayRulesMapping[added[i]],
+ "serving", ruleUID,
+ )
+ default:
+ panic("unreachable")
+ }
+ }
+ addedMapping := make(map[string]string, len(added))
+ for _, addedKey := range added {
+ addedMapping[addedKey] = uid
+ }
+ p.MSet(ctx, addedMapping)
+ }
+ }
+
_, err := ttnredis.SetProto(ctx, p, uk, updated, 0)
if err != nil {
return err
@@ -930,6 +1078,7 @@ func (r *DeviceRegistry) BatchDelete(
return err
}
euiKeys := make([]string, 0, len(raw))
+ relayRulesKeys := make([]string, 0, len(raw))
for _, raw := range raw {
switch val := raw.(type) {
case nil:
@@ -964,6 +1113,7 @@ func (r *DeviceRegistry) BatchDelete(
)),
}...)
}
+ relayRulesKeys = append(relayRulesKeys, maps.Keys(r.relayRulesMapping(ctx, dev))...)
}
}
// If the provided end device identifiers are not registered, it is possible
@@ -974,8 +1124,13 @@ func (r *DeviceRegistry) BatchDelete(
return err
}
}
+ if len(relayRulesKeys) > 0 {
+ if err := tx.Watch(ctx, relayRulesKeys...).Err(); err != nil {
+ return err
+ }
+ }
if _, err := tx.TxPipelined(ctx, func(p redis.Pipeliner) error {
- p.Del(ctx, append(uidKeys, euiKeys...)...)
+ p.Del(ctx, append(append(uidKeys, euiKeys...), relayRulesKeys...)...)
for uid, keys := range addrMapping {
for _, key := range keys {
removeAddrMapping(ctx, p, key, uid)
diff --git a/pkg/networkserver/redis/uplink_deduplicator.go b/pkg/networkserver/redis/uplink_deduplicator.go
index 2f747cdca4..7af56d81a4 100644
--- a/pkg/networkserver/redis/uplink_deduplicator.go
+++ b/pkg/networkserver/redis/uplink_deduplicator.go
@@ -52,7 +52,9 @@ func uplinkHash(ctx context.Context, up *ttnpb.UplinkMessage, round uint64) (str
}
// DeduplicateUplink deduplicates up for window. Since highest precision allowed by Redis is milliseconds, window is truncated to milliseconds.
-func (d *UplinkDeduplicator) DeduplicateUplink(ctx context.Context, up *ttnpb.UplinkMessage, window time.Duration, round uint64) (bool, error) {
+func (d *UplinkDeduplicator) DeduplicateUplink(
+ ctx context.Context, up *ttnpb.UplinkMessage, window time.Duration, limit int, round uint64,
+) (bool, error) {
h, err := uplinkHash(ctx, up, round)
if err != nil {
return false, err
@@ -61,7 +63,7 @@ func (d *UplinkDeduplicator) DeduplicateUplink(ctx context.Context, up *ttnpb.Up
for _, md := range up.RxMetadata {
msgs = append(msgs, md)
}
- return ttnredis.DeduplicateProtos(ctx, d.Redis, d.Redis.Key(h), window, msgs...)
+ return ttnredis.DeduplicateProtos(ctx, d.Redis, d.Redis.Key(h), window, limit, msgs...)
}
// AccumulatedMetadata returns accumulated metadata for up.
diff --git a/pkg/networkserver/registry.go b/pkg/networkserver/registry.go
index 2c58d582f9..e76eedfc77 100644
--- a/pkg/networkserver/registry.go
+++ b/pkg/networkserver/registry.go
@@ -43,6 +43,9 @@ type DeviceRegistry interface {
RangeByUplinkMatches(ctx context.Context, up *ttnpb.UplinkMessage, f func(context.Context, *UplinkMatch) (bool, error)) error
SetByID(ctx context.Context, appID *ttnpb.ApplicationIdentifiers, devID string, paths []string, f func(context.Context, *ttnpb.EndDevice) (*ttnpb.EndDevice, []string, error)) (*ttnpb.EndDevice, context.Context, error)
Range(ctx context.Context, paths []string, f func(context.Context, *ttnpb.EndDeviceIdentifiers, *ttnpb.EndDevice) bool) error
+ BatchGetByID(
+ ctx context.Context, appID *ttnpb.ApplicationIdentifiers, deviceIDs []string, paths []string,
+ ) ([]*ttnpb.EndDevice, error)
BatchDelete(
ctx context.Context,
appIDs *ttnpb.ApplicationIdentifiers,
diff --git a/pkg/networkserver/relay.go b/pkg/networkserver/relay.go
new file mode 100644
index 0000000000..f52776bd97
--- /dev/null
+++ b/pkg/networkserver/relay.go
@@ -0,0 +1,446 @@
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package networkserver
+
+import (
+ "bytes"
+ "context"
+
+ "go.thethings.network/lorawan-stack/v3/pkg/band"
+ "go.thethings.network/lorawan-stack/v3/pkg/crypto"
+ "go.thethings.network/lorawan-stack/v3/pkg/crypto/cryptoutil"
+ "go.thethings.network/lorawan-stack/v3/pkg/encoding/lorawan"
+ "go.thethings.network/lorawan-stack/v3/pkg/errors"
+ "go.thethings.network/lorawan-stack/v3/pkg/events"
+ "go.thethings.network/lorawan-stack/v3/pkg/log"
+ "go.thethings.network/lorawan-stack/v3/pkg/networkserver/internal"
+ "go.thethings.network/lorawan-stack/v3/pkg/networkserver/internal/time"
+ "go.thethings.network/lorawan-stack/v3/pkg/networkserver/mac"
+ "go.thethings.network/lorawan-stack/v3/pkg/specification/relayspec"
+ "go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
+ "go.thethings.network/lorawan-stack/v3/pkg/types"
+ "google.golang.org/grpc"
+ "google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/types/known/durationpb"
+ "google.golang.org/protobuf/types/known/timestamppb"
+)
+
+var (
+ errRelaySchedule = errors.DefineAborted("relay_schedule", "relay schedule")
+ errRelayInvalidUplinkToken = errors.DefineInvalidArgument("relay_uplink_token", "invalid relay uplink token")
+ errRelayNoSession = errors.DefineNotFound("relay_session", "relay session not found")
+ errRelayNoSessionKeyID = errors.DefineNotFound("relay_session_key_id", "relay session key ID not found")
+ errRelayNoRecentUplinks = errors.DefineNotFound("relay_recent_uplinks", "recent uplinks not found")
+ errRelayRXWindowUnavailable = errors.DefineUnavailable("relay_rx_windows_available", "no RX windows available")
+ errRelayMTYpe = errors.DefineInvalidArgument("relay_m_type", "invalid MType")
+ errRelayFullFCnt = errors.DefineInvalidArgument("relay_full_f_cnt", "invalid full FCnt")
+ errRelayNotServing = errors.DefineUnavailable("relay_serving", "relay not serving")
+)
+
+type relayKeyService struct {
+ devices DeviceRegistry
+ keys crypto.KeyService
+}
+
+var _ mac.RelayKeyService = (*relayKeyService)(nil)
+
+// BatchDeriveRootWorSKey implements mac.RelayKeyService.
+func (r *relayKeyService) BatchDeriveRootWorSKey(
+ ctx context.Context, appID *ttnpb.ApplicationIdentifiers, deviceIDs []string, sessionKeyIDs [][]byte,
+) (devAddrs []*types.DevAddr, keys []*types.AES128Key, err error) {
+ if len(deviceIDs) != len(sessionKeyIDs) {
+ panic("device IDs and session key IDs must have the same length")
+ }
+ if len(deviceIDs) == 0 {
+ return nil, nil, nil
+ }
+ devices, err := r.devices.BatchGetByID(
+ ctx,
+ appID,
+ deviceIDs,
+ []string{
+ "pending_session.dev_addr",
+ "pending_session.keys.nwk_s_enc_key.encrypted_key",
+ "pending_session.keys.nwk_s_enc_key.kek_label",
+ "pending_session.keys.nwk_s_enc_key.key",
+ "pending_session.keys.session_key_id",
+ "session.dev_addr",
+ "session.keys.nwk_s_enc_key.encrypted_key",
+ "session.keys.nwk_s_enc_key.kek_label",
+ "session.keys.nwk_s_enc_key.key",
+ "session.keys.session_key_id",
+ },
+ )
+ if err != nil {
+ return nil, nil, err
+ }
+ devAddrs, keys = make([]*types.DevAddr, len(deviceIDs)), make([]*types.AES128Key, len(deviceIDs))
+ for i, dev := range devices {
+ var devAddr types.DevAddr
+ var keyEnvelope *ttnpb.KeyEnvelope
+ switch {
+ case dev.GetPendingSession().GetKeys().GetNwkSEncKey() != nil &&
+ bytes.Equal(dev.PendingSession.Keys.SessionKeyId, sessionKeyIDs[i]):
+ copy(devAddr[:], dev.PendingSession.DevAddr)
+ keyEnvelope = dev.PendingSession.Keys.NwkSEncKey
+ case dev.GetSession().GetKeys().GetNwkSEncKey() != nil &&
+ bytes.Equal(dev.Session.Keys.SessionKeyId, sessionKeyIDs[i]):
+ copy(devAddr[:], dev.Session.DevAddr)
+ keyEnvelope = dev.Session.Keys.NwkSEncKey
+ default:
+ continue
+ }
+ key, err := cryptoutil.UnwrapAES128Key(ctx, keyEnvelope, r.keys)
+ if err != nil {
+ return nil, nil, err
+ }
+ key = crypto.DeriveRootWorSKey(key)
+ devAddrs[i], keys[i] = &devAddr, &key
+ }
+ return devAddrs, keys, nil
+}
+
+func (ns *NetworkServer) relayKeyService() mac.RelayKeyService {
+ return &relayKeyService{ns.devices, ns.KeyService()}
+}
+
+func relayUplinkToken(ids *ttnpb.EndDeviceIdentifiers, sessionKeyID []byte, fullFCnt uint32) ([]byte, error) {
+ token := &ttnpb.RelayUplinkToken{
+ Ids: ids,
+ SessionKeyId: sessionKeyID,
+ FullFCnt: fullFCnt,
+ }
+ if err := token.ValidateFields(); err != nil {
+ return nil, err
+ }
+ return proto.Marshal(token)
+}
+
+func handleRelayForwardingProtocol(
+ ctx context.Context,
+ dev *ttnpb.EndDevice,
+ fullFCnt uint32,
+ phy *band.Band,
+ up *ttnpb.UplinkMessage,
+ keyService crypto.KeyService,
+) (_ *ttnpb.UplinkMessage, queuedEvents []events.Event, err error) {
+ defer func() {
+ if err != nil {
+ queuedEvents = append(queuedEvents, evtDropRelayUplink.NewWithIdentifiersAndData(ctx, dev.Ids, err))
+ }
+ }()
+ session := dev.Session
+ nwkSEncKey := session.Keys.NwkSEncKey
+ key, err := cryptoutil.UnwrapAES128Key(ctx, nwkSEncKey, keyService)
+ if err != nil {
+ return nil, queuedEvents, err
+ }
+ rawPayload, err := crypto.DecryptUplink(
+ key, types.DevAddr(session.DevAddr), fullFCnt, up.Payload.GetMacPayload().FrmPayload,
+ )
+ if err != nil {
+ return nil, queuedEvents, err
+ }
+ req := &ttnpb.RelayForwardUplinkReq{}
+ if err := lorawan.UnmarshalRelayForwardUplinkReq(phy, rawPayload, req); err != nil {
+ return nil, queuedEvents, err
+ }
+ uplinkToken, err := relayUplinkToken(dev.Ids, session.Keys.SessionKeyId, fullFCnt)
+ if err != nil {
+ return nil, queuedEvents, err
+ }
+ mdTime, mdReceivedAt := up.ReceivedAt, up.ReceivedAt
+ var mdGPSTime *timestamppb.Timestamp
+ for _, md := range up.RxMetadata {
+ if md.GpsTime != nil {
+ mdTime, mdGPSTime, mdReceivedAt = md.Time, md.GpsTime, md.ReceivedAt
+ break
+ }
+ if mdReceivedAt == nil {
+ mdTime, mdGPSTime, mdReceivedAt = md.Time, md.GpsTime, md.ReceivedAt
+ continue
+ }
+ if md.ReceivedAt != nil && md.ReceivedAt.AsTime().Before(mdReceivedAt.AsTime()) {
+ mdTime, mdGPSTime, mdReceivedAt = md.Time, md.GpsTime, md.ReceivedAt
+ }
+ }
+ adjustTime := func(ts *timestamppb.Timestamp) *timestamppb.Timestamp {
+ if ts == nil {
+ return nil
+ }
+ t := ts.AsTime().Add(-(up.ConsumedAirtime.AsDuration() + phy.RelayForwardDelay))
+ return timestamppb.New(t)
+ }
+ up = &ttnpb.UplinkMessage{
+ RawPayload: req.RawPayload,
+ Settings: &ttnpb.TxSettings{
+ DataRate: req.DataRate,
+ Frequency: req.Frequency,
+ Time: adjustTime(up.Settings.Time),
+ },
+ RxMetadata: []*ttnpb.RxMetadata{
+ {
+ GatewayIds: relayspec.GatewayIdentifiers,
+ Relay: &ttnpb.RelayMetadata{
+ DeviceId: dev.Ids.DeviceId,
+ WorChannel: req.WorChannel,
+ },
+ Time: adjustTime(mdTime),
+ Rssi: float32(req.Rssi),
+ ChannelRssi: float32(req.Rssi),
+ Snr: float32(req.Snr),
+ UplinkToken: uplinkToken,
+ GpsTime: adjustTime(mdGPSTime),
+ ReceivedAt: adjustTime(mdReceivedAt),
+ },
+ },
+ ReceivedAt: up.ReceivedAt,
+ CorrelationIds: events.CorrelationIDsFromContext(ctx),
+ }
+ if err := up.ValidateFields(); err != nil {
+ return nil, queuedEvents, err
+ }
+ up.Payload = &ttnpb.Message{}
+ if err := lorawan.UnmarshalMessage(up.RawPayload, up.Payload); err != nil {
+ return nil, queuedEvents, err
+ }
+ if err := up.Payload.ValidateFields(); err != nil {
+ return nil, queuedEvents, err
+ }
+ queuedEvents = append(queuedEvents, evtProcessRelayUplink.NewWithIdentifiersAndData(ctx, dev.Ids, up))
+ return up, queuedEvents, nil
+}
+
+func relayLoopbackFunc(
+ conn *grpc.ClientConn,
+ up *ttnpb.UplinkMessage,
+ callOpts ...grpc.CallOption,
+) func(context.Context) error {
+ client := ttnpb.NewGsNsClient(conn)
+ return func(ctx context.Context) error {
+ switch _, err := client.HandleUplink(ctx, up, callOpts...); {
+ case err == nil, errors.IsNotFound(err), errors.IsAlreadyExists(err):
+ return nil
+ default:
+ return err
+ }
+ }
+}
+
+func relayUpdateRules(
+ deviceID string, sessionKeyID []byte, rules []*ttnpb.RelayUplinkForwardingRule,
+) bool {
+ for _, rule := range rules {
+ if rule.DeviceId != deviceID || bytes.Equal(rule.SessionKeyId, sessionKeyID) {
+ continue
+ }
+ rule.LastWFCnt = 0
+ rule.SessionKeyId = sessionKeyID
+ return true
+ }
+ return false
+}
+
+var relayDeliverSessionKeysPaths = ttnpb.AddFields(
+ deviceDownlinkFullPaths[:],
+ "mac_settings.desired_relay.mode.serving.uplink_forwarding_rules",
+ "mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules",
+ "pending_mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules",
+)
+
+func (ns *NetworkServer) deliverRelaySessionKeys(ctx context.Context, dev *ttnpb.EndDevice, sessionKeyID []byte) error {
+ for _, served := range []*ttnpb.ServedRelayParameters{
+ dev.MacSettings.GetRelay().GetServed(),
+ dev.MacSettings.GetDesiredRelay().GetServed(),
+ } {
+ if served == nil {
+ continue
+ }
+ serving, ctx, err := ns.devices.SetByID(
+ ctx,
+ dev.Ids.ApplicationIds,
+ served.ServingDeviceId,
+ relayDeliverSessionKeysPaths,
+ func(ctx context.Context, serving *ttnpb.EndDevice) (*ttnpb.EndDevice, []string, error) {
+ if serving == nil {
+ return nil, nil, nil
+ }
+ var paths []string
+ for path, rules := range map[string][]*ttnpb.RelayUplinkForwardingRule{
+ "mac_settings.desired_relay.mode.serving.uplink_forwarding_rules": serving.MacSettings.GetDesiredRelay().GetServing().GetUplinkForwardingRules(), // nolint:lll
+ "mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules": serving.MacState.GetDesiredParameters().GetRelay().GetServing().GetUplinkForwardingRules(), // nolint:lll
+ "pending_mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules": serving.PendingMacState.GetDesiredParameters().GetRelay().GetServing().GetUplinkForwardingRules(), // nolint:lll
+ } {
+ if relayUpdateRules(dev.Ids.DeviceId, sessionKeyID, rules) {
+ paths = ttnpb.AddFields(paths, path)
+ }
+ }
+ return serving, paths, nil
+ },
+ )
+ if err != nil {
+ return err
+ }
+ if err := ns.updateDataDownlinkTask(ctx, serving, time.Time{}); err != nil {
+ log.FromContext(ctx).WithError(err).Error("Failed to update downlink task queue after session key delivery")
+ }
+ }
+ return nil
+}
+
+func parseRelayUplinkToken(b []byte) (*ttnpb.RelayUplinkToken, error) {
+ token := &ttnpb.RelayUplinkToken{}
+ if err := proto.Unmarshal(b, token); err != nil {
+ return nil, err
+ }
+ if err := token.ValidateFields(); err != nil {
+ return nil, err
+ }
+ return token, nil
+}
+
+func (ns *NetworkServer) relayPatchServingDevice(
+ ctx context.Context,
+ appID *ttnpb.ApplicationIdentifiers,
+ devID string,
+ gets []string,
+ f func(context.Context, *ttnpb.EndDevice) (*ttnpb.EndDevice, []string, error),
+) error {
+ fullGets := ttnpb.AddFields(gets, deviceDownlinkFullPaths[:]...)
+ filteredF := func(ctx context.Context, dev *ttnpb.EndDevice) (*ttnpb.EndDevice, []string, error) {
+ dev, err := ttnpb.FilterGetEndDevice(dev, gets...)
+ if err != nil {
+ return nil, nil, err
+ }
+ dev, sets, err := f(ctx, dev)
+ if err != nil {
+ return nil, nil, err
+ }
+ if dev == nil {
+ panic("nil device returned")
+ }
+ return dev, sets, nil
+ }
+ dev, ctx, err := ns.devices.SetByID(ctx, appID, devID, fullGets, filteredF)
+ if err != nil {
+ return err
+ }
+ return ns.updateDataDownlinkTask(ctx, dev, time.Time{})
+}
+
+type relayDownlinkTarget struct {
+ servedEndDeviceIDs *ttnpb.EndDeviceIdentifiers
+ servedSessionKeyID []byte
+
+ patchServingDevice func(
+ ctx context.Context,
+ appID *ttnpb.ApplicationIdentifiers,
+ devID string,
+ paths []string,
+ f func(context.Context, *ttnpb.EndDevice) (*ttnpb.EndDevice, []string, error),
+ ) error
+}
+
+var _ downlinkTarget = (*relayDownlinkTarget)(nil)
+
+// Equal implements downlinkTarget.
+func (*relayDownlinkTarget) Equal(downlinkTarget) bool {
+ return false
+}
+
+// Schedule implements downlinkTarget.
+func (r *relayDownlinkTarget) Schedule(
+ ctx context.Context, down *ttnpb.DownlinkMessage, _ ...grpc.CallOption,
+) (*ttnpb.ScheduleDownlinkResponse, error) {
+ request := down.GetRequest()
+ if request == nil {
+ panic("downlink without request")
+ }
+ if len(request.DownlinkPaths) != 1 {
+ panic("invalid downlink paths length")
+ }
+ path := request.DownlinkPaths[0].GetUplinkToken()
+ if len(path) == 0 {
+ panic("invalid downlink path")
+ }
+ token, err := parseRelayUplinkToken(path)
+ if err != nil {
+ return nil, err
+ }
+ if !proto.Equal(token.Ids.ApplicationIds, r.servedEndDeviceIDs.ApplicationIds) {
+ return nil, errRelaySchedule.WithCause(errRelayInvalidUplinkToken)
+ }
+ f := func(ctx context.Context, dev *ttnpb.EndDevice) (*ttnpb.EndDevice, []string, error) {
+ session, macState := dev.GetSession(), dev.GetMacState()
+ if session == nil || macState == nil {
+ log.FromContext(ctx).Debug("Nil session or MAC state")
+ return dev, nil, errRelaySchedule.WithCause(errRelayNoSession)
+ }
+ if !bytes.Equal(session.Keys.SessionKeyId, token.SessionKeyId) {
+ log.FromContext(ctx).Debug("Invalid session key ID")
+ return dev, nil, errRelaySchedule.WithCause(errRelayNoSessionKeyID)
+ }
+ if len(macState.RecentUplinks) == 0 {
+ log.FromContext(ctx).Debug("No recent uplinks")
+ return dev, nil, errRelaySchedule.WithCause(errRelayNoRecentUplinks)
+ }
+ if !macState.RxWindowsAvailable {
+ log.FromContext(ctx).Debug("No RX windows available")
+ return dev, nil, errRelaySchedule.WithCause(errRelayRXWindowUnavailable)
+ }
+ lastPayload := internal.LastUplink(macState.RecentUplinks...).Payload
+ if mType := lastPayload.MHdr.MType; mType != ttnpb.MType_UNCONFIRMED_UP && mType != ttnpb.MType_CONFIRMED_UP {
+ log.FromContext(ctx).Debug("Invalid MType")
+ return dev, nil, errRelaySchedule.WithCause(errRelayMTYpe)
+ }
+ if lastPayload.GetMacPayload().FullFCnt != token.FullFCnt {
+ log.FromContext(ctx).Debug("Invalid full FCnt")
+ return dev, nil, errRelaySchedule.WithCause(errRelayFullFCnt)
+ }
+ if macState.CurrentParameters.Relay.GetServing() == nil {
+ log.FromContext(ctx).Debug("Not serving relay")
+ return dev, nil, errRelaySchedule.WithCause(errRelayNotServing)
+ }
+ log.FromContext(ctx).Debug("Relay downlink enqueued")
+ macState.PendingRelayDownlink = &ttnpb.RelayForwardDownlinkReq{
+ RawPayload: down.RawPayload,
+ }
+ return dev, []string{"mac_state.pending_relay_downlink.raw_payload"}, nil
+ }
+ if err := r.patchServingDevice(
+ ctx,
+ token.Ids.ApplicationIds,
+ token.Ids.DeviceId,
+ []string{
+ "mac_state.current_parameters.relay.mode.serving",
+ "mac_state.recent_uplinks",
+ "mac_state.rx_windows_available",
+ "session.keys.session_key_id",
+ },
+ f,
+ ); err != nil {
+ return nil, err
+ }
+ return &ttnpb.ScheduleDownlinkResponse{
+ Delay: durationpb.New(peeringScheduleDelay),
+ DownlinkPath: &ttnpb.DownlinkPath{
+ Path: &ttnpb.DownlinkPath_Fixed{
+ Fixed: &ttnpb.GatewayAntennaIdentifiers{
+ GatewayIds: relayspec.GatewayIdentifiers,
+ },
+ },
+ },
+ }, nil
+}
diff --git a/pkg/networkserver/relay_test.go b/pkg/networkserver/relay_test.go
new file mode 100644
index 0000000000..cda20e0769
--- /dev/null
+++ b/pkg/networkserver/relay_test.go
@@ -0,0 +1,279 @@
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package networkserver_test
+
+import (
+ "context"
+ "testing"
+
+ "github.com/smarty/assertions"
+ "go.thethings.network/lorawan-stack/v3/pkg/crypto"
+ "go.thethings.network/lorawan-stack/v3/pkg/crypto/cryptoutil"
+ "go.thethings.network/lorawan-stack/v3/pkg/networkserver"
+ "go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
+ "go.thethings.network/lorawan-stack/v3/pkg/types"
+ "go.thethings.network/lorawan-stack/v3/pkg/util/test"
+ "go.thethings.network/lorawan-stack/v3/pkg/util/test/assertions/should"
+)
+
+func TestBatchDeriveRootWorSKey(t *testing.T) {
+ t.Parallel()
+ keyVault := cryptoutil.NewMemKeyVault(nil)
+ keyService := crypto.NewKeyService(keyVault)
+ filterFields := func(
+ t *testing.T, a *assertions.Assertion, devices []*ttnpb.EndDevice, paths []string,
+ ) []*ttnpb.EndDevice {
+ t.Helper()
+ devices = append(devices[:0:0], devices...)
+ for i, dev := range devices {
+ var err error
+ devices[i], err = ttnpb.FilterGetEndDevice(dev, paths...)
+ if !a.So(err, should.BeNil) {
+ t.FailNow()
+ }
+ }
+ return devices
+ }
+ for _, tc := range []struct {
+ Name string
+
+ ApplicationIDs *ttnpb.ApplicationIdentifiers
+ DeviceIDs []string
+ SessionKeyIDs [][]byte
+
+ DevAddrs []*types.DevAddr
+ Keys []*types.AES128Key
+
+ BatchGetByIDFunc func(
+ ctx context.Context,
+ t *testing.T,
+ a *assertions.Assertion,
+ appIDs *ttnpb.ApplicationIdentifiers,
+ devIDs []string,
+ paths []string,
+ ) ([]*ttnpb.EndDevice, error)
+ }{
+ {
+ Name: "no devices",
+
+ ApplicationIDs: test.DefaultApplicationIdentifiers,
+
+ BatchGetByIDFunc: func(
+ ctx context.Context,
+ t *testing.T,
+ a *assertions.Assertion,
+ appIDs *ttnpb.ApplicationIdentifiers,
+ devIDs []string,
+ paths []string,
+ ) ([]*ttnpb.EndDevice, error) {
+ t.Helper()
+ t.Fatal("BatchGetByID must not be called")
+ return nil, nil
+ },
+ },
+ {
+ Name: "no sessions",
+
+ ApplicationIDs: test.DefaultApplicationIdentifiers,
+ DeviceIDs: []string{"device1", "device2"},
+ SessionKeyIDs: [][]byte{{0x01}, {0x02}},
+
+ DevAddrs: []*types.DevAddr{nil, nil},
+ Keys: []*types.AES128Key{nil, nil},
+
+ BatchGetByIDFunc: func(
+ ctx context.Context,
+ t *testing.T,
+ a *assertions.Assertion,
+ appIDs *ttnpb.ApplicationIdentifiers,
+ devIDs []string,
+ paths []string,
+ ) ([]*ttnpb.EndDevice, error) {
+ t.Helper()
+ a.So(appIDs, should.Resemble, test.DefaultApplicationIdentifiers)
+ a.So(devIDs, should.Resemble, []string{"device1", "device2"})
+ return filterFields(t, a, []*ttnpb.EndDevice{
+ {
+ Ids: &ttnpb.EndDeviceIdentifiers{
+ ApplicationIds: test.DefaultApplicationIdentifiers,
+ DeviceId: "device1",
+ },
+ },
+ {
+ Ids: &ttnpb.EndDeviceIdentifiers{
+ ApplicationIds: test.DefaultApplicationIdentifiers,
+ DeviceId: "device2",
+ },
+ },
+ }, paths), nil
+ },
+ },
+ {
+ Name: "only sessions",
+
+ ApplicationIDs: test.DefaultApplicationIdentifiers,
+ DeviceIDs: []string{"device1", "device2"},
+ SessionKeyIDs: [][]byte{{0x01}, {0x02}},
+
+ DevAddrs: []*types.DevAddr{{0x42, 0x42, 0x42, 0x42}, {0x43, 0x43, 0x43, 0x43}},
+ Keys: []*types.AES128Key{
+ {0xEE, 0x91, 0xDC, 0x1A, 0x66, 0x66, 0xC0, 0x6E, 0x82, 0x77, 0xDE, 0x6D, 0xB4, 0xDB, 0x94, 0x5F},
+ {0xC2, 0x7E, 0x77, 0x4E, 0x20, 0x73, 0x18, 0x96, 0xFE, 0x20, 0x5D, 0x77, 0x1D, 0x7B, 0xC1, 0xF1},
+ },
+
+ BatchGetByIDFunc: func(
+ ctx context.Context,
+ t *testing.T,
+ a *assertions.Assertion,
+ appIDs *ttnpb.ApplicationIdentifiers,
+ devIDs []string,
+ paths []string,
+ ) ([]*ttnpb.EndDevice, error) {
+ t.Helper()
+ a.So(appIDs, should.Resemble, test.DefaultApplicationIdentifiers)
+ a.So(devIDs, should.Resemble, []string{"device1", "device2"})
+ return filterFields(t, a, []*ttnpb.EndDevice{
+ {
+ Ids: &ttnpb.EndDeviceIdentifiers{
+ ApplicationIds: test.DefaultApplicationIdentifiers,
+ DeviceId: "device1",
+ },
+ Session: &ttnpb.Session{
+ DevAddr: types.DevAddr{0x42, 0x42, 0x42, 0x42}.Bytes(),
+ Keys: &ttnpb.SessionKeys{
+ SessionKeyId: []byte{0x01},
+ NwkSEncKey: &ttnpb.KeyEnvelope{
+ Key: []byte{0xCE, 0x07, 0xA0, 0x09, 0xA3, 0x97, 0x0A, 0xC0, 0x51, 0x9A, 0x09, 0x9E, 0xD5, 0x3E, 0x55, 0x0B}, // nolint:lll
+ },
+ },
+ },
+ },
+ {
+ Ids: &ttnpb.EndDeviceIdentifiers{
+ ApplicationIds: test.DefaultApplicationIdentifiers,
+ DeviceId: "device2",
+ },
+ Session: &ttnpb.Session{
+ DevAddr: types.DevAddr{0x43, 0x43, 0x43, 0x43}.Bytes(),
+ Keys: &ttnpb.SessionKeys{
+ SessionKeyId: []byte{0x02},
+ NwkSEncKey: &ttnpb.KeyEnvelope{
+ Key: []byte{0xCE, 0x07, 0xA0, 0x09, 0xA3, 0x97, 0x0A, 0xC0, 0x51, 0x9A, 0x09, 0x9E, 0xD5, 0x3E, 0x55, 0x0C}, // nolint:lll
+ },
+ },
+ },
+ },
+ }, paths), nil
+ },
+ },
+ {
+ Name: "with pending sessions",
+
+ ApplicationIDs: test.DefaultApplicationIdentifiers,
+ DeviceIDs: []string{"device1", "device2"},
+ SessionKeyIDs: [][]byte{{0x03}, {0x02}},
+
+ DevAddrs: []*types.DevAddr{{0x44, 0x44, 0x44, 0x44}, {0x43, 0x43, 0x43, 0x43}},
+ Keys: []*types.AES128Key{
+ {0x67, 0x11, 0x92, 0xD5, 0x9C, 0x0D, 0x35, 0x7D, 0xEF, 0xE2, 0xA9, 0x45, 0x21, 0xC4, 0x22, 0x7C},
+ {0xC2, 0x7E, 0x77, 0x4E, 0x20, 0x73, 0x18, 0x96, 0xFE, 0x20, 0x5D, 0x77, 0x1D, 0x7B, 0xC1, 0xF1},
+ },
+
+ BatchGetByIDFunc: func(
+ ctx context.Context,
+ t *testing.T,
+ a *assertions.Assertion,
+ appIDs *ttnpb.ApplicationIdentifiers,
+ devIDs []string,
+ paths []string,
+ ) ([]*ttnpb.EndDevice, error) {
+ t.Helper()
+ a.So(appIDs, should.Resemble, test.DefaultApplicationIdentifiers)
+ a.So(devIDs, should.Resemble, []string{"device1", "device2"})
+ return filterFields(t, a, []*ttnpb.EndDevice{
+ {
+ Ids: &ttnpb.EndDeviceIdentifiers{
+ ApplicationIds: test.DefaultApplicationIdentifiers,
+ DeviceId: "device1",
+ },
+ Session: &ttnpb.Session{
+ DevAddr: types.DevAddr{0x42, 0x42, 0x42, 0x42}.Bytes(),
+ Keys: &ttnpb.SessionKeys{
+ SessionKeyId: []byte{0x01},
+ NwkSEncKey: &ttnpb.KeyEnvelope{
+ Key: []byte{0xCE, 0x07, 0xA0, 0x09, 0xA3, 0x97, 0x0A, 0xC0, 0x51, 0x9A, 0x09, 0x9E, 0xD5, 0x3E, 0x55, 0x0B}, // nolint:lll
+ },
+ },
+ },
+ PendingSession: &ttnpb.Session{
+ DevAddr: types.DevAddr{0x44, 0x44, 0x44, 0x44}.Bytes(),
+ Keys: &ttnpb.SessionKeys{
+ SessionKeyId: []byte{0x03},
+ NwkSEncKey: &ttnpb.KeyEnvelope{
+ Key: []byte{0xCE, 0x07, 0xA0, 0x09, 0xA3, 0x97, 0x0A, 0xC0, 0x51, 0x9A, 0x09, 0x9E, 0xD5, 0x3E, 0x55, 0x0D}, // nolint:lll
+ },
+ },
+ },
+ },
+ {
+ Ids: &ttnpb.EndDeviceIdentifiers{
+ ApplicationIds: test.DefaultApplicationIdentifiers,
+ DeviceId: "device2",
+ },
+ Session: &ttnpb.Session{
+ DevAddr: types.DevAddr{0x43, 0x43, 0x43, 0x43}.Bytes(),
+ Keys: &ttnpb.SessionKeys{
+ SessionKeyId: []byte{0x02},
+ NwkSEncKey: &ttnpb.KeyEnvelope{
+ Key: []byte{0xCE, 0x07, 0xA0, 0x09, 0xA3, 0x97, 0x0A, 0xC0, 0x51, 0x9A, 0x09, 0x9E, 0xD5, 0x3E, 0x55, 0x0C}, // nolint:lll
+ },
+ },
+ },
+ },
+ }, paths), nil
+ },
+ },
+ } {
+ tc := tc
+ test.RunSubtest(t, test.SubtestConfig{
+ Name: tc.Name,
+ Parallel: true,
+ Func: func(ctx context.Context, t *testing.T, a *assertions.Assertion) {
+ t.Helper()
+ relayKeyService := networkserver.NewRelayKeyService(
+ &networkserver.MockDeviceRegistry{
+ BatchGetByIDFunc: func(
+ ctx context.Context,
+ appIDs *ttnpb.ApplicationIdentifiers,
+ devIDs []string,
+ paths []string,
+ ) ([]*ttnpb.EndDevice, error) {
+ t.Helper()
+ return tc.BatchGetByIDFunc(ctx, t, a, appIDs, devIDs, paths)
+ },
+ },
+ keyService,
+ )
+ devAddrs, keys, err := relayKeyService.BatchDeriveRootWorSKey(
+ ctx, tc.ApplicationIDs, tc.DeviceIDs, tc.SessionKeyIDs,
+ )
+ if a.So(err, should.BeNil) {
+ a.So(devAddrs, should.Resemble, tc.DevAddrs)
+ a.So(keys, should.Resemble, tc.Keys)
+ }
+ },
+ })
+ }
+}
diff --git a/pkg/networkserver/relay_util_test.go b/pkg/networkserver/relay_util_test.go
new file mode 100644
index 0000000000..4343c6fb92
--- /dev/null
+++ b/pkg/networkserver/relay_util_test.go
@@ -0,0 +1,28 @@
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package networkserver
+
+import (
+ "go.thethings.network/lorawan-stack/v3/pkg/crypto"
+ "go.thethings.network/lorawan-stack/v3/pkg/networkserver/mac"
+)
+
+// NewRelayKeyService returns a new mac.RelayKeyService.
+func NewRelayKeyService(devices DeviceRegistry, keys crypto.KeyService) mac.RelayKeyService {
+ return &relayKeyService{
+ devices: devices,
+ keys: keys,
+ }
+}
diff --git a/pkg/networkserver/utils.go b/pkg/networkserver/utils.go
index 9259e56994..43b00ca0ff 100644
--- a/pkg/networkserver/utils.go
+++ b/pkg/networkserver/utils.go
@@ -19,6 +19,7 @@ import (
"fmt"
"go.thethings.network/lorawan-stack/v3/pkg/band"
+ "go.thethings.network/lorawan-stack/v3/pkg/errors"
"go.thethings.network/lorawan-stack/v3/pkg/events"
"go.thethings.network/lorawan-stack/v3/pkg/log"
. "go.thethings.network/lorawan-stack/v3/pkg/networkserver/internal"
@@ -255,6 +256,9 @@ func nextDataDownlinkSlot(ctx context.Context, dev *ttnpb.EndDevice, phy *band.B
case mac.ContainsStickyMACCommand(dev.MacState.RecentMacCommandIdentifiers...):
logger.Debug("Sticky MAC response received, choose class A downlink slot")
return classA, true
+ case dev.MacState.PendingRelayDownlink != nil:
+ logger.Debug("Pending relay downlink, choose class A downlink slot")
+ return classA, true
case mac.DeviceNeedsADRParamSetupReq(dev, phy):
logger.Debug("Device needs ADRParamSetupReq, choose class A downlink slot")
return classA, true
@@ -294,6 +298,21 @@ func nextDataDownlinkSlot(ctx context.Context, dev *ttnpb.EndDevice, phy *band.B
case mac.DeviceNeedsTxParamSetupReq(dev, phy):
logger.Debug("Device needs TxParamSetupReq, choose class A downlink slot")
return classA, true
+ case mac.DeviceNeedsRelayConfReq(dev):
+ logger.Debug("Device needs RelayConfReq, choose class A downlink slot")
+ return classA, true
+ case mac.DeviceNeedsRelayEndDeviceConfReq(dev):
+ logger.Debug("Device needs RelayEndDeviceConfReq, choose class A downlink slot")
+ return classA, true
+ case mac.DeviceNeedsRelayUpdateUplinkListReq(dev):
+ logger.Debug("Device needs RelayUpdateUplinkListReq, choose class A downlink slot")
+ return classA, true
+ case mac.DeviceNeedsRelayCtrlUplinkListReq(dev):
+ logger.Debug("Device needs RelayCtrlUplinkListReq, choose class A downlink slot")
+ return classA, true
+ case mac.DeviceNeedsRelayConfigureFwdLimitReq(dev):
+ logger.Debug("Device needs RelayConfigureFwdLimitReq, choose class A downlink slot")
+ return classA, true
}
}
@@ -425,8 +444,10 @@ func (ns *NetworkServer) handleUplinkSubmission(ctx context.Context, ups []*ttnp
}
if err := ns.sendApplicationUplinks(ctx, ttnpb.NewNsAsClient(conn), ups...); err != nil {
log.FromContext(ctx).WithError(err).Warn("Failed to send application uplinks to Application Server")
+ if !retryableUplinkError(err) {
+ return
+ }
ns.enqueueApplicationUplinks(ctx, ups...)
- return
}
}
@@ -462,3 +483,11 @@ var (
"session",
}
)
+
+func retryableUplinkError(err error) bool {
+ return errors.IsCanceled(err) ||
+ errors.IsDeadlineExceeded(err) ||
+ errors.IsResourceExhausted(err) ||
+ errors.IsAborted(err) ||
+ errors.IsUnavailable(err)
+}
diff --git a/pkg/packetbrokeragent/agent.go b/pkg/packetbrokeragent/agent.go
index 41884e1d07..9bdf29bedc 100644
--- a/pkg/packetbrokeragent/agent.go
+++ b/pkg/packetbrokeragent/agent.go
@@ -74,7 +74,7 @@ type RegistrationInfo struct {
Listed bool
}
-// PacketBrokerClusterBuilder builds a Packet Broker Cluster ID from a The Things Stack Cluster ID.
+// PacketBrokerClusterIDBuilder builds a Packet Broker Cluster ID from a The Things Stack Cluster ID.
type PacketBrokerClusterIDBuilder func(clusterID string) (string, error)
func literalClusterID(clusterID string) (string, error) {
@@ -177,7 +177,7 @@ func New(c *component.Component, conf *Config, opts ...Option) (*Agent, error) {
}
devAddrPrefix := types.DevAddrPrefix{
DevAddr: devAddr,
- Length: uint8(conf.NetID.IDBits()),
+ Length: uint8(32 - types.NwkAddrBits(conf.NetID)),
}
devAddrPrefixes = append(devAddrPrefixes, devAddrPrefix)
}
@@ -675,7 +675,8 @@ func (a *Agent) handleDownlinkMessage(
}
}
- uid, msg, err := fromPBDownlink(ctx, down.Message, receivedAt, a.forwarderConfig)
+ forwarderData := forwarderAdditionalData(down.ForwarderNetId, down.ForwarderTenantId, down.ForwarderClusterId)
+ uid, msg, err := fromPBDownlink(ctx, down.Message, forwarderData, receivedAt, a.forwarderConfig)
if err != nil {
logger.WithError(err).Warn("Failed to convert incoming downlink message")
return err
@@ -944,7 +945,7 @@ func (a *Agent) handleUplink(
if up.Message == nil {
return
}
- ctx = appendDownlinkCorrelationID(ctx, up.Id)
+ ctx = appendUplinkCorrelationID(ctx, up.Id)
var forwarderNetID types.NetID
forwarderNetID.UnmarshalNumber(up.ForwarderNetId)
ctx = log.NewContextWithFields(ctx, log.Fields(
diff --git a/pkg/packetbrokeragent/agent_test.go b/pkg/packetbrokeragent/agent_test.go
index a7c1bbbded..157b437652 100644
--- a/pkg/packetbrokeragent/agent_test.go
+++ b/pkg/packetbrokeragent/agent_test.go
@@ -428,8 +428,9 @@ func TestForwarder(t *testing.T) {
}))
tokenNonce := make([]byte, aead.NonceSize())
test.Must(io.ReadFull(rand.Reader, tokenNonce))
+ forwarderData := []byte("000013:foo-tenant:test")
token := test.Must(proto.Marshal(&ttnpb.PacketBrokerAgentEncryptedPayload{
- Ciphertext: aead.Seal(nil, tokenNonce, plainToken, nil),
+ Ciphertext: aead.Seal(nil, tokenNonce, plainToken, forwarderData),
Nonce: tokenNonce,
}))
diff --git a/pkg/webui/lib/components/scroll-to-top.js b/pkg/packetbrokeragent/crypto.go
similarity index 67%
rename from pkg/webui/lib/components/scroll-to-top.js
rename to pkg/packetbrokeragent/crypto.go
index fa731830d0..7effaeca2b 100644
--- a/pkg/webui/lib/components/scroll-to-top.js
+++ b/pkg/packetbrokeragent/crypto.go
@@ -1,4 +1,4 @@
-// Copyright © 2020 The Things Network Foundation, The Things Industries B.V.
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,15 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import { useEffect } from 'react'
-import { useLocation } from 'react-router-dom'
+package packetbrokeragent
-export default () => {
- const { pathname } = useLocation()
+import "fmt"
- useEffect(() => {
- window.scrollTo(0, 0)
- }, [pathname])
-
- return null
+func forwarderAdditionalData(netID uint32, tenantID string, clusterID string) []byte {
+ return []byte(fmt.Sprintf("%06x:%s:%s", netID, tenantID, clusterID))
}
diff --git a/pkg/packetbrokeragent/grpc_gspba.go b/pkg/packetbrokeragent/grpc_gspba.go
index 468b187817..502adfc028 100644
--- a/pkg/packetbrokeragent/grpc_gspba.go
+++ b/pkg/packetbrokeragent/grpc_gspba.go
@@ -75,7 +75,8 @@ func (s *gsPbaServer) PublishUplink(ctx context.Context, up *ttnpb.GatewayUplink
ctx = appendUplinkCorrelationID(ctx)
up.Message.CorrelationIds = events.CorrelationIDsFromContext(ctx)
- msg, err := toPBUplink(ctx, up, s.config)
+ forwarderData := forwarderAdditionalData(s.netID.MarshalNumber(), s.tenantIDExtractor(ctx), s.clusterID)
+ msg, err := toPBUplink(ctx, up, forwarderData, s.config)
if err != nil {
log.FromContext(ctx).WithError(err).Warn("Failed to convert outgoing uplink message")
return nil, err
diff --git a/pkg/packetbrokeragent/grpc_pba.go b/pkg/packetbrokeragent/grpc_pba.go
index b706390c1f..6875cfdaf3 100644
--- a/pkg/packetbrokeragent/grpc_pba.go
+++ b/pkg/packetbrokeragent/grpc_pba.go
@@ -556,6 +556,8 @@ func (s *pbaServer) ListNetworks(ctx context.Context, req *ttnpb.ListPacketBroke
return res.GetNetworks(), res.GetTotal(), err
}
res, err := iampbv2.NewCatalogClient(s.iamConn).ListNetworks(ctx, &iampbv2.ListNetworksRequest{
+ NetId: s.netID.MarshalNumber(),
+ TenantId: s.tenantIDExtractor(ctx),
Offset: (page - 1) * req.Limit,
Limit: req.Limit,
TenantIdContains: req.TenantIdContains,
@@ -576,6 +578,8 @@ func (s *pbaServer) ListHomeNetworks(ctx context.Context, req *ttnpb.ListPacketB
}
return s.listNetworks(ctx, func() ([]*packetbroker.NetworkOrTenant, uint32, error) {
res, err := iampbv2.NewCatalogClient(s.iamConn).ListHomeNetworks(ctx, &iampbv2.ListNetworksRequest{
+ NetId: s.netID.MarshalNumber(),
+ TenantId: s.tenantIDExtractor(ctx),
Offset: (page - 1) * req.Limit,
Limit: req.Limit,
TenantIdContains: req.TenantIdContains,
diff --git a/pkg/packetbrokeragent/translation.go b/pkg/packetbrokeragent/translation.go
index 085f821a37..832dc6149f 100644
--- a/pkg/packetbrokeragent/translation.go
+++ b/pkg/packetbrokeragent/translation.go
@@ -180,27 +180,27 @@ func unwrapUplinkTokens(
return t.Gateway, t.Forwarder, t.Agent, nil
}
-func encryptPlaintext(plaintext []byte, aead cipher.AEAD) ([]byte, error) {
+func encryptPlaintext(plaintext, additionalData []byte, aead cipher.AEAD) ([]byte, error) {
nonce := make([]byte, aead.NonceSize())
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
return nil, err
}
return proto.Marshal(&ttnpb.PacketBrokerAgentEncryptedPayload{
- Ciphertext: aead.Seal(nil, nonce, plaintext, nil),
+ Ciphertext: aead.Seal(nil, nonce, plaintext, additionalData),
Nonce: nonce,
})
}
-func decryptCiphertext(payload []byte, aead cipher.AEAD) ([]byte, error) {
+func decryptCiphertext(payload, additionalData []byte, aead cipher.AEAD) ([]byte, error) {
var encrypted ttnpb.PacketBrokerAgentEncryptedPayload
if err := proto.Unmarshal(payload, &encrypted); err != nil {
return nil, err
}
- return aead.Open(nil, encrypted.Nonce, encrypted.Ciphertext, nil)
+ return aead.Open(nil, encrypted.Nonce, encrypted.Ciphertext, additionalData)
}
func wrapGatewayUplinkToken(
- ctx context.Context, ids *ttnpb.GatewayIdentifiers, ulToken []byte, aead cipher.AEAD,
+ ctx context.Context, ids *ttnpb.GatewayIdentifiers, ulToken, forwarderData []byte, aead cipher.AEAD,
) ([]byte, error) {
plaintext, err := proto.Marshal(&ttnpb.PacketBrokerAgentGatewayUplinkToken{
GatewayUid: unique.ID(ctx, ids),
@@ -209,11 +209,11 @@ func wrapGatewayUplinkToken(
if err != nil {
return nil, err
}
- return encryptPlaintext(plaintext, aead)
+ return encryptPlaintext(plaintext, forwarderData, aead)
}
-func unwrapGatewayUplinkToken(token []byte, aead cipher.AEAD) (string, []byte, error) {
- plaintext, err := decryptCiphertext(token, aead)
+func unwrapGatewayUplinkToken(token, forwarderData []byte, aead cipher.AEAD) (string, []byte, error) {
+ plaintext, err := decryptCiphertext(token, forwarderData, aead)
if err != nil {
return "", nil, err
}
@@ -266,7 +266,9 @@ var (
errWrapGatewayUplinkToken = errors.DefineAborted("wrap_gateway_uplink_token", "wrap gateway uplink token")
)
-func toPBUplink(ctx context.Context, msg *ttnpb.GatewayUplinkMessage, config ForwarderConfig) (*packetbroker.UplinkMessage, error) {
+func toPBUplink(
+ ctx context.Context, msg *ttnpb.GatewayUplinkMessage, forwarderData []byte, config ForwarderConfig,
+) (*packetbroker.UplinkMessage, error) {
msg.Message.Payload = &ttnpb.Message{}
if err := lorawan.UnmarshalMessage(msg.Message.RawPayload, msg.Message.Payload); err != nil {
return nil, errDecodePayload.WithCause(err)
@@ -400,7 +402,9 @@ func toPBUplink(ctx context.Context, msg *ttnpb.GatewayUplinkMessage, config For
if len(gatewayUplinkToken) == 0 {
var err error
- gatewayUplinkToken, err = wrapGatewayUplinkToken(ctx, md.GatewayIds, md.UplinkToken, config.TokenAEAD)
+ gatewayUplinkToken, err = wrapGatewayUplinkToken(
+ ctx, md.GatewayIds, md.UplinkToken, forwarderData, config.TokenAEAD,
+ )
if err != nil {
return nil, errWrapGatewayUplinkToken.WithCause(err)
}
@@ -684,8 +688,14 @@ var (
errInvalidRx1Delay = errors.DefineInvalidArgument("invalid_rx1_delay", "invalid Rx1 delay")
)
-func fromPBDownlink(ctx context.Context, msg *packetbroker.DownlinkMessage, receivedAt time.Time, conf ForwarderConfig) (uid string, res *ttnpb.DownlinkMessage, err error) {
- uid, token, err := unwrapGatewayUplinkToken(msg.GatewayUplinkToken, conf.TokenAEAD)
+func fromPBDownlink(
+ ctx context.Context,
+ msg *packetbroker.DownlinkMessage,
+ forwarderData []byte,
+ receivedAt time.Time,
+ conf ForwarderConfig,
+) (uid string, res *ttnpb.DownlinkMessage, err error) {
+ uid, token, err := unwrapGatewayUplinkToken(msg.GatewayUplinkToken, forwarderData, conf.TokenAEAD)
if err != nil {
return "", nil, errUnwrapGatewayUplinkToken.WithCause(err)
}
diff --git a/pkg/packetbrokeragent/translation_internal_test.go b/pkg/packetbrokeragent/translation_internal_test.go
index 248ff9dc66..90abb6fccb 100644
--- a/pkg/packetbrokeragent/translation_internal_test.go
+++ b/pkg/packetbrokeragent/translation_internal_test.go
@@ -34,6 +34,7 @@ func WrapUplinkTokens(gateway, forwarder []byte, agent *ttnpb.PacketBrokerAgentU
func TestWrapGatewayUplinkToken(t *testing.T) {
a, ctx := test.New(t)
key := bytes.Repeat([]byte{0x42}, 16)
+ forwarderData := []byte("000013:tnt:eu1")
blockCipher, err := aes.NewCipher(key)
if !a.So(err, should.BeNil) {
t.FailNow()
@@ -43,15 +44,19 @@ func TestWrapGatewayUplinkToken(t *testing.T) {
t.FailNow()
}
- wrappedToken, err := wrapGatewayUplinkToken(ctx, &ttnpb.GatewayIdentifiers{GatewayId: "test-gateway"},
- []byte{0x1, 0x2, 0x3}, aead,
+ wrappedToken, err := wrapGatewayUplinkToken(
+ ctx,
+ &ttnpb.GatewayIdentifiers{GatewayId: "test-gateway"},
+ []byte{0x1, 0x2, 0x3},
+ forwarderData,
+ aead,
)
if !a.So(err, should.BeNil) {
t.FailNow()
}
t.Logf("Wrapped token: %q", base64.RawStdEncoding.EncodeToString(wrappedToken))
- uid, gtwToken, err := unwrapGatewayUplinkToken(wrappedToken, aead)
+ uid, gtwToken, err := unwrapGatewayUplinkToken(wrappedToken, forwarderData, aead)
if !a.So(err, should.BeNil) {
t.FailNow()
}
diff --git a/pkg/pfconfig/lbslns/lbslbs_test.go b/pkg/pfconfig/lbslns/lbslbs_test.go
index 0ee90625ae..c14459e506 100644
--- a/pkg/pfconfig/lbslns/lbslbs_test.go
+++ b/pkg/pfconfig/lbslns/lbslbs_test.go
@@ -271,7 +271,7 @@ func TestGetRouterConfig(t *testing.T) {
t.Parallel()
a, ctx := test.New(t)
- fps := map[string]*frequencyplans.FrequencyPlan{tc.FrequencyPlanID: &tc.FrequencyPlan}
+ fps := []*frequencyplans.FrequencyPlan{&tc.FrequencyPlan}
cfg, err := GetRouterConfig(ctx, tc.FrequencyPlan.BandID, fps, tc.Features, time.Now(), 0)
if err != nil {
if tc.ErrorAssertion == nil || !a.So(tc.ErrorAssertion(err), should.BeTrue) {
@@ -295,7 +295,7 @@ func TestGetRouterConfigWithMultipleFP(t *testing.T) {
for _, tc := range []struct {
Name string
BandID string
- FrequencyPlans map[string]*frequencyplans.FrequencyPlan
+ FrequencyPlans []*frequencyplans.FrequencyPlan
Cfg RouterConfig
Features TestFeatures
ErrorAssertion func(err error) bool
@@ -303,8 +303,8 @@ func TestGetRouterConfigWithMultipleFP(t *testing.T) {
{
Name: "ValidFrequencyPlan",
BandID: "US_902_928",
- FrequencyPlans: map[string]*frequencyplans.FrequencyPlan{
- test.USFrequencyPlanID: {
+ FrequencyPlans: []*frequencyplans.FrequencyPlan{
+ {
BandID: "US_902_928",
Radios: []frequencyplans.Radio{
{
@@ -322,7 +322,8 @@ func TestGetRouterConfigWithMultipleFP(t *testing.T) {
Frequency: 925000000,
},
},
- }, "US_902_928_Custom": {
+ },
+ {
BandID: "US_902_928",
Radios: []frequencyplans.Radio{
{
diff --git a/pkg/pfconfig/lbslns/lbslns.go b/pkg/pfconfig/lbslns/lbslns.go
index 635072cf55..3ba01ace03 100644
--- a/pkg/pfconfig/lbslns/lbslns.go
+++ b/pkg/pfconfig/lbslns/lbslns.go
@@ -274,7 +274,7 @@ type RouterFeatures interface {
func GetRouterConfig(
ctx context.Context,
bandID string,
- fps map[string]*frequencyplans.FrequencyPlan,
+ fps []*frequencyplans.FrequencyPlan,
features RouterFeatures,
dlTime time.Time,
antennaGain int,
@@ -386,7 +386,7 @@ func getDataRatesFromBandID(id string) (DataRates, error) {
}
// getMinMaxFrequencies extract the minimum and maximum frequencies between all the bands.
-func getMinMaxFrequencies(fps map[string]*frequencyplans.FrequencyPlan) (min uint64, max uint64, err error) {
+func getMinMaxFrequencies(fps []*frequencyplans.FrequencyPlan) (min uint64, max uint64, err error) {
min = math.MaxUint64
for _, fp := range fps {
if len(fp.Radios) == 0 {
diff --git a/pkg/pfconfig/semtechudp/semtechudp.go b/pkg/pfconfig/semtechudp/semtechudp.go
index ee5fde2ec9..6e38096af9 100644
--- a/pkg/pfconfig/semtechudp/semtechudp.go
+++ b/pkg/pfconfig/semtechudp/semtechudp.go
@@ -16,6 +16,8 @@
package semtechudp
import (
+ "encoding/json"
+
"go.thethings.network/lorawan-stack/v3/pkg/frequencyplans"
"go.thethings.network/lorawan-stack/v3/pkg/pfconfig/shared"
"go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
@@ -24,8 +26,39 @@ import (
// Config represents the full configuration for Semtech's UDP Packet Forwarder.
type Config struct {
- SX1301Conf shared.SX1301Config `json:"SX1301_conf"`
- GatewayConf GatewayConf `json:"gateway_conf"`
+ SX1301Conf []*shared.SX1301Config `json:"SX1301_conf"`
+ GatewayConf GatewayConf `json:"gateway_conf"`
+}
+
+// SingleSX1301Config is a helper type for marshaling a config with a single SX1301Config.
+type singleSX1301Config struct {
+ SX1301Conf *shared.SX1301Config `json:"SX1301_conf"`
+ GatewayConf GatewayConf `json:"gateway_conf"`
+}
+
+// MarshalJSON implements json.Marshaler.
+// Serializes the SX1301Conf field as an object if it contains a single element and as an array otherwise.
+func (c Config) MarshalJSON() ([]byte, error) {
+ if len(c.SX1301Conf) == 1 {
+ return json.Marshal(singleSX1301Config{
+ SX1301Conf: c.SX1301Conf[0],
+ GatewayConf: c.GatewayConf,
+ })
+ }
+ type alias Config
+ return json.Marshal(alias(c))
+}
+
+// UnmarshalJSON implements json.Unmarshaler.
+func (c *Config) UnmarshalJSON(data []byte) error {
+ var single singleSX1301Config
+ if err := json.Unmarshal(data, &single); err == nil {
+ c.SX1301Conf = []*shared.SX1301Config{single.SX1301Conf}
+ c.GatewayConf = single.GatewayConf
+ return nil
+ }
+ type alias Config
+ return json.Unmarshal(data, (*alias)(c))
}
// GatewayConf contains the configuration for the gateway's server connection.
@@ -50,22 +83,26 @@ func Build(gateway *ttnpb.Gateway, store *frequencyplans.Store) (*Config, error)
if gateway.GetIds().GetEui() != nil {
c.GatewayConf.GatewayID = types.MustEUI64(gateway.GetIds().GetEui()).String()
}
- c.GatewayConf.ServerAddress, c.GatewayConf.ServerPortUp, c.GatewayConf.ServerPortDown = host, uint32(port), uint32(port)
+ c.GatewayConf.ServerAddress = host
+ c.GatewayConf.ServerPortUp = uint32(port)
+ c.GatewayConf.ServerPortDown = uint32(port)
server := c.GatewayConf
server.Enabled = true
c.GatewayConf.Servers = append(c.GatewayConf.Servers, server)
- frequencyPlan, err := store.GetByID(gateway.FrequencyPlanId)
- if err != nil {
- return nil, err
- }
- if len(frequencyPlan.Radios) != 0 {
- sx1301Config, err := shared.BuildSX1301Config(frequencyPlan)
+ c.SX1301Conf = make([]*shared.SX1301Config, 0, len(gateway.FrequencyPlanIds))
+ for _, frequencyPlanID := range gateway.FrequencyPlanIds {
+ frequencyPlan, err := store.GetByID(frequencyPlanID)
if err != nil {
return nil, err
}
- c.SX1301Conf = *sx1301Config
+ if len(frequencyPlan.Radios) != 0 {
+ sx1301Config, err := shared.BuildSX1301Config(frequencyPlan)
+ if err != nil {
+ return nil, err
+ }
+ c.SX1301Conf = append(c.SX1301Conf, sx1301Config)
+ }
}
-
return &c, nil
}
diff --git a/pkg/pfconfig/semtechudp/semtechudp_test.go b/pkg/pfconfig/semtechudp/semtechudp_test.go
new file mode 100644
index 0000000000..97ce438f9c
--- /dev/null
+++ b/pkg/pfconfig/semtechudp/semtechudp_test.go
@@ -0,0 +1,166 @@
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package semtechudp_test
+
+import (
+ "encoding/json"
+ "testing"
+
+ "github.com/smarty/assertions"
+ "go.thethings.network/lorawan-stack/v3/pkg/pfconfig/semtechudp"
+ "go.thethings.network/lorawan-stack/v3/pkg/pfconfig/shared"
+ "go.thethings.network/lorawan-stack/v3/pkg/util/test/assertions/should"
+)
+
+func getSX1301Conf(t *testing.T) *shared.SX1301Config {
+ t.Helper()
+
+ return &shared.SX1301Config{
+ LoRaWANPublic: true,
+ ClockSource: 1,
+ AntennaGain: 0,
+ Radios: []shared.RFConfig{
+ {
+ Enable: true,
+ Type: "SX1257",
+ Frequency: 867500000,
+ TxEnable: true,
+ TxFreqMin: 863000000,
+ TxFreqMax: 870000000,
+ RSSIOffset: -166,
+ },
+ {
+ Enable: true, Type: "SX1257",
+ Frequency: 868500000,
+ TxEnable: false,
+ TxFreqMin: 0,
+ TxFreqMax: 0,
+ RSSIOffset: -166,
+ },
+ },
+ Channels: []shared.IFConfig{
+ {Enable: true, Radio: 1, IFValue: -400000, Bandwidth: 0, SpreadFactor: 0, Datarate: 0},
+ {Enable: true, Radio: 1, IFValue: -200000, Bandwidth: 0, SpreadFactor: 0, Datarate: 0},
+ {Enable: true, Radio: 1, IFValue: 0, Bandwidth: 0, SpreadFactor: 0, Datarate: 0},
+ {Enable: true, Radio: 0, IFValue: -400000, Bandwidth: 0, SpreadFactor: 0, Datarate: 0},
+ {Enable: true, Radio: 0, IFValue: -200000, Bandwidth: 0, SpreadFactor: 0, Datarate: 0},
+ {Enable: true, Radio: 0, IFValue: 0, Bandwidth: 0, SpreadFactor: 0, Datarate: 0},
+ {Enable: true, Radio: 0, IFValue: 200000, Bandwidth: 0, SpreadFactor: 0, Datarate: 0},
+ {Enable: true, Radio: 0, IFValue: 400000, Bandwidth: 0, SpreadFactor: 0, Datarate: 0},
+ },
+ LoRaStandardChannel: &shared.IFConfig{
+ Enable: true,
+ Radio: 1,
+ IFValue: -200000,
+ Bandwidth: 250000,
+ SpreadFactor: 7,
+ Datarate: 0,
+ },
+ FSKChannel: &shared.IFConfig{
+ Enable: true,
+ Radio: 1,
+ IFValue: -200000,
+ Bandwidth: 250000,
+ SpreadFactor: 7,
+ Datarate: 0,
+ },
+ TxLUTConfigs: []shared.TxLUTConfig{
+ {PAGain: 0, MixGain: 8, RFPower: -6, DigGain: 0},
+ {PAGain: 0, MixGain: 10, RFPower: -3, DigGain: 0},
+ {PAGain: 0, MixGain: 12, RFPower: 0, DigGain: 0},
+ {PAGain: 1, MixGain: 8, RFPower: 3, DigGain: 0},
+ {PAGain: 1, MixGain: 10, RFPower: 6, DigGain: 0},
+ {PAGain: 1, MixGain: 12, RFPower: 10, DigGain: 0},
+ {PAGain: 1, MixGain: 13, RFPower: 11, DigGain: 0},
+ {PAGain: 2, MixGain: 9, RFPower: 12, DigGain: 0},
+ {PAGain: 1, MixGain: 15, RFPower: 13, DigGain: 0},
+ {PAGain: 2, MixGain: 10, RFPower: 14, DigGain: 0},
+ {PAGain: 2, MixGain: 11, RFPower: 16, DigGain: 0},
+ {PAGain: 3, MixGain: 9, RFPower: 20, DigGain: 0},
+ {PAGain: 3, MixGain: 10, RFPower: 23, DigGain: 0},
+ {PAGain: 3, MixGain: 11, RFPower: 25, DigGain: 0},
+ {PAGain: 3, MixGain: 12, RFPower: 26, DigGain: 0},
+ {PAGain: 3, MixGain: 14, RFPower: 27, DigGain: 0},
+ },
+ }
+}
+
+func getGtwConfig(t *testing.T) semtechudp.GatewayConf {
+ t.Helper()
+
+ return semtechudp.GatewayConf{
+ ServerAddress: "localhost",
+ ServerPortUp: 1700,
+ ServerPortDown: 1700,
+ Servers: []semtechudp.GatewayConf{
+ {
+ ServerAddress: "localhost",
+ ServerPortUp: 1700,
+ ServerPortDown: 1700,
+ Enabled: true,
+ },
+ },
+ }
+}
+
+func TestConfigSerialization(t *testing.T) {
+ t.Parallel()
+
+ testCases := []struct {
+ Name string
+ *semtechudp.Config
+ }{
+ {
+ Name: "Single Frequency Plan",
+ Config: &semtechudp.Config{
+ SX1301Conf: []*shared.SX1301Config{
+ getSX1301Conf(t),
+ },
+ GatewayConf: getGtwConfig(t),
+ },
+ },
+ {
+ Name: "Multiple Frequency Plans",
+ Config: &semtechudp.Config{
+ SX1301Conf: []*shared.SX1301Config{
+ getSX1301Conf(t),
+ getSX1301Conf(t),
+ getSX1301Conf(t),
+ },
+ GatewayConf: getGtwConfig(t),
+ },
+ },
+ }
+
+ for _, tc := range testCases {
+ tc := tc
+ t.Run(tc.Name, func(t *testing.T) {
+ t.Parallel()
+ a := assertions.New(t)
+ marshalled, err := json.Marshal(tc.Config)
+ if !a.So(err, should.BeNil) {
+ t.FailNow()
+ }
+
+ var cfg2 semtechudp.Config
+ err = json.Unmarshal(marshalled, &cfg2)
+ if !a.So(err, should.BeNil) {
+ t.FailNow()
+ }
+
+ a.So(cfg2, should.Resemble, *tc.Config)
+ })
+ }
+}
diff --git a/pkg/ratelimit/grpc.go b/pkg/ratelimit/grpc.go
index 406f2d6f9b..9a9c9d27d2 100644
--- a/pkg/ratelimit/grpc.go
+++ b/pkg/ratelimit/grpc.go
@@ -18,7 +18,6 @@ import (
"context"
"fmt"
- "go.thethings.network/lorawan-stack/v3/pkg/auth"
clusterauth "go.thethings.network/lorawan-stack/v3/pkg/auth/cluster"
"go.thethings.network/lorawan-stack/v3/pkg/log"
"go.thethings.network/lorawan-stack/v3/pkg/rpcmetadata"
@@ -44,17 +43,6 @@ func grpcIsClusterAuthCall(ctx context.Context) bool {
return rpcmetadata.FromIncomingContext(ctx).AuthType == clusterauth.AuthType
}
-func grpcAuthTokenID(ctx context.Context) string {
- if authValue := rpcmetadata.FromIncomingContext(ctx).AuthValue; authValue != "" {
- _, id, _, err := auth.SplitToken(authValue)
- if err != nil {
- return "unauthenticated"
- }
- return id
- }
- return "unauthenticated"
-}
-
// UnaryServerInterceptor returns a gRPC unary server interceptor that rate limits incoming gRPC requests.
func UnaryServerInterceptor(limiter Interface) grpc.UnaryServerInterceptor {
return func(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp any, err error) {
diff --git a/pkg/ratelimit/grpc_test.go b/pkg/ratelimit/grpc_test.go
index 0e42d8295b..d66d1d7ead 100644
--- a/pkg/ratelimit/grpc_test.go
+++ b/pkg/ratelimit/grpc_test.go
@@ -53,12 +53,6 @@ func (ss *serverStream) SetHeader(md metadata.MD) error {
return nil
}
-func grpcTokenContext(authTokenID string) context.Context {
- return metadata.NewIncomingContext(test.Context(), metadata.Pairs(
- "authorization", fmt.Sprintf("Bearer NNSXS.%s.authTokenKey", authTokenID),
- ))
-}
-
func grpcClusterContext() context.Context {
return metadata.NewIncomingContext(test.Context(), metadata.Pairs(
"authorization", fmt.Sprintf("%s %X", clusterauth.AuthType, []byte{0x00, 0x01, 0x02}),
@@ -82,7 +76,6 @@ func TestGRPC(t *testing.T) {
const (
unaryMethod = "/Service/UnaryMethod"
- authTokenID = "my-token-id"
streamMethod = "/Service/StreamMethod"
)
@@ -157,7 +150,7 @@ func TestGRPC(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
intercept := ratelimit.UnaryServerInterceptor(tc.limiter)
- ctx := grpcTokenContext(authTokenID)
+ ctx := tokenContext(authTokenID)
if tc.cluster {
ctx = grpcClusterContext()
}
@@ -219,7 +212,7 @@ func TestGRPC(t *testing.T) {
} {
t.Run(tc.name, func(t *testing.T) {
intercept := ratelimit.StreamServerInterceptor(tc.limiter)
- ss := &serverStream{t: t, ctx: grpcTokenContext(authTokenID)}
+ ss := &serverStream{t: t, ctx: tokenContext(authTokenID)}
if tc.cluster {
ss.ctx = grpcClusterContext()
}
@@ -238,7 +231,7 @@ func TestGRPC(t *testing.T) {
"grpc:stream:up": &mockLimiter{},
}
intercept := ratelimit.StreamServerInterceptor(limiter)
- ss := &serverStream{t: t, ctx: grpcTokenContext(authTokenID)}
+ ss := &serverStream{t: t, ctx: tokenContext(authTokenID)}
info := &grpc.StreamServerInfo{FullMethod: streamMethod}
keyFromFirstStream := ""
diff --git a/pkg/ratelimit/http_test.go b/pkg/ratelimit/http_test.go
index 1ab9a6f597..8972b78136 100644
--- a/pkg/ratelimit/http_test.go
+++ b/pkg/ratelimit/http_test.go
@@ -54,6 +54,42 @@ func TestHTTP(t *testing.T) {
a.So(limiter.calledWithResource.Classes(), should.Resemble, []string{class, "http"})
})
+ t.Run("PathTemplate", func(t *testing.T) {
+ limiter.limit = false
+ limiter.result = ratelimit.Result{Limit: 10}
+
+ restore := ratelimit.SetPathTemplate(func(r *http.Request) (string, bool) {
+ return "/path/{id}", true
+ })
+ defer restore()
+
+ rec := httptest.NewRecorder()
+ handler.ServeHTTP(rec, httpRequest("/path/123", "10.10.10.10"))
+
+ a.So(rec.Header().Get("x-rate-limit-limit"), should.Equal, "10")
+ a.So(rec.Result().StatusCode, should.Equal, http.StatusOK)
+
+ a.So(limiter.calledWithResource.Key(), should.ContainSubstring, "/path/123")
+ a.So(limiter.calledWithResource.Key(), should.ContainSubstring, "10.10.10.10")
+ a.So(limiter.calledWithResource.Classes(), should.Resemble, []string{"http:test:/path/{id}", class, "http"})
+ })
+
+ t.Run("AuthToken", func(t *testing.T) {
+ limiter.limit = false
+ limiter.result = ratelimit.Result{Limit: 10}
+
+ rec := httptest.NewRecorder()
+ req := httpRequest("/path", "10.10.10.10").WithContext(tokenContext(authTokenID))
+ handler.ServeHTTP(rec, req)
+
+ a.So(rec.Header().Get("x-rate-limit-limit"), should.Equal, "10")
+ a.So(rec.Result().StatusCode, should.Equal, http.StatusOK)
+
+ a.So(limiter.calledWithResource.Key(), should.ContainSubstring, "/path")
+ a.So(limiter.calledWithResource.Key(), should.ContainSubstring, authTokenID)
+ a.So(limiter.calledWithResource.Classes(), should.Resemble, []string{class, "http"})
+ })
+
t.Run("Limit", func(t *testing.T) {
limiter.limit = true
rec := httptest.NewRecorder()
diff --git a/pkg/ratelimit/resource.go b/pkg/ratelimit/resource.go
index afe7b5683f..dfb734d747 100644
--- a/pkg/ratelimit/resource.go
+++ b/pkg/ratelimit/resource.go
@@ -20,7 +20,10 @@ import (
"net"
"net/http"
+ "github.com/gorilla/mux"
+ "go.thethings.network/lorawan-stack/v3/pkg/auth"
"go.thethings.network/lorawan-stack/v3/pkg/events"
+ "go.thethings.network/lorawan-stack/v3/pkg/rpcmetadata"
"go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
"go.thethings.network/lorawan-stack/v3/pkg/unique"
)
@@ -44,18 +47,51 @@ type resource struct {
func (r *resource) Key() string { return r.key }
func (r *resource) Classes() []string { return r.classes }
+const unauthenticated = "unauthenticated"
+
+func authTokenID(ctx context.Context) string {
+ if authValue := rpcmetadata.FromIncomingContext(ctx).AuthValue; authValue != "" {
+ _, id, _, err := auth.SplitToken(authValue)
+ if err != nil {
+ return unauthenticated
+ }
+ return id
+ }
+ return unauthenticated
+}
+
+var pathTemplate = func(r *http.Request) (string, bool) {
+ route := mux.CurrentRoute(r)
+ if route == nil {
+ return "", false
+ }
+ pathTemplate, err := route.GetPathTemplate()
+ if err != nil {
+ return "", false
+ }
+ return pathTemplate, true
+}
+
// httpRequestResource represents an HTTP request. Avoid using directly, use HTTPMiddleware instead.
func httpRequestResource(r *http.Request, class string) Resource {
+ specificClasses := make([]string, 0, 3)
+ if template, ok := pathTemplate(r); ok {
+ specificClasses = append(specificClasses, fmt.Sprintf("%s:%s", class, template))
+ }
+ callerInfo := fmt.Sprintf("ip:%s", httpRemoteIP(r))
+ if authTokenID := authTokenID(r.Context()); authTokenID != unauthenticated {
+ callerInfo = fmt.Sprintf("token:%s", authTokenID)
+ }
return &resource{
- key: fmt.Sprintf("%s:ip:%s:url:%s", class, httpRemoteIP(r), r.URL.Path),
- classes: []string{class, "http"},
+ key: fmt.Sprintf("%s:%s:url:%s", class, callerInfo, r.URL.Path),
+ classes: append(specificClasses, class, "http"),
}
}
// grpcMethodResource represents a gRPC request.
func grpcMethodResource(ctx context.Context, fullMethod string, req any) Resource {
key := fmt.Sprintf("grpc:method:%s:%s", fullMethod, grpcEntityFromRequest(ctx, req))
- if authTokenID := grpcAuthTokenID(ctx); authTokenID != "" {
+ if authTokenID := authTokenID(ctx); authTokenID != unauthenticated {
key = fmt.Sprintf("%s:token:%s", key, authTokenID)
}
return &resource{
@@ -67,7 +103,7 @@ func grpcMethodResource(ctx context.Context, fullMethod string, req any) Resourc
// grpcStreamAcceptResource represents a new gRPC server stream.
func grpcStreamAcceptResource(ctx context.Context, fullMethod string) Resource {
key := fmt.Sprintf("grpc:stream:accept:%s", fullMethod)
- if authTokenID := grpcAuthTokenID(ctx); authTokenID != "" {
+ if authTokenID := authTokenID(ctx); authTokenID != unauthenticated {
key = fmt.Sprintf("%s:token:%s", key, authTokenID)
}
return &resource{
@@ -148,6 +184,15 @@ func ApplicationWebhooksDownResource(ctx context.Context, ids *ttnpb.EndDeviceId
}
}
+// ConsoleEventsRequestResource represents a request for events from the Console.
+func ConsoleEventsRequestResource(callerID string) Resource {
+ key := fmt.Sprintf("console:internal:events:request:%s", callerID)
+ return &resource{
+ key: key,
+ classes: []string{"http:console:internal:events"},
+ }
+}
+
// NewCustomResource returns a new resource. It is used internally by other components.
func NewCustomResource(key string, classes ...string) Resource {
return &resource{key, classes}
diff --git a/pkg/webui/console/containers/device-profile-section/device-card/connect.js b/pkg/ratelimit/resource_util_test.go
similarity index 58%
rename from pkg/webui/console/containers/device-profile-section/device-card/connect.js
rename to pkg/ratelimit/resource_util_test.go
index 0ab4bb6764..a94522a257 100644
--- a/pkg/webui/console/containers/device-profile-section/device-card/connect.js
+++ b/pkg/ratelimit/resource_util_test.go
@@ -1,4 +1,4 @@
-// Copyright © 2022 The Things Network Foundation, The Things Industries B.V.
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,16 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import { connect } from 'react-redux'
+package ratelimit
-import { selectDeviceModelById } from '@console/store/selectors/device-repository'
+import "net/http"
-const mapStateToProps = (state, props) => {
- const { brandId, modelId } = props
-
- return {
- model: selectDeviceModelById(state, brandId, modelId),
- }
+// SetPathTemplate sets the path template function for HTTP rate limiting.
+func SetPathTemplate(f func(*http.Request) (string, bool)) func() {
+ old := pathTemplate
+ pathTemplate = f
+ return func() { pathTemplate = old }
}
-
-export default DeviceCard => connect(mapStateToProps)(DeviceCard)
diff --git a/pkg/webui/console/containers/device-profile-section/device-selection/hw-version-select/connect.js b/pkg/ratelimit/util_test.go
similarity index 56%
rename from pkg/webui/console/containers/device-profile-section/device-selection/hw-version-select/connect.js
rename to pkg/ratelimit/util_test.go
index 3f1b4282db..7aaf76f6f4 100644
--- a/pkg/webui/console/containers/device-profile-section/device-selection/hw-version-select/connect.js
+++ b/pkg/ratelimit/util_test.go
@@ -1,4 +1,4 @@
-// Copyright © 2022 The Things Network Foundation, The Things Industries B.V.
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,16 +12,20 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import { connect } from 'react-redux'
+package ratelimit_test
-import { selectDeviceModelHardwareVersions } from '@console/store/selectors/device-repository'
+import (
+ "context"
+ "fmt"
-const mapStateToProps = (state, props) => {
- const { brandId, modelId } = props
+ "go.thethings.network/lorawan-stack/v3/pkg/util/test"
+ "google.golang.org/grpc/metadata"
+)
- return {
- versions: selectDeviceModelHardwareVersions(state, brandId, modelId),
- }
-}
+const authTokenID = "my-token-id"
-export default HardwareVersionSelect => connect(mapStateToProps)(HardwareVersionSelect)
+func tokenContext(authTokenID string) context.Context {
+ return metadata.NewIncomingContext(test.Context(), metadata.Pairs(
+ "authorization", fmt.Sprintf("Bearer NNSXS.%s.authTokenKey", authTokenID),
+ ))
+}
diff --git a/pkg/redis/redis.go b/pkg/redis/redis.go
index 1f88355d9e..7c66bb1d06 100644
--- a/pkg/redis/redis.go
+++ b/pkg/redis/redis.go
@@ -696,13 +696,17 @@ func (q *TaskQueue) Pop(ctx context.Context, consumerID string, r redis.Cmdable,
return popTask(ctx, r, q.Group, consumerID, f, q.Key, q.StreamBlockLimit)
}
-var deduplicateProtosScript = redis.NewScript(`local exp = ARGV[1]
+var deduplicateProtosScript = redis.NewScript(`local exp = table.remove(ARGV, 1)
+local limit = tonumber(table.remove(ARGV, 1))
local ok = redis.call('set', KEYS[1], '', 'px', exp, 'nx')
-if #ARGV > 1 then
- table.remove(ARGV, 1)
+
+if #ARGV > 0 then
redis.call('rpush', KEYS[2], unpack(ARGV))
local ttl = redis.call('pttl', KEYS[1])
redis.call('pexpire', KEYS[2], ttl)
+ if limit > 0 then
+ redis.call('ltrim', KEYS[2], -limit, -1)
+ end
end
if ok then
return 1
@@ -728,12 +732,19 @@ func milliseconds(d time.Duration) int64 {
return ms
}
-// DeduplicateProtos deduplicates protos using key k. It stores a lock at LockKey(k) and the list of collected protos at ListKey(k).
+// DeduplicateProtos deduplicates protos using key k. It stores a lock at LockKey(k)
+// and the list of collected protos at ListKey(k).
+// If the number of protos exceeds limit, the messages are trimmed from the start of the list.
func DeduplicateProtos(
- ctx context.Context, r redis.Scripter, k string, window time.Duration, msgs ...proto.Message,
+ ctx context.Context, r redis.Scripter, k string, window time.Duration, limit int, msgs ...proto.Message,
) (bool, error) {
- args := make([]any, 0, 1+len(msgs))
+ args := make([]any, 0, 2+len(msgs))
args = append(args, milliseconds(window))
+ args = append(args, limit)
+ if n := len(msgs) - limit; n > 0 {
+ msgs = msgs[n:]
+ }
+
for _, msg := range msgs {
s, err := MarshalProto(msg)
if err != nil {
@@ -885,17 +896,23 @@ func LockedWatch(ctx context.Context, r WatchCmdable, k, id string, expiration t
return nil
}
-// RangeStreams sequentially iterates over all non-acknowledged messages in streams calling f with at most count messages.
+// RangeStreams sequentially iterates over all non-acknowledged messages in streams calling f with at most count
+// messages. f must acknowledge the messages which have been processed.
// RangeStreams assumes that within its lifetime it is the only consumer within group group using ID id.
// RangeStreams iterates over all pending messages, which have been idle for at least minIdle milliseconds first.
-func RangeStreams(ctx context.Context, r redis.Cmdable, group, id string, count int64, minIdle time.Duration, f func(string, ...redis.XMessage) error, streams ...string) error {
- var ack func(context.Context, string, ...redis.XMessage) error
- {
- ids := make([]string, 0, int(count))
- ack = func(ctx context.Context, stream string, msgs ...redis.XMessage) error {
- ids = ids[:0]
- for _, msg := range msgs {
- ids = append(ids, msg.ID)
+func RangeStreams(
+ ctx context.Context,
+ r redis.Cmdable,
+ group, id string,
+ count int64,
+ minIdle time.Duration,
+ f func(string, func(...string) error, ...redis.XMessage) error,
+ streams ...string,
+) error {
+ makeAck := func(stream string) func(...string) error {
+ return func(ids ...string) error {
+ if len(ids) == 0 {
+ return nil
}
_, err := r.Pipelined(ctx, func(p redis.Pipeliner) error {
// NOTE: Both calls below copy contents of ids internally.
@@ -903,13 +920,17 @@ func RangeStreams(ctx context.Context, r redis.Cmdable, group, id string, count
p.XDel(ctx, stream, ids...)
return nil
})
- return err
+ if err != nil {
+ return ConvertError(err)
+ }
+ return nil
}
}
for _, stream := range streams {
- for start := "-"; ; {
- msgs, lastID, err := r.XAutoClaim(ctx, &redis.XAutoClaimArgs{
+ for start := "-"; start != "0-0"; {
+ var err error
+ _, start, err = r.XAutoClaimJustID(ctx, &redis.XAutoClaimArgs{
Stream: stream,
Group: group,
Consumer: id,
@@ -918,38 +939,27 @@ func RangeStreams(ctx context.Context, r redis.Cmdable, group, id string, count
Count: count,
}).Result()
if err != nil {
- return err
- }
- if len(msgs) == 0 {
- break
+ return ConvertError(err)
}
- if err := f(stream, msgs...); err != nil {
- return err
- }
- if err := ack(ctx, stream, msgs...); err != nil {
- return err
- }
- start = lastID
}
}
streamCount := len(streams)
- streamsArg := make([]string, 2*streamCount)
- idsArg := make([]string, 2*streamCount)
- for i, stream := range streams {
- j := i * 2
- streamsArg[j], streamsArg[j+1], idsArg[j], idsArg[j+1] = stream, stream, "0", ">"
+ args := make([]string, 2*streamCount)
+ streamsArg := args[:streamCount]
+ idsArg := args[streamCount:]
+ for i := range streams {
+ streamsArg[i], idsArg[i] = streams[i], "0"
}
- drainedOld := make(map[string]struct{}, streamCount)
-outer:
+ finishedOld, block := false, time.Duration(-1)
for {
rets, err := r.XReadGroup(ctx, &redis.XReadGroupArgs{
Group: group,
Consumer: id,
- Streams: append(streamsArg, idsArg...),
+ Streams: args,
Count: count,
- Block: -1, // do not block
+ Block: block,
}).Result()
if err != nil {
if errors.Is(err, redis.Nil) {
@@ -958,38 +968,33 @@ outer:
return ConvertError(err)
}
+ cont := false
for i, ret := range rets {
- if idsArg[i] == "0" && len(ret.Messages) < int(count) {
- drainedOld[ret.Stream] = struct{}{}
- }
- if len(ret.Messages) == 0 {
- if i == len(rets)-1 {
- return nil
- }
+ n := int64(len(ret.Messages))
+ if n == 0 {
continue
}
-
- if err := f(ret.Stream, ret.Messages...); err != nil {
- return err
- }
- if err := ack(ctx, ret.Stream, ret.Messages...); err != nil {
+ cont = cont || n == count
+ idsArg[i] = ret.Messages[len(ret.Messages)-1].ID
+ if err := f(ret.Stream, makeAck(ret.Stream), ret.Messages...); err != nil {
return err
}
- if len(ret.Messages) == int(count) {
- continue outer
- }
}
- streamsArg = streamsArg[:0]
- idsArg = idsArg[:0]
- for _, stream := range streams {
- _, ok := drainedOld[stream]
- if !ok {
- streamsArg = append(streamsArg, stream)
- idsArg = append(idsArg, "0")
+ switch {
+ case cont:
+ // At least one stream has returned `count` messages.
+ case finishedOld:
+ // All streams have returned less than `count` messages,
+ // and we have already processed all of the old and new messages.
+ return nil
+ default: // !cont && !finishedOld
+ // All streams have returned less than `count` messages,
+ // and we have processed all of the old messages.
+ finishedOld, block = true, minIdle
+ for i := range streams {
+ idsArg[i] = ">"
}
- streamsArg = append(streamsArg, stream)
- idsArg = append(idsArg, ">")
}
}
}
diff --git a/pkg/redis/redis_test.go b/pkg/redis/redis_test.go
index ed247ceca2..ce433375d6 100644
--- a/pkg/redis/redis_test.go
+++ b/pkg/redis/redis_test.go
@@ -487,57 +487,62 @@ func TestTaskQueue(t *testing.T) {
}
}
+func makeProto(t *testing.T, s string) proto.Message {
+ t.Helper()
+ return &ttnpb.APIKey{Id: s}
+}
+
+func makeProtoString(t *testing.T, s string) string {
+ t.Helper()
+ m := makeProto(t, s)
+ return test.Must(MarshalProto(m))
+}
+
func TestProtoDeduplicator(t *testing.T) {
a, ctx := test.New(t)
cl, flush := test.NewRedis(ctx, "redis_test")
defer flush()
defer cl.Close()
-
- makeProto := func(s string) proto.Message {
- return &ttnpb.APIKey{Id: s}
- }
- makeProtoString := func(s string) string {
- m := makeProto(s)
- s, _ = MarshalProto(m)
- return s
- }
+ limit := 50
ttl := (1 << 12) * test.Delay
key1 := cl.Key("test1")
key2 := cl.Key("test2")
- v, err := DeduplicateProtos(ctx, cl, key1, ttl)
+ v, err := DeduplicateProtos(ctx, cl, key1, ttl, limit)
if !a.So(err, should.BeNil) {
t.FailNow()
}
a.So(v, should.BeTrue)
- v, err = DeduplicateProtos(ctx, cl, key1, ttl, makeProto("proto1"))
+ v, err = DeduplicateProtos(ctx, cl, key1, ttl, limit, makeProto(t, "proto1"))
if !a.So(err, should.BeNil) {
t.FailNow()
}
a.So(v, should.BeFalse)
- v, err = DeduplicateProtos(ctx, cl, key2, ttl, makeProto("proto1"))
+ v, err = DeduplicateProtos(ctx, cl, key2, ttl, limit, makeProto(t, "proto1"))
if !a.So(err, should.BeNil) {
t.FailNow()
}
a.So(v, should.BeTrue)
- v, err = DeduplicateProtos(ctx, cl, key1, ttl, makeProto("proto1"))
+ v, err = DeduplicateProtos(ctx, cl, key1, ttl, limit, makeProto(t, "proto1"))
if !a.So(err, should.BeNil) {
t.FailNow()
}
a.So(v, should.BeFalse)
- v, err = DeduplicateProtos(ctx, cl, key1, ttl, makeProto("proto2"), makeProto("proto3"))
+ v, err = DeduplicateProtos(
+ ctx, cl, key1, ttl, limit, makeProto(t, "proto2"), makeProto(t, "proto3"),
+ )
if !a.So(err, should.BeNil) {
t.FailNow()
}
a.So(v, should.BeFalse)
- v, err = DeduplicateProtos(ctx, cl, key2, ttl, makeProto("proto2"))
+ v, err = DeduplicateProtos(ctx, cl, key2, ttl, limit, makeProto(t, "proto2"))
if !a.So(err, should.BeNil) {
t.FailNow()
}
@@ -556,10 +561,10 @@ func TestProtoDeduplicator(t *testing.T) {
t.FailNow()
}
a.So(ss, should.Resemble, []string{
- makeProtoString("proto1"),
- makeProtoString("proto1"),
- makeProtoString("proto2"),
- makeProtoString("proto3"),
+ makeProtoString(t, "proto1"),
+ makeProtoString(t, "proto1"),
+ makeProtoString(t, "proto2"),
+ makeProtoString(t, "proto3"),
})
a.So(lockTTL, should.BeGreaterThan, 0)
a.So(lockTTL, should.BeLessThanOrEqualTo, ttl)
@@ -579,8 +584,8 @@ func TestProtoDeduplicator(t *testing.T) {
t.FailNow()
}
a.So(ss, should.Resemble, []string{
- makeProtoString("proto1"),
- makeProtoString("proto2"),
+ makeProtoString(t, "proto1"),
+ makeProtoString(t, "proto2"),
})
a.So(lockTTL, should.BeGreaterThan, 0)
a.So(lockTTL, should.BeLessThanOrEqualTo, ttl)
@@ -588,6 +593,64 @@ func TestProtoDeduplicator(t *testing.T) {
a.So(listTTL, should.BeLessThanOrEqualTo, ttl)
}
+func TestProtoDeduplicatorRespectsLimit(t *testing.T) {
+ t.Parallel()
+ a, ctx := test.New(t)
+ cl, flush := test.NewRedis(ctx, "redis_test")
+ defer flush()
+ defer cl.Close()
+
+ ttl := (1 << 12) * test.Delay
+ key := cl.Key("test1")
+ limit := 30
+ protoID := 0
+
+ for i := 0; i < limit+3; i++ {
+ s := fmt.Sprintf("proto%d", protoID)
+ _, err := DeduplicateProtos(ctx, cl, key, ttl, limit, makeProto(t, s))
+ if !a.So(err, should.BeNil) {
+ t.FailNow()
+ }
+ protoID++
+ }
+
+ actual, err := cl.LRange(ctx, ListKey(key), 0, -1).Result()
+ if !a.So(err, should.BeNil) {
+ t.FailNow()
+ }
+ a.So(actual, should.HaveLength, limit)
+ expected := make([]string, limit)
+ for i := limit - 1; i >= 0; i-- {
+ s := fmt.Sprintf("proto%d", protoID-limit+i)
+ expected[i] = makeProtoString(t, s)
+ }
+ a.So(actual, should.Resemble, expected)
+
+ bulkedProtosLen := limit + 5
+ bulkedProtos := make([]proto.Message, bulkedProtosLen)
+ for i := 0; i < bulkedProtosLen; i++ {
+ s := fmt.Sprintf("proto%d", protoID)
+ bulkedProtos[i] = makeProto(t, s)
+ protoID++
+ }
+
+ if _, err := DeduplicateProtos(ctx, cl, key, ttl, limit, bulkedProtos...); !a.So(err, should.BeNil) {
+ t.FailNow()
+ }
+
+ actual, err = cl.LRange(ctx, ListKey(key), 0, -1).Result()
+ if !a.So(err, should.BeNil) {
+ t.FailNow()
+ }
+ a.So(actual, should.HaveLength, limit)
+ expected = make([]string, limit)
+ for i := limit - 1; i >= 0; i-- {
+ s := fmt.Sprintf("proto%d", protoID-limit+i)
+ expected[i] = makeProtoString(t, s)
+ }
+ a.So(actual, should.Resemble, expected)
+}
+
func TestMutex(t *testing.T) {
a, ctx := test.New(t)
diff --git a/pkg/rpcserver/rpcserver.go b/pkg/rpcserver/rpcserver.go
index 3d313ba9e9..0778a24c44 100644
--- a/pkg/rpcserver/rpcserver.go
+++ b/pkg/rpcserver/rpcserver.go
@@ -267,6 +267,9 @@ func New(ctx context.Context, opts ...Option) *Server {
}
return s, false
}),
+ runtime.WithOutgoingTrailerMatcher(func(s string) (string, bool) {
+ return s, false
+ }),
runtime.WithDisablePathLengthFallback(),
)
return server
diff --git a/pkg/specification/relayspec/relay.go b/pkg/specification/relayspec/relay.go
new file mode 100644
index 0000000000..81b8b1ebbd
--- /dev/null
+++ b/pkg/specification/relayspec/relay.go
@@ -0,0 +1,24 @@
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package relayspec contains LoRaWAN relay related functionality.
+package relayspec
+
+import "go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
+
+// FPort is the FPort used for the relay forwarding protocol.
+const FPort = 226
+
+// GatewayIdentifiers is the GatewayIdentifiers used for relay end devices.
+var GatewayIdentifiers = &ttnpb.GatewayIdentifiers{GatewayId: "relay"}
diff --git a/pkg/ttnpb/configuration_services.pb.go b/pkg/ttnpb/configuration_services.pb.go
index 8efa76b9df..4cb3b3c269 100644
--- a/pkg/ttnpb/configuration_services.pb.go
+++ b/pkg/ttnpb/configuration_services.pb.go
@@ -46,6 +46,8 @@ type ListFrequencyPlansRequest struct {
// Optional base frequency in MHz for hardware support (433, 470, 868 or 915)
BaseFrequency uint32 `protobuf:"varint,1,opt,name=base_frequency,json=baseFrequency,proto3" json:"base_frequency,omitempty"`
+ // Optional Band ID to filter the results.
+ BandId string `protobuf:"bytes,2,opt,name=band_id,json=bandId,proto3" json:"band_id,omitempty"`
}
func (x *ListFrequencyPlansRequest) Reset() {
@@ -87,6 +89,13 @@ func (x *ListFrequencyPlansRequest) GetBaseFrequency() uint32 {
return 0
}
+func (x *ListFrequencyPlansRequest) GetBandId() string {
+ if x != nil {
+ return x.BandId
+ }
+ return ""
+}
+
type FrequencyPlanDescription struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -98,6 +107,7 @@ type FrequencyPlanDescription struct {
Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
// Base frequency in MHz for hardware support (433, 470, 868 or 915)
BaseFrequency uint32 `protobuf:"varint,4,opt,name=base_frequency,json=baseFrequency,proto3" json:"base_frequency,omitempty"`
+ BandId string `protobuf:"bytes,5,opt,name=band_id,json=bandId,proto3" json:"band_id,omitempty"`
}
func (x *FrequencyPlanDescription) Reset() {
@@ -160,6 +170,13 @@ func (x *FrequencyPlanDescription) GetBaseFrequency() uint32 {
return 0
}
+func (x *FrequencyPlanDescription) GetBandId() string {
+ if x != nil {
+ return x.BandId
+ }
+ return ""
+}
+
type ListFrequencyPlansResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -390,6 +407,8 @@ type BandDescription struct {
MaxRetransmitTimeout *durationpb.Duration `protobuf:"bytes,21,opt,name=max_retransmit_timeout,json=maxRetransmitTimeout,proto3" json:"max_retransmit_timeout,omitempty"`
TxOffset []float32 `protobuf:"fixed32,22,rep,packed,name=tx_offset,json=txOffset,proto3" json:"tx_offset,omitempty"`
MaxAdrDataRateIndex DataRateIndex `protobuf:"varint,23,opt,name=max_adr_data_rate_index,json=maxAdrDataRateIndex,proto3,enum=ttn.lorawan.v3.DataRateIndex" json:"max_adr_data_rate_index,omitempty"`
+ RelayForwardDelay *durationpb.Duration `protobuf:"bytes,34,opt,name=relay_forward_delay,json=relayForwardDelay,proto3" json:"relay_forward_delay,omitempty"`
+ RelayReceiveDelay *durationpb.Duration `protobuf:"bytes,35,opt,name=relay_receive_delay,json=relayReceiveDelay,proto3" json:"relay_receive_delay,omitempty"`
TxParamSetupReqSupport bool `protobuf:"varint,24,opt,name=tx_param_setup_req_support,json=txParamSetupReqSupport,proto3" json:"tx_param_setup_req_support,omitempty"`
DefaultMaxEirp float32 `protobuf:"fixed32,25,opt,name=default_max_eirp,json=defaultMaxEirp,proto3" json:"default_max_eirp,omitempty"`
DefaultRx2Parameters *BandDescription_Rx2Parameters `protobuf:"bytes,30,opt,name=default_rx2_parameters,json=defaultRx2Parameters,proto3" json:"default_rx2_parameters,omitempty"`
@@ -590,6 +609,20 @@ func (x *BandDescription) GetMaxAdrDataRateIndex() DataRateIndex {
return DataRateIndex_DATA_RATE_0
}
+func (x *BandDescription) GetRelayForwardDelay() *durationpb.Duration {
+ if x != nil {
+ return x.RelayForwardDelay
+ }
+ return nil
+}
+
+func (x *BandDescription) GetRelayReceiveDelay() *durationpb.Duration {
+ if x != nil {
+ return x.RelayReceiveDelay
+ }
+ return nil
+}
+
func (x *BandDescription) GetTxParamSetupReqSupport() bool {
if x != nil {
return x.TxParamSetupReqSupport
@@ -1256,303 +1289,316 @@ var file_ttn_lorawan_v3_configuration_services_proto_rawDesc = []byte{
0x74, 0x74, 0x6e, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2f, 0x76, 0x33, 0x2f, 0x6c,
0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x76, 0x61,
0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x4c, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x72, 0x65,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x65, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x72, 0x65,
0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x50, 0x6c, 0x61, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75,
0x65, 0x6e, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x62, 0x61, 0x73, 0x65,
- 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08,
- 0x00, 0x10, 0x01, 0x22, 0x7e, 0x0a, 0x18, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79,
- 0x50, 0x6c, 0x61, 0x6e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12,
- 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12,
- 0x17, 0x0a, 0x07, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
- 0x52, 0x06, 0x62, 0x61, 0x73, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
- 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e,
- 0x62, 0x61, 0x73, 0x65, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x04,
- 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x62, 0x61, 0x73, 0x65, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65,
- 0x6e, 0x63, 0x79, 0x22, 0x6f, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x72, 0x65, 0x71, 0x75,
- 0x65, 0x6e, 0x63, 0x79, 0x50, 0x6c, 0x61, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
- 0x65, 0x12, 0x51, 0x0a, 0x0f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x70,
- 0x6c, 0x61, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x74, 0x6e,
- 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x46, 0x72, 0x65, 0x71,
- 0x75, 0x65, 0x6e, 0x63, 0x79, 0x50, 0x6c, 0x61, 0x6e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,
- 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x50,
- 0x6c, 0x61, 0x6e, 0x73, 0x22, 0x3a, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x50, 0x68, 0x79, 0x56, 0x65,
- 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a,
- 0x07, 0x62, 0x61, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
- 0x62, 0x61, 0x6e, 0x64, 0x49, 0x64, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x00, 0x10, 0x01,
- 0x22, 0xd6, 0x01, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x50, 0x68, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69,
- 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x55, 0x0a, 0x0c, 0x76,
- 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x03, 0x28,
- 0x0b, 0x32, 0x32, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
- 0x76, 0x33, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x68, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
- 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
- 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e,
- 0x66, 0x6f, 0x1a, 0x65, 0x0a, 0x0b, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66,
- 0x6f, 0x12, 0x17, 0x0a, 0x07, 0x62, 0x61, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x06, 0x62, 0x61, 0x6e, 0x64, 0x49, 0x64, 0x12, 0x3d, 0x0a, 0x0c, 0x70, 0x68,
- 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0e,
- 0x32, 0x1a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
- 0x33, 0x2e, 0x50, 0x48, 0x59, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x70, 0x68,
- 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x7c, 0x0a, 0x10, 0x4c, 0x69, 0x73,
- 0x74, 0x42, 0x61, 0x6e, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a,
- 0x07, 0x62, 0x61, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
- 0x62, 0x61, 0x6e, 0x64, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x0b, 0x70, 0x68, 0x79, 0x5f, 0x76, 0x65,
- 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x74,
- 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x50, 0x48, 0x59,
- 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10,
- 0x01, 0x52, 0x0a, 0x70, 0x68, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x08, 0xf2,
- 0xaa, 0x19, 0x04, 0x08, 0x00, 0x10, 0x01, 0x22, 0xc7, 0x17, 0x0a, 0x0f, 0x42, 0x61, 0x6e, 0x64,
- 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69,
- 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x3e, 0x0a, 0x06, 0x62,
- 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x74,
- 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x42, 0x61, 0x6e,
- 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x42, 0x65, 0x61,
- 0x63, 0x6f, 0x6e, 0x52, 0x06, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x15, 0x70,
- 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e,
- 0x63, 0x69, 0x65, 0x73, 0x18, 0x20, 0x20, 0x03, 0x28, 0x04, 0x52, 0x13, 0x70, 0x69, 0x6e, 0x67,
- 0x53, 0x6c, 0x6f, 0x74, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x12,
- 0x2e, 0x0a, 0x13, 0x6d, 0x61, 0x78, 0x5f, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x63, 0x68,
- 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x6d, 0x61,
- 0x78, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x12,
- 0x50, 0x0a, 0x0f, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65,
- 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c,
- 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x65,
- 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65,
- 0x6c, 0x52, 0x0e, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c,
- 0x73, 0x12, 0x32, 0x0a, 0x15, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e,
- 0x6b, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d,
- 0x52, 0x13, 0x6d, 0x61, 0x78, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x43, 0x68, 0x61,
- 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x12, 0x54, 0x0a, 0x11, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e,
- 0x6b, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b,
- 0x32, 0x27, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
- 0x33, 0x2e, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
- 0x6e, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x10, 0x64, 0x6f, 0x77, 0x6e, 0x6c,
- 0x69, 0x6e, 0x6b, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x12, 0x4e, 0x0a, 0x09, 0x73,
- 0x75, 0x62, 0x5f, 0x62, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31,
+ 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x17, 0x0a, 0x07, 0x62, 0x61, 0x6e,
+ 0x64, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x61, 0x6e, 0x64,
+ 0x49, 0x64, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x00, 0x10, 0x01, 0x22, 0x97, 0x01, 0x0a,
+ 0x18, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x50, 0x6c, 0x61, 0x6e, 0x44, 0x65,
+ 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x62, 0x61, 0x73,
+ 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x61, 0x73, 0x65,
+ 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x66,
+ 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d,
+ 0x62, 0x61, 0x73, 0x65, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x17, 0x0a,
+ 0x07, 0x62, 0x61, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
+ 0x62, 0x61, 0x6e, 0x64, 0x49, 0x64, 0x22, 0x6f, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x72,
+ 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x50, 0x6c, 0x61, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70,
+ 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x51, 0x0a, 0x0f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63,
+ 0x79, 0x5f, 0x70, 0x6c, 0x61, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e,
+ 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x46,
+ 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x50, 0x6c, 0x61, 0x6e, 0x44, 0x65, 0x73, 0x63,
+ 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e,
+ 0x63, 0x79, 0x50, 0x6c, 0x61, 0x6e, 0x73, 0x22, 0x3a, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x50, 0x68,
+ 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+ 0x12, 0x17, 0x0a, 0x07, 0x62, 0x61, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x06, 0x62, 0x61, 0x6e, 0x64, 0x49, 0x64, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08,
+ 0x00, 0x10, 0x01, 0x22, 0xd6, 0x01, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x50, 0x68, 0x79, 0x56, 0x65,
+ 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x55,
+ 0x0a, 0x0c, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02,
+ 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
+ 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x68, 0x79, 0x56, 0x65, 0x72, 0x73,
+ 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x56, 0x65, 0x72,
+ 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
+ 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0x65, 0x0a, 0x0b, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
+ 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x17, 0x0a, 0x07, 0x62, 0x61, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x61, 0x6e, 0x64, 0x49, 0x64, 0x12, 0x3d, 0x0a,
+ 0x0c, 0x70, 0x68, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20,
+ 0x03, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
+ 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x50, 0x48, 0x59, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52,
+ 0x0b, 0x70, 0x68, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x7c, 0x0a, 0x10,
+ 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x6e, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+ 0x12, 0x17, 0x0a, 0x07, 0x62, 0x61, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x06, 0x62, 0x61, 0x6e, 0x64, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x0b, 0x70, 0x68, 0x79,
+ 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a,
0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
- 0x42, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e,
- 0x53, 0x75, 0x62, 0x42, 0x61, 0x6e, 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72,
- 0x73, 0x52, 0x08, 0x73, 0x75, 0x62, 0x42, 0x61, 0x6e, 0x64, 0x73, 0x12, 0x4d, 0x0a, 0x0a, 0x64,
- 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32,
- 0x2e, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
- 0x2e, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,
- 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52,
- 0x09, 0x64, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x66, 0x72,
- 0x65, 0x71, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x69, 0x65, 0x72, 0x18, 0x0a, 0x20,
- 0x01, 0x28, 0x04, 0x52, 0x0e, 0x66, 0x72, 0x65, 0x71, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c,
- 0x69, 0x65, 0x72, 0x12, 0x2c, 0x0a, 0x12, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74,
- 0x73, 0x5f, 0x63, 0x66, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52,
- 0x10, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x43, 0x66, 0x4c, 0x69, 0x73,
- 0x74, 0x12, 0x3c, 0x0a, 0x0c, 0x63, 0x66, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x74, 0x79, 0x70,
- 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
- 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x46, 0x4c, 0x69, 0x73, 0x74, 0x54,
- 0x79, 0x70, 0x65, 0x52, 0x0a, 0x63, 0x66, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12,
- 0x41, 0x0a, 0x0f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79,
- 0x5f, 0x31, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
- 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74,
- 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x44, 0x65, 0x6c, 0x61,
- 0x79, 0x31, 0x12, 0x41, 0x0a, 0x0f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x5f, 0x64, 0x65,
- 0x6c, 0x61, 0x79, 0x5f, 0x32, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f,
- 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75,
- 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x44,
- 0x65, 0x6c, 0x61, 0x79, 0x32, 0x12, 0x48, 0x0a, 0x13, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x61, 0x63,
- 0x63, 0x65, 0x70, 0x74, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x31, 0x18, 0x0f, 0x20, 0x01,
- 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
- 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x6a,
- 0x6f, 0x69, 0x6e, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x31, 0x12,
- 0x48, 0x0a, 0x13, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x5f, 0x64,
- 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x32, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67,
- 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44,
- 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x6a, 0x6f, 0x69, 0x6e, 0x41, 0x63, 0x63,
- 0x65, 0x70, 0x74, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x32, 0x12, 0x20, 0x0a, 0x0c, 0x6d, 0x61, 0x78,
- 0x5f, 0x66, 0x63, 0x6e, 0x74, 0x5f, 0x67, 0x61, 0x70, 0x18, 0x11, 0x20, 0x01, 0x28, 0x04, 0x52,
- 0x0a, 0x6d, 0x61, 0x78, 0x46, 0x63, 0x6e, 0x74, 0x47, 0x61, 0x70, 0x12, 0x30, 0x0a, 0x14, 0x73,
- 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x5f, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x5f,
- 0x61, 0x64, 0x72, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x73, 0x75, 0x70, 0x70, 0x6f,
- 0x72, 0x74, 0x73, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x41, 0x64, 0x72, 0x12, 0x47, 0x0a,
- 0x0d, 0x61, 0x64, 0x72, 0x5f, 0x61, 0x63, 0x6b, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x13,
- 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
- 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x44, 0x52, 0x41, 0x63, 0x6b, 0x4c, 0x69, 0x6d, 0x69,
- 0x74, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x52, 0x0b, 0x61, 0x64, 0x72, 0x41, 0x63,
- 0x6b, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x4f, 0x0a, 0x16, 0x6d, 0x69, 0x6e, 0x5f, 0x72, 0x65,
- 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74,
- 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0x52, 0x14, 0x6d, 0x69, 0x6e, 0x52, 0x65, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x74,
- 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x4f, 0x0a, 0x16, 0x6d, 0x61, 0x78, 0x5f, 0x72,
- 0x65, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75,
- 0x74, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
- 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69,
- 0x6f, 0x6e, 0x52, 0x14, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69,
- 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x78, 0x5f, 0x6f,
- 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x16, 0x20, 0x03, 0x28, 0x02, 0x52, 0x08, 0x74, 0x78, 0x4f,
- 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x53, 0x0a, 0x17, 0x6d, 0x61, 0x78, 0x5f, 0x61, 0x64, 0x72,
- 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78,
- 0x18, 0x17, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
- 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65,
- 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x13, 0x6d, 0x61, 0x78, 0x41, 0x64, 0x72, 0x44, 0x61, 0x74,
- 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x3a, 0x0a, 0x1a, 0x74, 0x78,
- 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x5f, 0x73, 0x65, 0x74, 0x75, 0x70, 0x5f, 0x72, 0x65, 0x71,
- 0x5f, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x18, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16,
- 0x74, 0x78, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x65, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x53,
- 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c,
- 0x74, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x65, 0x69, 0x72, 0x70, 0x18, 0x19, 0x20, 0x01, 0x28, 0x02,
- 0x52, 0x0e, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x4d, 0x61, 0x78, 0x45, 0x69, 0x72, 0x70,
- 0x12, 0x63, 0x0a, 0x16, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x72, 0x78, 0x32, 0x5f,
- 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b,
- 0x32, 0x2d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
- 0x33, 0x2e, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
- 0x6e, 0x2e, 0x52, 0x78, 0x32, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x52,
- 0x14, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x52, 0x78, 0x32, 0x50, 0x61, 0x72, 0x61, 0x6d,
- 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x51, 0x0a, 0x0f, 0x62, 0x6f, 0x6f, 0x74, 0x5f, 0x64, 0x77,
- 0x65, 0x6c, 0x6c, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29,
+ 0x50, 0x48, 0x59, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82,
+ 0x01, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x70, 0x68, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
+ 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x00, 0x10, 0x01, 0x22, 0xdd, 0x18, 0x0a, 0x0f, 0x42,
+ 0x61, 0x6e, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e,
+ 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x3e,
+ 0x0a, 0x06, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26,
0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
0x42, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e,
- 0x44, 0x77, 0x65, 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x0d, 0x62, 0x6f, 0x6f, 0x74, 0x44,
- 0x77, 0x65, 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x45, 0x0a, 0x05, 0x72, 0x65, 0x6c, 0x61,
- 0x79, 0x18, 0x21, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
- 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x73,
- 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x50, 0x61,
- 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x52, 0x05, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x1a,
- 0x9e, 0x01, 0x0a, 0x06, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x12, 0x45, 0x0a, 0x0f, 0x64, 0x61,
- 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
- 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64,
- 0x65, 0x78, 0x52, 0x0d, 0x64, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65,
- 0x78, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x61, 0x74, 0x65,
- 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x61,
- 0x74, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x69, 0x65,
- 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x04, 0x52, 0x0b, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e,
- 0x63, 0x69, 0x65, 0x73, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05,
- 0x1a, 0xad, 0x01, 0x0a, 0x07, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x1c, 0x0a, 0x09,
- 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52,
- 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x41, 0x0a, 0x0d, 0x6d, 0x69,
- 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
- 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
- 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78,
- 0x52, 0x0b, 0x6d, 0x69, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x12, 0x41, 0x0a,
- 0x0d, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, 0x03,
- 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
- 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e,
- 0x64, 0x65, 0x78, 0x52, 0x0b, 0x6d, 0x61, 0x78, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65,
- 0x1a, 0x97, 0x01, 0x0a, 0x11, 0x53, 0x75, 0x62, 0x42, 0x61, 0x6e, 0x64, 0x50, 0x61, 0x72, 0x61,
- 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x69, 0x6e, 0x5f, 0x66, 0x72,
- 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d,
- 0x69, 0x6e, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x6d,
- 0x61, 0x78, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01,
- 0x28, 0x04, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79,
- 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x75, 0x74, 0x79, 0x5f, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x18, 0x03,
- 0x20, 0x01, 0x28, 0x02, 0x52, 0x09, 0x64, 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x12,
- 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, 0x65, 0x69, 0x72, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28,
- 0x02, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x45, 0x69, 0x72, 0x70, 0x1a, 0x42, 0x0a, 0x0c, 0x42, 0x61,
- 0x6e, 0x64, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x12, 0x2c, 0x0a, 0x04, 0x72, 0x61,
- 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c,
- 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61,
- 0x74, 0x65, 0x52, 0x04, 0x72, 0x61, 0x74, 0x65, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x1a, 0x6a,
- 0x0a, 0x0e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79,
- 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6b,
- 0x65, 0x79, 0x12, 0x42, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
- 0x0b, 0x32, 0x2c, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
+ 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x52, 0x06, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x12, 0x32,
+ 0x0a, 0x15, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x5f, 0x66, 0x72, 0x65, 0x71,
+ 0x75, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x18, 0x20, 0x20, 0x03, 0x28, 0x04, 0x52, 0x13, 0x70,
+ 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x69,
+ 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x6d, 0x61, 0x78, 0x5f, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b,
+ 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52,
+ 0x11, 0x6d, 0x61, 0x78, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65,
+ 0x6c, 0x73, 0x12, 0x50, 0x0a, 0x0f, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x63, 0x68, 0x61,
+ 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x74,
+ 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x42, 0x61, 0x6e,
+ 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x68, 0x61,
+ 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x0e, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x43, 0x68, 0x61, 0x6e,
+ 0x6e, 0x65, 0x6c, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x6f, 0x77, 0x6e,
+ 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x18, 0x06, 0x20,
+ 0x01, 0x28, 0x0d, 0x52, 0x13, 0x6d, 0x61, 0x78, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b,
+ 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x12, 0x54, 0x0a, 0x11, 0x64, 0x6f, 0x77, 0x6e,
+ 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x18, 0x07, 0x20,
+ 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
+ 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,
+ 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x10, 0x64, 0x6f,
+ 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x12, 0x4e,
+ 0x0a, 0x09, 0x73, 0x75, 0x62, 0x5f, 0x62, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28,
+ 0x0b, 0x32, 0x31, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
0x76, 0x33, 0x2e, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69,
- 0x6f, 0x6e, 0x2e, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x52,
- 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x74, 0x0a, 0x0d, 0x52, 0x78,
- 0x32, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x45, 0x0a, 0x0f, 0x64,
- 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01,
- 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
- 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e,
- 0x64, 0x65, 0x78, 0x52, 0x0d, 0x64, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64,
- 0x65, 0x78, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18,
- 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79,
- 0x1a, 0x7b, 0x0a, 0x09, 0x44, 0x77, 0x65, 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x34, 0x0a,
- 0x07, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a,
+ 0x6f, 0x6e, 0x2e, 0x53, 0x75, 0x62, 0x42, 0x61, 0x6e, 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65,
+ 0x74, 0x65, 0x72, 0x73, 0x52, 0x08, 0x73, 0x75, 0x62, 0x42, 0x61, 0x6e, 0x64, 0x73, 0x12, 0x4d,
+ 0x0a, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03,
+ 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
+ 0x2e, 0x76, 0x33, 0x2e, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
+ 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74,
+ 0x72, 0x79, 0x52, 0x09, 0x64, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x73, 0x12, 0x27, 0x0a,
+ 0x0f, 0x66, 0x72, 0x65, 0x71, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x69, 0x65, 0x72,
+ 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x66, 0x72, 0x65, 0x71, 0x4d, 0x75, 0x6c, 0x74,
+ 0x69, 0x70, 0x6c, 0x69, 0x65, 0x72, 0x12, 0x2c, 0x0a, 0x12, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d,
+ 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x63, 0x66, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x0b, 0x20, 0x01,
+ 0x28, 0x08, 0x52, 0x10, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x43, 0x66,
+ 0x4c, 0x69, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x0c, 0x63, 0x66, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f,
+ 0x74, 0x79, 0x70, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x74, 0x6e,
+ 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x46, 0x4c, 0x69,
+ 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x63, 0x66, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x79,
+ 0x70, 0x65, 0x12, 0x41, 0x0a, 0x0f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x5f, 0x64, 0x65,
+ 0x6c, 0x61, 0x79, 0x5f, 0x31, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f,
+ 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75,
+ 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x44,
+ 0x65, 0x6c, 0x61, 0x79, 0x31, 0x12, 0x41, 0x0a, 0x0f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65,
+ 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x32, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19,
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
- 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x75, 0x70, 0x6c, 0x69,
- 0x6e, 0x6b, 0x73, 0x12, 0x38, 0x0a, 0x09, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73,
- 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c,
- 0x75, 0x65, 0x52, 0x09, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x1a, 0x93, 0x02,
- 0x0a, 0x0f, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72,
- 0x73, 0x12, 0x62, 0x0a, 0x0c, 0x77, 0x6f, 0x72, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c,
- 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
+ 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x72, 0x65, 0x63, 0x65, 0x69,
+ 0x76, 0x65, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x32, 0x12, 0x48, 0x0a, 0x13, 0x6a, 0x6f, 0x69, 0x6e,
+ 0x5f, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x31, 0x18,
+ 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+ 0x52, 0x10, 0x6a, 0x6f, 0x69, 0x6e, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x44, 0x65, 0x6c, 0x61,
+ 0x79, 0x31, 0x12, 0x48, 0x0a, 0x13, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x70,
+ 0x74, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x32, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
+ 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x6a, 0x6f, 0x69, 0x6e,
+ 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x32, 0x12, 0x20, 0x0a, 0x0c,
+ 0x6d, 0x61, 0x78, 0x5f, 0x66, 0x63, 0x6e, 0x74, 0x5f, 0x67, 0x61, 0x70, 0x18, 0x11, 0x20, 0x01,
+ 0x28, 0x04, 0x52, 0x0a, 0x6d, 0x61, 0x78, 0x46, 0x63, 0x6e, 0x74, 0x47, 0x61, 0x70, 0x12, 0x30,
+ 0x0a, 0x14, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x5f, 0x64, 0x79, 0x6e, 0x61, 0x6d,
+ 0x69, 0x63, 0x5f, 0x61, 0x64, 0x72, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x73, 0x75,
+ 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x41, 0x64, 0x72,
+ 0x12, 0x47, 0x0a, 0x0d, 0x61, 0x64, 0x72, 0x5f, 0x61, 0x63, 0x6b, 0x5f, 0x6c, 0x69, 0x6d, 0x69,
+ 0x74, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
+ 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x44, 0x52, 0x41, 0x63, 0x6b, 0x4c,
+ 0x69, 0x6d, 0x69, 0x74, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x52, 0x0b, 0x61, 0x64,
+ 0x72, 0x41, 0x63, 0x6b, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x4f, 0x0a, 0x16, 0x6d, 0x69, 0x6e,
+ 0x5f, 0x72, 0x65, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65,
+ 0x6f, 0x75, 0x74, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
+ 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x14, 0x6d, 0x69, 0x6e, 0x52, 0x65, 0x74, 0x72, 0x61, 0x6e, 0x73,
+ 0x6d, 0x69, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x4f, 0x0a, 0x16, 0x6d, 0x61,
+ 0x78, 0x5f, 0x72, 0x65, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x74, 0x5f, 0x74, 0x69, 0x6d,
+ 0x65, 0x6f, 0x75, 0x74, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f,
+ 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x14, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x74, 0x72, 0x61, 0x6e,
+ 0x73, 0x6d, 0x69, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74,
+ 0x78, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x16, 0x20, 0x03, 0x28, 0x02, 0x52, 0x08,
+ 0x74, 0x78, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x53, 0x0a, 0x17, 0x6d, 0x61, 0x78, 0x5f,
+ 0x61, 0x64, 0x72, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e,
+ 0x64, 0x65, 0x78, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
+ 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52,
+ 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x13, 0x6d, 0x61, 0x78, 0x41, 0x64, 0x72,
+ 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x49, 0x0a,
+ 0x13, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x5f, 0x64,
+ 0x65, 0x6c, 0x61, 0x79, 0x18, 0x22, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f,
+ 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x11, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x46, 0x6f, 0x72, 0x77,
+ 0x61, 0x72, 0x64, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x49, 0x0a, 0x13, 0x72, 0x65, 0x6c, 0x61,
+ 0x79, 0x5f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x18,
+ 0x23, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+ 0x52, 0x11, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x44, 0x65,
+ 0x6c, 0x61, 0x79, 0x12, 0x3a, 0x0a, 0x1a, 0x74, 0x78, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x5f,
+ 0x73, 0x65, 0x74, 0x75, 0x70, 0x5f, 0x72, 0x65, 0x71, 0x5f, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72,
+ 0x74, 0x18, 0x18, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x74, 0x78, 0x50, 0x61, 0x72, 0x61, 0x6d,
+ 0x53, 0x65, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x12,
+ 0x28, 0x0a, 0x10, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x65,
+ 0x69, 0x72, 0x70, 0x18, 0x19, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0e, 0x64, 0x65, 0x66, 0x61, 0x75,
+ 0x6c, 0x74, 0x4d, 0x61, 0x78, 0x45, 0x69, 0x72, 0x70, 0x12, 0x63, 0x0a, 0x16, 0x64, 0x65, 0x66,
+ 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x72, 0x78, 0x32, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74,
+ 0x65, 0x72, 0x73, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
+ 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x42, 0x61, 0x6e, 0x64, 0x44,
+ 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x78, 0x32, 0x50, 0x61,
+ 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x52, 0x14, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c,
+ 0x74, 0x52, 0x78, 0x32, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x51,
+ 0x0a, 0x0f, 0x62, 0x6f, 0x6f, 0x74, 0x5f, 0x64, 0x77, 0x65, 0x6c, 0x6c, 0x5f, 0x74, 0x69, 0x6d,
+ 0x65, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x73,
- 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x50, 0x61,
- 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x57, 0x4f,
- 0x52, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x0b, 0x77, 0x6f, 0x72, 0x43, 0x68, 0x61,
- 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x1a, 0x9b, 0x01, 0x0a, 0x0f, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x57,
- 0x4f, 0x52, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x72, 0x65,
- 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x66, 0x72,
- 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x63, 0x6b, 0x5f, 0x66,
- 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c,
- 0x61, 0x63, 0x6b, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x45, 0x0a, 0x0f,
- 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18,
- 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
- 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49,
- 0x6e, 0x64, 0x65, 0x78, 0x52, 0x0d, 0x64, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e,
- 0x64, 0x65, 0x78, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x4a, 0x04, 0x08, 0x1a, 0x10, 0x1b, 0x4a,
- 0x04, 0x08, 0x1b, 0x10, 0x1c, 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, 0x4a, 0x04, 0x08, 0x1d, 0x10,
- 0x1e, 0x22, 0xba, 0x03, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x6e, 0x64, 0x73, 0x52,
- 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x0c, 0x64, 0x65, 0x73, 0x63, 0x72,
- 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e,
- 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c,
+ 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x77, 0x65, 0x6c, 0x6c, 0x54, 0x69,
+ 0x6d, 0x65, 0x52, 0x0d, 0x62, 0x6f, 0x6f, 0x74, 0x44, 0x77, 0x65, 0x6c, 0x6c, 0x54, 0x69, 0x6d,
+ 0x65, 0x12, 0x45, 0x0a, 0x05, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x21, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x2f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
+ 0x33, 0x2e, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
+ 0x6e, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72,
+ 0x73, 0x52, 0x05, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x1a, 0x9e, 0x01, 0x0a, 0x06, 0x42, 0x65, 0x61,
+ 0x63, 0x6f, 0x6e, 0x12, 0x45, 0x0a, 0x0f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65,
+ 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74,
+ 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61,
+ 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x0d, 0x64, 0x61, 0x74,
+ 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f,
+ 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x0a, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x61, 0x74, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x66,
+ 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x04,
+ 0x52, 0x0b, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x4a, 0x04, 0x08,
+ 0x03, 0x10, 0x04, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x1a, 0xad, 0x01, 0x0a, 0x07, 0x43, 0x68,
+ 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e,
+ 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65,
+ 0x6e, 0x63, 0x79, 0x12, 0x41, 0x0a, 0x0d, 0x6d, 0x69, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f,
+ 0x72, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e,
+ 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61,
+ 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x0b, 0x6d, 0x69, 0x6e, 0x44, 0x61,
+ 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x12, 0x41, 0x0a, 0x0d, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x61,
+ 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e,
+ 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44,
+ 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x0b, 0x6d, 0x61,
+ 0x78, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x1a, 0x97, 0x01, 0x0a, 0x11, 0x53, 0x75,
+ 0x62, 0x42, 0x61, 0x6e, 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12,
+ 0x23, 0x0a, 0x0d, 0x6d, 0x69, 0x6e, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d, 0x69, 0x6e, 0x46, 0x72, 0x65, 0x71, 0x75,
+ 0x65, 0x6e, 0x63, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x61, 0x78, 0x5f, 0x66, 0x72, 0x65, 0x71,
+ 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d, 0x61, 0x78,
+ 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x75, 0x74,
+ 0x79, 0x5f, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x09, 0x64,
+ 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f,
+ 0x65, 0x69, 0x72, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x02, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x45,
+ 0x69, 0x72, 0x70, 0x1a, 0x42, 0x0a, 0x0c, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x61, 0x74, 0x61, 0x52,
+ 0x61, 0x74, 0x65, 0x12, 0x2c, 0x0a, 0x04, 0x72, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
+ 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x52, 0x04, 0x72, 0x61, 0x74,
+ 0x65, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x1a, 0x6a, 0x0a, 0x0e, 0x44, 0x61, 0x74, 0x61, 0x52,
+ 0x61, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x42, 0x0a, 0x05, 0x76,
+ 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x74, 0x74, 0x6e,
+ 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x42, 0x61, 0x6e, 0x64,
+ 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x42, 0x61, 0x6e, 0x64,
+ 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a,
+ 0x02, 0x38, 0x01, 0x1a, 0x74, 0x0a, 0x0d, 0x52, 0x78, 0x32, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65,
+ 0x74, 0x65, 0x72, 0x73, 0x12, 0x45, 0x0a, 0x0f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74,
+ 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e,
+ 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44,
+ 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x0d, 0x64, 0x61,
+ 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x1c, 0x0a, 0x09, 0x66,
+ 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09,
+ 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x1a, 0x7b, 0x0a, 0x09, 0x44, 0x77, 0x65,
+ 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x34, 0x0a, 0x07, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b,
+ 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+ 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61,
+ 0x6c, 0x75, 0x65, 0x52, 0x07, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x12, 0x38, 0x0a, 0x09,
+ 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
+ 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x64, 0x6f, 0x77,
+ 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x1a, 0x93, 0x02, 0x0a, 0x0f, 0x52, 0x65, 0x6c, 0x61, 0x79,
+ 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x62, 0x0a, 0x0c, 0x77, 0x6f,
+ 0x72, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
+ 0x32, 0x3f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
+ 0x33, 0x2e, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
+ 0x6e, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72,
+ 0x73, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x57, 0x4f, 0x52, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65,
+ 0x6c, 0x52, 0x0b, 0x77, 0x6f, 0x72, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x1a, 0x9b,
+ 0x01, 0x0a, 0x0f, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x57, 0x4f, 0x52, 0x43, 0x68, 0x61, 0x6e, 0x6e,
+ 0x65, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79,
+ 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x63, 0x6b, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63,
+ 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x61, 0x63, 0x6b, 0x46, 0x72, 0x65, 0x71,
+ 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x45, 0x0a, 0x0f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61,
+ 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d,
+ 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
+ 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x0d, 0x64,
+ 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x4a, 0x04, 0x08, 0x03,
+ 0x10, 0x04, 0x4a, 0x04, 0x08, 0x1a, 0x10, 0x1b, 0x4a, 0x04, 0x08, 0x1b, 0x10, 0x1c, 0x4a, 0x04,
+ 0x08, 0x1c, 0x10, 0x1d, 0x4a, 0x04, 0x08, 0x1d, 0x10, 0x1e, 0x22, 0xba, 0x03, 0x0a, 0x11, 0x4c,
0x69, 0x73, 0x74, 0x42, 0x61, 0x6e, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
- 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74,
- 0x72, 0x79, 0x52, 0x0c, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73,
- 0x1a, 0xce, 0x01, 0x0a, 0x18, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x42, 0x61,
- 0x6e, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x58, 0x0a,
- 0x04, 0x62, 0x61, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x44, 0x2e, 0x74, 0x74,
+ 0x12, 0x57, 0x0a, 0x0c, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73,
+ 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
+ 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x6e, 0x64,
+ 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69,
+ 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x64, 0x65, 0x73,
+ 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0xce, 0x01, 0x0a, 0x18, 0x56, 0x65,
+ 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72,
+ 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x58, 0x0a, 0x04, 0x62, 0x61, 0x6e, 0x64, 0x18, 0x01,
+ 0x20, 0x03, 0x28, 0x0b, 0x32, 0x44, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
+ 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x6e, 0x64, 0x73, 0x52,
+ 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65,
+ 0x64, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,
+ 0x2e, 0x42, 0x61, 0x6e, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x62, 0x61, 0x6e, 0x64,
+ 0x1a, 0x58, 0x0a, 0x09, 0x42, 0x61, 0x6e, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a,
+ 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12,
+ 0x35, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f,
+ 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
+ 0x42, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52,
+ 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x7b, 0x0a, 0x11, 0x44, 0x65,
+ 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12,
+ 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65,
+ 0x79, 0x12, 0x50, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x3a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
+ 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x6e, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
+ 0x6e, 0x73, 0x65, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x42, 0x61, 0x6e,
+ 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x76, 0x61,
+ 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x32, 0xef, 0x03, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x66,
+ 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x93, 0x01, 0x0a, 0x12, 0x4c, 0x69,
+ 0x73, 0x74, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x50, 0x6c, 0x61, 0x6e, 0x73,
+ 0x12, 0x29, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
+ 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x50,
+ 0x6c, 0x61, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x74, 0x74,
0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73,
- 0x74, 0x42, 0x61, 0x6e, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x56,
- 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x73, 0x63,
- 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x42, 0x61, 0x6e, 0x64, 0x45, 0x6e, 0x74, 0x72,
- 0x79, 0x52, 0x04, 0x62, 0x61, 0x6e, 0x64, 0x1a, 0x58, 0x0a, 0x09, 0x42, 0x61, 0x6e, 0x64, 0x45,
- 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x35, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
- 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
- 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72,
- 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,
- 0x01, 0x1a, 0x7b, 0x0a, 0x11, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,
- 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x50, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
- 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
- 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x6e,
- 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69,
- 0x6f, 0x6e, 0x65, 0x64, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
- 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x32, 0xef,
- 0x03, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
- 0x12, 0x93, 0x01, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e,
- 0x63, 0x79, 0x50, 0x6c, 0x61, 0x6e, 0x73, 0x12, 0x29, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
- 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x72, 0x65,
- 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x50, 0x6c, 0x61, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
- 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
- 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63,
- 0x79, 0x50, 0x6c, 0x61, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26,
- 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x12, 0x1e, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75,
- 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79,
- 0x2d, 0x70, 0x6c, 0x61, 0x6e, 0x73, 0x12, 0x84, 0x01, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x50, 0x68,
- 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x25, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
+ 0x74, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x50, 0x6c, 0x61, 0x6e, 0x73, 0x52,
+ 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x12,
+ 0x1e, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f,
+ 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x2d, 0x70, 0x6c, 0x61, 0x6e, 0x73, 0x12,
+ 0x84, 0x01, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x50, 0x68, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
+ 0x6e, 0x73, 0x12, 0x25, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
+ 0x2e, 0x76, 0x33, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x68, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
+ 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x68,
- 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
- 0x1a, 0x26, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
- 0x33, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x68, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73,
- 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d,
- 0x12, 0x1b, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
- 0x2f, 0x70, 0x68, 0x79, 0x2d, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0xc0, 0x01,
- 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x6e, 0x64, 0x73, 0x12, 0x20, 0x2e, 0x74, 0x74,
- 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73,
- 0x74, 0x42, 0x61, 0x6e, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e,
- 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c,
- 0x69, 0x73, 0x74, 0x42, 0x61, 0x6e, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
- 0x22, 0x6e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x68, 0x5a, 0x20, 0x12, 0x1e, 0x2f, 0x63, 0x6f, 0x6e,
- 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x62, 0x61, 0x6e, 0x64, 0x73,
- 0x2f, 0x7b, 0x62, 0x61, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x7d, 0x5a, 0x2e, 0x12, 0x2c, 0x2f, 0x63,
- 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x62, 0x61, 0x6e,
- 0x64, 0x73, 0x2f, 0x7b, 0x62, 0x61, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x7b, 0x70, 0x68,
- 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x7d, 0x12, 0x14, 0x2f, 0x63, 0x6f, 0x6e,
- 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x62, 0x61, 0x6e, 0x64, 0x73,
- 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73,
- 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
- 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74,
- 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+ 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+ 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x63, 0x6f, 0x6e, 0x66,
+ 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x70, 0x68, 0x79, 0x2d, 0x76, 0x65,
+ 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0xc0, 0x01, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x42,
+ 0x61, 0x6e, 0x64, 0x73, 0x12, 0x20, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
+ 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x6e, 0x64, 0x73, 0x52,
+ 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
+ 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x6e, 0x64,
+ 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6e, 0x82, 0xd3, 0xe4, 0x93, 0x02,
+ 0x68, 0x5a, 0x20, 0x12, 0x1e, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x2f, 0x62, 0x61, 0x6e, 0x64, 0x73, 0x2f, 0x7b, 0x62, 0x61, 0x6e, 0x64, 0x5f,
+ 0x69, 0x64, 0x7d, 0x5a, 0x2e, 0x12, 0x2c, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x62, 0x61, 0x6e, 0x64, 0x73, 0x2f, 0x7b, 0x62, 0x61, 0x6e,
+ 0x64, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x7b, 0x70, 0x68, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69,
+ 0x6f, 0x6e, 0x7d, 0x12, 0x14, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x2f, 0x62, 0x61, 0x6e, 0x64, 0x73, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x6f, 0x2e,
+ 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72,
+ 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f,
+ 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74, 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -1616,35 +1662,37 @@ var file_ttn_lorawan_v3_configuration_services_proto_depIdxs = []int32{
23, // 14: ttn.lorawan.v3.BandDescription.min_retransmit_timeout:type_name -> google.protobuf.Duration
23, // 15: ttn.lorawan.v3.BandDescription.max_retransmit_timeout:type_name -> google.protobuf.Duration
25, // 16: ttn.lorawan.v3.BandDescription.max_adr_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
- 14, // 17: ttn.lorawan.v3.BandDescription.default_rx2_parameters:type_name -> ttn.lorawan.v3.BandDescription.Rx2Parameters
- 15, // 18: ttn.lorawan.v3.BandDescription.boot_dwell_time:type_name -> ttn.lorawan.v3.BandDescription.DwellTime
- 16, // 19: ttn.lorawan.v3.BandDescription.relay:type_name -> ttn.lorawan.v3.BandDescription.RelayParameters
- 19, // 20: ttn.lorawan.v3.ListBandsResponse.descriptions:type_name -> ttn.lorawan.v3.ListBandsResponse.DescriptionsEntry
- 21, // 21: ttn.lorawan.v3.GetPhyVersionsResponse.VersionInfo.phy_versions:type_name -> ttn.lorawan.v3.PHYVersion
- 25, // 22: ttn.lorawan.v3.BandDescription.Beacon.data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
- 25, // 23: ttn.lorawan.v3.BandDescription.Channel.min_data_rate:type_name -> ttn.lorawan.v3.DataRateIndex
- 25, // 24: ttn.lorawan.v3.BandDescription.Channel.max_data_rate:type_name -> ttn.lorawan.v3.DataRateIndex
- 26, // 25: ttn.lorawan.v3.BandDescription.BandDataRate.rate:type_name -> ttn.lorawan.v3.DataRate
- 12, // 26: ttn.lorawan.v3.BandDescription.DataRatesEntry.value:type_name -> ttn.lorawan.v3.BandDescription.BandDataRate
- 25, // 27: ttn.lorawan.v3.BandDescription.Rx2Parameters.data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
- 27, // 28: ttn.lorawan.v3.BandDescription.DwellTime.uplinks:type_name -> google.protobuf.BoolValue
- 27, // 29: ttn.lorawan.v3.BandDescription.DwellTime.downlinks:type_name -> google.protobuf.BoolValue
- 17, // 30: ttn.lorawan.v3.BandDescription.RelayParameters.wor_channels:type_name -> ttn.lorawan.v3.BandDescription.RelayParameters.RelayWORChannel
- 25, // 31: ttn.lorawan.v3.BandDescription.RelayParameters.RelayWORChannel.data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
- 20, // 32: ttn.lorawan.v3.ListBandsResponse.VersionedBandDescription.band:type_name -> ttn.lorawan.v3.ListBandsResponse.VersionedBandDescription.BandEntry
- 18, // 33: ttn.lorawan.v3.ListBandsResponse.DescriptionsEntry.value:type_name -> ttn.lorawan.v3.ListBandsResponse.VersionedBandDescription
- 6, // 34: ttn.lorawan.v3.ListBandsResponse.VersionedBandDescription.BandEntry.value:type_name -> ttn.lorawan.v3.BandDescription
- 0, // 35: ttn.lorawan.v3.Configuration.ListFrequencyPlans:input_type -> ttn.lorawan.v3.ListFrequencyPlansRequest
- 3, // 36: ttn.lorawan.v3.Configuration.GetPhyVersions:input_type -> ttn.lorawan.v3.GetPhyVersionsRequest
- 5, // 37: ttn.lorawan.v3.Configuration.ListBands:input_type -> ttn.lorawan.v3.ListBandsRequest
- 2, // 38: ttn.lorawan.v3.Configuration.ListFrequencyPlans:output_type -> ttn.lorawan.v3.ListFrequencyPlansResponse
- 4, // 39: ttn.lorawan.v3.Configuration.GetPhyVersions:output_type -> ttn.lorawan.v3.GetPhyVersionsResponse
- 7, // 40: ttn.lorawan.v3.Configuration.ListBands:output_type -> ttn.lorawan.v3.ListBandsResponse
- 38, // [38:41] is the sub-list for method output_type
- 35, // [35:38] is the sub-list for method input_type
- 35, // [35:35] is the sub-list for extension type_name
- 35, // [35:35] is the sub-list for extension extendee
- 0, // [0:35] is the sub-list for field type_name
+ 23, // 17: ttn.lorawan.v3.BandDescription.relay_forward_delay:type_name -> google.protobuf.Duration
+ 23, // 18: ttn.lorawan.v3.BandDescription.relay_receive_delay:type_name -> google.protobuf.Duration
+ 14, // 19: ttn.lorawan.v3.BandDescription.default_rx2_parameters:type_name -> ttn.lorawan.v3.BandDescription.Rx2Parameters
+ 15, // 20: ttn.lorawan.v3.BandDescription.boot_dwell_time:type_name -> ttn.lorawan.v3.BandDescription.DwellTime
+ 16, // 21: ttn.lorawan.v3.BandDescription.relay:type_name -> ttn.lorawan.v3.BandDescription.RelayParameters
+ 19, // 22: ttn.lorawan.v3.ListBandsResponse.descriptions:type_name -> ttn.lorawan.v3.ListBandsResponse.DescriptionsEntry
+ 21, // 23: ttn.lorawan.v3.GetPhyVersionsResponse.VersionInfo.phy_versions:type_name -> ttn.lorawan.v3.PHYVersion
+ 25, // 24: ttn.lorawan.v3.BandDescription.Beacon.data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
+ 25, // 25: ttn.lorawan.v3.BandDescription.Channel.min_data_rate:type_name -> ttn.lorawan.v3.DataRateIndex
+ 25, // 26: ttn.lorawan.v3.BandDescription.Channel.max_data_rate:type_name -> ttn.lorawan.v3.DataRateIndex
+ 26, // 27: ttn.lorawan.v3.BandDescription.BandDataRate.rate:type_name -> ttn.lorawan.v3.DataRate
+ 12, // 28: ttn.lorawan.v3.BandDescription.DataRatesEntry.value:type_name -> ttn.lorawan.v3.BandDescription.BandDataRate
+ 25, // 29: ttn.lorawan.v3.BandDescription.Rx2Parameters.data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
+ 27, // 30: ttn.lorawan.v3.BandDescription.DwellTime.uplinks:type_name -> google.protobuf.BoolValue
+ 27, // 31: ttn.lorawan.v3.BandDescription.DwellTime.downlinks:type_name -> google.protobuf.BoolValue
+ 17, // 32: ttn.lorawan.v3.BandDescription.RelayParameters.wor_channels:type_name -> ttn.lorawan.v3.BandDescription.RelayParameters.RelayWORChannel
+ 25, // 33: ttn.lorawan.v3.BandDescription.RelayParameters.RelayWORChannel.data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
+ 20, // 34: ttn.lorawan.v3.ListBandsResponse.VersionedBandDescription.band:type_name -> ttn.lorawan.v3.ListBandsResponse.VersionedBandDescription.BandEntry
+ 18, // 35: ttn.lorawan.v3.ListBandsResponse.DescriptionsEntry.value:type_name -> ttn.lorawan.v3.ListBandsResponse.VersionedBandDescription
+ 6, // 36: ttn.lorawan.v3.ListBandsResponse.VersionedBandDescription.BandEntry.value:type_name -> ttn.lorawan.v3.BandDescription
+ 0, // 37: ttn.lorawan.v3.Configuration.ListFrequencyPlans:input_type -> ttn.lorawan.v3.ListFrequencyPlansRequest
+ 3, // 38: ttn.lorawan.v3.Configuration.GetPhyVersions:input_type -> ttn.lorawan.v3.GetPhyVersionsRequest
+ 5, // 39: ttn.lorawan.v3.Configuration.ListBands:input_type -> ttn.lorawan.v3.ListBandsRequest
+ 2, // 40: ttn.lorawan.v3.Configuration.ListFrequencyPlans:output_type -> ttn.lorawan.v3.ListFrequencyPlansResponse
+ 4, // 41: ttn.lorawan.v3.Configuration.GetPhyVersions:output_type -> ttn.lorawan.v3.GetPhyVersionsResponse
+ 7, // 42: ttn.lorawan.v3.Configuration.ListBands:output_type -> ttn.lorawan.v3.ListBandsResponse
+ 40, // [40:43] is the sub-list for method output_type
+ 37, // [37:40] is the sub-list for method input_type
+ 37, // [37:37] is the sub-list for extension type_name
+ 37, // [37:37] is the sub-list for extension extendee
+ 0, // [0:37] is the sub-list for field type_name
}
func init() { file_ttn_lorawan_v3_configuration_services_proto_init() }
diff --git a/pkg/ttnpb/configuration_services.pb.paths.fm.go b/pkg/ttnpb/configuration_services.pb.paths.fm.go
index 95895132bb..64564273bb 100644
--- a/pkg/ttnpb/configuration_services.pb.paths.fm.go
+++ b/pkg/ttnpb/configuration_services.pb.paths.fm.go
@@ -3,13 +3,16 @@
package ttnpb
var ListFrequencyPlansRequestFieldPathsNested = []string{
+ "band_id",
"base_frequency",
}
var ListFrequencyPlansRequestFieldPathsTopLevel = []string{
+ "band_id",
"base_frequency",
}
var FrequencyPlanDescriptionFieldPathsNested = []string{
+ "band_id",
"base_frequency",
"base_id",
"id",
@@ -17,6 +20,7 @@ var FrequencyPlanDescriptionFieldPathsNested = []string{
}
var FrequencyPlanDescriptionFieldPathsTopLevel = []string{
+ "band_id",
"base_frequency",
"base_id",
"id",
@@ -84,6 +88,8 @@ var BandDescriptionFieldPathsNested = []string{
"receive_delay_2",
"relay",
"relay.wor_channels",
+ "relay_forward_delay",
+ "relay_receive_delay",
"sub_bands",
"supports_dynamic_adr",
"tx_offset",
@@ -115,6 +121,8 @@ var BandDescriptionFieldPathsTopLevel = []string{
"receive_delay_1",
"receive_delay_2",
"relay",
+ "relay_forward_delay",
+ "relay_receive_delay",
"sub_bands",
"supports_dynamic_adr",
"tx_offset",
diff --git a/pkg/ttnpb/configuration_services.pb.setters.fm.go b/pkg/ttnpb/configuration_services.pb.setters.fm.go
index 2c93fe5910..7dfacb8cd4 100644
--- a/pkg/ttnpb/configuration_services.pb.setters.fm.go
+++ b/pkg/ttnpb/configuration_services.pb.setters.fm.go
@@ -17,6 +17,16 @@ func (dst *ListFrequencyPlansRequest) SetFields(src *ListFrequencyPlansRequest,
var zero uint32
dst.BaseFrequency = zero
}
+ case "band_id":
+ if len(subs) > 0 {
+ return fmt.Errorf("'band_id' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.BandId = src.BandId
+ } else {
+ var zero string
+ dst.BandId = zero
+ }
default:
return fmt.Errorf("invalid field: '%s'", name)
@@ -68,6 +78,16 @@ func (dst *FrequencyPlanDescription) SetFields(src *FrequencyPlanDescription, pa
var zero uint32
dst.BaseFrequency = zero
}
+ case "band_id":
+ if len(subs) > 0 {
+ return fmt.Errorf("'band_id' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.BandId = src.BandId
+ } else {
+ var zero string
+ dst.BandId = zero
+ }
default:
return fmt.Errorf("invalid field: '%s'", name)
@@ -400,6 +420,24 @@ func (dst *BandDescription) SetFields(src *BandDescription, paths ...string) err
} else {
dst.MaxAdrDataRateIndex = 0
}
+ case "relay_forward_delay":
+ if len(subs) > 0 {
+ return fmt.Errorf("'relay_forward_delay' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.RelayForwardDelay = src.RelayForwardDelay
+ } else {
+ dst.RelayForwardDelay = nil
+ }
+ case "relay_receive_delay":
+ if len(subs) > 0 {
+ return fmt.Errorf("'relay_receive_delay' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.RelayReceiveDelay = src.RelayReceiveDelay
+ } else {
+ dst.RelayReceiveDelay = nil
+ }
case "tx_param_setup_req_support":
if len(subs) > 0 {
return fmt.Errorf("'tx_param_setup_req_support' has no subfields, but %s were specified", subs)
diff --git a/pkg/ttnpb/configuration_services.pb.validate.go b/pkg/ttnpb/configuration_services.pb.validate.go
index a2e2ad41ba..427ce5ba5d 100644
--- a/pkg/ttnpb/configuration_services.pb.validate.go
+++ b/pkg/ttnpb/configuration_services.pb.validate.go
@@ -49,6 +49,8 @@ func (m *ListFrequencyPlansRequest) ValidateFields(paths ...string) error {
switch name {
case "base_frequency":
// no validation rules for BaseFrequency
+ case "band_id":
+ // no validation rules for BandId
default:
return ListFrequencyPlansRequestValidationError{
field: name,
@@ -139,6 +141,8 @@ func (m *FrequencyPlanDescription) ValidateFields(paths ...string) error {
// no validation rules for Name
case "base_frequency":
// no validation rules for BaseFrequency
+ case "band_id":
+ // no validation rules for BandId
default:
return FrequencyPlanDescriptionValidationError{
field: name,
@@ -769,6 +773,30 @@ func (m *BandDescription) ValidateFields(paths ...string) error {
case "max_adr_data_rate_index":
// no validation rules for MaxAdrDataRateIndex
+ case "relay_forward_delay":
+
+ if v, ok := interface{}(m.GetRelayForwardDelay()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return BandDescriptionValidationError{
+ field: "relay_forward_delay",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "relay_receive_delay":
+
+ if v, ok := interface{}(m.GetRelayReceiveDelay()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return BandDescriptionValidationError{
+ field: "relay_receive_delay",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
case "tx_param_setup_req_support":
// no validation rules for TxParamSetupReqSupport
case "default_max_eirp":
diff --git a/pkg/ttnpb/configuration_services_flags.pb.go b/pkg/ttnpb/configuration_services_flags.pb.go
index 43a5d0f76c..e4e72481de 100644
--- a/pkg/ttnpb/configuration_services_flags.pb.go
+++ b/pkg/ttnpb/configuration_services_flags.pb.go
@@ -14,6 +14,7 @@ import (
// AddSetFlagsForListFrequencyPlansRequest adds flags to select fields in ListFrequencyPlansRequest.
func AddSetFlagsForListFrequencyPlansRequest(flags *pflag.FlagSet, prefix string, hidden bool) {
flags.AddFlag(flagsplugin.NewUint32Flag(flagsplugin.Prefix("base-frequency", prefix), "", flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewStringFlag(flagsplugin.Prefix("band-id", prefix), "", flagsplugin.WithHidden(hidden)))
}
// SetFromFlags sets the ListFrequencyPlansRequest message from flags.
@@ -24,6 +25,12 @@ func (m *ListFrequencyPlansRequest) SetFromFlags(flags *pflag.FlagSet, prefix st
m.BaseFrequency = val
paths = append(paths, flagsplugin.Prefix("base_frequency", prefix))
}
+ if val, changed, err := flagsplugin.GetString(flags, flagsplugin.Prefix("band_id", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.BandId = val
+ paths = append(paths, flagsplugin.Prefix("band_id", prefix))
+ }
return paths, nil
}
diff --git a/pkg/ttnpb/configuration_services_json.pb.go b/pkg/ttnpb/configuration_services_json.pb.go
index 22bbd70238..61586aead8 100644
--- a/pkg/ttnpb/configuration_services_json.pb.go
+++ b/pkg/ttnpb/configuration_services_json.pb.go
@@ -653,6 +653,24 @@ func (x *BandDescription) MarshalProtoJSON(s *jsonplugin.MarshalState) {
s.WriteObjectField("max_adr_data_rate_index")
x.MaxAdrDataRateIndex.MarshalProtoJSON(s)
}
+ if x.RelayForwardDelay != nil || s.HasField("relay_forward_delay") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("relay_forward_delay")
+ if x.RelayForwardDelay == nil {
+ s.WriteNil()
+ } else {
+ golang.MarshalDuration(s, x.RelayForwardDelay)
+ }
+ }
+ if x.RelayReceiveDelay != nil || s.HasField("relay_receive_delay") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("relay_receive_delay")
+ if x.RelayReceiveDelay == nil {
+ s.WriteNil()
+ } else {
+ golang.MarshalDuration(s, x.RelayReceiveDelay)
+ }
+ }
if x.TxParamSetupReqSupport || s.HasField("tx_param_setup_req_support") {
s.WriteMoreIf(&wroteField)
s.WriteObjectField("tx_param_setup_req_support")
@@ -874,6 +892,28 @@ func (x *BandDescription) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
case "max_adr_data_rate_index", "maxAdrDataRateIndex":
s.AddField("max_adr_data_rate_index")
x.MaxAdrDataRateIndex.UnmarshalProtoJSON(s)
+ case "relay_forward_delay", "relayForwardDelay":
+ s.AddField("relay_forward_delay")
+ if s.ReadNil() {
+ x.RelayForwardDelay = nil
+ return
+ }
+ v := golang.UnmarshalDuration(s)
+ if s.Err() != nil {
+ return
+ }
+ x.RelayForwardDelay = v
+ case "relay_receive_delay", "relayReceiveDelay":
+ s.AddField("relay_receive_delay")
+ if s.ReadNil() {
+ x.RelayReceiveDelay = nil
+ return
+ }
+ v := golang.UnmarshalDuration(s)
+ if s.Err() != nil {
+ return
+ }
+ x.RelayReceiveDelay = v
case "tx_param_setup_req_support", "txParamSetupReqSupport":
s.AddField("tx_param_setup_req_support")
x.TxParamSetupReqSupport = s.ReadBool()
diff --git a/pkg/ttnpb/end_device.go b/pkg/ttnpb/end_device.go
index 16b2c1d497..b1f1fe4f82 100644
--- a/pkg/ttnpb/end_device.go
+++ b/pkg/ttnpb/end_device.go
@@ -59,6 +59,222 @@ func (v *BoolValue) FieldIsZero(p string) bool {
panic(fmt.Sprintf("unknown path '%s'", p))
}
+// FieldIsZero returns whether path p is zero.
+func (v *ServedRelayParameters) FieldIsZero(p string) bool {
+ if v == nil {
+ return true
+ }
+ switch p {
+ case "backoff":
+ return v.Backoff == 0
+ case "mode":
+ return v.Mode == nil
+ case "mode.always":
+ return v.GetAlways() == nil
+ case "mode.dynamic":
+ return v.GetDynamic() == nil
+ case "mode.dynamic.smart_enable_level":
+ return v.GetDynamic().FieldIsZero("smart_enable_level")
+ case "mode.end_device_controlled":
+ return v.GetEndDeviceControlled() == nil
+ case "second_channel":
+ return v.SecondChannel == nil
+ case "second_channel.ack_offset":
+ return v.SecondChannel.FieldIsZero("ack_offset")
+ case "second_channel.data_rate_index":
+ return v.SecondChannel.FieldIsZero("data_rate_index")
+ case "second_channel.frequency":
+ return v.SecondChannel.FieldIsZero("frequency")
+ case "serving_device_id":
+ return v.ServingDeviceId == ""
+ }
+ panic(fmt.Sprintf("unknown path '%s'", p))
+}
+
+// FieldIsZero returns whether path p is zero.
+func (v *RelayForwardLimits) FieldIsZero(p string) bool {
+ if v == nil {
+ return true
+ }
+ switch p {
+ case "bucket_size":
+ return v.BucketSize == 0
+ case "reload_rate":
+ return v.ReloadRate == 0
+ }
+ panic(fmt.Sprintf("unknown path '%s'", p))
+}
+
+// FieldIsZero returns whether path p is zero.
+func (v *ServingRelayForwardingLimits) FieldIsZero(p string) bool {
+ if v == nil {
+ return true
+ }
+ switch p {
+ case "reset_behavior":
+ return v.ResetBehavior == 0
+ case "join_requests":
+ return v.JoinRequests == nil
+ case "join_requests.bucket_size":
+ return v.JoinRequests.FieldIsZero("bucket_size")
+ case "join_requests.reload_rate":
+ return v.JoinRequests.FieldIsZero("reload_rate")
+ case "notifications":
+ return v.Notifications == nil
+ case "notifications.bucket_size":
+ return v.Notifications.FieldIsZero("bucket_size")
+ case "notifications.reload_rate":
+ return v.Notifications.FieldIsZero("reload_rate")
+ case "uplink_messages":
+ return v.UplinkMessages == nil
+ case "uplink_messages.bucket_size":
+ return v.UplinkMessages.FieldIsZero("bucket_size")
+ case "uplink_messages.reload_rate":
+ return v.UplinkMessages.FieldIsZero("reload_rate")
+ case "overall":
+ return v.Overall == nil
+ case "overall.bucket_size":
+ return v.Overall.FieldIsZero("bucket_size")
+ case "overall.reload_rate":
+ return v.Overall.FieldIsZero("reload_rate")
+ }
+ panic(fmt.Sprintf("unknown path '%s'", p))
+}
+
+// FieldIsZero returns whether path p is zero.
+func (v *ServingRelayParameters) FieldIsZero(p string) bool {
+ if v == nil {
+ return true
+ }
+ switch p {
+ case "second_channel":
+ return v.SecondChannel == nil
+ case "second_channel.ack_offset":
+ return v.SecondChannel.FieldIsZero("ack_offset")
+ case "second_channel.data_rate_index":
+ return v.SecondChannel.FieldIsZero("data_rate_index")
+ case "second_channel.frequency":
+ return v.SecondChannel.FieldIsZero("frequency")
+ case "default_channel_index":
+ return v.DefaultChannelIndex == 0
+ case "cad_periodicity":
+ return v.CadPeriodicity == 0
+ case "uplink_forwarding_rules":
+ return v.UplinkForwardingRules == nil
+ case "limits":
+ return v.Limits == nil
+ case "limits.reset_behavior":
+ return v.Limits.FieldIsZero("reset_behavior")
+ case "limits.join_requests":
+ return v.Limits.FieldIsZero("join_requests")
+ case "limits.join_requests.bucket_size":
+ return v.Limits.FieldIsZero("join_requests.bucket_size")
+ case "limits.join_requests.reload_rate":
+ return v.Limits.FieldIsZero("join_requests.reload_rate")
+ case "limits.notifications":
+ return v.Limits.FieldIsZero("notifications")
+ case "limits.notifications.bucket_size":
+ return v.Limits.FieldIsZero("notifications.bucket_size")
+ case "limits.notifications.reload_rate":
+ return v.Limits.FieldIsZero("notifications.reload_rate")
+ case "limits.uplink_messages":
+ return v.Limits.FieldIsZero("uplink_messages")
+ case "limits.uplink_messages.bucket_size":
+ return v.Limits.FieldIsZero("uplink_messages.bucket_size")
+ case "limits.uplink_messages.reload_rate":
+ return v.Limits.FieldIsZero("uplink_messages.reload_rate")
+ case "limits.overall":
+ return v.Limits.FieldIsZero("overall")
+ case "limits.overall.bucket_size":
+ return v.Limits.FieldIsZero("overall.bucket_size")
+ case "limits.overall.reload_rate":
+ return v.Limits.FieldIsZero("overall.reload_rate")
+ }
+ panic(fmt.Sprintf("unknown path '%s'", p))
+}
+
+// FieldIsZero returns whether path p is zero.
+func (v *RelayParameters) FieldIsZero(p string) bool {
+ if v == nil {
+ return true
+ }
+ switch p {
+ case "mode":
+ return v.Mode == nil
+ case "mode.served":
+ return v.GetServed() == nil
+ case "mode.served.backoff":
+ return v.GetServed().FieldIsZero("backoff")
+ case "mode.served.mode":
+ return v.GetServed().FieldIsZero("mode")
+ case "mode.served.mode.always":
+ return v.GetServed().FieldIsZero("mode.always")
+ case "mode.served.mode.dynamic":
+ return v.GetServed().FieldIsZero("mode.dynamic")
+ case "mode.served.mode.dynamic.smart_enable_level":
+ return v.GetServed().FieldIsZero("mode.dynamic.smart_enable_level")
+ case "mode.served.mode.end_device_controlled":
+ return v.GetServed().FieldIsZero("mode.end_device_controlled")
+ case "mode.served.second_channel":
+ return v.GetServed().FieldIsZero("second_channel")
+ case "mode.served.second_channel.ack_offset":
+ return v.GetServed().FieldIsZero("second_channel.ack_offset")
+ case "mode.served.second_channel.data_rate_index":
+ return v.GetServed().FieldIsZero("second_channel.data_rate_index")
+ case "mode.served.second_channel.frequency":
+ return v.GetServed().FieldIsZero("second_channel.frequency")
+ case "mode.served.default_channel_index":
+ return v.GetServed().FieldIsZero("default_channel_index")
+ case "mode.served.serving_device_id":
+ return v.GetServed().FieldIsZero("serving_device_id")
+ case "mode.serving":
+ return v.GetServing() == nil
+ case "mode.serving.second_channel":
+ return v.GetServing().FieldIsZero("second_channel")
+ case "mode.serving.second_channel.ack_offset":
+ return v.GetServing().FieldIsZero("second_channel.ack_offset")
+ case "mode.serving.second_channel.data_rate_index":
+ return v.GetServing().FieldIsZero("second_channel.data_rate_index")
+ case "mode.serving.second_channel.frequency":
+ return v.GetServing().FieldIsZero("second_channel.frequency")
+ case "mode.serving.default_channel_index":
+ return v.GetServing().FieldIsZero("default_channel_index")
+ case "mode.serving.cad_periodicity":
+ return v.GetServing().FieldIsZero("cad_periodicity")
+ case "mode.serving.uplink_forwarding_rules":
+ return v.GetServing().FieldIsZero("uplink_forwarding_rules")
+ case "mode.serving.limits":
+ return v.GetServing().FieldIsZero("limits")
+ case "mode.serving.limits.reset_behavior":
+ return v.GetServing().FieldIsZero("limits.reset_behavior")
+ case "mode.serving.limits.join_requests":
+ return v.GetServing().FieldIsZero("limits.join_requests")
+ case "mode.serving.limits.join_requests.bucket_size":
+ return v.GetServing().FieldIsZero("limits.join_requests.bucket_size")
+ case "mode.serving.limits.join_requests.reload_rate":
+ return v.GetServing().FieldIsZero("limits.join_requests.reload_rate")
+ case "mode.serving.limits.notifications":
+ return v.GetServing().FieldIsZero("limits.notifications")
+ case "mode.serving.limits.notifications.bucket_size":
+ return v.GetServing().FieldIsZero("limits.notifications.bucket_size")
+ case "mode.serving.limits.notifications.reload_rate":
+ return v.GetServing().FieldIsZero("limits.notifications.reload_rate")
+ case "mode.serving.limits.uplink_messages":
+ return v.GetServing().FieldIsZero("limits.uplink_messages")
+ case "mode.serving.limits.uplink_messages.bucket_size":
+ return v.GetServing().FieldIsZero("limits.uplink_messages.bucket_size")
+ case "mode.serving.limits.uplink_messages.reload_rate":
+ return v.GetServing().FieldIsZero("limits.uplink_messages.reload_rate")
+ case "mode.serving.limits.overall":
+ return v.GetServing().FieldIsZero("limits.overall")
+ case "mode.serving.limits.overall.bucket_size":
+ return v.GetServing().FieldIsZero("limits.overall.bucket_size")
+ case "mode.serving.limits.overall.reload_rate":
+ return v.GetServing().FieldIsZero("limits.overall.reload_rate")
+ }
+ panic(fmt.Sprintf("unknown path '%s'", p))
+}
+
// FieldIsZero returns whether path p is zero.
func (v *EndDeviceAuthenticationCode) FieldIsZero(p string) bool {
if v == nil {
@@ -315,6 +531,154 @@ func (v *MACSettings) FieldIsZero(p string) bool {
return v.PingSlotPeriodicity == nil
case "ping_slot_periodicity.value":
return v.PingSlotPeriodicity.FieldIsZero("value")
+ case "relay":
+ return v.Relay == nil
+ case "relay.mode":
+ return v.Relay.FieldIsZero("mode")
+ case "relay.mode.served":
+ return v.Relay.FieldIsZero("mode.served")
+ case "relay.mode.served.backoff":
+ return v.Relay.FieldIsZero("mode.served.backoff")
+ case "relay.mode.served.mode":
+ return v.Relay.FieldIsZero("mode.served.mode")
+ case "relay.mode.served.mode.always":
+ return v.Relay.FieldIsZero("mode.served.mode.always")
+ case "relay.mode.served.mode.dynamic":
+ return v.Relay.FieldIsZero("mode.served.mode.dynamic")
+ case "relay.mode.served.mode.dynamic.smart_enable_level":
+ return v.Relay.FieldIsZero("mode.served.mode.dynamic.smart_enable_level")
+ case "relay.mode.served.mode.end_device_controlled":
+ return v.Relay.FieldIsZero("mode.served.mode.end_device_controlled")
+ case "relay.mode.served.second_channel":
+ return v.Relay.FieldIsZero("mode.served.second_channel")
+ case "relay.mode.served.second_channel.ack_offset":
+ return v.Relay.FieldIsZero("mode.served.second_channel.ack_offset")
+ case "relay.mode.served.second_channel.data_rate_index":
+ return v.Relay.FieldIsZero("mode.served.second_channel.data_rate_index")
+ case "relay.mode.served.second_channel.frequency":
+ return v.Relay.FieldIsZero("mode.served.second_channel.frequency")
+ case "relay.mode.served.default_channel_index":
+ return v.Relay.FieldIsZero("mode.served.default_channel_index")
+ case "relay.mode.served.serving_device_id":
+ return v.Relay.FieldIsZero("mode.served.serving_device_id")
+ case "relay.mode.serving":
+ return v.Relay.FieldIsZero("mode.serving")
+ case "relay.mode.serving.second_channel":
+ return v.Relay.FieldIsZero("mode.serving.second_channel")
+ case "relay.mode.serving.second_channel.ack_offset":
+ return v.Relay.FieldIsZero("mode.serving.second_channel.ack_offset")
+ case "relay.mode.serving.second_channel.data_rate_index":
+ return v.Relay.FieldIsZero("mode.serving.second_channel.data_rate_index")
+ case "relay.mode.serving.second_channel.frequency":
+ return v.Relay.FieldIsZero("mode.serving.second_channel.frequency")
+ case "relay.mode.serving.default_channel_index":
+ return v.Relay.FieldIsZero("mode.serving.default_channel_index")
+ case "relay.mode.serving.cad_periodicity":
+ return v.Relay.FieldIsZero("mode.serving.cad_periodicity")
+ case "relay.mode.serving.uplink_forwarding_rules":
+ return v.Relay.FieldIsZero("mode.serving.uplink_forwarding_rules")
+ case "relay.mode.serving.limits":
+ return v.Relay.FieldIsZero("mode.serving.limits")
+ case "relay.mode.serving.limits.reset_behavior":
+ return v.Relay.FieldIsZero("mode.serving.limits.reset_behavior")
+ case "relay.mode.serving.limits.join_requests":
+ return v.Relay.FieldIsZero("mode.serving.limits.join_requests")
+ case "relay.mode.serving.limits.join_requests.bucket_size":
+ return v.Relay.FieldIsZero("mode.serving.limits.join_requests.bucket_size")
+ case "relay.mode.serving.limits.join_requests.reload_rate":
+ return v.Relay.FieldIsZero("mode.serving.limits.join_requests.reload_rate")
+ case "relay.mode.serving.limits.notifications":
+ return v.Relay.FieldIsZero("mode.serving.limits.notifications")
+ case "relay.mode.serving.limits.notifications.bucket_size":
+ return v.Relay.FieldIsZero("mode.serving.limits.notifications.bucket_size")
+ case "relay.mode.serving.limits.notifications.reload_rate":
+ return v.Relay.FieldIsZero("mode.serving.limits.notifications.reload_rate")
+ case "relay.mode.serving.limits.uplink_messages":
+ return v.Relay.FieldIsZero("mode.serving.limits.uplink_messages")
+ case "relay.mode.serving.limits.uplink_messages.bucket_size":
+ return v.Relay.FieldIsZero("mode.serving.limits.uplink_messages.bucket_size")
+ case "relay.mode.serving.limits.uplink_messages.reload_rate":
+ return v.Relay.FieldIsZero("mode.serving.limits.uplink_messages.reload_rate")
+ case "relay.mode.serving.limits.overall":
+ return v.Relay.FieldIsZero("mode.serving.limits.overall")
+ case "relay.mode.serving.limits.overall.bucket_size":
+ return v.Relay.FieldIsZero("mode.serving.limits.overall.bucket_size")
+ case "relay.mode.serving.limits.overall.reload_rate":
+ return v.Relay.FieldIsZero("mode.serving.limits.overall.reload_rate")
+ case "desired_relay":
+ return v.DesiredRelay == nil
+ case "desired_relay.mode":
+ return v.DesiredRelay.FieldIsZero("mode")
+ case "desired_relay.mode.served":
+ return v.DesiredRelay.FieldIsZero("mode.served")
+ case "desired_relay.mode.served.backoff":
+ return v.DesiredRelay.FieldIsZero("mode.served.backoff")
+ case "desired_relay.mode.served.mode":
+ return v.DesiredRelay.FieldIsZero("mode.served.mode")
+ case "desired_relay.mode.served.mode.always":
+ return v.DesiredRelay.FieldIsZero("mode.served.mode.always")
+ case "desired_relay.mode.served.mode.dynamic":
+ return v.DesiredRelay.FieldIsZero("mode.served.mode.dynamic")
+ case "desired_relay.mode.served.mode.dynamic.smart_enable_level":
+ return v.DesiredRelay.FieldIsZero("mode.served.mode.dynamic.smart_enable_level")
+ case "desired_relay.mode.served.mode.end_device_controlled":
+ return v.DesiredRelay.FieldIsZero("mode.served.mode.end_device_controlled")
+ case "desired_relay.mode.served.second_channel":
+ return v.DesiredRelay.FieldIsZero("mode.served.second_channel")
+ case "desired_relay.mode.served.second_channel.ack_offset":
+ return v.DesiredRelay.FieldIsZero("mode.served.second_channel.ack_offset")
+ case "desired_relay.mode.served.second_channel.data_rate_index":
+ return v.DesiredRelay.FieldIsZero("mode.served.second_channel.data_rate_index")
+ case "desired_relay.mode.served.second_channel.frequency":
+ return v.DesiredRelay.FieldIsZero("mode.served.second_channel.frequency")
+ case "desired_relay.mode.served.default_channel_index":
+ return v.DesiredRelay.FieldIsZero("mode.served.default_channel_index")
+ case "desired_relay.mode.served.serving_device_id":
+ return v.DesiredRelay.FieldIsZero("mode.served.serving_device_id")
+ case "desired_relay.mode.serving":
+ return v.DesiredRelay.FieldIsZero("mode.serving")
+ case "desired_relay.mode.serving.second_channel":
+ return v.DesiredRelay.FieldIsZero("mode.serving.second_channel")
+ case "desired_relay.mode.serving.second_channel.ack_offset":
+ return v.DesiredRelay.FieldIsZero("mode.serving.second_channel.ack_offset")
+ case "desired_relay.mode.serving.second_channel.data_rate_index":
+ return v.DesiredRelay.FieldIsZero("mode.serving.second_channel.data_rate_index")
+ case "desired_relay.mode.serving.second_channel.frequency":
+ return v.DesiredRelay.FieldIsZero("mode.serving.second_channel.frequency")
+ case "desired_relay.mode.serving.default_channel_index":
+ return v.DesiredRelay.FieldIsZero("mode.serving.default_channel_index")
+ case "desired_relay.mode.serving.cad_periodicity":
+ return v.DesiredRelay.FieldIsZero("mode.serving.cad_periodicity")
+ case "desired_relay.mode.serving.uplink_forwarding_rules":
+ return v.DesiredRelay.FieldIsZero("mode.serving.uplink_forwarding_rules")
+ case "desired_relay.mode.serving.limits":
+ return v.DesiredRelay.FieldIsZero("mode.serving.limits")
+ case "desired_relay.mode.serving.limits.reset_behavior":
+ return v.DesiredRelay.FieldIsZero("mode.serving.limits.reset_behavior")
+ case "desired_relay.mode.serving.limits.join_requests":
+ return v.DesiredRelay.FieldIsZero("mode.serving.limits.join_requests")
+ case "desired_relay.mode.serving.limits.join_requests.bucket_size":
+ return v.DesiredRelay.FieldIsZero("mode.serving.limits.join_requests.bucket_size")
+ case "desired_relay.mode.serving.limits.join_requests.reload_rate":
+ return v.DesiredRelay.FieldIsZero("mode.serving.limits.join_requests.reload_rate")
+ case "desired_relay.mode.serving.limits.notifications":
+ return v.DesiredRelay.FieldIsZero("mode.serving.limits.notifications")
+ case "desired_relay.mode.serving.limits.notifications.bucket_size":
+ return v.DesiredRelay.FieldIsZero("mode.serving.limits.notifications.bucket_size")
+ case "desired_relay.mode.serving.limits.notifications.reload_rate":
+ return v.DesiredRelay.FieldIsZero("mode.serving.limits.notifications.reload_rate")
+ case "desired_relay.mode.serving.limits.uplink_messages":
+ return v.DesiredRelay.FieldIsZero("mode.serving.limits.uplink_messages")
+ case "desired_relay.mode.serving.limits.uplink_messages.bucket_size":
+ return v.DesiredRelay.FieldIsZero("mode.serving.limits.uplink_messages.bucket_size")
+ case "desired_relay.mode.serving.limits.uplink_messages.reload_rate":
+ return v.DesiredRelay.FieldIsZero("mode.serving.limits.uplink_messages.reload_rate")
+ case "desired_relay.mode.serving.limits.overall":
+ return v.DesiredRelay.FieldIsZero("mode.serving.limits.overall")
+ case "desired_relay.mode.serving.limits.overall.bucket_size":
+ return v.DesiredRelay.FieldIsZero("mode.serving.limits.overall.bucket_size")
+ case "desired_relay.mode.serving.limits.overall.reload_rate":
+ return v.DesiredRelay.FieldIsZero("mode.serving.limits.overall.reload_rate")
case "resets_f_cnt":
return v.ResetsFCnt == nil
case "resets_f_cnt.value":
@@ -411,6 +775,80 @@ func (v *MACParameters) FieldIsZero(p string) bool {
return v.RejoinCountPeriodicity == 0
case "rejoin_time_periodicity":
return v.RejoinTimePeriodicity == 0
+ case "relay":
+ return v.Relay == nil
+ case "relay.mode":
+ return v.Relay.FieldIsZero("mode")
+ case "relay.mode.served":
+ return v.Relay.FieldIsZero("mode.served")
+ case "relay.mode.served.backoff":
+ return v.Relay.FieldIsZero("mode.served.backoff")
+ case "relay.mode.served.mode":
+ return v.Relay.FieldIsZero("mode.served.mode")
+ case "relay.mode.served.mode.always":
+ return v.Relay.FieldIsZero("mode.served.mode.always")
+ case "relay.mode.served.mode.dynamic":
+ return v.Relay.FieldIsZero("mode.served.mode.dynamic")
+ case "relay.mode.served.mode.dynamic.smart_enable_level":
+ return v.Relay.FieldIsZero("mode.served.mode.dynamic.smart_enable_level")
+ case "relay.mode.served.mode.end_device_controlled":
+ return v.Relay.FieldIsZero("mode.served.mode.end_device_controlled")
+ case "relay.mode.served.second_channel":
+ return v.Relay.FieldIsZero("mode.served.second_channel")
+ case "relay.mode.served.second_channel.ack_offset":
+ return v.Relay.FieldIsZero("mode.served.second_channel.ack_offset")
+ case "relay.mode.served.second_channel.data_rate_index":
+ return v.Relay.FieldIsZero("mode.served.second_channel.data_rate_index")
+ case "relay.mode.served.second_channel.frequency":
+ return v.Relay.FieldIsZero("mode.served.second_channel.frequency")
+ case "relay.mode.served.default_channel_index":
+ return v.Relay.FieldIsZero("mode.served.default_channel_index")
+ case "relay.mode.served.serving_device_id":
+ return v.Relay.FieldIsZero("mode.served.serving_device_id")
+ case "relay.mode.serving":
+ return v.Relay.FieldIsZero("mode.serving")
+ case "relay.mode.serving.second_channel":
+ return v.Relay.FieldIsZero("mode.serving.second_channel")
+ case "relay.mode.serving.second_channel.ack_offset":
+ return v.Relay.FieldIsZero("mode.serving.second_channel.ack_offset")
+ case "relay.mode.serving.second_channel.data_rate_index":
+ return v.Relay.FieldIsZero("mode.serving.second_channel.data_rate_index")
+ case "relay.mode.serving.second_channel.frequency":
+ return v.Relay.FieldIsZero("mode.serving.second_channel.frequency")
+ case "relay.mode.serving.default_channel_index":
+ return v.Relay.FieldIsZero("mode.serving.default_channel_index")
+ case "relay.mode.serving.cad_periodicity":
+ return v.Relay.FieldIsZero("mode.serving.cad_periodicity")
+ case "relay.mode.serving.uplink_forwarding_rules":
+ return v.Relay.FieldIsZero("mode.serving.uplink_forwarding_rules")
+ case "relay.mode.serving.limits":
+ return v.Relay.FieldIsZero("mode.serving.limits")
+ case "relay.mode.serving.limits.reset_behavior":
+ return v.Relay.FieldIsZero("mode.serving.limits.reset_behavior")
+ case "relay.mode.serving.limits.join_requests":
+ return v.Relay.FieldIsZero("mode.serving.limits.join_requests")
+ case "relay.mode.serving.limits.join_requests.bucket_size":
+ return v.Relay.FieldIsZero("mode.serving.limits.join_requests.bucket_size")
+ case "relay.mode.serving.limits.join_requests.reload_rate":
+ return v.Relay.FieldIsZero("mode.serving.limits.join_requests.reload_rate")
+ case "relay.mode.serving.limits.notifications":
+ return v.Relay.FieldIsZero("mode.serving.limits.notifications")
+ case "relay.mode.serving.limits.notifications.bucket_size":
+ return v.Relay.FieldIsZero("mode.serving.limits.notifications.bucket_size")
+ case "relay.mode.serving.limits.notifications.reload_rate":
+ return v.Relay.FieldIsZero("mode.serving.limits.notifications.reload_rate")
+ case "relay.mode.serving.limits.uplink_messages":
+ return v.Relay.FieldIsZero("mode.serving.limits.uplink_messages")
+ case "relay.mode.serving.limits.uplink_messages.bucket_size":
+ return v.Relay.FieldIsZero("mode.serving.limits.uplink_messages.bucket_size")
+ case "relay.mode.serving.limits.uplink_messages.reload_rate":
+ return v.Relay.FieldIsZero("mode.serving.limits.uplink_messages.reload_rate")
+ case "relay.mode.serving.limits.overall":
+ return v.Relay.FieldIsZero("mode.serving.limits.overall")
+ case "relay.mode.serving.limits.overall.bucket_size":
+ return v.Relay.FieldIsZero("mode.serving.limits.overall.bucket_size")
+ case "relay.mode.serving.limits.overall.reload_rate":
+ return v.Relay.FieldIsZero("mode.serving.limits.overall.reload_rate")
case "rx1_data_rate_offset":
return v.Rx1DataRateOffset == 0
case "rx1_delay":
@@ -579,6 +1017,80 @@ func (v *MACState) FieldIsZero(p string) bool {
return v.CurrentParameters.FieldIsZero("rejoin_count_periodicity")
case "current_parameters.rejoin_time_periodicity":
return v.CurrentParameters.FieldIsZero("rejoin_time_periodicity")
+ case "current_parameters.relay":
+ return v.CurrentParameters.FieldIsZero("relay")
+ case "current_parameters.relay.mode":
+ return v.CurrentParameters.FieldIsZero("relay.mode")
+ case "current_parameters.relay.mode.served":
+ return v.CurrentParameters.FieldIsZero("relay.mode.served")
+ case "current_parameters.relay.mode.served.backoff":
+ return v.CurrentParameters.FieldIsZero("relay.mode.served.backoff")
+ case "current_parameters.relay.mode.served.mode":
+ return v.CurrentParameters.FieldIsZero("relay.mode.served.mode")
+ case "current_parameters.relay.mode.served.mode.always":
+ return v.CurrentParameters.FieldIsZero("relay.mode.served.mode.always")
+ case "current_parameters.relay.mode.served.mode.dynamic":
+ return v.CurrentParameters.FieldIsZero("relay.mode.served.mode.dynamic")
+ case "current_parameters.relay.mode.served.mode.dynamic.smart_enable_level":
+ return v.CurrentParameters.FieldIsZero("relay.mode.served.mode.dynamic.smart_enable_level")
+ case "current_parameters.relay.mode.served.mode.end_device_controlled":
+ return v.CurrentParameters.FieldIsZero("relay.mode.served.mode.end_device_controlled")
+ case "current_parameters.relay.mode.served.second_channel":
+ return v.CurrentParameters.FieldIsZero("relay.mode.served.second_channel")
+ case "current_parameters.relay.mode.served.second_channel.ack_offset":
+ return v.CurrentParameters.FieldIsZero("relay.mode.served.second_channel.ack_offset")
+ case "current_parameters.relay.mode.served.second_channel.data_rate_index":
+ return v.CurrentParameters.FieldIsZero("relay.mode.served.second_channel.data_rate_index")
+ case "current_parameters.relay.mode.served.second_channel.frequency":
+ return v.CurrentParameters.FieldIsZero("relay.mode.served.second_channel.frequency")
+ case "current_parameters.relay.mode.served.default_channel_index":
+ return v.CurrentParameters.FieldIsZero("relay.mode.served.default_channel_index")
+ case "current_parameters.relay.mode.served.serving_device_id":
+ return v.CurrentParameters.FieldIsZero("relay.mode.served.serving_device_id")
+ case "current_parameters.relay.mode.serving":
+ return v.CurrentParameters.FieldIsZero("relay.mode.serving")
+ case "current_parameters.relay.mode.serving.second_channel":
+ return v.CurrentParameters.FieldIsZero("relay.mode.serving.second_channel")
+ case "current_parameters.relay.mode.serving.second_channel.ack_offset":
+ return v.CurrentParameters.FieldIsZero("relay.mode.serving.second_channel.ack_offset")
+ case "current_parameters.relay.mode.serving.second_channel.data_rate_index":
+ return v.CurrentParameters.FieldIsZero("relay.mode.serving.second_channel.data_rate_index")
+ case "current_parameters.relay.mode.serving.second_channel.frequency":
+ return v.CurrentParameters.FieldIsZero("relay.mode.serving.second_channel.frequency")
+ case "current_parameters.relay.mode.serving.default_channel_index":
+ return v.CurrentParameters.FieldIsZero("relay.mode.serving.default_channel_index")
+ case "current_parameters.relay.mode.serving.cad_periodicity":
+ return v.CurrentParameters.FieldIsZero("relay.mode.serving.cad_periodicity")
+ case "current_parameters.relay.mode.serving.uplink_forwarding_rules":
+ return v.CurrentParameters.FieldIsZero("relay.mode.serving.uplink_forwarding_rules")
+ case "current_parameters.relay.mode.serving.limits":
+ return v.CurrentParameters.FieldIsZero("relay.mode.serving.limits")
+ case "current_parameters.relay.mode.serving.limits.reset_behavior":
+ return v.CurrentParameters.FieldIsZero("relay.mode.serving.limits.reset_behavior")
+ case "current_parameters.relay.mode.serving.limits.join_requests":
+ return v.CurrentParameters.FieldIsZero("relay.mode.serving.limits.join_requests")
+ case "current_parameters.relay.mode.serving.limits.join_requests.bucket_size":
+ return v.CurrentParameters.FieldIsZero("relay.mode.serving.limits.join_requests.bucket_size")
+ case "current_parameters.relay.mode.serving.limits.join_requests.reload_rate":
+ return v.CurrentParameters.FieldIsZero("relay.mode.serving.limits.join_requests.reload_rate")
+ case "current_parameters.relay.mode.serving.limits.notifications":
+ return v.CurrentParameters.FieldIsZero("relay.mode.serving.limits.notifications")
+ case "current_parameters.relay.mode.serving.limits.notifications.bucket_size":
+ return v.CurrentParameters.FieldIsZero("relay.mode.serving.limits.notifications.bucket_size")
+ case "current_parameters.relay.mode.serving.limits.notifications.reload_rate":
+ return v.CurrentParameters.FieldIsZero("relay.mode.serving.limits.notifications.reload_rate")
+ case "current_parameters.relay.mode.serving.limits.uplink_messages":
+ return v.CurrentParameters.FieldIsZero("relay.mode.serving.limits.uplink_messages")
+ case "current_parameters.relay.mode.serving.limits.uplink_messages.bucket_size":
+ return v.CurrentParameters.FieldIsZero("relay.mode.serving.limits.uplink_messages.bucket_size")
+ case "current_parameters.relay.mode.serving.limits.uplink_messages.reload_rate":
+ return v.CurrentParameters.FieldIsZero("relay.mode.serving.limits.uplink_messages.reload_rate")
+ case "current_parameters.relay.mode.serving.limits.overall":
+ return v.CurrentParameters.FieldIsZero("relay.mode.serving.limits.overall")
+ case "current_parameters.relay.mode.serving.limits.overall.bucket_size":
+ return v.CurrentParameters.FieldIsZero("relay.mode.serving.limits.overall.bucket_size")
+ case "current_parameters.relay.mode.serving.limits.overall.reload_rate":
+ return v.CurrentParameters.FieldIsZero("relay.mode.serving.limits.overall.reload_rate")
case "current_parameters.rx1_data_rate_offset":
return v.CurrentParameters.FieldIsZero("rx1_data_rate_offset")
case "current_parameters.rx1_delay":
@@ -635,6 +1147,80 @@ func (v *MACState) FieldIsZero(p string) bool {
return v.DesiredParameters.FieldIsZero("rejoin_count_periodicity")
case "desired_parameters.rejoin_time_periodicity":
return v.DesiredParameters.FieldIsZero("rejoin_time_periodicity")
+ case "desired_parameters.relay":
+ return v.DesiredParameters.FieldIsZero("relay")
+ case "desired_parameters.relay.mode":
+ return v.DesiredParameters.FieldIsZero("relay.mode")
+ case "desired_parameters.relay.mode.served":
+ return v.DesiredParameters.FieldIsZero("relay.mode.served")
+ case "desired_parameters.relay.mode.served.backoff":
+ return v.DesiredParameters.FieldIsZero("relay.mode.served.backoff")
+ case "desired_parameters.relay.mode.served.mode":
+ return v.DesiredParameters.FieldIsZero("relay.mode.served.mode")
+ case "desired_parameters.relay.mode.served.mode.always":
+ return v.DesiredParameters.FieldIsZero("relay.mode.served.mode.always")
+ case "desired_parameters.relay.mode.served.mode.dynamic":
+ return v.DesiredParameters.FieldIsZero("relay.mode.served.mode.dynamic")
+ case "desired_parameters.relay.mode.served.mode.dynamic.smart_enable_level":
+ return v.DesiredParameters.FieldIsZero("relay.mode.served.mode.dynamic.smart_enable_level")
+ case "desired_parameters.relay.mode.served.mode.end_device_controlled":
+ return v.DesiredParameters.FieldIsZero("relay.mode.served.mode.end_device_controlled")
+ case "desired_parameters.relay.mode.served.second_channel":
+ return v.DesiredParameters.FieldIsZero("relay.mode.served.second_channel")
+ case "desired_parameters.relay.mode.served.second_channel.ack_offset":
+ return v.DesiredParameters.FieldIsZero("relay.mode.served.second_channel.ack_offset")
+ case "desired_parameters.relay.mode.served.second_channel.data_rate_index":
+ return v.DesiredParameters.FieldIsZero("relay.mode.served.second_channel.data_rate_index")
+ case "desired_parameters.relay.mode.served.second_channel.frequency":
+ return v.DesiredParameters.FieldIsZero("relay.mode.served.second_channel.frequency")
+ case "desired_parameters.relay.mode.served.default_channel_index":
+ return v.DesiredParameters.FieldIsZero("relay.mode.served.default_channel_index")
+ case "desired_parameters.relay.mode.served.serving_device_id":
+ return v.DesiredParameters.FieldIsZero("relay.mode.served.serving_device_id")
+ case "desired_parameters.relay.mode.serving":
+ return v.DesiredParameters.FieldIsZero("relay.mode.serving")
+ case "desired_parameters.relay.mode.serving.second_channel":
+ return v.DesiredParameters.FieldIsZero("relay.mode.serving.second_channel")
+ case "desired_parameters.relay.mode.serving.second_channel.ack_offset":
+ return v.DesiredParameters.FieldIsZero("relay.mode.serving.second_channel.ack_offset")
+ case "desired_parameters.relay.mode.serving.second_channel.data_rate_index":
+ return v.DesiredParameters.FieldIsZero("relay.mode.serving.second_channel.data_rate_index")
+ case "desired_parameters.relay.mode.serving.second_channel.frequency":
+ return v.DesiredParameters.FieldIsZero("relay.mode.serving.second_channel.frequency")
+ case "desired_parameters.relay.mode.serving.default_channel_index":
+ return v.DesiredParameters.FieldIsZero("relay.mode.serving.default_channel_index")
+ case "desired_parameters.relay.mode.serving.cad_periodicity":
+ return v.DesiredParameters.FieldIsZero("relay.mode.serving.cad_periodicity")
+ case "desired_parameters.relay.mode.serving.uplink_forwarding_rules":
+ return v.DesiredParameters.FieldIsZero("relay.mode.serving.uplink_forwarding_rules")
+ case "desired_parameters.relay.mode.serving.limits":
+ return v.DesiredParameters.FieldIsZero("relay.mode.serving.limits")
+ case "desired_parameters.relay.mode.serving.limits.reset_behavior":
+ return v.DesiredParameters.FieldIsZero("relay.mode.serving.limits.reset_behavior")
+ case "desired_parameters.relay.mode.serving.limits.join_requests":
+ return v.DesiredParameters.FieldIsZero("relay.mode.serving.limits.join_requests")
+ case "desired_parameters.relay.mode.serving.limits.join_requests.bucket_size":
+ return v.DesiredParameters.FieldIsZero("relay.mode.serving.limits.join_requests.bucket_size")
+ case "desired_parameters.relay.mode.serving.limits.join_requests.reload_rate":
+ return v.DesiredParameters.FieldIsZero("relay.mode.serving.limits.join_requests.reload_rate")
+ case "desired_parameters.relay.mode.serving.limits.notifications":
+ return v.DesiredParameters.FieldIsZero("relay.mode.serving.limits.notifications")
+ case "desired_parameters.relay.mode.serving.limits.notifications.bucket_size":
+ return v.DesiredParameters.FieldIsZero("relay.mode.serving.limits.notifications.bucket_size")
+ case "desired_parameters.relay.mode.serving.limits.notifications.reload_rate":
+ return v.DesiredParameters.FieldIsZero("relay.mode.serving.limits.notifications.reload_rate")
+ case "desired_parameters.relay.mode.serving.limits.uplink_messages":
+ return v.DesiredParameters.FieldIsZero("relay.mode.serving.limits.uplink_messages")
+ case "desired_parameters.relay.mode.serving.limits.uplink_messages.bucket_size":
+ return v.DesiredParameters.FieldIsZero("relay.mode.serving.limits.uplink_messages.bucket_size")
+ case "desired_parameters.relay.mode.serving.limits.uplink_messages.reload_rate":
+ return v.DesiredParameters.FieldIsZero("relay.mode.serving.limits.uplink_messages.reload_rate")
+ case "desired_parameters.relay.mode.serving.limits.overall":
+ return v.DesiredParameters.FieldIsZero("relay.mode.serving.limits.overall")
+ case "desired_parameters.relay.mode.serving.limits.overall.bucket_size":
+ return v.DesiredParameters.FieldIsZero("relay.mode.serving.limits.overall.bucket_size")
+ case "desired_parameters.relay.mode.serving.limits.overall.reload_rate":
+ return v.DesiredParameters.FieldIsZero("relay.mode.serving.limits.overall.reload_rate")
case "desired_parameters.rx1_data_rate_offset":
return v.DesiredParameters.FieldIsZero("rx1_data_rate_offset")
case "desired_parameters.rx1_delay":
@@ -815,6 +1401,10 @@ func (v *MACState) FieldIsZero(p string) bool {
return v.PendingJoinRequest.FieldIsZero("rx_delay")
case "pending_join_request.selected_mac_version":
return v.PendingJoinRequest.FieldIsZero("selected_mac_version")
+ case "pending_relay_downlink":
+ return v.PendingRelayDownlink == nil
+ case "pending_relay_downlink.raw_payload":
+ return v.PendingRelayDownlink.FieldIsZero("raw_payload")
case "pending_requests":
return v.PendingRequests == nil
case "ping_slot_periodicity":
@@ -1199,6 +1789,150 @@ func (v *EndDevice) FieldIsZero(p string) bool {
return v.MacSettings.FieldIsZero("ping_slot_periodicity")
case "mac_settings.ping_slot_periodicity.value":
return v.MacSettings.FieldIsZero("ping_slot_periodicity.value")
+ case "mac_settings.relay":
+ return v.MacSettings.FieldIsZero("relay")
+ case "mac_settings.relay.mode":
+ return v.MacSettings.FieldIsZero("relay.mode")
+ case "mac_settings.relay.mode.served":
+ return v.MacSettings.FieldIsZero("relay.mode.served")
+ case "mac_settings.relay.mode.served.backoff":
+ return v.MacSettings.FieldIsZero("relay.mode.served.backoff")
+ case "mac_settings.relay.mode.served.mode":
+ return v.MacSettings.FieldIsZero("relay.mode.served.mode")
+ case "mac_settings.relay.mode.served.mode.always":
+ return v.MacSettings.FieldIsZero("relay.mode.served.mode.always")
+ case "mac_settings.relay.mode.served.mode.dynamic":
+ return v.MacSettings.FieldIsZero("relay.mode.served.mode.dynamic")
+ case "mac_settings.relay.mode.served.mode.dynamic.smart_enable_level":
+ return v.MacSettings.FieldIsZero("relay.mode.served.mode.dynamic.smart_enable_level")
+ case "mac_settings.relay.mode.served.mode.end_device_controlled":
+ return v.MacSettings.FieldIsZero("relay.mode.served.mode.end_device_controlled")
+ case "mac_settings.relay.mode.served.second_channel":
+ return v.MacSettings.FieldIsZero("relay.mode.served.second_channel")
+ case "mac_settings.relay.mode.served.second_channel.ack_offset":
+ return v.MacSettings.FieldIsZero("relay.mode.served.second_channel.ack_offset")
+ case "mac_settings.relay.mode.served.second_channel.data_rate_index":
+ return v.MacSettings.FieldIsZero("relay.mode.served.second_channel.data_rate_index")
+ case "mac_settings.relay.mode.served.second_channel.frequency":
+ return v.MacSettings.FieldIsZero("relay.mode.served.second_channel.frequency")
+ case "mac_settings.relay.mode.served.serving_device_id":
+ return v.MacSettings.FieldIsZero("relay.mode.served.serving_device_id")
+ case "mac_settings.relay.mode.serving":
+ return v.MacSettings.FieldIsZero("relay.mode.serving")
+ case "mac_settings.relay.mode.serving.second_channel":
+ return v.MacSettings.FieldIsZero("relay.mode.serving.second_channel")
+ case "mac_settings.relay.mode.serving.second_channel.ack_offset":
+ return v.MacSettings.FieldIsZero("relay.mode.serving.second_channel.ack_offset")
+ case "mac_settings.relay.mode.serving.second_channel.data_rate_index":
+ return v.MacSettings.FieldIsZero("relay.mode.serving.second_channel.data_rate_index")
+ case "mac_settings.relay.mode.serving.second_channel.frequency":
+ return v.MacSettings.FieldIsZero("relay.mode.serving.second_channel.frequency")
+ case "mac_settings.relay.mode.serving.default_channel_index":
+ return v.MacSettings.FieldIsZero("relay.mode.serving.default_channel_index")
+ case "mac_settings.relay.mode.serving.cad_periodicity":
+ return v.MacSettings.FieldIsZero("relay.mode.serving.cad_periodicity")
+ case "mac_settings.relay.mode.serving.uplink_forwarding_rules":
+ return v.MacSettings.FieldIsZero("relay.mode.serving.uplink_forwarding_rules")
+ case "mac_settings.relay.mode.serving.limits":
+ return v.MacSettings.FieldIsZero("relay.mode.serving.limits")
+ case "mac_settings.relay.mode.serving.limits.reset_behavior":
+ return v.MacSettings.FieldIsZero("relay.mode.serving.limits.reset_behavior")
+ case "mac_settings.relay.mode.serving.limits.join_requests":
+ return v.MacSettings.FieldIsZero("relay.mode.serving.limits.join_requests")
+ case "mac_settings.relay.mode.serving.limits.join_requests.bucket_size":
+ return v.MacSettings.FieldIsZero("relay.mode.serving.limits.join_requests.bucket_size")
+ case "mac_settings.relay.mode.serving.limits.join_requests.reload_rate":
+ return v.MacSettings.FieldIsZero("relay.mode.serving.limits.join_requests.reload_rate")
+ case "mac_settings.relay.mode.serving.limits.notifications":
+ return v.MacSettings.FieldIsZero("relay.mode.serving.limits.notifications")
+ case "mac_settings.relay.mode.serving.limits.notifications.bucket_size":
+ return v.MacSettings.FieldIsZero("relay.mode.serving.limits.notifications.bucket_size")
+ case "mac_settings.relay.mode.serving.limits.notifications.reload_rate":
+ return v.MacSettings.FieldIsZero("relay.mode.serving.limits.notifications.reload_rate")
+ case "mac_settings.relay.mode.serving.limits.uplink_messages":
+ return v.MacSettings.FieldIsZero("relay.mode.serving.limits.uplink_messages")
+ case "mac_settings.relay.mode.serving.limits.uplink_messages.bucket_size":
+ return v.MacSettings.FieldIsZero("relay.mode.serving.limits.uplink_messages.bucket_size")
+ case "mac_settings.relay.mode.serving.limits.uplink_messages.reload_rate":
+ return v.MacSettings.FieldIsZero("relay.mode.serving.limits.uplink_messages.reload_rate")
+ case "mac_settings.relay.mode.serving.limits.overall":
+ return v.MacSettings.FieldIsZero("relay.mode.serving.limits.overall")
+ case "mac_settings.relay.mode.serving.limits.overall.bucket_size":
+ return v.MacSettings.FieldIsZero("relay.mode.serving.limits.overall.bucket_size")
+ case "mac_settings.relay.mode.serving.limits.overall.reload_rate":
+ return v.MacSettings.FieldIsZero("relay.mode.serving.limits.overall.reload_rate")
+ case "mac_settings.desired_relay":
+ return v.MacSettings.FieldIsZero("desired_relay")
+ case "mac_settings.desired_relay.mode":
+ return v.MacSettings.FieldIsZero("desired_relay.mode")
+ case "mac_settings.desired_relay.mode.served":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.served")
+ case "mac_settings.desired_relay.mode.served.backoff":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.served.backoff")
+ case "mac_settings.desired_relay.mode.served.mode":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.served.mode")
+ case "mac_settings.desired_relay.mode.served.mode.always":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.served.mode.always")
+ case "mac_settings.desired_relay.mode.served.mode.dynamic":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.served.mode.dynamic")
+ case "mac_settings.desired_relay.mode.served.mode.dynamic.smart_enable_level":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.served.mode.dynamic.smart_enable_level")
+ case "mac_settings.desired_relay.mode.served.mode.end_device_controlled":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.served.mode.end_device_controlled")
+ case "mac_settings.desired_relay.mode.served.second_channel":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.served.second_channel")
+ case "mac_settings.desired_relay.mode.served.second_channel.ack_offset":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.served.second_channel.ack_offset")
+ case "mac_settings.desired_relay.mode.served.second_channel.data_rate_index":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.served.second_channel.data_rate_index")
+ case "mac_settings.desired_relay.mode.served.second_channel.frequency":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.served.second_channel.frequency")
+ case "mac_settings.desired_relay.mode.served.serving_device_id":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.served.serving_device_id")
+ case "mac_settings.desired_relay.mode.serving":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.serving")
+ case "mac_settings.desired_relay.mode.serving.second_channel":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.serving.second_channel")
+ case "mac_settings.desired_relay.mode.serving.second_channel.ack_offset":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.serving.second_channel.ack_offset")
+ case "mac_settings.desired_relay.mode.serving.second_channel.data_rate_index":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.serving.second_channel.data_rate_index")
+ case "mac_settings.desired_relay.mode.serving.second_channel.frequency":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.serving.second_channel.frequency")
+ case "mac_settings.desired_relay.mode.serving.default_channel_index":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.serving.default_channel_index")
+ case "mac_settings.desired_relay.mode.serving.cad_periodicity":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.serving.cad_periodicity")
+ case "mac_settings.desired_relay.mode.serving.uplink_forwarding_rules":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.serving.uplink_forwarding_rules")
+ case "mac_settings.desired_relay.mode.serving.limits":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.serving.limits")
+ case "mac_settings.desired_relay.mode.serving.limits.reset_behavior":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.serving.limits.reset_behavior")
+ case "mac_settings.desired_relay.mode.serving.limits.join_requests":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.serving.limits.join_requests")
+ case "mac_settings.desired_relay.mode.serving.limits.join_requests.bucket_size":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.serving.limits.join_requests.bucket_size")
+ case "mac_settings.desired_relay.mode.serving.limits.join_requests.reload_rate":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.serving.limits.join_requests.reload_rate")
+ case "mac_settings.desired_relay.mode.serving.limits.notifications":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.serving.limits.notifications")
+ case "mac_settings.desired_relay.mode.serving.limits.notifications.bucket_size":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.serving.limits.notifications.bucket_size")
+ case "mac_settings.desired_relay.mode.serving.limits.notifications.reload_rate":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.serving.limits.notifications.reload_rate")
+ case "mac_settings.desired_relay.mode.serving.limits.uplink_messages":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.serving.limits.uplink_messages")
+ case "mac_settings.desired_relay.mode.serving.limits.uplink_messages.bucket_size":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.serving.limits.uplink_messages.bucket_size")
+ case "mac_settings.desired_relay.mode.serving.limits.uplink_messages.reload_rate":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.serving.limits.uplink_messages.reload_rate")
+ case "mac_settings.desired_relay.mode.serving.limits.overall":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.serving.limits.overall")
+ case "mac_settings.desired_relay.mode.serving.limits.overall.bucket_size":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.serving.limits.overall.bucket_size")
+ case "mac_settings.desired_relay.mode.serving.limits.overall.reload_rate":
+ return v.MacSettings.FieldIsZero("desired_relay.mode.serving.limits.overall.reload_rate")
case "mac_settings.resets_f_cnt":
return v.MacSettings.FieldIsZero("resets_f_cnt")
case "mac_settings.resets_f_cnt.value":
diff --git a/pkg/ttnpb/end_device.pb.go b/pkg/ttnpb/end_device.pb.go
index ce9dffa44e..587dd02e6f 100644
--- a/pkg/ttnpb/end_device.pb.go
+++ b/pkg/ttnpb/end_device.pb.go
@@ -251,6 +251,466 @@ func (x *BoolValue) GetValue() bool {
return false
}
+type ServingRelayForwardingLimits struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // Reset behavior of the buckets upon limit update.
+ ResetBehavior RelayResetLimitCounter `protobuf:"varint,1,opt,name=reset_behavior,json=resetBehavior,proto3,enum=ttn.lorawan.v3.RelayResetLimitCounter" json:"reset_behavior,omitempty"`
+ // Bucket configuration for join requests.
+ // If unset, no individual limits will apply to join requests, but the relay overall limitations will apply.
+ JoinRequests *RelayForwardLimits `protobuf:"bytes,2,opt,name=join_requests,json=joinRequests,proto3" json:"join_requests,omitempty"`
+ // Bucket configuration for unknown device notifications.
+ // If unset, no individual limits will apply to unknown end device notifications, but the relay overall
+ // limitations will still apply.
+ Notifications *RelayForwardLimits `protobuf:"bytes,3,opt,name=notifications,proto3" json:"notifications,omitempty"`
+ // Bucket configuration for uplink messages across all served end devices.
+ // If unset, no individual limits will apply to uplink messages across all served end devices, but the relay
+ // overall limitations will still apply.
+ UplinkMessages *RelayForwardLimits `protobuf:"bytes,4,opt,name=uplink_messages,json=uplinkMessages,proto3" json:"uplink_messages,omitempty"`
+ // Bucket configuration for all relay messages.
+ // If unset, no overall limits will apply to the relay, but individual limitations will still apply.
+ Overall *RelayForwardLimits `protobuf:"bytes,5,opt,name=overall,proto3" json:"overall,omitempty"`
+}
+
+func (x *ServingRelayForwardingLimits) Reset() {
+ *x = ServingRelayForwardingLimits{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[2]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ServingRelayForwardingLimits) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ServingRelayForwardingLimits) ProtoMessage() {}
+
+func (x *ServingRelayForwardingLimits) ProtoReflect() protoreflect.Message {
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[2]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ServingRelayForwardingLimits.ProtoReflect.Descriptor instead.
+func (*ServingRelayForwardingLimits) Descriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *ServingRelayForwardingLimits) GetResetBehavior() RelayResetLimitCounter {
+ if x != nil {
+ return x.ResetBehavior
+ }
+ return RelayResetLimitCounter_RELAY_RESET_LIMIT_COUNTER_ZERO
+}
+
+func (x *ServingRelayForwardingLimits) GetJoinRequests() *RelayForwardLimits {
+ if x != nil {
+ return x.JoinRequests
+ }
+ return nil
+}
+
+func (x *ServingRelayForwardingLimits) GetNotifications() *RelayForwardLimits {
+ if x != nil {
+ return x.Notifications
+ }
+ return nil
+}
+
+func (x *ServingRelayForwardingLimits) GetUplinkMessages() *RelayForwardLimits {
+ if x != nil {
+ return x.UplinkMessages
+ }
+ return nil
+}
+
+func (x *ServingRelayForwardingLimits) GetOverall() *RelayForwardLimits {
+ if x != nil {
+ return x.Overall
+ }
+ return nil
+}
+
+type RelayUplinkForwardingRule struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // Bucket configuration for the served end device.
+ // If unset, no individual limits will apply to the end device, but the relay global limitations will apply.
+ Limits *RelayUplinkForwardLimits `protobuf:"bytes,1,opt,name=limits,proto3" json:"limits,omitempty"`
+ // Last wake on radio frame counter used by the served end device.
+ LastWFCnt uint32 `protobuf:"varint,2,opt,name=last_w_f_cnt,json=lastWFCnt,proto3" json:"last_w_f_cnt,omitempty"`
+ // End device identifier of the served end device.
+ DeviceId string `protobuf:"bytes,3,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"`
+ // Session key ID of the session keys used to derive the root relay session key.
+ SessionKeyId []byte `protobuf:"bytes,4,opt,name=session_key_id,json=sessionKeyId,proto3" json:"session_key_id,omitempty"`
+}
+
+func (x *RelayUplinkForwardingRule) Reset() {
+ *x = RelayUplinkForwardingRule{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[3]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *RelayUplinkForwardingRule) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RelayUplinkForwardingRule) ProtoMessage() {}
+
+func (x *RelayUplinkForwardingRule) ProtoReflect() protoreflect.Message {
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[3]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use RelayUplinkForwardingRule.ProtoReflect.Descriptor instead.
+func (*RelayUplinkForwardingRule) Descriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *RelayUplinkForwardingRule) GetLimits() *RelayUplinkForwardLimits {
+ if x != nil {
+ return x.Limits
+ }
+ return nil
+}
+
+func (x *RelayUplinkForwardingRule) GetLastWFCnt() uint32 {
+ if x != nil {
+ return x.LastWFCnt
+ }
+ return 0
+}
+
+func (x *RelayUplinkForwardingRule) GetDeviceId() string {
+ if x != nil {
+ return x.DeviceId
+ }
+ return ""
+}
+
+func (x *RelayUplinkForwardingRule) GetSessionKeyId() []byte {
+ if x != nil {
+ return x.SessionKeyId
+ }
+ return nil
+}
+
+type ServingRelayParameters struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // Second wake on radio channel configuration.
+ SecondChannel *RelaySecondChannel `protobuf:"bytes,1,opt,name=second_channel,json=secondChannel,proto3" json:"second_channel,omitempty"`
+ // Index of the default wake on radio channel.
+ DefaultChannelIndex uint32 `protobuf:"varint,2,opt,name=default_channel_index,json=defaultChannelIndex,proto3" json:"default_channel_index,omitempty"`
+ // Channel activity detection periodicity.
+ CadPeriodicity RelayCADPeriodicity `protobuf:"varint,3,opt,name=cad_periodicity,json=cadPeriodicity,proto3,enum=ttn.lorawan.v3.RelayCADPeriodicity" json:"cad_periodicity,omitempty"`
+ // Configured uplink forwarding rules.
+ UplinkForwardingRules []*RelayUplinkForwardingRule `protobuf:"bytes,4,rep,name=uplink_forwarding_rules,json=uplinkForwardingRules,proto3" json:"uplink_forwarding_rules,omitempty"`
+ // Configured forwarding limits.
+ // If unset, the default value from Network Server configuration will be used.
+ Limits *ServingRelayForwardingLimits `protobuf:"bytes,5,opt,name=limits,proto3" json:"limits,omitempty"`
+}
+
+func (x *ServingRelayParameters) Reset() {
+ *x = ServingRelayParameters{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[4]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ServingRelayParameters) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ServingRelayParameters) ProtoMessage() {}
+
+func (x *ServingRelayParameters) ProtoReflect() protoreflect.Message {
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[4]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ServingRelayParameters.ProtoReflect.Descriptor instead.
+func (*ServingRelayParameters) Descriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *ServingRelayParameters) GetSecondChannel() *RelaySecondChannel {
+ if x != nil {
+ return x.SecondChannel
+ }
+ return nil
+}
+
+func (x *ServingRelayParameters) GetDefaultChannelIndex() uint32 {
+ if x != nil {
+ return x.DefaultChannelIndex
+ }
+ return 0
+}
+
+func (x *ServingRelayParameters) GetCadPeriodicity() RelayCADPeriodicity {
+ if x != nil {
+ return x.CadPeriodicity
+ }
+ return RelayCADPeriodicity_RELAY_CAD_PERIODICITY_1_SECOND
+}
+
+func (x *ServingRelayParameters) GetUplinkForwardingRules() []*RelayUplinkForwardingRule {
+ if x != nil {
+ return x.UplinkForwardingRules
+ }
+ return nil
+}
+
+func (x *ServingRelayParameters) GetLimits() *ServingRelayForwardingLimits {
+ if x != nil {
+ return x.Limits
+ }
+ return nil
+}
+
+type ServedRelayParameters struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // Types that are assignable to Mode:
+ // *ServedRelayParameters_Always
+ // *ServedRelayParameters_Dynamic
+ // *ServedRelayParameters_EndDeviceControlled
+ Mode isServedRelayParameters_Mode `protobuf_oneof:"mode"`
+ // Number of uplinks to be sent without a wake on radio frame.
+ Backoff uint32 `protobuf:"varint,4,opt,name=backoff,proto3" json:"backoff,omitempty"`
+ // Second wake on radio channel configuration.
+ SecondChannel *RelaySecondChannel `protobuf:"bytes,5,opt,name=second_channel,json=secondChannel,proto3" json:"second_channel,omitempty"`
+ // End device identifier of the serving end device.
+ ServingDeviceId string `protobuf:"bytes,6,opt,name=serving_device_id,json=servingDeviceId,proto3" json:"serving_device_id,omitempty"`
+}
+
+func (x *ServedRelayParameters) Reset() {
+ *x = ServedRelayParameters{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[5]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ServedRelayParameters) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ServedRelayParameters) ProtoMessage() {}
+
+func (x *ServedRelayParameters) ProtoReflect() protoreflect.Message {
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[5]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ServedRelayParameters.ProtoReflect.Descriptor instead.
+func (*ServedRelayParameters) Descriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{5}
+}
+
+func (m *ServedRelayParameters) GetMode() isServedRelayParameters_Mode {
+ if m != nil {
+ return m.Mode
+ }
+ return nil
+}
+
+func (x *ServedRelayParameters) GetAlways() *RelayEndDeviceAlwaysMode {
+ if x, ok := x.GetMode().(*ServedRelayParameters_Always); ok {
+ return x.Always
+ }
+ return nil
+}
+
+func (x *ServedRelayParameters) GetDynamic() *RelayEndDeviceDynamicMode {
+ if x, ok := x.GetMode().(*ServedRelayParameters_Dynamic); ok {
+ return x.Dynamic
+ }
+ return nil
+}
+
+func (x *ServedRelayParameters) GetEndDeviceControlled() *RelayEndDeviceControlledMode {
+ if x, ok := x.GetMode().(*ServedRelayParameters_EndDeviceControlled); ok {
+ return x.EndDeviceControlled
+ }
+ return nil
+}
+
+func (x *ServedRelayParameters) GetBackoff() uint32 {
+ if x != nil {
+ return x.Backoff
+ }
+ return 0
+}
+
+func (x *ServedRelayParameters) GetSecondChannel() *RelaySecondChannel {
+ if x != nil {
+ return x.SecondChannel
+ }
+ return nil
+}
+
+func (x *ServedRelayParameters) GetServingDeviceId() string {
+ if x != nil {
+ return x.ServingDeviceId
+ }
+ return ""
+}
+
+type isServedRelayParameters_Mode interface {
+ isServedRelayParameters_Mode()
+}
+
+type ServedRelayParameters_Always struct {
+ // The end device will always attempt to use the relay mode in order to send uplink messages.
+ Always *RelayEndDeviceAlwaysMode `protobuf:"bytes,1,opt,name=always,proto3,oneof"`
+}
+
+type ServedRelayParameters_Dynamic struct {
+ // The end device will attempt to use relay mode only after a number of uplink messages have been sent without
+ // receiving a valid a downlink message.
+ Dynamic *RelayEndDeviceDynamicMode `protobuf:"bytes,2,opt,name=dynamic,proto3,oneof"`
+}
+
+type ServedRelayParameters_EndDeviceControlled struct {
+ // The end device will control when it uses the relay mode. This is the default mode.
+ EndDeviceControlled *RelayEndDeviceControlledMode `protobuf:"bytes,3,opt,name=end_device_controlled,json=endDeviceControlled,proto3,oneof"`
+}
+
+func (*ServedRelayParameters_Always) isServedRelayParameters_Mode() {}
+
+func (*ServedRelayParameters_Dynamic) isServedRelayParameters_Mode() {}
+
+func (*ServedRelayParameters_EndDeviceControlled) isServedRelayParameters_Mode() {}
+
+// RelayParameters represent the parameters of a relay.
+// This is used internally by the Network Server.
+type RelayParameters struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // Types that are assignable to Mode:
+ // *RelayParameters_Serving
+ // *RelayParameters_Served
+ Mode isRelayParameters_Mode `protobuf_oneof:"mode"`
+}
+
+func (x *RelayParameters) Reset() {
+ *x = RelayParameters{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[6]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *RelayParameters) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RelayParameters) ProtoMessage() {}
+
+func (x *RelayParameters) ProtoReflect() protoreflect.Message {
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[6]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use RelayParameters.ProtoReflect.Descriptor instead.
+func (*RelayParameters) Descriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{6}
+}
+
+func (m *RelayParameters) GetMode() isRelayParameters_Mode {
+ if m != nil {
+ return m.Mode
+ }
+ return nil
+}
+
+func (x *RelayParameters) GetServing() *ServingRelayParameters {
+ if x, ok := x.GetMode().(*RelayParameters_Serving); ok {
+ return x.Serving
+ }
+ return nil
+}
+
+func (x *RelayParameters) GetServed() *ServedRelayParameters {
+ if x, ok := x.GetMode().(*RelayParameters_Served); ok {
+ return x.Served
+ }
+ return nil
+}
+
+type isRelayParameters_Mode interface {
+ isRelayParameters_Mode()
+}
+
+type RelayParameters_Serving struct {
+ // Parameters related to a relay which is serving end devices.
+ Serving *ServingRelayParameters `protobuf:"bytes,25,opt,name=serving,proto3,oneof"`
+}
+
+type RelayParameters_Served struct {
+ // Parameters related to an end device served by a relay.
+ Served *ServedRelayParameters `protobuf:"bytes,26,opt,name=served,proto3,oneof"`
+}
+
+func (*RelayParameters_Serving) isRelayParameters_Mode() {}
+
+func (*RelayParameters_Served) isRelayParameters_Mode() {}
+
// MACParameters represent the parameters of the device's MAC layer (active or desired).
// This is used internally by the Network Server.
type MACParameters struct {
@@ -302,10 +762,10 @@ type MACParameters struct {
// Configured uplink channels and optionally Rx1 frequency.
Channels []*MACParameters_Channel `protobuf:"bytes,19,rep,name=channels,proto3" json:"channels,omitempty"`
// Whether uplink dwell time is set (400ms).
- // If this field is not set, then the value is either unknown or irrelevant(Network Server cannot modify it).
+ // If unset, then the value is either unknown or irrelevant(Network Server cannot modify it).
UplinkDwellTime *BoolValue `protobuf:"bytes,20,opt,name=uplink_dwell_time,json=uplinkDwellTime,proto3" json:"uplink_dwell_time,omitempty"`
// Whether downlink dwell time is set (400ms).
- // If this field is not set, then the value is either unknown or irrelevant(Network Server cannot modify it).
+ // If unset, then the value is either unknown or irrelevant(Network Server cannot modify it).
DownlinkDwellTime *BoolValue `protobuf:"bytes,21,opt,name=downlink_dwell_time,json=downlinkDwellTime,proto3" json:"downlink_dwell_time,omitempty"`
// ADR: number of messages to wait before setting ADRAckReq.
AdrAckLimitExponent *ADRAckLimitExponentValue `protobuf:"bytes,22,opt,name=adr_ack_limit_exponent,json=adrAckLimitExponent,proto3" json:"adr_ack_limit_exponent,omitempty"`
@@ -313,12 +773,14 @@ type MACParameters struct {
AdrAckDelayExponent *ADRAckDelayExponentValue `protobuf:"bytes,23,opt,name=adr_ack_delay_exponent,json=adrAckDelayExponent,proto3" json:"adr_ack_delay_exponent,omitempty"`
// Data rate index of the class B ping slot.
PingSlotDataRateIndexValue *DataRateIndexValue `protobuf:"bytes,24,opt,name=ping_slot_data_rate_index_value,json=pingSlotDataRateIndexValue,proto3" json:"ping_slot_data_rate_index_value,omitempty"`
+ // Relay parameters.
+ Relay *RelayParameters `protobuf:"bytes,25,opt,name=relay,proto3" json:"relay,omitempty"`
}
func (x *MACParameters) Reset() {
*x = MACParameters{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[2]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -331,7 +793,7 @@ func (x *MACParameters) String() string {
func (*MACParameters) ProtoMessage() {}
func (x *MACParameters) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[2]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[7]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -344,7 +806,7 @@ func (x *MACParameters) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACParameters.ProtoReflect.Descriptor instead.
func (*MACParameters) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{2}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{7}
}
func (x *MACParameters) GetMaxEirp() float32 {
@@ -504,6 +966,13 @@ func (x *MACParameters) GetPingSlotDataRateIndexValue() *DataRateIndexValue {
return nil
}
+func (x *MACParameters) GetRelay() *RelayParameters {
+ if x != nil {
+ return x.Relay
+ }
+ return nil
+}
+
// Template for creating end devices.
type EndDeviceVersion struct {
state protoimpl.MessageState
@@ -541,7 +1010,7 @@ type EndDeviceVersion struct {
func (x *EndDeviceVersion) Reset() {
*x = EndDeviceVersion{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[3]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -554,7 +1023,7 @@ func (x *EndDeviceVersion) String() string {
func (*EndDeviceVersion) ProtoMessage() {}
func (x *EndDeviceVersion) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[3]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[8]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -567,7 +1036,7 @@ func (x *EndDeviceVersion) ProtoReflect() protoreflect.Message {
// Deprecated: Use EndDeviceVersion.ProtoReflect.Descriptor instead.
func (*EndDeviceVersion) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{3}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{8}
}
func (x *EndDeviceVersion) GetIds() *EndDeviceVersionIdentifiers {
@@ -677,7 +1146,7 @@ type ADRSettings struct {
func (x *ADRSettings) Reset() {
*x = ADRSettings{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[4]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -690,7 +1159,7 @@ func (x *ADRSettings) String() string {
func (*ADRSettings) ProtoMessage() {}
func (x *ADRSettings) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[4]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[9]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -703,7 +1172,7 @@ func (x *ADRSettings) ProtoReflect() protoreflect.Message {
// Deprecated: Use ADRSettings.ProtoReflect.Descriptor instead.
func (*ADRSettings) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{4}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{9}
}
func (m *ADRSettings) GetMode() isADRSettings_Mode {
@@ -867,12 +1336,18 @@ type MACSettings struct {
// This option can be used in order to disable any downlink interaction with the end device. It will affect all types
// of downlink messages: data and MAC downlinks, and join accepts.
ScheduleDownlinks *BoolValue `protobuf:"bytes,35,opt,name=schedule_downlinks,json=scheduleDownlinks,proto3" json:"schedule_downlinks,omitempty"`
+ // The relay parameters the end device is using.
+ // If unset, the default value from Network Server configuration or regional parameters specification will be used.
+ Relay *RelayParameters `protobuf:"bytes,36,opt,name=relay,proto3" json:"relay,omitempty"`
+ // The relay parameters the Network Server should configure device to use via MAC commands.
+ // If unset, the default value from Network Server configuration or regional parameters specification will be used.
+ DesiredRelay *RelayParameters `protobuf:"bytes,37,opt,name=desired_relay,json=desiredRelay,proto3" json:"desired_relay,omitempty"`
}
func (x *MACSettings) Reset() {
*x = MACSettings{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[5]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -885,7 +1360,7 @@ func (x *MACSettings) String() string {
func (*MACSettings) ProtoMessage() {}
func (x *MACSettings) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[5]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[10]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -898,7 +1373,7 @@ func (x *MACSettings) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACSettings.ProtoReflect.Descriptor instead.
func (*MACSettings) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{5}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{10}
}
func (x *MACSettings) GetClassBTimeout() *durationpb.Duration {
@@ -1141,6 +1616,20 @@ func (x *MACSettings) GetScheduleDownlinks() *BoolValue {
return nil
}
+func (x *MACSettings) GetRelay() *RelayParameters {
+ if x != nil {
+ return x.Relay
+ }
+ return nil
+}
+
+func (x *MACSettings) GetDesiredRelay() *RelayParameters {
+ if x != nil {
+ return x.DesiredRelay
+ }
+ return nil
+}
+
// 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.
@@ -1211,12 +1700,16 @@ type MACState struct {
// The Network Server may choose to store only certain types of MAC
// command identifiers in the underlying implementation.
RecentMacCommandIdentifiers []MACCommandIdentifier `protobuf:"varint,23,rep,packed,name=recent_mac_command_identifiers,json=recentMacCommandIdentifiers,proto3,enum=ttn.lorawan.v3.MACCommandIdentifier" json:"recent_mac_command_identifiers,omitempty"`
+ // Pending relay downlink contents.
+ // The pending downlink will be scheduled to the relay in either Rx1 or Rx2.
+ // The pending downlink will be cleared after the scheduling attempt.
+ PendingRelayDownlink *RelayForwardDownlinkReq `protobuf:"bytes,24,opt,name=pending_relay_downlink,json=pendingRelayDownlink,proto3" json:"pending_relay_downlink,omitempty"`
}
func (x *MACState) Reset() {
*x = MACState{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[6]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1229,7 +1722,7 @@ func (x *MACState) String() string {
func (*MACState) ProtoMessage() {}
func (x *MACState) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[6]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[11]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1242,7 +1735,7 @@ func (x *MACState) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACState.ProtoReflect.Descriptor instead.
func (*MACState) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{6}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{11}
}
func (x *MACState) GetCurrentParameters() *MACParameters {
@@ -1406,6 +1899,13 @@ func (x *MACState) GetRecentMacCommandIdentifiers() []MACCommandIdentifier {
return nil
}
+func (x *MACState) GetPendingRelayDownlink() *RelayForwardDownlinkReq {
+ if x != nil {
+ return x.PendingRelayDownlink
+ }
+ return nil
+}
+
// Authentication code for end devices.
type EndDeviceAuthenticationCode struct {
state protoimpl.MessageState
@@ -1420,7 +1920,7 @@ type EndDeviceAuthenticationCode struct {
func (x *EndDeviceAuthenticationCode) Reset() {
*x = EndDeviceAuthenticationCode{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[7]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[12]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1433,7 +1933,7 @@ func (x *EndDeviceAuthenticationCode) String() string {
func (*EndDeviceAuthenticationCode) ProtoMessage() {}
func (x *EndDeviceAuthenticationCode) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[7]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[12]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1446,7 +1946,7 @@ func (x *EndDeviceAuthenticationCode) ProtoReflect() protoreflect.Message {
// Deprecated: Use EndDeviceAuthenticationCode.ProtoReflect.Descriptor instead.
func (*EndDeviceAuthenticationCode) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{7}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{12}
}
func (x *EndDeviceAuthenticationCode) GetValue() string {
@@ -1639,7 +2139,7 @@ type EndDevice struct {
func (x *EndDevice) Reset() {
*x = EndDevice{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[8]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[13]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1652,7 +2152,7 @@ func (x *EndDevice) String() string {
func (*EndDevice) ProtoMessage() {}
func (x *EndDevice) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[8]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[13]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1665,7 +2165,7 @@ func (x *EndDevice) ProtoReflect() protoreflect.Message {
// Deprecated: Use EndDevice.ProtoReflect.Descriptor instead.
func (*EndDevice) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{8}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{13}
}
func (x *EndDevice) GetIds() *EndDeviceIdentifiers {
@@ -2050,7 +2550,7 @@ type EndDevices struct {
func (x *EndDevices) Reset() {
*x = EndDevices{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[9]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[14]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2063,7 +2563,7 @@ func (x *EndDevices) String() string {
func (*EndDevices) ProtoMessage() {}
func (x *EndDevices) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[9]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[14]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2076,7 +2576,7 @@ func (x *EndDevices) ProtoReflect() protoreflect.Message {
// Deprecated: Use EndDevices.ProtoReflect.Descriptor instead.
func (*EndDevices) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{9}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{14}
}
func (x *EndDevices) GetEndDevices() []*EndDevice {
@@ -2100,7 +2600,7 @@ type DevAddrPrefix struct {
func (x *DevAddrPrefix) Reset() {
*x = DevAddrPrefix{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[10]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[15]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2113,7 +2613,7 @@ func (x *DevAddrPrefix) String() string {
func (*DevAddrPrefix) ProtoMessage() {}
func (x *DevAddrPrefix) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[10]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[15]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2126,7 +2626,7 @@ func (x *DevAddrPrefix) ProtoReflect() protoreflect.Message {
// Deprecated: Use DevAddrPrefix.ProtoReflect.Descriptor instead.
func (*DevAddrPrefix) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{10}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{15}
}
func (x *DevAddrPrefix) GetDevAddr() []byte {
@@ -2154,7 +2654,7 @@ type CreateEndDeviceRequest struct {
func (x *CreateEndDeviceRequest) Reset() {
*x = CreateEndDeviceRequest{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[11]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[16]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2167,7 +2667,7 @@ func (x *CreateEndDeviceRequest) String() string {
func (*CreateEndDeviceRequest) ProtoMessage() {}
func (x *CreateEndDeviceRequest) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[11]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[16]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2180,7 +2680,7 @@ func (x *CreateEndDeviceRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use CreateEndDeviceRequest.ProtoReflect.Descriptor instead.
func (*CreateEndDeviceRequest) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{11}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{16}
}
func (x *CreateEndDeviceRequest) GetEndDevice() *EndDevice {
@@ -2204,7 +2704,7 @@ type UpdateEndDeviceRequest struct {
func (x *UpdateEndDeviceRequest) Reset() {
*x = UpdateEndDeviceRequest{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[12]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[17]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2217,7 +2717,7 @@ func (x *UpdateEndDeviceRequest) String() string {
func (*UpdateEndDeviceRequest) ProtoMessage() {}
func (x *UpdateEndDeviceRequest) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[12]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[17]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2230,7 +2730,7 @@ func (x *UpdateEndDeviceRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use UpdateEndDeviceRequest.ProtoReflect.Descriptor instead.
func (*UpdateEndDeviceRequest) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{12}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{17}
}
func (x *UpdateEndDeviceRequest) GetEndDevice() *EndDevice {
@@ -2259,7 +2759,7 @@ type BatchUpdateEndDeviceLastSeenRequest struct {
func (x *BatchUpdateEndDeviceLastSeenRequest) Reset() {
*x = BatchUpdateEndDeviceLastSeenRequest{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[13]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[18]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2272,7 +2772,7 @@ func (x *BatchUpdateEndDeviceLastSeenRequest) String() string {
func (*BatchUpdateEndDeviceLastSeenRequest) ProtoMessage() {}
func (x *BatchUpdateEndDeviceLastSeenRequest) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[13]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[18]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2285,7 +2785,7 @@ func (x *BatchUpdateEndDeviceLastSeenRequest) ProtoReflect() protoreflect.Messag
// Deprecated: Use BatchUpdateEndDeviceLastSeenRequest.ProtoReflect.Descriptor instead.
func (*BatchUpdateEndDeviceLastSeenRequest) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{13}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{18}
}
func (x *BatchUpdateEndDeviceLastSeenRequest) GetUpdates() []*BatchUpdateEndDeviceLastSeenRequest_EndDeviceLastSeenUpdate {
@@ -2309,7 +2809,7 @@ type GetEndDeviceRequest struct {
func (x *GetEndDeviceRequest) Reset() {
*x = GetEndDeviceRequest{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[14]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[19]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2322,7 +2822,7 @@ func (x *GetEndDeviceRequest) String() string {
func (*GetEndDeviceRequest) ProtoMessage() {}
func (x *GetEndDeviceRequest) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[14]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[19]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2335,7 +2835,7 @@ func (x *GetEndDeviceRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use GetEndDeviceRequest.ProtoReflect.Descriptor instead.
func (*GetEndDeviceRequest) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{14}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{19}
}
func (x *GetEndDeviceRequest) GetEndDeviceIds() *EndDeviceIdentifiers {
@@ -2364,7 +2864,7 @@ type GetEndDeviceIdentifiersForEUIsRequest struct {
func (x *GetEndDeviceIdentifiersForEUIsRequest) Reset() {
*x = GetEndDeviceIdentifiersForEUIsRequest{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[15]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[20]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2377,7 +2877,7 @@ func (x *GetEndDeviceIdentifiersForEUIsRequest) String() string {
func (*GetEndDeviceIdentifiersForEUIsRequest) ProtoMessage() {}
func (x *GetEndDeviceIdentifiersForEUIsRequest) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[15]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[20]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2390,7 +2890,7 @@ func (x *GetEndDeviceIdentifiersForEUIsRequest) ProtoReflect() protoreflect.Mess
// Deprecated: Use GetEndDeviceIdentifiersForEUIsRequest.ProtoReflect.Descriptor instead.
func (*GetEndDeviceIdentifiersForEUIsRequest) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{15}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{20}
}
func (x *GetEndDeviceIdentifiersForEUIsRequest) GetJoinEui() []byte {
@@ -2428,7 +2928,7 @@ type ListEndDevicesRequest struct {
func (x *ListEndDevicesRequest) Reset() {
*x = ListEndDevicesRequest{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[16]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[21]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2441,7 +2941,7 @@ func (x *ListEndDevicesRequest) String() string {
func (*ListEndDevicesRequest) ProtoMessage() {}
func (x *ListEndDevicesRequest) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[16]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[21]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2454,7 +2954,7 @@ func (x *ListEndDevicesRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use ListEndDevicesRequest.ProtoReflect.Descriptor instead.
func (*ListEndDevicesRequest) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{16}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{21}
}
func (x *ListEndDevicesRequest) GetApplicationIds() *ApplicationIdentifiers {
@@ -2506,7 +3006,7 @@ type SetEndDeviceRequest struct {
func (x *SetEndDeviceRequest) Reset() {
*x = SetEndDeviceRequest{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[17]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[22]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2519,7 +3019,7 @@ func (x *SetEndDeviceRequest) String() string {
func (*SetEndDeviceRequest) ProtoMessage() {}
func (x *SetEndDeviceRequest) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[17]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[22]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2532,7 +3032,7 @@ func (x *SetEndDeviceRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use SetEndDeviceRequest.ProtoReflect.Descriptor instead.
func (*SetEndDeviceRequest) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{17}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{22}
}
func (x *SetEndDeviceRequest) GetEndDevice() *EndDevice {
@@ -2563,7 +3063,7 @@ type ResetAndGetEndDeviceRequest struct {
func (x *ResetAndGetEndDeviceRequest) Reset() {
*x = ResetAndGetEndDeviceRequest{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[18]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[23]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2576,7 +3076,7 @@ func (x *ResetAndGetEndDeviceRequest) String() string {
func (*ResetAndGetEndDeviceRequest) ProtoMessage() {}
func (x *ResetAndGetEndDeviceRequest) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[18]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[23]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2589,7 +3089,7 @@ func (x *ResetAndGetEndDeviceRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use ResetAndGetEndDeviceRequest.ProtoReflect.Descriptor instead.
func (*ResetAndGetEndDeviceRequest) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{18}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{23}
}
func (x *ResetAndGetEndDeviceRequest) GetEndDeviceIds() *EndDeviceIdentifiers {
@@ -2619,7 +3119,7 @@ type EndDeviceTemplate struct {
func (x *EndDeviceTemplate) Reset() {
*x = EndDeviceTemplate{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[19]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[24]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2632,7 +3132,7 @@ func (x *EndDeviceTemplate) String() string {
func (*EndDeviceTemplate) ProtoMessage() {}
func (x *EndDeviceTemplate) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[19]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[24]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2645,7 +3145,7 @@ func (x *EndDeviceTemplate) ProtoReflect() protoreflect.Message {
// Deprecated: Use EndDeviceTemplate.ProtoReflect.Descriptor instead.
func (*EndDeviceTemplate) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{19}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{24}
}
func (x *EndDeviceTemplate) GetEndDevice() *EndDevice {
@@ -2682,7 +3182,7 @@ type EndDeviceTemplateFormat struct {
func (x *EndDeviceTemplateFormat) Reset() {
*x = EndDeviceTemplateFormat{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[20]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[25]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2695,7 +3195,7 @@ func (x *EndDeviceTemplateFormat) String() string {
func (*EndDeviceTemplateFormat) ProtoMessage() {}
func (x *EndDeviceTemplateFormat) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[20]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[25]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2708,7 +3208,7 @@ func (x *EndDeviceTemplateFormat) ProtoReflect() protoreflect.Message {
// Deprecated: Use EndDeviceTemplateFormat.ProtoReflect.Descriptor instead.
func (*EndDeviceTemplateFormat) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{20}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{25}
}
func (x *EndDeviceTemplateFormat) GetName() string {
@@ -2743,7 +3243,7 @@ type EndDeviceTemplateFormats struct {
func (x *EndDeviceTemplateFormats) Reset() {
*x = EndDeviceTemplateFormats{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[21]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[26]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2756,7 +3256,7 @@ func (x *EndDeviceTemplateFormats) String() string {
func (*EndDeviceTemplateFormats) ProtoMessage() {}
func (x *EndDeviceTemplateFormats) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[21]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[26]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2769,7 +3269,7 @@ func (x *EndDeviceTemplateFormats) ProtoReflect() protoreflect.Message {
// Deprecated: Use EndDeviceTemplateFormats.ProtoReflect.Descriptor instead.
func (*EndDeviceTemplateFormats) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{21}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{26}
}
func (x *EndDeviceTemplateFormats) GetFormats() map[string]*EndDeviceTemplateFormat {
@@ -2795,7 +3295,7 @@ type ConvertEndDeviceTemplateRequest struct {
func (x *ConvertEndDeviceTemplateRequest) Reset() {
*x = ConvertEndDeviceTemplateRequest{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[22]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[27]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2808,7 +3308,7 @@ func (x *ConvertEndDeviceTemplateRequest) String() string {
func (*ConvertEndDeviceTemplateRequest) ProtoMessage() {}
func (x *ConvertEndDeviceTemplateRequest) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[22]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[27]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2821,7 +3321,7 @@ func (x *ConvertEndDeviceTemplateRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use ConvertEndDeviceTemplateRequest.ProtoReflect.Descriptor instead.
func (*ConvertEndDeviceTemplateRequest) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{22}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{27}
}
func (x *ConvertEndDeviceTemplateRequest) GetFormatId() string {
@@ -2857,7 +3357,7 @@ type BatchDeleteEndDevicesRequest struct {
func (x *BatchDeleteEndDevicesRequest) Reset() {
*x = BatchDeleteEndDevicesRequest{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[23]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[28]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2870,7 +3370,7 @@ func (x *BatchDeleteEndDevicesRequest) String() string {
func (*BatchDeleteEndDevicesRequest) ProtoMessage() {}
func (x *BatchDeleteEndDevicesRequest) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[23]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[28]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2883,7 +3383,7 @@ func (x *BatchDeleteEndDevicesRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use BatchDeleteEndDevicesRequest.ProtoReflect.Descriptor instead.
func (*BatchDeleteEndDevicesRequest) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{23}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{28}
}
func (x *BatchDeleteEndDevicesRequest) GetApplicationIds() *ApplicationIdentifiers {
@@ -2916,7 +3416,7 @@ type BatchGetEndDevicesRequest struct {
func (x *BatchGetEndDevicesRequest) Reset() {
*x = BatchGetEndDevicesRequest{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[24]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[29]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2929,7 +3429,7 @@ func (x *BatchGetEndDevicesRequest) String() string {
func (*BatchGetEndDevicesRequest) ProtoMessage() {}
func (x *BatchGetEndDevicesRequest) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[24]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[29]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2942,7 +3442,7 @@ func (x *BatchGetEndDevicesRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use BatchGetEndDevicesRequest.ProtoReflect.Descriptor instead.
func (*BatchGetEndDevicesRequest) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{24}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{29}
}
func (x *BatchGetEndDevicesRequest) GetApplicationIds() *ApplicationIdentifiers {
@@ -2986,7 +3486,7 @@ type MACParameters_Channel struct {
func (x *MACParameters_Channel) Reset() {
*x = MACParameters_Channel{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[25]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[30]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2999,7 +3499,7 @@ func (x *MACParameters_Channel) String() string {
func (*MACParameters_Channel) ProtoMessage() {}
func (x *MACParameters_Channel) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[25]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[30]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3012,7 +3512,7 @@ func (x *MACParameters_Channel) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACParameters_Channel.ProtoReflect.Descriptor instead.
func (*MACParameters_Channel) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{2, 0}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{7, 0}
}
func (x *MACParameters_Channel) GetUplinkFrequency() uint64 {
@@ -3067,7 +3567,7 @@ type ADRSettings_StaticMode struct {
func (x *ADRSettings_StaticMode) Reset() {
*x = ADRSettings_StaticMode{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[26]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[31]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3080,7 +3580,7 @@ func (x *ADRSettings_StaticMode) String() string {
func (*ADRSettings_StaticMode) ProtoMessage() {}
func (x *ADRSettings_StaticMode) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[26]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[31]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3093,7 +3593,7 @@ func (x *ADRSettings_StaticMode) ProtoReflect() protoreflect.Message {
// Deprecated: Use ADRSettings_StaticMode.ProtoReflect.Descriptor instead.
func (*ADRSettings_StaticMode) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{4, 0}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{9, 0}
}
func (x *ADRSettings_StaticMode) GetDataRateIndex() DataRateIndex {
@@ -3151,7 +3651,7 @@ type ADRSettings_DynamicMode struct {
func (x *ADRSettings_DynamicMode) Reset() {
*x = ADRSettings_DynamicMode{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[27]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[32]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3164,7 +3664,7 @@ func (x *ADRSettings_DynamicMode) String() string {
func (*ADRSettings_DynamicMode) ProtoMessage() {}
func (x *ADRSettings_DynamicMode) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[27]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[32]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3177,7 +3677,7 @@ func (x *ADRSettings_DynamicMode) ProtoReflect() protoreflect.Message {
// Deprecated: Use ADRSettings_DynamicMode.ProtoReflect.Descriptor instead.
func (*ADRSettings_DynamicMode) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{4, 1}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{9, 1}
}
func (x *ADRSettings_DynamicMode) GetMargin() *wrapperspb.FloatValue {
@@ -3247,7 +3747,7 @@ type ADRSettings_DisabledMode struct {
func (x *ADRSettings_DisabledMode) Reset() {
*x = ADRSettings_DisabledMode{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[28]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[33]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3260,7 +3760,7 @@ func (x *ADRSettings_DisabledMode) String() string {
func (*ADRSettings_DisabledMode) ProtoMessage() {}
func (x *ADRSettings_DisabledMode) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[28]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[33]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3273,7 +3773,7 @@ func (x *ADRSettings_DisabledMode) ProtoReflect() protoreflect.Message {
// Deprecated: Use ADRSettings_DisabledMode.ProtoReflect.Descriptor instead.
func (*ADRSettings_DisabledMode) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{4, 2}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{9, 2}
}
// EXPERIMENTAL: Channel steering settings.
@@ -3291,7 +3791,7 @@ type ADRSettings_DynamicMode_ChannelSteeringSettings struct {
func (x *ADRSettings_DynamicMode_ChannelSteeringSettings) Reset() {
*x = ADRSettings_DynamicMode_ChannelSteeringSettings{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[29]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[34]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3304,7 +3804,7 @@ func (x *ADRSettings_DynamicMode_ChannelSteeringSettings) String() string {
func (*ADRSettings_DynamicMode_ChannelSteeringSettings) ProtoMessage() {}
func (x *ADRSettings_DynamicMode_ChannelSteeringSettings) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[29]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[34]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3317,7 +3817,7 @@ func (x *ADRSettings_DynamicMode_ChannelSteeringSettings) ProtoReflect() protore
// Deprecated: Use ADRSettings_DynamicMode_ChannelSteeringSettings.ProtoReflect.Descriptor instead.
func (*ADRSettings_DynamicMode_ChannelSteeringSettings) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{4, 1, 0}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{9, 1, 0}
}
func (m *ADRSettings_DynamicMode_ChannelSteeringSettings) GetMode() isADRSettings_DynamicMode_ChannelSteeringSettings_Mode {
@@ -3371,7 +3871,7 @@ type ADRSettings_DynamicMode_ChannelSteeringSettings_LoRaNarrowMode struct {
func (x *ADRSettings_DynamicMode_ChannelSteeringSettings_LoRaNarrowMode) Reset() {
*x = ADRSettings_DynamicMode_ChannelSteeringSettings_LoRaNarrowMode{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[30]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[35]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3384,7 +3884,7 @@ func (x *ADRSettings_DynamicMode_ChannelSteeringSettings_LoRaNarrowMode) String(
func (*ADRSettings_DynamicMode_ChannelSteeringSettings_LoRaNarrowMode) ProtoMessage() {}
func (x *ADRSettings_DynamicMode_ChannelSteeringSettings_LoRaNarrowMode) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[30]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[35]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3397,7 +3897,7 @@ func (x *ADRSettings_DynamicMode_ChannelSteeringSettings_LoRaNarrowMode) ProtoRe
// Deprecated: Use ADRSettings_DynamicMode_ChannelSteeringSettings_LoRaNarrowMode.ProtoReflect.Descriptor instead.
func (*ADRSettings_DynamicMode_ChannelSteeringSettings_LoRaNarrowMode) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{4, 1, 0, 0}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{9, 1, 0, 0}
}
// Configuration options for cases in which ADR is not supposed to steer the end device
@@ -3411,7 +3911,7 @@ type ADRSettings_DynamicMode_ChannelSteeringSettings_DisabledMode struct {
func (x *ADRSettings_DynamicMode_ChannelSteeringSettings_DisabledMode) Reset() {
*x = ADRSettings_DynamicMode_ChannelSteeringSettings_DisabledMode{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[31]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[36]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3424,7 +3924,7 @@ func (x *ADRSettings_DynamicMode_ChannelSteeringSettings_DisabledMode) String()
func (*ADRSettings_DynamicMode_ChannelSteeringSettings_DisabledMode) ProtoMessage() {}
func (x *ADRSettings_DynamicMode_ChannelSteeringSettings_DisabledMode) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[31]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[36]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3437,7 +3937,7 @@ func (x *ADRSettings_DynamicMode_ChannelSteeringSettings_DisabledMode) ProtoRefl
// Deprecated: Use ADRSettings_DynamicMode_ChannelSteeringSettings_DisabledMode.ProtoReflect.Descriptor instead.
func (*ADRSettings_DynamicMode_ChannelSteeringSettings_DisabledMode) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{4, 1, 0, 1}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{9, 1, 0, 1}
}
type MACState_JoinRequest struct {
@@ -3453,7 +3953,7 @@ type MACState_JoinRequest struct {
func (x *MACState_JoinRequest) Reset() {
*x = MACState_JoinRequest{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[32]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[37]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3466,7 +3966,7 @@ func (x *MACState_JoinRequest) String() string {
func (*MACState_JoinRequest) ProtoMessage() {}
func (x *MACState_JoinRequest) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[32]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[37]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3479,7 +3979,7 @@ func (x *MACState_JoinRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACState_JoinRequest.ProtoReflect.Descriptor instead.
func (*MACState_JoinRequest) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{6, 0}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{11, 0}
}
func (x *MACState_JoinRequest) GetDownlinkSettings() *DLSettings {
@@ -3521,7 +4021,7 @@ type MACState_JoinAccept struct {
func (x *MACState_JoinAccept) Reset() {
*x = MACState_JoinAccept{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[33]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[38]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3534,7 +4034,7 @@ func (x *MACState_JoinAccept) String() string {
func (*MACState_JoinAccept) ProtoMessage() {}
func (x *MACState_JoinAccept) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[33]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[38]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3547,7 +4047,7 @@ func (x *MACState_JoinAccept) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACState_JoinAccept.ProtoReflect.Descriptor instead.
func (*MACState_JoinAccept) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{6, 1}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{11, 1}
}
func (x *MACState_JoinAccept) GetPayload() []byte {
@@ -3610,7 +4110,7 @@ type MACState_UplinkMessage struct {
func (x *MACState_UplinkMessage) Reset() {
*x = MACState_UplinkMessage{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[34]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[39]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3623,7 +4123,7 @@ func (x *MACState_UplinkMessage) String() string {
func (*MACState_UplinkMessage) ProtoMessage() {}
func (x *MACState_UplinkMessage) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[34]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[39]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3636,7 +4136,7 @@ func (x *MACState_UplinkMessage) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACState_UplinkMessage.ProtoReflect.Descriptor instead.
func (*MACState_UplinkMessage) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{6, 2}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{11, 2}
}
func (x *MACState_UplinkMessage) GetPayload() *Message {
@@ -3695,7 +4195,7 @@ type MACState_DownlinkMessage struct {
func (x *MACState_DownlinkMessage) Reset() {
*x = MACState_DownlinkMessage{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[35]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[40]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3708,7 +4208,7 @@ func (x *MACState_DownlinkMessage) String() string {
func (*MACState_DownlinkMessage) ProtoMessage() {}
func (x *MACState_DownlinkMessage) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[35]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[40]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3721,7 +4221,7 @@ func (x *MACState_DownlinkMessage) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACState_DownlinkMessage.ProtoReflect.Descriptor instead.
func (*MACState_DownlinkMessage) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{6, 3}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{11, 3}
}
func (x *MACState_DownlinkMessage) GetPayload() *MACState_DownlinkMessage_Message {
@@ -3750,7 +4250,7 @@ type MACState_DataRateRange struct {
func (x *MACState_DataRateRange) Reset() {
*x = MACState_DataRateRange{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[36]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[41]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3763,7 +4263,7 @@ func (x *MACState_DataRateRange) String() string {
func (*MACState_DataRateRange) ProtoMessage() {}
func (x *MACState_DataRateRange) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[36]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[41]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3776,7 +4276,7 @@ func (x *MACState_DataRateRange) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACState_DataRateRange.ProtoReflect.Descriptor instead.
func (*MACState_DataRateRange) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{6, 4}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{11, 4}
}
func (x *MACState_DataRateRange) GetMinDataRateIndex() DataRateIndex {
@@ -3804,7 +4304,7 @@ type MACState_DataRateRanges struct {
func (x *MACState_DataRateRanges) Reset() {
*x = MACState_DataRateRanges{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[37]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[42]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3817,7 +4317,7 @@ func (x *MACState_DataRateRanges) String() string {
func (*MACState_DataRateRanges) ProtoMessage() {}
func (x *MACState_DataRateRanges) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[37]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[42]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3830,7 +4330,7 @@ func (x *MACState_DataRateRanges) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACState_DataRateRanges.ProtoReflect.Descriptor instead.
func (*MACState_DataRateRanges) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{6, 5}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{11, 5}
}
func (x *MACState_DataRateRanges) GetRanges() []*MACState_DataRateRange {
@@ -3851,7 +4351,7 @@ type MACState_UplinkMessage_TxSettings struct {
func (x *MACState_UplinkMessage_TxSettings) Reset() {
*x = MACState_UplinkMessage_TxSettings{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[39]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[44]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3864,7 +4364,7 @@ func (x *MACState_UplinkMessage_TxSettings) String() string {
func (*MACState_UplinkMessage_TxSettings) ProtoMessage() {}
func (x *MACState_UplinkMessage_TxSettings) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[39]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[44]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3877,7 +4377,7 @@ func (x *MACState_UplinkMessage_TxSettings) ProtoReflect() protoreflect.Message
// Deprecated: Use MACState_UplinkMessage_TxSettings.ProtoReflect.Descriptor instead.
func (*MACState_UplinkMessage_TxSettings) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{6, 2, 0}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{11, 2, 0}
}
func (x *MACState_UplinkMessage_TxSettings) GetDataRate() *DataRate {
@@ -3898,12 +4398,13 @@ type MACState_UplinkMessage_RxMetadata struct {
DownlinkPathConstraint DownlinkPathConstraint `protobuf:"varint,14,opt,name=downlink_path_constraint,json=downlinkPathConstraint,proto3,enum=ttn.lorawan.v3.DownlinkPathConstraint" json:"downlink_path_constraint,omitempty"`
UplinkToken []byte `protobuf:"bytes,15,opt,name=uplink_token,json=uplinkToken,proto3" json:"uplink_token,omitempty"`
PacketBroker *MACState_UplinkMessage_RxMetadata_PacketBrokerMetadata `protobuf:"bytes,18,opt,name=packet_broker,json=packetBroker,proto3" json:"packet_broker,omitempty"`
+ Relay *MACState_UplinkMessage_RxMetadata_RelayMetadata `protobuf:"bytes,23,opt,name=relay,proto3" json:"relay,omitempty"`
}
func (x *MACState_UplinkMessage_RxMetadata) Reset() {
*x = MACState_UplinkMessage_RxMetadata{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[40]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[45]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3916,7 +4417,7 @@ func (x *MACState_UplinkMessage_RxMetadata) String() string {
func (*MACState_UplinkMessage_RxMetadata) ProtoMessage() {}
func (x *MACState_UplinkMessage_RxMetadata) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[40]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[45]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3929,7 +4430,7 @@ func (x *MACState_UplinkMessage_RxMetadata) ProtoReflect() protoreflect.Message
// Deprecated: Use MACState_UplinkMessage_RxMetadata.ProtoReflect.Descriptor instead.
func (*MACState_UplinkMessage_RxMetadata) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{6, 2, 1}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{11, 2, 1}
}
func (x *MACState_UplinkMessage_RxMetadata) GetGatewayIds() *GatewayIdentifiers {
@@ -3974,6 +4475,13 @@ func (x *MACState_UplinkMessage_RxMetadata) GetPacketBroker() *MACState_UplinkMe
return nil
}
+func (x *MACState_UplinkMessage_RxMetadata) GetRelay() *MACState_UplinkMessage_RxMetadata_RelayMetadata {
+ if x != nil {
+ return x.Relay
+ }
+ return nil
+}
+
type MACState_UplinkMessage_RxMetadata_PacketBrokerMetadata struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -3983,7 +4491,7 @@ type MACState_UplinkMessage_RxMetadata_PacketBrokerMetadata struct {
func (x *MACState_UplinkMessage_RxMetadata_PacketBrokerMetadata) Reset() {
*x = MACState_UplinkMessage_RxMetadata_PacketBrokerMetadata{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[41]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[46]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3996,7 +4504,7 @@ func (x *MACState_UplinkMessage_RxMetadata_PacketBrokerMetadata) String() string
func (*MACState_UplinkMessage_RxMetadata_PacketBrokerMetadata) ProtoMessage() {}
func (x *MACState_UplinkMessage_RxMetadata_PacketBrokerMetadata) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[41]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[46]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4009,7 +4517,45 @@ func (x *MACState_UplinkMessage_RxMetadata_PacketBrokerMetadata) ProtoReflect()
// Deprecated: Use MACState_UplinkMessage_RxMetadata_PacketBrokerMetadata.ProtoReflect.Descriptor instead.
func (*MACState_UplinkMessage_RxMetadata_PacketBrokerMetadata) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{6, 2, 1, 0}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{11, 2, 1, 0}
+}
+
+type MACState_UplinkMessage_RxMetadata_RelayMetadata struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+}
+
+func (x *MACState_UplinkMessage_RxMetadata_RelayMetadata) Reset() {
+ *x = MACState_UplinkMessage_RxMetadata_RelayMetadata{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[47]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *MACState_UplinkMessage_RxMetadata_RelayMetadata) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MACState_UplinkMessage_RxMetadata_RelayMetadata) ProtoMessage() {}
+
+func (x *MACState_UplinkMessage_RxMetadata_RelayMetadata) ProtoReflect() protoreflect.Message {
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[47]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use MACState_UplinkMessage_RxMetadata_RelayMetadata.ProtoReflect.Descriptor instead.
+func (*MACState_UplinkMessage_RxMetadata_RelayMetadata) Descriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{11, 2, 1, 1}
}
type MACState_DownlinkMessage_Message struct {
@@ -4024,7 +4570,7 @@ type MACState_DownlinkMessage_Message struct {
func (x *MACState_DownlinkMessage_Message) Reset() {
*x = MACState_DownlinkMessage_Message{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[42]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[48]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4037,7 +4583,7 @@ func (x *MACState_DownlinkMessage_Message) String() string {
func (*MACState_DownlinkMessage_Message) ProtoMessage() {}
func (x *MACState_DownlinkMessage_Message) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[42]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[48]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4050,7 +4596,7 @@ func (x *MACState_DownlinkMessage_Message) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACState_DownlinkMessage_Message.ProtoReflect.Descriptor instead.
func (*MACState_DownlinkMessage_Message) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{6, 3, 0}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{11, 3, 0}
}
func (x *MACState_DownlinkMessage_Message) GetMHdr() *MACState_DownlinkMessage_Message_MHDR {
@@ -4078,7 +4624,7 @@ type MACState_DownlinkMessage_Message_MHDR struct {
func (x *MACState_DownlinkMessage_Message_MHDR) Reset() {
*x = MACState_DownlinkMessage_Message_MHDR{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[43]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[49]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4091,7 +4637,7 @@ func (x *MACState_DownlinkMessage_Message_MHDR) String() string {
func (*MACState_DownlinkMessage_Message_MHDR) ProtoMessage() {}
func (x *MACState_DownlinkMessage_Message_MHDR) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[43]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[49]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4104,7 +4650,7 @@ func (x *MACState_DownlinkMessage_Message_MHDR) ProtoReflect() protoreflect.Mess
// Deprecated: Use MACState_DownlinkMessage_Message_MHDR.ProtoReflect.Descriptor instead.
func (*MACState_DownlinkMessage_Message_MHDR) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{6, 3, 0, 0}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{11, 3, 0, 0}
}
func (x *MACState_DownlinkMessage_Message_MHDR) GetMType() MType {
@@ -4126,7 +4672,7 @@ type MACState_DownlinkMessage_Message_MACPayload struct {
func (x *MACState_DownlinkMessage_Message_MACPayload) Reset() {
*x = MACState_DownlinkMessage_Message_MACPayload{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[44]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[50]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4139,7 +4685,7 @@ func (x *MACState_DownlinkMessage_Message_MACPayload) String() string {
func (*MACState_DownlinkMessage_Message_MACPayload) ProtoMessage() {}
func (x *MACState_DownlinkMessage_Message_MACPayload) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[44]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[50]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4152,7 +4698,7 @@ func (x *MACState_DownlinkMessage_Message_MACPayload) ProtoReflect() protoreflec
// Deprecated: Use MACState_DownlinkMessage_Message_MACPayload.ProtoReflect.Descriptor instead.
func (*MACState_DownlinkMessage_Message_MACPayload) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{6, 3, 0, 1}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{11, 3, 0, 1}
}
func (x *MACState_DownlinkMessage_Message_MACPayload) GetFPort() uint32 {
@@ -4181,7 +4727,7 @@ type BatchUpdateEndDeviceLastSeenRequest_EndDeviceLastSeenUpdate struct {
func (x *BatchUpdateEndDeviceLastSeenRequest_EndDeviceLastSeenUpdate) Reset() {
*x = BatchUpdateEndDeviceLastSeenRequest_EndDeviceLastSeenUpdate{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[47]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[53]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4194,7 +4740,7 @@ func (x *BatchUpdateEndDeviceLastSeenRequest_EndDeviceLastSeenUpdate) String() s
func (*BatchUpdateEndDeviceLastSeenRequest_EndDeviceLastSeenUpdate) ProtoMessage() {}
func (x *BatchUpdateEndDeviceLastSeenRequest_EndDeviceLastSeenUpdate) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[47]
+ mi := &file_ttn_lorawan_v3_end_device_proto_msgTypes[53]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4207,7 +4753,7 @@ func (x *BatchUpdateEndDeviceLastSeenRequest_EndDeviceLastSeenUpdate) ProtoRefle
// Deprecated: Use BatchUpdateEndDeviceLastSeenRequest_EndDeviceLastSeenUpdate.ProtoReflect.Descriptor instead.
func (*BatchUpdateEndDeviceLastSeenRequest_EndDeviceLastSeenUpdate) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{13, 0}
+ return file_ttn_lorawan_v3_end_device_proto_rawDescGZIP(), []int{18, 0}
}
func (x *BatchUpdateEndDeviceLastSeenRequest_EndDeviceLastSeenUpdate) GetIds() *EndDeviceIdentifiers {
@@ -4314,834 +4860,990 @@ var file_ttn_lorawan_v3_end_device_proto_rawDesc = []byte{
0x01, 0x10, 0x02, 0x22, 0x33, 0x0a, 0x09, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65,
0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52,
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x10, 0xea, 0xaa, 0x19, 0x02, 0x18, 0x01, 0xf2, 0xaa,
- 0x19, 0x06, 0x08, 0x01, 0x10, 0x01, 0x18, 0x01, 0x22, 0xc5, 0x0f, 0x0a, 0x0d, 0x4d, 0x41, 0x43,
- 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61,
- 0x78, 0x5f, 0x65, 0x69, 0x72, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x02, 0x52, 0x07, 0x6d, 0x61,
- 0x78, 0x45, 0x69, 0x72, 0x70, 0x12, 0x56, 0x0a, 0x13, 0x61, 0x64, 0x72, 0x5f, 0x64, 0x61, 0x74,
- 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01,
- 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
- 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65,
- 0x78, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x10, 0x61, 0x64, 0x72,
- 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x34, 0x0a,
- 0x12, 0x61, 0x64, 0x72, 0x5f, 0x74, 0x78, 0x5f, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x5f, 0x69, 0x6e,
- 0x64, 0x65, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02,
- 0x18, 0x0f, 0x52, 0x0f, 0x61, 0x64, 0x72, 0x54, 0x78, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x49, 0x6e,
- 0x64, 0x65, 0x78, 0x12, 0x29, 0x0a, 0x0c, 0x61, 0x64, 0x72, 0x5f, 0x6e, 0x62, 0x5f, 0x74, 0x72,
- 0x61, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02,
- 0x18, 0x0f, 0x52, 0x0a, 0x61, 0x64, 0x72, 0x4e, 0x62, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x12, 0x26,
- 0x0a, 0x0d, 0x61, 0x64, 0x72, 0x5f, 0x61, 0x63, 0x6b, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18,
- 0x07, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0b, 0x61, 0x64, 0x72, 0x41, 0x63,
- 0x6b, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x26, 0x0a, 0x0d, 0x61, 0x64, 0x72, 0x5f, 0x61, 0x63,
- 0x6b, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x02, 0x18,
- 0x01, 0x52, 0x0b, 0x61, 0x64, 0x72, 0x41, 0x63, 0x6b, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x3e,
- 0x0a, 0x09, 0x72, 0x78, 0x31, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28,
- 0x0e, 0x32, 0x17, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
- 0x76, 0x33, 0x2e, 0x52, 0x78, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82,
- 0x01, 0x02, 0x10, 0x01, 0x52, 0x08, 0x72, 0x78, 0x31, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x59,
- 0x0a, 0x14, 0x72, 0x78, 0x31, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f,
- 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x74,
- 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61,
- 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x42, 0x08, 0xfa, 0x42,
- 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x11, 0x72, 0x78, 0x31, 0x44, 0x61, 0x74, 0x61, 0x52,
- 0x61, 0x74, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x56, 0x0a, 0x13, 0x72, 0x78, 0x32,
- 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78,
- 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
- 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65,
- 0x49, 0x6e, 0x64, 0x65, 0x78, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52,
- 0x10, 0x72, 0x78, 0x32, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65,
- 0x78, 0x12, 0x2e, 0x0a, 0x0d, 0x72, 0x78, 0x32, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e,
- 0x63, 0x79, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x04, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x32, 0x04, 0x28,
- 0xa0, 0x8d, 0x06, 0x52, 0x0c, 0x72, 0x78, 0x32, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63,
- 0x79, 0x12, 0x53, 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x75, 0x74, 0x79, 0x5f, 0x63, 0x79,
- 0x63, 0x6c, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
- 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65,
- 0x67, 0x61, 0x74, 0x65, 0x64, 0x44, 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x42, 0x08,
- 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x44, 0x75, 0x74,
- 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x64, 0x0a, 0x17, 0x72, 0x65, 0x6a, 0x6f, 0x69, 0x6e,
- 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63, 0x69, 0x74,
- 0x79, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
- 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x54,
- 0x69, 0x6d, 0x65, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x42, 0x08, 0xfa, 0x42, 0x05,
- 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x15, 0x72, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x54, 0x69, 0x6d,
- 0x65, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63, 0x69, 0x74, 0x79, 0x12, 0x67, 0x0a, 0x18,
- 0x72, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x70, 0x65, 0x72,
- 0x69, 0x6f, 0x64, 0x69, 0x63, 0x69, 0x74, 0x79, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23,
+ 0x19, 0x06, 0x08, 0x01, 0x10, 0x01, 0x18, 0x01, 0x22, 0x95, 0x03, 0x0a, 0x1c, 0x53, 0x65, 0x72,
+ 0x76, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64,
+ 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x4d, 0x0a, 0x0e, 0x72, 0x65, 0x73,
+ 0x65, 0x74, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x0e, 0x32, 0x26, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
+ 0x76, 0x33, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x52, 0x65, 0x73, 0x65, 0x74, 0x4c, 0x69, 0x6d,
+ 0x69, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x52, 0x0d, 0x72, 0x65, 0x73, 0x65, 0x74,
+ 0x42, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x12, 0x47, 0x0a, 0x0d, 0x6a, 0x6f, 0x69, 0x6e,
+ 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x22, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
+ 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x4c, 0x69, 0x6d,
+ 0x69, 0x74, 0x73, 0x52, 0x0c, 0x6a, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+ 0x73, 0x12, 0x48, 0x0a, 0x0d, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c,
+ 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x46,
+ 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x0d, 0x6e, 0x6f,
+ 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4b, 0x0a, 0x0f, 0x75,
+ 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x04,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
+ 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x46, 0x6f, 0x72, 0x77, 0x61,
+ 0x72, 0x64, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x0e, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b,
+ 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x3c, 0x0a, 0x07, 0x6f, 0x76, 0x65, 0x72,
+ 0x61, 0x6c, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
+ 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79,
+ 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x07, 0x6f,
+ 0x76, 0x65, 0x72, 0x61, 0x6c, 0x6c, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01,
+ 0x22, 0xf7, 0x01, 0x0a, 0x19, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b,
+ 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x40,
+ 0x0a, 0x06, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28,
0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
- 0x52, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x45, 0x78, 0x70, 0x6f, 0x6e,
- 0x65, 0x6e, 0x74, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x16, 0x72,
- 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64,
- 0x69, 0x63, 0x69, 0x74, 0x79, 0x12, 0x3b, 0x0a, 0x13, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x6c,
- 0x6f, 0x74, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x10, 0x20, 0x01,
- 0x28, 0x04, 0x42, 0x0b, 0xfa, 0x42, 0x08, 0x32, 0x06, 0x18, 0x00, 0x28, 0xa0, 0x8d, 0x06, 0x52,
- 0x11, 0x70, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e,
- 0x63, 0x79, 0x12, 0x5b, 0x0a, 0x19, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x5f,
- 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18,
- 0x11, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
- 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49,
- 0x6e, 0x64, 0x65, 0x78, 0x42, 0x02, 0x18, 0x01, 0x52, 0x15, 0x70, 0x69, 0x6e, 0x67, 0x53, 0x6c,
- 0x6f, 0x74, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12,
- 0x36, 0x0a, 0x10, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65,
- 0x6e, 0x63, 0x79, 0x18, 0x12, 0x20, 0x01, 0x28, 0x04, 0x42, 0x0b, 0xfa, 0x42, 0x08, 0x32, 0x06,
- 0x18, 0x00, 0x28, 0xa0, 0x8d, 0x06, 0x52, 0x0f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x46, 0x72,
- 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x4b, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x6e, 0x6e,
- 0x65, 0x6c, 0x73, 0x18, 0x13, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
- 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x50, 0x61,
- 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c,
- 0x42, 0x08, 0xfa, 0x42, 0x05, 0x92, 0x01, 0x02, 0x08, 0x01, 0x52, 0x08, 0x63, 0x68, 0x61, 0x6e,
- 0x6e, 0x65, 0x6c, 0x73, 0x12, 0x45, 0x0a, 0x11, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x64,
- 0x77, 0x65, 0x6c, 0x6c, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32,
- 0x19, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
- 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0f, 0x75, 0x70, 0x6c, 0x69,
- 0x6e, 0x6b, 0x44, 0x77, 0x65, 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x49, 0x0a, 0x13, 0x64,
- 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x64, 0x77, 0x65, 0x6c, 0x6c, 0x5f, 0x74, 0x69,
- 0x6d, 0x65, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c,
- 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61,
- 0x6c, 0x75, 0x65, 0x52, 0x11, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x44, 0x77, 0x65,
- 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x5d, 0x0a, 0x16, 0x61, 0x64, 0x72, 0x5f, 0x61, 0x63,
- 0x6b, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74,
- 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
- 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x44, 0x52, 0x41, 0x63, 0x6b, 0x4c, 0x69,
- 0x6d, 0x69, 0x74, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65,
- 0x52, 0x13, 0x61, 0x64, 0x72, 0x41, 0x63, 0x6b, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x45, 0x78, 0x70,
- 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x5d, 0x0a, 0x16, 0x61, 0x64, 0x72, 0x5f, 0x61, 0x63, 0x6b,
- 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18,
- 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
- 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x44, 0x52, 0x41, 0x63, 0x6b, 0x44, 0x65, 0x6c,
- 0x61, 0x79, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52,
- 0x13, 0x61, 0x64, 0x72, 0x41, 0x63, 0x6b, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x45, 0x78, 0x70, 0x6f,
- 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x67, 0x0a, 0x1f, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x6c, 0x6f,
- 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65,
- 0x78, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e,
- 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44,
- 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x56, 0x61, 0x6c, 0x75,
- 0x65, 0x52, 0x1a, 0x70, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x44, 0x61, 0x74, 0x61, 0x52,
- 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0xda, 0x02,
- 0x0a, 0x07, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x36, 0x0a, 0x10, 0x75, 0x70, 0x6c,
- 0x69, 0x6e, 0x6b, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x04, 0x42, 0x0b, 0xfa, 0x42, 0x08, 0x32, 0x06, 0x18, 0x00, 0x28, 0xa0, 0x8d, 0x06,
- 0x52, 0x0f, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63,
- 0x79, 0x12, 0x38, 0x0a, 0x12, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x66, 0x72,
- 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x42, 0x09, 0xfa,
- 0x42, 0x06, 0x32, 0x04, 0x28, 0xa0, 0x8d, 0x06, 0x52, 0x11, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69,
- 0x6e, 0x6b, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x56, 0x0a, 0x13, 0x6d,
- 0x69, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64,
- 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c,
+ 0x52, 0x65, 0x6c, 0x61, 0x79, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x46, 0x6f, 0x72, 0x77, 0x61,
+ 0x72, 0x64, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x06, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73,
+ 0x12, 0x1f, 0x0a, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x77, 0x5f, 0x66, 0x5f, 0x63, 0x6e, 0x74,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x57, 0x46, 0x43, 0x6e,
+ 0x74, 0x12, 0x47, 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03,
+ 0x20, 0x01, 0x28, 0x09, 0x42, 0x2a, 0xfa, 0x42, 0x27, 0x72, 0x25, 0x18, 0x24, 0x32, 0x1e, 0x5e,
+ 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x3f, 0x3a, 0x5b, 0x2d, 0x5d, 0x3f, 0x5b,
+ 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x7b, 0x32, 0x2c, 0x7d, 0x24, 0xd0, 0x01, 0x01,
+ 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0e, 0x73, 0x65,
+ 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01,
+ 0x28, 0x0c, 0x52, 0x0c, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x49, 0x64,
+ 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x22, 0xb6, 0x03, 0x0a, 0x16, 0x53,
+ 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d,
+ 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x49, 0x0a, 0x0e, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x5f,
+ 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e,
+ 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x52,
+ 0x65, 0x6c, 0x61, 0x79, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65,
+ 0x6c, 0x52, 0x0d, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c,
+ 0x12, 0x3c, 0x0a, 0x15, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x6e,
+ 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x42,
+ 0x08, 0xfa, 0x42, 0x05, 0x2a, 0x03, 0x18, 0xff, 0x01, 0x52, 0x13, 0x64, 0x65, 0x66, 0x61, 0x75,
+ 0x6c, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x56,
+ 0x0a, 0x0f, 0x63, 0x61, 0x64, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63, 0x69, 0x74,
+ 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
+ 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x43, 0x41,
+ 0x44, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63, 0x69, 0x74, 0x79, 0x42, 0x08, 0xfa, 0x42,
+ 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0e, 0x63, 0x61, 0x64, 0x50, 0x65, 0x72, 0x69, 0x6f,
+ 0x64, 0x69, 0x63, 0x69, 0x74, 0x79, 0x12, 0x6b, 0x0a, 0x17, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b,
+ 0x5f, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65,
+ 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
+ 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x55, 0x70,
+ 0x6c, 0x69, 0x6e, 0x6b, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x75,
+ 0x6c, 0x65, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x92, 0x01, 0x02, 0x10, 0x10, 0x52, 0x15, 0x75, 0x70,
+ 0x6c, 0x69, 0x6e, 0x6b, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x75,
+ 0x6c, 0x65, 0x73, 0x12, 0x44, 0x0a, 0x06, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x05, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
+ 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x6c, 0x61,
+ 0x79, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x6d, 0x69, 0x74,
+ 0x73, 0x52, 0x06, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08,
+ 0x01, 0x10, 0x01, 0x22, 0xe2, 0x03, 0x0a, 0x15, 0x53, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x65,
+ 0x6c, 0x61, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x42, 0x0a,
+ 0x06, 0x61, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e,
+ 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x52,
+ 0x65, 0x6c, 0x61, 0x79, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x41, 0x6c, 0x77,
+ 0x61, 0x79, 0x73, 0x4d, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x06, 0x61, 0x6c, 0x77, 0x61, 0x79,
+ 0x73, 0x12, 0x45, 0x0a, 0x07, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x18, 0x02, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
+ 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69,
+ 0x63, 0x65, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52,
+ 0x07, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x12, 0x62, 0x0a, 0x15, 0x65, 0x6e, 0x64, 0x5f,
+ 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65,
+ 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
+ 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x45, 0x6e,
+ 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65,
+ 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x13, 0x65, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69,
+ 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x07,
+ 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa,
+ 0x42, 0x04, 0x2a, 0x02, 0x18, 0x3f, 0x52, 0x07, 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x12,
+ 0x49, 0x0a, 0x0e, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65,
+ 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
+ 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x53, 0x65,
+ 0x63, 0x6f, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x0d, 0x73, 0x65, 0x63,
+ 0x6f, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x53, 0x0a, 0x11, 0x73, 0x65,
+ 0x72, 0x76, 0x69, 0x6e, 0x67, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18,
+ 0x06, 0x20, 0x01, 0x28, 0x09, 0x42, 0x27, 0xfa, 0x42, 0x24, 0x72, 0x22, 0x18, 0x24, 0x32, 0x1e,
+ 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x3f, 0x3a, 0x5b, 0x2d, 0x5d, 0x3f,
+ 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x7b, 0x32, 0x2c, 0x7d, 0x24, 0x52, 0x0f,
+ 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x3a,
+ 0x0a, 0xf2, 0xaa, 0x19, 0x06, 0x08, 0x01, 0x10, 0x01, 0x20, 0x01, 0x42, 0x0b, 0x0a, 0x04, 0x6d,
+ 0x6f, 0x64, 0x65, 0x12, 0x03, 0xf8, 0x42, 0x01, 0x22, 0xaf, 0x01, 0x0a, 0x0f, 0x52, 0x65, 0x6c,
+ 0x61, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x42, 0x0a, 0x07,
+ 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e,
+ 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x53,
+ 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d,
+ 0x65, 0x74, 0x65, 0x72, 0x73, 0x48, 0x00, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67,
+ 0x12, 0x3f, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x25, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
+ 0x33, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x50, 0x61, 0x72,
+ 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x48, 0x00, 0x52, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65,
+ 0x64, 0x3a, 0x0a, 0xf2, 0xaa, 0x19, 0x06, 0x08, 0x01, 0x10, 0x01, 0x20, 0x01, 0x42, 0x0b, 0x0a,
+ 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x03, 0xf8, 0x42, 0x01, 0x22, 0xfc, 0x0f, 0x0a, 0x0d, 0x4d,
+ 0x41, 0x43, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08,
+ 0x6d, 0x61, 0x78, 0x5f, 0x65, 0x69, 0x72, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x02, 0x52, 0x07,
+ 0x6d, 0x61, 0x78, 0x45, 0x69, 0x72, 0x70, 0x12, 0x56, 0x0a, 0x13, 0x61, 0x64, 0x72, 0x5f, 0x64,
+ 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x04,
+ 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
+ 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e,
+ 0x64, 0x65, 0x78, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x10, 0x61,
+ 0x64, 0x72, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12,
+ 0x34, 0x0a, 0x12, 0x61, 0x64, 0x72, 0x5f, 0x74, 0x78, 0x5f, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x5f,
+ 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04,
+ 0x2a, 0x02, 0x18, 0x0f, 0x52, 0x0f, 0x61, 0x64, 0x72, 0x54, 0x78, 0x50, 0x6f, 0x77, 0x65, 0x72,
+ 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x29, 0x0a, 0x0c, 0x61, 0x64, 0x72, 0x5f, 0x6e, 0x62, 0x5f,
+ 0x74, 0x72, 0x61, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04,
+ 0x2a, 0x02, 0x18, 0x0f, 0x52, 0x0a, 0x61, 0x64, 0x72, 0x4e, 0x62, 0x54, 0x72, 0x61, 0x6e, 0x73,
+ 0x12, 0x26, 0x0a, 0x0d, 0x61, 0x64, 0x72, 0x5f, 0x61, 0x63, 0x6b, 0x5f, 0x6c, 0x69, 0x6d, 0x69,
+ 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0b, 0x61, 0x64, 0x72,
+ 0x41, 0x63, 0x6b, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x26, 0x0a, 0x0d, 0x61, 0x64, 0x72, 0x5f,
+ 0x61, 0x63, 0x6b, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x42,
+ 0x02, 0x18, 0x01, 0x52, 0x0b, 0x61, 0x64, 0x72, 0x41, 0x63, 0x6b, 0x44, 0x65, 0x6c, 0x61, 0x79,
+ 0x12, 0x3e, 0x0a, 0x09, 0x72, 0x78, 0x31, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x09, 0x20,
+ 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
+ 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x78, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x42, 0x08, 0xfa, 0x42,
+ 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x08, 0x72, 0x78, 0x31, 0x44, 0x65, 0x6c, 0x61, 0x79,
+ 0x12, 0x59, 0x0a, 0x14, 0x72, 0x78, 0x31, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74,
+ 0x65, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e,
+ 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
+ 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x42, 0x08,
+ 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x11, 0x72, 0x78, 0x31, 0x44, 0x61, 0x74,
+ 0x61, 0x52, 0x61, 0x74, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x56, 0x0a, 0x13, 0x72,
+ 0x78, 0x32, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64,
+ 0x65, 0x78, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c,
0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61,
0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10,
- 0x01, 0x52, 0x10, 0x6d, 0x69, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e,
- 0x64, 0x65, 0x78, 0x12, 0x56, 0x0a, 0x13, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f,
- 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e,
- 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
- 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x42,
- 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x10, 0x6d, 0x61, 0x78, 0x44, 0x61,
- 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x23, 0x0a, 0x0d, 0x65,
- 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x05, 0x20, 0x01,
- 0x28, 0x08, 0x52, 0x0c, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b,
- 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04,
- 0x08, 0x01, 0x10, 0x01, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04,
- 0x22, 0xfa, 0x05, 0x0a, 0x10, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x56, 0x65,
- 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x47, 0x0a, 0x03, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
- 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x56, 0x65, 0x72,
- 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42,
- 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x03, 0x69, 0x64, 0x73, 0x12, 0x4d,
- 0x0a, 0x0f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
- 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
- 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x56, 0x65, 0x72, 0x73,
- 0x69, 0x6f, 0x6e, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0e, 0x6c,
- 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x54, 0x0a,
- 0x13, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x5f, 0x70, 0x68, 0x79, 0x5f, 0x76, 0x65, 0x72,
- 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x74, 0x6e,
- 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x50, 0x48, 0x59, 0x56,
- 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01,
- 0x52, 0x11, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x50, 0x68, 0x79, 0x56, 0x65, 0x72, 0x73,
- 0x69, 0x6f, 0x6e, 0x12, 0x33, 0x0a, 0x11, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79,
- 0x5f, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07,
- 0xfa, 0x42, 0x04, 0x72, 0x02, 0x18, 0x40, 0x52, 0x0f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e,
- 0x63, 0x79, 0x50, 0x6c, 0x61, 0x6e, 0x49, 0x64, 0x12, 0x20, 0x0a, 0x06, 0x70, 0x68, 0x6f, 0x74,
- 0x6f, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x92, 0x01, 0x02,
- 0x10, 0x0a, 0x52, 0x06, 0x70, 0x68, 0x6f, 0x74, 0x6f, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x75,
- 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x62, 0x18, 0x06,
- 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x43, 0x6c,
- 0x61, 0x73, 0x73, 0x42, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73,
- 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x63, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e,
- 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x12, 0x4d,
- 0x0a, 0x14, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x6d, 0x61, 0x63, 0x5f, 0x73, 0x65,
- 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74,
- 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41,
- 0x43, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x12, 0x64, 0x65, 0x66, 0x61, 0x75,
- 0x6c, 0x74, 0x4d, 0x61, 0x63, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x23, 0x0a,
- 0x0d, 0x6d, 0x69, 0x6e, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x09,
- 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d, 0x69, 0x6e, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e,
- 0x63, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x61, 0x78, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65,
- 0x6e, 0x63, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x46, 0x72,
- 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x75, 0x70, 0x70, 0x6f,
- 0x72, 0x74, 0x73, 0x5f, 0x6a, 0x6f, 0x69, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c,
- 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x4a, 0x6f, 0x69, 0x6e, 0x12, 0x2c, 0x0a, 0x12,
- 0x72, 0x65, 0x73, 0x65, 0x74, 0x73, 0x5f, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x6e, 0x6f, 0x6e, 0x63,
- 0x65, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x72, 0x65, 0x73, 0x65, 0x74, 0x73,
- 0x4a, 0x6f, 0x69, 0x6e, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x61, 0x0a, 0x12, 0x64, 0x65,
- 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x73,
- 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
- 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x50,
- 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x73,
- 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x11, 0x64, 0x65, 0x66, 0x61,
- 0x75, 0x6c, 0x74, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x73, 0x22, 0xad, 0x0b,
- 0x0a, 0x0b, 0x41, 0x44, 0x52, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x40, 0x0a,
- 0x06, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e,
- 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41,
- 0x44, 0x52, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x69,
- 0x63, 0x4d, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x12,
- 0x43, 0x0a, 0x07, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
- 0x32, 0x27, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
- 0x33, 0x2e, 0x41, 0x44, 0x52, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x44, 0x79,
- 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x07, 0x64, 0x79, 0x6e,
- 0x61, 0x6d, 0x69, 0x63, 0x12, 0x46, 0x0a, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64,
- 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
+ 0x01, 0x52, 0x10, 0x72, 0x78, 0x32, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e,
+ 0x64, 0x65, 0x78, 0x12, 0x2e, 0x0a, 0x0d, 0x72, 0x78, 0x32, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75,
+ 0x65, 0x6e, 0x63, 0x79, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x04, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x32,
+ 0x04, 0x28, 0xa0, 0x8d, 0x06, 0x52, 0x0c, 0x72, 0x78, 0x32, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65,
+ 0x6e, 0x63, 0x79, 0x12, 0x53, 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x75, 0x74, 0x79, 0x5f,
+ 0x63, 0x79, 0x63, 0x6c, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x74, 0x74,
+ 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x67, 0x67,
+ 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x44, 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65,
+ 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x44,
+ 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x64, 0x0a, 0x17, 0x72, 0x65, 0x6a, 0x6f,
+ 0x69, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63,
+ 0x69, 0x74, 0x79, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
+ 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65, 0x6a, 0x6f, 0x69,
+ 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x42, 0x08, 0xfa,
+ 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x15, 0x72, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x54,
+ 0x69, 0x6d, 0x65, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63, 0x69, 0x74, 0x79, 0x12, 0x67,
+ 0x0a, 0x18, 0x72, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x70,
+ 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63, 0x69, 0x74, 0x79, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0e,
+ 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
+ 0x33, 0x2e, 0x52, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x45, 0x78, 0x70,
+ 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52,
+ 0x16, 0x72, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x65, 0x72, 0x69,
+ 0x6f, 0x64, 0x69, 0x63, 0x69, 0x74, 0x79, 0x12, 0x3b, 0x0a, 0x13, 0x70, 0x69, 0x6e, 0x67, 0x5f,
+ 0x73, 0x6c, 0x6f, 0x74, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x10,
+ 0x20, 0x01, 0x28, 0x04, 0x42, 0x0b, 0xfa, 0x42, 0x08, 0x32, 0x06, 0x18, 0x00, 0x28, 0xa0, 0x8d,
+ 0x06, 0x52, 0x11, 0x70, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x46, 0x72, 0x65, 0x71, 0x75,
+ 0x65, 0x6e, 0x63, 0x79, 0x12, 0x5b, 0x0a, 0x19, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x6c, 0x6f,
+ 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65,
+ 0x78, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
+ 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74,
+ 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x42, 0x02, 0x18, 0x01, 0x52, 0x15, 0x70, 0x69, 0x6e, 0x67,
+ 0x53, 0x6c, 0x6f, 0x74, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65,
+ 0x78, 0x12, 0x36, 0x0a, 0x10, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x5f, 0x66, 0x72, 0x65, 0x71,
+ 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x12, 0x20, 0x01, 0x28, 0x04, 0x42, 0x0b, 0xfa, 0x42, 0x08,
+ 0x32, 0x06, 0x18, 0x00, 0x28, 0xa0, 0x8d, 0x06, 0x52, 0x0f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e,
+ 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x4b, 0x0a, 0x08, 0x63, 0x68, 0x61,
+ 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x18, 0x13, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x74, 0x74,
+ 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43,
+ 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e,
+ 0x65, 0x6c, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x92, 0x01, 0x02, 0x08, 0x01, 0x52, 0x08, 0x63, 0x68,
+ 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x12, 0x45, 0x0a, 0x11, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b,
+ 0x5f, 0x64, 0x77, 0x65, 0x6c, 0x6c, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28,
+ 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
+ 0x76, 0x33, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0f, 0x75, 0x70,
+ 0x6c, 0x69, 0x6e, 0x6b, 0x44, 0x77, 0x65, 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x49, 0x0a,
+ 0x13, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x64, 0x77, 0x65, 0x6c, 0x6c, 0x5f,
+ 0x74, 0x69, 0x6d, 0x65, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x74, 0x6e,
+ 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x42, 0x6f, 0x6f, 0x6c,
+ 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x11, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x44,
+ 0x77, 0x65, 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x5d, 0x0a, 0x16, 0x61, 0x64, 0x72, 0x5f,
+ 0x61, 0x63, 0x6b, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x6e, 0x65,
+ 0x6e, 0x74, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c,
+ 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x44, 0x52, 0x41, 0x63, 0x6b,
+ 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x6c,
+ 0x75, 0x65, 0x52, 0x13, 0x61, 0x64, 0x72, 0x41, 0x63, 0x6b, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x45,
+ 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x5d, 0x0a, 0x16, 0x61, 0x64, 0x72, 0x5f, 0x61,
+ 0x63, 0x6b, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e,
+ 0x74, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
+ 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x44, 0x52, 0x41, 0x63, 0x6b, 0x44,
+ 0x65, 0x6c, 0x61, 0x79, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75,
+ 0x65, 0x52, 0x13, 0x61, 0x64, 0x72, 0x41, 0x63, 0x6b, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x45, 0x78,
+ 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x67, 0x0a, 0x1f, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x73,
+ 0x6c, 0x6f, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e,
+ 0x64, 0x65, 0x78, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x22, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
+ 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x56, 0x61,
+ 0x6c, 0x75, 0x65, 0x52, 0x1a, 0x70, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x44, 0x61, 0x74,
+ 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12,
+ 0x35, 0x0a, 0x05, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f,
+ 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
+ 0x52, 0x65, 0x6c, 0x61, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x52,
+ 0x05, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x1a, 0xda, 0x02, 0x0a, 0x07, 0x43, 0x68, 0x61, 0x6e, 0x6e,
+ 0x65, 0x6c, 0x12, 0x36, 0x0a, 0x10, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x66, 0x72, 0x65,
+ 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x42, 0x0b, 0xfa, 0x42,
+ 0x08, 0x32, 0x06, 0x18, 0x00, 0x28, 0xa0, 0x8d, 0x06, 0x52, 0x0f, 0x75, 0x70, 0x6c, 0x69, 0x6e,
+ 0x6b, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x38, 0x0a, 0x12, 0x64, 0x6f,
+ 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x32, 0x04, 0x28, 0xa0, 0x8d,
+ 0x06, 0x52, 0x11, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x46, 0x72, 0x65, 0x71, 0x75,
+ 0x65, 0x6e, 0x63, 0x79, 0x12, 0x56, 0x0a, 0x13, 0x6d, 0x69, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61,
+ 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28,
+ 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
+ 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78,
+ 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x10, 0x6d, 0x69, 0x6e, 0x44,
+ 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x56, 0x0a, 0x13,
+ 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e,
+ 0x64, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
+ 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52,
+ 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02,
+ 0x10, 0x01, 0x52, 0x10, 0x6d, 0x61, 0x78, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49,
+ 0x6e, 0x64, 0x65, 0x78, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x75,
+ 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x65, 0x6e, 0x61,
+ 0x62, 0x6c, 0x65, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08,
+ 0x01, 0x10, 0x01, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x4a, 0x04, 0x08,
+ 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x22, 0xfa, 0x05, 0x0a, 0x10, 0x45, 0x6e,
+ 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x47,
+ 0x0a, 0x03, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x74,
+ 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x64,
+ 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x65,
+ 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02,
+ 0x10, 0x01, 0x52, 0x03, 0x69, 0x64, 0x73, 0x12, 0x4d, 0x0a, 0x0f, 0x6c, 0x6f, 0x72, 0x61, 0x77,
+ 0x61, 0x6e, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e,
+ 0x32, 0x1a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
+ 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x08, 0xfa, 0x42,
+ 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x56,
+ 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x54, 0x0a, 0x13, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
+ 0x6e, 0x5f, 0x70, 0x68, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20,
+ 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
+ 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x50, 0x48, 0x59, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42,
+ 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x11, 0x6c, 0x6f, 0x72, 0x61, 0x77,
+ 0x61, 0x6e, 0x50, 0x68, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x33, 0x0a, 0x11,
+ 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69,
+ 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x18, 0x40,
+ 0x52, 0x0f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x50, 0x6c, 0x61, 0x6e, 0x49,
+ 0x64, 0x12, 0x20, 0x0a, 0x06, 0x70, 0x68, 0x6f, 0x74, 0x6f, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28,
+ 0x09, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x92, 0x01, 0x02, 0x10, 0x0a, 0x52, 0x06, 0x70, 0x68, 0x6f,
+ 0x74, 0x6f, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x5f,
+ 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x62, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x73,
+ 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x42, 0x12, 0x28, 0x0a,
+ 0x10, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f,
+ 0x63, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74,
+ 0x73, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x12, 0x4d, 0x0a, 0x14, 0x64, 0x65, 0x66, 0x61, 0x75,
+ 0x6c, 0x74, 0x5f, 0x6d, 0x61, 0x63, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18,
+ 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
+ 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e,
+ 0x67, 0x73, 0x52, 0x12, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x4d, 0x61, 0x63, 0x53, 0x65,
+ 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x69, 0x6e, 0x5f, 0x66, 0x72,
+ 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d,
+ 0x69, 0x6e, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x6d,
+ 0x61, 0x78, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x0a, 0x20, 0x01,
+ 0x28, 0x04, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79,
+ 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x5f, 0x6a, 0x6f, 0x69,
+ 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74,
+ 0x73, 0x4a, 0x6f, 0x69, 0x6e, 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x65, 0x73, 0x65, 0x74, 0x73, 0x5f,
+ 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28,
+ 0x08, 0x52, 0x10, 0x72, 0x65, 0x73, 0x65, 0x74, 0x73, 0x4a, 0x6f, 0x69, 0x6e, 0x4e, 0x6f, 0x6e,
+ 0x63, 0x65, 0x73, 0x12, 0x61, 0x0a, 0x12, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x66,
+ 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x28, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
+ 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x46,
+ 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01,
+ 0x02, 0x10, 0x01, 0x52, 0x11, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x46, 0x6f, 0x72, 0x6d,
+ 0x61, 0x74, 0x74, 0x65, 0x72, 0x73, 0x22, 0xad, 0x0b, 0x0a, 0x0b, 0x41, 0x44, 0x52, 0x53, 0x65,
+ 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x40, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x44, 0x52, 0x53, 0x65, 0x74, 0x74, 0x69,
- 0x6e, 0x67, 0x73, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x65,
- 0x48, 0x00, 0x52, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x1a, 0xbc, 0x01, 0x0a,
- 0x0a, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x4f, 0x0a, 0x0f, 0x64,
- 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01,
- 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
- 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e,
- 0x64, 0x65, 0x78, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0d, 0x64,
- 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x2d, 0x0a, 0x0e,
- 0x74, 0x78, 0x5f, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02,
- 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, 0x18, 0x0f, 0x52, 0x0c, 0x74,
- 0x78, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x24, 0x0a, 0x08, 0x6e,
- 0x62, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x09, 0xfa,
- 0x42, 0x06, 0x2a, 0x04, 0x18, 0x0f, 0x28, 0x01, 0x52, 0x07, 0x6e, 0x62, 0x54, 0x72, 0x61, 0x6e,
- 0x73, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x1a, 0xe1, 0x07, 0x0a, 0x0b,
- 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x33, 0x0a, 0x06, 0x6d,
- 0x61, 0x72, 0x67, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f,
- 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x6c,
- 0x6f, 0x61, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e,
- 0x12, 0x51, 0x0a, 0x13, 0x6d, 0x69, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74,
- 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e,
+ 0x6e, 0x67, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x4d, 0x6f, 0x64, 0x65, 0x48, 0x00,
+ 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x12, 0x43, 0x0a, 0x07, 0x64, 0x79, 0x6e, 0x61,
+ 0x6d, 0x69, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
+ 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x44, 0x52, 0x53, 0x65,
+ 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d, 0x6f,
+ 0x64, 0x65, 0x48, 0x00, 0x52, 0x07, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x12, 0x46, 0x0a,
+ 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x28, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
+ 0x2e, 0x41, 0x44, 0x52, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x44, 0x69, 0x73,
+ 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x08, 0x64, 0x69, 0x73,
+ 0x61, 0x62, 0x6c, 0x65, 0x64, 0x1a, 0xbc, 0x01, 0x0a, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63,
+ 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x4f, 0x0a, 0x0f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74,
+ 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e,
0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44,
- 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x56, 0x61, 0x6c, 0x75,
- 0x65, 0x52, 0x10, 0x6d, 0x69, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e,
- 0x64, 0x65, 0x78, 0x12, 0x51, 0x0a, 0x13, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f,
- 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b,
- 0x32, 0x22, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
- 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x56,
- 0x61, 0x6c, 0x75, 0x65, 0x52, 0x10, 0x6d, 0x61, 0x78, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74,
- 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x52, 0x0a, 0x12, 0x6d, 0x69, 0x6e, 0x5f, 0x74, 0x78,
- 0x5f, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01,
- 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
- 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65,
- 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, 0x18, 0x0f, 0x52, 0x0f, 0x6d, 0x69, 0x6e, 0x54, 0x78,
- 0x50, 0x6f, 0x77, 0x65, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x52, 0x0a, 0x12, 0x6d, 0x61,
- 0x78, 0x5f, 0x74, 0x78, 0x5f, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78,
- 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56,
- 0x61, 0x6c, 0x75, 0x65, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, 0x18, 0x0f, 0x52, 0x0f, 0x6d,
- 0x61, 0x78, 0x54, 0x78, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x49,
- 0x0a, 0x0c, 0x6d, 0x69, 0x6e, 0x5f, 0x6e, 0x62, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x18, 0x06,
- 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
- 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c,
- 0x75, 0x65, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x2a, 0x04, 0x18, 0x03, 0x28, 0x01, 0x52, 0x0a, 0x6d,
- 0x69, 0x6e, 0x4e, 0x62, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x12, 0x49, 0x0a, 0x0c, 0x6d, 0x61, 0x78,
- 0x5f, 0x6e, 0x62, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x42, 0x08, 0xfa, 0x42,
+ 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0d, 0x64, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65,
+ 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x2d, 0x0a, 0x0e, 0x74, 0x78, 0x5f, 0x70, 0x6f, 0x77, 0x65,
+ 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa,
+ 0x42, 0x04, 0x2a, 0x02, 0x18, 0x0f, 0x52, 0x0c, 0x74, 0x78, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x49,
+ 0x6e, 0x64, 0x65, 0x78, 0x12, 0x24, 0x0a, 0x08, 0x6e, 0x62, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73,
+ 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x2a, 0x04, 0x18, 0x0f, 0x28,
+ 0x01, 0x52, 0x07, 0x6e, 0x62, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04,
+ 0x08, 0x01, 0x10, 0x01, 0x1a, 0xe1, 0x07, 0x0a, 0x0b, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63,
+ 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x33, 0x0a, 0x06, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x56, 0x61, 0x6c, 0x75,
+ 0x65, 0x52, 0x06, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x12, 0x51, 0x0a, 0x13, 0x6d, 0x69, 0x6e,
+ 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
+ 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65,
+ 0x49, 0x6e, 0x64, 0x65, 0x78, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x10, 0x6d, 0x69, 0x6e, 0x44,
+ 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x51, 0x0a, 0x13,
+ 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e,
+ 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
+ 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52,
+ 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x10, 0x6d,
+ 0x61, 0x78, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12,
+ 0x52, 0x0a, 0x12, 0x6d, 0x69, 0x6e, 0x5f, 0x74, 0x78, 0x5f, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x5f,
+ 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f,
+ 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49,
+ 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02,
+ 0x18, 0x0f, 0x52, 0x0f, 0x6d, 0x69, 0x6e, 0x54, 0x78, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x49, 0x6e,
+ 0x64, 0x65, 0x78, 0x12, 0x52, 0x0a, 0x12, 0x6d, 0x61, 0x78, 0x5f, 0x74, 0x78, 0x5f, 0x70, 0x6f,
+ 0x77, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
- 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x09, 0xfa,
- 0x42, 0x06, 0x2a, 0x04, 0x18, 0x03, 0x28, 0x01, 0x52, 0x0a, 0x6d, 0x61, 0x78, 0x4e, 0x62, 0x54,
- 0x72, 0x61, 0x6e, 0x73, 0x12, 0x6a, 0x0a, 0x10, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f,
- 0x73, 0x74, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3f,
- 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
- 0x41, 0x44, 0x52, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x44, 0x79, 0x6e, 0x61,
- 0x6d, 0x69, 0x63, 0x4d, 0x6f, 0x64, 0x65, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x53,
- 0x74, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52,
- 0x0f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x53, 0x74, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67,
- 0x1a, 0xc2, 0x02, 0x0a, 0x17, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x53, 0x74, 0x65, 0x65,
- 0x72, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x71, 0x0a, 0x0b,
- 0x6c, 0x6f, 0x72, 0x61, 0x5f, 0x6e, 0x61, 0x72, 0x72, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28,
- 0x0b, 0x32, 0x4e, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
- 0x76, 0x33, 0x2e, 0x41, 0x44, 0x52, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x44,
- 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d, 0x6f, 0x64, 0x65, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e,
- 0x65, 0x6c, 0x53, 0x74, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e,
- 0x67, 0x73, 0x2e, 0x4c, 0x6f, 0x52, 0x61, 0x4e, 0x61, 0x72, 0x72, 0x6f, 0x77, 0x4d, 0x6f, 0x64,
- 0x65, 0x48, 0x00, 0x52, 0x0a, 0x6c, 0x6f, 0x72, 0x61, 0x4e, 0x61, 0x72, 0x72, 0x6f, 0x77, 0x12,
- 0x6a, 0x0a, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
- 0x0b, 0x32, 0x4c, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
- 0x76, 0x33, 0x2e, 0x41, 0x44, 0x52, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x44,
- 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d, 0x6f, 0x64, 0x65, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e,
- 0x65, 0x6c, 0x53, 0x74, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e,
- 0x67, 0x73, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x48,
- 0x00, 0x52, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x1a, 0x1a, 0x0a, 0x0e, 0x4c,
- 0x6f, 0x52, 0x61, 0x4e, 0x61, 0x72, 0x72, 0x6f, 0x77, 0x4d, 0x6f, 0x64, 0x65, 0x3a, 0x08, 0xf2,
- 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x1a, 0x18, 0x0a, 0x0c, 0x44, 0x69, 0x73, 0x61, 0x62,
- 0x6c, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10,
- 0x01, 0x3a, 0x0a, 0xf2, 0xaa, 0x19, 0x06, 0x08, 0x01, 0x10, 0x01, 0x20, 0x01, 0x42, 0x06, 0x0a,
- 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x1a,
- 0x18, 0x0a, 0x0c, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x3a,
- 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x3a, 0x0a, 0xf2, 0xaa, 0x19, 0x06, 0x08,
- 0x01, 0x10, 0x01, 0x20, 0x01, 0x42, 0x06, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x22, 0xf2, 0x15,
- 0x0a, 0x0b, 0x4d, 0x41, 0x43, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x41, 0x0a,
- 0x0f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x62, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74,
- 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0x52, 0x0d, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x42, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74,
- 0x12, 0x57, 0x0a, 0x15, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x5f, 0x70, 0x65,
- 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
- 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
- 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x56,
- 0x61, 0x6c, 0x75, 0x65, 0x52, 0x13, 0x70, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x50, 0x65,
- 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63, 0x69, 0x74, 0x79, 0x12, 0x5c, 0x0a, 0x19, 0x70, 0x69, 0x6e,
- 0x67, 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65,
- 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74,
+ 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x07, 0xfa,
+ 0x42, 0x04, 0x2a, 0x02, 0x18, 0x0f, 0x52, 0x0f, 0x6d, 0x61, 0x78, 0x54, 0x78, 0x50, 0x6f, 0x77,
+ 0x65, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x49, 0x0a, 0x0c, 0x6d, 0x69, 0x6e, 0x5f, 0x6e,
+ 0x62, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e,
+ 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
+ 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x09, 0xfa, 0x42, 0x06,
+ 0x2a, 0x04, 0x18, 0x03, 0x28, 0x01, 0x52, 0x0a, 0x6d, 0x69, 0x6e, 0x4e, 0x62, 0x54, 0x72, 0x61,
+ 0x6e, 0x73, 0x12, 0x49, 0x0a, 0x0c, 0x6d, 0x61, 0x78, 0x5f, 0x6e, 0x62, 0x5f, 0x74, 0x72, 0x61,
+ 0x6e, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
+ 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33,
+ 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x2a, 0x04, 0x18, 0x03, 0x28,
+ 0x01, 0x52, 0x0a, 0x6d, 0x61, 0x78, 0x4e, 0x62, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x12, 0x6a, 0x0a,
+ 0x10, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x73, 0x74, 0x65, 0x65, 0x72, 0x69, 0x6e,
+ 0x67, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
+ 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x44, 0x52, 0x53, 0x65, 0x74, 0x74,
+ 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d, 0x6f, 0x64, 0x65,
+ 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x53, 0x74, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67,
+ 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x0f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65,
+ 0x6c, 0x53, 0x74, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x1a, 0xc2, 0x02, 0x0a, 0x17, 0x43, 0x68,
+ 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x53, 0x74, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x74,
+ 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x71, 0x0a, 0x0b, 0x6c, 0x6f, 0x72, 0x61, 0x5f, 0x6e, 0x61,
+ 0x72, 0x72, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x4e, 0x2e, 0x74, 0x74, 0x6e,
+ 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x44, 0x52, 0x53,
+ 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d,
+ 0x6f, 0x64, 0x65, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x53, 0x74, 0x65, 0x65, 0x72,
+ 0x69, 0x6e, 0x67, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x4c, 0x6f, 0x52, 0x61,
+ 0x4e, 0x61, 0x72, 0x72, 0x6f, 0x77, 0x4d, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x0a, 0x6c, 0x6f,
+ 0x72, 0x61, 0x4e, 0x61, 0x72, 0x72, 0x6f, 0x77, 0x12, 0x6a, 0x0a, 0x08, 0x64, 0x69, 0x73, 0x61,
+ 0x62, 0x6c, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x4c, 0x2e, 0x74, 0x74, 0x6e,
+ 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x44, 0x52, 0x53,
+ 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d,
+ 0x6f, 0x64, 0x65, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x53, 0x74, 0x65, 0x65, 0x72,
+ 0x69, 0x6e, 0x67, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x44, 0x69, 0x73, 0x61,
+ 0x62, 0x6c, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x08, 0x64, 0x69, 0x73, 0x61,
+ 0x62, 0x6c, 0x65, 0x64, 0x1a, 0x1a, 0x0a, 0x0e, 0x4c, 0x6f, 0x52, 0x61, 0x4e, 0x61, 0x72, 0x72,
+ 0x6f, 0x77, 0x4d, 0x6f, 0x64, 0x65, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01,
+ 0x1a, 0x18, 0x0a, 0x0c, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x65,
+ 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x3a, 0x0a, 0xf2, 0xaa, 0x19, 0x06,
+ 0x08, 0x01, 0x10, 0x01, 0x20, 0x01, 0x42, 0x06, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x3a, 0x08,
+ 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x1a, 0x18, 0x0a, 0x0c, 0x44, 0x69, 0x73, 0x61,
+ 0x62, 0x6c, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01,
+ 0x10, 0x01, 0x3a, 0x0a, 0xf2, 0xaa, 0x19, 0x06, 0x08, 0x01, 0x10, 0x01, 0x20, 0x01, 0x42, 0x06,
+ 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x22, 0xef, 0x16, 0x0a, 0x0b, 0x4d, 0x41, 0x43, 0x53, 0x65,
+ 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x41, 0x0a, 0x0f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f,
+ 0x62, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
+ 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x63, 0x6c, 0x61, 0x73,
+ 0x73, 0x42, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x57, 0x0a, 0x15, 0x70, 0x69, 0x6e,
+ 0x67, 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63, 0x69,
+ 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c,
+ 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x53, 0x6c,
+ 0x6f, 0x74, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x13, 0x70,
+ 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63, 0x69,
+ 0x74, 0x79, 0x12, 0x5c, 0x0a, 0x19, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x5f,
+ 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18,
+ 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
+ 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49,
+ 0x6e, 0x64, 0x65, 0x78, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x15, 0x70, 0x69, 0x6e, 0x67, 0x53,
+ 0x6c, 0x6f, 0x74, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78,
+ 0x12, 0x56, 0x0a, 0x13, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x5f, 0x66, 0x72,
+ 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e,
+ 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x5a,
+ 0x65, 0x72, 0x6f, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79,
+ 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x11, 0x70, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x46,
+ 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x51, 0x0a, 0x10, 0x62, 0x65, 0x61, 0x63,
+ 0x6f, 0x6e, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x19, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
+ 0x2e, 0x76, 0x33, 0x2e, 0x5a, 0x65, 0x72, 0x6f, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x72, 0x65, 0x71,
+ 0x75, 0x65, 0x6e, 0x63, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0f, 0x62, 0x65, 0x61, 0x63,
+ 0x6f, 0x6e, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x41, 0x0a, 0x0f, 0x63,
+ 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x63, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x05,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,
+ 0x0d, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x39,
+ 0x0a, 0x09, 0x72, 0x78, 0x31, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28,
+ 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
+ 0x76, 0x33, 0x2e, 0x52, 0x78, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52,
+ 0x08, 0x72, 0x78, 0x31, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x54, 0x0a, 0x14, 0x72, 0x78, 0x31,
+ 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65,
+ 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
+ 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74,
+ 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x11, 0x72, 0x78,
+ 0x31, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12,
+ 0x51, 0x0a, 0x13, 0x72, 0x78, 0x32, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65,
+ 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74,
0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61,
0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x56, 0x61, 0x6c, 0x75, 0x65,
- 0x52, 0x15, 0x70, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61,
- 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x56, 0x0a, 0x13, 0x70, 0x69, 0x6e, 0x67, 0x5f,
- 0x73, 0x6c, 0x6f, 0x74, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x04,
- 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
- 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x5a, 0x65, 0x72, 0x6f, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x72,
- 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x11, 0x70, 0x69,
- 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12,
- 0x51, 0x0a, 0x10, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65,
- 0x6e, 0x63, 0x79, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
- 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x5a, 0x65, 0x72, 0x6f, 0x61,
- 0x62, 0x6c, 0x65, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x56, 0x61, 0x6c, 0x75,
- 0x65, 0x52, 0x0f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e,
- 0x63, 0x79, 0x12, 0x41, 0x0a, 0x0f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x63, 0x5f, 0x74, 0x69,
- 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f,
- 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75,
- 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x54, 0x69,
- 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x39, 0x0a, 0x09, 0x72, 0x78, 0x31, 0x5f, 0x64, 0x65, 0x6c,
- 0x61, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c,
- 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x78, 0x44, 0x65, 0x6c, 0x61,
- 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x72, 0x78, 0x31, 0x44, 0x65, 0x6c, 0x61, 0x79,
- 0x12, 0x54, 0x0a, 0x14, 0x72, 0x78, 0x31, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74,
- 0x65, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23,
- 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
- 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x56, 0x61,
- 0x6c, 0x75, 0x65, 0x52, 0x11, 0x72, 0x78, 0x31, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65,
- 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x51, 0x0a, 0x13, 0x72, 0x78, 0x32, 0x5f, 0x64, 0x61,
- 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x08, 0x20,
- 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
- 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64,
- 0x65, 0x78, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x10, 0x72, 0x78, 0x32, 0x44, 0x61, 0x74, 0x61,
- 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x43, 0x0a, 0x0d, 0x72, 0x78, 0x32,
- 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b,
- 0x32, 0x1e, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
- 0x33, 0x2e, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65,
- 0x52, 0x0c, 0x72, 0x78, 0x32, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x46,
- 0x0a, 0x1a, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x70, 0x72, 0x65, 0x73, 0x65, 0x74,
- 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03,
- 0x28, 0x04, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x92, 0x01, 0x02, 0x10, 0x60, 0x52, 0x18, 0x66, 0x61,
- 0x63, 0x74, 0x6f, 0x72, 0x79, 0x50, 0x72, 0x65, 0x73, 0x65, 0x74, 0x46, 0x72, 0x65, 0x71, 0x75,
- 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x12, 0x4e, 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x75,
- 0x74, 0x79, 0x5f, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28,
- 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
- 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x44, 0x75, 0x74, 0x79, 0x43, 0x79,
- 0x63, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x44, 0x75, 0x74,
- 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x4b, 0x0a, 0x15, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72,
- 0x74, 0x73, 0x5f, 0x33, 0x32, 0x5f, 0x62, 0x69, 0x74, 0x5f, 0x66, 0x5f, 0x63, 0x6e, 0x74, 0x18,
- 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
- 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65,
- 0x52, 0x11, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x33, 0x32, 0x42, 0x69, 0x74, 0x46,
- 0x43, 0x6e, 0x74, 0x12, 0x36, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x5f, 0x61, 0x64, 0x72, 0x18, 0x0d,
- 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
- 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42,
- 0x02, 0x18, 0x01, 0x52, 0x06, 0x75, 0x73, 0x65, 0x41, 0x64, 0x72, 0x12, 0x3e, 0x0a, 0x0a, 0x61,
- 0x64, 0x72, 0x5f, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32,
- 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
- 0x66, 0x2e, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x02, 0x18, 0x01,
- 0x52, 0x09, 0x61, 0x64, 0x72, 0x4d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x12, 0x3b, 0x0a, 0x0c, 0x72,
- 0x65, 0x73, 0x65, 0x74, 0x73, 0x5f, 0x66, 0x5f, 0x63, 0x6e, 0x74, 0x18, 0x0f, 0x20, 0x01, 0x28,
- 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
- 0x76, 0x33, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x72, 0x65,
- 0x73, 0x65, 0x74, 0x73, 0x46, 0x43, 0x6e, 0x74, 0x12, 0x51, 0x0a, 0x17, 0x73, 0x74, 0x61, 0x74,
- 0x75, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63,
- 0x69, 0x74, 0x79, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
- 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61,
- 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x15, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x54, 0x69, 0x6d, 0x65,
- 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63, 0x69, 0x74, 0x79, 0x12, 0x56, 0x0a, 0x18, 0x73,
- 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x70, 0x65, 0x72, 0x69,
- 0x6f, 0x64, 0x69, 0x63, 0x69, 0x74, 0x79, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e,
- 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
- 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x16, 0x73, 0x74, 0x61,
- 0x74, 0x75, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63,
- 0x69, 0x74, 0x79, 0x12, 0x48, 0x0a, 0x11, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x72,
- 0x78, 0x31, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c,
+ 0x52, 0x10, 0x72, 0x78, 0x32, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64,
+ 0x65, 0x78, 0x12, 0x43, 0x0a, 0x0d, 0x72, 0x78, 0x32, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65,
+ 0x6e, 0x63, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
+ 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x46, 0x72, 0x65, 0x71, 0x75,
+ 0x65, 0x6e, 0x63, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x72, 0x78, 0x32, 0x46, 0x72,
+ 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x46, 0x0a, 0x1a, 0x66, 0x61, 0x63, 0x74, 0x6f,
+ 0x72, 0x79, 0x5f, 0x70, 0x72, 0x65, 0x73, 0x65, 0x74, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65,
+ 0x6e, 0x63, 0x69, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x04, 0x42, 0x08, 0xfa, 0x42, 0x05,
+ 0x92, 0x01, 0x02, 0x10, 0x60, 0x52, 0x18, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x50, 0x72,
+ 0x65, 0x73, 0x65, 0x74, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x12,
+ 0x4e, 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x75, 0x74, 0x79, 0x5f, 0x63, 0x79, 0x63, 0x6c,
+ 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
+ 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61,
+ 0x74, 0x65, 0x64, 0x44, 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75,
+ 0x65, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x44, 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x12,
+ 0x4b, 0x0a, 0x15, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x5f, 0x33, 0x32, 0x5f, 0x62,
+ 0x69, 0x74, 0x5f, 0x66, 0x5f, 0x63, 0x6e, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19,
0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
- 0x52, 0x78, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0f, 0x64, 0x65,
- 0x73, 0x69, 0x72, 0x65, 0x64, 0x52, 0x78, 0x31, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x63, 0x0a,
- 0x1c, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x72, 0x78, 0x31, 0x5f, 0x64, 0x61, 0x74,
- 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x13, 0x20,
- 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
- 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x4f, 0x66, 0x66,
- 0x73, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x18, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65,
- 0x64, 0x52, 0x78, 0x31, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x4f, 0x66, 0x66, 0x73,
- 0x65, 0x74, 0x12, 0x60, 0x0a, 0x1b, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x72, 0x78,
- 0x32, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65,
- 0x78, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
+ 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x11, 0x73, 0x75, 0x70, 0x70, 0x6f,
+ 0x72, 0x74, 0x73, 0x33, 0x32, 0x42, 0x69, 0x74, 0x46, 0x43, 0x6e, 0x74, 0x12, 0x36, 0x0a, 0x07,
+ 0x75, 0x73, 0x65, 0x5f, 0x61, 0x64, 0x72, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e,
+ 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x42,
+ 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x02, 0x18, 0x01, 0x52, 0x06, 0x75, 0x73,
+ 0x65, 0x41, 0x64, 0x72, 0x12, 0x3e, 0x0a, 0x0a, 0x61, 0x64, 0x72, 0x5f, 0x6d, 0x61, 0x72, 0x67,
+ 0x69, 0x6e, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
+ 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x6c, 0x6f, 0x61, 0x74,
+ 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x02, 0x18, 0x01, 0x52, 0x09, 0x61, 0x64, 0x72, 0x4d, 0x61,
+ 0x72, 0x67, 0x69, 0x6e, 0x12, 0x3b, 0x0a, 0x0c, 0x72, 0x65, 0x73, 0x65, 0x74, 0x73, 0x5f, 0x66,
+ 0x5f, 0x63, 0x6e, 0x74, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x74, 0x6e,
+ 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x42, 0x6f, 0x6f, 0x6c,
+ 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x65, 0x74, 0x73, 0x46, 0x43, 0x6e,
+ 0x74, 0x12, 0x51, 0x0a, 0x17, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65,
+ 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63, 0x69, 0x74, 0x79, 0x18, 0x10, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x15, 0x73,
+ 0x74, 0x61, 0x74, 0x75, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69,
+ 0x63, 0x69, 0x74, 0x79, 0x12, 0x56, 0x0a, 0x18, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x63,
+ 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63, 0x69, 0x74, 0x79,
+ 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56,
+ 0x61, 0x6c, 0x75, 0x65, 0x52, 0x16, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, 0x75, 0x6e,
+ 0x74, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63, 0x69, 0x74, 0x79, 0x12, 0x48, 0x0a, 0x11,
+ 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x72, 0x78, 0x31, 0x5f, 0x64, 0x65, 0x6c, 0x61,
+ 0x79, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
+ 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x78, 0x44, 0x65, 0x6c, 0x61, 0x79,
+ 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0f, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x52, 0x78,
+ 0x31, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x63, 0x0a, 0x1c, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65,
+ 0x64, 0x5f, 0x72, 0x78, 0x31, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f,
+ 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74,
+ 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61,
+ 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75,
+ 0x65, 0x52, 0x18, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x52, 0x78, 0x31, 0x44, 0x61, 0x74,
+ 0x61, 0x52, 0x61, 0x74, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x60, 0x0a, 0x1b, 0x64,
+ 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x72, 0x78, 0x32, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f,
+ 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x22, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
+ 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x56,
+ 0x61, 0x6c, 0x75, 0x65, 0x52, 0x17, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x52, 0x78, 0x32,
+ 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x52, 0x0a,
+ 0x15, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x72, 0x78, 0x32, 0x5f, 0x66, 0x72, 0x65,
+ 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74,
+ 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x46, 0x72,
+ 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x13, 0x64, 0x65,
+ 0x73, 0x69, 0x72, 0x65, 0x64, 0x52, 0x78, 0x32, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63,
+ 0x79, 0x12, 0x5d, 0x0a, 0x16, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x6d, 0x61, 0x78,
+ 0x5f, 0x64, 0x75, 0x74, 0x79, 0x5f, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x18, 0x16, 0x20, 0x01, 0x28,
+ 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
+ 0x76, 0x33, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x44, 0x75, 0x74,
+ 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x13, 0x64, 0x65, 0x73,
+ 0x69, 0x72, 0x65, 0x64, 0x4d, 0x61, 0x78, 0x44, 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65,
+ 0x12, 0x6c, 0x0a, 0x1e, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x61, 0x64, 0x72, 0x5f,
+ 0x61, 0x63, 0x6b, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x6e, 0x65,
+ 0x6e, 0x74, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c,
+ 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x44, 0x52, 0x41, 0x63, 0x6b,
+ 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x6c,
+ 0x75, 0x65, 0x52, 0x1a, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x41, 0x64, 0x72, 0x41, 0x63,
+ 0x6b, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x6c,
+ 0x0a, 0x1e, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x61, 0x64, 0x72, 0x5f, 0x61, 0x63,
+ 0x6b, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74,
+ 0x18, 0x18, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
+ 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x44, 0x52, 0x41, 0x63, 0x6b, 0x44, 0x65,
+ 0x6c, 0x61, 0x79, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65,
+ 0x52, 0x1a, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x41, 0x64, 0x72, 0x41, 0x63, 0x6b, 0x44,
+ 0x65, 0x6c, 0x61, 0x79, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x6b, 0x0a, 0x21,
+ 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x6c, 0x6f,
+ 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65,
+ 0x78, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74,
- 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x17, 0x64, 0x65, 0x73,
- 0x69, 0x72, 0x65, 0x64, 0x52, 0x78, 0x32, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49,
- 0x6e, 0x64, 0x65, 0x78, 0x12, 0x52, 0x0a, 0x15, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x5f,
- 0x72, 0x78, 0x32, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x15, 0x20,
- 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
- 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x56, 0x61,
- 0x6c, 0x75, 0x65, 0x52, 0x13, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x52, 0x78, 0x32, 0x46,
- 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x5d, 0x0a, 0x16, 0x64, 0x65, 0x73, 0x69,
- 0x72, 0x65, 0x64, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x75, 0x74, 0x79, 0x5f, 0x63, 0x79, 0x63,
- 0x6c, 0x65, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c,
- 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67,
- 0x61, 0x74, 0x65, 0x64, 0x44, 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x56, 0x61, 0x6c,
- 0x75, 0x65, 0x52, 0x13, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x4d, 0x61, 0x78, 0x44, 0x75,
- 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x6c, 0x0a, 0x1e, 0x64, 0x65, 0x73, 0x69, 0x72,
- 0x65, 0x64, 0x5f, 0x61, 0x64, 0x72, 0x5f, 0x61, 0x63, 0x6b, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74,
- 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32,
- 0x28, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
- 0x2e, 0x41, 0x44, 0x52, 0x41, 0x63, 0x6b, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x45, 0x78, 0x70, 0x6f,
- 0x6e, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x1a, 0x64, 0x65, 0x73, 0x69, 0x72,
- 0x65, 0x64, 0x41, 0x64, 0x72, 0x41, 0x63, 0x6b, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x45, 0x78, 0x70,
- 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x6c, 0x0a, 0x1e, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64,
- 0x5f, 0x61, 0x64, 0x72, 0x5f, 0x61, 0x63, 0x6b, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x65,
- 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e,
- 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41,
- 0x44, 0x52, 0x41, 0x63, 0x6b, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65,
- 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x1a, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64,
- 0x41, 0x64, 0x72, 0x41, 0x63, 0x6b, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x45, 0x78, 0x70, 0x6f, 0x6e,
- 0x65, 0x6e, 0x74, 0x12, 0x6b, 0x0a, 0x21, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x70,
- 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61,
- 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22,
+ 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x1c, 0x64, 0x65, 0x73,
+ 0x69, 0x72, 0x65, 0x64, 0x50, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x44, 0x61, 0x74, 0x61,
+ 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x65, 0x0a, 0x1b, 0x64, 0x65, 0x73,
+ 0x69, 0x72, 0x65, 0x64, 0x5f, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x5f, 0x66,
+ 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26,
0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
- 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x56, 0x61, 0x6c,
- 0x75, 0x65, 0x52, 0x1c, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x50, 0x69, 0x6e, 0x67, 0x53,
- 0x6c, 0x6f, 0x74, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78,
- 0x12, 0x65, 0x0a, 0x1b, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x70, 0x69, 0x6e, 0x67,
- 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18,
- 0x1c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
- 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x5a, 0x65, 0x72, 0x6f, 0x61, 0x62, 0x6c, 0x65, 0x46,
- 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x18, 0x64,
- 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x50, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x46, 0x72,
- 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x60, 0x0a, 0x18, 0x64, 0x65, 0x73, 0x69, 0x72,
- 0x65, 0x64, 0x5f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65,
- 0x6e, 0x63, 0x79, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
- 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x5a, 0x65, 0x72, 0x6f, 0x61,
- 0x62, 0x6c, 0x65, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x56, 0x61, 0x6c, 0x75,
- 0x65, 0x52, 0x16, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e,
- 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x49, 0x0a, 0x10, 0x64, 0x65, 0x73,
- 0x69, 0x72, 0x65, 0x64, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x65, 0x69, 0x72, 0x70, 0x18, 0x1e, 0x20,
- 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
- 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, 0x49, 0x52, 0x50, 0x56,
- 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x4d, 0x61, 0x78,
- 0x45, 0x69, 0x72, 0x70, 0x12, 0x57, 0x0a, 0x1b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x62, 0x5f,
- 0x63, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72,
- 0x76, 0x61, 0x6c, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
- 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61,
- 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x17, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x42, 0x43, 0x44, 0x6f, 0x77,
- 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x45, 0x0a,
- 0x11, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x64, 0x77, 0x65, 0x6c, 0x6c, 0x5f, 0x74, 0x69,
- 0x6d, 0x65, 0x18, 0x20, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c,
- 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61,
- 0x6c, 0x75, 0x65, 0x52, 0x0f, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x44, 0x77, 0x65, 0x6c, 0x6c,
- 0x54, 0x69, 0x6d, 0x65, 0x12, 0x49, 0x0a, 0x13, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b,
- 0x5f, 0x64, 0x77, 0x65, 0x6c, 0x6c, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x21, 0x20, 0x01, 0x28,
+ 0x5a, 0x65, 0x72, 0x6f, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63,
+ 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x18, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x50,
+ 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79,
+ 0x12, 0x60, 0x0a, 0x18, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x62, 0x65, 0x61, 0x63,
+ 0x6f, 0x6e, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x1d, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
+ 0x2e, 0x76, 0x33, 0x2e, 0x5a, 0x65, 0x72, 0x6f, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x72, 0x65, 0x71,
+ 0x75, 0x65, 0x6e, 0x63, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x16, 0x64, 0x65, 0x73, 0x69,
+ 0x72, 0x65, 0x64, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e,
+ 0x63, 0x79, 0x12, 0x49, 0x0a, 0x10, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x6d, 0x61,
+ 0x78, 0x5f, 0x65, 0x69, 0x72, 0x70, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74,
+ 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x65,
+ 0x76, 0x69, 0x63, 0x65, 0x45, 0x49, 0x52, 0x50, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x64,
+ 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x4d, 0x61, 0x78, 0x45, 0x69, 0x72, 0x70, 0x12, 0x57, 0x0a,
+ 0x1b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x62, 0x5f, 0x63, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x6c,
+ 0x69, 0x6e, 0x6b, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x1f, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x17, 0x63,
+ 0x6c, 0x61, 0x73, 0x73, 0x42, 0x43, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x49, 0x6e,
+ 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x45, 0x0a, 0x11, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b,
+ 0x5f, 0x64, 0x77, 0x65, 0x6c, 0x6c, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x20, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x19, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
- 0x76, 0x33, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x11, 0x64, 0x6f,
- 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x44, 0x77, 0x65, 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x12,
- 0x2d, 0x0a, 0x03, 0x61, 0x64, 0x72, 0x18, 0x22, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74,
- 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x44,
- 0x52, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x03, 0x61, 0x64, 0x72, 0x12, 0x48,
- 0x0a, 0x12, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x6c,
- 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x23, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x74, 0x6e,
+ 0x76, 0x33, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0f, 0x75, 0x70,
+ 0x6c, 0x69, 0x6e, 0x6b, 0x44, 0x77, 0x65, 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x49, 0x0a,
+ 0x13, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x64, 0x77, 0x65, 0x6c, 0x6c, 0x5f,
+ 0x74, 0x69, 0x6d, 0x65, 0x18, 0x21, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x74, 0x6e,
0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x42, 0x6f, 0x6f, 0x6c,
- 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x11, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x44,
- 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01,
- 0x10, 0x01, 0x22, 0x96, 0x28, 0x0a, 0x08, 0x4d, 0x41, 0x43, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12,
- 0x56, 0x0a, 0x12, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d,
- 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x74,
+ 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x11, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x44,
+ 0x77, 0x65, 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x2d, 0x0a, 0x03, 0x61, 0x64, 0x72, 0x18,
+ 0x22, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
+ 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x44, 0x52, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e,
+ 0x67, 0x73, 0x52, 0x03, 0x61, 0x64, 0x72, 0x12, 0x48, 0x0a, 0x12, 0x73, 0x63, 0x68, 0x65, 0x64,
+ 0x75, 0x6c, 0x65, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x23, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
+ 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x11,
+ 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b,
+ 0x73, 0x12, 0x35, 0x0a, 0x05, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x24, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x1f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
+ 0x33, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72,
+ 0x73, 0x52, 0x05, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x44, 0x0a, 0x0d, 0x64, 0x65, 0x73, 0x69,
+ 0x72, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x25, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x1f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
+ 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73,
+ 0x52, 0x0c, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x3a, 0x08,
+ 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x22, 0xef, 0x29, 0x0a, 0x08, 0x4d, 0x41, 0x43,
+ 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x56, 0x0a, 0x12, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74,
+ 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
+ 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73,
+ 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x11, 0x63, 0x75, 0x72, 0x72,
+ 0x65, 0x6e, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x56, 0x0a,
+ 0x12, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74,
+ 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
+ 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x50, 0x61,
+ 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02,
+ 0x10, 0x01, 0x52, 0x11, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d,
+ 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x42, 0x0a, 0x0c, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f,
+ 0x63, 0x6c, 0x61, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x74, 0x74,
+ 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x6c, 0x61,
+ 0x73, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0b, 0x64, 0x65,
+ 0x76, 0x69, 0x63, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x12, 0x4d, 0x0a, 0x0f, 0x6c, 0x6f, 0x72,
+ 0x61, 0x77, 0x61, 0x6e, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01,
+ 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
+ 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x08,
+ 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
+ 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x57, 0x0a, 0x1a, 0x6c, 0x61, 0x73, 0x74,
+ 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x6c,
+ 0x69, 0x6e, 0x6b, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67,
+ 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54,
+ 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x17, 0x6c, 0x61, 0x73, 0x74, 0x43, 0x6f,
+ 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x41,
+ 0x74, 0x12, 0x35, 0x0a, 0x18, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x64, 0x65, 0x76, 0x5f, 0x73, 0x74,
+ 0x61, 0x74, 0x75, 0x73, 0x5f, 0x66, 0x5f, 0x63, 0x6e, 0x74, 0x5f, 0x75, 0x70, 0x18, 0x06, 0x20,
+ 0x01, 0x28, 0x0d, 0x52, 0x13, 0x6c, 0x61, 0x73, 0x74, 0x44, 0x65, 0x76, 0x53, 0x74, 0x61, 0x74,
+ 0x75, 0x73, 0x46, 0x43, 0x6e, 0x74, 0x55, 0x70, 0x12, 0x57, 0x0a, 0x15, 0x70, 0x69, 0x6e, 0x67,
+ 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63, 0x69, 0x74,
+ 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
+ 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f,
+ 0x74, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x13, 0x70, 0x69,
+ 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63, 0x69, 0x74,
+ 0x79, 0x12, 0x65, 0x0a, 0x1c, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x70, 0x70,
+ 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e,
+ 0x6b, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
+ 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x52, 0x1a, 0x70, 0x65,
+ 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+ 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x45, 0x0a, 0x10, 0x71, 0x75, 0x65, 0x75,
+ 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03,
+ 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
+ 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x0f,
+ 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x12,
+ 0x45, 0x0a, 0x10, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65,
+ 0x73, 0x74, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
+ 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f,
+ 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x0f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65,
+ 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, 0x51, 0x0a, 0x12, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64,
+ 0x5f, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x18, 0x0b, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
+ 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4a, 0x6f, 0x69,
+ 0x6e, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, 0x10, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x4a,
+ 0x6f, 0x69, 0x6e, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x12, 0x56, 0x0a, 0x14, 0x70, 0x65, 0x6e,
+ 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73,
+ 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
+ 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x53, 0x74, 0x61, 0x74,
+ 0x65, 0x2e, 0x4a, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x12, 0x70,
+ 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4a, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+ 0x74, 0x12, 0x30, 0x0a, 0x14, 0x72, 0x78, 0x5f, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x5f,
+ 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52,
+ 0x12, 0x72, 0x78, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61,
+ 0x62, 0x6c, 0x65, 0x12, 0x4d, 0x0a, 0x0e, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x5f, 0x75, 0x70,
+ 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x74,
0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43,
- 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a,
- 0x01, 0x02, 0x10, 0x01, 0x52, 0x11, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x50, 0x61, 0x72,
- 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x56, 0x0a, 0x12, 0x64, 0x65, 0x73, 0x69, 0x72,
- 0x65, 0x64, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20,
- 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
- 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65,
- 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x11, 0x64, 0x65,
- 0x73, 0x69, 0x72, 0x65, 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12,
- 0x42, 0x0a, 0x0c, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x18,
- 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
- 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x42, 0x08, 0xfa, 0x42,
- 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0b, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6c,
- 0x61, 0x73, 0x73, 0x12, 0x4d, 0x0a, 0x0f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x5f, 0x76,
- 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74,
- 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41,
- 0x43, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02,
- 0x10, 0x01, 0x52, 0x0e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69,
- 0x6f, 0x6e, 0x12, 0x57, 0x0a, 0x1a, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69,
- 0x72, 0x6d, 0x65, 0x64, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x61, 0x74,
- 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
- 0x6d, 0x70, 0x52, 0x17, 0x6c, 0x61, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65,
- 0x64, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x41, 0x74, 0x12, 0x35, 0x0a, 0x18, 0x6c,
- 0x61, 0x73, 0x74, 0x5f, 0x64, 0x65, 0x76, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x66,
- 0x5f, 0x63, 0x6e, 0x74, 0x5f, 0x75, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, 0x6c,
- 0x61, 0x73, 0x74, 0x44, 0x65, 0x76, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x46, 0x43, 0x6e, 0x74,
- 0x55, 0x70, 0x12, 0x57, 0x0a, 0x15, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x5f,
- 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63, 0x69, 0x74, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28,
- 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
- 0x76, 0x33, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x50, 0x65, 0x72, 0x69, 0x6f,
- 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x13, 0x70, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74,
- 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63, 0x69, 0x74, 0x79, 0x12, 0x65, 0x0a, 0x1c, 0x70,
- 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69,
- 0x6f, 0x6e, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x08, 0x20, 0x01, 0x28,
- 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
- 0x76, 0x33, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x6f,
- 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x52, 0x1a, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x41,
- 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69,
- 0x6e, 0x6b, 0x12, 0x45, 0x0a, 0x10, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73,
- 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74,
- 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41,
- 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x0f, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64,
- 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x12, 0x45, 0x0a, 0x10, 0x70, 0x65, 0x6e,
- 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x0a, 0x20,
- 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
- 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52,
- 0x0f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73,
- 0x12, 0x51, 0x0a, 0x12, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x5f, 0x6a, 0x6f, 0x69, 0x6e, 0x5f,
- 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74,
+ 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x4d, 0x65, 0x73, 0x73,
+ 0x61, 0x67, 0x65, 0x52, 0x0d, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x55, 0x70, 0x6c, 0x69, 0x6e,
+ 0x6b, 0x73, 0x12, 0x53, 0x0a, 0x10, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x5f, 0x64, 0x6f, 0x77,
+ 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74,
0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41,
- 0x43, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4a, 0x6f, 0x69, 0x6e, 0x41, 0x63, 0x63, 0x65, 0x70,
- 0x74, 0x52, 0x10, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x4a, 0x6f, 0x69, 0x6e, 0x41, 0x63, 0x63,
- 0x65, 0x70, 0x74, 0x12, 0x56, 0x0a, 0x14, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x6a,
- 0x6f, 0x69, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28,
- 0x0b, 0x32, 0x24, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
- 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4a, 0x6f, 0x69, 0x6e,
- 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x12, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67,
- 0x4a, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x30, 0x0a, 0x14, 0x72,
- 0x78, 0x5f, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x5f, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61,
- 0x62, 0x6c, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x72, 0x78, 0x57, 0x69, 0x6e,
- 0x64, 0x6f, 0x77, 0x73, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x4d, 0x0a,
- 0x0e, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x5f, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18,
- 0x0e, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
- 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e,
- 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0d, 0x72,
- 0x65, 0x63, 0x65, 0x6e, 0x74, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x12, 0x53, 0x0a, 0x10,
- 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73,
- 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
- 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x53, 0x74, 0x61, 0x74, 0x65,
- 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
- 0x52, 0x0f, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b,
- 0x73, 0x12, 0x66, 0x0a, 0x22, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72,
- 0x6b, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x64, 0x6f, 0x77, 0x6e,
- 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x61, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
- 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
- 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x1e, 0x6c, 0x61, 0x73, 0x74, 0x4e,
- 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x65, 0x64, 0x44,
- 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x41, 0x74, 0x12, 0x72, 0x0a, 0x1e, 0x72, 0x65, 0x6a,
- 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x64, 0x72, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72,
- 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x73, 0x18, 0x11, 0x20, 0x03, 0x28,
- 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
- 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78,
- 0x42, 0x0f, 0xfa, 0x42, 0x0c, 0x92, 0x01, 0x09, 0x10, 0x0f, 0x22, 0x05, 0x82, 0x01, 0x02, 0x10,
- 0x01, 0x52, 0x1a, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x41, 0x64, 0x72, 0x44, 0x61,
- 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x73, 0x12, 0x50, 0x0a,
- 0x1d, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x64, 0x72, 0x5f, 0x74, 0x78,
- 0x5f, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x73, 0x18, 0x12,
- 0x20, 0x03, 0x28, 0x0d, 0x42, 0x0e, 0xfa, 0x42, 0x0b, 0x92, 0x01, 0x08, 0x10, 0x0f, 0x22, 0x04,
- 0x2a, 0x02, 0x18, 0x0f, 0x52, 0x19, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x41, 0x64,
- 0x72, 0x54, 0x78, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x73, 0x12,
- 0x41, 0x0a, 0x14, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x66, 0x72, 0x65, 0x71,
- 0x75, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x18, 0x13, 0x20, 0x03, 0x28, 0x04, 0x42, 0x0e, 0xfa,
- 0x42, 0x0b, 0x92, 0x01, 0x08, 0x22, 0x06, 0x32, 0x04, 0x28, 0xa0, 0x8d, 0x06, 0x52, 0x13, 0x72,
- 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x69,
- 0x65, 0x73, 0x12, 0x44, 0x0a, 0x10, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x6c,
- 0x69, 0x6e, 0x6b, 0x5f, 0x61, 0x74, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67,
- 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54,
- 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x44, 0x6f,
- 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x41, 0x74, 0x12, 0x6f, 0x0a, 0x19, 0x72, 0x65, 0x6a, 0x65,
- 0x63, 0x74, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x72,
- 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x15, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x74, 0x74,
+ 0x43, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x4d,
+ 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0f, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x44, 0x6f,
+ 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x12, 0x66, 0x0a, 0x22, 0x6c, 0x61, 0x73, 0x74, 0x5f,
+ 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x65,
+ 0x64, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x61, 0x74, 0x18, 0x10, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52,
+ 0x1e, 0x6c, 0x61, 0x73, 0x74, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x6e, 0x69, 0x74,
+ 0x69, 0x61, 0x74, 0x65, 0x64, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x41, 0x74, 0x12,
+ 0x72, 0x0a, 0x1e, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x64, 0x72, 0x5f,
+ 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x65,
+ 0x73, 0x18, 0x11, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
+ 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74,
+ 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x42, 0x0f, 0xfa, 0x42, 0x0c, 0x92, 0x01, 0x09, 0x10, 0x0f,
+ 0x22, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x1a, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65,
+ 0x64, 0x41, 0x64, 0x72, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65,
+ 0x78, 0x65, 0x73, 0x12, 0x50, 0x0a, 0x1d, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f,
+ 0x61, 0x64, 0x72, 0x5f, 0x74, 0x78, 0x5f, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x64,
+ 0x65, 0x78, 0x65, 0x73, 0x18, 0x12, 0x20, 0x03, 0x28, 0x0d, 0x42, 0x0e, 0xfa, 0x42, 0x0b, 0x92,
+ 0x01, 0x08, 0x10, 0x0f, 0x22, 0x04, 0x2a, 0x02, 0x18, 0x0f, 0x52, 0x19, 0x72, 0x65, 0x6a, 0x65,
+ 0x63, 0x74, 0x65, 0x64, 0x41, 0x64, 0x72, 0x54, 0x78, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x49, 0x6e,
+ 0x64, 0x65, 0x78, 0x65, 0x73, 0x12, 0x41, 0x0a, 0x14, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65,
+ 0x64, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x18, 0x13, 0x20,
+ 0x03, 0x28, 0x04, 0x42, 0x0e, 0xfa, 0x42, 0x0b, 0x92, 0x01, 0x08, 0x22, 0x06, 0x32, 0x04, 0x28,
+ 0xa0, 0x8d, 0x06, 0x52, 0x13, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x46, 0x72, 0x65,
+ 0x71, 0x75, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x12, 0x44, 0x0a, 0x10, 0x6c, 0x61, 0x73, 0x74,
+ 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x61, 0x74, 0x18, 0x14, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0e,
+ 0x6c, 0x61, 0x73, 0x74, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x41, 0x74, 0x12, 0x6f,
+ 0x0a, 0x19, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f,
+ 0x72, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x15, 0x20, 0x03, 0x28,
+ 0x0b, 0x32, 0x34, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
+ 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x6a, 0x65,
+ 0x63, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x52, 0x61, 0x6e, 0x67,
+ 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x16, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65,
+ 0x64, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12,
+ 0x35, 0x0a, 0x18, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x61, 0x64, 0x72, 0x5f, 0x63, 0x68, 0x61, 0x6e,
+ 0x67, 0x65, 0x5f, 0x66, 0x5f, 0x63, 0x6e, 0x74, 0x5f, 0x75, 0x70, 0x18, 0x16, 0x20, 0x01, 0x28,
+ 0x0d, 0x52, 0x13, 0x6c, 0x61, 0x73, 0x74, 0x41, 0x64, 0x72, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65,
+ 0x46, 0x43, 0x6e, 0x74, 0x55, 0x70, 0x12, 0x69, 0x0a, 0x1e, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74,
+ 0x5f, 0x6d, 0x61, 0x63, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x65,
+ 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x18, 0x17, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x24,
+ 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
+ 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69,
+ 0x66, 0x69, 0x65, 0x72, 0x52, 0x1b, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x63, 0x43,
+ 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72,
+ 0x73, 0x12, 0x5d, 0x0a, 0x16, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x65, 0x6c,
+ 0x61, 0x79, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x18, 0x20, 0x01, 0x28,
+ 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
+ 0x76, 0x33, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x44,
+ 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x71, 0x52, 0x14, 0x70, 0x65, 0x6e, 0x64,
+ 0x69, 0x6e, 0x67, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b,
+ 0x1a, 0x83, 0x02, 0x0a, 0x0b, 0x4a, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+ 0x12, 0x51, 0x0a, 0x11, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x73, 0x65, 0x74,
+ 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x74,
+ 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x4c, 0x53,
+ 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10,
+ 0x01, 0x52, 0x10, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x53, 0x65, 0x74, 0x74, 0x69,
+ 0x6e, 0x67, 0x73, 0x12, 0x3c, 0x0a, 0x08, 0x72, 0x78, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x18,
+ 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
+ 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x78, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x42, 0x08,
+ 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x07, 0x72, 0x78, 0x44, 0x65, 0x6c, 0x61,
+ 0x79, 0x12, 0x2f, 0x0a, 0x07, 0x63, 0x66, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x08, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
+ 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x46, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x06, 0x63, 0x66, 0x4c, 0x69,
+ 0x73, 0x74, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x4a, 0x04, 0x08, 0x01,
+ 0x10, 0x02, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x4a, 0x04,
+ 0x08, 0x04, 0x10, 0x05, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a,
+ 0x4a, 0x04, 0x08, 0x0a, 0x10, 0x0b, 0x1a, 0xd1, 0x07, 0x0a, 0x0a, 0x4a, 0x6f, 0x69, 0x6e, 0x41,
+ 0x63, 0x63, 0x65, 0x70, 0x74, 0x12, 0x23, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x7a, 0x04, 0x10, 0x11, 0x18,
+ 0x21, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x48, 0x0a, 0x07, 0x72, 0x65,
+ 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x74, 0x74,
0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43,
- 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x44, 0x61,
- 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72,
- 0x79, 0x52, 0x16, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x52,
- 0x61, 0x74, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x35, 0x0a, 0x18, 0x6c, 0x61, 0x73,
- 0x74, 0x5f, 0x61, 0x64, 0x72, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x5f, 0x66, 0x5f, 0x63,
- 0x6e, 0x74, 0x5f, 0x75, 0x70, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, 0x6c, 0x61, 0x73,
- 0x74, 0x41, 0x64, 0x72, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x46, 0x43, 0x6e, 0x74, 0x55, 0x70,
- 0x12, 0x69, 0x0a, 0x1e, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x61, 0x63, 0x5f, 0x63,
- 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65,
- 0x72, 0x73, 0x18, 0x17, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c,
- 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d,
- 0x6d, 0x61, 0x6e, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x1b,
- 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64,
- 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x1a, 0x83, 0x02, 0x0a, 0x0b,
- 0x4a, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x51, 0x0a, 0x11, 0x64,
- 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73,
- 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
- 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x4c, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e,
- 0x67, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x10, 0x64, 0x6f,
- 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x3c,
- 0x0a, 0x08, 0x72, 0x78, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e,
- 0x32, 0x17, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
- 0x33, 0x2e, 0x52, 0x78, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01,
- 0x02, 0x10, 0x01, 0x52, 0x07, 0x72, 0x78, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x2f, 0x0a, 0x07,
- 0x63, 0x66, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e,
- 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x43,
- 0x46, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x06, 0x63, 0x66, 0x4c, 0x69, 0x73, 0x74, 0x3a, 0x08, 0xf2,
- 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x4a, 0x04, 0x08,
- 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x4a,
- 0x04, 0x08, 0x05, 0x10, 0x06, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x0a, 0x10,
- 0x0b, 0x1a, 0xd1, 0x07, 0x0a, 0x0a, 0x4a, 0x6f, 0x69, 0x6e, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74,
- 0x12, 0x23, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
- 0x0c, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x7a, 0x04, 0x10, 0x11, 0x18, 0x21, 0x52, 0x07, 0x70, 0x61,
- 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x48, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
- 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
- 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x53, 0x74, 0x61, 0x74, 0x65,
- 0x2e, 0x4a, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x42, 0x08, 0xfa, 0x42,
- 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
- 0x39, 0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e,
- 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x53,
- 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a,
- 0x01, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x12, 0x35, 0x0a, 0x0f, 0x63, 0x6f,
- 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x04, 0x20,
- 0x03, 0x28, 0x09, 0x42, 0x0c, 0xfa, 0x42, 0x09, 0x92, 0x01, 0x06, 0x22, 0x04, 0x72, 0x02, 0x18,
- 0x64, 0x52, 0x0e, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64,
- 0x73, 0x12, 0xed, 0x02, 0x0a, 0x08, 0x64, 0x65, 0x76, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x05,
- 0x20, 0x01, 0x28, 0x0c, 0x42, 0xd1, 0x02, 0x92, 0x41, 0x19, 0x4a, 0x0a, 0x22, 0x32, 0x36, 0x30,
- 0x30, 0x41, 0x42, 0x43, 0x44, 0x22, 0x9a, 0x02, 0x01, 0x07, 0xa2, 0x02, 0x06, 0x73, 0x74, 0x72,
- 0x69, 0x6e, 0x67, 0xfa, 0x42, 0x06, 0x7a, 0x04, 0x68, 0x04, 0x70, 0x01, 0xea, 0xaa, 0x19, 0x82,
- 0x01, 0x0a, 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e,
- 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d,
- 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x79, 0x70,
- 0x65, 0x73, 0x2e, 0x4d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x48, 0x45, 0x58, 0x42, 0x79, 0x74,
- 0x65, 0x73, 0x12, 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73,
- 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
- 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x79,
- 0x70, 0x65, 0x73, 0x2e, 0x55, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x34, 0x42, 0x79,
- 0x74, 0x65, 0x73, 0xf2, 0xaa, 0x19, 0xa0, 0x01, 0x1a, 0x4e, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65,
- 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c,
- 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f,
- 0x63, 0x6d, 0x64, 0x2f, 0x74, 0x74, 0x6e, 0x2d, 0x6c, 0x77, 0x2d, 0x63, 0x6c, 0x69, 0x2f, 0x63,
- 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x2e, 0x4e, 0x65, 0x77, 0x34, 0x42,
- 0x79, 0x74, 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x22, 0x4e, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65,
- 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c,
- 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f,
- 0x63, 0x6d, 0x64, 0x2f, 0x74, 0x74, 0x6e, 0x2d, 0x6c, 0x77, 0x2d, 0x63, 0x6c, 0x69, 0x2f, 0x63,
- 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78,
- 0x61, 0x63, 0x74, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x07, 0x64, 0x65, 0x76, 0x41, 0x64, 0x64,
- 0x72, 0x12, 0xe7, 0x02, 0x0a, 0x06, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01,
- 0x28, 0x0c, 0x42, 0xcf, 0x02, 0x92, 0x41, 0x17, 0x4a, 0x08, 0x22, 0x30, 0x30, 0x30, 0x30, 0x31,
- 0x33, 0x22, 0x9a, 0x02, 0x01, 0x07, 0xa2, 0x02, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0xfa,
- 0x42, 0x06, 0x7a, 0x04, 0x68, 0x03, 0x70, 0x01, 0xea, 0xaa, 0x19, 0x82, 0x01, 0x0a, 0x3f, 0x67,
+ 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4a, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+ 0x74, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x07, 0x72, 0x65, 0x71,
+ 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x03, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
+ 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x42,
+ 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x12,
+ 0x35, 0x0a, 0x0f, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69,
+ 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x42, 0x0c, 0xfa, 0x42, 0x09, 0x92, 0x01, 0x06,
+ 0x22, 0x04, 0x72, 0x02, 0x18, 0x64, 0x52, 0x0e, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0xed, 0x02, 0x0a, 0x08, 0x64, 0x65, 0x76, 0x5f, 0x61,
+ 0x64, 0x64, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x42, 0xd1, 0x02, 0x92, 0x41, 0x19, 0x4a,
+ 0x0a, 0x22, 0x32, 0x36, 0x30, 0x30, 0x41, 0x42, 0x43, 0x44, 0x22, 0x9a, 0x02, 0x01, 0x07, 0xa2,
+ 0x02, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0xfa, 0x42, 0x06, 0x7a, 0x04, 0x68, 0x04, 0x70,
+ 0x01, 0xea, 0xaa, 0x19, 0x82, 0x01, 0x0a, 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68,
+ 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72,
+ 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b,
+ 0x67, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x48,
+ 0x45, 0x58, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74,
+ 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f,
+ 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70,
+ 0x6b, 0x67, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x55, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68,
+ 0x61, 0x6c, 0x34, 0x42, 0x79, 0x74, 0x65, 0x73, 0xf2, 0xaa, 0x19, 0xa0, 0x01, 0x1a, 0x4e, 0x67,
0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77,
0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63,
- 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4d,
- 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x48, 0x45, 0x58, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x3f,
- 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74,
- 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61,
- 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e,
- 0x55, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x33, 0x42, 0x79, 0x74, 0x65, 0x73, 0xf2,
- 0xaa, 0x19, 0xa0, 0x01, 0x1a, 0x4e, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e,
- 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77,
- 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x63, 0x6d, 0x64, 0x2f,
- 0x74, 0x74, 0x6e, 0x2d, 0x6c, 0x77, 0x2d, 0x63, 0x6c, 0x69, 0x2f, 0x63, 0x75, 0x73, 0x74, 0x6f,
- 0x6d, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x2e, 0x4e, 0x65, 0x77, 0x33, 0x42, 0x79, 0x74, 0x65, 0x73,
- 0x46, 0x6c, 0x61, 0x67, 0x22, 0x4e, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e,
- 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77,
- 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x63, 0x6d, 0x64, 0x2f,
- 0x74, 0x74, 0x6e, 0x2d, 0x6c, 0x77, 0x2d, 0x63, 0x6c, 0x69, 0x2f, 0x63, 0x75, 0x73, 0x74, 0x6f,
- 0x6d, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, 0x61, 0x63, 0x74, 0x42,
- 0x79, 0x74, 0x65, 0x73, 0x52, 0x05, 0x6e, 0x65, 0x74, 0x49, 0x64, 0x3a, 0x08, 0xf2, 0xaa, 0x19,
- 0x04, 0x08, 0x01, 0x10, 0x01, 0x1a, 0xf9, 0x07, 0x0a, 0x0d, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b,
- 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3b, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f,
- 0x61, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c,
- 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
- 0x65, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x07, 0x70, 0x61, 0x79,
- 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x57, 0x0a, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73,
- 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
- 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x53, 0x74, 0x61, 0x74, 0x65,
- 0x2e, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x54,
- 0x78, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01,
- 0x02, 0x10, 0x01, 0x52, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x52, 0x0a,
- 0x0b, 0x72, 0x78, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, 0x03,
- 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
- 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x55, 0x70, 0x6c,
- 0x69, 0x6e, 0x6b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x52, 0x78, 0x4d, 0x65, 0x74,
- 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x0a, 0x72, 0x78, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
- 0x61, 0x12, 0x3b, 0x0a, 0x0b, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x5f, 0x61, 0x74,
- 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
- 0x6d, 0x70, 0x52, 0x0a, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x41, 0x74, 0x12, 0x35,
- 0x0a, 0x0f, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64,
- 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x42, 0x0c, 0xfa, 0x42, 0x09, 0x92, 0x01, 0x06, 0x22,
- 0x04, 0x72, 0x02, 0x18, 0x64, 0x52, 0x0e, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69,
- 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x3a, 0x0a, 0x14, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f,
- 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x09, 0x20,
- 0x01, 0x28, 0x0d, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x2a, 0x03, 0x18, 0xff, 0x01, 0x52, 0x12, 0x64,
- 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x6e, 0x64, 0x65,
- 0x78, 0x1a, 0x53, 0x0a, 0x0a, 0x54, 0x78, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12,
- 0x3f, 0x0a, 0x09, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
- 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x42, 0x08, 0xfa, 0x42,
- 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65,
- 0x4a, 0x04, 0x08, 0x02, 0x10, 0x0a, 0x1a, 0xe0, 0x03, 0x0a, 0x0a, 0x52, 0x78, 0x4d, 0x65, 0x74,
- 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x4d, 0x0a, 0x0b, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
- 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x74, 0x6e,
- 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x47, 0x61, 0x74, 0x65,
- 0x77, 0x61, 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08,
- 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61,
- 0x79, 0x49, 0x64, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f,
- 0x72, 0x73, 0x73, 0x69, 0x18, 0x09, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0b, 0x63, 0x68, 0x61, 0x6e,
- 0x6e, 0x65, 0x6c, 0x52, 0x73, 0x73, 0x69, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x6e, 0x72, 0x18, 0x0b,
- 0x20, 0x01, 0x28, 0x02, 0x52, 0x03, 0x73, 0x6e, 0x72, 0x12, 0x6a, 0x0a, 0x18, 0x64, 0x6f, 0x77,
- 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74,
- 0x72, 0x61, 0x69, 0x6e, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x74, 0x74,
- 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x6f, 0x77,
- 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x50, 0x61, 0x74, 0x68, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61,
- 0x69, 0x6e, 0x74, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x16, 0x64,
- 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x50, 0x61, 0x74, 0x68, 0x43, 0x6f, 0x6e, 0x73, 0x74,
- 0x72, 0x61, 0x69, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x5f,
- 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x75, 0x70, 0x6c,
- 0x69, 0x6e, 0x6b, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x6b, 0x0a, 0x0d, 0x70, 0x61, 0x63, 0x6b,
- 0x65, 0x74, 0x5f, 0x62, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32,
- 0x46, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
- 0x2e, 0x4d, 0x41, 0x43, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b,
- 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x52, 0x78, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61,
- 0x74, 0x61, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x4d,
- 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x0c, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x42,
- 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x1a, 0x1c, 0x0a, 0x14, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x42,
- 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4a, 0x04, 0x08,
- 0x01, 0x10, 0x0b, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x09, 0x4a, 0x04, 0x08, 0x0a, 0x10, 0x0b, 0x4a,
- 0x04, 0x08, 0x0c, 0x10, 0x0d, 0x4a, 0x04, 0x08, 0x0d, 0x10, 0x0e, 0x4a, 0x04, 0x08, 0x10, 0x10,
- 0x11, 0x4a, 0x04, 0x08, 0x11, 0x10, 0x12, 0x4a, 0x04, 0x08, 0x13, 0x10, 0x14, 0x4a, 0x04, 0x08,
- 0x14, 0x10, 0x15, 0x4a, 0x04, 0x08, 0x63, 0x10, 0x64, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x4a,
- 0x04, 0x08, 0x03, 0x10, 0x04, 0x4a, 0x04, 0x08, 0x08, 0x10, 0x09, 0x4a, 0x04, 0x08, 0x0a, 0x10,
- 0x0b, 0x1a, 0x97, 0x04, 0x0a, 0x0f, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x4d, 0x65,
- 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x4a, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64,
- 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
- 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x53, 0x74, 0x61, 0x74, 0x65,
- 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
- 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61,
- 0x64, 0x12, 0x35, 0x0a, 0x0f, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e,
- 0x5f, 0x69, 0x64, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x42, 0x0c, 0xfa, 0x42, 0x09, 0x92,
- 0x01, 0x06, 0x22, 0x04, 0x72, 0x02, 0x18, 0x64, 0x52, 0x0e, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x6c,
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x1a, 0xee, 0x02, 0x0a, 0x07, 0x4d, 0x65, 0x73,
- 0x73, 0x61, 0x67, 0x65, 0x12, 0x54, 0x0a, 0x05, 0x6d, 0x5f, 0x68, 0x64, 0x72, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
- 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x44, 0x6f,
- 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x65,
- 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x48, 0x44, 0x52, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a,
- 0x01, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6d, 0x48, 0x64, 0x72, 0x12, 0x5c, 0x0a, 0x0b, 0x6d, 0x61,
- 0x63, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32,
- 0x3b, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
- 0x2e, 0x4d, 0x41, 0x43, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69,
- 0x6e, 0x6b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
- 0x65, 0x2e, 0x4d, 0x41, 0x43, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x0a, 0x6d, 0x61,
- 0x63, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x1a, 0x44, 0x0a, 0x04, 0x4d, 0x48, 0x44, 0x52,
- 0x12, 0x36, 0x0a, 0x06, 0x6d, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e,
- 0x32, 0x15, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
- 0x33, 0x2e, 0x4d, 0x54, 0x79, 0x70, 0x65, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10,
- 0x01, 0x52, 0x05, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x1a, 0x5d,
- 0x0a, 0x0a, 0x4d, 0x41, 0x43, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x1f, 0x0a, 0x06,
- 0x66, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x08, 0xfa, 0x42,
- 0x05, 0x2a, 0x03, 0x18, 0xff, 0x01, 0x52, 0x05, 0x66, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1c, 0x0a,
- 0x0a, 0x66, 0x75, 0x6c, 0x6c, 0x5f, 0x66, 0x5f, 0x63, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28,
- 0x0d, 0x52, 0x08, 0x66, 0x75, 0x6c, 0x6c, 0x46, 0x43, 0x6e, 0x74, 0x4a, 0x04, 0x08, 0x01, 0x10,
- 0x02, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x4a, 0x04, 0x08,
- 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x08, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x4a,
- 0x04, 0x08, 0x03, 0x10, 0x06, 0x4a, 0x04, 0x08, 0x07, 0x10, 0x08, 0x1a, 0xc9, 0x01, 0x0a, 0x0d,
- 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x56, 0x0a,
- 0x13, 0x6d, 0x69, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69,
- 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e,
- 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61,
- 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01,
- 0x02, 0x10, 0x01, 0x52, 0x10, 0x6d, 0x69, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65,
- 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x56, 0x0a, 0x13, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x61, 0x74,
- 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01,
- 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
- 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65,
- 0x78, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x10, 0x6d, 0x61, 0x78,
- 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x3a, 0x08, 0xf2,
- 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x1a, 0x64, 0x0a, 0x0e, 0x44, 0x61, 0x74, 0x61, 0x52,
- 0x61, 0x74, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x48, 0x0a, 0x06, 0x72, 0x61, 0x6e,
- 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
- 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x53, 0x74,
- 0x61, 0x74, 0x65, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x52, 0x61, 0x6e, 0x67,
- 0x65, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x92, 0x01, 0x02, 0x08, 0x01, 0x52, 0x06, 0x72, 0x61, 0x6e,
- 0x67, 0x65, 0x73, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x1a, 0x72, 0x0a,
- 0x1b, 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74,
- 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03,
- 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x3d,
- 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e,
+ 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x74, 0x74, 0x6e, 0x2d, 0x6c, 0x77, 0x2d,
+ 0x63, 0x6c, 0x69, 0x2f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x2e,
+ 0x4e, 0x65, 0x77, 0x34, 0x42, 0x79, 0x74, 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x22, 0x4e, 0x67,
+ 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77,
+ 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63,
+ 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x74, 0x74, 0x6e, 0x2d, 0x6c, 0x77, 0x2d,
+ 0x63, 0x6c, 0x69, 0x2f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x2e,
+ 0x47, 0x65, 0x74, 0x45, 0x78, 0x61, 0x63, 0x74, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x07, 0x64,
+ 0x65, 0x76, 0x41, 0x64, 0x64, 0x72, 0x12, 0xe7, 0x02, 0x0a, 0x06, 0x6e, 0x65, 0x74, 0x5f, 0x69,
+ 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x42, 0xcf, 0x02, 0x92, 0x41, 0x17, 0x4a, 0x08, 0x22,
+ 0x30, 0x30, 0x30, 0x30, 0x31, 0x33, 0x22, 0x9a, 0x02, 0x01, 0x07, 0xa2, 0x02, 0x06, 0x73, 0x74,
+ 0x72, 0x69, 0x6e, 0x67, 0xfa, 0x42, 0x06, 0x7a, 0x04, 0x68, 0x03, 0x70, 0x01, 0xea, 0xaa, 0x19,
+ 0x82, 0x01, 0x0a, 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73,
+ 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
+ 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x79,
+ 0x70, 0x65, 0x73, 0x2e, 0x4d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x48, 0x45, 0x58, 0x42, 0x79,
+ 0x74, 0x65, 0x73, 0x12, 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67,
+ 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
+ 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74,
+ 0x79, 0x70, 0x65, 0x73, 0x2e, 0x55, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x33, 0x42,
+ 0x79, 0x74, 0x65, 0x73, 0xf2, 0xaa, 0x19, 0xa0, 0x01, 0x1a, 0x4e, 0x67, 0x6f, 0x2e, 0x74, 0x68,
+ 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f,
+ 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33,
+ 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x74, 0x74, 0x6e, 0x2d, 0x6c, 0x77, 0x2d, 0x63, 0x6c, 0x69, 0x2f,
+ 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x2e, 0x4e, 0x65, 0x77, 0x33,
+ 0x42, 0x79, 0x74, 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x22, 0x4e, 0x67, 0x6f, 0x2e, 0x74, 0x68,
+ 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f,
+ 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33,
+ 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x74, 0x74, 0x6e, 0x2d, 0x6c, 0x77, 0x2d, 0x63, 0x6c, 0x69, 0x2f,
+ 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x45,
+ 0x78, 0x61, 0x63, 0x74, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x05, 0x6e, 0x65, 0x74, 0x49, 0x64,
+ 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x1a, 0xf3, 0x08, 0x0a, 0x0d, 0x55,
+ 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3b, 0x0a, 0x07,
+ 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e,
0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d,
- 0x41, 0x43, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65,
- 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,
- 0x01, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x22, 0xcb, 0x01, 0x0a, 0x1b,
- 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74,
- 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x30, 0x0a, 0x05, 0x76,
- 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x1a, 0xfa, 0x42, 0x17, 0x72,
- 0x15, 0x32, 0x13, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x7b,
- 0x31, 0x2c, 0x33, 0x32, 0x7d, 0x24, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x39, 0x0a,
- 0x0a, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28,
- 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
- 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x76,
- 0x61, 0x6c, 0x69, 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x12, 0x35, 0x0a, 0x08, 0x76, 0x61, 0x6c, 0x69,
- 0x64, 0x5f, 0x74, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f,
- 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d,
- 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x07, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x54, 0x6f, 0x3a,
- 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x22, 0xd7, 0x21, 0x0a, 0x09, 0x45, 0x6e,
- 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x48, 0x0a, 0x03, 0x69, 0x64, 0x73, 0x18, 0x01,
- 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
- 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49,
- 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x10, 0xfa, 0x42, 0x05, 0x8a,
- 0x01, 0x02, 0x10, 0x01, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x00, 0x28, 0x01, 0x52, 0x03, 0x69, 0x64,
- 0x73, 0x12, 0x43, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18,
- 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
- 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
- 0x70, 0x42, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x00, 0x10, 0x00, 0x52, 0x09, 0x63, 0x72, 0x65,
- 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x43, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65,
- 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f,
- 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d,
- 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x00, 0x10, 0x00,
- 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1b, 0x0a, 0x04, 0x6e,
- 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02,
- 0x18, 0x32, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63,
- 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xfa,
- 0x42, 0x05, 0x72, 0x03, 0x18, 0xd0, 0x0f, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,
- 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x80, 0x01, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75,
- 0x74, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
- 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x64, 0x44, 0x65,
- 0x76, 0x69, 0x63, 0x65, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x45,
- 0x6e, 0x74, 0x72, 0x79, 0x42, 0x35, 0xfa, 0x42, 0x32, 0x9a, 0x01, 0x2f, 0x10, 0x0a, 0x22, 0x24,
- 0x72, 0x22, 0x18, 0x24, 0x32, 0x1e, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x28,
- 0x3f, 0x3a, 0x5b, 0x2d, 0x5d, 0x3f, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x7b,
- 0x32, 0x2c, 0x7d, 0x24, 0x2a, 0x05, 0x72, 0x03, 0x18, 0xc8, 0x01, 0x52, 0x0a, 0x61, 0x74, 0x74,
- 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x4c, 0x0a, 0x0b, 0x76, 0x65, 0x72, 0x73, 0x69,
- 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74,
- 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e,
- 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64,
- 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x52, 0x0a, 0x76, 0x65, 0x72, 0x73, 0x69,
- 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x35, 0x0a, 0x12, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
- 0x5f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28,
- 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x18, 0x40, 0x52, 0x10, 0x73, 0x65, 0x72, 0x76,
- 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x12, 0xc5, 0x01, 0x0a,
- 0x16, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f,
- 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x42, 0x8e, 0x01,
- 0xfa, 0x42, 0x8a, 0x01, 0x72, 0x87, 0x01, 0x32, 0x84, 0x01, 0x5e, 0x28, 0x3f, 0x3a, 0x28, 0x3f,
- 0x3a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x7c, 0x5b, 0x61, 0x2d,
- 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30,
- 0x2d, 0x39, 0x5c, 0x2d, 0x5d, 0x2a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39,
- 0x5d, 0x29, 0x5c, 0x2e, 0x29, 0x2a, 0x28, 0x3f, 0x3a, 0x5b, 0x41, 0x2d, 0x5a, 0x61, 0x2d, 0x7a,
- 0x30, 0x2d, 0x39, 0x5d, 0x7c, 0x5b, 0x41, 0x2d, 0x5a, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d,
- 0x5b, 0x41, 0x2d, 0x5a, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5c, 0x2d, 0x5d, 0x2a, 0x5b, 0x41,
- 0x2d, 0x5a, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x28, 0x3f, 0x3a, 0x3a, 0x5b, 0x30,
- 0x2d, 0x39, 0x5d, 0x7b, 0x31, 0x2c, 0x35, 0x7d, 0x29, 0x3f, 0x24, 0x7c, 0x5e, 0x24, 0x52, 0x14,
- 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64,
- 0x72, 0x65, 0x73, 0x73, 0x12, 0x41, 0x0a, 0x18, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f,
- 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x6b, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c,
- 0x18, 0x2f, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x72, 0x03, 0x18, 0x80, 0x10,
- 0x52, 0x15, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4b,
- 0x65, 0x6b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0xcd, 0x01, 0x0a, 0x1a, 0x61, 0x70, 0x70, 0x6c,
- 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x61,
- 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x42, 0x8e, 0x01, 0xfa,
+ 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01,
+ 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x57, 0x0a, 0x08, 0x73, 0x65, 0x74,
+ 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x74, 0x74,
+ 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43,
+ 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x4d, 0x65, 0x73, 0x73,
+ 0x61, 0x67, 0x65, 0x2e, 0x54, 0x78, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x42, 0x08,
+ 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e,
+ 0x67, 0x73, 0x12, 0x52, 0x0a, 0x0b, 0x72, 0x78, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
+ 0x61, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
+ 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x53, 0x74, 0x61, 0x74,
+ 0x65, 0x2e, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e,
+ 0x52, 0x78, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x0a, 0x72, 0x78, 0x4d, 0x65,
+ 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x3b, 0x0a, 0x0b, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76,
+ 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f,
+ 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69,
+ 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65,
+ 0x64, 0x41, 0x74, 0x12, 0x35, 0x0a, 0x0f, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69,
+ 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x42, 0x0c, 0xfa, 0x42,
+ 0x09, 0x92, 0x01, 0x06, 0x22, 0x04, 0x72, 0x02, 0x18, 0x64, 0x52, 0x0e, 0x63, 0x6f, 0x72, 0x72,
+ 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x3a, 0x0a, 0x14, 0x64, 0x65,
+ 0x76, 0x69, 0x63, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x6e, 0x64,
+ 0x65, 0x78, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x2a, 0x03, 0x18,
+ 0xff, 0x01, 0x52, 0x12, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65,
+ 0x6c, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x53, 0x0a, 0x0a, 0x54, 0x78, 0x53, 0x65, 0x74, 0x74,
+ 0x69, 0x6e, 0x67, 0x73, 0x12, 0x3f, 0x0a, 0x09, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74,
+ 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
+ 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74,
+ 0x65, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x08, 0x64, 0x61, 0x74,
+ 0x61, 0x52, 0x61, 0x74, 0x65, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x0a, 0x1a, 0xda, 0x04, 0x0a, 0x0a,
+ 0x52, 0x78, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x4d, 0x0a, 0x0b, 0x67, 0x61,
+ 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x22, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
+ 0x2e, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69,
+ 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x67,
+ 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x68, 0x61,
+ 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x72, 0x73, 0x73, 0x69, 0x18, 0x09, 0x20, 0x01, 0x28, 0x02, 0x52,
+ 0x0b, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x73, 0x73, 0x69, 0x12, 0x10, 0x0a, 0x03,
+ 0x73, 0x6e, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x02, 0x52, 0x03, 0x73, 0x6e, 0x72, 0x12, 0x6a,
+ 0x0a, 0x18, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f,
+ 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0e,
+ 0x32, 0x26, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
+ 0x33, 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x50, 0x61, 0x74, 0x68, 0x43, 0x6f,
+ 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02,
+ 0x10, 0x01, 0x52, 0x16, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x50, 0x61, 0x74, 0x68,
+ 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x75, 0x70,
+ 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0c,
+ 0x52, 0x0b, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x6b, 0x0a,
+ 0x0d, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x62, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x18, 0x12,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x46, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
+ 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x55,
+ 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x52, 0x78, 0x4d,
+ 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x42, 0x72,
+ 0x6f, 0x6b, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x0c, 0x70, 0x61,
+ 0x63, 0x6b, 0x65, 0x74, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x12, 0x55, 0x0a, 0x05, 0x72, 0x65,
+ 0x6c, 0x61, 0x79, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
+ 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x53, 0x74,
+ 0x61, 0x74, 0x65, 0x2e, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
+ 0x65, 0x2e, 0x52, 0x78, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x6c,
+ 0x61, 0x79, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x05, 0x72, 0x65, 0x6c, 0x61,
+ 0x79, 0x1a, 0x1c, 0x0a, 0x14, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x42, 0x72, 0x6f, 0x6b, 0x65,
+ 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x0b, 0x1a,
+ 0x15, 0x0a, 0x0d, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
+ 0x4a, 0x04, 0x08, 0x01, 0x10, 0x04, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x09, 0x4a, 0x04, 0x08, 0x0a,
+ 0x10, 0x0b, 0x4a, 0x04, 0x08, 0x0c, 0x10, 0x0d, 0x4a, 0x04, 0x08, 0x0d, 0x10, 0x0e, 0x4a, 0x04,
+ 0x08, 0x10, 0x10, 0x11, 0x4a, 0x04, 0x08, 0x11, 0x10, 0x12, 0x4a, 0x04, 0x08, 0x13, 0x10, 0x14,
+ 0x4a, 0x04, 0x08, 0x14, 0x10, 0x15, 0x4a, 0x04, 0x08, 0x15, 0x10, 0x16, 0x4a, 0x04, 0x08, 0x16,
+ 0x10, 0x17, 0x4a, 0x04, 0x08, 0x63, 0x10, 0x64, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x4a, 0x04,
+ 0x08, 0x03, 0x10, 0x04, 0x4a, 0x04, 0x08, 0x08, 0x10, 0x09, 0x4a, 0x04, 0x08, 0x0a, 0x10, 0x0b,
+ 0x1a, 0x97, 0x04, 0x0a, 0x0f, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x4d, 0x65, 0x73,
+ 0x73, 0x61, 0x67, 0x65, 0x12, 0x4a, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18,
+ 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
+ 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e,
+ 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e,
+ 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64,
+ 0x12, 0x35, 0x0a, 0x0f, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f,
+ 0x69, 0x64, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x42, 0x0c, 0xfa, 0x42, 0x09, 0x92, 0x01,
+ 0x06, 0x22, 0x04, 0x72, 0x02, 0x18, 0x64, 0x52, 0x0e, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x6c, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x1a, 0xee, 0x02, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73,
+ 0x61, 0x67, 0x65, 0x12, 0x54, 0x0a, 0x05, 0x6d, 0x5f, 0x68, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
+ 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x44, 0x6f, 0x77,
+ 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x65, 0x73,
+ 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x48, 0x44, 0x52, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01,
+ 0x02, 0x10, 0x01, 0x52, 0x04, 0x6d, 0x48, 0x64, 0x72, 0x12, 0x5c, 0x0a, 0x0b, 0x6d, 0x61, 0x63,
+ 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3b,
+ 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
+ 0x4d, 0x41, 0x43, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e,
+ 0x6b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
+ 0x2e, 0x4d, 0x41, 0x43, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x0a, 0x6d, 0x61, 0x63,
+ 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x1a, 0x44, 0x0a, 0x04, 0x4d, 0x48, 0x44, 0x52, 0x12,
+ 0x36, 0x0a, 0x06, 0x6d, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32,
+ 0x15, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
+ 0x2e, 0x4d, 0x54, 0x79, 0x70, 0x65, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01,
+ 0x52, 0x05, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x1a, 0x5d, 0x0a,
+ 0x0a, 0x4d, 0x41, 0x43, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x1f, 0x0a, 0x06, 0x66,
+ 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x08, 0xfa, 0x42, 0x05,
+ 0x2a, 0x03, 0x18, 0xff, 0x01, 0x52, 0x05, 0x66, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1c, 0x0a, 0x0a,
+ 0x66, 0x75, 0x6c, 0x6c, 0x5f, 0x66, 0x5f, 0x63, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d,
+ 0x52, 0x08, 0x66, 0x75, 0x6c, 0x6c, 0x46, 0x43, 0x6e, 0x74, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02,
+ 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x4a, 0x04, 0x08, 0x02,
+ 0x10, 0x03, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x08, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x4a, 0x04,
+ 0x08, 0x03, 0x10, 0x06, 0x4a, 0x04, 0x08, 0x07, 0x10, 0x08, 0x1a, 0xc9, 0x01, 0x0a, 0x0d, 0x44,
+ 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x56, 0x0a, 0x13,
+ 0x6d, 0x69, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e,
+ 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
+ 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52,
+ 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02,
+ 0x10, 0x01, 0x52, 0x10, 0x6d, 0x69, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49,
+ 0x6e, 0x64, 0x65, 0x78, 0x12, 0x56, 0x0a, 0x13, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x61, 0x74, 0x61,
+ 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28,
+ 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
+ 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78,
+ 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x10, 0x6d, 0x61, 0x78, 0x44,
+ 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x3a, 0x08, 0xf2, 0xaa,
+ 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x1a, 0x64, 0x0a, 0x0e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61,
+ 0x74, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x48, 0x0a, 0x06, 0x72, 0x61, 0x6e, 0x67,
+ 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c,
+ 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x53, 0x74, 0x61,
+ 0x74, 0x65, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65,
+ 0x42, 0x08, 0xfa, 0x42, 0x05, 0x92, 0x01, 0x02, 0x08, 0x01, 0x52, 0x06, 0x72, 0x61, 0x6e, 0x67,
+ 0x65, 0x73, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x1a, 0x72, 0x0a, 0x1b,
+ 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65,
+ 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b,
+ 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x3d, 0x0a,
+ 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74,
+ 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41,
+ 0x43, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x52,
+ 0x61, 0x6e, 0x67, 0x65, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01,
+ 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x22, 0xcb, 0x01, 0x0a, 0x1b, 0x45,
+ 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69,
+ 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61,
+ 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x1a, 0xfa, 0x42, 0x17, 0x72, 0x15,
+ 0x32, 0x13, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x7b, 0x31,
+ 0x2c, 0x33, 0x32, 0x7d, 0x24, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x39, 0x0a, 0x0a,
+ 0x76, 0x61, 0x6c, 0x69, 0x64, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
+ 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x76, 0x61,
+ 0x6c, 0x69, 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x12, 0x35, 0x0a, 0x08, 0x76, 0x61, 0x6c, 0x69, 0x64,
+ 0x5f, 0x74, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
+ 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65,
+ 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x07, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x54, 0x6f, 0x3a, 0x08,
+ 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x22, 0xd7, 0x21, 0x0a, 0x09, 0x45, 0x6e, 0x64,
+ 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x48, 0x0a, 0x03, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
+ 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64,
+ 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x10, 0xfa, 0x42, 0x05, 0x8a, 0x01,
+ 0x02, 0x10, 0x01, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x00, 0x28, 0x01, 0x52, 0x03, 0x69, 0x64, 0x73,
+ 0x12, 0x43, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
+ 0x42, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x00, 0x10, 0x00, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61,
+ 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x43, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64,
+ 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
+ 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65,
+ 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x00, 0x10, 0x00, 0x52,
+ 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61,
+ 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x18,
+ 0x32, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72,
+ 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xfa, 0x42,
+ 0x05, 0x72, 0x03, 0x18, 0xd0, 0x0f, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
+ 0x69, 0x6f, 0x6e, 0x12, 0x80, 0x01, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74,
+ 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c,
+ 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76,
+ 0x69, 0x63, 0x65, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x45, 0x6e,
+ 0x74, 0x72, 0x79, 0x42, 0x35, 0xfa, 0x42, 0x32, 0x9a, 0x01, 0x2f, 0x10, 0x0a, 0x22, 0x24, 0x72,
+ 0x22, 0x18, 0x24, 0x32, 0x1e, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x3f,
+ 0x3a, 0x5b, 0x2d, 0x5d, 0x3f, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x7b, 0x32,
+ 0x2c, 0x7d, 0x24, 0x2a, 0x05, 0x72, 0x03, 0x18, 0xc8, 0x01, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72,
+ 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x4c, 0x0a, 0x0b, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
+ 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x74,
+ 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x64,
+ 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x65,
+ 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x52, 0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
+ 0x6e, 0x49, 0x64, 0x73, 0x12, 0x35, 0x0a, 0x12, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f,
+ 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09,
+ 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x18, 0x40, 0x52, 0x10, 0x73, 0x65, 0x72, 0x76, 0x69,
+ 0x63, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x12, 0xc5, 0x01, 0x0a, 0x16,
+ 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x61,
+ 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x42, 0x8e, 0x01, 0xfa,
+ 0x42, 0x8a, 0x01, 0x72, 0x87, 0x01, 0x32, 0x84, 0x01, 0x5e, 0x28, 0x3f, 0x3a, 0x28, 0x3f, 0x3a,
+ 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x7c, 0x5b, 0x61, 0x2d, 0x7a,
+ 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d,
+ 0x39, 0x5c, 0x2d, 0x5d, 0x2a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d,
+ 0x29, 0x5c, 0x2e, 0x29, 0x2a, 0x28, 0x3f, 0x3a, 0x5b, 0x41, 0x2d, 0x5a, 0x61, 0x2d, 0x7a, 0x30,
+ 0x2d, 0x39, 0x5d, 0x7c, 0x5b, 0x41, 0x2d, 0x5a, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x5b,
+ 0x41, 0x2d, 0x5a, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5c, 0x2d, 0x5d, 0x2a, 0x5b, 0x41, 0x2d,
+ 0x5a, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x28, 0x3f, 0x3a, 0x3a, 0x5b, 0x30, 0x2d,
+ 0x39, 0x5d, 0x7b, 0x31, 0x2c, 0x35, 0x7d, 0x29, 0x3f, 0x24, 0x7c, 0x5e, 0x24, 0x52, 0x14, 0x6e,
+ 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72,
+ 0x65, 0x73, 0x73, 0x12, 0x41, 0x0a, 0x18, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x73,
+ 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x6b, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18,
+ 0x2f, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x72, 0x03, 0x18, 0x80, 0x10, 0x52,
+ 0x15, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4b, 0x65,
+ 0x6b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0xcd, 0x01, 0x0a, 0x1a, 0x61, 0x70, 0x70, 0x6c, 0x69,
+ 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x61, 0x64,
+ 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x42, 0x8e, 0x01, 0xfa, 0x42,
+ 0x8a, 0x01, 0x72, 0x87, 0x01, 0x32, 0x84, 0x01, 0x5e, 0x28, 0x3f, 0x3a, 0x28, 0x3f, 0x3a, 0x5b,
+ 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x7c, 0x5b, 0x61, 0x2d, 0x7a, 0x41,
+ 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39,
+ 0x5c, 0x2d, 0x5d, 0x2a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x29,
+ 0x5c, 0x2e, 0x29, 0x2a, 0x28, 0x3f, 0x3a, 0x5b, 0x41, 0x2d, 0x5a, 0x61, 0x2d, 0x7a, 0x30, 0x2d,
+ 0x39, 0x5d, 0x7c, 0x5b, 0x41, 0x2d, 0x5a, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x5b, 0x41,
+ 0x2d, 0x5a, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5c, 0x2d, 0x5d, 0x2a, 0x5b, 0x41, 0x2d, 0x5a,
+ 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x28, 0x3f, 0x3a, 0x3a, 0x5b, 0x30, 0x2d, 0x39,
+ 0x5d, 0x7b, 0x31, 0x2c, 0x35, 0x7d, 0x29, 0x3f, 0x24, 0x7c, 0x5e, 0x24, 0x52, 0x18, 0x61, 0x70,
+ 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41,
+ 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x49, 0x0a, 0x1c, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x6b,
+ 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x30, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xfa, 0x42,
+ 0x05, 0x72, 0x03, 0x18, 0x80, 0x10, 0x52, 0x19, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4b, 0x65, 0x6b, 0x4c, 0x61, 0x62, 0x65,
+ 0x6c, 0x12, 0x3b, 0x0a, 0x15, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+ 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x31, 0x20, 0x01, 0x28, 0x09,
+ 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x18, 0x64, 0x52, 0x13, 0x61, 0x70, 0x70, 0x6c, 0x69,
+ 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x64, 0x12, 0xbf,
+ 0x01, 0x0a, 0x13, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x61,
+ 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x42, 0x8e, 0x01, 0xfa,
0x42, 0x8a, 0x01, 0x72, 0x87, 0x01, 0x32, 0x84, 0x01, 0x5e, 0x28, 0x3f, 0x3a, 0x28, 0x3f, 0x3a,
0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x7c, 0x5b, 0x61, 0x2d, 0x7a,
0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d,
@@ -5150,448 +5852,427 @@ var file_ttn_lorawan_v3_end_device_proto_rawDesc = []byte{
0x2d, 0x39, 0x5d, 0x7c, 0x5b, 0x41, 0x2d, 0x5a, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x5b,
0x41, 0x2d, 0x5a, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5c, 0x2d, 0x5d, 0x2a, 0x5b, 0x41, 0x2d,
0x5a, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x28, 0x3f, 0x3a, 0x3a, 0x5b, 0x30, 0x2d,
- 0x39, 0x5d, 0x7b, 0x31, 0x2c, 0x35, 0x7d, 0x29, 0x3f, 0x24, 0x7c, 0x5e, 0x24, 0x52, 0x18, 0x61,
- 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
- 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x49, 0x0a, 0x1c, 0x61, 0x70, 0x70, 0x6c, 0x69,
- 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x6b, 0x65,
- 0x6b, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x30, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xfa,
- 0x42, 0x05, 0x72, 0x03, 0x18, 0x80, 0x10, 0x52, 0x19, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61,
- 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4b, 0x65, 0x6b, 0x4c, 0x61, 0x62,
- 0x65, 0x6c, 0x12, 0x3b, 0x0a, 0x15, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x31, 0x20, 0x01, 0x28,
- 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x18, 0x64, 0x52, 0x13, 0x61, 0x70, 0x70, 0x6c,
- 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x64, 0x12,
- 0xbf, 0x01, 0x0a, 0x13, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f,
- 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x42, 0x8e, 0x01,
- 0xfa, 0x42, 0x8a, 0x01, 0x72, 0x87, 0x01, 0x32, 0x84, 0x01, 0x5e, 0x28, 0x3f, 0x3a, 0x28, 0x3f,
- 0x3a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x7c, 0x5b, 0x61, 0x2d,
- 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30,
- 0x2d, 0x39, 0x5c, 0x2d, 0x5d, 0x2a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39,
- 0x5d, 0x29, 0x5c, 0x2e, 0x29, 0x2a, 0x28, 0x3f, 0x3a, 0x5b, 0x41, 0x2d, 0x5a, 0x61, 0x2d, 0x7a,
- 0x30, 0x2d, 0x39, 0x5d, 0x7c, 0x5b, 0x41, 0x2d, 0x5a, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d,
- 0x5b, 0x41, 0x2d, 0x5a, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5c, 0x2d, 0x5d, 0x2a, 0x5b, 0x41,
- 0x2d, 0x5a, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x28, 0x3f, 0x3a, 0x3a, 0x5b, 0x30,
- 0x2d, 0x39, 0x5d, 0x7b, 0x31, 0x2c, 0x35, 0x7d, 0x29, 0x3f, 0x24, 0x7c, 0x5e, 0x24, 0x52, 0x11,
- 0x6a, 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73,
- 0x73, 0x12, 0x74, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0c,
- 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
- 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2e,
- 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x42, 0x2c,
- 0xfa, 0x42, 0x29, 0x9a, 0x01, 0x26, 0x22, 0x24, 0x72, 0x22, 0x18, 0x24, 0x32, 0x1e, 0x5e, 0x5b,
- 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x3f, 0x3a, 0x5b, 0x2d, 0x5d, 0x3f, 0x5b, 0x61,
- 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x7b, 0x32, 0x2c, 0x7d, 0x24, 0x52, 0x09, 0x6c, 0x6f,
- 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x31, 0x0a, 0x07, 0x70, 0x69, 0x63, 0x74, 0x75,
- 0x72, 0x65, 0x18, 0x32, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c,
- 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x50, 0x69, 0x63, 0x74, 0x75, 0x72,
- 0x65, 0x52, 0x07, 0x70, 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x75,
- 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x62, 0x18, 0x0d,
- 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x43, 0x6c,
- 0x61, 0x73, 0x73, 0x42, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73,
- 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x63, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e,
- 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x12, 0x4d,
- 0x0a, 0x0f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
- 0x6e, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
- 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x56, 0x65, 0x72, 0x73,
- 0x69, 0x6f, 0x6e, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0e, 0x6c,
- 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x54, 0x0a,
- 0x13, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x5f, 0x70, 0x68, 0x79, 0x5f, 0x76, 0x65, 0x72,
- 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x74, 0x6e,
- 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x50, 0x48, 0x59, 0x56,
- 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01,
- 0x52, 0x11, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x50, 0x68, 0x79, 0x56, 0x65, 0x72, 0x73,
- 0x69, 0x6f, 0x6e, 0x12, 0x33, 0x0a, 0x11, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79,
- 0x5f, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07,
- 0xfa, 0x42, 0x04, 0x72, 0x02, 0x18, 0x40, 0x52, 0x0f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e,
- 0x63, 0x79, 0x50, 0x6c, 0x61, 0x6e, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x69, 0x6e, 0x5f,
- 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x12, 0x20, 0x01, 0x28, 0x04, 0x52,
- 0x0c, 0x6d, 0x69, 0x6e, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x23, 0x0a,
- 0x0d, 0x6d, 0x61, 0x78, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x13,
- 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e,
- 0x63, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x5f, 0x6a,
- 0x6f, 0x69, 0x6e, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x73, 0x75, 0x70, 0x70, 0x6f,
- 0x72, 0x74, 0x73, 0x4a, 0x6f, 0x69, 0x6e, 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x65, 0x73, 0x65, 0x74,
- 0x73, 0x5f, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x15, 0x20,
- 0x01, 0x28, 0x08, 0x52, 0x10, 0x72, 0x65, 0x73, 0x65, 0x74, 0x73, 0x4a, 0x6f, 0x69, 0x6e, 0x4e,
- 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x35, 0x0a, 0x09, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x6b, 0x65,
- 0x79, 0x73, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c,
- 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x6f, 0x6f, 0x74, 0x4b, 0x65,
- 0x79, 0x73, 0x52, 0x08, 0x72, 0x6f, 0x6f, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x12, 0xe7, 0x02, 0x0a,
- 0x06, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0c, 0x42, 0xcf, 0x02,
- 0x92, 0x41, 0x17, 0x4a, 0x08, 0x22, 0x30, 0x30, 0x30, 0x30, 0x31, 0x33, 0x22, 0x9a, 0x02, 0x01,
- 0x07, 0xa2, 0x02, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0xfa, 0x42, 0x06, 0x7a, 0x04, 0x68,
- 0x03, 0x70, 0x01, 0xea, 0xaa, 0x19, 0x82, 0x01, 0x0a, 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65,
+ 0x39, 0x5d, 0x7b, 0x31, 0x2c, 0x35, 0x7d, 0x29, 0x3f, 0x24, 0x7c, 0x5e, 0x24, 0x52, 0x11, 0x6a,
+ 0x6f, 0x69, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73,
+ 0x12, 0x74, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0c, 0x20,
+ 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
+ 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4c,
+ 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x42, 0x2c, 0xfa,
+ 0x42, 0x29, 0x9a, 0x01, 0x26, 0x22, 0x24, 0x72, 0x22, 0x18, 0x24, 0x32, 0x1e, 0x5e, 0x5b, 0x61,
+ 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x3f, 0x3a, 0x5b, 0x2d, 0x5d, 0x3f, 0x5b, 0x61, 0x2d,
+ 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x7b, 0x32, 0x2c, 0x7d, 0x24, 0x52, 0x09, 0x6c, 0x6f, 0x63,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x31, 0x0a, 0x07, 0x70, 0x69, 0x63, 0x74, 0x75, 0x72,
+ 0x65, 0x18, 0x32, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
+ 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x50, 0x69, 0x63, 0x74, 0x75, 0x72, 0x65,
+ 0x52, 0x07, 0x70, 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x75, 0x70,
+ 0x70, 0x6f, 0x72, 0x74, 0x73, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x62, 0x18, 0x0d, 0x20,
+ 0x01, 0x28, 0x08, 0x52, 0x0e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x43, 0x6c, 0x61,
+ 0x73, 0x73, 0x42, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x5f,
+ 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x63, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x73,
+ 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x12, 0x4d, 0x0a,
+ 0x0f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
+ 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
+ 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x56, 0x65, 0x72, 0x73, 0x69,
+ 0x6f, 0x6e, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0e, 0x6c, 0x6f,
+ 0x72, 0x61, 0x77, 0x61, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x54, 0x0a, 0x13,
+ 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x5f, 0x70, 0x68, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73,
+ 0x69, 0x6f, 0x6e, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
+ 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x50, 0x48, 0x59, 0x56, 0x65,
+ 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52,
+ 0x11, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x50, 0x68, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69,
+ 0x6f, 0x6e, 0x12, 0x33, 0x0a, 0x11, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x5f,
+ 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa,
+ 0x42, 0x04, 0x72, 0x02, 0x18, 0x40, 0x52, 0x0f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63,
+ 0x79, 0x50, 0x6c, 0x61, 0x6e, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x69, 0x6e, 0x5f, 0x66,
+ 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x12, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c,
+ 0x6d, 0x69, 0x6e, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x23, 0x0a, 0x0d,
+ 0x6d, 0x61, 0x78, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x13, 0x20,
+ 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63,
+ 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x5f, 0x6a, 0x6f,
+ 0x69, 0x6e, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72,
+ 0x74, 0x73, 0x4a, 0x6f, 0x69, 0x6e, 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x65, 0x73, 0x65, 0x74, 0x73,
+ 0x5f, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x15, 0x20, 0x01,
+ 0x28, 0x08, 0x52, 0x10, 0x72, 0x65, 0x73, 0x65, 0x74, 0x73, 0x4a, 0x6f, 0x69, 0x6e, 0x4e, 0x6f,
+ 0x6e, 0x63, 0x65, 0x73, 0x12, 0x35, 0x0a, 0x09, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x6b, 0x65, 0x79,
+ 0x73, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
+ 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x6f, 0x6f, 0x74, 0x4b, 0x65, 0x79,
+ 0x73, 0x52, 0x08, 0x72, 0x6f, 0x6f, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x12, 0xe7, 0x02, 0x0a, 0x06,
+ 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0c, 0x42, 0xcf, 0x02, 0x92,
+ 0x41, 0x17, 0x4a, 0x08, 0x22, 0x30, 0x30, 0x30, 0x30, 0x31, 0x33, 0x22, 0x9a, 0x02, 0x01, 0x07,
+ 0xa2, 0x02, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0xfa, 0x42, 0x06, 0x7a, 0x04, 0x68, 0x03,
+ 0x70, 0x01, 0xea, 0xaa, 0x19, 0x82, 0x01, 0x0a, 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74,
+ 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f,
+ 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70,
+ 0x6b, 0x67, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c,
+ 0x48, 0x45, 0x58, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65,
0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c,
0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f,
- 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4d, 0x61, 0x72, 0x73, 0x68, 0x61,
- 0x6c, 0x48, 0x45, 0x58, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68,
- 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f,
- 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33,
- 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x55, 0x6e, 0x6d, 0x61, 0x72,
- 0x73, 0x68, 0x61, 0x6c, 0x33, 0x42, 0x79, 0x74, 0x65, 0x73, 0xf2, 0xaa, 0x19, 0xa0, 0x01, 0x1a,
- 0x4e, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65,
- 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74,
- 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x74, 0x74, 0x6e, 0x2d, 0x6c,
- 0x77, 0x2d, 0x63, 0x6c, 0x69, 0x2f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x66, 0x6c, 0x61, 0x67,
- 0x73, 0x2e, 0x4e, 0x65, 0x77, 0x33, 0x42, 0x79, 0x74, 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x22,
- 0x4e, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65,
- 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74,
- 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x74, 0x74, 0x6e, 0x2d, 0x6c,
- 0x77, 0x2d, 0x63, 0x6c, 0x69, 0x2f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x66, 0x6c, 0x61, 0x67,
- 0x73, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, 0x61, 0x63, 0x74, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52,
- 0x05, 0x6e, 0x65, 0x74, 0x49, 0x64, 0x12, 0x3e, 0x0a, 0x0c, 0x6d, 0x61, 0x63, 0x5f, 0x73, 0x65,
- 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74,
- 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41,
- 0x43, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x0b, 0x6d, 0x61, 0x63, 0x53, 0x65,
- 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x35, 0x0a, 0x09, 0x6d, 0x61, 0x63, 0x5f, 0x73, 0x74,
- 0x61, 0x74, 0x65, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
- 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x53, 0x74,
- 0x61, 0x74, 0x65, 0x52, 0x08, 0x6d, 0x61, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x44, 0x0a,
- 0x11, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x6d, 0x61, 0x63, 0x5f, 0x73, 0x74, 0x61,
- 0x74, 0x65, 0x18, 0x2c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c,
+ 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x55, 0x6e, 0x6d, 0x61, 0x72, 0x73,
+ 0x68, 0x61, 0x6c, 0x33, 0x42, 0x79, 0x74, 0x65, 0x73, 0xf2, 0xaa, 0x19, 0xa0, 0x01, 0x1a, 0x4e,
+ 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74,
+ 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61,
+ 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x74, 0x74, 0x6e, 0x2d, 0x6c, 0x77,
+ 0x2d, 0x63, 0x6c, 0x69, 0x2f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x66, 0x6c, 0x61, 0x67, 0x73,
+ 0x2e, 0x4e, 0x65, 0x77, 0x33, 0x42, 0x79, 0x74, 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x22, 0x4e,
+ 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74,
+ 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61,
+ 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x74, 0x74, 0x6e, 0x2d, 0x6c, 0x77,
+ 0x2d, 0x63, 0x6c, 0x69, 0x2f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x66, 0x6c, 0x61, 0x67, 0x73,
+ 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, 0x61, 0x63, 0x74, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x05,
+ 0x6e, 0x65, 0x74, 0x49, 0x64, 0x12, 0x3e, 0x0a, 0x0c, 0x6d, 0x61, 0x63, 0x5f, 0x73, 0x65, 0x74,
+ 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x74,
+ 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43,
+ 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x0b, 0x6d, 0x61, 0x63, 0x53, 0x65, 0x74,
+ 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x35, 0x0a, 0x09, 0x6d, 0x61, 0x63, 0x5f, 0x73, 0x74, 0x61,
+ 0x74, 0x65, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c,
0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x53, 0x74, 0x61,
- 0x74, 0x65, 0x52, 0x0f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4d, 0x61, 0x63, 0x53, 0x74,
- 0x61, 0x74, 0x65, 0x12, 0x31, 0x0a, 0x07, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x1a,
- 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
- 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x73,
- 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x40, 0x0a, 0x0f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e,
- 0x67, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0b, 0x32,
- 0x17, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
- 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e,
- 0x67, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x24, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74,
- 0x5f, 0x64, 0x65, 0x76, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0d,
- 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x44, 0x65, 0x76, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x26,
- 0x0a, 0x0f, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x64, 0x65, 0x76, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65,
- 0x73, 0x18, 0x1d, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x0d, 0x75, 0x73, 0x65, 0x64, 0x44, 0x65, 0x76,
- 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6a,
- 0x6f, 0x69, 0x6e, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0d, 0x52,
- 0x0d, 0x6c, 0x61, 0x73, 0x74, 0x4a, 0x6f, 0x69, 0x6e, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x25,
- 0x0a, 0x0f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x72, 0x6a, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f,
- 0x30, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x52, 0x6a, 0x43,
- 0x6f, 0x75, 0x6e, 0x74, 0x30, 0x12, 0x25, 0x0a, 0x0f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x72, 0x6a,
- 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x31, 0x18, 0x20, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c,
- 0x6c, 0x61, 0x73, 0x74, 0x52, 0x6a, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x31, 0x12, 0x58, 0x0a, 0x1b,
- 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x64, 0x65, 0x76, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f,
- 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x21, 0x20, 0x01, 0x28,
- 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
- 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x17, 0x6c,
- 0x61, 0x73, 0x74, 0x44, 0x65, 0x76, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x63, 0x65,
- 0x69, 0x76, 0x65, 0x64, 0x41, 0x74, 0x12, 0x4b, 0x0a, 0x0b, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x5f,
- 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x22, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x74,
- 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x50, 0x6f, 0x77,
- 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x42, 0x0e, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10,
- 0x01, 0xf2, 0xaa, 0x19, 0x02, 0x10, 0x00, 0x52, 0x0a, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x53, 0x74,
- 0x61, 0x74, 0x65, 0x12, 0x5b, 0x0a, 0x12, 0x62, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x5f, 0x70,
- 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x18, 0x23, 0x20, 0x01, 0x28, 0x0b, 0x32,
- 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
- 0x66, 0x2e, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x0f, 0xfa, 0x42,
- 0x0c, 0x0a, 0x0a, 0x1d, 0x00, 0x00, 0x80, 0x3f, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x52, 0x11, 0x62,
- 0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65,
- 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6d, 0x61, 0x72,
- 0x67, 0x69, 0x6e, 0x18, 0x24, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x64, 0x6f, 0x77, 0x6e, 0x6c,
- 0x69, 0x6e, 0x6b, 0x4d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x12, 0x65, 0x0a, 0x1c, 0x71, 0x75, 0x65,
- 0x75, 0x65, 0x64, 0x5f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f,
- 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x28, 0x20, 0x03, 0x28, 0x0b, 0x32,
- 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
- 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x6f, 0x77, 0x6e,
- 0x6c, 0x69, 0x6e, 0x6b, 0x52, 0x1a, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x41, 0x70, 0x70, 0x6c,
- 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73,
- 0x12, 0x48, 0x0a, 0x0a, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x73, 0x18, 0x29,
- 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
- 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x50, 0x61, 0x79,
- 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x73, 0x52, 0x0a,
- 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x73, 0x12, 0x51, 0x0a, 0x0e, 0x70, 0x72,
- 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x2a, 0x20, 0x01,
- 0x28, 0x09, 0x42, 0x2a, 0xfa, 0x42, 0x27, 0x72, 0x25, 0x18, 0x24, 0x32, 0x21, 0x5e, 0x5b, 0x61,
- 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x3f, 0x3a, 0x5b, 0x2d, 0x5d, 0x3f, 0x5b, 0x61, 0x2d,
- 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x7b, 0x32, 0x2c, 0x7d, 0x24, 0x7c, 0x5e, 0x24, 0x52, 0x0d,
- 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x44, 0x0a,
- 0x11, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x64, 0x61,
- 0x74, 0x61, 0x18, 0x2b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
- 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63,
- 0x74, 0x52, 0x10, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x67, 0x44,
- 0x61, 0x74, 0x61, 0x12, 0x1c, 0x0a, 0x09, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61, 0x73, 0x74,
- 0x18, 0x2d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61, 0x73,
- 0x74, 0x12, 0x67, 0x0a, 0x19, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x65,
- 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x2e,
- 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
- 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x41,
- 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x64,
- 0x65, 0x52, 0x17, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69,
- 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x73, 0x6b,
- 0x69, 0x70, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x63, 0x72, 0x79, 0x70, 0x74,
- 0x6f, 0x18, 0x33, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x73, 0x6b, 0x69, 0x70, 0x50, 0x61, 0x79,
- 0x6c, 0x6f, 0x61, 0x64, 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x12, 0x5b, 0x0a, 0x1c, 0x73, 0x6b,
- 0x69, 0x70, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x63, 0x72, 0x79, 0x70, 0x74,
- 0x6f, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x18, 0x34, 0x20, 0x01, 0x28, 0x0b,
+ 0x74, 0x65, 0x52, 0x08, 0x6d, 0x61, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x44, 0x0a, 0x11,
+ 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x6d, 0x61, 0x63, 0x5f, 0x73, 0x74, 0x61, 0x74,
+ 0x65, 0x18, 0x2c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
+ 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x53, 0x74, 0x61, 0x74,
+ 0x65, 0x52, 0x0f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4d, 0x61, 0x63, 0x53, 0x74, 0x61,
+ 0x74, 0x65, 0x12, 0x31, 0x0a, 0x07, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x1a, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
+ 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x73, 0x65,
+ 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x40, 0x0a, 0x0f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67,
+ 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17,
+ 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
+ 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67,
+ 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x24, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f,
+ 0x64, 0x65, 0x76, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0d, 0x52,
+ 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x44, 0x65, 0x76, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x26, 0x0a,
+ 0x0f, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x64, 0x65, 0x76, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73,
+ 0x18, 0x1d, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x0d, 0x75, 0x73, 0x65, 0x64, 0x44, 0x65, 0x76, 0x4e,
+ 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6a, 0x6f,
+ 0x69, 0x6e, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d,
+ 0x6c, 0x61, 0x73, 0x74, 0x4a, 0x6f, 0x69, 0x6e, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x25, 0x0a,
+ 0x0f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x72, 0x6a, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x30,
+ 0x18, 0x1f, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x52, 0x6a, 0x43, 0x6f,
+ 0x75, 0x6e, 0x74, 0x30, 0x12, 0x25, 0x0a, 0x0f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x72, 0x6a, 0x5f,
+ 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x31, 0x18, 0x20, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x6c,
+ 0x61, 0x73, 0x74, 0x52, 0x6a, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x31, 0x12, 0x58, 0x0a, 0x1b, 0x6c,
+ 0x61, 0x73, 0x74, 0x5f, 0x64, 0x65, 0x76, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x72,
+ 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x21, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
- 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x19, 0x73, 0x6b,
- 0x69, 0x70, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x4f,
- 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x12, 0x3d, 0x0a, 0x0c, 0x61, 0x63, 0x74, 0x69, 0x76,
- 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x35, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
- 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
- 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0b, 0x61, 0x63, 0x74, 0x69, 0x76,
- 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x3c, 0x0a, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73,
- 0x65, 0x65, 0x6e, 0x5f, 0x61, 0x74, 0x18, 0x36, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67,
+ 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x17, 0x6c, 0x61,
+ 0x73, 0x74, 0x44, 0x65, 0x76, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x63, 0x65, 0x69,
+ 0x76, 0x65, 0x64, 0x41, 0x74, 0x12, 0x4b, 0x0a, 0x0b, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x5f, 0x73,
+ 0x74, 0x61, 0x74, 0x65, 0x18, 0x22, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x74, 0x6e,
+ 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x50, 0x6f, 0x77, 0x65,
+ 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x42, 0x0e, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01,
+ 0xf2, 0xaa, 0x19, 0x02, 0x10, 0x00, 0x52, 0x0a, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x53, 0x74, 0x61,
+ 0x74, 0x65, 0x12, 0x5b, 0x0a, 0x12, 0x62, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x5f, 0x70, 0x65,
+ 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x18, 0x23, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b,
+ 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
+ 0x2e, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x0f, 0xfa, 0x42, 0x0c,
+ 0x0a, 0x0a, 0x1d, 0x00, 0x00, 0x80, 0x3f, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x52, 0x11, 0x62, 0x61,
+ 0x74, 0x74, 0x65, 0x72, 0x79, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x12,
+ 0x27, 0x0a, 0x0f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6d, 0x61, 0x72, 0x67,
+ 0x69, 0x6e, 0x18, 0x24, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69,
+ 0x6e, 0x6b, 0x4d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x12, 0x65, 0x0a, 0x1c, 0x71, 0x75, 0x65, 0x75,
+ 0x65, 0x64, 0x5f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64,
+ 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x28, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23,
+ 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
+ 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x6f, 0x77, 0x6e, 0x6c,
+ 0x69, 0x6e, 0x6b, 0x52, 0x1a, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x41, 0x70, 0x70, 0x6c, 0x69,
+ 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x12,
+ 0x48, 0x0a, 0x0a, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x73, 0x18, 0x29, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
+ 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x50, 0x61, 0x79, 0x6c,
+ 0x6f, 0x61, 0x64, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x73, 0x52, 0x0a, 0x66,
+ 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x73, 0x12, 0x51, 0x0a, 0x0e, 0x70, 0x72, 0x6f,
+ 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x2a, 0x20, 0x01, 0x28,
+ 0x09, 0x42, 0x2a, 0xfa, 0x42, 0x27, 0x72, 0x25, 0x18, 0x24, 0x32, 0x21, 0x5e, 0x5b, 0x61, 0x2d,
+ 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x3f, 0x3a, 0x5b, 0x2d, 0x5d, 0x3f, 0x5b, 0x61, 0x2d, 0x7a,
+ 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x7b, 0x32, 0x2c, 0x7d, 0x24, 0x7c, 0x5e, 0x24, 0x52, 0x0d, 0x70,
+ 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x44, 0x0a, 0x11,
+ 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x64, 0x61, 0x74,
+ 0x61, 0x18, 0x2b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+ 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74,
+ 0x52, 0x10, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x67, 0x44, 0x61,
+ 0x74, 0x61, 0x12, 0x1c, 0x0a, 0x09, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61, 0x73, 0x74, 0x18,
+ 0x2d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61, 0x73, 0x74,
+ 0x12, 0x67, 0x0a, 0x19, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e,
+ 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x2e, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
+ 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x41, 0x75,
+ 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x64, 0x65,
+ 0x52, 0x17, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x73, 0x6b, 0x69,
+ 0x70, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f,
+ 0x18, 0x33, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x73, 0x6b, 0x69, 0x70, 0x50, 0x61, 0x79, 0x6c,
+ 0x6f, 0x61, 0x64, 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x12, 0x5b, 0x0a, 0x1c, 0x73, 0x6b, 0x69,
+ 0x70, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f,
+ 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x18, 0x34, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
+ 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x19, 0x73, 0x6b, 0x69,
+ 0x70, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x4f, 0x76,
+ 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x12, 0x3d, 0x0a, 0x0c, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61,
+ 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x35, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67,
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54,
- 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x65,
- 0x65, 0x6e, 0x41, 0x74, 0x12, 0x4f, 0x0a, 0x0d, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x5f, 0x6e,
- 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x37, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2a, 0xfa, 0x42, 0x27,
- 0x72, 0x25, 0x18, 0x24, 0x32, 0x1e, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x28,
- 0x3f, 0x3a, 0x5b, 0x2d, 0x5d, 0x3f, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x7b,
- 0x32, 0x2c, 0x7d, 0x24, 0xd0, 0x01, 0x01, 0x52, 0x0c, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x4e,
- 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x69, 0x0a, 0x19, 0x6c, 0x6f, 0x72, 0x61, 0x5f, 0x61, 0x6c,
- 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x69,
- 0x64, 0x73, 0x18, 0x38, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c,
- 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x6f, 0x52, 0x61, 0x41, 0x6c,
- 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x65,
- 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x52, 0x16, 0x6c, 0x6f, 0x72, 0x61, 0x41, 0x6c,
- 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x73,
- 0x1a, 0x3d, 0x0a, 0x0f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x45, 0x6e,
- 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
- 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02,
- 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a,
- 0x56, 0x0a, 0x0e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72,
- 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
- 0x6b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01,
- 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
- 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x76, 0x61,
- 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10,
- 0x01, 0x4a, 0x04, 0x08, 0x25, 0x10, 0x26, 0x4a, 0x04, 0x08, 0x26, 0x10, 0x27, 0x4a, 0x04, 0x08,
- 0x27, 0x10, 0x28, 0x22, 0x48, 0x0a, 0x0a, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65,
- 0x73, 0x12, 0x3a, 0x0a, 0x0b, 0x65, 0x6e, 0x64, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73,
- 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
- 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63,
- 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x22, 0xf2, 0x01,
- 0x0a, 0x0d, 0x44, 0x65, 0x76, 0x41, 0x64, 0x64, 0x72, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12,
- 0xc8, 0x01, 0x0a, 0x08, 0x64, 0x65, 0x76, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x0c, 0x42, 0xac, 0x01, 0x92, 0x41, 0x19, 0x4a, 0x0a, 0x22, 0x32, 0x36, 0x30, 0x30, 0x41,
- 0x42, 0x43, 0x44, 0x22, 0x9a, 0x02, 0x01, 0x07, 0xa2, 0x02, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e,
- 0x67, 0xfa, 0x42, 0x06, 0x7a, 0x04, 0x68, 0x04, 0x70, 0x01, 0xea, 0xaa, 0x19, 0x82, 0x01, 0x0a,
+ 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0b, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61,
+ 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x3c, 0x0a, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x65,
+ 0x65, 0x6e, 0x5f, 0x61, 0x74, 0x18, 0x36, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f,
+ 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69,
+ 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x65, 0x65,
+ 0x6e, 0x41, 0x74, 0x12, 0x4f, 0x0a, 0x0d, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x5f, 0x6e, 0x75,
+ 0x6d, 0x62, 0x65, 0x72, 0x18, 0x37, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2a, 0xfa, 0x42, 0x27, 0x72,
+ 0x25, 0x18, 0x24, 0x32, 0x1e, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x3f,
+ 0x3a, 0x5b, 0x2d, 0x5d, 0x3f, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x7b, 0x32,
+ 0x2c, 0x7d, 0x24, 0xd0, 0x01, 0x01, 0x52, 0x0c, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x4e, 0x75,
+ 0x6d, 0x62, 0x65, 0x72, 0x12, 0x69, 0x0a, 0x19, 0x6c, 0x6f, 0x72, 0x61, 0x5f, 0x61, 0x6c, 0x6c,
+ 0x69, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x69, 0x64,
+ 0x73, 0x18, 0x38, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
+ 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x6f, 0x52, 0x61, 0x41, 0x6c, 0x6c,
+ 0x69, 0x61, 0x6e, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x65, 0x6e,
+ 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x52, 0x16, 0x6c, 0x6f, 0x72, 0x61, 0x41, 0x6c, 0x6c,
+ 0x69, 0x61, 0x6e, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x73, 0x1a,
+ 0x3d, 0x0a, 0x0f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74,
+ 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x56,
+ 0x0a, 0x0e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79,
+ 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b,
+ 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+ 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
+ 0x76, 0x33, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c,
+ 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01,
+ 0x4a, 0x04, 0x08, 0x25, 0x10, 0x26, 0x4a, 0x04, 0x08, 0x26, 0x10, 0x27, 0x4a, 0x04, 0x08, 0x27,
+ 0x10, 0x28, 0x22, 0x48, 0x0a, 0x0a, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73,
+ 0x12, 0x3a, 0x0a, 0x0b, 0x65, 0x6e, 0x64, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18,
+ 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
+ 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65,
+ 0x52, 0x0a, 0x65, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x22, 0xf2, 0x01, 0x0a,
+ 0x0d, 0x44, 0x65, 0x76, 0x41, 0x64, 0x64, 0x72, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0xc8,
+ 0x01, 0x0a, 0x08, 0x64, 0x65, 0x76, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x0c, 0x42, 0xac, 0x01, 0x92, 0x41, 0x19, 0x4a, 0x0a, 0x22, 0x32, 0x36, 0x30, 0x30, 0x41, 0x42,
+ 0x43, 0x44, 0x22, 0x9a, 0x02, 0x01, 0x07, 0xa2, 0x02, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67,
+ 0xfa, 0x42, 0x06, 0x7a, 0x04, 0x68, 0x04, 0x70, 0x01, 0xea, 0xaa, 0x19, 0x82, 0x01, 0x0a, 0x3f,
+ 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74,
+ 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61,
+ 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e,
+ 0x4d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x48, 0x45, 0x58, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12,
0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65,
0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74,
0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73,
- 0x2e, 0x4d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x48, 0x45, 0x58, 0x42, 0x79, 0x74, 0x65, 0x73,
- 0x12, 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e,
- 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73,
- 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x79, 0x70, 0x65,
- 0x73, 0x2e, 0x55, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x34, 0x42, 0x79, 0x74, 0x65,
- 0x73, 0x52, 0x07, 0x64, 0x65, 0x76, 0x41, 0x64, 0x64, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x65,
- 0x6e, 0x67, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6c, 0x65, 0x6e, 0x67,
- 0x74, 0x68, 0x22, 0x5c, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x64, 0x44,
- 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x0a,
- 0x65, 0x6e, 0x64, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
- 0x32, 0x19, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
- 0x33, 0x2e, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x42, 0x08, 0xfa, 0x42, 0x05,
- 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x09, 0x65, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65,
- 0x22, 0x97, 0x01, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x64, 0x44, 0x65,
+ 0x2e, 0x55, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x34, 0x42, 0x79, 0x74, 0x65, 0x73,
+ 0x52, 0x07, 0x64, 0x65, 0x76, 0x41, 0x64, 0x64, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x65, 0x6e,
+ 0x67, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74,
+ 0x68, 0x22, 0x5c, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x64, 0x44, 0x65,
0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x0a, 0x65,
0x6e, 0x64, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x19, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
0x2e, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a,
- 0x01, 0x02, 0x10, 0x01, 0x52, 0x09, 0x65, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12,
- 0x39, 0x0a, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20,
- 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
- 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52,
- 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0xa8, 0x02, 0x0a, 0x23, 0x42,
- 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76,
- 0x69, 0x63, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65,
- 0x73, 0x74, 0x12, 0x65, 0x0a, 0x07, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20,
- 0x03, 0x28, 0x0b, 0x32, 0x4b, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
- 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
- 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x53, 0x65, 0x65,
- 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69,
- 0x63, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
- 0x52, 0x07, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x1a, 0x99, 0x01, 0x0a, 0x17, 0x45, 0x6e,
- 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x55,
- 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x40, 0x0a, 0x03, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
- 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x65,
- 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02,
- 0x10, 0x01, 0x52, 0x03, 0x69, 0x64, 0x73, 0x12, 0x3c, 0x0a, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x5f,
- 0x73, 0x65, 0x65, 0x6e, 0x5f, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
- 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
- 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x53,
- 0x65, 0x65, 0x6e, 0x41, 0x74, 0x22, 0xa6, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x64,
- 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x54, 0x0a,
- 0x0e, 0x65, 0x6e, 0x64, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18,
- 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
- 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65,
- 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05,
- 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0c, 0x65, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65,
- 0x49, 0x64, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73,
- 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
- 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d,
- 0x61, 0x73, 0x6b, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0xcb,
- 0x03, 0x0a, 0x25, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49,
- 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x46, 0x6f, 0x72, 0x45, 0x55, 0x49,
- 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xd0, 0x01, 0x0a, 0x08, 0x6a, 0x6f, 0x69,
- 0x6e, 0x5f, 0x65, 0x75, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0xb4, 0x01, 0x92, 0x41,
- 0x21, 0x4a, 0x12, 0x22, 0x37, 0x30, 0x42, 0x33, 0x44, 0x35, 0x37, 0x45, 0x44, 0x30, 0x30, 0x30,
- 0x41, 0x42, 0x43, 0x44, 0x22, 0x9a, 0x02, 0x01, 0x07, 0xa2, 0x02, 0x06, 0x73, 0x74, 0x72, 0x69,
- 0x6e, 0x67, 0xfa, 0x42, 0x06, 0x7a, 0x04, 0x68, 0x08, 0x70, 0x01, 0xea, 0xaa, 0x19, 0x82, 0x01,
- 0x0a, 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e,
+ 0x01, 0x02, 0x10, 0x01, 0x52, 0x09, 0x65, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x22,
+ 0x97, 0x01, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76,
+ 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x0a, 0x65, 0x6e,
+ 0x64, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19,
+ 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
+ 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01,
+ 0x02, 0x10, 0x01, 0x52, 0x09, 0x65, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x39,
+ 0x0a, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x09,
+ 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0xa8, 0x02, 0x0a, 0x23, 0x42, 0x61,
+ 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69,
+ 0x63, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+ 0x74, 0x12, 0x65, 0x0a, 0x07, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03,
+ 0x28, 0x0b, 0x32, 0x4b, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
+ 0x2e, 0x76, 0x33, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45,
+ 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e,
+ 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63,
+ 0x65, 0x4c, 0x61, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52,
+ 0x07, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x1a, 0x99, 0x01, 0x0a, 0x17, 0x45, 0x6e, 0x64,
+ 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x55, 0x70,
+ 0x64, 0x61, 0x74, 0x65, 0x12, 0x40, 0x0a, 0x03, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x0b, 0x32, 0x24, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
+ 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e,
+ 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10,
+ 0x01, 0x52, 0x03, 0x69, 0x64, 0x73, 0x12, 0x3c, 0x0a, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73,
+ 0x65, 0x65, 0x6e, 0x5f, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67,
+ 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54,
+ 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x65,
+ 0x65, 0x6e, 0x41, 0x74, 0x22, 0xa6, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x64, 0x44,
+ 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x54, 0x0a, 0x0e,
+ 0x65, 0x6e, 0x64, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
+ 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49,
+ 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a,
+ 0x01, 0x02, 0x10, 0x01, 0x52, 0x0c, 0x65, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49,
+ 0x64, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61,
+ 0x73, 0x6b, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0xcb, 0x03,
+ 0x0a, 0x25, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64,
+ 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x46, 0x6f, 0x72, 0x45, 0x55, 0x49, 0x73,
+ 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xd0, 0x01, 0x0a, 0x08, 0x6a, 0x6f, 0x69, 0x6e,
+ 0x5f, 0x65, 0x75, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0xb4, 0x01, 0x92, 0x41, 0x21,
+ 0x4a, 0x12, 0x22, 0x37, 0x30, 0x42, 0x33, 0x44, 0x35, 0x37, 0x45, 0x44, 0x30, 0x30, 0x30, 0x41,
+ 0x42, 0x43, 0x44, 0x22, 0x9a, 0x02, 0x01, 0x07, 0xa2, 0x02, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e,
+ 0x67, 0xfa, 0x42, 0x06, 0x7a, 0x04, 0x68, 0x08, 0x70, 0x01, 0xea, 0xaa, 0x19, 0x82, 0x01, 0x0a,
+ 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65,
+ 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74,
+ 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73,
+ 0x2e, 0x4d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x48, 0x45, 0x58, 0x42, 0x79, 0x74, 0x65, 0x73,
+ 0x12, 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e,
0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73,
0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x79, 0x70, 0x65,
- 0x73, 0x2e, 0x4d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x48, 0x45, 0x58, 0x42, 0x79, 0x74, 0x65,
- 0x73, 0x12, 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e,
+ 0x73, 0x2e, 0x55, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x38, 0x42, 0x79, 0x74, 0x65,
+ 0x73, 0x52, 0x07, 0x6a, 0x6f, 0x69, 0x6e, 0x45, 0x75, 0x69, 0x12, 0xce, 0x01, 0x0a, 0x07, 0x64,
+ 0x65, 0x76, 0x5f, 0x65, 0x75, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0xb4, 0x01, 0x92,
+ 0x41, 0x21, 0x4a, 0x12, 0x22, 0x37, 0x30, 0x42, 0x33, 0x44, 0x35, 0x37, 0x45, 0x44, 0x30, 0x30,
+ 0x30, 0x41, 0x42, 0x43, 0x44, 0x22, 0x9a, 0x02, 0x01, 0x07, 0xa2, 0x02, 0x06, 0x73, 0x74, 0x72,
+ 0x69, 0x6e, 0x67, 0xfa, 0x42, 0x06, 0x7a, 0x04, 0x68, 0x08, 0x70, 0x01, 0xea, 0xaa, 0x19, 0x82,
+ 0x01, 0x0a, 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e,
0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d,
0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x79, 0x70,
- 0x65, 0x73, 0x2e, 0x55, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x38, 0x42, 0x79, 0x74,
- 0x65, 0x73, 0x52, 0x07, 0x6a, 0x6f, 0x69, 0x6e, 0x45, 0x75, 0x69, 0x12, 0xce, 0x01, 0x0a, 0x07,
- 0x64, 0x65, 0x76, 0x5f, 0x65, 0x75, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0xb4, 0x01,
- 0x92, 0x41, 0x21, 0x4a, 0x12, 0x22, 0x37, 0x30, 0x42, 0x33, 0x44, 0x35, 0x37, 0x45, 0x44, 0x30,
- 0x30, 0x30, 0x41, 0x42, 0x43, 0x44, 0x22, 0x9a, 0x02, 0x01, 0x07, 0xa2, 0x02, 0x06, 0x73, 0x74,
- 0x72, 0x69, 0x6e, 0x67, 0xfa, 0x42, 0x06, 0x7a, 0x04, 0x68, 0x08, 0x70, 0x01, 0xea, 0xaa, 0x19,
- 0x82, 0x01, 0x0a, 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73,
+ 0x65, 0x73, 0x2e, 0x4d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x48, 0x45, 0x58, 0x42, 0x79, 0x74,
+ 0x65, 0x73, 0x12, 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73,
0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x79,
- 0x70, 0x65, 0x73, 0x2e, 0x4d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x48, 0x45, 0x58, 0x42, 0x79,
- 0x74, 0x65, 0x73, 0x12, 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67,
- 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
- 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74,
- 0x79, 0x70, 0x65, 0x73, 0x2e, 0x55, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x38, 0x42,
- 0x79, 0x74, 0x65, 0x73, 0x52, 0x06, 0x64, 0x65, 0x76, 0x45, 0x75, 0x69, 0x22, 0x97, 0x03, 0x0a,
- 0x15, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52,
- 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4f, 0x0a, 0x0f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63,
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
- 0x26, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
- 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x65, 0x6e,
- 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x52, 0x0e, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61,
- 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64,
+ 0x70, 0x65, 0x73, 0x2e, 0x55, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x38, 0x42, 0x79,
+ 0x74, 0x65, 0x73, 0x52, 0x06, 0x64, 0x65, 0x76, 0x45, 0x75, 0x69, 0x22, 0x97, 0x03, 0x0a, 0x15,
+ 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65,
+ 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4f, 0x0a, 0x0f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26,
+ 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
+ 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x65, 0x6e, 0x74,
+ 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x52, 0x0e, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f,
+ 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f,
+ 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65,
+ 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73,
+ 0x6b, 0x12, 0xbd, 0x01, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28,
+ 0x09, 0x42, 0xa6, 0x01, 0xfa, 0x42, 0xa2, 0x01, 0x72, 0x9f, 0x01, 0x52, 0x00, 0x52, 0x09, 0x64,
+ 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x52, 0x0a, 0x2d, 0x64, 0x65, 0x76, 0x69, 0x63,
+ 0x65, 0x5f, 0x69, 0x64, 0x52, 0x08, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x65, 0x75, 0x69, 0x52, 0x09,
+ 0x2d, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x65, 0x75, 0x69, 0x52, 0x07, 0x64, 0x65, 0x76, 0x5f, 0x65,
+ 0x75, 0x69, 0x52, 0x08, 0x2d, 0x64, 0x65, 0x76, 0x5f, 0x65, 0x75, 0x69, 0x52, 0x04, 0x6e, 0x61,
+ 0x6d, 0x65, 0x52, 0x05, 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72,
+ 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x2d, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,
+ 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74,
+ 0x52, 0x0b, 0x2d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x52, 0x0c, 0x6c,
+ 0x61, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x5f, 0x61, 0x74, 0x52, 0x0d, 0x2d, 0x6c, 0x61,
+ 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x5f, 0x61, 0x74, 0x52, 0x05, 0x6f, 0x72, 0x64, 0x65,
+ 0x72, 0x12, 0x1e, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d,
+ 0x42, 0x08, 0xfa, 0x42, 0x05, 0x2a, 0x03, 0x18, 0xe8, 0x07, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69,
+ 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52,
+ 0x04, 0x70, 0x61, 0x67, 0x65, 0x22, 0x94, 0x01, 0x0a, 0x13, 0x53, 0x65, 0x74, 0x45, 0x6e, 0x64,
+ 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a,
+ 0x0a, 0x65, 0x6e, 0x64, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
+ 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x42, 0x08, 0xfa, 0x42,
+ 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x09, 0x65, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63,
+ 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18,
+ 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73,
+ 0x6b, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0xae, 0x01, 0x0a,
+ 0x1b, 0x52, 0x65, 0x73, 0x65, 0x74, 0x41, 0x6e, 0x64, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x64, 0x44,
+ 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x54, 0x0a, 0x0e,
+ 0x65, 0x6e, 0x64, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
+ 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49,
+ 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a,
+ 0x01, 0x02, 0x10, 0x01, 0x52, 0x0c, 0x65, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49,
+ 0x64, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61,
+ 0x73, 0x6b, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0xbc, 0x01,
+ 0x0a, 0x11, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x65, 0x6d, 0x70, 0x6c,
+ 0x61, 0x74, 0x65, 0x12, 0x42, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63,
+ 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
+ 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69,
+ 0x63, 0x65, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x09, 0x65, 0x6e,
+ 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64,
0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f,
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69,
0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61,
- 0x73, 0x6b, 0x12, 0xbd, 0x01, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01,
- 0x28, 0x09, 0x42, 0xa6, 0x01, 0xfa, 0x42, 0xa2, 0x01, 0x72, 0x9f, 0x01, 0x52, 0x00, 0x52, 0x09,
- 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x52, 0x0a, 0x2d, 0x64, 0x65, 0x76, 0x69,
- 0x63, 0x65, 0x5f, 0x69, 0x64, 0x52, 0x08, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x65, 0x75, 0x69, 0x52,
- 0x09, 0x2d, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x65, 0x75, 0x69, 0x52, 0x07, 0x64, 0x65, 0x76, 0x5f,
- 0x65, 0x75, 0x69, 0x52, 0x08, 0x2d, 0x64, 0x65, 0x76, 0x5f, 0x65, 0x75, 0x69, 0x52, 0x04, 0x6e,
- 0x61, 0x6d, 0x65, 0x52, 0x05, 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63,
- 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x2d, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
- 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61,
- 0x74, 0x52, 0x0b, 0x2d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x52, 0x0c,
- 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x5f, 0x61, 0x74, 0x52, 0x0d, 0x2d, 0x6c,
- 0x61, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x5f, 0x61, 0x74, 0x52, 0x05, 0x6f, 0x72, 0x64,
- 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28,
- 0x0d, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x2a, 0x03, 0x18, 0xe8, 0x07, 0x52, 0x05, 0x6c, 0x69, 0x6d,
- 0x69, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d,
- 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x22, 0x94, 0x01, 0x0a, 0x13, 0x53, 0x65, 0x74, 0x45, 0x6e,
- 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42,
- 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
- 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x42, 0x08, 0xfa,
- 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x09, 0x65, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69,
- 0x63, 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b,
- 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61,
- 0x73, 0x6b, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0xae, 0x01,
- 0x0a, 0x1b, 0x52, 0x65, 0x73, 0x65, 0x74, 0x41, 0x6e, 0x64, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x64,
- 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x54, 0x0a,
- 0x0e, 0x65, 0x6e, 0x64, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18,
- 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
+ 0x73, 0x6b, 0x12, 0x28, 0x0a, 0x0b, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x6b, 0x65,
+ 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x18, 0x64,
+ 0x52, 0x0a, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4b, 0x65, 0x79, 0x22, 0xb8, 0x01, 0x0a,
+ 0x17, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61,
+ 0x74, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x18, 0x64, 0x52,
+ 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,
+ 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x72,
+ 0x03, 0x18, 0xc8, 0x01, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
+ 0x6e, 0x12, 0x54, 0x0a, 0x0f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73,
+ 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x42, 0x2b, 0xfa, 0x42, 0x28, 0x92,
+ 0x01, 0x25, 0x10, 0x64, 0x18, 0x01, 0x22, 0x1f, 0x72, 0x1d, 0x32, 0x1b, 0x5e, 0x28, 0x3f, 0x3a,
+ 0x5c, 0x2e, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x7b, 0x31, 0x2c, 0x31, 0x36, 0x7d,
+ 0x29, 0x7b, 0x31, 0x2c, 0x32, 0x7d, 0x24, 0x52, 0x0e, 0x66, 0x69, 0x6c, 0x65, 0x45, 0x78, 0x74,
+ 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xfe, 0x01, 0x0a, 0x18, 0x45, 0x6e, 0x64, 0x44,
+ 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x46, 0x6f, 0x72,
+ 0x6d, 0x61, 0x74, 0x73, 0x12, 0x7d, 0x0a, 0x07, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x73, 0x18,
+ 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65,
- 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05,
- 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0c, 0x65, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65,
- 0x49, 0x64, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73,
- 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
- 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d,
- 0x61, 0x73, 0x6b, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0xbc,
- 0x01, 0x0a, 0x11, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x65, 0x6d, 0x70,
- 0x6c, 0x61, 0x74, 0x65, 0x12, 0x42, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x5f, 0x64, 0x65, 0x76, 0x69,
- 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c,
- 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76,
- 0x69, 0x63, 0x65, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x09, 0x65,
- 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x66, 0x69, 0x65, 0x6c,
- 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67,
- 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46,
- 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4d,
- 0x61, 0x73, 0x6b, 0x12, 0x28, 0x0a, 0x0b, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x6b,
- 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x18,
- 0x64, 0x52, 0x0a, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4b, 0x65, 0x79, 0x22, 0xb8, 0x01,
- 0x0a, 0x17, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x65, 0x6d, 0x70, 0x6c,
- 0x61, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
- 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x18, 0x64,
- 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
- 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xfa, 0x42, 0x05,
- 0x72, 0x03, 0x18, 0xc8, 0x01, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69,
- 0x6f, 0x6e, 0x12, 0x54, 0x0a, 0x0f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e,
- 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x42, 0x2b, 0xfa, 0x42, 0x28,
- 0x92, 0x01, 0x25, 0x10, 0x64, 0x18, 0x01, 0x22, 0x1f, 0x72, 0x1d, 0x32, 0x1b, 0x5e, 0x28, 0x3f,
- 0x3a, 0x5c, 0x2e, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x7b, 0x31, 0x2c, 0x31, 0x36,
- 0x7d, 0x29, 0x7b, 0x31, 0x2c, 0x32, 0x7d, 0x24, 0x52, 0x0e, 0x66, 0x69, 0x6c, 0x65, 0x45, 0x78,
- 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xfe, 0x01, 0x0a, 0x18, 0x45, 0x6e, 0x64,
- 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x46, 0x6f,
- 0x72, 0x6d, 0x61, 0x74, 0x73, 0x12, 0x7d, 0x0a, 0x07, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x73,
- 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
+ 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x73, 0x2e,
+ 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x42, 0x2c, 0xfa, 0x42,
+ 0x29, 0x9a, 0x01, 0x26, 0x22, 0x24, 0x72, 0x22, 0x18, 0x24, 0x32, 0x1e, 0x5e, 0x5b, 0x61, 0x2d,
+ 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x3f, 0x3a, 0x5b, 0x2d, 0x5d, 0x3f, 0x5b, 0x61, 0x2d, 0x7a,
+ 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x7b, 0x32, 0x2c, 0x7d, 0x24, 0x52, 0x07, 0x66, 0x6f, 0x72, 0x6d,
+ 0x61, 0x74, 0x73, 0x1a, 0x63, 0x0a, 0x0c, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x73, 0x45, 0x6e,
+ 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x3d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
+ 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54,
+ 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x05, 0x76,
+ 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xdd, 0x01, 0x0a, 0x1f, 0x43, 0x6f, 0x6e,
+ 0x76, 0x65, 0x72, 0x74, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x65, 0x6d,
+ 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x09,
+ 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42,
+ 0x27, 0xfa, 0x42, 0x24, 0x72, 0x22, 0x18, 0x24, 0x32, 0x1e, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x30,
+ 0x2d, 0x39, 0x5d, 0x28, 0x3f, 0x3a, 0x5b, 0x2d, 0x5d, 0x3f, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d,
+ 0x39, 0x5d, 0x29, 0x7b, 0x32, 0x2c, 0x7d, 0x24, 0x52, 0x08, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74,
+ 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c,
+ 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x60, 0x0a, 0x16, 0x65, 0x6e, 0x64, 0x5f, 0x64, 0x65,
+ 0x76, 0x69, 0x63, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73,
+ 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63,
- 0x65, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x73,
- 0x2e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x42, 0x2c, 0xfa,
- 0x42, 0x29, 0x9a, 0x01, 0x26, 0x22, 0x24, 0x72, 0x22, 0x18, 0x24, 0x32, 0x1e, 0x5e, 0x5b, 0x61,
- 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x3f, 0x3a, 0x5b, 0x2d, 0x5d, 0x3f, 0x5b, 0x61, 0x2d,
- 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x7b, 0x32, 0x2c, 0x7d, 0x24, 0x52, 0x07, 0x66, 0x6f, 0x72,
- 0x6d, 0x61, 0x74, 0x73, 0x1a, 0x63, 0x0a, 0x0c, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x73, 0x45,
- 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x3d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
- 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
- 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65,
- 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x05,
- 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xdd, 0x01, 0x0a, 0x1f, 0x43, 0x6f,
- 0x6e, 0x76, 0x65, 0x72, 0x74, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x65,
- 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a,
- 0x09, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
- 0x42, 0x27, 0xfa, 0x42, 0x24, 0x72, 0x22, 0x18, 0x24, 0x32, 0x1e, 0x5e, 0x5b, 0x61, 0x2d, 0x7a,
- 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x3f, 0x3a, 0x5b, 0x2d, 0x5d, 0x3f, 0x5b, 0x61, 0x2d, 0x7a, 0x30,
- 0x2d, 0x39, 0x5d, 0x29, 0x7b, 0x32, 0x2c, 0x7d, 0x24, 0x52, 0x08, 0x66, 0x6f, 0x72, 0x6d, 0x61,
- 0x74, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28,
- 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x60, 0x0a, 0x16, 0x65, 0x6e, 0x64, 0x5f, 0x64,
- 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64,
- 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
- 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69,
- 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66,
- 0x69, 0x65, 0x72, 0x73, 0x52, 0x13, 0x65, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x56,
- 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x22, 0xca, 0x01, 0x0a, 0x1c, 0x42, 0x61,
- 0x74, 0x63, 0x68, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69,
- 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x59, 0x0a, 0x0f, 0x61, 0x70,
- 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
- 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
- 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05,
- 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0e, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69,
- 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x4f, 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f,
- 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x42, 0x30, 0xfa, 0x42, 0x2d, 0x92, 0x01,
- 0x2a, 0x08, 0x01, 0x10, 0x14, 0x22, 0x24, 0x72, 0x22, 0x18, 0x24, 0x32, 0x1e, 0x5e, 0x5b, 0x61,
- 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x3f, 0x3a, 0x5b, 0x2d, 0x5d, 0x3f, 0x5b, 0x61, 0x2d,
- 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x7b, 0x32, 0x2c, 0x7d, 0x24, 0x52, 0x09, 0x64, 0x65, 0x76,
- 0x69, 0x63, 0x65, 0x49, 0x64, 0x73, 0x22, 0xa8, 0x02, 0x0a, 0x19, 0x42, 0x61, 0x74, 0x63, 0x68,
- 0x47, 0x65, 0x74, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71,
- 0x75, 0x65, 0x73, 0x74, 0x12, 0x59, 0x0a, 0x0f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74,
- 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e,
- 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41,
- 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69,
- 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52,
- 0x0e, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12,
- 0x4f, 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20,
- 0x03, 0x28, 0x09, 0x42, 0x30, 0xfa, 0x42, 0x2d, 0x92, 0x01, 0x2a, 0x08, 0x01, 0x10, 0x14, 0x22,
- 0x24, 0x72, 0x22, 0x18, 0x24, 0x32, 0x1e, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d,
- 0x28, 0x3f, 0x3a, 0x5b, 0x2d, 0x5d, 0x3f, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x29,
- 0x7b, 0x32, 0x2c, 0x7d, 0x24, 0x52, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x73,
- 0x12, 0x39, 0x0a, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x03,
- 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
- 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b,
- 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x4a, 0x04, 0x08, 0x04, 0x10,
- 0x05, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x4a, 0x04, 0x08, 0x06, 0x10, 0x07, 0x52, 0x05, 0x6f,
- 0x72, 0x64, 0x65, 0x72, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x04, 0x70, 0x61, 0x67,
- 0x65, 0x2a, 0x55, 0x0a, 0x0a, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12,
- 0x11, 0x0a, 0x0d, 0x50, 0x4f, 0x57, 0x45, 0x52, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e,
- 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x50, 0x4f, 0x57, 0x45, 0x52, 0x5f, 0x42, 0x41, 0x54, 0x54,
- 0x45, 0x52, 0x59, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x50, 0x4f, 0x57, 0x45, 0x52, 0x5f, 0x45,
- 0x58, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x10, 0x02, 0x1a, 0x0d, 0xea, 0xaa, 0x19, 0x09, 0x18,
- 0x01, 0x2a, 0x05, 0x50, 0x4f, 0x57, 0x45, 0x52, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x6f, 0x2e, 0x74,
- 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
- 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76,
- 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74, 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f,
- 0x74, 0x6f, 0x33,
+ 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69,
+ 0x65, 0x72, 0x73, 0x52, 0x13, 0x65, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x56, 0x65,
+ 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x22, 0xca, 0x01, 0x0a, 0x1c, 0x42, 0x61, 0x74,
+ 0x63, 0x68, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63,
+ 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x59, 0x0a, 0x0f, 0x61, 0x70, 0x70,
+ 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
+ 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49,
+ 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a,
+ 0x01, 0x02, 0x10, 0x01, 0x52, 0x0e, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x49, 0x64, 0x73, 0x12, 0x4f, 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69,
+ 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x42, 0x30, 0xfa, 0x42, 0x2d, 0x92, 0x01, 0x2a,
+ 0x08, 0x01, 0x10, 0x14, 0x22, 0x24, 0x72, 0x22, 0x18, 0x24, 0x32, 0x1e, 0x5e, 0x5b, 0x61, 0x2d,
+ 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x3f, 0x3a, 0x5b, 0x2d, 0x5d, 0x3f, 0x5b, 0x61, 0x2d, 0x7a,
+ 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x7b, 0x32, 0x2c, 0x7d, 0x24, 0x52, 0x09, 0x64, 0x65, 0x76, 0x69,
+ 0x63, 0x65, 0x49, 0x64, 0x73, 0x22, 0xa8, 0x02, 0x0a, 0x19, 0x42, 0x61, 0x74, 0x63, 0x68, 0x47,
+ 0x65, 0x74, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75,
+ 0x65, 0x73, 0x74, 0x12, 0x59, 0x0a, 0x0f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69,
+ 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74,
+ 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x70,
+ 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66,
+ 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0e,
+ 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x4f,
+ 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03,
+ 0x28, 0x09, 0x42, 0x30, 0xfa, 0x42, 0x2d, 0x92, 0x01, 0x2a, 0x08, 0x01, 0x10, 0x14, 0x22, 0x24,
+ 0x72, 0x22, 0x18, 0x24, 0x32, 0x1e, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x28,
+ 0x3f, 0x3a, 0x5b, 0x2d, 0x5d, 0x3f, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x7b,
+ 0x32, 0x2c, 0x7d, 0x24, 0x52, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x73, 0x12,
+ 0x39, 0x0a, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x03, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52,
+ 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05,
+ 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x4a, 0x04, 0x08, 0x06, 0x10, 0x07, 0x52, 0x05, 0x6f, 0x72,
+ 0x64, 0x65, 0x72, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x04, 0x70, 0x61, 0x67, 0x65,
+ 0x2a, 0x55, 0x0a, 0x0a, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x11,
+ 0x0a, 0x0d, 0x50, 0x4f, 0x57, 0x45, 0x52, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10,
+ 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x50, 0x4f, 0x57, 0x45, 0x52, 0x5f, 0x42, 0x41, 0x54, 0x54, 0x45,
+ 0x52, 0x59, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x50, 0x4f, 0x57, 0x45, 0x52, 0x5f, 0x45, 0x58,
+ 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x10, 0x02, 0x1a, 0x0d, 0xea, 0xaa, 0x19, 0x09, 0x18, 0x01,
+ 0x2a, 0x05, 0x50, 0x4f, 0x57, 0x45, 0x52, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x6f, 0x2e, 0x74, 0x68,
+ 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f,
+ 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33,
+ 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74, 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x33,
}
var (
@@ -5607,272 +6288,308 @@ func file_ttn_lorawan_v3_end_device_proto_rawDescGZIP() []byte {
}
var file_ttn_lorawan_v3_end_device_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
-var file_ttn_lorawan_v3_end_device_proto_msgTypes = make([]protoimpl.MessageInfo, 49)
+var file_ttn_lorawan_v3_end_device_proto_msgTypes = make([]protoimpl.MessageInfo, 55)
var file_ttn_lorawan_v3_end_device_proto_goTypes = []interface{}{
(PowerState)(0), // 0: ttn.lorawan.v3.PowerState
(*Session)(nil), // 1: ttn.lorawan.v3.Session
(*BoolValue)(nil), // 2: ttn.lorawan.v3.BoolValue
- (*MACParameters)(nil), // 3: ttn.lorawan.v3.MACParameters
- (*EndDeviceVersion)(nil), // 4: ttn.lorawan.v3.EndDeviceVersion
- (*ADRSettings)(nil), // 5: ttn.lorawan.v3.ADRSettings
- (*MACSettings)(nil), // 6: ttn.lorawan.v3.MACSettings
- (*MACState)(nil), // 7: ttn.lorawan.v3.MACState
- (*EndDeviceAuthenticationCode)(nil), // 8: ttn.lorawan.v3.EndDeviceAuthenticationCode
- (*EndDevice)(nil), // 9: ttn.lorawan.v3.EndDevice
- (*EndDevices)(nil), // 10: ttn.lorawan.v3.EndDevices
- (*DevAddrPrefix)(nil), // 11: ttn.lorawan.v3.DevAddrPrefix
- (*CreateEndDeviceRequest)(nil), // 12: ttn.lorawan.v3.CreateEndDeviceRequest
- (*UpdateEndDeviceRequest)(nil), // 13: ttn.lorawan.v3.UpdateEndDeviceRequest
- (*BatchUpdateEndDeviceLastSeenRequest)(nil), // 14: ttn.lorawan.v3.BatchUpdateEndDeviceLastSeenRequest
- (*GetEndDeviceRequest)(nil), // 15: ttn.lorawan.v3.GetEndDeviceRequest
- (*GetEndDeviceIdentifiersForEUIsRequest)(nil), // 16: ttn.lorawan.v3.GetEndDeviceIdentifiersForEUIsRequest
- (*ListEndDevicesRequest)(nil), // 17: ttn.lorawan.v3.ListEndDevicesRequest
- (*SetEndDeviceRequest)(nil), // 18: ttn.lorawan.v3.SetEndDeviceRequest
- (*ResetAndGetEndDeviceRequest)(nil), // 19: ttn.lorawan.v3.ResetAndGetEndDeviceRequest
- (*EndDeviceTemplate)(nil), // 20: ttn.lorawan.v3.EndDeviceTemplate
- (*EndDeviceTemplateFormat)(nil), // 21: ttn.lorawan.v3.EndDeviceTemplateFormat
- (*EndDeviceTemplateFormats)(nil), // 22: ttn.lorawan.v3.EndDeviceTemplateFormats
- (*ConvertEndDeviceTemplateRequest)(nil), // 23: ttn.lorawan.v3.ConvertEndDeviceTemplateRequest
- (*BatchDeleteEndDevicesRequest)(nil), // 24: ttn.lorawan.v3.BatchDeleteEndDevicesRequest
- (*BatchGetEndDevicesRequest)(nil), // 25: ttn.lorawan.v3.BatchGetEndDevicesRequest
- (*MACParameters_Channel)(nil), // 26: ttn.lorawan.v3.MACParameters.Channel
- (*ADRSettings_StaticMode)(nil), // 27: ttn.lorawan.v3.ADRSettings.StaticMode
- (*ADRSettings_DynamicMode)(nil), // 28: ttn.lorawan.v3.ADRSettings.DynamicMode
- (*ADRSettings_DisabledMode)(nil), // 29: ttn.lorawan.v3.ADRSettings.DisabledMode
- (*ADRSettings_DynamicMode_ChannelSteeringSettings)(nil), // 30: ttn.lorawan.v3.ADRSettings.DynamicMode.ChannelSteeringSettings
- (*ADRSettings_DynamicMode_ChannelSteeringSettings_LoRaNarrowMode)(nil), // 31: ttn.lorawan.v3.ADRSettings.DynamicMode.ChannelSteeringSettings.LoRaNarrowMode
- (*ADRSettings_DynamicMode_ChannelSteeringSettings_DisabledMode)(nil), // 32: ttn.lorawan.v3.ADRSettings.DynamicMode.ChannelSteeringSettings.DisabledMode
- (*MACState_JoinRequest)(nil), // 33: ttn.lorawan.v3.MACState.JoinRequest
- (*MACState_JoinAccept)(nil), // 34: ttn.lorawan.v3.MACState.JoinAccept
- (*MACState_UplinkMessage)(nil), // 35: ttn.lorawan.v3.MACState.UplinkMessage
- (*MACState_DownlinkMessage)(nil), // 36: ttn.lorawan.v3.MACState.DownlinkMessage
- (*MACState_DataRateRange)(nil), // 37: ttn.lorawan.v3.MACState.DataRateRange
- (*MACState_DataRateRanges)(nil), // 38: ttn.lorawan.v3.MACState.DataRateRanges
- nil, // 39: ttn.lorawan.v3.MACState.RejectedDataRateRangesEntry
- (*MACState_UplinkMessage_TxSettings)(nil), // 40: ttn.lorawan.v3.MACState.UplinkMessage.TxSettings
- (*MACState_UplinkMessage_RxMetadata)(nil), // 41: ttn.lorawan.v3.MACState.UplinkMessage.RxMetadata
- (*MACState_UplinkMessage_RxMetadata_PacketBrokerMetadata)(nil), // 42: ttn.lorawan.v3.MACState.UplinkMessage.RxMetadata.PacketBrokerMetadata
- (*MACState_DownlinkMessage_Message)(nil), // 43: ttn.lorawan.v3.MACState.DownlinkMessage.Message
- (*MACState_DownlinkMessage_Message_MHDR)(nil), // 44: ttn.lorawan.v3.MACState.DownlinkMessage.Message.MHDR
- (*MACState_DownlinkMessage_Message_MACPayload)(nil), // 45: ttn.lorawan.v3.MACState.DownlinkMessage.Message.MACPayload
- nil, // 46: ttn.lorawan.v3.EndDevice.AttributesEntry
- nil, // 47: ttn.lorawan.v3.EndDevice.LocationsEntry
- (*BatchUpdateEndDeviceLastSeenRequest_EndDeviceLastSeenUpdate)(nil), // 48: ttn.lorawan.v3.BatchUpdateEndDeviceLastSeenRequest.EndDeviceLastSeenUpdate
- nil, // 49: ttn.lorawan.v3.EndDeviceTemplateFormats.FormatsEntry
- (*SessionKeys)(nil), // 50: ttn.lorawan.v3.SessionKeys
- (*timestamppb.Timestamp)(nil), // 51: google.protobuf.Timestamp
- (*ApplicationDownlink)(nil), // 52: ttn.lorawan.v3.ApplicationDownlink
- (DataRateIndex)(0), // 53: ttn.lorawan.v3.DataRateIndex
- (RxDelay)(0), // 54: ttn.lorawan.v3.RxDelay
- (DataRateOffset)(0), // 55: ttn.lorawan.v3.DataRateOffset
- (AggregatedDutyCycle)(0), // 56: ttn.lorawan.v3.AggregatedDutyCycle
- (RejoinTimeExponent)(0), // 57: ttn.lorawan.v3.RejoinTimeExponent
- (RejoinCountExponent)(0), // 58: ttn.lorawan.v3.RejoinCountExponent
- (*ADRAckLimitExponentValue)(nil), // 59: ttn.lorawan.v3.ADRAckLimitExponentValue
- (*ADRAckDelayExponentValue)(nil), // 60: ttn.lorawan.v3.ADRAckDelayExponentValue
- (*DataRateIndexValue)(nil), // 61: ttn.lorawan.v3.DataRateIndexValue
- (*EndDeviceVersionIdentifiers)(nil), // 62: ttn.lorawan.v3.EndDeviceVersionIdentifiers
- (MACVersion)(0), // 63: ttn.lorawan.v3.MACVersion
- (PHYVersion)(0), // 64: ttn.lorawan.v3.PHYVersion
- (*MessagePayloadFormatters)(nil), // 65: ttn.lorawan.v3.MessagePayloadFormatters
- (*durationpb.Duration)(nil), // 66: google.protobuf.Duration
- (*PingSlotPeriodValue)(nil), // 67: ttn.lorawan.v3.PingSlotPeriodValue
- (*ZeroableFrequencyValue)(nil), // 68: ttn.lorawan.v3.ZeroableFrequencyValue
- (*RxDelayValue)(nil), // 69: ttn.lorawan.v3.RxDelayValue
- (*DataRateOffsetValue)(nil), // 70: ttn.lorawan.v3.DataRateOffsetValue
- (*FrequencyValue)(nil), // 71: ttn.lorawan.v3.FrequencyValue
- (*AggregatedDutyCycleValue)(nil), // 72: ttn.lorawan.v3.AggregatedDutyCycleValue
- (*wrapperspb.FloatValue)(nil), // 73: google.protobuf.FloatValue
- (*wrapperspb.UInt32Value)(nil), // 74: google.protobuf.UInt32Value
- (*DeviceEIRPValue)(nil), // 75: ttn.lorawan.v3.DeviceEIRPValue
- (Class)(0), // 76: ttn.lorawan.v3.Class
- (*MACCommand)(nil), // 77: ttn.lorawan.v3.MACCommand
- (MACCommandIdentifier)(0), // 78: ttn.lorawan.v3.MACCommandIdentifier
- (*EndDeviceIdentifiers)(nil), // 79: ttn.lorawan.v3.EndDeviceIdentifiers
- (*Picture)(nil), // 80: ttn.lorawan.v3.Picture
- (*RootKeys)(nil), // 81: ttn.lorawan.v3.RootKeys
- (*structpb.Struct)(nil), // 82: google.protobuf.Struct
- (*wrapperspb.BoolValue)(nil), // 83: google.protobuf.BoolValue
- (*LoRaAllianceProfileIdentifiers)(nil), // 84: ttn.lorawan.v3.LoRaAllianceProfileIdentifiers
- (*fieldmaskpb.FieldMask)(nil), // 85: google.protobuf.FieldMask
- (*ApplicationIdentifiers)(nil), // 86: ttn.lorawan.v3.ApplicationIdentifiers
- (*DLSettings)(nil), // 87: ttn.lorawan.v3.DLSettings
- (*CFList)(nil), // 88: ttn.lorawan.v3.CFList
- (*Message)(nil), // 89: ttn.lorawan.v3.Message
- (*DataRate)(nil), // 90: ttn.lorawan.v3.DataRate
- (*GatewayIdentifiers)(nil), // 91: ttn.lorawan.v3.GatewayIdentifiers
- (DownlinkPathConstraint)(0), // 92: ttn.lorawan.v3.DownlinkPathConstraint
- (MType)(0), // 93: ttn.lorawan.v3.MType
- (*Location)(nil), // 94: ttn.lorawan.v3.Location
+ (*ServingRelayForwardingLimits)(nil), // 3: ttn.lorawan.v3.ServingRelayForwardingLimits
+ (*RelayUplinkForwardingRule)(nil), // 4: ttn.lorawan.v3.RelayUplinkForwardingRule
+ (*ServingRelayParameters)(nil), // 5: ttn.lorawan.v3.ServingRelayParameters
+ (*ServedRelayParameters)(nil), // 6: ttn.lorawan.v3.ServedRelayParameters
+ (*RelayParameters)(nil), // 7: ttn.lorawan.v3.RelayParameters
+ (*MACParameters)(nil), // 8: ttn.lorawan.v3.MACParameters
+ (*EndDeviceVersion)(nil), // 9: ttn.lorawan.v3.EndDeviceVersion
+ (*ADRSettings)(nil), // 10: ttn.lorawan.v3.ADRSettings
+ (*MACSettings)(nil), // 11: ttn.lorawan.v3.MACSettings
+ (*MACState)(nil), // 12: ttn.lorawan.v3.MACState
+ (*EndDeviceAuthenticationCode)(nil), // 13: ttn.lorawan.v3.EndDeviceAuthenticationCode
+ (*EndDevice)(nil), // 14: ttn.lorawan.v3.EndDevice
+ (*EndDevices)(nil), // 15: ttn.lorawan.v3.EndDevices
+ (*DevAddrPrefix)(nil), // 16: ttn.lorawan.v3.DevAddrPrefix
+ (*CreateEndDeviceRequest)(nil), // 17: ttn.lorawan.v3.CreateEndDeviceRequest
+ (*UpdateEndDeviceRequest)(nil), // 18: ttn.lorawan.v3.UpdateEndDeviceRequest
+ (*BatchUpdateEndDeviceLastSeenRequest)(nil), // 19: ttn.lorawan.v3.BatchUpdateEndDeviceLastSeenRequest
+ (*GetEndDeviceRequest)(nil), // 20: ttn.lorawan.v3.GetEndDeviceRequest
+ (*GetEndDeviceIdentifiersForEUIsRequest)(nil), // 21: ttn.lorawan.v3.GetEndDeviceIdentifiersForEUIsRequest
+ (*ListEndDevicesRequest)(nil), // 22: ttn.lorawan.v3.ListEndDevicesRequest
+ (*SetEndDeviceRequest)(nil), // 23: ttn.lorawan.v3.SetEndDeviceRequest
+ (*ResetAndGetEndDeviceRequest)(nil), // 24: ttn.lorawan.v3.ResetAndGetEndDeviceRequest
+ (*EndDeviceTemplate)(nil), // 25: ttn.lorawan.v3.EndDeviceTemplate
+ (*EndDeviceTemplateFormat)(nil), // 26: ttn.lorawan.v3.EndDeviceTemplateFormat
+ (*EndDeviceTemplateFormats)(nil), // 27: ttn.lorawan.v3.EndDeviceTemplateFormats
+ (*ConvertEndDeviceTemplateRequest)(nil), // 28: ttn.lorawan.v3.ConvertEndDeviceTemplateRequest
+ (*BatchDeleteEndDevicesRequest)(nil), // 29: ttn.lorawan.v3.BatchDeleteEndDevicesRequest
+ (*BatchGetEndDevicesRequest)(nil), // 30: ttn.lorawan.v3.BatchGetEndDevicesRequest
+ (*MACParameters_Channel)(nil), // 31: ttn.lorawan.v3.MACParameters.Channel
+ (*ADRSettings_StaticMode)(nil), // 32: ttn.lorawan.v3.ADRSettings.StaticMode
+ (*ADRSettings_DynamicMode)(nil), // 33: ttn.lorawan.v3.ADRSettings.DynamicMode
+ (*ADRSettings_DisabledMode)(nil), // 34: ttn.lorawan.v3.ADRSettings.DisabledMode
+ (*ADRSettings_DynamicMode_ChannelSteeringSettings)(nil), // 35: ttn.lorawan.v3.ADRSettings.DynamicMode.ChannelSteeringSettings
+ (*ADRSettings_DynamicMode_ChannelSteeringSettings_LoRaNarrowMode)(nil), // 36: ttn.lorawan.v3.ADRSettings.DynamicMode.ChannelSteeringSettings.LoRaNarrowMode
+ (*ADRSettings_DynamicMode_ChannelSteeringSettings_DisabledMode)(nil), // 37: ttn.lorawan.v3.ADRSettings.DynamicMode.ChannelSteeringSettings.DisabledMode
+ (*MACState_JoinRequest)(nil), // 38: ttn.lorawan.v3.MACState.JoinRequest
+ (*MACState_JoinAccept)(nil), // 39: ttn.lorawan.v3.MACState.JoinAccept
+ (*MACState_UplinkMessage)(nil), // 40: ttn.lorawan.v3.MACState.UplinkMessage
+ (*MACState_DownlinkMessage)(nil), // 41: ttn.lorawan.v3.MACState.DownlinkMessage
+ (*MACState_DataRateRange)(nil), // 42: ttn.lorawan.v3.MACState.DataRateRange
+ (*MACState_DataRateRanges)(nil), // 43: ttn.lorawan.v3.MACState.DataRateRanges
+ nil, // 44: ttn.lorawan.v3.MACState.RejectedDataRateRangesEntry
+ (*MACState_UplinkMessage_TxSettings)(nil), // 45: ttn.lorawan.v3.MACState.UplinkMessage.TxSettings
+ (*MACState_UplinkMessage_RxMetadata)(nil), // 46: ttn.lorawan.v3.MACState.UplinkMessage.RxMetadata
+ (*MACState_UplinkMessage_RxMetadata_PacketBrokerMetadata)(nil), // 47: ttn.lorawan.v3.MACState.UplinkMessage.RxMetadata.PacketBrokerMetadata
+ (*MACState_UplinkMessage_RxMetadata_RelayMetadata)(nil), // 48: ttn.lorawan.v3.MACState.UplinkMessage.RxMetadata.RelayMetadata
+ (*MACState_DownlinkMessage_Message)(nil), // 49: ttn.lorawan.v3.MACState.DownlinkMessage.Message
+ (*MACState_DownlinkMessage_Message_MHDR)(nil), // 50: ttn.lorawan.v3.MACState.DownlinkMessage.Message.MHDR
+ (*MACState_DownlinkMessage_Message_MACPayload)(nil), // 51: ttn.lorawan.v3.MACState.DownlinkMessage.Message.MACPayload
+ nil, // 52: ttn.lorawan.v3.EndDevice.AttributesEntry
+ nil, // 53: ttn.lorawan.v3.EndDevice.LocationsEntry
+ (*BatchUpdateEndDeviceLastSeenRequest_EndDeviceLastSeenUpdate)(nil), // 54: ttn.lorawan.v3.BatchUpdateEndDeviceLastSeenRequest.EndDeviceLastSeenUpdate
+ nil, // 55: ttn.lorawan.v3.EndDeviceTemplateFormats.FormatsEntry
+ (*SessionKeys)(nil), // 56: ttn.lorawan.v3.SessionKeys
+ (*timestamppb.Timestamp)(nil), // 57: google.protobuf.Timestamp
+ (*ApplicationDownlink)(nil), // 58: ttn.lorawan.v3.ApplicationDownlink
+ (RelayResetLimitCounter)(0), // 59: ttn.lorawan.v3.RelayResetLimitCounter
+ (*RelayForwardLimits)(nil), // 60: ttn.lorawan.v3.RelayForwardLimits
+ (*RelayUplinkForwardLimits)(nil), // 61: ttn.lorawan.v3.RelayUplinkForwardLimits
+ (*RelaySecondChannel)(nil), // 62: ttn.lorawan.v3.RelaySecondChannel
+ (RelayCADPeriodicity)(0), // 63: ttn.lorawan.v3.RelayCADPeriodicity
+ (*RelayEndDeviceAlwaysMode)(nil), // 64: ttn.lorawan.v3.RelayEndDeviceAlwaysMode
+ (*RelayEndDeviceDynamicMode)(nil), // 65: ttn.lorawan.v3.RelayEndDeviceDynamicMode
+ (*RelayEndDeviceControlledMode)(nil), // 66: ttn.lorawan.v3.RelayEndDeviceControlledMode
+ (DataRateIndex)(0), // 67: ttn.lorawan.v3.DataRateIndex
+ (RxDelay)(0), // 68: ttn.lorawan.v3.RxDelay
+ (DataRateOffset)(0), // 69: ttn.lorawan.v3.DataRateOffset
+ (AggregatedDutyCycle)(0), // 70: ttn.lorawan.v3.AggregatedDutyCycle
+ (RejoinTimeExponent)(0), // 71: ttn.lorawan.v3.RejoinTimeExponent
+ (RejoinCountExponent)(0), // 72: ttn.lorawan.v3.RejoinCountExponent
+ (*ADRAckLimitExponentValue)(nil), // 73: ttn.lorawan.v3.ADRAckLimitExponentValue
+ (*ADRAckDelayExponentValue)(nil), // 74: ttn.lorawan.v3.ADRAckDelayExponentValue
+ (*DataRateIndexValue)(nil), // 75: ttn.lorawan.v3.DataRateIndexValue
+ (*EndDeviceVersionIdentifiers)(nil), // 76: ttn.lorawan.v3.EndDeviceVersionIdentifiers
+ (MACVersion)(0), // 77: ttn.lorawan.v3.MACVersion
+ (PHYVersion)(0), // 78: ttn.lorawan.v3.PHYVersion
+ (*MessagePayloadFormatters)(nil), // 79: ttn.lorawan.v3.MessagePayloadFormatters
+ (*durationpb.Duration)(nil), // 80: google.protobuf.Duration
+ (*PingSlotPeriodValue)(nil), // 81: ttn.lorawan.v3.PingSlotPeriodValue
+ (*ZeroableFrequencyValue)(nil), // 82: ttn.lorawan.v3.ZeroableFrequencyValue
+ (*RxDelayValue)(nil), // 83: ttn.lorawan.v3.RxDelayValue
+ (*DataRateOffsetValue)(nil), // 84: ttn.lorawan.v3.DataRateOffsetValue
+ (*FrequencyValue)(nil), // 85: ttn.lorawan.v3.FrequencyValue
+ (*AggregatedDutyCycleValue)(nil), // 86: ttn.lorawan.v3.AggregatedDutyCycleValue
+ (*wrapperspb.FloatValue)(nil), // 87: google.protobuf.FloatValue
+ (*wrapperspb.UInt32Value)(nil), // 88: google.protobuf.UInt32Value
+ (*DeviceEIRPValue)(nil), // 89: ttn.lorawan.v3.DeviceEIRPValue
+ (Class)(0), // 90: ttn.lorawan.v3.Class
+ (*MACCommand)(nil), // 91: ttn.lorawan.v3.MACCommand
+ (MACCommandIdentifier)(0), // 92: ttn.lorawan.v3.MACCommandIdentifier
+ (*RelayForwardDownlinkReq)(nil), // 93: ttn.lorawan.v3.RelayForwardDownlinkReq
+ (*EndDeviceIdentifiers)(nil), // 94: ttn.lorawan.v3.EndDeviceIdentifiers
+ (*Picture)(nil), // 95: ttn.lorawan.v3.Picture
+ (*RootKeys)(nil), // 96: ttn.lorawan.v3.RootKeys
+ (*structpb.Struct)(nil), // 97: google.protobuf.Struct
+ (*wrapperspb.BoolValue)(nil), // 98: google.protobuf.BoolValue
+ (*LoRaAllianceProfileIdentifiers)(nil), // 99: ttn.lorawan.v3.LoRaAllianceProfileIdentifiers
+ (*fieldmaskpb.FieldMask)(nil), // 100: google.protobuf.FieldMask
+ (*ApplicationIdentifiers)(nil), // 101: ttn.lorawan.v3.ApplicationIdentifiers
+ (*DLSettings)(nil), // 102: ttn.lorawan.v3.DLSettings
+ (*CFList)(nil), // 103: ttn.lorawan.v3.CFList
+ (*Message)(nil), // 104: ttn.lorawan.v3.Message
+ (*DataRate)(nil), // 105: ttn.lorawan.v3.DataRate
+ (*GatewayIdentifiers)(nil), // 106: ttn.lorawan.v3.GatewayIdentifiers
+ (DownlinkPathConstraint)(0), // 107: ttn.lorawan.v3.DownlinkPathConstraint
+ (MType)(0), // 108: ttn.lorawan.v3.MType
+ (*Location)(nil), // 109: ttn.lorawan.v3.Location
}
var file_ttn_lorawan_v3_end_device_proto_depIdxs = []int32{
- 50, // 0: ttn.lorawan.v3.Session.keys:type_name -> ttn.lorawan.v3.SessionKeys
- 51, // 1: ttn.lorawan.v3.Session.started_at:type_name -> google.protobuf.Timestamp
- 52, // 2: ttn.lorawan.v3.Session.queued_application_downlinks:type_name -> ttn.lorawan.v3.ApplicationDownlink
- 53, // 3: ttn.lorawan.v3.MACParameters.adr_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
- 54, // 4: ttn.lorawan.v3.MACParameters.rx1_delay:type_name -> ttn.lorawan.v3.RxDelay
- 55, // 5: ttn.lorawan.v3.MACParameters.rx1_data_rate_offset:type_name -> ttn.lorawan.v3.DataRateOffset
- 53, // 6: ttn.lorawan.v3.MACParameters.rx2_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
- 56, // 7: ttn.lorawan.v3.MACParameters.max_duty_cycle:type_name -> ttn.lorawan.v3.AggregatedDutyCycle
- 57, // 8: ttn.lorawan.v3.MACParameters.rejoin_time_periodicity:type_name -> ttn.lorawan.v3.RejoinTimeExponent
- 58, // 9: ttn.lorawan.v3.MACParameters.rejoin_count_periodicity:type_name -> ttn.lorawan.v3.RejoinCountExponent
- 53, // 10: ttn.lorawan.v3.MACParameters.ping_slot_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
- 26, // 11: ttn.lorawan.v3.MACParameters.channels:type_name -> ttn.lorawan.v3.MACParameters.Channel
- 2, // 12: ttn.lorawan.v3.MACParameters.uplink_dwell_time:type_name -> ttn.lorawan.v3.BoolValue
- 2, // 13: ttn.lorawan.v3.MACParameters.downlink_dwell_time:type_name -> ttn.lorawan.v3.BoolValue
- 59, // 14: ttn.lorawan.v3.MACParameters.adr_ack_limit_exponent:type_name -> ttn.lorawan.v3.ADRAckLimitExponentValue
- 60, // 15: ttn.lorawan.v3.MACParameters.adr_ack_delay_exponent:type_name -> ttn.lorawan.v3.ADRAckDelayExponentValue
- 61, // 16: ttn.lorawan.v3.MACParameters.ping_slot_data_rate_index_value:type_name -> ttn.lorawan.v3.DataRateIndexValue
- 62, // 17: ttn.lorawan.v3.EndDeviceVersion.ids:type_name -> ttn.lorawan.v3.EndDeviceVersionIdentifiers
- 63, // 18: ttn.lorawan.v3.EndDeviceVersion.lorawan_version:type_name -> ttn.lorawan.v3.MACVersion
- 64, // 19: ttn.lorawan.v3.EndDeviceVersion.lorawan_phy_version:type_name -> ttn.lorawan.v3.PHYVersion
- 6, // 20: ttn.lorawan.v3.EndDeviceVersion.default_mac_settings:type_name -> ttn.lorawan.v3.MACSettings
- 65, // 21: ttn.lorawan.v3.EndDeviceVersion.default_formatters:type_name -> ttn.lorawan.v3.MessagePayloadFormatters
- 27, // 22: ttn.lorawan.v3.ADRSettings.static:type_name -> ttn.lorawan.v3.ADRSettings.StaticMode
- 28, // 23: ttn.lorawan.v3.ADRSettings.dynamic:type_name -> ttn.lorawan.v3.ADRSettings.DynamicMode
- 29, // 24: ttn.lorawan.v3.ADRSettings.disabled:type_name -> ttn.lorawan.v3.ADRSettings.DisabledMode
- 66, // 25: ttn.lorawan.v3.MACSettings.class_b_timeout:type_name -> google.protobuf.Duration
- 67, // 26: ttn.lorawan.v3.MACSettings.ping_slot_periodicity:type_name -> ttn.lorawan.v3.PingSlotPeriodValue
- 61, // 27: ttn.lorawan.v3.MACSettings.ping_slot_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndexValue
- 68, // 28: ttn.lorawan.v3.MACSettings.ping_slot_frequency:type_name -> ttn.lorawan.v3.ZeroableFrequencyValue
- 68, // 29: ttn.lorawan.v3.MACSettings.beacon_frequency:type_name -> ttn.lorawan.v3.ZeroableFrequencyValue
- 66, // 30: ttn.lorawan.v3.MACSettings.class_c_timeout:type_name -> google.protobuf.Duration
- 69, // 31: ttn.lorawan.v3.MACSettings.rx1_delay:type_name -> ttn.lorawan.v3.RxDelayValue
- 70, // 32: ttn.lorawan.v3.MACSettings.rx1_data_rate_offset:type_name -> ttn.lorawan.v3.DataRateOffsetValue
- 61, // 33: ttn.lorawan.v3.MACSettings.rx2_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndexValue
- 71, // 34: ttn.lorawan.v3.MACSettings.rx2_frequency:type_name -> ttn.lorawan.v3.FrequencyValue
- 72, // 35: ttn.lorawan.v3.MACSettings.max_duty_cycle:type_name -> ttn.lorawan.v3.AggregatedDutyCycleValue
- 2, // 36: ttn.lorawan.v3.MACSettings.supports_32_bit_f_cnt:type_name -> ttn.lorawan.v3.BoolValue
- 2, // 37: ttn.lorawan.v3.MACSettings.use_adr:type_name -> ttn.lorawan.v3.BoolValue
- 73, // 38: ttn.lorawan.v3.MACSettings.adr_margin:type_name -> google.protobuf.FloatValue
- 2, // 39: ttn.lorawan.v3.MACSettings.resets_f_cnt:type_name -> ttn.lorawan.v3.BoolValue
- 66, // 40: ttn.lorawan.v3.MACSettings.status_time_periodicity:type_name -> google.protobuf.Duration
- 74, // 41: ttn.lorawan.v3.MACSettings.status_count_periodicity:type_name -> google.protobuf.UInt32Value
- 69, // 42: ttn.lorawan.v3.MACSettings.desired_rx1_delay:type_name -> ttn.lorawan.v3.RxDelayValue
- 70, // 43: ttn.lorawan.v3.MACSettings.desired_rx1_data_rate_offset:type_name -> ttn.lorawan.v3.DataRateOffsetValue
- 61, // 44: ttn.lorawan.v3.MACSettings.desired_rx2_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndexValue
- 71, // 45: ttn.lorawan.v3.MACSettings.desired_rx2_frequency:type_name -> ttn.lorawan.v3.FrequencyValue
- 72, // 46: ttn.lorawan.v3.MACSettings.desired_max_duty_cycle:type_name -> ttn.lorawan.v3.AggregatedDutyCycleValue
- 59, // 47: ttn.lorawan.v3.MACSettings.desired_adr_ack_limit_exponent:type_name -> ttn.lorawan.v3.ADRAckLimitExponentValue
- 60, // 48: ttn.lorawan.v3.MACSettings.desired_adr_ack_delay_exponent:type_name -> ttn.lorawan.v3.ADRAckDelayExponentValue
- 61, // 49: ttn.lorawan.v3.MACSettings.desired_ping_slot_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndexValue
- 68, // 50: ttn.lorawan.v3.MACSettings.desired_ping_slot_frequency:type_name -> ttn.lorawan.v3.ZeroableFrequencyValue
- 68, // 51: ttn.lorawan.v3.MACSettings.desired_beacon_frequency:type_name -> ttn.lorawan.v3.ZeroableFrequencyValue
- 75, // 52: ttn.lorawan.v3.MACSettings.desired_max_eirp:type_name -> ttn.lorawan.v3.DeviceEIRPValue
- 66, // 53: ttn.lorawan.v3.MACSettings.class_b_c_downlink_interval:type_name -> google.protobuf.Duration
- 2, // 54: ttn.lorawan.v3.MACSettings.uplink_dwell_time:type_name -> ttn.lorawan.v3.BoolValue
- 2, // 55: ttn.lorawan.v3.MACSettings.downlink_dwell_time:type_name -> ttn.lorawan.v3.BoolValue
- 5, // 56: ttn.lorawan.v3.MACSettings.adr:type_name -> ttn.lorawan.v3.ADRSettings
- 2, // 57: ttn.lorawan.v3.MACSettings.schedule_downlinks:type_name -> ttn.lorawan.v3.BoolValue
- 3, // 58: ttn.lorawan.v3.MACState.current_parameters:type_name -> ttn.lorawan.v3.MACParameters
- 3, // 59: ttn.lorawan.v3.MACState.desired_parameters:type_name -> ttn.lorawan.v3.MACParameters
- 76, // 60: ttn.lorawan.v3.MACState.device_class:type_name -> ttn.lorawan.v3.Class
- 63, // 61: ttn.lorawan.v3.MACState.lorawan_version:type_name -> ttn.lorawan.v3.MACVersion
- 51, // 62: ttn.lorawan.v3.MACState.last_confirmed_downlink_at:type_name -> google.protobuf.Timestamp
- 67, // 63: ttn.lorawan.v3.MACState.ping_slot_periodicity:type_name -> ttn.lorawan.v3.PingSlotPeriodValue
- 52, // 64: ttn.lorawan.v3.MACState.pending_application_downlink:type_name -> ttn.lorawan.v3.ApplicationDownlink
- 77, // 65: ttn.lorawan.v3.MACState.queued_responses:type_name -> ttn.lorawan.v3.MACCommand
- 77, // 66: ttn.lorawan.v3.MACState.pending_requests:type_name -> ttn.lorawan.v3.MACCommand
- 34, // 67: ttn.lorawan.v3.MACState.queued_join_accept:type_name -> ttn.lorawan.v3.MACState.JoinAccept
- 33, // 68: ttn.lorawan.v3.MACState.pending_join_request:type_name -> ttn.lorawan.v3.MACState.JoinRequest
- 35, // 69: ttn.lorawan.v3.MACState.recent_uplinks:type_name -> ttn.lorawan.v3.MACState.UplinkMessage
- 36, // 70: ttn.lorawan.v3.MACState.recent_downlinks:type_name -> ttn.lorawan.v3.MACState.DownlinkMessage
- 51, // 71: ttn.lorawan.v3.MACState.last_network_initiated_downlink_at:type_name -> google.protobuf.Timestamp
- 53, // 72: ttn.lorawan.v3.MACState.rejected_adr_data_rate_indexes:type_name -> ttn.lorawan.v3.DataRateIndex
- 51, // 73: ttn.lorawan.v3.MACState.last_downlink_at:type_name -> google.protobuf.Timestamp
- 39, // 74: ttn.lorawan.v3.MACState.rejected_data_rate_ranges:type_name -> ttn.lorawan.v3.MACState.RejectedDataRateRangesEntry
- 78, // 75: ttn.lorawan.v3.MACState.recent_mac_command_identifiers:type_name -> ttn.lorawan.v3.MACCommandIdentifier
- 51, // 76: ttn.lorawan.v3.EndDeviceAuthenticationCode.valid_from:type_name -> google.protobuf.Timestamp
- 51, // 77: ttn.lorawan.v3.EndDeviceAuthenticationCode.valid_to:type_name -> google.protobuf.Timestamp
- 79, // 78: ttn.lorawan.v3.EndDevice.ids:type_name -> ttn.lorawan.v3.EndDeviceIdentifiers
- 51, // 79: ttn.lorawan.v3.EndDevice.created_at:type_name -> google.protobuf.Timestamp
- 51, // 80: ttn.lorawan.v3.EndDevice.updated_at:type_name -> google.protobuf.Timestamp
- 46, // 81: ttn.lorawan.v3.EndDevice.attributes:type_name -> ttn.lorawan.v3.EndDevice.AttributesEntry
- 62, // 82: ttn.lorawan.v3.EndDevice.version_ids:type_name -> ttn.lorawan.v3.EndDeviceVersionIdentifiers
- 47, // 83: ttn.lorawan.v3.EndDevice.locations:type_name -> ttn.lorawan.v3.EndDevice.LocationsEntry
- 80, // 84: ttn.lorawan.v3.EndDevice.picture:type_name -> ttn.lorawan.v3.Picture
- 63, // 85: ttn.lorawan.v3.EndDevice.lorawan_version:type_name -> ttn.lorawan.v3.MACVersion
- 64, // 86: ttn.lorawan.v3.EndDevice.lorawan_phy_version:type_name -> ttn.lorawan.v3.PHYVersion
- 81, // 87: ttn.lorawan.v3.EndDevice.root_keys:type_name -> ttn.lorawan.v3.RootKeys
- 6, // 88: ttn.lorawan.v3.EndDevice.mac_settings:type_name -> ttn.lorawan.v3.MACSettings
- 7, // 89: ttn.lorawan.v3.EndDevice.mac_state:type_name -> ttn.lorawan.v3.MACState
- 7, // 90: ttn.lorawan.v3.EndDevice.pending_mac_state:type_name -> ttn.lorawan.v3.MACState
- 1, // 91: ttn.lorawan.v3.EndDevice.session:type_name -> ttn.lorawan.v3.Session
- 1, // 92: ttn.lorawan.v3.EndDevice.pending_session:type_name -> ttn.lorawan.v3.Session
- 51, // 93: ttn.lorawan.v3.EndDevice.last_dev_status_received_at:type_name -> google.protobuf.Timestamp
- 0, // 94: ttn.lorawan.v3.EndDevice.power_state:type_name -> ttn.lorawan.v3.PowerState
- 73, // 95: ttn.lorawan.v3.EndDevice.battery_percentage:type_name -> google.protobuf.FloatValue
- 52, // 96: ttn.lorawan.v3.EndDevice.queued_application_downlinks:type_name -> ttn.lorawan.v3.ApplicationDownlink
- 65, // 97: ttn.lorawan.v3.EndDevice.formatters:type_name -> ttn.lorawan.v3.MessagePayloadFormatters
- 82, // 98: ttn.lorawan.v3.EndDevice.provisioning_data:type_name -> google.protobuf.Struct
- 8, // 99: ttn.lorawan.v3.EndDevice.claim_authentication_code:type_name -> ttn.lorawan.v3.EndDeviceAuthenticationCode
- 83, // 100: ttn.lorawan.v3.EndDevice.skip_payload_crypto_override:type_name -> google.protobuf.BoolValue
- 51, // 101: ttn.lorawan.v3.EndDevice.activated_at:type_name -> google.protobuf.Timestamp
- 51, // 102: ttn.lorawan.v3.EndDevice.last_seen_at:type_name -> google.protobuf.Timestamp
- 84, // 103: ttn.lorawan.v3.EndDevice.lora_alliance_profile_ids:type_name -> ttn.lorawan.v3.LoRaAllianceProfileIdentifiers
- 9, // 104: ttn.lorawan.v3.EndDevices.end_devices:type_name -> ttn.lorawan.v3.EndDevice
- 9, // 105: ttn.lorawan.v3.CreateEndDeviceRequest.end_device:type_name -> ttn.lorawan.v3.EndDevice
- 9, // 106: ttn.lorawan.v3.UpdateEndDeviceRequest.end_device:type_name -> ttn.lorawan.v3.EndDevice
- 85, // 107: ttn.lorawan.v3.UpdateEndDeviceRequest.field_mask:type_name -> google.protobuf.FieldMask
- 48, // 108: ttn.lorawan.v3.BatchUpdateEndDeviceLastSeenRequest.updates:type_name -> ttn.lorawan.v3.BatchUpdateEndDeviceLastSeenRequest.EndDeviceLastSeenUpdate
- 79, // 109: ttn.lorawan.v3.GetEndDeviceRequest.end_device_ids:type_name -> ttn.lorawan.v3.EndDeviceIdentifiers
- 85, // 110: ttn.lorawan.v3.GetEndDeviceRequest.field_mask:type_name -> google.protobuf.FieldMask
- 86, // 111: ttn.lorawan.v3.ListEndDevicesRequest.application_ids:type_name -> ttn.lorawan.v3.ApplicationIdentifiers
- 85, // 112: ttn.lorawan.v3.ListEndDevicesRequest.field_mask:type_name -> google.protobuf.FieldMask
- 9, // 113: ttn.lorawan.v3.SetEndDeviceRequest.end_device:type_name -> ttn.lorawan.v3.EndDevice
- 85, // 114: ttn.lorawan.v3.SetEndDeviceRequest.field_mask:type_name -> google.protobuf.FieldMask
- 79, // 115: ttn.lorawan.v3.ResetAndGetEndDeviceRequest.end_device_ids:type_name -> ttn.lorawan.v3.EndDeviceIdentifiers
- 85, // 116: ttn.lorawan.v3.ResetAndGetEndDeviceRequest.field_mask:type_name -> google.protobuf.FieldMask
- 9, // 117: ttn.lorawan.v3.EndDeviceTemplate.end_device:type_name -> ttn.lorawan.v3.EndDevice
- 85, // 118: ttn.lorawan.v3.EndDeviceTemplate.field_mask:type_name -> google.protobuf.FieldMask
- 49, // 119: ttn.lorawan.v3.EndDeviceTemplateFormats.formats:type_name -> ttn.lorawan.v3.EndDeviceTemplateFormats.FormatsEntry
- 62, // 120: ttn.lorawan.v3.ConvertEndDeviceTemplateRequest.end_device_version_ids:type_name -> ttn.lorawan.v3.EndDeviceVersionIdentifiers
- 86, // 121: ttn.lorawan.v3.BatchDeleteEndDevicesRequest.application_ids:type_name -> ttn.lorawan.v3.ApplicationIdentifiers
- 86, // 122: ttn.lorawan.v3.BatchGetEndDevicesRequest.application_ids:type_name -> ttn.lorawan.v3.ApplicationIdentifiers
- 85, // 123: ttn.lorawan.v3.BatchGetEndDevicesRequest.field_mask:type_name -> google.protobuf.FieldMask
- 53, // 124: ttn.lorawan.v3.MACParameters.Channel.min_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
- 53, // 125: ttn.lorawan.v3.MACParameters.Channel.max_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
- 53, // 126: ttn.lorawan.v3.ADRSettings.StaticMode.data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
- 73, // 127: ttn.lorawan.v3.ADRSettings.DynamicMode.margin:type_name -> google.protobuf.FloatValue
- 61, // 128: ttn.lorawan.v3.ADRSettings.DynamicMode.min_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndexValue
- 61, // 129: ttn.lorawan.v3.ADRSettings.DynamicMode.max_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndexValue
- 74, // 130: ttn.lorawan.v3.ADRSettings.DynamicMode.min_tx_power_index:type_name -> google.protobuf.UInt32Value
- 74, // 131: ttn.lorawan.v3.ADRSettings.DynamicMode.max_tx_power_index:type_name -> google.protobuf.UInt32Value
- 74, // 132: ttn.lorawan.v3.ADRSettings.DynamicMode.min_nb_trans:type_name -> google.protobuf.UInt32Value
- 74, // 133: ttn.lorawan.v3.ADRSettings.DynamicMode.max_nb_trans:type_name -> google.protobuf.UInt32Value
- 30, // 134: ttn.lorawan.v3.ADRSettings.DynamicMode.channel_steering:type_name -> ttn.lorawan.v3.ADRSettings.DynamicMode.ChannelSteeringSettings
- 31, // 135: ttn.lorawan.v3.ADRSettings.DynamicMode.ChannelSteeringSettings.lora_narrow:type_name -> ttn.lorawan.v3.ADRSettings.DynamicMode.ChannelSteeringSettings.LoRaNarrowMode
- 32, // 136: ttn.lorawan.v3.ADRSettings.DynamicMode.ChannelSteeringSettings.disabled:type_name -> ttn.lorawan.v3.ADRSettings.DynamicMode.ChannelSteeringSettings.DisabledMode
- 87, // 137: ttn.lorawan.v3.MACState.JoinRequest.downlink_settings:type_name -> ttn.lorawan.v3.DLSettings
- 54, // 138: ttn.lorawan.v3.MACState.JoinRequest.rx_delay:type_name -> ttn.lorawan.v3.RxDelay
- 88, // 139: ttn.lorawan.v3.MACState.JoinRequest.cf_list:type_name -> ttn.lorawan.v3.CFList
- 33, // 140: ttn.lorawan.v3.MACState.JoinAccept.request:type_name -> ttn.lorawan.v3.MACState.JoinRequest
- 50, // 141: ttn.lorawan.v3.MACState.JoinAccept.keys:type_name -> ttn.lorawan.v3.SessionKeys
- 89, // 142: ttn.lorawan.v3.MACState.UplinkMessage.payload:type_name -> ttn.lorawan.v3.Message
- 40, // 143: ttn.lorawan.v3.MACState.UplinkMessage.settings:type_name -> ttn.lorawan.v3.MACState.UplinkMessage.TxSettings
- 41, // 144: ttn.lorawan.v3.MACState.UplinkMessage.rx_metadata:type_name -> ttn.lorawan.v3.MACState.UplinkMessage.RxMetadata
- 51, // 145: ttn.lorawan.v3.MACState.UplinkMessage.received_at:type_name -> google.protobuf.Timestamp
- 43, // 146: ttn.lorawan.v3.MACState.DownlinkMessage.payload:type_name -> ttn.lorawan.v3.MACState.DownlinkMessage.Message
- 53, // 147: ttn.lorawan.v3.MACState.DataRateRange.min_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
- 53, // 148: ttn.lorawan.v3.MACState.DataRateRange.max_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
- 37, // 149: ttn.lorawan.v3.MACState.DataRateRanges.ranges:type_name -> ttn.lorawan.v3.MACState.DataRateRange
- 38, // 150: ttn.lorawan.v3.MACState.RejectedDataRateRangesEntry.value:type_name -> ttn.lorawan.v3.MACState.DataRateRanges
- 90, // 151: ttn.lorawan.v3.MACState.UplinkMessage.TxSettings.data_rate:type_name -> ttn.lorawan.v3.DataRate
- 91, // 152: ttn.lorawan.v3.MACState.UplinkMessage.RxMetadata.gateway_ids:type_name -> ttn.lorawan.v3.GatewayIdentifiers
- 92, // 153: ttn.lorawan.v3.MACState.UplinkMessage.RxMetadata.downlink_path_constraint:type_name -> ttn.lorawan.v3.DownlinkPathConstraint
- 42, // 154: ttn.lorawan.v3.MACState.UplinkMessage.RxMetadata.packet_broker:type_name -> ttn.lorawan.v3.MACState.UplinkMessage.RxMetadata.PacketBrokerMetadata
- 44, // 155: ttn.lorawan.v3.MACState.DownlinkMessage.Message.m_hdr:type_name -> ttn.lorawan.v3.MACState.DownlinkMessage.Message.MHDR
- 45, // 156: ttn.lorawan.v3.MACState.DownlinkMessage.Message.mac_payload:type_name -> ttn.lorawan.v3.MACState.DownlinkMessage.Message.MACPayload
- 93, // 157: ttn.lorawan.v3.MACState.DownlinkMessage.Message.MHDR.m_type:type_name -> ttn.lorawan.v3.MType
- 94, // 158: ttn.lorawan.v3.EndDevice.LocationsEntry.value:type_name -> ttn.lorawan.v3.Location
- 79, // 159: ttn.lorawan.v3.BatchUpdateEndDeviceLastSeenRequest.EndDeviceLastSeenUpdate.ids:type_name -> ttn.lorawan.v3.EndDeviceIdentifiers
- 51, // 160: ttn.lorawan.v3.BatchUpdateEndDeviceLastSeenRequest.EndDeviceLastSeenUpdate.last_seen_at:type_name -> google.protobuf.Timestamp
- 21, // 161: ttn.lorawan.v3.EndDeviceTemplateFormats.FormatsEntry.value:type_name -> ttn.lorawan.v3.EndDeviceTemplateFormat
- 162, // [162:162] is the sub-list for method output_type
- 162, // [162:162] is the sub-list for method input_type
- 162, // [162:162] is the sub-list for extension type_name
- 162, // [162:162] is the sub-list for extension extendee
- 0, // [0:162] is the sub-list for field type_name
+ 56, // 0: ttn.lorawan.v3.Session.keys:type_name -> ttn.lorawan.v3.SessionKeys
+ 57, // 1: ttn.lorawan.v3.Session.started_at:type_name -> google.protobuf.Timestamp
+ 58, // 2: ttn.lorawan.v3.Session.queued_application_downlinks:type_name -> ttn.lorawan.v3.ApplicationDownlink
+ 59, // 3: ttn.lorawan.v3.ServingRelayForwardingLimits.reset_behavior:type_name -> ttn.lorawan.v3.RelayResetLimitCounter
+ 60, // 4: ttn.lorawan.v3.ServingRelayForwardingLimits.join_requests:type_name -> ttn.lorawan.v3.RelayForwardLimits
+ 60, // 5: ttn.lorawan.v3.ServingRelayForwardingLimits.notifications:type_name -> ttn.lorawan.v3.RelayForwardLimits
+ 60, // 6: ttn.lorawan.v3.ServingRelayForwardingLimits.uplink_messages:type_name -> ttn.lorawan.v3.RelayForwardLimits
+ 60, // 7: ttn.lorawan.v3.ServingRelayForwardingLimits.overall:type_name -> ttn.lorawan.v3.RelayForwardLimits
+ 61, // 8: ttn.lorawan.v3.RelayUplinkForwardingRule.limits:type_name -> ttn.lorawan.v3.RelayUplinkForwardLimits
+ 62, // 9: ttn.lorawan.v3.ServingRelayParameters.second_channel:type_name -> ttn.lorawan.v3.RelaySecondChannel
+ 63, // 10: ttn.lorawan.v3.ServingRelayParameters.cad_periodicity:type_name -> ttn.lorawan.v3.RelayCADPeriodicity
+ 4, // 11: ttn.lorawan.v3.ServingRelayParameters.uplink_forwarding_rules:type_name -> ttn.lorawan.v3.RelayUplinkForwardingRule
+ 3, // 12: ttn.lorawan.v3.ServingRelayParameters.limits:type_name -> ttn.lorawan.v3.ServingRelayForwardingLimits
+ 64, // 13: ttn.lorawan.v3.ServedRelayParameters.always:type_name -> ttn.lorawan.v3.RelayEndDeviceAlwaysMode
+ 65, // 14: ttn.lorawan.v3.ServedRelayParameters.dynamic:type_name -> ttn.lorawan.v3.RelayEndDeviceDynamicMode
+ 66, // 15: ttn.lorawan.v3.ServedRelayParameters.end_device_controlled:type_name -> ttn.lorawan.v3.RelayEndDeviceControlledMode
+ 62, // 16: ttn.lorawan.v3.ServedRelayParameters.second_channel:type_name -> ttn.lorawan.v3.RelaySecondChannel
+ 5, // 17: ttn.lorawan.v3.RelayParameters.serving:type_name -> ttn.lorawan.v3.ServingRelayParameters
+ 6, // 18: ttn.lorawan.v3.RelayParameters.served:type_name -> ttn.lorawan.v3.ServedRelayParameters
+ 67, // 19: ttn.lorawan.v3.MACParameters.adr_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
+ 68, // 20: ttn.lorawan.v3.MACParameters.rx1_delay:type_name -> ttn.lorawan.v3.RxDelay
+ 69, // 21: ttn.lorawan.v3.MACParameters.rx1_data_rate_offset:type_name -> ttn.lorawan.v3.DataRateOffset
+ 67, // 22: ttn.lorawan.v3.MACParameters.rx2_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
+ 70, // 23: ttn.lorawan.v3.MACParameters.max_duty_cycle:type_name -> ttn.lorawan.v3.AggregatedDutyCycle
+ 71, // 24: ttn.lorawan.v3.MACParameters.rejoin_time_periodicity:type_name -> ttn.lorawan.v3.RejoinTimeExponent
+ 72, // 25: ttn.lorawan.v3.MACParameters.rejoin_count_periodicity:type_name -> ttn.lorawan.v3.RejoinCountExponent
+ 67, // 26: ttn.lorawan.v3.MACParameters.ping_slot_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
+ 31, // 27: ttn.lorawan.v3.MACParameters.channels:type_name -> ttn.lorawan.v3.MACParameters.Channel
+ 2, // 28: ttn.lorawan.v3.MACParameters.uplink_dwell_time:type_name -> ttn.lorawan.v3.BoolValue
+ 2, // 29: ttn.lorawan.v3.MACParameters.downlink_dwell_time:type_name -> ttn.lorawan.v3.BoolValue
+ 73, // 30: ttn.lorawan.v3.MACParameters.adr_ack_limit_exponent:type_name -> ttn.lorawan.v3.ADRAckLimitExponentValue
+ 74, // 31: ttn.lorawan.v3.MACParameters.adr_ack_delay_exponent:type_name -> ttn.lorawan.v3.ADRAckDelayExponentValue
+ 75, // 32: ttn.lorawan.v3.MACParameters.ping_slot_data_rate_index_value:type_name -> ttn.lorawan.v3.DataRateIndexValue
+ 7, // 33: ttn.lorawan.v3.MACParameters.relay:type_name -> ttn.lorawan.v3.RelayParameters
+ 76, // 34: ttn.lorawan.v3.EndDeviceVersion.ids:type_name -> ttn.lorawan.v3.EndDeviceVersionIdentifiers
+ 77, // 35: ttn.lorawan.v3.EndDeviceVersion.lorawan_version:type_name -> ttn.lorawan.v3.MACVersion
+ 78, // 36: ttn.lorawan.v3.EndDeviceVersion.lorawan_phy_version:type_name -> ttn.lorawan.v3.PHYVersion
+ 11, // 37: ttn.lorawan.v3.EndDeviceVersion.default_mac_settings:type_name -> ttn.lorawan.v3.MACSettings
+ 79, // 38: ttn.lorawan.v3.EndDeviceVersion.default_formatters:type_name -> ttn.lorawan.v3.MessagePayloadFormatters
+ 32, // 39: ttn.lorawan.v3.ADRSettings.static:type_name -> ttn.lorawan.v3.ADRSettings.StaticMode
+ 33, // 40: ttn.lorawan.v3.ADRSettings.dynamic:type_name -> ttn.lorawan.v3.ADRSettings.DynamicMode
+ 34, // 41: ttn.lorawan.v3.ADRSettings.disabled:type_name -> ttn.lorawan.v3.ADRSettings.DisabledMode
+ 80, // 42: ttn.lorawan.v3.MACSettings.class_b_timeout:type_name -> google.protobuf.Duration
+ 81, // 43: ttn.lorawan.v3.MACSettings.ping_slot_periodicity:type_name -> ttn.lorawan.v3.PingSlotPeriodValue
+ 75, // 44: ttn.lorawan.v3.MACSettings.ping_slot_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndexValue
+ 82, // 45: ttn.lorawan.v3.MACSettings.ping_slot_frequency:type_name -> ttn.lorawan.v3.ZeroableFrequencyValue
+ 82, // 46: ttn.lorawan.v3.MACSettings.beacon_frequency:type_name -> ttn.lorawan.v3.ZeroableFrequencyValue
+ 80, // 47: ttn.lorawan.v3.MACSettings.class_c_timeout:type_name -> google.protobuf.Duration
+ 83, // 48: ttn.lorawan.v3.MACSettings.rx1_delay:type_name -> ttn.lorawan.v3.RxDelayValue
+ 84, // 49: ttn.lorawan.v3.MACSettings.rx1_data_rate_offset:type_name -> ttn.lorawan.v3.DataRateOffsetValue
+ 75, // 50: ttn.lorawan.v3.MACSettings.rx2_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndexValue
+ 85, // 51: ttn.lorawan.v3.MACSettings.rx2_frequency:type_name -> ttn.lorawan.v3.FrequencyValue
+ 86, // 52: ttn.lorawan.v3.MACSettings.max_duty_cycle:type_name -> ttn.lorawan.v3.AggregatedDutyCycleValue
+ 2, // 53: ttn.lorawan.v3.MACSettings.supports_32_bit_f_cnt:type_name -> ttn.lorawan.v3.BoolValue
+ 2, // 54: ttn.lorawan.v3.MACSettings.use_adr:type_name -> ttn.lorawan.v3.BoolValue
+ 87, // 55: ttn.lorawan.v3.MACSettings.adr_margin:type_name -> google.protobuf.FloatValue
+ 2, // 56: ttn.lorawan.v3.MACSettings.resets_f_cnt:type_name -> ttn.lorawan.v3.BoolValue
+ 80, // 57: ttn.lorawan.v3.MACSettings.status_time_periodicity:type_name -> google.protobuf.Duration
+ 88, // 58: ttn.lorawan.v3.MACSettings.status_count_periodicity:type_name -> google.protobuf.UInt32Value
+ 83, // 59: ttn.lorawan.v3.MACSettings.desired_rx1_delay:type_name -> ttn.lorawan.v3.RxDelayValue
+ 84, // 60: ttn.lorawan.v3.MACSettings.desired_rx1_data_rate_offset:type_name -> ttn.lorawan.v3.DataRateOffsetValue
+ 75, // 61: ttn.lorawan.v3.MACSettings.desired_rx2_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndexValue
+ 85, // 62: ttn.lorawan.v3.MACSettings.desired_rx2_frequency:type_name -> ttn.lorawan.v3.FrequencyValue
+ 86, // 63: ttn.lorawan.v3.MACSettings.desired_max_duty_cycle:type_name -> ttn.lorawan.v3.AggregatedDutyCycleValue
+ 73, // 64: ttn.lorawan.v3.MACSettings.desired_adr_ack_limit_exponent:type_name -> ttn.lorawan.v3.ADRAckLimitExponentValue
+ 74, // 65: ttn.lorawan.v3.MACSettings.desired_adr_ack_delay_exponent:type_name -> ttn.lorawan.v3.ADRAckDelayExponentValue
+ 75, // 66: ttn.lorawan.v3.MACSettings.desired_ping_slot_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndexValue
+ 82, // 67: ttn.lorawan.v3.MACSettings.desired_ping_slot_frequency:type_name -> ttn.lorawan.v3.ZeroableFrequencyValue
+ 82, // 68: ttn.lorawan.v3.MACSettings.desired_beacon_frequency:type_name -> ttn.lorawan.v3.ZeroableFrequencyValue
+ 89, // 69: ttn.lorawan.v3.MACSettings.desired_max_eirp:type_name -> ttn.lorawan.v3.DeviceEIRPValue
+ 80, // 70: ttn.lorawan.v3.MACSettings.class_b_c_downlink_interval:type_name -> google.protobuf.Duration
+ 2, // 71: ttn.lorawan.v3.MACSettings.uplink_dwell_time:type_name -> ttn.lorawan.v3.BoolValue
+ 2, // 72: ttn.lorawan.v3.MACSettings.downlink_dwell_time:type_name -> ttn.lorawan.v3.BoolValue
+ 10, // 73: ttn.lorawan.v3.MACSettings.adr:type_name -> ttn.lorawan.v3.ADRSettings
+ 2, // 74: ttn.lorawan.v3.MACSettings.schedule_downlinks:type_name -> ttn.lorawan.v3.BoolValue
+ 7, // 75: ttn.lorawan.v3.MACSettings.relay:type_name -> ttn.lorawan.v3.RelayParameters
+ 7, // 76: ttn.lorawan.v3.MACSettings.desired_relay:type_name -> ttn.lorawan.v3.RelayParameters
+ 8, // 77: ttn.lorawan.v3.MACState.current_parameters:type_name -> ttn.lorawan.v3.MACParameters
+ 8, // 78: ttn.lorawan.v3.MACState.desired_parameters:type_name -> ttn.lorawan.v3.MACParameters
+ 90, // 79: ttn.lorawan.v3.MACState.device_class:type_name -> ttn.lorawan.v3.Class
+ 77, // 80: ttn.lorawan.v3.MACState.lorawan_version:type_name -> ttn.lorawan.v3.MACVersion
+ 57, // 81: ttn.lorawan.v3.MACState.last_confirmed_downlink_at:type_name -> google.protobuf.Timestamp
+ 81, // 82: ttn.lorawan.v3.MACState.ping_slot_periodicity:type_name -> ttn.lorawan.v3.PingSlotPeriodValue
+ 58, // 83: ttn.lorawan.v3.MACState.pending_application_downlink:type_name -> ttn.lorawan.v3.ApplicationDownlink
+ 91, // 84: ttn.lorawan.v3.MACState.queued_responses:type_name -> ttn.lorawan.v3.MACCommand
+ 91, // 85: ttn.lorawan.v3.MACState.pending_requests:type_name -> ttn.lorawan.v3.MACCommand
+ 39, // 86: ttn.lorawan.v3.MACState.queued_join_accept:type_name -> ttn.lorawan.v3.MACState.JoinAccept
+ 38, // 87: ttn.lorawan.v3.MACState.pending_join_request:type_name -> ttn.lorawan.v3.MACState.JoinRequest
+ 40, // 88: ttn.lorawan.v3.MACState.recent_uplinks:type_name -> ttn.lorawan.v3.MACState.UplinkMessage
+ 41, // 89: ttn.lorawan.v3.MACState.recent_downlinks:type_name -> ttn.lorawan.v3.MACState.DownlinkMessage
+ 57, // 90: ttn.lorawan.v3.MACState.last_network_initiated_downlink_at:type_name -> google.protobuf.Timestamp
+ 67, // 91: ttn.lorawan.v3.MACState.rejected_adr_data_rate_indexes:type_name -> ttn.lorawan.v3.DataRateIndex
+ 57, // 92: ttn.lorawan.v3.MACState.last_downlink_at:type_name -> google.protobuf.Timestamp
+ 44, // 93: ttn.lorawan.v3.MACState.rejected_data_rate_ranges:type_name -> ttn.lorawan.v3.MACState.RejectedDataRateRangesEntry
+ 92, // 94: ttn.lorawan.v3.MACState.recent_mac_command_identifiers:type_name -> ttn.lorawan.v3.MACCommandIdentifier
+ 93, // 95: ttn.lorawan.v3.MACState.pending_relay_downlink:type_name -> ttn.lorawan.v3.RelayForwardDownlinkReq
+ 57, // 96: ttn.lorawan.v3.EndDeviceAuthenticationCode.valid_from:type_name -> google.protobuf.Timestamp
+ 57, // 97: ttn.lorawan.v3.EndDeviceAuthenticationCode.valid_to:type_name -> google.protobuf.Timestamp
+ 94, // 98: ttn.lorawan.v3.EndDevice.ids:type_name -> ttn.lorawan.v3.EndDeviceIdentifiers
+ 57, // 99: ttn.lorawan.v3.EndDevice.created_at:type_name -> google.protobuf.Timestamp
+ 57, // 100: ttn.lorawan.v3.EndDevice.updated_at:type_name -> google.protobuf.Timestamp
+ 52, // 101: ttn.lorawan.v3.EndDevice.attributes:type_name -> ttn.lorawan.v3.EndDevice.AttributesEntry
+ 76, // 102: ttn.lorawan.v3.EndDevice.version_ids:type_name -> ttn.lorawan.v3.EndDeviceVersionIdentifiers
+ 53, // 103: ttn.lorawan.v3.EndDevice.locations:type_name -> ttn.lorawan.v3.EndDevice.LocationsEntry
+ 95, // 104: ttn.lorawan.v3.EndDevice.picture:type_name -> ttn.lorawan.v3.Picture
+ 77, // 105: ttn.lorawan.v3.EndDevice.lorawan_version:type_name -> ttn.lorawan.v3.MACVersion
+ 78, // 106: ttn.lorawan.v3.EndDevice.lorawan_phy_version:type_name -> ttn.lorawan.v3.PHYVersion
+ 96, // 107: ttn.lorawan.v3.EndDevice.root_keys:type_name -> ttn.lorawan.v3.RootKeys
+ 11, // 108: ttn.lorawan.v3.EndDevice.mac_settings:type_name -> ttn.lorawan.v3.MACSettings
+ 12, // 109: ttn.lorawan.v3.EndDevice.mac_state:type_name -> ttn.lorawan.v3.MACState
+ 12, // 110: ttn.lorawan.v3.EndDevice.pending_mac_state:type_name -> ttn.lorawan.v3.MACState
+ 1, // 111: ttn.lorawan.v3.EndDevice.session:type_name -> ttn.lorawan.v3.Session
+ 1, // 112: ttn.lorawan.v3.EndDevice.pending_session:type_name -> ttn.lorawan.v3.Session
+ 57, // 113: ttn.lorawan.v3.EndDevice.last_dev_status_received_at:type_name -> google.protobuf.Timestamp
+ 0, // 114: ttn.lorawan.v3.EndDevice.power_state:type_name -> ttn.lorawan.v3.PowerState
+ 87, // 115: ttn.lorawan.v3.EndDevice.battery_percentage:type_name -> google.protobuf.FloatValue
+ 58, // 116: ttn.lorawan.v3.EndDevice.queued_application_downlinks:type_name -> ttn.lorawan.v3.ApplicationDownlink
+ 79, // 117: ttn.lorawan.v3.EndDevice.formatters:type_name -> ttn.lorawan.v3.MessagePayloadFormatters
+ 97, // 118: ttn.lorawan.v3.EndDevice.provisioning_data:type_name -> google.protobuf.Struct
+ 13, // 119: ttn.lorawan.v3.EndDevice.claim_authentication_code:type_name -> ttn.lorawan.v3.EndDeviceAuthenticationCode
+ 98, // 120: ttn.lorawan.v3.EndDevice.skip_payload_crypto_override:type_name -> google.protobuf.BoolValue
+ 57, // 121: ttn.lorawan.v3.EndDevice.activated_at:type_name -> google.protobuf.Timestamp
+ 57, // 122: ttn.lorawan.v3.EndDevice.last_seen_at:type_name -> google.protobuf.Timestamp
+ 99, // 123: ttn.lorawan.v3.EndDevice.lora_alliance_profile_ids:type_name -> ttn.lorawan.v3.LoRaAllianceProfileIdentifiers
+ 14, // 124: ttn.lorawan.v3.EndDevices.end_devices:type_name -> ttn.lorawan.v3.EndDevice
+ 14, // 125: ttn.lorawan.v3.CreateEndDeviceRequest.end_device:type_name -> ttn.lorawan.v3.EndDevice
+ 14, // 126: ttn.lorawan.v3.UpdateEndDeviceRequest.end_device:type_name -> ttn.lorawan.v3.EndDevice
+ 100, // 127: ttn.lorawan.v3.UpdateEndDeviceRequest.field_mask:type_name -> google.protobuf.FieldMask
+ 54, // 128: ttn.lorawan.v3.BatchUpdateEndDeviceLastSeenRequest.updates:type_name -> ttn.lorawan.v3.BatchUpdateEndDeviceLastSeenRequest.EndDeviceLastSeenUpdate
+ 94, // 129: ttn.lorawan.v3.GetEndDeviceRequest.end_device_ids:type_name -> ttn.lorawan.v3.EndDeviceIdentifiers
+ 100, // 130: ttn.lorawan.v3.GetEndDeviceRequest.field_mask:type_name -> google.protobuf.FieldMask
+ 101, // 131: ttn.lorawan.v3.ListEndDevicesRequest.application_ids:type_name -> ttn.lorawan.v3.ApplicationIdentifiers
+ 100, // 132: ttn.lorawan.v3.ListEndDevicesRequest.field_mask:type_name -> google.protobuf.FieldMask
+ 14, // 133: ttn.lorawan.v3.SetEndDeviceRequest.end_device:type_name -> ttn.lorawan.v3.EndDevice
+ 100, // 134: ttn.lorawan.v3.SetEndDeviceRequest.field_mask:type_name -> google.protobuf.FieldMask
+ 94, // 135: ttn.lorawan.v3.ResetAndGetEndDeviceRequest.end_device_ids:type_name -> ttn.lorawan.v3.EndDeviceIdentifiers
+ 100, // 136: ttn.lorawan.v3.ResetAndGetEndDeviceRequest.field_mask:type_name -> google.protobuf.FieldMask
+ 14, // 137: ttn.lorawan.v3.EndDeviceTemplate.end_device:type_name -> ttn.lorawan.v3.EndDevice
+ 100, // 138: ttn.lorawan.v3.EndDeviceTemplate.field_mask:type_name -> google.protobuf.FieldMask
+ 55, // 139: ttn.lorawan.v3.EndDeviceTemplateFormats.formats:type_name -> ttn.lorawan.v3.EndDeviceTemplateFormats.FormatsEntry
+ 76, // 140: ttn.lorawan.v3.ConvertEndDeviceTemplateRequest.end_device_version_ids:type_name -> ttn.lorawan.v3.EndDeviceVersionIdentifiers
+ 101, // 141: ttn.lorawan.v3.BatchDeleteEndDevicesRequest.application_ids:type_name -> ttn.lorawan.v3.ApplicationIdentifiers
+ 101, // 142: ttn.lorawan.v3.BatchGetEndDevicesRequest.application_ids:type_name -> ttn.lorawan.v3.ApplicationIdentifiers
+ 100, // 143: ttn.lorawan.v3.BatchGetEndDevicesRequest.field_mask:type_name -> google.protobuf.FieldMask
+ 67, // 144: ttn.lorawan.v3.MACParameters.Channel.min_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
+ 67, // 145: ttn.lorawan.v3.MACParameters.Channel.max_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
+ 67, // 146: ttn.lorawan.v3.ADRSettings.StaticMode.data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
+ 87, // 147: ttn.lorawan.v3.ADRSettings.DynamicMode.margin:type_name -> google.protobuf.FloatValue
+ 75, // 148: ttn.lorawan.v3.ADRSettings.DynamicMode.min_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndexValue
+ 75, // 149: ttn.lorawan.v3.ADRSettings.DynamicMode.max_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndexValue
+ 88, // 150: ttn.lorawan.v3.ADRSettings.DynamicMode.min_tx_power_index:type_name -> google.protobuf.UInt32Value
+ 88, // 151: ttn.lorawan.v3.ADRSettings.DynamicMode.max_tx_power_index:type_name -> google.protobuf.UInt32Value
+ 88, // 152: ttn.lorawan.v3.ADRSettings.DynamicMode.min_nb_trans:type_name -> google.protobuf.UInt32Value
+ 88, // 153: ttn.lorawan.v3.ADRSettings.DynamicMode.max_nb_trans:type_name -> google.protobuf.UInt32Value
+ 35, // 154: ttn.lorawan.v3.ADRSettings.DynamicMode.channel_steering:type_name -> ttn.lorawan.v3.ADRSettings.DynamicMode.ChannelSteeringSettings
+ 36, // 155: ttn.lorawan.v3.ADRSettings.DynamicMode.ChannelSteeringSettings.lora_narrow:type_name -> ttn.lorawan.v3.ADRSettings.DynamicMode.ChannelSteeringSettings.LoRaNarrowMode
+ 37, // 156: ttn.lorawan.v3.ADRSettings.DynamicMode.ChannelSteeringSettings.disabled:type_name -> ttn.lorawan.v3.ADRSettings.DynamicMode.ChannelSteeringSettings.DisabledMode
+ 102, // 157: ttn.lorawan.v3.MACState.JoinRequest.downlink_settings:type_name -> ttn.lorawan.v3.DLSettings
+ 68, // 158: ttn.lorawan.v3.MACState.JoinRequest.rx_delay:type_name -> ttn.lorawan.v3.RxDelay
+ 103, // 159: ttn.lorawan.v3.MACState.JoinRequest.cf_list:type_name -> ttn.lorawan.v3.CFList
+ 38, // 160: ttn.lorawan.v3.MACState.JoinAccept.request:type_name -> ttn.lorawan.v3.MACState.JoinRequest
+ 56, // 161: ttn.lorawan.v3.MACState.JoinAccept.keys:type_name -> ttn.lorawan.v3.SessionKeys
+ 104, // 162: ttn.lorawan.v3.MACState.UplinkMessage.payload:type_name -> ttn.lorawan.v3.Message
+ 45, // 163: ttn.lorawan.v3.MACState.UplinkMessage.settings:type_name -> ttn.lorawan.v3.MACState.UplinkMessage.TxSettings
+ 46, // 164: ttn.lorawan.v3.MACState.UplinkMessage.rx_metadata:type_name -> ttn.lorawan.v3.MACState.UplinkMessage.RxMetadata
+ 57, // 165: ttn.lorawan.v3.MACState.UplinkMessage.received_at:type_name -> google.protobuf.Timestamp
+ 49, // 166: ttn.lorawan.v3.MACState.DownlinkMessage.payload:type_name -> ttn.lorawan.v3.MACState.DownlinkMessage.Message
+ 67, // 167: ttn.lorawan.v3.MACState.DataRateRange.min_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
+ 67, // 168: ttn.lorawan.v3.MACState.DataRateRange.max_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
+ 42, // 169: ttn.lorawan.v3.MACState.DataRateRanges.ranges:type_name -> ttn.lorawan.v3.MACState.DataRateRange
+ 43, // 170: ttn.lorawan.v3.MACState.RejectedDataRateRangesEntry.value:type_name -> ttn.lorawan.v3.MACState.DataRateRanges
+ 105, // 171: ttn.lorawan.v3.MACState.UplinkMessage.TxSettings.data_rate:type_name -> ttn.lorawan.v3.DataRate
+ 106, // 172: ttn.lorawan.v3.MACState.UplinkMessage.RxMetadata.gateway_ids:type_name -> ttn.lorawan.v3.GatewayIdentifiers
+ 107, // 173: ttn.lorawan.v3.MACState.UplinkMessage.RxMetadata.downlink_path_constraint:type_name -> ttn.lorawan.v3.DownlinkPathConstraint
+ 47, // 174: ttn.lorawan.v3.MACState.UplinkMessage.RxMetadata.packet_broker:type_name -> ttn.lorawan.v3.MACState.UplinkMessage.RxMetadata.PacketBrokerMetadata
+ 48, // 175: ttn.lorawan.v3.MACState.UplinkMessage.RxMetadata.relay:type_name -> ttn.lorawan.v3.MACState.UplinkMessage.RxMetadata.RelayMetadata
+ 50, // 176: ttn.lorawan.v3.MACState.DownlinkMessage.Message.m_hdr:type_name -> ttn.lorawan.v3.MACState.DownlinkMessage.Message.MHDR
+ 51, // 177: ttn.lorawan.v3.MACState.DownlinkMessage.Message.mac_payload:type_name -> ttn.lorawan.v3.MACState.DownlinkMessage.Message.MACPayload
+ 108, // 178: ttn.lorawan.v3.MACState.DownlinkMessage.Message.MHDR.m_type:type_name -> ttn.lorawan.v3.MType
+ 109, // 179: ttn.lorawan.v3.EndDevice.LocationsEntry.value:type_name -> ttn.lorawan.v3.Location
+ 94, // 180: ttn.lorawan.v3.BatchUpdateEndDeviceLastSeenRequest.EndDeviceLastSeenUpdate.ids:type_name -> ttn.lorawan.v3.EndDeviceIdentifiers
+ 57, // 181: ttn.lorawan.v3.BatchUpdateEndDeviceLastSeenRequest.EndDeviceLastSeenUpdate.last_seen_at:type_name -> google.protobuf.Timestamp
+ 26, // 182: ttn.lorawan.v3.EndDeviceTemplateFormats.FormatsEntry.value:type_name -> ttn.lorawan.v3.EndDeviceTemplateFormat
+ 183, // [183:183] is the sub-list for method output_type
+ 183, // [183:183] is the sub-list for method input_type
+ 183, // [183:183] is the sub-list for extension type_name
+ 183, // [183:183] is the sub-list for extension extendee
+ 0, // [0:183] is the sub-list for field type_name
}
func init() { file_ttn_lorawan_v3_end_device_proto_init() }
@@ -5913,7 +6630,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACParameters); i {
+ switch v := v.(*ServingRelayForwardingLimits); i {
case 0:
return &v.state
case 1:
@@ -5925,7 +6642,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*EndDeviceVersion); i {
+ switch v := v.(*RelayUplinkForwardingRule); i {
case 0:
return &v.state
case 1:
@@ -5937,7 +6654,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*ADRSettings); i {
+ switch v := v.(*ServingRelayParameters); i {
case 0:
return &v.state
case 1:
@@ -5949,7 +6666,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACSettings); i {
+ switch v := v.(*ServedRelayParameters); i {
case 0:
return &v.state
case 1:
@@ -5961,7 +6678,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACState); i {
+ switch v := v.(*RelayParameters); i {
case 0:
return &v.state
case 1:
@@ -5973,7 +6690,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*EndDeviceAuthenticationCode); i {
+ switch v := v.(*MACParameters); i {
case 0:
return &v.state
case 1:
@@ -5985,7 +6702,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*EndDevice); i {
+ switch v := v.(*EndDeviceVersion); i {
case 0:
return &v.state
case 1:
@@ -5997,7 +6714,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*EndDevices); i {
+ switch v := v.(*ADRSettings); i {
case 0:
return &v.state
case 1:
@@ -6009,7 +6726,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*DevAddrPrefix); i {
+ switch v := v.(*MACSettings); i {
case 0:
return &v.state
case 1:
@@ -6021,7 +6738,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*CreateEndDeviceRequest); i {
+ switch v := v.(*MACState); i {
case 0:
return &v.state
case 1:
@@ -6033,7 +6750,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*UpdateEndDeviceRequest); i {
+ switch v := v.(*EndDeviceAuthenticationCode); i {
case 0:
return &v.state
case 1:
@@ -6045,7 +6762,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*BatchUpdateEndDeviceLastSeenRequest); i {
+ switch v := v.(*EndDevice); i {
case 0:
return &v.state
case 1:
@@ -6057,7 +6774,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*GetEndDeviceRequest); i {
+ switch v := v.(*EndDevices); i {
case 0:
return &v.state
case 1:
@@ -6069,7 +6786,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*GetEndDeviceIdentifiersForEUIsRequest); i {
+ switch v := v.(*DevAddrPrefix); i {
case 0:
return &v.state
case 1:
@@ -6081,7 +6798,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*ListEndDevicesRequest); i {
+ switch v := v.(*CreateEndDeviceRequest); i {
case 0:
return &v.state
case 1:
@@ -6093,7 +6810,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*SetEndDeviceRequest); i {
+ switch v := v.(*UpdateEndDeviceRequest); i {
case 0:
return &v.state
case 1:
@@ -6105,7 +6822,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*ResetAndGetEndDeviceRequest); i {
+ switch v := v.(*BatchUpdateEndDeviceLastSeenRequest); i {
case 0:
return &v.state
case 1:
@@ -6117,7 +6834,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*EndDeviceTemplate); i {
+ switch v := v.(*GetEndDeviceRequest); i {
case 0:
return &v.state
case 1:
@@ -6129,7 +6846,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*EndDeviceTemplateFormat); i {
+ switch v := v.(*GetEndDeviceIdentifiersForEUIsRequest); i {
case 0:
return &v.state
case 1:
@@ -6141,7 +6858,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*EndDeviceTemplateFormats); i {
+ switch v := v.(*ListEndDevicesRequest); i {
case 0:
return &v.state
case 1:
@@ -6153,7 +6870,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*ConvertEndDeviceTemplateRequest); i {
+ switch v := v.(*SetEndDeviceRequest); i {
case 0:
return &v.state
case 1:
@@ -6165,7 +6882,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*BatchDeleteEndDevicesRequest); i {
+ switch v := v.(*ResetAndGetEndDeviceRequest); i {
case 0:
return &v.state
case 1:
@@ -6177,7 +6894,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*BatchGetEndDevicesRequest); i {
+ switch v := v.(*EndDeviceTemplate); i {
case 0:
return &v.state
case 1:
@@ -6189,7 +6906,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACParameters_Channel); i {
+ switch v := v.(*EndDeviceTemplateFormat); i {
case 0:
return &v.state
case 1:
@@ -6201,7 +6918,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*ADRSettings_StaticMode); i {
+ switch v := v.(*EndDeviceTemplateFormats); i {
case 0:
return &v.state
case 1:
@@ -6213,7 +6930,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*ADRSettings_DynamicMode); i {
+ switch v := v.(*ConvertEndDeviceTemplateRequest); i {
case 0:
return &v.state
case 1:
@@ -6225,7 +6942,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*ADRSettings_DisabledMode); i {
+ switch v := v.(*BatchDeleteEndDevicesRequest); i {
case 0:
return &v.state
case 1:
@@ -6237,7 +6954,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*ADRSettings_DynamicMode_ChannelSteeringSettings); i {
+ switch v := v.(*BatchGetEndDevicesRequest); i {
case 0:
return &v.state
case 1:
@@ -6249,7 +6966,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*ADRSettings_DynamicMode_ChannelSteeringSettings_LoRaNarrowMode); i {
+ switch v := v.(*MACParameters_Channel); i {
case 0:
return &v.state
case 1:
@@ -6261,7 +6978,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*ADRSettings_DynamicMode_ChannelSteeringSettings_DisabledMode); i {
+ switch v := v.(*ADRSettings_StaticMode); i {
case 0:
return &v.state
case 1:
@@ -6273,7 +6990,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACState_JoinRequest); i {
+ switch v := v.(*ADRSettings_DynamicMode); i {
case 0:
return &v.state
case 1:
@@ -6285,7 +7002,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACState_JoinAccept); i {
+ switch v := v.(*ADRSettings_DisabledMode); i {
case 0:
return &v.state
case 1:
@@ -6297,7 +7014,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACState_UplinkMessage); i {
+ switch v := v.(*ADRSettings_DynamicMode_ChannelSteeringSettings); i {
case 0:
return &v.state
case 1:
@@ -6309,7 +7026,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACState_DownlinkMessage); i {
+ switch v := v.(*ADRSettings_DynamicMode_ChannelSteeringSettings_LoRaNarrowMode); i {
case 0:
return &v.state
case 1:
@@ -6321,7 +7038,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACState_DataRateRange); i {
+ switch v := v.(*ADRSettings_DynamicMode_ChannelSteeringSettings_DisabledMode); i {
case 0:
return &v.state
case 1:
@@ -6333,7 +7050,19 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACState_DataRateRanges); i {
+ switch v := v.(*MACState_JoinRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_ttn_lorawan_v3_end_device_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACState_JoinAccept); i {
case 0:
return &v.state
case 1:
@@ -6345,7 +7074,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACState_UplinkMessage_TxSettings); i {
+ switch v := v.(*MACState_UplinkMessage); i {
case 0:
return &v.state
case 1:
@@ -6357,7 +7086,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACState_UplinkMessage_RxMetadata); i {
+ switch v := v.(*MACState_DownlinkMessage); i {
case 0:
return &v.state
case 1:
@@ -6369,7 +7098,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACState_UplinkMessage_RxMetadata_PacketBrokerMetadata); i {
+ switch v := v.(*MACState_DataRateRange); i {
case 0:
return &v.state
case 1:
@@ -6381,6 +7110,66 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
file_ttn_lorawan_v3_end_device_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACState_DataRateRanges); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_ttn_lorawan_v3_end_device_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACState_UplinkMessage_TxSettings); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_ttn_lorawan_v3_end_device_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACState_UplinkMessage_RxMetadata); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_ttn_lorawan_v3_end_device_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACState_UplinkMessage_RxMetadata_PacketBrokerMetadata); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_ttn_lorawan_v3_end_device_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACState_UplinkMessage_RxMetadata_RelayMetadata); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_ttn_lorawan_v3_end_device_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*MACState_DownlinkMessage_Message); i {
case 0:
return &v.state
@@ -6392,7 +7181,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_end_device_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} {
+ file_ttn_lorawan_v3_end_device_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*MACState_DownlinkMessage_Message_MHDR); i {
case 0:
return &v.state
@@ -6404,7 +7193,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_end_device_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} {
+ file_ttn_lorawan_v3_end_device_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*MACState_DownlinkMessage_Message_MACPayload); i {
case 0:
return &v.state
@@ -6416,7 +7205,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_end_device_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} {
+ file_ttn_lorawan_v3_end_device_proto_msgTypes[53].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BatchUpdateEndDeviceLastSeenRequest_EndDeviceLastSeenUpdate); i {
case 0:
return &v.state
@@ -6429,12 +7218,21 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
}
}
}
- file_ttn_lorawan_v3_end_device_proto_msgTypes[4].OneofWrappers = []interface{}{
+ file_ttn_lorawan_v3_end_device_proto_msgTypes[5].OneofWrappers = []interface{}{
+ (*ServedRelayParameters_Always)(nil),
+ (*ServedRelayParameters_Dynamic)(nil),
+ (*ServedRelayParameters_EndDeviceControlled)(nil),
+ }
+ file_ttn_lorawan_v3_end_device_proto_msgTypes[6].OneofWrappers = []interface{}{
+ (*RelayParameters_Serving)(nil),
+ (*RelayParameters_Served)(nil),
+ }
+ file_ttn_lorawan_v3_end_device_proto_msgTypes[9].OneofWrappers = []interface{}{
(*ADRSettings_Static)(nil),
(*ADRSettings_Dynamic)(nil),
(*ADRSettings_Disabled)(nil),
}
- file_ttn_lorawan_v3_end_device_proto_msgTypes[29].OneofWrappers = []interface{}{
+ file_ttn_lorawan_v3_end_device_proto_msgTypes[34].OneofWrappers = []interface{}{
(*ADRSettings_DynamicMode_ChannelSteeringSettings_LoraNarrow)(nil),
(*ADRSettings_DynamicMode_ChannelSteeringSettings_Disabled)(nil),
}
@@ -6444,7 +7242,7 @@ func file_ttn_lorawan_v3_end_device_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_ttn_lorawan_v3_end_device_proto_rawDesc,
NumEnums: 1,
- NumMessages: 49,
+ NumMessages: 55,
NumExtensions: 0,
NumServices: 0,
},
diff --git a/pkg/ttnpb/end_device.pb.paths.fm.go b/pkg/ttnpb/end_device.pb.paths.fm.go
index 8a4bf5852b..d93d2affac 100644
--- a/pkg/ttnpb/end_device.pb.paths.fm.go
+++ b/pkg/ttnpb/end_device.pb.paths.fm.go
@@ -47,6 +47,136 @@ var BoolValueFieldPathsNested = []string{
var BoolValueFieldPathsTopLevel = []string{
"value",
}
+var ServingRelayForwardingLimitsFieldPathsNested = []string{
+ "join_requests",
+ "join_requests.bucket_size",
+ "join_requests.reload_rate",
+ "notifications",
+ "notifications.bucket_size",
+ "notifications.reload_rate",
+ "overall",
+ "overall.bucket_size",
+ "overall.reload_rate",
+ "reset_behavior",
+ "uplink_messages",
+ "uplink_messages.bucket_size",
+ "uplink_messages.reload_rate",
+}
+
+var ServingRelayForwardingLimitsFieldPathsTopLevel = []string{
+ "join_requests",
+ "notifications",
+ "overall",
+ "reset_behavior",
+ "uplink_messages",
+}
+var RelayUplinkForwardingRuleFieldPathsNested = []string{
+ "device_id",
+ "last_w_f_cnt",
+ "limits",
+ "limits.bucket_size",
+ "limits.reload_rate",
+ "session_key_id",
+}
+
+var RelayUplinkForwardingRuleFieldPathsTopLevel = []string{
+ "device_id",
+ "last_w_f_cnt",
+ "limits",
+ "session_key_id",
+}
+var ServingRelayParametersFieldPathsNested = []string{
+ "cad_periodicity",
+ "default_channel_index",
+ "limits",
+ "limits.join_requests",
+ "limits.join_requests.bucket_size",
+ "limits.join_requests.reload_rate",
+ "limits.notifications",
+ "limits.notifications.bucket_size",
+ "limits.notifications.reload_rate",
+ "limits.overall",
+ "limits.overall.bucket_size",
+ "limits.overall.reload_rate",
+ "limits.reset_behavior",
+ "limits.uplink_messages",
+ "limits.uplink_messages.bucket_size",
+ "limits.uplink_messages.reload_rate",
+ "second_channel",
+ "second_channel.ack_offset",
+ "second_channel.data_rate_index",
+ "second_channel.frequency",
+ "uplink_forwarding_rules",
+}
+
+var ServingRelayParametersFieldPathsTopLevel = []string{
+ "cad_periodicity",
+ "default_channel_index",
+ "limits",
+ "second_channel",
+ "uplink_forwarding_rules",
+}
+var ServedRelayParametersFieldPathsNested = []string{
+ "backoff",
+ "mode",
+ "mode.always",
+ "mode.dynamic",
+ "mode.dynamic.smart_enable_level",
+ "mode.end_device_controlled",
+ "second_channel",
+ "second_channel.ack_offset",
+ "second_channel.data_rate_index",
+ "second_channel.frequency",
+ "serving_device_id",
+}
+
+var ServedRelayParametersFieldPathsTopLevel = []string{
+ "backoff",
+ "mode",
+ "second_channel",
+ "serving_device_id",
+}
+var RelayParametersFieldPathsNested = []string{
+ "mode",
+ "mode.served",
+ "mode.served.backoff",
+ "mode.served.mode",
+ "mode.served.mode.always",
+ "mode.served.mode.dynamic",
+ "mode.served.mode.dynamic.smart_enable_level",
+ "mode.served.mode.end_device_controlled",
+ "mode.served.second_channel",
+ "mode.served.second_channel.ack_offset",
+ "mode.served.second_channel.data_rate_index",
+ "mode.served.second_channel.frequency",
+ "mode.served.serving_device_id",
+ "mode.serving",
+ "mode.serving.cad_periodicity",
+ "mode.serving.default_channel_index",
+ "mode.serving.limits",
+ "mode.serving.limits.join_requests",
+ "mode.serving.limits.join_requests.bucket_size",
+ "mode.serving.limits.join_requests.reload_rate",
+ "mode.serving.limits.notifications",
+ "mode.serving.limits.notifications.bucket_size",
+ "mode.serving.limits.notifications.reload_rate",
+ "mode.serving.limits.overall",
+ "mode.serving.limits.overall.bucket_size",
+ "mode.serving.limits.overall.reload_rate",
+ "mode.serving.limits.reset_behavior",
+ "mode.serving.limits.uplink_messages",
+ "mode.serving.limits.uplink_messages.bucket_size",
+ "mode.serving.limits.uplink_messages.reload_rate",
+ "mode.serving.second_channel",
+ "mode.serving.second_channel.ack_offset",
+ "mode.serving.second_channel.data_rate_index",
+ "mode.serving.second_channel.frequency",
+ "mode.serving.uplink_forwarding_rules",
+}
+
+var RelayParametersFieldPathsTopLevel = []string{
+ "mode",
+}
var MACParametersFieldPathsNested = []string{
"adr_ack_delay",
"adr_ack_delay_exponent",
@@ -69,6 +199,42 @@ var MACParametersFieldPathsNested = []string{
"ping_slot_frequency",
"rejoin_count_periodicity",
"rejoin_time_periodicity",
+ "relay",
+ "relay.mode",
+ "relay.mode.served",
+ "relay.mode.served.backoff",
+ "relay.mode.served.mode",
+ "relay.mode.served.mode.always",
+ "relay.mode.served.mode.dynamic",
+ "relay.mode.served.mode.dynamic.smart_enable_level",
+ "relay.mode.served.mode.end_device_controlled",
+ "relay.mode.served.second_channel",
+ "relay.mode.served.second_channel.ack_offset",
+ "relay.mode.served.second_channel.data_rate_index",
+ "relay.mode.served.second_channel.frequency",
+ "relay.mode.served.serving_device_id",
+ "relay.mode.serving",
+ "relay.mode.serving.cad_periodicity",
+ "relay.mode.serving.default_channel_index",
+ "relay.mode.serving.limits",
+ "relay.mode.serving.limits.join_requests",
+ "relay.mode.serving.limits.join_requests.bucket_size",
+ "relay.mode.serving.limits.join_requests.reload_rate",
+ "relay.mode.serving.limits.notifications",
+ "relay.mode.serving.limits.notifications.bucket_size",
+ "relay.mode.serving.limits.notifications.reload_rate",
+ "relay.mode.serving.limits.overall",
+ "relay.mode.serving.limits.overall.bucket_size",
+ "relay.mode.serving.limits.overall.reload_rate",
+ "relay.mode.serving.limits.reset_behavior",
+ "relay.mode.serving.limits.uplink_messages",
+ "relay.mode.serving.limits.uplink_messages.bucket_size",
+ "relay.mode.serving.limits.uplink_messages.reload_rate",
+ "relay.mode.serving.second_channel",
+ "relay.mode.serving.second_channel.ack_offset",
+ "relay.mode.serving.second_channel.data_rate_index",
+ "relay.mode.serving.second_channel.frequency",
+ "relay.mode.serving.uplink_forwarding_rules",
"rx1_data_rate_offset",
"rx1_delay",
"rx2_data_rate_index",
@@ -95,6 +261,7 @@ var MACParametersFieldPathsTopLevel = []string{
"ping_slot_frequency",
"rejoin_count_periodicity",
"rejoin_time_periodicity",
+ "relay",
"rx1_data_rate_offset",
"rx1_delay",
"rx2_data_rate_index",
@@ -149,6 +316,42 @@ var EndDeviceVersionFieldPathsNested = []string{
"default_mac_settings.desired_ping_slot_data_rate_index.value",
"default_mac_settings.desired_ping_slot_frequency",
"default_mac_settings.desired_ping_slot_frequency.value",
+ "default_mac_settings.desired_relay",
+ "default_mac_settings.desired_relay.mode",
+ "default_mac_settings.desired_relay.mode.served",
+ "default_mac_settings.desired_relay.mode.served.backoff",
+ "default_mac_settings.desired_relay.mode.served.mode",
+ "default_mac_settings.desired_relay.mode.served.mode.always",
+ "default_mac_settings.desired_relay.mode.served.mode.dynamic",
+ "default_mac_settings.desired_relay.mode.served.mode.dynamic.smart_enable_level",
+ "default_mac_settings.desired_relay.mode.served.mode.end_device_controlled",
+ "default_mac_settings.desired_relay.mode.served.second_channel",
+ "default_mac_settings.desired_relay.mode.served.second_channel.ack_offset",
+ "default_mac_settings.desired_relay.mode.served.second_channel.data_rate_index",
+ "default_mac_settings.desired_relay.mode.served.second_channel.frequency",
+ "default_mac_settings.desired_relay.mode.served.serving_device_id",
+ "default_mac_settings.desired_relay.mode.serving",
+ "default_mac_settings.desired_relay.mode.serving.cad_periodicity",
+ "default_mac_settings.desired_relay.mode.serving.default_channel_index",
+ "default_mac_settings.desired_relay.mode.serving.limits",
+ "default_mac_settings.desired_relay.mode.serving.limits.join_requests",
+ "default_mac_settings.desired_relay.mode.serving.limits.join_requests.bucket_size",
+ "default_mac_settings.desired_relay.mode.serving.limits.join_requests.reload_rate",
+ "default_mac_settings.desired_relay.mode.serving.limits.notifications",
+ "default_mac_settings.desired_relay.mode.serving.limits.notifications.bucket_size",
+ "default_mac_settings.desired_relay.mode.serving.limits.notifications.reload_rate",
+ "default_mac_settings.desired_relay.mode.serving.limits.overall",
+ "default_mac_settings.desired_relay.mode.serving.limits.overall.bucket_size",
+ "default_mac_settings.desired_relay.mode.serving.limits.overall.reload_rate",
+ "default_mac_settings.desired_relay.mode.serving.limits.reset_behavior",
+ "default_mac_settings.desired_relay.mode.serving.limits.uplink_messages",
+ "default_mac_settings.desired_relay.mode.serving.limits.uplink_messages.bucket_size",
+ "default_mac_settings.desired_relay.mode.serving.limits.uplink_messages.reload_rate",
+ "default_mac_settings.desired_relay.mode.serving.second_channel",
+ "default_mac_settings.desired_relay.mode.serving.second_channel.ack_offset",
+ "default_mac_settings.desired_relay.mode.serving.second_channel.data_rate_index",
+ "default_mac_settings.desired_relay.mode.serving.second_channel.frequency",
+ "default_mac_settings.desired_relay.mode.serving.uplink_forwarding_rules",
"default_mac_settings.desired_rx1_data_rate_offset",
"default_mac_settings.desired_rx1_data_rate_offset.value",
"default_mac_settings.desired_rx1_delay",
@@ -168,6 +371,42 @@ var EndDeviceVersionFieldPathsNested = []string{
"default_mac_settings.ping_slot_frequency.value",
"default_mac_settings.ping_slot_periodicity",
"default_mac_settings.ping_slot_periodicity.value",
+ "default_mac_settings.relay",
+ "default_mac_settings.relay.mode",
+ "default_mac_settings.relay.mode.served",
+ "default_mac_settings.relay.mode.served.backoff",
+ "default_mac_settings.relay.mode.served.mode",
+ "default_mac_settings.relay.mode.served.mode.always",
+ "default_mac_settings.relay.mode.served.mode.dynamic",
+ "default_mac_settings.relay.mode.served.mode.dynamic.smart_enable_level",
+ "default_mac_settings.relay.mode.served.mode.end_device_controlled",
+ "default_mac_settings.relay.mode.served.second_channel",
+ "default_mac_settings.relay.mode.served.second_channel.ack_offset",
+ "default_mac_settings.relay.mode.served.second_channel.data_rate_index",
+ "default_mac_settings.relay.mode.served.second_channel.frequency",
+ "default_mac_settings.relay.mode.served.serving_device_id",
+ "default_mac_settings.relay.mode.serving",
+ "default_mac_settings.relay.mode.serving.cad_periodicity",
+ "default_mac_settings.relay.mode.serving.default_channel_index",
+ "default_mac_settings.relay.mode.serving.limits",
+ "default_mac_settings.relay.mode.serving.limits.join_requests",
+ "default_mac_settings.relay.mode.serving.limits.join_requests.bucket_size",
+ "default_mac_settings.relay.mode.serving.limits.join_requests.reload_rate",
+ "default_mac_settings.relay.mode.serving.limits.notifications",
+ "default_mac_settings.relay.mode.serving.limits.notifications.bucket_size",
+ "default_mac_settings.relay.mode.serving.limits.notifications.reload_rate",
+ "default_mac_settings.relay.mode.serving.limits.overall",
+ "default_mac_settings.relay.mode.serving.limits.overall.bucket_size",
+ "default_mac_settings.relay.mode.serving.limits.overall.reload_rate",
+ "default_mac_settings.relay.mode.serving.limits.reset_behavior",
+ "default_mac_settings.relay.mode.serving.limits.uplink_messages",
+ "default_mac_settings.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "default_mac_settings.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "default_mac_settings.relay.mode.serving.second_channel",
+ "default_mac_settings.relay.mode.serving.second_channel.ack_offset",
+ "default_mac_settings.relay.mode.serving.second_channel.data_rate_index",
+ "default_mac_settings.relay.mode.serving.second_channel.frequency",
+ "default_mac_settings.relay.mode.serving.uplink_forwarding_rules",
"default_mac_settings.resets_f_cnt",
"default_mac_settings.resets_f_cnt.value",
"default_mac_settings.rx1_data_rate_offset",
@@ -289,6 +528,42 @@ var MACSettingsFieldPathsNested = []string{
"desired_ping_slot_data_rate_index.value",
"desired_ping_slot_frequency",
"desired_ping_slot_frequency.value",
+ "desired_relay",
+ "desired_relay.mode",
+ "desired_relay.mode.served",
+ "desired_relay.mode.served.backoff",
+ "desired_relay.mode.served.mode",
+ "desired_relay.mode.served.mode.always",
+ "desired_relay.mode.served.mode.dynamic",
+ "desired_relay.mode.served.mode.dynamic.smart_enable_level",
+ "desired_relay.mode.served.mode.end_device_controlled",
+ "desired_relay.mode.served.second_channel",
+ "desired_relay.mode.served.second_channel.ack_offset",
+ "desired_relay.mode.served.second_channel.data_rate_index",
+ "desired_relay.mode.served.second_channel.frequency",
+ "desired_relay.mode.served.serving_device_id",
+ "desired_relay.mode.serving",
+ "desired_relay.mode.serving.cad_periodicity",
+ "desired_relay.mode.serving.default_channel_index",
+ "desired_relay.mode.serving.limits",
+ "desired_relay.mode.serving.limits.join_requests",
+ "desired_relay.mode.serving.limits.join_requests.bucket_size",
+ "desired_relay.mode.serving.limits.join_requests.reload_rate",
+ "desired_relay.mode.serving.limits.notifications",
+ "desired_relay.mode.serving.limits.notifications.bucket_size",
+ "desired_relay.mode.serving.limits.notifications.reload_rate",
+ "desired_relay.mode.serving.limits.overall",
+ "desired_relay.mode.serving.limits.overall.bucket_size",
+ "desired_relay.mode.serving.limits.overall.reload_rate",
+ "desired_relay.mode.serving.limits.reset_behavior",
+ "desired_relay.mode.serving.limits.uplink_messages",
+ "desired_relay.mode.serving.limits.uplink_messages.bucket_size",
+ "desired_relay.mode.serving.limits.uplink_messages.reload_rate",
+ "desired_relay.mode.serving.second_channel",
+ "desired_relay.mode.serving.second_channel.ack_offset",
+ "desired_relay.mode.serving.second_channel.data_rate_index",
+ "desired_relay.mode.serving.second_channel.frequency",
+ "desired_relay.mode.serving.uplink_forwarding_rules",
"desired_rx1_data_rate_offset",
"desired_rx1_data_rate_offset.value",
"desired_rx1_delay",
@@ -308,6 +583,42 @@ var MACSettingsFieldPathsNested = []string{
"ping_slot_frequency.value",
"ping_slot_periodicity",
"ping_slot_periodicity.value",
+ "relay",
+ "relay.mode",
+ "relay.mode.served",
+ "relay.mode.served.backoff",
+ "relay.mode.served.mode",
+ "relay.mode.served.mode.always",
+ "relay.mode.served.mode.dynamic",
+ "relay.mode.served.mode.dynamic.smart_enable_level",
+ "relay.mode.served.mode.end_device_controlled",
+ "relay.mode.served.second_channel",
+ "relay.mode.served.second_channel.ack_offset",
+ "relay.mode.served.second_channel.data_rate_index",
+ "relay.mode.served.second_channel.frequency",
+ "relay.mode.served.serving_device_id",
+ "relay.mode.serving",
+ "relay.mode.serving.cad_periodicity",
+ "relay.mode.serving.default_channel_index",
+ "relay.mode.serving.limits",
+ "relay.mode.serving.limits.join_requests",
+ "relay.mode.serving.limits.join_requests.bucket_size",
+ "relay.mode.serving.limits.join_requests.reload_rate",
+ "relay.mode.serving.limits.notifications",
+ "relay.mode.serving.limits.notifications.bucket_size",
+ "relay.mode.serving.limits.notifications.reload_rate",
+ "relay.mode.serving.limits.overall",
+ "relay.mode.serving.limits.overall.bucket_size",
+ "relay.mode.serving.limits.overall.reload_rate",
+ "relay.mode.serving.limits.reset_behavior",
+ "relay.mode.serving.limits.uplink_messages",
+ "relay.mode.serving.limits.uplink_messages.bucket_size",
+ "relay.mode.serving.limits.uplink_messages.reload_rate",
+ "relay.mode.serving.second_channel",
+ "relay.mode.serving.second_channel.ack_offset",
+ "relay.mode.serving.second_channel.data_rate_index",
+ "relay.mode.serving.second_channel.frequency",
+ "relay.mode.serving.uplink_forwarding_rules",
"resets_f_cnt",
"resets_f_cnt.value",
"rx1_data_rate_offset",
@@ -344,6 +655,7 @@ var MACSettingsFieldPathsTopLevel = []string{
"desired_max_eirp",
"desired_ping_slot_data_rate_index",
"desired_ping_slot_frequency",
+ "desired_relay",
"desired_rx1_data_rate_offset",
"desired_rx1_delay",
"desired_rx2_data_rate_index",
@@ -354,6 +666,7 @@ var MACSettingsFieldPathsTopLevel = []string{
"ping_slot_data_rate_index",
"ping_slot_frequency",
"ping_slot_periodicity",
+ "relay",
"resets_f_cnt",
"rx1_data_rate_offset",
"rx1_delay",
@@ -389,6 +702,42 @@ var MACStateFieldPathsNested = []string{
"current_parameters.ping_slot_frequency",
"current_parameters.rejoin_count_periodicity",
"current_parameters.rejoin_time_periodicity",
+ "current_parameters.relay",
+ "current_parameters.relay.mode",
+ "current_parameters.relay.mode.served",
+ "current_parameters.relay.mode.served.backoff",
+ "current_parameters.relay.mode.served.mode",
+ "current_parameters.relay.mode.served.mode.always",
+ "current_parameters.relay.mode.served.mode.dynamic",
+ "current_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "current_parameters.relay.mode.served.mode.end_device_controlled",
+ "current_parameters.relay.mode.served.second_channel",
+ "current_parameters.relay.mode.served.second_channel.ack_offset",
+ "current_parameters.relay.mode.served.second_channel.data_rate_index",
+ "current_parameters.relay.mode.served.second_channel.frequency",
+ "current_parameters.relay.mode.served.serving_device_id",
+ "current_parameters.relay.mode.serving",
+ "current_parameters.relay.mode.serving.cad_periodicity",
+ "current_parameters.relay.mode.serving.default_channel_index",
+ "current_parameters.relay.mode.serving.limits",
+ "current_parameters.relay.mode.serving.limits.join_requests",
+ "current_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "current_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "current_parameters.relay.mode.serving.limits.notifications",
+ "current_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "current_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "current_parameters.relay.mode.serving.limits.overall",
+ "current_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "current_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "current_parameters.relay.mode.serving.limits.reset_behavior",
+ "current_parameters.relay.mode.serving.limits.uplink_messages",
+ "current_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "current_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "current_parameters.relay.mode.serving.second_channel",
+ "current_parameters.relay.mode.serving.second_channel.ack_offset",
+ "current_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "current_parameters.relay.mode.serving.second_channel.frequency",
+ "current_parameters.relay.mode.serving.uplink_forwarding_rules",
"current_parameters.rx1_data_rate_offset",
"current_parameters.rx1_delay",
"current_parameters.rx2_data_rate_index",
@@ -417,6 +766,42 @@ var MACStateFieldPathsNested = []string{
"desired_parameters.ping_slot_frequency",
"desired_parameters.rejoin_count_periodicity",
"desired_parameters.rejoin_time_periodicity",
+ "desired_parameters.relay",
+ "desired_parameters.relay.mode",
+ "desired_parameters.relay.mode.served",
+ "desired_parameters.relay.mode.served.backoff",
+ "desired_parameters.relay.mode.served.mode",
+ "desired_parameters.relay.mode.served.mode.always",
+ "desired_parameters.relay.mode.served.mode.dynamic",
+ "desired_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "desired_parameters.relay.mode.served.mode.end_device_controlled",
+ "desired_parameters.relay.mode.served.second_channel",
+ "desired_parameters.relay.mode.served.second_channel.ack_offset",
+ "desired_parameters.relay.mode.served.second_channel.data_rate_index",
+ "desired_parameters.relay.mode.served.second_channel.frequency",
+ "desired_parameters.relay.mode.served.serving_device_id",
+ "desired_parameters.relay.mode.serving",
+ "desired_parameters.relay.mode.serving.cad_periodicity",
+ "desired_parameters.relay.mode.serving.default_channel_index",
+ "desired_parameters.relay.mode.serving.limits",
+ "desired_parameters.relay.mode.serving.limits.join_requests",
+ "desired_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "desired_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "desired_parameters.relay.mode.serving.limits.notifications",
+ "desired_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "desired_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "desired_parameters.relay.mode.serving.limits.overall",
+ "desired_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "desired_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "desired_parameters.relay.mode.serving.limits.reset_behavior",
+ "desired_parameters.relay.mode.serving.limits.uplink_messages",
+ "desired_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "desired_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "desired_parameters.relay.mode.serving.second_channel",
+ "desired_parameters.relay.mode.serving.second_channel.ack_offset",
+ "desired_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "desired_parameters.relay.mode.serving.second_channel.frequency",
+ "desired_parameters.relay.mode.serving.uplink_forwarding_rules",
"desired_parameters.rx1_data_rate_offset",
"desired_parameters.rx1_delay",
"desired_parameters.rx2_data_rate_index",
@@ -456,6 +841,8 @@ var MACStateFieldPathsNested = []string{
"pending_join_request.downlink_settings.rx1_dr_offset",
"pending_join_request.downlink_settings.rx2_dr",
"pending_join_request.rx_delay",
+ "pending_relay_downlink",
+ "pending_relay_downlink.raw_payload",
"pending_requests",
"ping_slot_periodicity",
"ping_slot_periodicity.value",
@@ -515,6 +902,7 @@ var MACStateFieldPathsTopLevel = []string{
"lorawan_version",
"pending_application_downlink",
"pending_join_request",
+ "pending_relay_downlink",
"pending_requests",
"ping_slot_periodicity",
"queued_join_accept",
@@ -621,6 +1009,42 @@ var EndDeviceFieldPathsNested = []string{
"mac_settings.desired_ping_slot_data_rate_index.value",
"mac_settings.desired_ping_slot_frequency",
"mac_settings.desired_ping_slot_frequency.value",
+ "mac_settings.desired_relay",
+ "mac_settings.desired_relay.mode",
+ "mac_settings.desired_relay.mode.served",
+ "mac_settings.desired_relay.mode.served.backoff",
+ "mac_settings.desired_relay.mode.served.mode",
+ "mac_settings.desired_relay.mode.served.mode.always",
+ "mac_settings.desired_relay.mode.served.mode.dynamic",
+ "mac_settings.desired_relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_settings.desired_relay.mode.served.mode.end_device_controlled",
+ "mac_settings.desired_relay.mode.served.second_channel",
+ "mac_settings.desired_relay.mode.served.second_channel.ack_offset",
+ "mac_settings.desired_relay.mode.served.second_channel.data_rate_index",
+ "mac_settings.desired_relay.mode.served.second_channel.frequency",
+ "mac_settings.desired_relay.mode.served.serving_device_id",
+ "mac_settings.desired_relay.mode.serving",
+ "mac_settings.desired_relay.mode.serving.cad_periodicity",
+ "mac_settings.desired_relay.mode.serving.default_channel_index",
+ "mac_settings.desired_relay.mode.serving.limits",
+ "mac_settings.desired_relay.mode.serving.limits.join_requests",
+ "mac_settings.desired_relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_settings.desired_relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_settings.desired_relay.mode.serving.limits.notifications",
+ "mac_settings.desired_relay.mode.serving.limits.notifications.bucket_size",
+ "mac_settings.desired_relay.mode.serving.limits.notifications.reload_rate",
+ "mac_settings.desired_relay.mode.serving.limits.overall",
+ "mac_settings.desired_relay.mode.serving.limits.overall.bucket_size",
+ "mac_settings.desired_relay.mode.serving.limits.overall.reload_rate",
+ "mac_settings.desired_relay.mode.serving.limits.reset_behavior",
+ "mac_settings.desired_relay.mode.serving.limits.uplink_messages",
+ "mac_settings.desired_relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_settings.desired_relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_settings.desired_relay.mode.serving.second_channel",
+ "mac_settings.desired_relay.mode.serving.second_channel.ack_offset",
+ "mac_settings.desired_relay.mode.serving.second_channel.data_rate_index",
+ "mac_settings.desired_relay.mode.serving.second_channel.frequency",
+ "mac_settings.desired_relay.mode.serving.uplink_forwarding_rules",
"mac_settings.desired_rx1_data_rate_offset",
"mac_settings.desired_rx1_data_rate_offset.value",
"mac_settings.desired_rx1_delay",
@@ -640,6 +1064,42 @@ var EndDeviceFieldPathsNested = []string{
"mac_settings.ping_slot_frequency.value",
"mac_settings.ping_slot_periodicity",
"mac_settings.ping_slot_periodicity.value",
+ "mac_settings.relay",
+ "mac_settings.relay.mode",
+ "mac_settings.relay.mode.served",
+ "mac_settings.relay.mode.served.backoff",
+ "mac_settings.relay.mode.served.mode",
+ "mac_settings.relay.mode.served.mode.always",
+ "mac_settings.relay.mode.served.mode.dynamic",
+ "mac_settings.relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_settings.relay.mode.served.mode.end_device_controlled",
+ "mac_settings.relay.mode.served.second_channel",
+ "mac_settings.relay.mode.served.second_channel.ack_offset",
+ "mac_settings.relay.mode.served.second_channel.data_rate_index",
+ "mac_settings.relay.mode.served.second_channel.frequency",
+ "mac_settings.relay.mode.served.serving_device_id",
+ "mac_settings.relay.mode.serving",
+ "mac_settings.relay.mode.serving.cad_periodicity",
+ "mac_settings.relay.mode.serving.default_channel_index",
+ "mac_settings.relay.mode.serving.limits",
+ "mac_settings.relay.mode.serving.limits.join_requests",
+ "mac_settings.relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_settings.relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_settings.relay.mode.serving.limits.notifications",
+ "mac_settings.relay.mode.serving.limits.notifications.bucket_size",
+ "mac_settings.relay.mode.serving.limits.notifications.reload_rate",
+ "mac_settings.relay.mode.serving.limits.overall",
+ "mac_settings.relay.mode.serving.limits.overall.bucket_size",
+ "mac_settings.relay.mode.serving.limits.overall.reload_rate",
+ "mac_settings.relay.mode.serving.limits.reset_behavior",
+ "mac_settings.relay.mode.serving.limits.uplink_messages",
+ "mac_settings.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_settings.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_settings.relay.mode.serving.second_channel",
+ "mac_settings.relay.mode.serving.second_channel.ack_offset",
+ "mac_settings.relay.mode.serving.second_channel.data_rate_index",
+ "mac_settings.relay.mode.serving.second_channel.frequency",
+ "mac_settings.relay.mode.serving.uplink_forwarding_rules",
"mac_settings.resets_f_cnt",
"mac_settings.resets_f_cnt.value",
"mac_settings.rx1_data_rate_offset",
@@ -683,6 +1143,42 @@ var EndDeviceFieldPathsNested = []string{
"mac_state.current_parameters.ping_slot_frequency",
"mac_state.current_parameters.rejoin_count_periodicity",
"mac_state.current_parameters.rejoin_time_periodicity",
+ "mac_state.current_parameters.relay",
+ "mac_state.current_parameters.relay.mode",
+ "mac_state.current_parameters.relay.mode.served",
+ "mac_state.current_parameters.relay.mode.served.backoff",
+ "mac_state.current_parameters.relay.mode.served.mode",
+ "mac_state.current_parameters.relay.mode.served.mode.always",
+ "mac_state.current_parameters.relay.mode.served.mode.dynamic",
+ "mac_state.current_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_state.current_parameters.relay.mode.served.mode.end_device_controlled",
+ "mac_state.current_parameters.relay.mode.served.second_channel",
+ "mac_state.current_parameters.relay.mode.served.second_channel.ack_offset",
+ "mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index",
+ "mac_state.current_parameters.relay.mode.served.second_channel.frequency",
+ "mac_state.current_parameters.relay.mode.served.serving_device_id",
+ "mac_state.current_parameters.relay.mode.serving",
+ "mac_state.current_parameters.relay.mode.serving.cad_periodicity",
+ "mac_state.current_parameters.relay.mode.serving.default_channel_index",
+ "mac_state.current_parameters.relay.mode.serving.limits",
+ "mac_state.current_parameters.relay.mode.serving.limits.join_requests",
+ "mac_state.current_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.limits.notifications",
+ "mac_state.current_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.limits.overall",
+ "mac_state.current_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.limits.reset_behavior",
+ "mac_state.current_parameters.relay.mode.serving.limits.uplink_messages",
+ "mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.second_channel",
+ "mac_state.current_parameters.relay.mode.serving.second_channel.ack_offset",
+ "mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "mac_state.current_parameters.relay.mode.serving.second_channel.frequency",
+ "mac_state.current_parameters.relay.mode.serving.uplink_forwarding_rules",
"mac_state.current_parameters.rx1_data_rate_offset",
"mac_state.current_parameters.rx1_delay",
"mac_state.current_parameters.rx2_data_rate_index",
@@ -711,6 +1207,42 @@ var EndDeviceFieldPathsNested = []string{
"mac_state.desired_parameters.ping_slot_frequency",
"mac_state.desired_parameters.rejoin_count_periodicity",
"mac_state.desired_parameters.rejoin_time_periodicity",
+ "mac_state.desired_parameters.relay",
+ "mac_state.desired_parameters.relay.mode",
+ "mac_state.desired_parameters.relay.mode.served",
+ "mac_state.desired_parameters.relay.mode.served.backoff",
+ "mac_state.desired_parameters.relay.mode.served.mode",
+ "mac_state.desired_parameters.relay.mode.served.mode.always",
+ "mac_state.desired_parameters.relay.mode.served.mode.dynamic",
+ "mac_state.desired_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_state.desired_parameters.relay.mode.served.mode.end_device_controlled",
+ "mac_state.desired_parameters.relay.mode.served.second_channel",
+ "mac_state.desired_parameters.relay.mode.served.second_channel.ack_offset",
+ "mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index",
+ "mac_state.desired_parameters.relay.mode.served.second_channel.frequency",
+ "mac_state.desired_parameters.relay.mode.served.serving_device_id",
+ "mac_state.desired_parameters.relay.mode.serving",
+ "mac_state.desired_parameters.relay.mode.serving.cad_periodicity",
+ "mac_state.desired_parameters.relay.mode.serving.default_channel_index",
+ "mac_state.desired_parameters.relay.mode.serving.limits",
+ "mac_state.desired_parameters.relay.mode.serving.limits.join_requests",
+ "mac_state.desired_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.limits.notifications",
+ "mac_state.desired_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.limits.overall",
+ "mac_state.desired_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.limits.reset_behavior",
+ "mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages",
+ "mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel.ack_offset",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel.frequency",
+ "mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules",
"mac_state.desired_parameters.rx1_data_rate_offset",
"mac_state.desired_parameters.rx1_delay",
"mac_state.desired_parameters.rx2_data_rate_index",
@@ -750,6 +1282,8 @@ var EndDeviceFieldPathsNested = []string{
"mac_state.pending_join_request.downlink_settings.rx1_dr_offset",
"mac_state.pending_join_request.downlink_settings.rx2_dr",
"mac_state.pending_join_request.rx_delay",
+ "mac_state.pending_relay_downlink",
+ "mac_state.pending_relay_downlink.raw_payload",
"mac_state.pending_requests",
"mac_state.ping_slot_periodicity",
"mac_state.ping_slot_periodicity.value",
@@ -825,6 +1359,42 @@ var EndDeviceFieldPathsNested = []string{
"pending_mac_state.current_parameters.ping_slot_frequency",
"pending_mac_state.current_parameters.rejoin_count_periodicity",
"pending_mac_state.current_parameters.rejoin_time_periodicity",
+ "pending_mac_state.current_parameters.relay",
+ "pending_mac_state.current_parameters.relay.mode",
+ "pending_mac_state.current_parameters.relay.mode.served",
+ "pending_mac_state.current_parameters.relay.mode.served.backoff",
+ "pending_mac_state.current_parameters.relay.mode.served.mode",
+ "pending_mac_state.current_parameters.relay.mode.served.mode.always",
+ "pending_mac_state.current_parameters.relay.mode.served.mode.dynamic",
+ "pending_mac_state.current_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "pending_mac_state.current_parameters.relay.mode.served.mode.end_device_controlled",
+ "pending_mac_state.current_parameters.relay.mode.served.second_channel",
+ "pending_mac_state.current_parameters.relay.mode.served.second_channel.ack_offset",
+ "pending_mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index",
+ "pending_mac_state.current_parameters.relay.mode.served.second_channel.frequency",
+ "pending_mac_state.current_parameters.relay.mode.served.serving_device_id",
+ "pending_mac_state.current_parameters.relay.mode.serving",
+ "pending_mac_state.current_parameters.relay.mode.serving.cad_periodicity",
+ "pending_mac_state.current_parameters.relay.mode.serving.default_channel_index",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.notifications",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.overall",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.reset_behavior",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "pending_mac_state.current_parameters.relay.mode.serving.second_channel",
+ "pending_mac_state.current_parameters.relay.mode.serving.second_channel.ack_offset",
+ "pending_mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "pending_mac_state.current_parameters.relay.mode.serving.second_channel.frequency",
+ "pending_mac_state.current_parameters.relay.mode.serving.uplink_forwarding_rules",
"pending_mac_state.current_parameters.rx1_data_rate_offset",
"pending_mac_state.current_parameters.rx1_delay",
"pending_mac_state.current_parameters.rx2_data_rate_index",
@@ -853,6 +1423,42 @@ var EndDeviceFieldPathsNested = []string{
"pending_mac_state.desired_parameters.ping_slot_frequency",
"pending_mac_state.desired_parameters.rejoin_count_periodicity",
"pending_mac_state.desired_parameters.rejoin_time_periodicity",
+ "pending_mac_state.desired_parameters.relay",
+ "pending_mac_state.desired_parameters.relay.mode",
+ "pending_mac_state.desired_parameters.relay.mode.served",
+ "pending_mac_state.desired_parameters.relay.mode.served.backoff",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode.always",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode.dynamic",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode.end_device_controlled",
+ "pending_mac_state.desired_parameters.relay.mode.served.second_channel",
+ "pending_mac_state.desired_parameters.relay.mode.served.second_channel.ack_offset",
+ "pending_mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index",
+ "pending_mac_state.desired_parameters.relay.mode.served.second_channel.frequency",
+ "pending_mac_state.desired_parameters.relay.mode.served.serving_device_id",
+ "pending_mac_state.desired_parameters.relay.mode.serving",
+ "pending_mac_state.desired_parameters.relay.mode.serving.cad_periodicity",
+ "pending_mac_state.desired_parameters.relay.mode.serving.default_channel_index",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.overall",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.reset_behavior",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "pending_mac_state.desired_parameters.relay.mode.serving.second_channel",
+ "pending_mac_state.desired_parameters.relay.mode.serving.second_channel.ack_offset",
+ "pending_mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "pending_mac_state.desired_parameters.relay.mode.serving.second_channel.frequency",
+ "pending_mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules",
"pending_mac_state.desired_parameters.rx1_data_rate_offset",
"pending_mac_state.desired_parameters.rx1_delay",
"pending_mac_state.desired_parameters.rx2_data_rate_index",
@@ -892,6 +1498,8 @@ var EndDeviceFieldPathsNested = []string{
"pending_mac_state.pending_join_request.downlink_settings.rx1_dr_offset",
"pending_mac_state.pending_join_request.downlink_settings.rx2_dr",
"pending_mac_state.pending_join_request.rx_delay",
+ "pending_mac_state.pending_relay_downlink",
+ "pending_mac_state.pending_relay_downlink.raw_payload",
"pending_mac_state.pending_requests",
"pending_mac_state.ping_slot_periodicity",
"pending_mac_state.ping_slot_periodicity.value",
@@ -1180,6 +1788,42 @@ var CreateEndDeviceRequestFieldPathsNested = []string{
"end_device.mac_settings.desired_ping_slot_data_rate_index.value",
"end_device.mac_settings.desired_ping_slot_frequency",
"end_device.mac_settings.desired_ping_slot_frequency.value",
+ "end_device.mac_settings.desired_relay",
+ "end_device.mac_settings.desired_relay.mode",
+ "end_device.mac_settings.desired_relay.mode.served",
+ "end_device.mac_settings.desired_relay.mode.served.backoff",
+ "end_device.mac_settings.desired_relay.mode.served.mode",
+ "end_device.mac_settings.desired_relay.mode.served.mode.always",
+ "end_device.mac_settings.desired_relay.mode.served.mode.dynamic",
+ "end_device.mac_settings.desired_relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device.mac_settings.desired_relay.mode.served.mode.end_device_controlled",
+ "end_device.mac_settings.desired_relay.mode.served.second_channel",
+ "end_device.mac_settings.desired_relay.mode.served.second_channel.ack_offset",
+ "end_device.mac_settings.desired_relay.mode.served.second_channel.data_rate_index",
+ "end_device.mac_settings.desired_relay.mode.served.second_channel.frequency",
+ "end_device.mac_settings.desired_relay.mode.served.serving_device_id",
+ "end_device.mac_settings.desired_relay.mode.serving",
+ "end_device.mac_settings.desired_relay.mode.serving.cad_periodicity",
+ "end_device.mac_settings.desired_relay.mode.serving.default_channel_index",
+ "end_device.mac_settings.desired_relay.mode.serving.limits",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.join_requests",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.notifications",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.notifications.bucket_size",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.notifications.reload_rate",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.overall",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.overall.bucket_size",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.overall.reload_rate",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.reset_behavior",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.uplink_messages",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device.mac_settings.desired_relay.mode.serving.second_channel",
+ "end_device.mac_settings.desired_relay.mode.serving.second_channel.ack_offset",
+ "end_device.mac_settings.desired_relay.mode.serving.second_channel.data_rate_index",
+ "end_device.mac_settings.desired_relay.mode.serving.second_channel.frequency",
+ "end_device.mac_settings.desired_relay.mode.serving.uplink_forwarding_rules",
"end_device.mac_settings.desired_rx1_data_rate_offset",
"end_device.mac_settings.desired_rx1_data_rate_offset.value",
"end_device.mac_settings.desired_rx1_delay",
@@ -1199,6 +1843,42 @@ var CreateEndDeviceRequestFieldPathsNested = []string{
"end_device.mac_settings.ping_slot_frequency.value",
"end_device.mac_settings.ping_slot_periodicity",
"end_device.mac_settings.ping_slot_periodicity.value",
+ "end_device.mac_settings.relay",
+ "end_device.mac_settings.relay.mode",
+ "end_device.mac_settings.relay.mode.served",
+ "end_device.mac_settings.relay.mode.served.backoff",
+ "end_device.mac_settings.relay.mode.served.mode",
+ "end_device.mac_settings.relay.mode.served.mode.always",
+ "end_device.mac_settings.relay.mode.served.mode.dynamic",
+ "end_device.mac_settings.relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device.mac_settings.relay.mode.served.mode.end_device_controlled",
+ "end_device.mac_settings.relay.mode.served.second_channel",
+ "end_device.mac_settings.relay.mode.served.second_channel.ack_offset",
+ "end_device.mac_settings.relay.mode.served.second_channel.data_rate_index",
+ "end_device.mac_settings.relay.mode.served.second_channel.frequency",
+ "end_device.mac_settings.relay.mode.served.serving_device_id",
+ "end_device.mac_settings.relay.mode.serving",
+ "end_device.mac_settings.relay.mode.serving.cad_periodicity",
+ "end_device.mac_settings.relay.mode.serving.default_channel_index",
+ "end_device.mac_settings.relay.mode.serving.limits",
+ "end_device.mac_settings.relay.mode.serving.limits.join_requests",
+ "end_device.mac_settings.relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device.mac_settings.relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device.mac_settings.relay.mode.serving.limits.notifications",
+ "end_device.mac_settings.relay.mode.serving.limits.notifications.bucket_size",
+ "end_device.mac_settings.relay.mode.serving.limits.notifications.reload_rate",
+ "end_device.mac_settings.relay.mode.serving.limits.overall",
+ "end_device.mac_settings.relay.mode.serving.limits.overall.bucket_size",
+ "end_device.mac_settings.relay.mode.serving.limits.overall.reload_rate",
+ "end_device.mac_settings.relay.mode.serving.limits.reset_behavior",
+ "end_device.mac_settings.relay.mode.serving.limits.uplink_messages",
+ "end_device.mac_settings.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device.mac_settings.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device.mac_settings.relay.mode.serving.second_channel",
+ "end_device.mac_settings.relay.mode.serving.second_channel.ack_offset",
+ "end_device.mac_settings.relay.mode.serving.second_channel.data_rate_index",
+ "end_device.mac_settings.relay.mode.serving.second_channel.frequency",
+ "end_device.mac_settings.relay.mode.serving.uplink_forwarding_rules",
"end_device.mac_settings.resets_f_cnt",
"end_device.mac_settings.resets_f_cnt.value",
"end_device.mac_settings.rx1_data_rate_offset",
@@ -1242,6 +1922,42 @@ var CreateEndDeviceRequestFieldPathsNested = []string{
"end_device.mac_state.current_parameters.ping_slot_frequency",
"end_device.mac_state.current_parameters.rejoin_count_periodicity",
"end_device.mac_state.current_parameters.rejoin_time_periodicity",
+ "end_device.mac_state.current_parameters.relay",
+ "end_device.mac_state.current_parameters.relay.mode",
+ "end_device.mac_state.current_parameters.relay.mode.served",
+ "end_device.mac_state.current_parameters.relay.mode.served.backoff",
+ "end_device.mac_state.current_parameters.relay.mode.served.mode",
+ "end_device.mac_state.current_parameters.relay.mode.served.mode.always",
+ "end_device.mac_state.current_parameters.relay.mode.served.mode.dynamic",
+ "end_device.mac_state.current_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device.mac_state.current_parameters.relay.mode.served.mode.end_device_controlled",
+ "end_device.mac_state.current_parameters.relay.mode.served.second_channel",
+ "end_device.mac_state.current_parameters.relay.mode.served.second_channel.ack_offset",
+ "end_device.mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index",
+ "end_device.mac_state.current_parameters.relay.mode.served.second_channel.frequency",
+ "end_device.mac_state.current_parameters.relay.mode.served.serving_device_id",
+ "end_device.mac_state.current_parameters.relay.mode.serving",
+ "end_device.mac_state.current_parameters.relay.mode.serving.cad_periodicity",
+ "end_device.mac_state.current_parameters.relay.mode.serving.default_channel_index",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.join_requests",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.notifications",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.overall",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.reset_behavior",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.uplink_messages",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device.mac_state.current_parameters.relay.mode.serving.second_channel",
+ "end_device.mac_state.current_parameters.relay.mode.serving.second_channel.ack_offset",
+ "end_device.mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "end_device.mac_state.current_parameters.relay.mode.serving.second_channel.frequency",
+ "end_device.mac_state.current_parameters.relay.mode.serving.uplink_forwarding_rules",
"end_device.mac_state.current_parameters.rx1_data_rate_offset",
"end_device.mac_state.current_parameters.rx1_delay",
"end_device.mac_state.current_parameters.rx2_data_rate_index",
@@ -1270,6 +1986,42 @@ var CreateEndDeviceRequestFieldPathsNested = []string{
"end_device.mac_state.desired_parameters.ping_slot_frequency",
"end_device.mac_state.desired_parameters.rejoin_count_periodicity",
"end_device.mac_state.desired_parameters.rejoin_time_periodicity",
+ "end_device.mac_state.desired_parameters.relay",
+ "end_device.mac_state.desired_parameters.relay.mode",
+ "end_device.mac_state.desired_parameters.relay.mode.served",
+ "end_device.mac_state.desired_parameters.relay.mode.served.backoff",
+ "end_device.mac_state.desired_parameters.relay.mode.served.mode",
+ "end_device.mac_state.desired_parameters.relay.mode.served.mode.always",
+ "end_device.mac_state.desired_parameters.relay.mode.served.mode.dynamic",
+ "end_device.mac_state.desired_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device.mac_state.desired_parameters.relay.mode.served.mode.end_device_controlled",
+ "end_device.mac_state.desired_parameters.relay.mode.served.second_channel",
+ "end_device.mac_state.desired_parameters.relay.mode.served.second_channel.ack_offset",
+ "end_device.mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index",
+ "end_device.mac_state.desired_parameters.relay.mode.served.second_channel.frequency",
+ "end_device.mac_state.desired_parameters.relay.mode.served.serving_device_id",
+ "end_device.mac_state.desired_parameters.relay.mode.serving",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.cad_periodicity",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.default_channel_index",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.join_requests",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.notifications",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.overall",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.reset_behavior",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.second_channel",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.second_channel.ack_offset",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.second_channel.frequency",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules",
"end_device.mac_state.desired_parameters.rx1_data_rate_offset",
"end_device.mac_state.desired_parameters.rx1_delay",
"end_device.mac_state.desired_parameters.rx2_data_rate_index",
@@ -1309,6 +2061,8 @@ var CreateEndDeviceRequestFieldPathsNested = []string{
"end_device.mac_state.pending_join_request.downlink_settings.rx1_dr_offset",
"end_device.mac_state.pending_join_request.downlink_settings.rx2_dr",
"end_device.mac_state.pending_join_request.rx_delay",
+ "end_device.mac_state.pending_relay_downlink",
+ "end_device.mac_state.pending_relay_downlink.raw_payload",
"end_device.mac_state.pending_requests",
"end_device.mac_state.ping_slot_periodicity",
"end_device.mac_state.ping_slot_periodicity.value",
@@ -1384,6 +2138,42 @@ var CreateEndDeviceRequestFieldPathsNested = []string{
"end_device.pending_mac_state.current_parameters.ping_slot_frequency",
"end_device.pending_mac_state.current_parameters.rejoin_count_periodicity",
"end_device.pending_mac_state.current_parameters.rejoin_time_periodicity",
+ "end_device.pending_mac_state.current_parameters.relay",
+ "end_device.pending_mac_state.current_parameters.relay.mode",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.backoff",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.mode",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.mode.always",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.mode.dynamic",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.mode.end_device_controlled",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.second_channel",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.second_channel.ack_offset",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.second_channel.frequency",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.serving_device_id",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.cad_periodicity",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.default_channel_index",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.notifications",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.overall",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.reset_behavior",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.second_channel",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.second_channel.ack_offset",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.second_channel.frequency",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.uplink_forwarding_rules",
"end_device.pending_mac_state.current_parameters.rx1_data_rate_offset",
"end_device.pending_mac_state.current_parameters.rx1_delay",
"end_device.pending_mac_state.current_parameters.rx2_data_rate_index",
@@ -1412,6 +2202,42 @@ var CreateEndDeviceRequestFieldPathsNested = []string{
"end_device.pending_mac_state.desired_parameters.ping_slot_frequency",
"end_device.pending_mac_state.desired_parameters.rejoin_count_periodicity",
"end_device.pending_mac_state.desired_parameters.rejoin_time_periodicity",
+ "end_device.pending_mac_state.desired_parameters.relay",
+ "end_device.pending_mac_state.desired_parameters.relay.mode",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.backoff",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.mode",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.mode.always",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.mode.dynamic",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.mode.end_device_controlled",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.second_channel",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.second_channel.ack_offset",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.second_channel.frequency",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.serving_device_id",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.cad_periodicity",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.default_channel_index",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.overall",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.reset_behavior",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.second_channel",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.second_channel.ack_offset",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.second_channel.frequency",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules",
"end_device.pending_mac_state.desired_parameters.rx1_data_rate_offset",
"end_device.pending_mac_state.desired_parameters.rx1_delay",
"end_device.pending_mac_state.desired_parameters.rx2_data_rate_index",
@@ -1451,6 +2277,8 @@ var CreateEndDeviceRequestFieldPathsNested = []string{
"end_device.pending_mac_state.pending_join_request.downlink_settings.rx1_dr_offset",
"end_device.pending_mac_state.pending_join_request.downlink_settings.rx2_dr",
"end_device.pending_mac_state.pending_join_request.rx_delay",
+ "end_device.pending_mac_state.pending_relay_downlink",
+ "end_device.pending_mac_state.pending_relay_downlink.raw_payload",
"end_device.pending_mac_state.pending_requests",
"end_device.pending_mac_state.ping_slot_periodicity",
"end_device.pending_mac_state.ping_slot_periodicity.value",
@@ -1671,6 +2499,42 @@ var UpdateEndDeviceRequestFieldPathsNested = []string{
"end_device.mac_settings.desired_ping_slot_data_rate_index.value",
"end_device.mac_settings.desired_ping_slot_frequency",
"end_device.mac_settings.desired_ping_slot_frequency.value",
+ "end_device.mac_settings.desired_relay",
+ "end_device.mac_settings.desired_relay.mode",
+ "end_device.mac_settings.desired_relay.mode.served",
+ "end_device.mac_settings.desired_relay.mode.served.backoff",
+ "end_device.mac_settings.desired_relay.mode.served.mode",
+ "end_device.mac_settings.desired_relay.mode.served.mode.always",
+ "end_device.mac_settings.desired_relay.mode.served.mode.dynamic",
+ "end_device.mac_settings.desired_relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device.mac_settings.desired_relay.mode.served.mode.end_device_controlled",
+ "end_device.mac_settings.desired_relay.mode.served.second_channel",
+ "end_device.mac_settings.desired_relay.mode.served.second_channel.ack_offset",
+ "end_device.mac_settings.desired_relay.mode.served.second_channel.data_rate_index",
+ "end_device.mac_settings.desired_relay.mode.served.second_channel.frequency",
+ "end_device.mac_settings.desired_relay.mode.served.serving_device_id",
+ "end_device.mac_settings.desired_relay.mode.serving",
+ "end_device.mac_settings.desired_relay.mode.serving.cad_periodicity",
+ "end_device.mac_settings.desired_relay.mode.serving.default_channel_index",
+ "end_device.mac_settings.desired_relay.mode.serving.limits",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.join_requests",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.notifications",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.notifications.bucket_size",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.notifications.reload_rate",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.overall",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.overall.bucket_size",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.overall.reload_rate",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.reset_behavior",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.uplink_messages",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device.mac_settings.desired_relay.mode.serving.second_channel",
+ "end_device.mac_settings.desired_relay.mode.serving.second_channel.ack_offset",
+ "end_device.mac_settings.desired_relay.mode.serving.second_channel.data_rate_index",
+ "end_device.mac_settings.desired_relay.mode.serving.second_channel.frequency",
+ "end_device.mac_settings.desired_relay.mode.serving.uplink_forwarding_rules",
"end_device.mac_settings.desired_rx1_data_rate_offset",
"end_device.mac_settings.desired_rx1_data_rate_offset.value",
"end_device.mac_settings.desired_rx1_delay",
@@ -1690,6 +2554,42 @@ var UpdateEndDeviceRequestFieldPathsNested = []string{
"end_device.mac_settings.ping_slot_frequency.value",
"end_device.mac_settings.ping_slot_periodicity",
"end_device.mac_settings.ping_slot_periodicity.value",
+ "end_device.mac_settings.relay",
+ "end_device.mac_settings.relay.mode",
+ "end_device.mac_settings.relay.mode.served",
+ "end_device.mac_settings.relay.mode.served.backoff",
+ "end_device.mac_settings.relay.mode.served.mode",
+ "end_device.mac_settings.relay.mode.served.mode.always",
+ "end_device.mac_settings.relay.mode.served.mode.dynamic",
+ "end_device.mac_settings.relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device.mac_settings.relay.mode.served.mode.end_device_controlled",
+ "end_device.mac_settings.relay.mode.served.second_channel",
+ "end_device.mac_settings.relay.mode.served.second_channel.ack_offset",
+ "end_device.mac_settings.relay.mode.served.second_channel.data_rate_index",
+ "end_device.mac_settings.relay.mode.served.second_channel.frequency",
+ "end_device.mac_settings.relay.mode.served.serving_device_id",
+ "end_device.mac_settings.relay.mode.serving",
+ "end_device.mac_settings.relay.mode.serving.cad_periodicity",
+ "end_device.mac_settings.relay.mode.serving.default_channel_index",
+ "end_device.mac_settings.relay.mode.serving.limits",
+ "end_device.mac_settings.relay.mode.serving.limits.join_requests",
+ "end_device.mac_settings.relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device.mac_settings.relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device.mac_settings.relay.mode.serving.limits.notifications",
+ "end_device.mac_settings.relay.mode.serving.limits.notifications.bucket_size",
+ "end_device.mac_settings.relay.mode.serving.limits.notifications.reload_rate",
+ "end_device.mac_settings.relay.mode.serving.limits.overall",
+ "end_device.mac_settings.relay.mode.serving.limits.overall.bucket_size",
+ "end_device.mac_settings.relay.mode.serving.limits.overall.reload_rate",
+ "end_device.mac_settings.relay.mode.serving.limits.reset_behavior",
+ "end_device.mac_settings.relay.mode.serving.limits.uplink_messages",
+ "end_device.mac_settings.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device.mac_settings.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device.mac_settings.relay.mode.serving.second_channel",
+ "end_device.mac_settings.relay.mode.serving.second_channel.ack_offset",
+ "end_device.mac_settings.relay.mode.serving.second_channel.data_rate_index",
+ "end_device.mac_settings.relay.mode.serving.second_channel.frequency",
+ "end_device.mac_settings.relay.mode.serving.uplink_forwarding_rules",
"end_device.mac_settings.resets_f_cnt",
"end_device.mac_settings.resets_f_cnt.value",
"end_device.mac_settings.rx1_data_rate_offset",
@@ -1733,6 +2633,42 @@ var UpdateEndDeviceRequestFieldPathsNested = []string{
"end_device.mac_state.current_parameters.ping_slot_frequency",
"end_device.mac_state.current_parameters.rejoin_count_periodicity",
"end_device.mac_state.current_parameters.rejoin_time_periodicity",
+ "end_device.mac_state.current_parameters.relay",
+ "end_device.mac_state.current_parameters.relay.mode",
+ "end_device.mac_state.current_parameters.relay.mode.served",
+ "end_device.mac_state.current_parameters.relay.mode.served.backoff",
+ "end_device.mac_state.current_parameters.relay.mode.served.mode",
+ "end_device.mac_state.current_parameters.relay.mode.served.mode.always",
+ "end_device.mac_state.current_parameters.relay.mode.served.mode.dynamic",
+ "end_device.mac_state.current_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device.mac_state.current_parameters.relay.mode.served.mode.end_device_controlled",
+ "end_device.mac_state.current_parameters.relay.mode.served.second_channel",
+ "end_device.mac_state.current_parameters.relay.mode.served.second_channel.ack_offset",
+ "end_device.mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index",
+ "end_device.mac_state.current_parameters.relay.mode.served.second_channel.frequency",
+ "end_device.mac_state.current_parameters.relay.mode.served.serving_device_id",
+ "end_device.mac_state.current_parameters.relay.mode.serving",
+ "end_device.mac_state.current_parameters.relay.mode.serving.cad_periodicity",
+ "end_device.mac_state.current_parameters.relay.mode.serving.default_channel_index",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.join_requests",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.notifications",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.overall",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.reset_behavior",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.uplink_messages",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device.mac_state.current_parameters.relay.mode.serving.second_channel",
+ "end_device.mac_state.current_parameters.relay.mode.serving.second_channel.ack_offset",
+ "end_device.mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "end_device.mac_state.current_parameters.relay.mode.serving.second_channel.frequency",
+ "end_device.mac_state.current_parameters.relay.mode.serving.uplink_forwarding_rules",
"end_device.mac_state.current_parameters.rx1_data_rate_offset",
"end_device.mac_state.current_parameters.rx1_delay",
"end_device.mac_state.current_parameters.rx2_data_rate_index",
@@ -1761,6 +2697,42 @@ var UpdateEndDeviceRequestFieldPathsNested = []string{
"end_device.mac_state.desired_parameters.ping_slot_frequency",
"end_device.mac_state.desired_parameters.rejoin_count_periodicity",
"end_device.mac_state.desired_parameters.rejoin_time_periodicity",
+ "end_device.mac_state.desired_parameters.relay",
+ "end_device.mac_state.desired_parameters.relay.mode",
+ "end_device.mac_state.desired_parameters.relay.mode.served",
+ "end_device.mac_state.desired_parameters.relay.mode.served.backoff",
+ "end_device.mac_state.desired_parameters.relay.mode.served.mode",
+ "end_device.mac_state.desired_parameters.relay.mode.served.mode.always",
+ "end_device.mac_state.desired_parameters.relay.mode.served.mode.dynamic",
+ "end_device.mac_state.desired_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device.mac_state.desired_parameters.relay.mode.served.mode.end_device_controlled",
+ "end_device.mac_state.desired_parameters.relay.mode.served.second_channel",
+ "end_device.mac_state.desired_parameters.relay.mode.served.second_channel.ack_offset",
+ "end_device.mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index",
+ "end_device.mac_state.desired_parameters.relay.mode.served.second_channel.frequency",
+ "end_device.mac_state.desired_parameters.relay.mode.served.serving_device_id",
+ "end_device.mac_state.desired_parameters.relay.mode.serving",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.cad_periodicity",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.default_channel_index",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.join_requests",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.notifications",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.overall",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.reset_behavior",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.second_channel",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.second_channel.ack_offset",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.second_channel.frequency",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules",
"end_device.mac_state.desired_parameters.rx1_data_rate_offset",
"end_device.mac_state.desired_parameters.rx1_delay",
"end_device.mac_state.desired_parameters.rx2_data_rate_index",
@@ -1800,6 +2772,8 @@ var UpdateEndDeviceRequestFieldPathsNested = []string{
"end_device.mac_state.pending_join_request.downlink_settings.rx1_dr_offset",
"end_device.mac_state.pending_join_request.downlink_settings.rx2_dr",
"end_device.mac_state.pending_join_request.rx_delay",
+ "end_device.mac_state.pending_relay_downlink",
+ "end_device.mac_state.pending_relay_downlink.raw_payload",
"end_device.mac_state.pending_requests",
"end_device.mac_state.ping_slot_periodicity",
"end_device.mac_state.ping_slot_periodicity.value",
@@ -1875,6 +2849,42 @@ var UpdateEndDeviceRequestFieldPathsNested = []string{
"end_device.pending_mac_state.current_parameters.ping_slot_frequency",
"end_device.pending_mac_state.current_parameters.rejoin_count_periodicity",
"end_device.pending_mac_state.current_parameters.rejoin_time_periodicity",
+ "end_device.pending_mac_state.current_parameters.relay",
+ "end_device.pending_mac_state.current_parameters.relay.mode",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.backoff",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.mode",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.mode.always",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.mode.dynamic",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.mode.end_device_controlled",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.second_channel",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.second_channel.ack_offset",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.second_channel.frequency",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.serving_device_id",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.cad_periodicity",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.default_channel_index",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.notifications",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.overall",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.reset_behavior",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.second_channel",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.second_channel.ack_offset",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.second_channel.frequency",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.uplink_forwarding_rules",
"end_device.pending_mac_state.current_parameters.rx1_data_rate_offset",
"end_device.pending_mac_state.current_parameters.rx1_delay",
"end_device.pending_mac_state.current_parameters.rx2_data_rate_index",
@@ -1903,6 +2913,42 @@ var UpdateEndDeviceRequestFieldPathsNested = []string{
"end_device.pending_mac_state.desired_parameters.ping_slot_frequency",
"end_device.pending_mac_state.desired_parameters.rejoin_count_periodicity",
"end_device.pending_mac_state.desired_parameters.rejoin_time_periodicity",
+ "end_device.pending_mac_state.desired_parameters.relay",
+ "end_device.pending_mac_state.desired_parameters.relay.mode",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.backoff",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.mode",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.mode.always",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.mode.dynamic",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.mode.end_device_controlled",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.second_channel",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.second_channel.ack_offset",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.second_channel.frequency",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.serving_device_id",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.cad_periodicity",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.default_channel_index",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.overall",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.reset_behavior",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.second_channel",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.second_channel.ack_offset",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.second_channel.frequency",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules",
"end_device.pending_mac_state.desired_parameters.rx1_data_rate_offset",
"end_device.pending_mac_state.desired_parameters.rx1_delay",
"end_device.pending_mac_state.desired_parameters.rx2_data_rate_index",
@@ -1942,6 +2988,8 @@ var UpdateEndDeviceRequestFieldPathsNested = []string{
"end_device.pending_mac_state.pending_join_request.downlink_settings.rx1_dr_offset",
"end_device.pending_mac_state.pending_join_request.downlink_settings.rx2_dr",
"end_device.pending_mac_state.pending_join_request.rx_delay",
+ "end_device.pending_mac_state.pending_relay_downlink",
+ "end_device.pending_mac_state.pending_relay_downlink.raw_payload",
"end_device.pending_mac_state.pending_requests",
"end_device.pending_mac_state.ping_slot_periodicity",
"end_device.pending_mac_state.ping_slot_periodicity.value",
@@ -2211,6 +3259,42 @@ var SetEndDeviceRequestFieldPathsNested = []string{
"end_device.mac_settings.desired_ping_slot_data_rate_index.value",
"end_device.mac_settings.desired_ping_slot_frequency",
"end_device.mac_settings.desired_ping_slot_frequency.value",
+ "end_device.mac_settings.desired_relay",
+ "end_device.mac_settings.desired_relay.mode",
+ "end_device.mac_settings.desired_relay.mode.served",
+ "end_device.mac_settings.desired_relay.mode.served.backoff",
+ "end_device.mac_settings.desired_relay.mode.served.mode",
+ "end_device.mac_settings.desired_relay.mode.served.mode.always",
+ "end_device.mac_settings.desired_relay.mode.served.mode.dynamic",
+ "end_device.mac_settings.desired_relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device.mac_settings.desired_relay.mode.served.mode.end_device_controlled",
+ "end_device.mac_settings.desired_relay.mode.served.second_channel",
+ "end_device.mac_settings.desired_relay.mode.served.second_channel.ack_offset",
+ "end_device.mac_settings.desired_relay.mode.served.second_channel.data_rate_index",
+ "end_device.mac_settings.desired_relay.mode.served.second_channel.frequency",
+ "end_device.mac_settings.desired_relay.mode.served.serving_device_id",
+ "end_device.mac_settings.desired_relay.mode.serving",
+ "end_device.mac_settings.desired_relay.mode.serving.cad_periodicity",
+ "end_device.mac_settings.desired_relay.mode.serving.default_channel_index",
+ "end_device.mac_settings.desired_relay.mode.serving.limits",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.join_requests",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.notifications",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.notifications.bucket_size",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.notifications.reload_rate",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.overall",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.overall.bucket_size",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.overall.reload_rate",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.reset_behavior",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.uplink_messages",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device.mac_settings.desired_relay.mode.serving.second_channel",
+ "end_device.mac_settings.desired_relay.mode.serving.second_channel.ack_offset",
+ "end_device.mac_settings.desired_relay.mode.serving.second_channel.data_rate_index",
+ "end_device.mac_settings.desired_relay.mode.serving.second_channel.frequency",
+ "end_device.mac_settings.desired_relay.mode.serving.uplink_forwarding_rules",
"end_device.mac_settings.desired_rx1_data_rate_offset",
"end_device.mac_settings.desired_rx1_data_rate_offset.value",
"end_device.mac_settings.desired_rx1_delay",
@@ -2230,6 +3314,42 @@ var SetEndDeviceRequestFieldPathsNested = []string{
"end_device.mac_settings.ping_slot_frequency.value",
"end_device.mac_settings.ping_slot_periodicity",
"end_device.mac_settings.ping_slot_periodicity.value",
+ "end_device.mac_settings.relay",
+ "end_device.mac_settings.relay.mode",
+ "end_device.mac_settings.relay.mode.served",
+ "end_device.mac_settings.relay.mode.served.backoff",
+ "end_device.mac_settings.relay.mode.served.mode",
+ "end_device.mac_settings.relay.mode.served.mode.always",
+ "end_device.mac_settings.relay.mode.served.mode.dynamic",
+ "end_device.mac_settings.relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device.mac_settings.relay.mode.served.mode.end_device_controlled",
+ "end_device.mac_settings.relay.mode.served.second_channel",
+ "end_device.mac_settings.relay.mode.served.second_channel.ack_offset",
+ "end_device.mac_settings.relay.mode.served.second_channel.data_rate_index",
+ "end_device.mac_settings.relay.mode.served.second_channel.frequency",
+ "end_device.mac_settings.relay.mode.served.serving_device_id",
+ "end_device.mac_settings.relay.mode.serving",
+ "end_device.mac_settings.relay.mode.serving.cad_periodicity",
+ "end_device.mac_settings.relay.mode.serving.default_channel_index",
+ "end_device.mac_settings.relay.mode.serving.limits",
+ "end_device.mac_settings.relay.mode.serving.limits.join_requests",
+ "end_device.mac_settings.relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device.mac_settings.relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device.mac_settings.relay.mode.serving.limits.notifications",
+ "end_device.mac_settings.relay.mode.serving.limits.notifications.bucket_size",
+ "end_device.mac_settings.relay.mode.serving.limits.notifications.reload_rate",
+ "end_device.mac_settings.relay.mode.serving.limits.overall",
+ "end_device.mac_settings.relay.mode.serving.limits.overall.bucket_size",
+ "end_device.mac_settings.relay.mode.serving.limits.overall.reload_rate",
+ "end_device.mac_settings.relay.mode.serving.limits.reset_behavior",
+ "end_device.mac_settings.relay.mode.serving.limits.uplink_messages",
+ "end_device.mac_settings.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device.mac_settings.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device.mac_settings.relay.mode.serving.second_channel",
+ "end_device.mac_settings.relay.mode.serving.second_channel.ack_offset",
+ "end_device.mac_settings.relay.mode.serving.second_channel.data_rate_index",
+ "end_device.mac_settings.relay.mode.serving.second_channel.frequency",
+ "end_device.mac_settings.relay.mode.serving.uplink_forwarding_rules",
"end_device.mac_settings.resets_f_cnt",
"end_device.mac_settings.resets_f_cnt.value",
"end_device.mac_settings.rx1_data_rate_offset",
@@ -2273,6 +3393,42 @@ var SetEndDeviceRequestFieldPathsNested = []string{
"end_device.mac_state.current_parameters.ping_slot_frequency",
"end_device.mac_state.current_parameters.rejoin_count_periodicity",
"end_device.mac_state.current_parameters.rejoin_time_periodicity",
+ "end_device.mac_state.current_parameters.relay",
+ "end_device.mac_state.current_parameters.relay.mode",
+ "end_device.mac_state.current_parameters.relay.mode.served",
+ "end_device.mac_state.current_parameters.relay.mode.served.backoff",
+ "end_device.mac_state.current_parameters.relay.mode.served.mode",
+ "end_device.mac_state.current_parameters.relay.mode.served.mode.always",
+ "end_device.mac_state.current_parameters.relay.mode.served.mode.dynamic",
+ "end_device.mac_state.current_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device.mac_state.current_parameters.relay.mode.served.mode.end_device_controlled",
+ "end_device.mac_state.current_parameters.relay.mode.served.second_channel",
+ "end_device.mac_state.current_parameters.relay.mode.served.second_channel.ack_offset",
+ "end_device.mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index",
+ "end_device.mac_state.current_parameters.relay.mode.served.second_channel.frequency",
+ "end_device.mac_state.current_parameters.relay.mode.served.serving_device_id",
+ "end_device.mac_state.current_parameters.relay.mode.serving",
+ "end_device.mac_state.current_parameters.relay.mode.serving.cad_periodicity",
+ "end_device.mac_state.current_parameters.relay.mode.serving.default_channel_index",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.join_requests",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.notifications",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.overall",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.reset_behavior",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.uplink_messages",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device.mac_state.current_parameters.relay.mode.serving.second_channel",
+ "end_device.mac_state.current_parameters.relay.mode.serving.second_channel.ack_offset",
+ "end_device.mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "end_device.mac_state.current_parameters.relay.mode.serving.second_channel.frequency",
+ "end_device.mac_state.current_parameters.relay.mode.serving.uplink_forwarding_rules",
"end_device.mac_state.current_parameters.rx1_data_rate_offset",
"end_device.mac_state.current_parameters.rx1_delay",
"end_device.mac_state.current_parameters.rx2_data_rate_index",
@@ -2301,6 +3457,42 @@ var SetEndDeviceRequestFieldPathsNested = []string{
"end_device.mac_state.desired_parameters.ping_slot_frequency",
"end_device.mac_state.desired_parameters.rejoin_count_periodicity",
"end_device.mac_state.desired_parameters.rejoin_time_periodicity",
+ "end_device.mac_state.desired_parameters.relay",
+ "end_device.mac_state.desired_parameters.relay.mode",
+ "end_device.mac_state.desired_parameters.relay.mode.served",
+ "end_device.mac_state.desired_parameters.relay.mode.served.backoff",
+ "end_device.mac_state.desired_parameters.relay.mode.served.mode",
+ "end_device.mac_state.desired_parameters.relay.mode.served.mode.always",
+ "end_device.mac_state.desired_parameters.relay.mode.served.mode.dynamic",
+ "end_device.mac_state.desired_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device.mac_state.desired_parameters.relay.mode.served.mode.end_device_controlled",
+ "end_device.mac_state.desired_parameters.relay.mode.served.second_channel",
+ "end_device.mac_state.desired_parameters.relay.mode.served.second_channel.ack_offset",
+ "end_device.mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index",
+ "end_device.mac_state.desired_parameters.relay.mode.served.second_channel.frequency",
+ "end_device.mac_state.desired_parameters.relay.mode.served.serving_device_id",
+ "end_device.mac_state.desired_parameters.relay.mode.serving",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.cad_periodicity",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.default_channel_index",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.join_requests",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.notifications",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.overall",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.reset_behavior",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.second_channel",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.second_channel.ack_offset",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.second_channel.frequency",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules",
"end_device.mac_state.desired_parameters.rx1_data_rate_offset",
"end_device.mac_state.desired_parameters.rx1_delay",
"end_device.mac_state.desired_parameters.rx2_data_rate_index",
@@ -2340,6 +3532,8 @@ var SetEndDeviceRequestFieldPathsNested = []string{
"end_device.mac_state.pending_join_request.downlink_settings.rx1_dr_offset",
"end_device.mac_state.pending_join_request.downlink_settings.rx2_dr",
"end_device.mac_state.pending_join_request.rx_delay",
+ "end_device.mac_state.pending_relay_downlink",
+ "end_device.mac_state.pending_relay_downlink.raw_payload",
"end_device.mac_state.pending_requests",
"end_device.mac_state.ping_slot_periodicity",
"end_device.mac_state.ping_slot_periodicity.value",
@@ -2415,6 +3609,42 @@ var SetEndDeviceRequestFieldPathsNested = []string{
"end_device.pending_mac_state.current_parameters.ping_slot_frequency",
"end_device.pending_mac_state.current_parameters.rejoin_count_periodicity",
"end_device.pending_mac_state.current_parameters.rejoin_time_periodicity",
+ "end_device.pending_mac_state.current_parameters.relay",
+ "end_device.pending_mac_state.current_parameters.relay.mode",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.backoff",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.mode",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.mode.always",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.mode.dynamic",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.mode.end_device_controlled",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.second_channel",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.second_channel.ack_offset",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.second_channel.frequency",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.serving_device_id",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.cad_periodicity",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.default_channel_index",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.notifications",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.overall",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.reset_behavior",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.second_channel",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.second_channel.ack_offset",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.second_channel.frequency",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.uplink_forwarding_rules",
"end_device.pending_mac_state.current_parameters.rx1_data_rate_offset",
"end_device.pending_mac_state.current_parameters.rx1_delay",
"end_device.pending_mac_state.current_parameters.rx2_data_rate_index",
@@ -2443,6 +3673,42 @@ var SetEndDeviceRequestFieldPathsNested = []string{
"end_device.pending_mac_state.desired_parameters.ping_slot_frequency",
"end_device.pending_mac_state.desired_parameters.rejoin_count_periodicity",
"end_device.pending_mac_state.desired_parameters.rejoin_time_periodicity",
+ "end_device.pending_mac_state.desired_parameters.relay",
+ "end_device.pending_mac_state.desired_parameters.relay.mode",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.backoff",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.mode",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.mode.always",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.mode.dynamic",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.mode.end_device_controlled",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.second_channel",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.second_channel.ack_offset",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.second_channel.frequency",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.serving_device_id",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.cad_periodicity",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.default_channel_index",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.overall",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.reset_behavior",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.second_channel",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.second_channel.ack_offset",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.second_channel.frequency",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules",
"end_device.pending_mac_state.desired_parameters.rx1_data_rate_offset",
"end_device.pending_mac_state.desired_parameters.rx1_delay",
"end_device.pending_mac_state.desired_parameters.rx2_data_rate_index",
@@ -2482,6 +3748,8 @@ var SetEndDeviceRequestFieldPathsNested = []string{
"end_device.pending_mac_state.pending_join_request.downlink_settings.rx1_dr_offset",
"end_device.pending_mac_state.pending_join_request.downlink_settings.rx2_dr",
"end_device.pending_mac_state.pending_join_request.rx_delay",
+ "end_device.pending_mac_state.pending_relay_downlink",
+ "end_device.pending_mac_state.pending_relay_downlink.raw_payload",
"end_device.pending_mac_state.pending_requests",
"end_device.pending_mac_state.ping_slot_periodicity",
"end_device.pending_mac_state.ping_slot_periodicity.value",
@@ -2719,6 +3987,42 @@ var EndDeviceTemplateFieldPathsNested = []string{
"end_device.mac_settings.desired_ping_slot_data_rate_index.value",
"end_device.mac_settings.desired_ping_slot_frequency",
"end_device.mac_settings.desired_ping_slot_frequency.value",
+ "end_device.mac_settings.desired_relay",
+ "end_device.mac_settings.desired_relay.mode",
+ "end_device.mac_settings.desired_relay.mode.served",
+ "end_device.mac_settings.desired_relay.mode.served.backoff",
+ "end_device.mac_settings.desired_relay.mode.served.mode",
+ "end_device.mac_settings.desired_relay.mode.served.mode.always",
+ "end_device.mac_settings.desired_relay.mode.served.mode.dynamic",
+ "end_device.mac_settings.desired_relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device.mac_settings.desired_relay.mode.served.mode.end_device_controlled",
+ "end_device.mac_settings.desired_relay.mode.served.second_channel",
+ "end_device.mac_settings.desired_relay.mode.served.second_channel.ack_offset",
+ "end_device.mac_settings.desired_relay.mode.served.second_channel.data_rate_index",
+ "end_device.mac_settings.desired_relay.mode.served.second_channel.frequency",
+ "end_device.mac_settings.desired_relay.mode.served.serving_device_id",
+ "end_device.mac_settings.desired_relay.mode.serving",
+ "end_device.mac_settings.desired_relay.mode.serving.cad_periodicity",
+ "end_device.mac_settings.desired_relay.mode.serving.default_channel_index",
+ "end_device.mac_settings.desired_relay.mode.serving.limits",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.join_requests",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.notifications",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.notifications.bucket_size",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.notifications.reload_rate",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.overall",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.overall.bucket_size",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.overall.reload_rate",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.reset_behavior",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.uplink_messages",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device.mac_settings.desired_relay.mode.serving.second_channel",
+ "end_device.mac_settings.desired_relay.mode.serving.second_channel.ack_offset",
+ "end_device.mac_settings.desired_relay.mode.serving.second_channel.data_rate_index",
+ "end_device.mac_settings.desired_relay.mode.serving.second_channel.frequency",
+ "end_device.mac_settings.desired_relay.mode.serving.uplink_forwarding_rules",
"end_device.mac_settings.desired_rx1_data_rate_offset",
"end_device.mac_settings.desired_rx1_data_rate_offset.value",
"end_device.mac_settings.desired_rx1_delay",
@@ -2738,6 +4042,42 @@ var EndDeviceTemplateFieldPathsNested = []string{
"end_device.mac_settings.ping_slot_frequency.value",
"end_device.mac_settings.ping_slot_periodicity",
"end_device.mac_settings.ping_slot_periodicity.value",
+ "end_device.mac_settings.relay",
+ "end_device.mac_settings.relay.mode",
+ "end_device.mac_settings.relay.mode.served",
+ "end_device.mac_settings.relay.mode.served.backoff",
+ "end_device.mac_settings.relay.mode.served.mode",
+ "end_device.mac_settings.relay.mode.served.mode.always",
+ "end_device.mac_settings.relay.mode.served.mode.dynamic",
+ "end_device.mac_settings.relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device.mac_settings.relay.mode.served.mode.end_device_controlled",
+ "end_device.mac_settings.relay.mode.served.second_channel",
+ "end_device.mac_settings.relay.mode.served.second_channel.ack_offset",
+ "end_device.mac_settings.relay.mode.served.second_channel.data_rate_index",
+ "end_device.mac_settings.relay.mode.served.second_channel.frequency",
+ "end_device.mac_settings.relay.mode.served.serving_device_id",
+ "end_device.mac_settings.relay.mode.serving",
+ "end_device.mac_settings.relay.mode.serving.cad_periodicity",
+ "end_device.mac_settings.relay.mode.serving.default_channel_index",
+ "end_device.mac_settings.relay.mode.serving.limits",
+ "end_device.mac_settings.relay.mode.serving.limits.join_requests",
+ "end_device.mac_settings.relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device.mac_settings.relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device.mac_settings.relay.mode.serving.limits.notifications",
+ "end_device.mac_settings.relay.mode.serving.limits.notifications.bucket_size",
+ "end_device.mac_settings.relay.mode.serving.limits.notifications.reload_rate",
+ "end_device.mac_settings.relay.mode.serving.limits.overall",
+ "end_device.mac_settings.relay.mode.serving.limits.overall.bucket_size",
+ "end_device.mac_settings.relay.mode.serving.limits.overall.reload_rate",
+ "end_device.mac_settings.relay.mode.serving.limits.reset_behavior",
+ "end_device.mac_settings.relay.mode.serving.limits.uplink_messages",
+ "end_device.mac_settings.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device.mac_settings.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device.mac_settings.relay.mode.serving.second_channel",
+ "end_device.mac_settings.relay.mode.serving.second_channel.ack_offset",
+ "end_device.mac_settings.relay.mode.serving.second_channel.data_rate_index",
+ "end_device.mac_settings.relay.mode.serving.second_channel.frequency",
+ "end_device.mac_settings.relay.mode.serving.uplink_forwarding_rules",
"end_device.mac_settings.resets_f_cnt",
"end_device.mac_settings.resets_f_cnt.value",
"end_device.mac_settings.rx1_data_rate_offset",
@@ -2781,6 +4121,42 @@ var EndDeviceTemplateFieldPathsNested = []string{
"end_device.mac_state.current_parameters.ping_slot_frequency",
"end_device.mac_state.current_parameters.rejoin_count_periodicity",
"end_device.mac_state.current_parameters.rejoin_time_periodicity",
+ "end_device.mac_state.current_parameters.relay",
+ "end_device.mac_state.current_parameters.relay.mode",
+ "end_device.mac_state.current_parameters.relay.mode.served",
+ "end_device.mac_state.current_parameters.relay.mode.served.backoff",
+ "end_device.mac_state.current_parameters.relay.mode.served.mode",
+ "end_device.mac_state.current_parameters.relay.mode.served.mode.always",
+ "end_device.mac_state.current_parameters.relay.mode.served.mode.dynamic",
+ "end_device.mac_state.current_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device.mac_state.current_parameters.relay.mode.served.mode.end_device_controlled",
+ "end_device.mac_state.current_parameters.relay.mode.served.second_channel",
+ "end_device.mac_state.current_parameters.relay.mode.served.second_channel.ack_offset",
+ "end_device.mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index",
+ "end_device.mac_state.current_parameters.relay.mode.served.second_channel.frequency",
+ "end_device.mac_state.current_parameters.relay.mode.served.serving_device_id",
+ "end_device.mac_state.current_parameters.relay.mode.serving",
+ "end_device.mac_state.current_parameters.relay.mode.serving.cad_periodicity",
+ "end_device.mac_state.current_parameters.relay.mode.serving.default_channel_index",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.join_requests",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.notifications",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.overall",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.reset_behavior",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.uplink_messages",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device.mac_state.current_parameters.relay.mode.serving.second_channel",
+ "end_device.mac_state.current_parameters.relay.mode.serving.second_channel.ack_offset",
+ "end_device.mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "end_device.mac_state.current_parameters.relay.mode.serving.second_channel.frequency",
+ "end_device.mac_state.current_parameters.relay.mode.serving.uplink_forwarding_rules",
"end_device.mac_state.current_parameters.rx1_data_rate_offset",
"end_device.mac_state.current_parameters.rx1_delay",
"end_device.mac_state.current_parameters.rx2_data_rate_index",
@@ -2809,6 +4185,42 @@ var EndDeviceTemplateFieldPathsNested = []string{
"end_device.mac_state.desired_parameters.ping_slot_frequency",
"end_device.mac_state.desired_parameters.rejoin_count_periodicity",
"end_device.mac_state.desired_parameters.rejoin_time_periodicity",
+ "end_device.mac_state.desired_parameters.relay",
+ "end_device.mac_state.desired_parameters.relay.mode",
+ "end_device.mac_state.desired_parameters.relay.mode.served",
+ "end_device.mac_state.desired_parameters.relay.mode.served.backoff",
+ "end_device.mac_state.desired_parameters.relay.mode.served.mode",
+ "end_device.mac_state.desired_parameters.relay.mode.served.mode.always",
+ "end_device.mac_state.desired_parameters.relay.mode.served.mode.dynamic",
+ "end_device.mac_state.desired_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device.mac_state.desired_parameters.relay.mode.served.mode.end_device_controlled",
+ "end_device.mac_state.desired_parameters.relay.mode.served.second_channel",
+ "end_device.mac_state.desired_parameters.relay.mode.served.second_channel.ack_offset",
+ "end_device.mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index",
+ "end_device.mac_state.desired_parameters.relay.mode.served.second_channel.frequency",
+ "end_device.mac_state.desired_parameters.relay.mode.served.serving_device_id",
+ "end_device.mac_state.desired_parameters.relay.mode.serving",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.cad_periodicity",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.default_channel_index",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.join_requests",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.notifications",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.overall",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.reset_behavior",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.second_channel",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.second_channel.ack_offset",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.second_channel.frequency",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules",
"end_device.mac_state.desired_parameters.rx1_data_rate_offset",
"end_device.mac_state.desired_parameters.rx1_delay",
"end_device.mac_state.desired_parameters.rx2_data_rate_index",
@@ -2848,6 +4260,8 @@ var EndDeviceTemplateFieldPathsNested = []string{
"end_device.mac_state.pending_join_request.downlink_settings.rx1_dr_offset",
"end_device.mac_state.pending_join_request.downlink_settings.rx2_dr",
"end_device.mac_state.pending_join_request.rx_delay",
+ "end_device.mac_state.pending_relay_downlink",
+ "end_device.mac_state.pending_relay_downlink.raw_payload",
"end_device.mac_state.pending_requests",
"end_device.mac_state.ping_slot_periodicity",
"end_device.mac_state.ping_slot_periodicity.value",
@@ -2923,6 +4337,42 @@ var EndDeviceTemplateFieldPathsNested = []string{
"end_device.pending_mac_state.current_parameters.ping_slot_frequency",
"end_device.pending_mac_state.current_parameters.rejoin_count_periodicity",
"end_device.pending_mac_state.current_parameters.rejoin_time_periodicity",
+ "end_device.pending_mac_state.current_parameters.relay",
+ "end_device.pending_mac_state.current_parameters.relay.mode",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.backoff",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.mode",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.mode.always",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.mode.dynamic",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.mode.end_device_controlled",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.second_channel",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.second_channel.ack_offset",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.second_channel.frequency",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.serving_device_id",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.cad_periodicity",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.default_channel_index",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.notifications",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.overall",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.reset_behavior",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.second_channel",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.second_channel.ack_offset",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.second_channel.frequency",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.uplink_forwarding_rules",
"end_device.pending_mac_state.current_parameters.rx1_data_rate_offset",
"end_device.pending_mac_state.current_parameters.rx1_delay",
"end_device.pending_mac_state.current_parameters.rx2_data_rate_index",
@@ -2951,6 +4401,42 @@ var EndDeviceTemplateFieldPathsNested = []string{
"end_device.pending_mac_state.desired_parameters.ping_slot_frequency",
"end_device.pending_mac_state.desired_parameters.rejoin_count_periodicity",
"end_device.pending_mac_state.desired_parameters.rejoin_time_periodicity",
+ "end_device.pending_mac_state.desired_parameters.relay",
+ "end_device.pending_mac_state.desired_parameters.relay.mode",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.backoff",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.mode",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.mode.always",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.mode.dynamic",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.mode.end_device_controlled",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.second_channel",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.second_channel.ack_offset",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.second_channel.frequency",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.serving_device_id",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.cad_periodicity",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.default_channel_index",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.overall",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.reset_behavior",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.second_channel",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.second_channel.ack_offset",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.second_channel.frequency",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules",
"end_device.pending_mac_state.desired_parameters.rx1_data_rate_offset",
"end_device.pending_mac_state.desired_parameters.rx1_delay",
"end_device.pending_mac_state.desired_parameters.rx2_data_rate_index",
@@ -2990,6 +4476,8 @@ var EndDeviceTemplateFieldPathsNested = []string{
"end_device.pending_mac_state.pending_join_request.downlink_settings.rx1_dr_offset",
"end_device.pending_mac_state.pending_join_request.downlink_settings.rx2_dr",
"end_device.pending_mac_state.pending_join_request.rx_delay",
+ "end_device.pending_mac_state.pending_relay_downlink",
+ "end_device.pending_mac_state.pending_relay_downlink.raw_payload",
"end_device.pending_mac_state.pending_requests",
"end_device.pending_mac_state.ping_slot_periodicity",
"end_device.pending_mac_state.ping_slot_periodicity.value",
@@ -3442,6 +4930,7 @@ var MACState_UplinkMessage_RxMetadataFieldPathsNested = []string{
"gateway_ids.eui",
"gateway_ids.gateway_id",
"packet_broker",
+ "relay",
"snr",
"uplink_token",
}
@@ -3451,11 +4940,14 @@ var MACState_UplinkMessage_RxMetadataFieldPathsTopLevel = []string{
"downlink_path_constraint",
"gateway_ids",
"packet_broker",
+ "relay",
"snr",
"uplink_token",
}
var MACState_UplinkMessage_RxMetadata_PacketBrokerMetadataFieldPathsNested []string
var MACState_UplinkMessage_RxMetadata_PacketBrokerMetadataFieldPathsTopLevel []string
+var MACState_UplinkMessage_RxMetadata_RelayMetadataFieldPathsNested []string
+var MACState_UplinkMessage_RxMetadata_RelayMetadataFieldPathsTopLevel []string
var MACState_DownlinkMessage_MessageFieldPathsNested = []string{
"m_hdr",
"m_hdr.m_type",
diff --git a/pkg/ttnpb/end_device.pb.setters.fm.go b/pkg/ttnpb/end_device.pb.setters.fm.go
index 542781d369..a3d903fb27 100644
--- a/pkg/ttnpb/end_device.pb.setters.fm.go
+++ b/pkg/ttnpb/end_device.pb.setters.fm.go
@@ -128,6 +128,569 @@ func (dst *BoolValue) SetFields(src *BoolValue, paths ...string) error {
return nil
}
+func (dst *ServingRelayForwardingLimits) SetFields(src *ServingRelayForwardingLimits, paths ...string) error {
+ for name, subs := range _processPaths(paths) {
+ switch name {
+ case "reset_behavior":
+ if len(subs) > 0 {
+ return fmt.Errorf("'reset_behavior' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.ResetBehavior = src.ResetBehavior
+ } else {
+ dst.ResetBehavior = 0
+ }
+ case "join_requests":
+ if len(subs) > 0 {
+ var newDst, newSrc *RelayForwardLimits
+ if (src == nil || src.JoinRequests == nil) && dst.JoinRequests == nil {
+ continue
+ }
+ if src != nil {
+ newSrc = src.JoinRequests
+ }
+ if dst.JoinRequests != nil {
+ newDst = dst.JoinRequests
+ } else {
+ newDst = &RelayForwardLimits{}
+ dst.JoinRequests = newDst
+ }
+ if err := newDst.SetFields(newSrc, subs...); err != nil {
+ return err
+ }
+ } else {
+ if src != nil {
+ dst.JoinRequests = src.JoinRequests
+ } else {
+ dst.JoinRequests = nil
+ }
+ }
+ case "notifications":
+ if len(subs) > 0 {
+ var newDst, newSrc *RelayForwardLimits
+ if (src == nil || src.Notifications == nil) && dst.Notifications == nil {
+ continue
+ }
+ if src != nil {
+ newSrc = src.Notifications
+ }
+ if dst.Notifications != nil {
+ newDst = dst.Notifications
+ } else {
+ newDst = &RelayForwardLimits{}
+ dst.Notifications = newDst
+ }
+ if err := newDst.SetFields(newSrc, subs...); err != nil {
+ return err
+ }
+ } else {
+ if src != nil {
+ dst.Notifications = src.Notifications
+ } else {
+ dst.Notifications = nil
+ }
+ }
+ case "uplink_messages":
+ if len(subs) > 0 {
+ var newDst, newSrc *RelayForwardLimits
+ if (src == nil || src.UplinkMessages == nil) && dst.UplinkMessages == nil {
+ continue
+ }
+ if src != nil {
+ newSrc = src.UplinkMessages
+ }
+ if dst.UplinkMessages != nil {
+ newDst = dst.UplinkMessages
+ } else {
+ newDst = &RelayForwardLimits{}
+ dst.UplinkMessages = newDst
+ }
+ if err := newDst.SetFields(newSrc, subs...); err != nil {
+ return err
+ }
+ } else {
+ if src != nil {
+ dst.UplinkMessages = src.UplinkMessages
+ } else {
+ dst.UplinkMessages = nil
+ }
+ }
+ case "overall":
+ if len(subs) > 0 {
+ var newDst, newSrc *RelayForwardLimits
+ if (src == nil || src.Overall == nil) && dst.Overall == nil {
+ continue
+ }
+ if src != nil {
+ newSrc = src.Overall
+ }
+ if dst.Overall != nil {
+ newDst = dst.Overall
+ } else {
+ newDst = &RelayForwardLimits{}
+ dst.Overall = newDst
+ }
+ if err := newDst.SetFields(newSrc, subs...); err != nil {
+ return err
+ }
+ } else {
+ if src != nil {
+ dst.Overall = src.Overall
+ } else {
+ dst.Overall = nil
+ }
+ }
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *RelayUplinkForwardingRule) SetFields(src *RelayUplinkForwardingRule, paths ...string) error {
+ for name, subs := range _processPaths(paths) {
+ switch name {
+ case "limits":
+ if len(subs) > 0 {
+ var newDst, newSrc *RelayUplinkForwardLimits
+ if (src == nil || src.Limits == nil) && dst.Limits == nil {
+ continue
+ }
+ if src != nil {
+ newSrc = src.Limits
+ }
+ if dst.Limits != nil {
+ newDst = dst.Limits
+ } else {
+ newDst = &RelayUplinkForwardLimits{}
+ dst.Limits = newDst
+ }
+ if err := newDst.SetFields(newSrc, subs...); err != nil {
+ return err
+ }
+ } else {
+ if src != nil {
+ dst.Limits = src.Limits
+ } else {
+ dst.Limits = nil
+ }
+ }
+ case "last_w_f_cnt":
+ if len(subs) > 0 {
+ return fmt.Errorf("'last_w_f_cnt' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.LastWFCnt = src.LastWFCnt
+ } else {
+ var zero uint32
+ dst.LastWFCnt = zero
+ }
+ case "device_id":
+ if len(subs) > 0 {
+ return fmt.Errorf("'device_id' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.DeviceId = src.DeviceId
+ } else {
+ var zero string
+ dst.DeviceId = zero
+ }
+ case "session_key_id":
+ if len(subs) > 0 {
+ return fmt.Errorf("'session_key_id' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.SessionKeyId = src.SessionKeyId
+ } else {
+ dst.SessionKeyId = nil
+ }
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *ServingRelayParameters) SetFields(src *ServingRelayParameters, paths ...string) error {
+ for name, subs := range _processPaths(paths) {
+ switch name {
+ case "second_channel":
+ if len(subs) > 0 {
+ var newDst, newSrc *RelaySecondChannel
+ if (src == nil || src.SecondChannel == nil) && dst.SecondChannel == nil {
+ continue
+ }
+ if src != nil {
+ newSrc = src.SecondChannel
+ }
+ if dst.SecondChannel != nil {
+ newDst = dst.SecondChannel
+ } else {
+ newDst = &RelaySecondChannel{}
+ dst.SecondChannel = newDst
+ }
+ if err := newDst.SetFields(newSrc, subs...); err != nil {
+ return err
+ }
+ } else {
+ if src != nil {
+ dst.SecondChannel = src.SecondChannel
+ } else {
+ dst.SecondChannel = nil
+ }
+ }
+ case "default_channel_index":
+ if len(subs) > 0 {
+ return fmt.Errorf("'default_channel_index' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.DefaultChannelIndex = src.DefaultChannelIndex
+ } else {
+ var zero uint32
+ dst.DefaultChannelIndex = zero
+ }
+ case "cad_periodicity":
+ if len(subs) > 0 {
+ return fmt.Errorf("'cad_periodicity' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.CadPeriodicity = src.CadPeriodicity
+ } else {
+ dst.CadPeriodicity = 0
+ }
+ case "uplink_forwarding_rules":
+ if len(subs) > 0 {
+ return fmt.Errorf("'uplink_forwarding_rules' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.UplinkForwardingRules = src.UplinkForwardingRules
+ } else {
+ dst.UplinkForwardingRules = nil
+ }
+ case "limits":
+ if len(subs) > 0 {
+ var newDst, newSrc *ServingRelayForwardingLimits
+ if (src == nil || src.Limits == nil) && dst.Limits == nil {
+ continue
+ }
+ if src != nil {
+ newSrc = src.Limits
+ }
+ if dst.Limits != nil {
+ newDst = dst.Limits
+ } else {
+ newDst = &ServingRelayForwardingLimits{}
+ dst.Limits = newDst
+ }
+ if err := newDst.SetFields(newSrc, subs...); err != nil {
+ return err
+ }
+ } else {
+ if src != nil {
+ dst.Limits = src.Limits
+ } else {
+ dst.Limits = nil
+ }
+ }
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *ServedRelayParameters) SetFields(src *ServedRelayParameters, paths ...string) error {
+ for name, subs := range _processPaths(paths) {
+ switch name {
+ case "backoff":
+ if len(subs) > 0 {
+ return fmt.Errorf("'backoff' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.Backoff = src.Backoff
+ } else {
+ var zero uint32
+ dst.Backoff = zero
+ }
+ case "second_channel":
+ if len(subs) > 0 {
+ var newDst, newSrc *RelaySecondChannel
+ if (src == nil || src.SecondChannel == nil) && dst.SecondChannel == nil {
+ continue
+ }
+ if src != nil {
+ newSrc = src.SecondChannel
+ }
+ if dst.SecondChannel != nil {
+ newDst = dst.SecondChannel
+ } else {
+ newDst = &RelaySecondChannel{}
+ dst.SecondChannel = newDst
+ }
+ if err := newDst.SetFields(newSrc, subs...); err != nil {
+ return err
+ }
+ } else {
+ if src != nil {
+ dst.SecondChannel = src.SecondChannel
+ } else {
+ dst.SecondChannel = nil
+ }
+ }
+ case "serving_device_id":
+ if len(subs) > 0 {
+ return fmt.Errorf("'serving_device_id' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.ServingDeviceId = src.ServingDeviceId
+ } else {
+ var zero string
+ dst.ServingDeviceId = zero
+ }
+
+ case "mode":
+ if len(subs) == 0 && src == nil {
+ dst.Mode = nil
+ continue
+ } else if len(subs) == 0 {
+ dst.Mode = src.Mode
+ continue
+ }
+
+ subPathMap := _processPaths(subs)
+ if len(subPathMap) > 1 {
+ return fmt.Errorf("more than one field specified for oneof field '%s'", name)
+ }
+ for oneofName, oneofSubs := range subPathMap {
+ switch oneofName {
+ case "always":
+ var srcTypeOk bool
+ if src != nil {
+ _, srcTypeOk = src.Mode.(*ServedRelayParameters_Always)
+ }
+ if srcValid := srcTypeOk || src == nil || src.Mode == nil || len(oneofSubs) == 0; !srcValid {
+ return fmt.Errorf("attempt to set oneof 'always', while different oneof is set in source")
+ }
+ _, dstTypeOk := dst.Mode.(*ServedRelayParameters_Always)
+ if dstValid := dstTypeOk || dst.Mode == nil || len(oneofSubs) == 0; !dstValid {
+ return fmt.Errorf("attempt to set oneof 'always', while different oneof is set in destination")
+ }
+ if len(oneofSubs) > 0 {
+ var newDst, newSrc *RelayEndDeviceAlwaysMode
+ if srcTypeOk {
+ newSrc = src.Mode.(*ServedRelayParameters_Always).Always
+ }
+ if dstTypeOk {
+ newDst = dst.Mode.(*ServedRelayParameters_Always).Always
+ } else if srcTypeOk {
+ newDst = &RelayEndDeviceAlwaysMode{}
+ dst.Mode = &ServedRelayParameters_Always{Always: newDst}
+ } else {
+ dst.Mode = nil
+ continue
+ }
+ if err := newDst.SetFields(newSrc, oneofSubs...); err != nil {
+ return err
+ }
+ } else {
+ if srcTypeOk {
+ dst.Mode = src.Mode
+ } else {
+ dst.Mode = nil
+ }
+ }
+ case "dynamic":
+ var srcTypeOk bool
+ if src != nil {
+ _, srcTypeOk = src.Mode.(*ServedRelayParameters_Dynamic)
+ }
+ if srcValid := srcTypeOk || src == nil || src.Mode == nil || len(oneofSubs) == 0; !srcValid {
+ return fmt.Errorf("attempt to set oneof 'dynamic', while different oneof is set in source")
+ }
+ _, dstTypeOk := dst.Mode.(*ServedRelayParameters_Dynamic)
+ if dstValid := dstTypeOk || dst.Mode == nil || len(oneofSubs) == 0; !dstValid {
+ return fmt.Errorf("attempt to set oneof 'dynamic', while different oneof is set in destination")
+ }
+ if len(oneofSubs) > 0 {
+ var newDst, newSrc *RelayEndDeviceDynamicMode
+ if srcTypeOk {
+ newSrc = src.Mode.(*ServedRelayParameters_Dynamic).Dynamic
+ }
+ if dstTypeOk {
+ newDst = dst.Mode.(*ServedRelayParameters_Dynamic).Dynamic
+ } else if srcTypeOk {
+ newDst = &RelayEndDeviceDynamicMode{}
+ dst.Mode = &ServedRelayParameters_Dynamic{Dynamic: newDst}
+ } else {
+ dst.Mode = nil
+ continue
+ }
+ if err := newDst.SetFields(newSrc, oneofSubs...); err != nil {
+ return err
+ }
+ } else {
+ if srcTypeOk {
+ dst.Mode = src.Mode
+ } else {
+ dst.Mode = nil
+ }
+ }
+ case "end_device_controlled":
+ var srcTypeOk bool
+ if src != nil {
+ _, srcTypeOk = src.Mode.(*ServedRelayParameters_EndDeviceControlled)
+ }
+ if srcValid := srcTypeOk || src == nil || src.Mode == nil || len(oneofSubs) == 0; !srcValid {
+ return fmt.Errorf("attempt to set oneof 'end_device_controlled', while different oneof is set in source")
+ }
+ _, dstTypeOk := dst.Mode.(*ServedRelayParameters_EndDeviceControlled)
+ if dstValid := dstTypeOk || dst.Mode == nil || len(oneofSubs) == 0; !dstValid {
+ return fmt.Errorf("attempt to set oneof 'end_device_controlled', while different oneof is set in destination")
+ }
+ if len(oneofSubs) > 0 {
+ var newDst, newSrc *RelayEndDeviceControlledMode
+ if srcTypeOk {
+ newSrc = src.Mode.(*ServedRelayParameters_EndDeviceControlled).EndDeviceControlled
+ }
+ if dstTypeOk {
+ newDst = dst.Mode.(*ServedRelayParameters_EndDeviceControlled).EndDeviceControlled
+ } else if srcTypeOk {
+ newDst = &RelayEndDeviceControlledMode{}
+ dst.Mode = &ServedRelayParameters_EndDeviceControlled{EndDeviceControlled: newDst}
+ } else {
+ dst.Mode = nil
+ continue
+ }
+ if err := newDst.SetFields(newSrc, oneofSubs...); err != nil {
+ return err
+ }
+ } else {
+ if srcTypeOk {
+ dst.Mode = src.Mode
+ } else {
+ dst.Mode = nil
+ }
+ }
+
+ default:
+ return fmt.Errorf("invalid oneof field: '%s.%s'", name, oneofName)
+ }
+ }
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *RelayParameters) SetFields(src *RelayParameters, paths ...string) error {
+ for name, subs := range _processPaths(paths) {
+ switch name {
+
+ case "mode":
+ if len(subs) == 0 && src == nil {
+ dst.Mode = nil
+ continue
+ } else if len(subs) == 0 {
+ dst.Mode = src.Mode
+ continue
+ }
+
+ subPathMap := _processPaths(subs)
+ if len(subPathMap) > 1 {
+ return fmt.Errorf("more than one field specified for oneof field '%s'", name)
+ }
+ for oneofName, oneofSubs := range subPathMap {
+ switch oneofName {
+ case "serving":
+ var srcTypeOk bool
+ if src != nil {
+ _, srcTypeOk = src.Mode.(*RelayParameters_Serving)
+ }
+ if srcValid := srcTypeOk || src == nil || src.Mode == nil || len(oneofSubs) == 0; !srcValid {
+ return fmt.Errorf("attempt to set oneof 'serving', while different oneof is set in source")
+ }
+ _, dstTypeOk := dst.Mode.(*RelayParameters_Serving)
+ if dstValid := dstTypeOk || dst.Mode == nil || len(oneofSubs) == 0; !dstValid {
+ return fmt.Errorf("attempt to set oneof 'serving', while different oneof is set in destination")
+ }
+ if len(oneofSubs) > 0 {
+ var newDst, newSrc *ServingRelayParameters
+ if srcTypeOk {
+ newSrc = src.Mode.(*RelayParameters_Serving).Serving
+ }
+ if dstTypeOk {
+ newDst = dst.Mode.(*RelayParameters_Serving).Serving
+ } else if srcTypeOk {
+ newDst = &ServingRelayParameters{}
+ dst.Mode = &RelayParameters_Serving{Serving: newDst}
+ } else {
+ dst.Mode = nil
+ continue
+ }
+ if err := newDst.SetFields(newSrc, oneofSubs...); err != nil {
+ return err
+ }
+ } else {
+ if srcTypeOk {
+ dst.Mode = src.Mode
+ } else {
+ dst.Mode = nil
+ }
+ }
+ case "served":
+ var srcTypeOk bool
+ if src != nil {
+ _, srcTypeOk = src.Mode.(*RelayParameters_Served)
+ }
+ if srcValid := srcTypeOk || src == nil || src.Mode == nil || len(oneofSubs) == 0; !srcValid {
+ return fmt.Errorf("attempt to set oneof 'served', while different oneof is set in source")
+ }
+ _, dstTypeOk := dst.Mode.(*RelayParameters_Served)
+ if dstValid := dstTypeOk || dst.Mode == nil || len(oneofSubs) == 0; !dstValid {
+ return fmt.Errorf("attempt to set oneof 'served', while different oneof is set in destination")
+ }
+ if len(oneofSubs) > 0 {
+ var newDst, newSrc *ServedRelayParameters
+ if srcTypeOk {
+ newSrc = src.Mode.(*RelayParameters_Served).Served
+ }
+ if dstTypeOk {
+ newDst = dst.Mode.(*RelayParameters_Served).Served
+ } else if srcTypeOk {
+ newDst = &ServedRelayParameters{}
+ dst.Mode = &RelayParameters_Served{Served: newDst}
+ } else {
+ dst.Mode = nil
+ continue
+ }
+ if err := newDst.SetFields(newSrc, oneofSubs...); err != nil {
+ return err
+ }
+ } else {
+ if srcTypeOk {
+ dst.Mode = src.Mode
+ } else {
+ dst.Mode = nil
+ }
+ }
+
+ default:
+ return fmt.Errorf("invalid oneof field: '%s.%s'", name, oneofName)
+ }
+ }
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
func (dst *MACParameters) SetFields(src *MACParameters, paths ...string) error {
for name, subs := range _processPaths(paths) {
switch name {
@@ -417,6 +980,31 @@ func (dst *MACParameters) SetFields(src *MACParameters, paths ...string) error {
dst.PingSlotDataRateIndexValue = nil
}
}
+ case "relay":
+ if len(subs) > 0 {
+ var newDst, newSrc *RelayParameters
+ if (src == nil || src.Relay == nil) && dst.Relay == nil {
+ continue
+ }
+ if src != nil {
+ newSrc = src.Relay
+ }
+ if dst.Relay != nil {
+ newDst = dst.Relay
+ } else {
+ newDst = &RelayParameters{}
+ dst.Relay = newDst
+ }
+ if err := newDst.SetFields(newSrc, subs...); err != nil {
+ return err
+ }
+ } else {
+ if src != nil {
+ dst.Relay = src.Relay
+ } else {
+ dst.Relay = nil
+ }
+ }
default:
return fmt.Errorf("invalid field: '%s'", name)
@@ -1489,6 +2077,56 @@ func (dst *MACSettings) SetFields(src *MACSettings, paths ...string) error {
dst.ScheduleDownlinks = nil
}
}
+ case "relay":
+ if len(subs) > 0 {
+ var newDst, newSrc *RelayParameters
+ if (src == nil || src.Relay == nil) && dst.Relay == nil {
+ continue
+ }
+ if src != nil {
+ newSrc = src.Relay
+ }
+ if dst.Relay != nil {
+ newDst = dst.Relay
+ } else {
+ newDst = &RelayParameters{}
+ dst.Relay = newDst
+ }
+ if err := newDst.SetFields(newSrc, subs...); err != nil {
+ return err
+ }
+ } else {
+ if src != nil {
+ dst.Relay = src.Relay
+ } else {
+ dst.Relay = nil
+ }
+ }
+ case "desired_relay":
+ if len(subs) > 0 {
+ var newDst, newSrc *RelayParameters
+ if (src == nil || src.DesiredRelay == nil) && dst.DesiredRelay == nil {
+ continue
+ }
+ if src != nil {
+ newSrc = src.DesiredRelay
+ }
+ if dst.DesiredRelay != nil {
+ newDst = dst.DesiredRelay
+ } else {
+ newDst = &RelayParameters{}
+ dst.DesiredRelay = newDst
+ }
+ if err := newDst.SetFields(newSrc, subs...); err != nil {
+ return err
+ }
+ } else {
+ if src != nil {
+ dst.DesiredRelay = src.DesiredRelay
+ } else {
+ dst.DesiredRelay = nil
+ }
+ }
default:
return fmt.Errorf("invalid field: '%s'", name)
@@ -1806,6 +2444,31 @@ func (dst *MACState) SetFields(src *MACState, paths ...string) error {
} else {
dst.RecentMacCommandIdentifiers = nil
}
+ case "pending_relay_downlink":
+ if len(subs) > 0 {
+ var newDst, newSrc *RelayForwardDownlinkReq
+ if (src == nil || src.PendingRelayDownlink == nil) && dst.PendingRelayDownlink == nil {
+ continue
+ }
+ if src != nil {
+ newSrc = src.PendingRelayDownlink
+ }
+ if dst.PendingRelayDownlink != nil {
+ newDst = dst.PendingRelayDownlink
+ } else {
+ newDst = &RelayForwardDownlinkReq{}
+ dst.PendingRelayDownlink = newDst
+ }
+ if err := newDst.SetFields(newSrc, subs...); err != nil {
+ return err
+ }
+ } else {
+ if src != nil {
+ dst.PendingRelayDownlink = src.PendingRelayDownlink
+ } else {
+ dst.PendingRelayDownlink = nil
+ }
+ }
default:
return fmt.Errorf("invalid field: '%s'", name)
@@ -4058,6 +4721,31 @@ func (dst *MACState_UplinkMessage_RxMetadata) SetFields(src *MACState_UplinkMess
dst.PacketBroker = nil
}
}
+ case "relay":
+ if len(subs) > 0 {
+ var newDst, newSrc *MACState_UplinkMessage_RxMetadata_RelayMetadata
+ if (src == nil || src.Relay == nil) && dst.Relay == nil {
+ continue
+ }
+ if src != nil {
+ newSrc = src.Relay
+ }
+ if dst.Relay != nil {
+ newDst = dst.Relay
+ } else {
+ newDst = &MACState_UplinkMessage_RxMetadata_RelayMetadata{}
+ dst.Relay = newDst
+ }
+ if err := newDst.SetFields(newSrc, subs...); err != nil {
+ return err
+ }
+ } else {
+ if src != nil {
+ dst.Relay = src.Relay
+ } else {
+ dst.Relay = nil
+ }
+ }
default:
return fmt.Errorf("invalid field: '%s'", name)
@@ -4073,6 +4761,13 @@ func (dst *MACState_UplinkMessage_RxMetadata_PacketBrokerMetadata) SetFields(src
return nil
}
+func (dst *MACState_UplinkMessage_RxMetadata_RelayMetadata) SetFields(src *MACState_UplinkMessage_RxMetadata_RelayMetadata, paths ...string) error {
+ if len(paths) != 0 {
+ return fmt.Errorf("message MACState_UplinkMessage_RxMetadata_RelayMetadata has no fields, but paths %s were specified", paths)
+ }
+ return nil
+}
+
func (dst *MACState_DownlinkMessage_Message) SetFields(src *MACState_DownlinkMessage_Message, paths ...string) error {
for name, subs := range _processPaths(paths) {
switch name {
diff --git a/pkg/ttnpb/end_device.pb.validate.go b/pkg/ttnpb/end_device.pb.validate.go
index 45654db403..f9f236ff2b 100644
--- a/pkg/ttnpb/end_device.pb.validate.go
+++ b/pkg/ttnpb/end_device.pb.validate.go
@@ -261,6 +261,718 @@ var _ interface {
ErrorName() string
} = BoolValueValidationError{}
+// ValidateFields checks the field values on ServingRelayForwardingLimits with
+// the rules defined in the proto definition for this message. If any rules
+// are violated, an error is returned.
+func (m *ServingRelayForwardingLimits) ValidateFields(paths ...string) error {
+ if m == nil {
+ return nil
+ }
+
+ if len(paths) == 0 {
+ paths = ServingRelayForwardingLimitsFieldPathsNested
+ }
+
+ for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
+ _ = subs
+ switch name {
+ case "reset_behavior":
+ // no validation rules for ResetBehavior
+ case "join_requests":
+
+ if v, ok := interface{}(m.GetJoinRequests()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return ServingRelayForwardingLimitsValidationError{
+ field: "join_requests",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "notifications":
+
+ if v, ok := interface{}(m.GetNotifications()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return ServingRelayForwardingLimitsValidationError{
+ field: "notifications",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "uplink_messages":
+
+ if v, ok := interface{}(m.GetUplinkMessages()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return ServingRelayForwardingLimitsValidationError{
+ field: "uplink_messages",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "overall":
+
+ if v, ok := interface{}(m.GetOverall()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return ServingRelayForwardingLimitsValidationError{
+ field: "overall",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ default:
+ return ServingRelayForwardingLimitsValidationError{
+ field: name,
+ reason: "invalid field path",
+ }
+ }
+ }
+ return nil
+}
+
+// ServingRelayForwardingLimitsValidationError is the validation error returned
+// by ServingRelayForwardingLimits.ValidateFields if the designated
+// constraints aren't met.
+type ServingRelayForwardingLimitsValidationError struct {
+ field string
+ reason string
+ cause error
+ key bool
+}
+
+// Field function returns field value.
+func (e ServingRelayForwardingLimitsValidationError) Field() string { return e.field }
+
+// Reason function returns reason value.
+func (e ServingRelayForwardingLimitsValidationError) Reason() string { return e.reason }
+
+// Cause function returns cause value.
+func (e ServingRelayForwardingLimitsValidationError) Cause() error { return e.cause }
+
+// Key function returns key value.
+func (e ServingRelayForwardingLimitsValidationError) Key() bool { return e.key }
+
+// ErrorName returns error name.
+func (e ServingRelayForwardingLimitsValidationError) ErrorName() string {
+ return "ServingRelayForwardingLimitsValidationError"
+}
+
+// Error satisfies the builtin error interface
+func (e ServingRelayForwardingLimitsValidationError) Error() string {
+ cause := ""
+ if e.cause != nil {
+ cause = fmt.Sprintf(" | caused by: %v", e.cause)
+ }
+
+ key := ""
+ if e.key {
+ key = "key for "
+ }
+
+ return fmt.Sprintf(
+ "invalid %sServingRelayForwardingLimits.%s: %s%s",
+ key,
+ e.field,
+ e.reason,
+ cause)
+}
+
+var _ error = ServingRelayForwardingLimitsValidationError{}
+
+var _ interface {
+ Field() string
+ Reason() string
+ Key() bool
+ Cause() error
+ ErrorName() string
+} = ServingRelayForwardingLimitsValidationError{}
+
+// ValidateFields checks the field values on RelayUplinkForwardingRule with the
+// rules defined in the proto definition for this message. If any rules are
+// violated, an error is returned.
+func (m *RelayUplinkForwardingRule) ValidateFields(paths ...string) error {
+ if m == nil {
+ return nil
+ }
+
+ if len(paths) == 0 {
+ paths = RelayUplinkForwardingRuleFieldPathsNested
+ }
+
+ for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
+ _ = subs
+ switch name {
+ case "limits":
+
+ if v, ok := interface{}(m.GetLimits()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return RelayUplinkForwardingRuleValidationError{
+ field: "limits",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "last_w_f_cnt":
+ // no validation rules for LastWFCnt
+ case "device_id":
+
+ if m.GetDeviceId() != "" {
+
+ if utf8.RuneCountInString(m.GetDeviceId()) > 36 {
+ return RelayUplinkForwardingRuleValidationError{
+ field: "device_id",
+ reason: "value length must be at most 36 runes",
+ }
+ }
+
+ if !_RelayUplinkForwardingRule_DeviceId_Pattern.MatchString(m.GetDeviceId()) {
+ return RelayUplinkForwardingRuleValidationError{
+ field: "device_id",
+ reason: "value does not match regex pattern \"^[a-z0-9](?:[-]?[a-z0-9]){2,}$\"",
+ }
+ }
+
+ }
+
+ case "session_key_id":
+ // no validation rules for SessionKeyId
+ default:
+ return RelayUplinkForwardingRuleValidationError{
+ field: name,
+ reason: "invalid field path",
+ }
+ }
+ }
+ return nil
+}
+
+// RelayUplinkForwardingRuleValidationError is the validation error returned by
+// RelayUplinkForwardingRule.ValidateFields if the designated constraints
+// aren't met.
+type RelayUplinkForwardingRuleValidationError struct {
+ field string
+ reason string
+ cause error
+ key bool
+}
+
+// Field function returns field value.
+func (e RelayUplinkForwardingRuleValidationError) Field() string { return e.field }
+
+// Reason function returns reason value.
+func (e RelayUplinkForwardingRuleValidationError) Reason() string { return e.reason }
+
+// Cause function returns cause value.
+func (e RelayUplinkForwardingRuleValidationError) Cause() error { return e.cause }
+
+// Key function returns key value.
+func (e RelayUplinkForwardingRuleValidationError) Key() bool { return e.key }
+
+// ErrorName returns error name.
+func (e RelayUplinkForwardingRuleValidationError) ErrorName() string {
+ return "RelayUplinkForwardingRuleValidationError"
+}
+
+// Error satisfies the builtin error interface
+func (e RelayUplinkForwardingRuleValidationError) Error() string {
+ cause := ""
+ if e.cause != nil {
+ cause = fmt.Sprintf(" | caused by: %v", e.cause)
+ }
+
+ key := ""
+ if e.key {
+ key = "key for "
+ }
+
+ return fmt.Sprintf(
+ "invalid %sRelayUplinkForwardingRule.%s: %s%s",
+ key,
+ e.field,
+ e.reason,
+ cause)
+}
+
+var _ error = RelayUplinkForwardingRuleValidationError{}
+
+var _ interface {
+ Field() string
+ Reason() string
+ Key() bool
+ Cause() error
+ ErrorName() string
+} = RelayUplinkForwardingRuleValidationError{}
+
+var _RelayUplinkForwardingRule_DeviceId_Pattern = regexp.MustCompile("^[a-z0-9](?:[-]?[a-z0-9]){2,}$")
+
+// ValidateFields checks the field values on ServingRelayParameters with the
+// rules defined in the proto definition for this message. If any rules are
+// violated, an error is returned.
+func (m *ServingRelayParameters) ValidateFields(paths ...string) error {
+ if m == nil {
+ return nil
+ }
+
+ if len(paths) == 0 {
+ paths = ServingRelayParametersFieldPathsNested
+ }
+
+ for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
+ _ = subs
+ switch name {
+ case "second_channel":
+
+ if v, ok := interface{}(m.GetSecondChannel()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return ServingRelayParametersValidationError{
+ field: "second_channel",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "default_channel_index":
+
+ if m.GetDefaultChannelIndex() > 255 {
+ return ServingRelayParametersValidationError{
+ field: "default_channel_index",
+ reason: "value must be less than or equal to 255",
+ }
+ }
+
+ case "cad_periodicity":
+
+ if _, ok := RelayCADPeriodicity_name[int32(m.GetCadPeriodicity())]; !ok {
+ return ServingRelayParametersValidationError{
+ field: "cad_periodicity",
+ reason: "value must be one of the defined enum values",
+ }
+ }
+
+ case "uplink_forwarding_rules":
+
+ if len(m.GetUplinkForwardingRules()) > 16 {
+ return ServingRelayParametersValidationError{
+ field: "uplink_forwarding_rules",
+ reason: "value must contain no more than 16 item(s)",
+ }
+ }
+
+ for idx, item := range m.GetUplinkForwardingRules() {
+ _, _ = idx, item
+
+ if v, ok := interface{}(item).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return ServingRelayParametersValidationError{
+ field: fmt.Sprintf("uplink_forwarding_rules[%v]", idx),
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ }
+
+ case "limits":
+
+ if v, ok := interface{}(m.GetLimits()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return ServingRelayParametersValidationError{
+ field: "limits",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ default:
+ return ServingRelayParametersValidationError{
+ field: name,
+ reason: "invalid field path",
+ }
+ }
+ }
+ return nil
+}
+
+// ServingRelayParametersValidationError is the validation error returned by
+// ServingRelayParameters.ValidateFields if the designated constraints aren't met.
+type ServingRelayParametersValidationError struct {
+ field string
+ reason string
+ cause error
+ key bool
+}
+
+// Field function returns field value.
+func (e ServingRelayParametersValidationError) Field() string { return e.field }
+
+// Reason function returns reason value.
+func (e ServingRelayParametersValidationError) Reason() string { return e.reason }
+
+// Cause function returns cause value.
+func (e ServingRelayParametersValidationError) Cause() error { return e.cause }
+
+// Key function returns key value.
+func (e ServingRelayParametersValidationError) Key() bool { return e.key }
+
+// ErrorName returns error name.
+func (e ServingRelayParametersValidationError) ErrorName() string {
+ return "ServingRelayParametersValidationError"
+}
+
+// Error satisfies the builtin error interface
+func (e ServingRelayParametersValidationError) Error() string {
+ cause := ""
+ if e.cause != nil {
+ cause = fmt.Sprintf(" | caused by: %v", e.cause)
+ }
+
+ key := ""
+ if e.key {
+ key = "key for "
+ }
+
+ return fmt.Sprintf(
+ "invalid %sServingRelayParameters.%s: %s%s",
+ key,
+ e.field,
+ e.reason,
+ cause)
+}
+
+var _ error = ServingRelayParametersValidationError{}
+
+var _ interface {
+ Field() string
+ Reason() string
+ Key() bool
+ Cause() error
+ ErrorName() string
+} = ServingRelayParametersValidationError{}
+
+// ValidateFields checks the field values on ServedRelayParameters with the
+// rules defined in the proto definition for this message. If any rules are
+// violated, an error is returned.
+func (m *ServedRelayParameters) ValidateFields(paths ...string) error {
+ if m == nil {
+ return nil
+ }
+
+ if len(paths) == 0 {
+ paths = ServedRelayParametersFieldPathsNested
+ }
+
+ for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
+ _ = subs
+ switch name {
+ case "backoff":
+
+ if m.GetBackoff() > 63 {
+ return ServedRelayParametersValidationError{
+ field: "backoff",
+ reason: "value must be less than or equal to 63",
+ }
+ }
+
+ case "second_channel":
+
+ if v, ok := interface{}(m.GetSecondChannel()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return ServedRelayParametersValidationError{
+ field: "second_channel",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "serving_device_id":
+
+ if utf8.RuneCountInString(m.GetServingDeviceId()) > 36 {
+ return ServedRelayParametersValidationError{
+ field: "serving_device_id",
+ reason: "value length must be at most 36 runes",
+ }
+ }
+
+ if !_ServedRelayParameters_ServingDeviceId_Pattern.MatchString(m.GetServingDeviceId()) {
+ return ServedRelayParametersValidationError{
+ field: "serving_device_id",
+ reason: "value does not match regex pattern \"^[a-z0-9](?:[-]?[a-z0-9]){2,}$\"",
+ }
+ }
+
+ case "mode":
+ if m.Mode == nil {
+ return ServedRelayParametersValidationError{
+ field: "mode",
+ reason: "value is required",
+ }
+ }
+ if len(subs) == 0 {
+ subs = []string{
+ "always", "dynamic", "end_device_controlled",
+ }
+ }
+ for name, subs := range _processPaths(subs) {
+ _ = subs
+ switch name {
+ case "always":
+ w, ok := m.Mode.(*ServedRelayParameters_Always)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetAlways()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return ServedRelayParametersValidationError{
+ field: "always",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "dynamic":
+ w, ok := m.Mode.(*ServedRelayParameters_Dynamic)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetDynamic()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return ServedRelayParametersValidationError{
+ field: "dynamic",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "end_device_controlled":
+ w, ok := m.Mode.(*ServedRelayParameters_EndDeviceControlled)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetEndDeviceControlled()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return ServedRelayParametersValidationError{
+ field: "end_device_controlled",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ }
+ }
+ default:
+ return ServedRelayParametersValidationError{
+ field: name,
+ reason: "invalid field path",
+ }
+ }
+ }
+ return nil
+}
+
+// ServedRelayParametersValidationError is the validation error returned by
+// ServedRelayParameters.ValidateFields if the designated constraints aren't met.
+type ServedRelayParametersValidationError struct {
+ field string
+ reason string
+ cause error
+ key bool
+}
+
+// Field function returns field value.
+func (e ServedRelayParametersValidationError) Field() string { return e.field }
+
+// Reason function returns reason value.
+func (e ServedRelayParametersValidationError) Reason() string { return e.reason }
+
+// Cause function returns cause value.
+func (e ServedRelayParametersValidationError) Cause() error { return e.cause }
+
+// Key function returns key value.
+func (e ServedRelayParametersValidationError) Key() bool { return e.key }
+
+// ErrorName returns error name.
+func (e ServedRelayParametersValidationError) ErrorName() string {
+ return "ServedRelayParametersValidationError"
+}
+
+// Error satisfies the builtin error interface
+func (e ServedRelayParametersValidationError) Error() string {
+ cause := ""
+ if e.cause != nil {
+ cause = fmt.Sprintf(" | caused by: %v", e.cause)
+ }
+
+ key := ""
+ if e.key {
+ key = "key for "
+ }
+
+ return fmt.Sprintf(
+ "invalid %sServedRelayParameters.%s: %s%s",
+ key,
+ e.field,
+ e.reason,
+ cause)
+}
+
+var _ error = ServedRelayParametersValidationError{}
+
+var _ interface {
+ Field() string
+ Reason() string
+ Key() bool
+ Cause() error
+ ErrorName() string
+} = ServedRelayParametersValidationError{}
+
+var _ServedRelayParameters_ServingDeviceId_Pattern = regexp.MustCompile("^[a-z0-9](?:[-]?[a-z0-9]){2,}$")
+
+// ValidateFields checks the field values on RelayParameters with the rules
+// defined in the proto definition for this message. If any rules are
+// violated, an error is returned.
+func (m *RelayParameters) ValidateFields(paths ...string) error {
+ if m == nil {
+ return nil
+ }
+
+ if len(paths) == 0 {
+ paths = RelayParametersFieldPathsNested
+ }
+
+ for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
+ _ = subs
+ switch name {
+ case "mode":
+ if m.Mode == nil {
+ return RelayParametersValidationError{
+ field: "mode",
+ reason: "value is required",
+ }
+ }
+ if len(subs) == 0 {
+ subs = []string{
+ "serving", "served",
+ }
+ }
+ for name, subs := range _processPaths(subs) {
+ _ = subs
+ switch name {
+ case "serving":
+ w, ok := m.Mode.(*RelayParameters_Serving)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetServing()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return RelayParametersValidationError{
+ field: "serving",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "served":
+ w, ok := m.Mode.(*RelayParameters_Served)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetServed()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return RelayParametersValidationError{
+ field: "served",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ }
+ }
+ default:
+ return RelayParametersValidationError{
+ field: name,
+ reason: "invalid field path",
+ }
+ }
+ }
+ return nil
+}
+
+// RelayParametersValidationError is the validation error returned by
+// RelayParameters.ValidateFields if the designated constraints aren't met.
+type RelayParametersValidationError struct {
+ field string
+ reason string
+ cause error
+ key bool
+}
+
+// Field function returns field value.
+func (e RelayParametersValidationError) Field() string { return e.field }
+
+// Reason function returns reason value.
+func (e RelayParametersValidationError) Reason() string { return e.reason }
+
+// Cause function returns cause value.
+func (e RelayParametersValidationError) Cause() error { return e.cause }
+
+// Key function returns key value.
+func (e RelayParametersValidationError) Key() bool { return e.key }
+
+// ErrorName returns error name.
+func (e RelayParametersValidationError) ErrorName() string { return "RelayParametersValidationError" }
+
+// Error satisfies the builtin error interface
+func (e RelayParametersValidationError) Error() string {
+ cause := ""
+ if e.cause != nil {
+ cause = fmt.Sprintf(" | caused by: %v", e.cause)
+ }
+
+ key := ""
+ if e.key {
+ key = "key for "
+ }
+
+ return fmt.Sprintf(
+ "invalid %sRelayParameters.%s: %s%s",
+ key,
+ e.field,
+ e.reason,
+ cause)
+}
+
+var _ error = RelayParametersValidationError{}
+
+var _ interface {
+ Field() string
+ Reason() string
+ Key() bool
+ Cause() error
+ ErrorName() string
+} = RelayParametersValidationError{}
+
// ValidateFields checks the field values on MACParameters with the rules
// defined in the proto definition for this message. If any rules are
// violated, an error is returned.
@@ -476,6 +1188,18 @@ func (m *MACParameters) ValidateFields(paths ...string) error {
}
}
+ case "relay":
+
+ if v, ok := interface{}(m.GetRelay()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACParametersValidationError{
+ field: "relay",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
default:
return MACParametersValidationError{
field: name,
@@ -1275,6 +1999,30 @@ func (m *MACSettings) ValidateFields(paths ...string) error {
}
}
+ case "relay":
+
+ if v, ok := interface{}(m.GetRelay()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACSettingsValidationError{
+ field: "relay",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "desired_relay":
+
+ if v, ok := interface{}(m.GetDesiredRelay()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACSettingsValidationError{
+ field: "desired_relay",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
default:
return MACSettingsValidationError{
field: name,
@@ -1645,6 +2393,18 @@ func (m *MACState) ValidateFields(paths ...string) error {
// no validation rules for LastAdrChangeFCntUp
case "recent_mac_command_identifiers":
+ case "pending_relay_downlink":
+
+ if v, ok := interface{}(m.GetPendingRelayDownlink()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACStateValidationError{
+ field: "pending_relay_downlink",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
default:
return MACStateValidationError{
field: name,
@@ -5984,6 +6744,18 @@ func (m *MACState_UplinkMessage_RxMetadata) ValidateFields(paths ...string) erro
}
}
+ case "relay":
+
+ if v, ok := interface{}(m.GetRelay()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACState_UplinkMessage_RxMetadataValidationError{
+ field: "relay",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
default:
return MACState_UplinkMessage_RxMetadataValidationError{
field: name,
@@ -6128,6 +6900,79 @@ var _ interface {
ErrorName() string
} = MACState_UplinkMessage_RxMetadata_PacketBrokerMetadataValidationError{}
+// ValidateFields checks the field values on
+// MACState_UplinkMessage_RxMetadata_RelayMetadata with the rules defined in
+// the proto definition for this message. If any rules are violated, an error
+// is returned.
+func (m *MACState_UplinkMessage_RxMetadata_RelayMetadata) ValidateFields(paths ...string) error {
+ if len(paths) > 0 {
+ return fmt.Errorf("message MACState_UplinkMessage_RxMetadata_RelayMetadata has no fields, but paths %s were specified", paths)
+ }
+ return nil
+}
+
+// MACState_UplinkMessage_RxMetadata_RelayMetadataValidationError is the
+// validation error returned by
+// MACState_UplinkMessage_RxMetadata_RelayMetadata.ValidateFields if the
+// designated constraints aren't met.
+type MACState_UplinkMessage_RxMetadata_RelayMetadataValidationError struct {
+ field string
+ reason string
+ cause error
+ key bool
+}
+
+// Field function returns field value.
+func (e MACState_UplinkMessage_RxMetadata_RelayMetadataValidationError) Field() string {
+ return e.field
+}
+
+// Reason function returns reason value.
+func (e MACState_UplinkMessage_RxMetadata_RelayMetadataValidationError) Reason() string {
+ return e.reason
+}
+
+// Cause function returns cause value.
+func (e MACState_UplinkMessage_RxMetadata_RelayMetadataValidationError) Cause() error { return e.cause }
+
+// Key function returns key value.
+func (e MACState_UplinkMessage_RxMetadata_RelayMetadataValidationError) Key() bool { return e.key }
+
+// ErrorName returns error name.
+func (e MACState_UplinkMessage_RxMetadata_RelayMetadataValidationError) ErrorName() string {
+ return "MACState_UplinkMessage_RxMetadata_RelayMetadataValidationError"
+}
+
+// Error satisfies the builtin error interface
+func (e MACState_UplinkMessage_RxMetadata_RelayMetadataValidationError) Error() string {
+ cause := ""
+ if e.cause != nil {
+ cause = fmt.Sprintf(" | caused by: %v", e.cause)
+ }
+
+ key := ""
+ if e.key {
+ key = "key for "
+ }
+
+ return fmt.Sprintf(
+ "invalid %sMACState_UplinkMessage_RxMetadata_RelayMetadata.%s: %s%s",
+ key,
+ e.field,
+ e.reason,
+ cause)
+}
+
+var _ error = MACState_UplinkMessage_RxMetadata_RelayMetadataValidationError{}
+
+var _ interface {
+ Field() string
+ Reason() string
+ Key() bool
+ Cause() error
+ ErrorName() string
+} = MACState_UplinkMessage_RxMetadata_RelayMetadataValidationError{}
+
// ValidateFields checks the field values on MACState_DownlinkMessage_Message
// with the rules defined in the proto definition for this message. If any
// rules are violated, an error is returned.
diff --git a/pkg/ttnpb/end_device_flags.pb.go b/pkg/ttnpb/end_device_flags.pb.go
index 55531cc5c7..7a6ee92da9 100644
--- a/pkg/ttnpb/end_device_flags.pb.go
+++ b/pkg/ttnpb/end_device_flags.pb.go
@@ -172,6 +172,543 @@ func (m *BoolValue) SetFromFlags(flags *pflag.FlagSet, prefix string) (paths []s
return paths, nil
}
+// AddSelectFlagsForServingRelayForwardingLimits adds flags to select fields in ServingRelayForwardingLimits.
+func AddSelectFlagsForServingRelayForwardingLimits(flags *pflag.FlagSet, prefix string, hidden bool) {
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("reset-behavior", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("reset-behavior", prefix), false), flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("join-requests", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("join-requests", prefix), true), flagsplugin.WithHidden(hidden)))
+ AddSelectFlagsForRelayForwardLimits(flags, flagsplugin.Prefix("join-requests", prefix), hidden)
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("notifications", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("notifications", prefix), true), flagsplugin.WithHidden(hidden)))
+ AddSelectFlagsForRelayForwardLimits(flags, flagsplugin.Prefix("notifications", prefix), hidden)
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("uplink-messages", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("uplink-messages", prefix), true), flagsplugin.WithHidden(hidden)))
+ AddSelectFlagsForRelayForwardLimits(flags, flagsplugin.Prefix("uplink-messages", prefix), hidden)
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("overall", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("overall", prefix), true), flagsplugin.WithHidden(hidden)))
+ AddSelectFlagsForRelayForwardLimits(flags, flagsplugin.Prefix("overall", prefix), hidden)
+}
+
+// SelectFromFlags outputs the fieldmask paths forServingRelayForwardingLimits message from select flags.
+func PathsFromSelectFlagsForServingRelayForwardingLimits(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("reset_behavior", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("reset_behavior", prefix))
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("join_requests", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("join_requests", prefix))
+ }
+ if selectPaths, err := PathsFromSelectFlagsForRelayForwardLimits(flags, flagsplugin.Prefix("join_requests", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, selectPaths...)
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("notifications", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("notifications", prefix))
+ }
+ if selectPaths, err := PathsFromSelectFlagsForRelayForwardLimits(flags, flagsplugin.Prefix("notifications", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, selectPaths...)
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("uplink_messages", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("uplink_messages", prefix))
+ }
+ if selectPaths, err := PathsFromSelectFlagsForRelayForwardLimits(flags, flagsplugin.Prefix("uplink_messages", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, selectPaths...)
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("overall", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("overall", prefix))
+ }
+ if selectPaths, err := PathsFromSelectFlagsForRelayForwardLimits(flags, flagsplugin.Prefix("overall", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, selectPaths...)
+ }
+ return paths, nil
+}
+
+// AddSetFlagsForServingRelayForwardingLimits adds flags to select fields in ServingRelayForwardingLimits.
+func AddSetFlagsForServingRelayForwardingLimits(flags *pflag.FlagSet, prefix string, hidden bool) {
+ flags.AddFlag(flagsplugin.NewStringFlag(flagsplugin.Prefix("reset-behavior", prefix), flagsplugin.EnumValueDesc(RelayResetLimitCounter_value), flagsplugin.WithHidden(hidden)))
+ AddSetFlagsForRelayForwardLimits(flags, flagsplugin.Prefix("join-requests", prefix), hidden)
+ AddSetFlagsForRelayForwardLimits(flags, flagsplugin.Prefix("notifications", prefix), hidden)
+ AddSetFlagsForRelayForwardLimits(flags, flagsplugin.Prefix("uplink-messages", prefix), hidden)
+ AddSetFlagsForRelayForwardLimits(flags, flagsplugin.Prefix("overall", prefix), hidden)
+}
+
+// SetFromFlags sets the ServingRelayForwardingLimits message from flags.
+func (m *ServingRelayForwardingLimits) SetFromFlags(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ if val, changed, err := flagsplugin.GetString(flags, flagsplugin.Prefix("reset_behavior", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ enumValue, err := flagsplugin.SetEnumString(val, RelayResetLimitCounter_value)
+ if err != nil {
+ return nil, err
+ }
+ m.ResetBehavior = RelayResetLimitCounter(enumValue)
+ paths = append(paths, flagsplugin.Prefix("reset_behavior", prefix))
+ }
+ if changed := flagsplugin.IsAnyPrefixSet(flags, flagsplugin.Prefix("join_requests", prefix)); changed {
+ if m.JoinRequests == nil {
+ m.JoinRequests = &RelayForwardLimits{}
+ }
+ if setPaths, err := m.JoinRequests.SetFromFlags(flags, flagsplugin.Prefix("join_requests", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, setPaths...)
+ }
+ }
+ if changed := flagsplugin.IsAnyPrefixSet(flags, flagsplugin.Prefix("notifications", prefix)); changed {
+ if m.Notifications == nil {
+ m.Notifications = &RelayForwardLimits{}
+ }
+ if setPaths, err := m.Notifications.SetFromFlags(flags, flagsplugin.Prefix("notifications", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, setPaths...)
+ }
+ }
+ if changed := flagsplugin.IsAnyPrefixSet(flags, flagsplugin.Prefix("uplink_messages", prefix)); changed {
+ if m.UplinkMessages == nil {
+ m.UplinkMessages = &RelayForwardLimits{}
+ }
+ if setPaths, err := m.UplinkMessages.SetFromFlags(flags, flagsplugin.Prefix("uplink_messages", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, setPaths...)
+ }
+ }
+ if changed := flagsplugin.IsAnyPrefixSet(flags, flagsplugin.Prefix("overall", prefix)); changed {
+ if m.Overall == nil {
+ m.Overall = &RelayForwardLimits{}
+ }
+ if setPaths, err := m.Overall.SetFromFlags(flags, flagsplugin.Prefix("overall", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, setPaths...)
+ }
+ }
+ return paths, nil
+}
+
+// AddSelectFlagsForRelayUplinkForwardingRule adds flags to select fields in RelayUplinkForwardingRule.
+func AddSelectFlagsForRelayUplinkForwardingRule(flags *pflag.FlagSet, prefix string, hidden bool) {
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("limits", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("limits", prefix), true), flagsplugin.WithHidden(hidden)))
+ AddSelectFlagsForRelayUplinkForwardLimits(flags, flagsplugin.Prefix("limits", prefix), hidden)
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("last-w-f-cnt", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("last-w-f-cnt", prefix), false), flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("device-id", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("device-id", prefix), false), flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("session-key-id", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("session-key-id", prefix), false), flagsplugin.WithHidden(hidden)))
+}
+
+// SelectFromFlags outputs the fieldmask paths forRelayUplinkForwardingRule message from select flags.
+func PathsFromSelectFlagsForRelayUplinkForwardingRule(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("limits", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("limits", prefix))
+ }
+ if selectPaths, err := PathsFromSelectFlagsForRelayUplinkForwardLimits(flags, flagsplugin.Prefix("limits", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, selectPaths...)
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("last_w_f_cnt", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("last_w_f_cnt", prefix))
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("device_id", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("device_id", prefix))
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("session_key_id", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("session_key_id", prefix))
+ }
+ return paths, nil
+}
+
+// AddSetFlagsForRelayUplinkForwardingRule adds flags to select fields in RelayUplinkForwardingRule.
+func AddSetFlagsForRelayUplinkForwardingRule(flags *pflag.FlagSet, prefix string, hidden bool) {
+ AddSetFlagsForRelayUplinkForwardLimits(flags, flagsplugin.Prefix("limits", prefix), hidden)
+ flags.AddFlag(flagsplugin.NewUint32Flag(flagsplugin.Prefix("last-w-f-cnt", prefix), "", flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewStringFlag(flagsplugin.Prefix("device-id", prefix), "", flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewBytesFlag(flagsplugin.Prefix("session-key-id", prefix), "", flagsplugin.WithHidden(hidden)))
+}
+
+// SetFromFlags sets the RelayUplinkForwardingRule message from flags.
+func (m *RelayUplinkForwardingRule) SetFromFlags(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ if changed := flagsplugin.IsAnyPrefixSet(flags, flagsplugin.Prefix("limits", prefix)); changed {
+ if m.Limits == nil {
+ m.Limits = &RelayUplinkForwardLimits{}
+ }
+ if setPaths, err := m.Limits.SetFromFlags(flags, flagsplugin.Prefix("limits", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, setPaths...)
+ }
+ }
+ if val, changed, err := flagsplugin.GetUint32(flags, flagsplugin.Prefix("last_w_f_cnt", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.LastWFCnt = val
+ paths = append(paths, flagsplugin.Prefix("last_w_f_cnt", prefix))
+ }
+ if val, changed, err := flagsplugin.GetString(flags, flagsplugin.Prefix("device_id", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.DeviceId = val
+ paths = append(paths, flagsplugin.Prefix("device_id", prefix))
+ }
+ if val, changed, err := flagsplugin.GetBytes(flags, flagsplugin.Prefix("session_key_id", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.SessionKeyId = val
+ paths = append(paths, flagsplugin.Prefix("session_key_id", prefix))
+ }
+ return paths, nil
+}
+
+// AddSelectFlagsForServingRelayParameters adds flags to select fields in ServingRelayParameters.
+func AddSelectFlagsForServingRelayParameters(flags *pflag.FlagSet, prefix string, hidden bool) {
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("second-channel", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("second-channel", prefix), true), flagsplugin.WithHidden(hidden)))
+ AddSelectFlagsForRelaySecondChannel(flags, flagsplugin.Prefix("second-channel", prefix), hidden)
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("default-channel-index", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("default-channel-index", prefix), false), flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("cad-periodicity", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("cad-periodicity", prefix), false), flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("uplink-forwarding-rules", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("uplink-forwarding-rules", prefix), false), flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("limits", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("limits", prefix), true), flagsplugin.WithHidden(hidden)))
+ AddSelectFlagsForServingRelayForwardingLimits(flags, flagsplugin.Prefix("limits", prefix), hidden)
+}
+
+// SelectFromFlags outputs the fieldmask paths forServingRelayParameters message from select flags.
+func PathsFromSelectFlagsForServingRelayParameters(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("second_channel", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("second_channel", prefix))
+ }
+ if selectPaths, err := PathsFromSelectFlagsForRelaySecondChannel(flags, flagsplugin.Prefix("second_channel", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, selectPaths...)
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("default_channel_index", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("default_channel_index", prefix))
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("cad_periodicity", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("cad_periodicity", prefix))
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("uplink_forwarding_rules", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("uplink_forwarding_rules", prefix))
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("limits", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("limits", prefix))
+ }
+ if selectPaths, err := PathsFromSelectFlagsForServingRelayForwardingLimits(flags, flagsplugin.Prefix("limits", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, selectPaths...)
+ }
+ return paths, nil
+}
+
+// AddSetFlagsForServingRelayParameters adds flags to select fields in ServingRelayParameters.
+func AddSetFlagsForServingRelayParameters(flags *pflag.FlagSet, prefix string, hidden bool) {
+ AddSetFlagsForRelaySecondChannel(flags, flagsplugin.Prefix("second-channel", prefix), hidden)
+ flags.AddFlag(flagsplugin.NewUint32Flag(flagsplugin.Prefix("default-channel-index", prefix), "", flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewStringFlag(flagsplugin.Prefix("cad-periodicity", prefix), flagsplugin.EnumValueDesc(RelayCADPeriodicity_value), flagsplugin.WithHidden(hidden)))
+ // FIXME: Skipping UplinkForwardingRules because repeated messages are currently not supported.
+ AddSetFlagsForServingRelayForwardingLimits(flags, flagsplugin.Prefix("limits", prefix), hidden)
+}
+
+// SetFromFlags sets the ServingRelayParameters message from flags.
+func (m *ServingRelayParameters) SetFromFlags(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ if changed := flagsplugin.IsAnyPrefixSet(flags, flagsplugin.Prefix("second_channel", prefix)); changed {
+ if m.SecondChannel == nil {
+ m.SecondChannel = &RelaySecondChannel{}
+ }
+ if setPaths, err := m.SecondChannel.SetFromFlags(flags, flagsplugin.Prefix("second_channel", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, setPaths...)
+ }
+ }
+ if val, changed, err := flagsplugin.GetUint32(flags, flagsplugin.Prefix("default_channel_index", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.DefaultChannelIndex = val
+ paths = append(paths, flagsplugin.Prefix("default_channel_index", prefix))
+ }
+ if val, changed, err := flagsplugin.GetString(flags, flagsplugin.Prefix("cad_periodicity", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ enumValue, err := flagsplugin.SetEnumString(val, RelayCADPeriodicity_value)
+ if err != nil {
+ return nil, err
+ }
+ m.CadPeriodicity = RelayCADPeriodicity(enumValue)
+ paths = append(paths, flagsplugin.Prefix("cad_periodicity", prefix))
+ }
+ // FIXME: Skipping UplinkForwardingRules because it does not seem to implement AddSetFlags.
+ if changed := flagsplugin.IsAnyPrefixSet(flags, flagsplugin.Prefix("limits", prefix)); changed {
+ if m.Limits == nil {
+ m.Limits = &ServingRelayForwardingLimits{}
+ }
+ if setPaths, err := m.Limits.SetFromFlags(flags, flagsplugin.Prefix("limits", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, setPaths...)
+ }
+ }
+ return paths, nil
+}
+
+// AddSelectFlagsForServedRelayParameters adds flags to select fields in ServedRelayParameters.
+func AddSelectFlagsForServedRelayParameters(flags *pflag.FlagSet, prefix string, hidden bool) {
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("mode.always", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("mode.always", prefix), true), flagsplugin.WithHidden(hidden)))
+ AddSelectFlagsForRelayEndDeviceAlwaysMode(flags, flagsplugin.Prefix("mode.always", prefix), hidden)
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("mode.dynamic", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("mode.dynamic", prefix), true), flagsplugin.WithHidden(hidden)))
+ AddSelectFlagsForRelayEndDeviceDynamicMode(flags, flagsplugin.Prefix("mode.dynamic", prefix), hidden)
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("mode.end-device-controlled", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("mode.end-device-controlled", prefix), true), flagsplugin.WithHidden(hidden)))
+ AddSelectFlagsForRelayEndDeviceControlledMode(flags, flagsplugin.Prefix("mode.end-device-controlled", prefix), hidden)
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("backoff", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("backoff", prefix), false), flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("second-channel", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("second-channel", prefix), true), flagsplugin.WithHidden(hidden)))
+ AddSelectFlagsForRelaySecondChannel(flags, flagsplugin.Prefix("second-channel", prefix), hidden)
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("serving-device-id", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("serving-device-id", prefix), false), flagsplugin.WithHidden(hidden)))
+}
+
+// SelectFromFlags outputs the fieldmask paths forServedRelayParameters message from select flags.
+func PathsFromSelectFlagsForServedRelayParameters(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("mode.always", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("mode.always", prefix))
+ }
+ if selectPaths, err := PathsFromSelectFlagsForRelayEndDeviceAlwaysMode(flags, flagsplugin.Prefix("mode.always", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, selectPaths...)
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("mode.dynamic", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("mode.dynamic", prefix))
+ }
+ if selectPaths, err := PathsFromSelectFlagsForRelayEndDeviceDynamicMode(flags, flagsplugin.Prefix("mode.dynamic", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, selectPaths...)
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("mode.end_device_controlled", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("mode.end_device_controlled", prefix))
+ }
+ if selectPaths, err := PathsFromSelectFlagsForRelayEndDeviceControlledMode(flags, flagsplugin.Prefix("mode.end_device_controlled", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, selectPaths...)
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("backoff", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("backoff", prefix))
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("second_channel", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("second_channel", prefix))
+ }
+ if selectPaths, err := PathsFromSelectFlagsForRelaySecondChannel(flags, flagsplugin.Prefix("second_channel", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, selectPaths...)
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("serving_device_id", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("serving_device_id", prefix))
+ }
+ return paths, nil
+}
+
+// AddSetFlagsForServedRelayParameters adds flags to select fields in ServedRelayParameters.
+func AddSetFlagsForServedRelayParameters(flags *pflag.FlagSet, prefix string, hidden bool) {
+ AddSetFlagsForRelayEndDeviceAlwaysMode(flags, flagsplugin.Prefix("mode.always", prefix), hidden)
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("mode.always", prefix), "", flagsplugin.WithHidden(hidden)))
+ AddSetFlagsForRelayEndDeviceDynamicMode(flags, flagsplugin.Prefix("mode.dynamic", prefix), hidden)
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("mode.dynamic", prefix), "", flagsplugin.WithHidden(hidden)))
+ AddSetFlagsForRelayEndDeviceControlledMode(flags, flagsplugin.Prefix("mode.end-device-controlled", prefix), hidden)
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("mode.end-device-controlled", prefix), "", flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewUint32Flag(flagsplugin.Prefix("backoff", prefix), "", flagsplugin.WithHidden(hidden)))
+ AddSetFlagsForRelaySecondChannel(flags, flagsplugin.Prefix("second-channel", prefix), hidden)
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("second-channel", prefix), "", flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewStringFlag(flagsplugin.Prefix("serving-device-id", prefix), "", flagsplugin.WithHidden(hidden)))
+}
+
+// SetFromFlags sets the ServedRelayParameters message from flags.
+func (m *ServedRelayParameters) SetFromFlags(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ if changed := flagsplugin.IsAnyPrefixSet(flags, flagsplugin.Prefix("mode.always", prefix)); changed {
+ ov := &ServedRelayParameters_Always{}
+ if ov.Always == nil {
+ ov.Always = &RelayEndDeviceAlwaysMode{}
+ }
+ if setPaths, err := ov.Always.SetFromFlags(flags, flagsplugin.Prefix("mode.always", prefix)); err != nil {
+ return nil, err
+ } else if len(setPaths) == 0 {
+ paths = append(paths, "mode.always")
+ } else {
+ paths = append(paths, setPaths...)
+ }
+ m.Mode = ov
+ }
+ if changed := flagsplugin.IsAnyPrefixSet(flags, flagsplugin.Prefix("mode.dynamic", prefix)); changed {
+ ov := &ServedRelayParameters_Dynamic{}
+ if ov.Dynamic == nil {
+ ov.Dynamic = &RelayEndDeviceDynamicMode{}
+ }
+ if setPaths, err := ov.Dynamic.SetFromFlags(flags, flagsplugin.Prefix("mode.dynamic", prefix)); err != nil {
+ return nil, err
+ } else if len(setPaths) == 0 {
+ paths = append(paths, "mode.dynamic")
+ } else {
+ paths = append(paths, setPaths...)
+ }
+ m.Mode = ov
+ }
+ if changed := flagsplugin.IsAnyPrefixSet(flags, flagsplugin.Prefix("mode.end_device_controlled", prefix)); changed {
+ ov := &ServedRelayParameters_EndDeviceControlled{}
+ if ov.EndDeviceControlled == nil {
+ ov.EndDeviceControlled = &RelayEndDeviceControlledMode{}
+ }
+ if setPaths, err := ov.EndDeviceControlled.SetFromFlags(flags, flagsplugin.Prefix("mode.end_device_controlled", prefix)); err != nil {
+ return nil, err
+ } else if len(setPaths) == 0 {
+ paths = append(paths, "mode.end_device_controlled")
+ } else {
+ paths = append(paths, setPaths...)
+ }
+ m.Mode = ov
+ }
+ if val, changed, err := flagsplugin.GetUint32(flags, flagsplugin.Prefix("backoff", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.Backoff = val
+ paths = append(paths, flagsplugin.Prefix("backoff", prefix))
+ }
+ if changed := flagsplugin.IsAnyPrefixSet(flags, flagsplugin.Prefix("second_channel", prefix)); changed {
+ if m.SecondChannel == nil {
+ m.SecondChannel = &RelaySecondChannel{}
+ }
+ if setPaths, err := m.SecondChannel.SetFromFlags(flags, flagsplugin.Prefix("second_channel", prefix)); err != nil {
+ return nil, err
+ } else if len(setPaths) == 0 {
+ paths = append(paths, "second_channel")
+ } else {
+ paths = append(paths, setPaths...)
+ }
+ }
+ if val, changed, err := flagsplugin.GetString(flags, flagsplugin.Prefix("serving_device_id", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.ServingDeviceId = val
+ paths = append(paths, flagsplugin.Prefix("serving_device_id", prefix))
+ }
+ return paths, nil
+}
+
+// AddSelectFlagsForRelayParameters adds flags to select fields in RelayParameters.
+func AddSelectFlagsForRelayParameters(flags *pflag.FlagSet, prefix string, hidden bool) {
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("mode.serving", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("mode.serving", prefix), true), flagsplugin.WithHidden(hidden)))
+ AddSelectFlagsForServingRelayParameters(flags, flagsplugin.Prefix("mode.serving", prefix), hidden)
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("mode.served", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("mode.served", prefix), true), flagsplugin.WithHidden(hidden)))
+ AddSelectFlagsForServedRelayParameters(flags, flagsplugin.Prefix("mode.served", prefix), hidden)
+}
+
+// SelectFromFlags outputs the fieldmask paths forRelayParameters message from select flags.
+func PathsFromSelectFlagsForRelayParameters(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("mode.serving", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("mode.serving", prefix))
+ }
+ if selectPaths, err := PathsFromSelectFlagsForServingRelayParameters(flags, flagsplugin.Prefix("mode.serving", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, selectPaths...)
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("mode.served", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("mode.served", prefix))
+ }
+ if selectPaths, err := PathsFromSelectFlagsForServedRelayParameters(flags, flagsplugin.Prefix("mode.served", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, selectPaths...)
+ }
+ return paths, nil
+}
+
+// AddSetFlagsForRelayParameters adds flags to select fields in RelayParameters.
+func AddSetFlagsForRelayParameters(flags *pflag.FlagSet, prefix string, hidden bool) {
+ AddSetFlagsForServingRelayParameters(flags, flagsplugin.Prefix("mode.serving", prefix), hidden)
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("mode.serving", prefix), "", flagsplugin.WithHidden(hidden)))
+ AddSetFlagsForServedRelayParameters(flags, flagsplugin.Prefix("mode.served", prefix), hidden)
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("mode.served", prefix), "", flagsplugin.WithHidden(hidden)))
+}
+
+// SetFromFlags sets the RelayParameters message from flags.
+func (m *RelayParameters) SetFromFlags(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ if changed := flagsplugin.IsAnyPrefixSet(flags, flagsplugin.Prefix("mode.serving", prefix)); changed {
+ ov := &RelayParameters_Serving{}
+ if ov.Serving == nil {
+ ov.Serving = &ServingRelayParameters{}
+ }
+ if setPaths, err := ov.Serving.SetFromFlags(flags, flagsplugin.Prefix("mode.serving", prefix)); err != nil {
+ return nil, err
+ } else if len(setPaths) == 0 {
+ paths = append(paths, "mode.serving")
+ } else {
+ paths = append(paths, setPaths...)
+ }
+ m.Mode = ov
+ }
+ if changed := flagsplugin.IsAnyPrefixSet(flags, flagsplugin.Prefix("mode.served", prefix)); changed {
+ ov := &RelayParameters_Served{}
+ if ov.Served == nil {
+ ov.Served = &ServedRelayParameters{}
+ }
+ if setPaths, err := ov.Served.SetFromFlags(flags, flagsplugin.Prefix("mode.served", prefix)); err != nil {
+ return nil, err
+ } else if len(setPaths) == 0 {
+ paths = append(paths, "mode.served")
+ } else {
+ paths = append(paths, setPaths...)
+ }
+ m.Mode = ov
+ }
+ return paths, nil
+}
+
// AddSelectFlagsForMACParameters_Channel adds flags to select fields in MACParameters_Channel.
func AddSelectFlagsForMACParameters_Channel(flags *pflag.FlagSet, prefix string, hidden bool) {
flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("uplink-frequency", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("uplink-frequency", prefix), false), flagsplugin.WithHidden(hidden)))
@@ -292,6 +829,8 @@ func AddSelectFlagsForMACParameters(flags *pflag.FlagSet, prefix string, hidden
AddSelectFlagsForADRAckDelayExponentValue(flags, flagsplugin.Prefix("adr-ack-delay-exponent", prefix), true)
flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("ping-slot-data-rate-index-value", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("ping-slot-data-rate-index-value", prefix), true), flagsplugin.WithHidden(hidden)))
AddSelectFlagsForDataRateIndexValue(flags, flagsplugin.Prefix("ping-slot-data-rate-index-value", prefix), true)
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("relay", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("relay", prefix), true), flagsplugin.WithHidden(hidden)))
+ AddSelectFlagsForRelayParameters(flags, flagsplugin.Prefix("relay", prefix), hidden)
}
// SelectFromFlags outputs the fieldmask paths forMACParameters message from select flags.
@@ -431,6 +970,16 @@ func PathsFromSelectFlagsForMACParameters(flags *pflag.FlagSet, prefix string) (
} else {
paths = append(paths, selectPaths...)
}
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("relay", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("relay", prefix))
+ }
+ if selectPaths, err := PathsFromSelectFlagsForRelayParameters(flags, flagsplugin.Prefix("relay", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, selectPaths...)
+ }
return paths, nil
}
@@ -463,6 +1012,7 @@ func AddSetFlagsForMACParameters(flags *pflag.FlagSet, prefix string, hidden boo
flagsplugin.AddAlias(flags, flagsplugin.Prefix("adr-ack-delay-exponent.value", prefix), flagsplugin.Prefix("adr-ack-delay-exponent", prefix), flagsplugin.WithHidden(hidden))
AddSetFlagsForDataRateIndexValue(flags, flagsplugin.Prefix("ping-slot-data-rate-index-value", prefix), true)
flagsplugin.AddAlias(flags, flagsplugin.Prefix("ping-slot-data-rate-index-value.value", prefix), flagsplugin.Prefix("ping-slot-data-rate-index-value", prefix), flagsplugin.WithHidden(hidden))
+ AddSetFlagsForRelayParameters(flags, flagsplugin.Prefix("relay", prefix), hidden)
}
// SetFromFlags sets the MACParameters message from flags.
@@ -646,6 +1196,16 @@ func (m *MACParameters) SetFromFlags(flags *pflag.FlagSet, prefix string) (paths
paths = append(paths, setPaths...)
}
}
+ if changed := flagsplugin.IsAnyPrefixSet(flags, flagsplugin.Prefix("relay", prefix)); changed {
+ if m.Relay == nil {
+ m.Relay = &RelayParameters{}
+ }
+ if setPaths, err := m.Relay.SetFromFlags(flags, flagsplugin.Prefix("relay", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, setPaths...)
+ }
+ }
return paths, nil
}
@@ -1157,6 +1717,10 @@ func AddSelectFlagsForMACSettings(flags *pflag.FlagSet, prefix string, hidden bo
AddSelectFlagsForADRSettings(flags, flagsplugin.Prefix("adr", prefix), hidden)
flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("schedule-downlinks", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("schedule-downlinks", prefix), true), flagsplugin.WithHidden(hidden)))
AddSelectFlagsForBoolValue(flags, flagsplugin.Prefix("schedule-downlinks", prefix), true)
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("relay", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("relay", prefix), true), flagsplugin.WithHidden(hidden)))
+ AddSelectFlagsForRelayParameters(flags, flagsplugin.Prefix("relay", prefix), hidden)
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("desired-relay", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("desired-relay", prefix), true), flagsplugin.WithHidden(hidden)))
+ AddSelectFlagsForRelayParameters(flags, flagsplugin.Prefix("desired-relay", prefix), hidden)
}
// SelectFromFlags outputs the fieldmask paths forMACSettings message from select flags.
@@ -1466,6 +2030,26 @@ func PathsFromSelectFlagsForMACSettings(flags *pflag.FlagSet, prefix string) (pa
} else {
paths = append(paths, selectPaths...)
}
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("relay", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("relay", prefix))
+ }
+ if selectPaths, err := PathsFromSelectFlagsForRelayParameters(flags, flagsplugin.Prefix("relay", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, selectPaths...)
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("desired_relay", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("desired_relay", prefix))
+ }
+ if selectPaths, err := PathsFromSelectFlagsForRelayParameters(flags, flagsplugin.Prefix("desired_relay", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, selectPaths...)
+ }
return paths, nil
}
@@ -1531,6 +2115,8 @@ func AddSetFlagsForMACSettings(flags *pflag.FlagSet, prefix string, hidden bool)
AddSetFlagsForADRSettings(flags, flagsplugin.Prefix("adr", prefix), hidden)
AddSetFlagsForBoolValue(flags, flagsplugin.Prefix("schedule-downlinks", prefix), true)
flagsplugin.AddAlias(flags, flagsplugin.Prefix("schedule-downlinks.value", prefix), flagsplugin.Prefix("schedule-downlinks", prefix), flagsplugin.WithHidden(hidden))
+ AddSetFlagsForRelayParameters(flags, flagsplugin.Prefix("relay", prefix), hidden)
+ AddSetFlagsForRelayParameters(flags, flagsplugin.Prefix("desired-relay", prefix), hidden)
}
// SetFromFlags sets the MACSettings message from flags.
@@ -1847,6 +2433,26 @@ func (m *MACSettings) SetFromFlags(flags *pflag.FlagSet, prefix string) (paths [
paths = append(paths, setPaths...)
}
}
+ if changed := flagsplugin.IsAnyPrefixSet(flags, flagsplugin.Prefix("relay", prefix)); changed {
+ if m.Relay == nil {
+ m.Relay = &RelayParameters{}
+ }
+ if setPaths, err := m.Relay.SetFromFlags(flags, flagsplugin.Prefix("relay", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, setPaths...)
+ }
+ }
+ if changed := flagsplugin.IsAnyPrefixSet(flags, flagsplugin.Prefix("desired_relay", prefix)); changed {
+ if m.DesiredRelay == nil {
+ m.DesiredRelay = &RelayParameters{}
+ }
+ if setPaths, err := m.DesiredRelay.SetFromFlags(flags, flagsplugin.Prefix("desired_relay", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, setPaths...)
+ }
+ }
return paths, nil
}
@@ -2156,6 +2762,8 @@ func AddSelectFlagsForMACState(flags *pflag.FlagSet, prefix string, hidden bool)
flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("rejected-data-rate-ranges", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("rejected-data-rate-ranges", prefix), false), flagsplugin.WithHidden(hidden)))
flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("last-adr-change-f-cnt-up", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("last-adr-change-f-cnt-up", prefix), false), flagsplugin.WithHidden(hidden)))
flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("recent-mac-command-identifiers", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("recent-mac-command-identifiers", prefix), false), flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("pending-relay-downlink", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("pending-relay-downlink", prefix), true), flagsplugin.WithHidden(hidden)))
+ AddSelectFlagsForRelayForwardDownlinkReq(flags, flagsplugin.Prefix("pending-relay-downlink", prefix), hidden)
}
// SelectFromFlags outputs the fieldmask paths forMACState message from select flags.
@@ -2305,6 +2913,16 @@ func PathsFromSelectFlagsForMACState(flags *pflag.FlagSet, prefix string) (paths
} else if selected && val {
paths = append(paths, flagsplugin.Prefix("recent_mac_command_identifiers", prefix))
}
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("pending_relay_downlink", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("pending_relay_downlink", prefix))
+ }
+ if selectPaths, err := PathsFromSelectFlagsForRelayForwardDownlinkReq(flags, flagsplugin.Prefix("pending_relay_downlink", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, selectPaths...)
+ }
return paths, nil
}
@@ -2334,6 +2952,7 @@ func AddSetFlagsForMACState(flags *pflag.FlagSet, prefix string, hidden bool) {
// FIXME: Skipping RejectedDataRateRanges because maps with uint64 key types are currently not supported.
flags.AddFlag(flagsplugin.NewUint32Flag(flagsplugin.Prefix("last-adr-change-f-cnt-up", prefix), "", flagsplugin.WithHidden(hidden)))
flags.AddFlag(flagsplugin.NewStringSliceFlag(flagsplugin.Prefix("recent-mac-command-identifiers", prefix), flagsplugin.EnumValueDesc(MACCommandIdentifier_value), flagsplugin.WithHidden(hidden)))
+ AddSetFlagsForRelayForwardDownlinkReq(flags, flagsplugin.Prefix("pending-relay-downlink", prefix), hidden)
}
// SetFromFlags sets the MACState message from flags.
@@ -2497,6 +3116,16 @@ func (m *MACState) SetFromFlags(flags *pflag.FlagSet, prefix string) (paths []st
}
paths = append(paths, flagsplugin.Prefix("recent_mac_command_identifiers", prefix))
}
+ if changed := flagsplugin.IsAnyPrefixSet(flags, flagsplugin.Prefix("pending_relay_downlink", prefix)); changed {
+ if m.PendingRelayDownlink == nil {
+ m.PendingRelayDownlink = &RelayForwardDownlinkReq{}
+ }
+ if setPaths, err := m.PendingRelayDownlink.SetFromFlags(flags, flagsplugin.Prefix("pending_relay_downlink", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, setPaths...)
+ }
+ }
return paths, nil
}
diff --git a/pkg/ttnpb/end_device_json.pb.go b/pkg/ttnpb/end_device_json.pb.go
index 51fdb9c4d7..13c070cba7 100644
--- a/pkg/ttnpb/end_device_json.pb.go
+++ b/pkg/ttnpb/end_device_json.pb.go
@@ -224,6 +224,446 @@ func (x *BoolValue) UnmarshalJSON(b []byte) error {
return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
}
+// MarshalProtoJSON marshals the ServingRelayForwardingLimits message to JSON.
+func (x *ServingRelayForwardingLimits) MarshalProtoJSON(s *jsonplugin.MarshalState) {
+ if x == nil {
+ s.WriteNil()
+ return
+ }
+ s.WriteObjectStart()
+ var wroteField bool
+ if x.ResetBehavior != 0 || s.HasField("reset_behavior") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("reset_behavior")
+ x.ResetBehavior.MarshalProtoJSON(s)
+ }
+ if x.JoinRequests != nil || s.HasField("join_requests") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("join_requests")
+ x.JoinRequests.MarshalProtoJSON(s.WithField("join_requests"))
+ }
+ if x.Notifications != nil || s.HasField("notifications") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("notifications")
+ x.Notifications.MarshalProtoJSON(s.WithField("notifications"))
+ }
+ if x.UplinkMessages != nil || s.HasField("uplink_messages") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("uplink_messages")
+ x.UplinkMessages.MarshalProtoJSON(s.WithField("uplink_messages"))
+ }
+ if x.Overall != nil || s.HasField("overall") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("overall")
+ x.Overall.MarshalProtoJSON(s.WithField("overall"))
+ }
+ s.WriteObjectEnd()
+}
+
+// MarshalJSON marshals the ServingRelayForwardingLimits to JSON.
+func (x *ServingRelayForwardingLimits) MarshalJSON() ([]byte, error) {
+ return jsonplugin.DefaultMarshalerConfig.Marshal(x)
+}
+
+// UnmarshalProtoJSON unmarshals the ServingRelayForwardingLimits message from JSON.
+func (x *ServingRelayForwardingLimits) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+ if s.ReadNil() {
+ return
+ }
+ s.ReadObject(func(key string) {
+ switch key {
+ default:
+ s.ReadAny() // ignore unknown field
+ case "reset_behavior", "resetBehavior":
+ s.AddField("reset_behavior")
+ x.ResetBehavior.UnmarshalProtoJSON(s)
+ case "join_requests", "joinRequests":
+ if s.ReadNil() {
+ x.JoinRequests = nil
+ return
+ }
+ x.JoinRequests = &RelayForwardLimits{}
+ x.JoinRequests.UnmarshalProtoJSON(s.WithField("join_requests", true))
+ case "notifications":
+ if s.ReadNil() {
+ x.Notifications = nil
+ return
+ }
+ x.Notifications = &RelayForwardLimits{}
+ x.Notifications.UnmarshalProtoJSON(s.WithField("notifications", true))
+ case "uplink_messages", "uplinkMessages":
+ if s.ReadNil() {
+ x.UplinkMessages = nil
+ return
+ }
+ x.UplinkMessages = &RelayForwardLimits{}
+ x.UplinkMessages.UnmarshalProtoJSON(s.WithField("uplink_messages", true))
+ case "overall":
+ if s.ReadNil() {
+ x.Overall = nil
+ return
+ }
+ x.Overall = &RelayForwardLimits{}
+ x.Overall.UnmarshalProtoJSON(s.WithField("overall", true))
+ }
+ })
+}
+
+// UnmarshalJSON unmarshals the ServingRelayForwardingLimits from JSON.
+func (x *ServingRelayForwardingLimits) UnmarshalJSON(b []byte) error {
+ return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
+}
+
+// MarshalProtoJSON marshals the RelayUplinkForwardingRule message to JSON.
+func (x *RelayUplinkForwardingRule) MarshalProtoJSON(s *jsonplugin.MarshalState) {
+ if x == nil {
+ s.WriteNil()
+ return
+ }
+ s.WriteObjectStart()
+ var wroteField bool
+ if x.Limits != nil || s.HasField("limits") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("limits")
+ x.Limits.MarshalProtoJSON(s.WithField("limits"))
+ }
+ if x.LastWFCnt != 0 || s.HasField("last_w_f_cnt") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("last_w_f_cnt")
+ s.WriteUint32(x.LastWFCnt)
+ }
+ if x.DeviceId != "" || s.HasField("device_id") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("device_id")
+ s.WriteString(x.DeviceId)
+ }
+ if len(x.SessionKeyId) > 0 || s.HasField("session_key_id") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("session_key_id")
+ s.WriteBytes(x.SessionKeyId)
+ }
+ s.WriteObjectEnd()
+}
+
+// MarshalJSON marshals the RelayUplinkForwardingRule to JSON.
+func (x *RelayUplinkForwardingRule) MarshalJSON() ([]byte, error) {
+ return jsonplugin.DefaultMarshalerConfig.Marshal(x)
+}
+
+// UnmarshalProtoJSON unmarshals the RelayUplinkForwardingRule message from JSON.
+func (x *RelayUplinkForwardingRule) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+ if s.ReadNil() {
+ return
+ }
+ s.ReadObject(func(key string) {
+ switch key {
+ default:
+ s.ReadAny() // ignore unknown field
+ case "limits":
+ if s.ReadNil() {
+ x.Limits = nil
+ return
+ }
+ x.Limits = &RelayUplinkForwardLimits{}
+ x.Limits.UnmarshalProtoJSON(s.WithField("limits", true))
+ case "last_w_f_cnt", "lastWFCnt":
+ s.AddField("last_w_f_cnt")
+ x.LastWFCnt = s.ReadUint32()
+ case "device_id", "deviceId":
+ s.AddField("device_id")
+ x.DeviceId = s.ReadString()
+ case "session_key_id", "sessionKeyId":
+ s.AddField("session_key_id")
+ x.SessionKeyId = s.ReadBytes()
+ }
+ })
+}
+
+// UnmarshalJSON unmarshals the RelayUplinkForwardingRule from JSON.
+func (x *RelayUplinkForwardingRule) UnmarshalJSON(b []byte) error {
+ return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
+}
+
+// MarshalProtoJSON marshals the ServingRelayParameters message to JSON.
+func (x *ServingRelayParameters) MarshalProtoJSON(s *jsonplugin.MarshalState) {
+ if x == nil {
+ s.WriteNil()
+ return
+ }
+ s.WriteObjectStart()
+ var wroteField bool
+ if x.SecondChannel != nil || s.HasField("second_channel") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("second_channel")
+ x.SecondChannel.MarshalProtoJSON(s.WithField("second_channel"))
+ }
+ if x.DefaultChannelIndex != 0 || s.HasField("default_channel_index") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("default_channel_index")
+ s.WriteUint32(x.DefaultChannelIndex)
+ }
+ if x.CadPeriodicity != 0 || s.HasField("cad_periodicity") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("cad_periodicity")
+ x.CadPeriodicity.MarshalProtoJSON(s)
+ }
+ if len(x.UplinkForwardingRules) > 0 || s.HasField("uplink_forwarding_rules") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("uplink_forwarding_rules")
+ s.WriteArrayStart()
+ var wroteElement bool
+ for _, element := range x.UplinkForwardingRules {
+ s.WriteMoreIf(&wroteElement)
+ element.MarshalProtoJSON(s.WithField("uplink_forwarding_rules"))
+ }
+ s.WriteArrayEnd()
+ }
+ if x.Limits != nil || s.HasField("limits") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("limits")
+ x.Limits.MarshalProtoJSON(s.WithField("limits"))
+ }
+ s.WriteObjectEnd()
+}
+
+// MarshalJSON marshals the ServingRelayParameters to JSON.
+func (x *ServingRelayParameters) MarshalJSON() ([]byte, error) {
+ return jsonplugin.DefaultMarshalerConfig.Marshal(x)
+}
+
+// UnmarshalProtoJSON unmarshals the ServingRelayParameters message from JSON.
+func (x *ServingRelayParameters) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+ if s.ReadNil() {
+ return
+ }
+ s.ReadObject(func(key string) {
+ switch key {
+ default:
+ s.ReadAny() // ignore unknown field
+ case "second_channel", "secondChannel":
+ if s.ReadNil() {
+ x.SecondChannel = nil
+ return
+ }
+ x.SecondChannel = &RelaySecondChannel{}
+ x.SecondChannel.UnmarshalProtoJSON(s.WithField("second_channel", true))
+ case "default_channel_index", "defaultChannelIndex":
+ s.AddField("default_channel_index")
+ x.DefaultChannelIndex = s.ReadUint32()
+ case "cad_periodicity", "cadPeriodicity":
+ s.AddField("cad_periodicity")
+ x.CadPeriodicity.UnmarshalProtoJSON(s)
+ case "uplink_forwarding_rules", "uplinkForwardingRules":
+ s.AddField("uplink_forwarding_rules")
+ if s.ReadNil() {
+ x.UplinkForwardingRules = nil
+ return
+ }
+ s.ReadArray(func() {
+ if s.ReadNil() {
+ x.UplinkForwardingRules = append(x.UplinkForwardingRules, nil)
+ return
+ }
+ v := &RelayUplinkForwardingRule{}
+ v.UnmarshalProtoJSON(s.WithField("uplink_forwarding_rules", false))
+ if s.Err() != nil {
+ return
+ }
+ x.UplinkForwardingRules = append(x.UplinkForwardingRules, v)
+ })
+ case "limits":
+ if s.ReadNil() {
+ x.Limits = nil
+ return
+ }
+ x.Limits = &ServingRelayForwardingLimits{}
+ x.Limits.UnmarshalProtoJSON(s.WithField("limits", true))
+ }
+ })
+}
+
+// UnmarshalJSON unmarshals the ServingRelayParameters from JSON.
+func (x *ServingRelayParameters) UnmarshalJSON(b []byte) error {
+ return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
+}
+
+// MarshalProtoJSON marshals the ServedRelayParameters message to JSON.
+func (x *ServedRelayParameters) MarshalProtoJSON(s *jsonplugin.MarshalState) {
+ if x == nil {
+ s.WriteNil()
+ return
+ }
+ s.WriteObjectStart()
+ var wroteField bool
+ if x.Mode != nil {
+ switch ov := x.Mode.(type) {
+ case *ServedRelayParameters_Always:
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("always")
+ // NOTE: RelayEndDeviceAlwaysMode does not seem to implement MarshalProtoJSON.
+ golang.MarshalMessage(s, ov.Always)
+ case *ServedRelayParameters_Dynamic:
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("dynamic")
+ ov.Dynamic.MarshalProtoJSON(s.WithField("dynamic"))
+ case *ServedRelayParameters_EndDeviceControlled:
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("end_device_controlled")
+ // NOTE: RelayEndDeviceControlledMode does not seem to implement MarshalProtoJSON.
+ golang.MarshalMessage(s, ov.EndDeviceControlled)
+ }
+ }
+ if x.Backoff != 0 || s.HasField("backoff") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("backoff")
+ s.WriteUint32(x.Backoff)
+ }
+ if x.SecondChannel != nil || s.HasField("second_channel") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("second_channel")
+ x.SecondChannel.MarshalProtoJSON(s.WithField("second_channel"))
+ }
+ if x.ServingDeviceId != "" || s.HasField("serving_device_id") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("serving_device_id")
+ s.WriteString(x.ServingDeviceId)
+ }
+ s.WriteObjectEnd()
+}
+
+// MarshalJSON marshals the ServedRelayParameters to JSON.
+func (x *ServedRelayParameters) MarshalJSON() ([]byte, error) {
+ return jsonplugin.DefaultMarshalerConfig.Marshal(x)
+}
+
+// UnmarshalProtoJSON unmarshals the ServedRelayParameters message from JSON.
+func (x *ServedRelayParameters) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+ if s.ReadNil() {
+ return
+ }
+ s.ReadObject(func(key string) {
+ switch key {
+ default:
+ s.ReadAny() // ignore unknown field
+ case "always":
+ s.AddField("always")
+ ov := &ServedRelayParameters_Always{}
+ x.Mode = ov
+ if s.ReadNil() {
+ ov.Always = nil
+ return
+ }
+ // NOTE: RelayEndDeviceAlwaysMode does not seem to implement UnmarshalProtoJSON.
+ var v RelayEndDeviceAlwaysMode
+ golang.UnmarshalMessage(s, &v)
+ ov.Always = &v
+ case "dynamic":
+ ov := &ServedRelayParameters_Dynamic{}
+ x.Mode = ov
+ if s.ReadNil() {
+ ov.Dynamic = nil
+ return
+ }
+ ov.Dynamic = &RelayEndDeviceDynamicMode{}
+ ov.Dynamic.UnmarshalProtoJSON(s.WithField("dynamic", true))
+ case "end_device_controlled", "endDeviceControlled":
+ s.AddField("end_device_controlled")
+ ov := &ServedRelayParameters_EndDeviceControlled{}
+ x.Mode = ov
+ if s.ReadNil() {
+ ov.EndDeviceControlled = nil
+ return
+ }
+ // NOTE: RelayEndDeviceControlledMode does not seem to implement UnmarshalProtoJSON.
+ var v RelayEndDeviceControlledMode
+ golang.UnmarshalMessage(s, &v)
+ ov.EndDeviceControlled = &v
+ case "backoff":
+ s.AddField("backoff")
+ x.Backoff = s.ReadUint32()
+ case "second_channel", "secondChannel":
+ if s.ReadNil() {
+ x.SecondChannel = nil
+ return
+ }
+ x.SecondChannel = &RelaySecondChannel{}
+ x.SecondChannel.UnmarshalProtoJSON(s.WithField("second_channel", true))
+ case "serving_device_id", "servingDeviceId":
+ s.AddField("serving_device_id")
+ x.ServingDeviceId = s.ReadString()
+ }
+ })
+}
+
+// UnmarshalJSON unmarshals the ServedRelayParameters from JSON.
+func (x *ServedRelayParameters) UnmarshalJSON(b []byte) error {
+ return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
+}
+
+// MarshalProtoJSON marshals the RelayParameters message to JSON.
+func (x *RelayParameters) MarshalProtoJSON(s *jsonplugin.MarshalState) {
+ if x == nil {
+ s.WriteNil()
+ return
+ }
+ s.WriteObjectStart()
+ var wroteField bool
+ if x.Mode != nil {
+ switch ov := x.Mode.(type) {
+ case *RelayParameters_Serving:
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("serving")
+ ov.Serving.MarshalProtoJSON(s.WithField("serving"))
+ case *RelayParameters_Served:
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("served")
+ ov.Served.MarshalProtoJSON(s.WithField("served"))
+ }
+ }
+ s.WriteObjectEnd()
+}
+
+// MarshalJSON marshals the RelayParameters to JSON.
+func (x *RelayParameters) MarshalJSON() ([]byte, error) {
+ return jsonplugin.DefaultMarshalerConfig.Marshal(x)
+}
+
+// UnmarshalProtoJSON unmarshals the RelayParameters message from JSON.
+func (x *RelayParameters) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+ if s.ReadNil() {
+ return
+ }
+ s.ReadObject(func(key string) {
+ switch key {
+ default:
+ s.ReadAny() // ignore unknown field
+ case "serving":
+ ov := &RelayParameters_Serving{}
+ x.Mode = ov
+ if s.ReadNil() {
+ ov.Serving = nil
+ return
+ }
+ ov.Serving = &ServingRelayParameters{}
+ ov.Serving.UnmarshalProtoJSON(s.WithField("serving", true))
+ case "served":
+ ov := &RelayParameters_Served{}
+ x.Mode = ov
+ if s.ReadNil() {
+ ov.Served = nil
+ return
+ }
+ ov.Served = &ServedRelayParameters{}
+ ov.Served.UnmarshalProtoJSON(s.WithField("served", true))
+ }
+ })
+}
+
+// UnmarshalJSON unmarshals the RelayParameters from JSON.
+func (x *RelayParameters) UnmarshalJSON(b []byte) error {
+ return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
+}
+
// MarshalProtoJSON marshals the MACParameters_Channel message to JSON.
func (x *MACParameters_Channel) MarshalProtoJSON(s *jsonplugin.MarshalState) {
if x == nil {
@@ -422,6 +862,11 @@ func (x *MACParameters) MarshalProtoJSON(s *jsonplugin.MarshalState) {
s.WriteObjectField("ping_slot_data_rate_index_value")
x.PingSlotDataRateIndexValue.MarshalProtoJSON(s.WithField("ping_slot_data_rate_index_value"))
}
+ if x.Relay != nil || s.HasField("relay") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("relay")
+ x.Relay.MarshalProtoJSON(s.WithField("relay"))
+ }
s.WriteObjectEnd()
}
@@ -545,6 +990,13 @@ func (x *MACParameters) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
}
x.PingSlotDataRateIndexValue = &DataRateIndexValue{}
x.PingSlotDataRateIndexValue.UnmarshalProtoJSON(s.WithField("ping_slot_data_rate_index_value", false))
+ case "relay":
+ if s.ReadNil() {
+ x.Relay = nil
+ return
+ }
+ x.Relay = &RelayParameters{}
+ x.Relay.UnmarshalProtoJSON(s.WithField("relay", true))
}
})
}
@@ -1229,6 +1681,16 @@ func (x *MACSettings) MarshalProtoJSON(s *jsonplugin.MarshalState) {
s.WriteObjectField("schedule_downlinks")
x.ScheduleDownlinks.MarshalProtoJSON(s.WithField("schedule_downlinks"))
}
+ if x.Relay != nil || s.HasField("relay") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("relay")
+ x.Relay.MarshalProtoJSON(s.WithField("relay"))
+ }
+ if x.DesiredRelay != nil || s.HasField("desired_relay") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("desired_relay")
+ x.DesiredRelay.MarshalProtoJSON(s.WithField("desired_relay"))
+ }
s.WriteObjectEnd()
}
@@ -1534,6 +1996,20 @@ func (x *MACSettings) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
}
x.ScheduleDownlinks = &BoolValue{}
x.ScheduleDownlinks.UnmarshalProtoJSON(s.WithField("schedule_downlinks", false))
+ case "relay":
+ if s.ReadNil() {
+ x.Relay = nil
+ return
+ }
+ x.Relay = &RelayParameters{}
+ x.Relay.UnmarshalProtoJSON(s.WithField("relay", true))
+ case "desired_relay", "desiredRelay":
+ if s.ReadNil() {
+ x.DesiredRelay = nil
+ return
+ }
+ x.DesiredRelay = &RelayParameters{}
+ x.DesiredRelay.UnmarshalProtoJSON(s.WithField("desired_relay", true))
}
})
}
@@ -1742,6 +2218,12 @@ func (x *MACState_UplinkMessage_RxMetadata) MarshalProtoJSON(s *jsonplugin.Marsh
// NOTE: MACState_UplinkMessage_RxMetadata_PacketBrokerMetadata does not seem to implement MarshalProtoJSON.
golang.MarshalMessage(s, x.PacketBroker)
}
+ if x.Relay != nil || s.HasField("relay") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("relay")
+ // NOTE: MACState_UplinkMessage_RxMetadata_RelayMetadata does not seem to implement MarshalProtoJSON.
+ golang.MarshalMessage(s, x.Relay)
+ }
s.WriteObjectEnd()
}
@@ -1788,6 +2270,16 @@ func (x *MACState_UplinkMessage_RxMetadata) UnmarshalProtoJSON(s *jsonplugin.Unm
var v MACState_UplinkMessage_RxMetadata_PacketBrokerMetadata
golang.UnmarshalMessage(s, &v)
x.PacketBroker = &v
+ case "relay":
+ s.AddField("relay")
+ if s.ReadNil() {
+ x.Relay = nil
+ return
+ }
+ // NOTE: MACState_UplinkMessage_RxMetadata_RelayMetadata does not seem to implement UnmarshalProtoJSON.
+ var v MACState_UplinkMessage_RxMetadata_RelayMetadata
+ golang.UnmarshalMessage(s, &v)
+ x.Relay = &v
}
})
}
@@ -2381,6 +2873,12 @@ func (x *MACState) MarshalProtoJSON(s *jsonplugin.MarshalState) {
}
s.WriteArrayEnd()
}
+ if x.PendingRelayDownlink != nil || s.HasField("pending_relay_downlink") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("pending_relay_downlink")
+ // NOTE: RelayForwardDownlinkReq does not seem to implement MarshalProtoJSON.
+ golang.MarshalMessage(s, x.PendingRelayDownlink)
+ }
s.WriteObjectEnd()
}
@@ -2609,6 +3107,16 @@ func (x *MACState) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
v.UnmarshalProtoJSON(s)
x.RecentMacCommandIdentifiers = append(x.RecentMacCommandIdentifiers, v)
})
+ case "pending_relay_downlink", "pendingRelayDownlink":
+ s.AddField("pending_relay_downlink")
+ if s.ReadNil() {
+ x.PendingRelayDownlink = nil
+ return
+ }
+ // NOTE: RelayForwardDownlinkReq does not seem to implement UnmarshalProtoJSON.
+ var v RelayForwardDownlinkReq
+ golang.UnmarshalMessage(s, &v)
+ x.PendingRelayDownlink = &v
}
})
}
diff --git a/pkg/ttnpb/field_mask_validation.go b/pkg/ttnpb/field_mask_validation.go
index 7ab678dea1..fa39c8db22 100644
--- a/pkg/ttnpb/field_mask_validation.go
+++ b/pkg/ttnpb/field_mask_validation.go
@@ -148,6 +148,42 @@ var nsEndDeviceReadFieldPaths = [...]string{
"mac_settings.desired_ping_slot_data_rate_index.value",
"mac_settings.desired_ping_slot_frequency",
"mac_settings.desired_ping_slot_frequency.value",
+ "mac_settings.desired_relay",
+ "mac_settings.desired_relay.mode",
+ "mac_settings.desired_relay.mode.served",
+ "mac_settings.desired_relay.mode.served.backoff",
+ "mac_settings.desired_relay.mode.served.mode",
+ "mac_settings.desired_relay.mode.served.mode.always",
+ "mac_settings.desired_relay.mode.served.mode.dynamic",
+ "mac_settings.desired_relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_settings.desired_relay.mode.served.mode.end_device_controlled",
+ "mac_settings.desired_relay.mode.served.second_channel",
+ "mac_settings.desired_relay.mode.served.second_channel.ack_offset",
+ "mac_settings.desired_relay.mode.served.second_channel.data_rate_index",
+ "mac_settings.desired_relay.mode.served.second_channel.frequency",
+ "mac_settings.desired_relay.mode.served.serving_device_id",
+ "mac_settings.desired_relay.mode.serving",
+ "mac_settings.desired_relay.mode.serving.cad_periodicity",
+ "mac_settings.desired_relay.mode.serving.default_channel_index",
+ "mac_settings.desired_relay.mode.serving.limits",
+ "mac_settings.desired_relay.mode.serving.limits.join_requests",
+ "mac_settings.desired_relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_settings.desired_relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_settings.desired_relay.mode.serving.limits.notifications",
+ "mac_settings.desired_relay.mode.serving.limits.notifications.bucket_size",
+ "mac_settings.desired_relay.mode.serving.limits.notifications.reload_rate",
+ "mac_settings.desired_relay.mode.serving.limits.overall",
+ "mac_settings.desired_relay.mode.serving.limits.overall.bucket_size",
+ "mac_settings.desired_relay.mode.serving.limits.overall.reload_rate",
+ "mac_settings.desired_relay.mode.serving.limits.reset_behavior",
+ "mac_settings.desired_relay.mode.serving.limits.uplink_messages",
+ "mac_settings.desired_relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_settings.desired_relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_settings.desired_relay.mode.serving.second_channel",
+ "mac_settings.desired_relay.mode.serving.second_channel.ack_offset",
+ "mac_settings.desired_relay.mode.serving.second_channel.data_rate_index",
+ "mac_settings.desired_relay.mode.serving.second_channel.frequency",
+ "mac_settings.desired_relay.mode.serving.uplink_forwarding_rules",
"mac_settings.desired_rx1_data_rate_offset",
"mac_settings.desired_rx1_data_rate_offset.value",
"mac_settings.desired_rx1_delay",
@@ -165,6 +201,42 @@ var nsEndDeviceReadFieldPaths = [...]string{
"mac_settings.ping_slot_frequency.value",
"mac_settings.ping_slot_periodicity",
"mac_settings.ping_slot_periodicity.value",
+ "mac_settings.relay",
+ "mac_settings.relay.mode",
+ "mac_settings.relay.mode.served",
+ "mac_settings.relay.mode.served.backoff",
+ "mac_settings.relay.mode.served.mode",
+ "mac_settings.relay.mode.served.mode.always",
+ "mac_settings.relay.mode.served.mode.dynamic",
+ "mac_settings.relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_settings.relay.mode.served.mode.end_device_controlled",
+ "mac_settings.relay.mode.served.second_channel",
+ "mac_settings.relay.mode.served.second_channel.ack_offset",
+ "mac_settings.relay.mode.served.second_channel.data_rate_index",
+ "mac_settings.relay.mode.served.second_channel.frequency",
+ "mac_settings.relay.mode.served.serving_device_id",
+ "mac_settings.relay.mode.serving",
+ "mac_settings.relay.mode.serving.cad_periodicity",
+ "mac_settings.relay.mode.serving.default_channel_index",
+ "mac_settings.relay.mode.serving.limits",
+ "mac_settings.relay.mode.serving.limits.join_requests",
+ "mac_settings.relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_settings.relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_settings.relay.mode.serving.limits.notifications",
+ "mac_settings.relay.mode.serving.limits.notifications.bucket_size",
+ "mac_settings.relay.mode.serving.limits.notifications.reload_rate",
+ "mac_settings.relay.mode.serving.limits.overall",
+ "mac_settings.relay.mode.serving.limits.overall.bucket_size",
+ "mac_settings.relay.mode.serving.limits.overall.reload_rate",
+ "mac_settings.relay.mode.serving.limits.reset_behavior",
+ "mac_settings.relay.mode.serving.limits.uplink_messages",
+ "mac_settings.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_settings.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_settings.relay.mode.serving.second_channel",
+ "mac_settings.relay.mode.serving.second_channel.ack_offset",
+ "mac_settings.relay.mode.serving.second_channel.data_rate_index",
+ "mac_settings.relay.mode.serving.second_channel.frequency",
+ "mac_settings.relay.mode.serving.uplink_forwarding_rules",
"mac_settings.resets_f_cnt",
"mac_settings.resets_f_cnt.value",
"mac_settings.rx1_data_rate_offset",
@@ -207,6 +279,42 @@ var nsEndDeviceReadFieldPaths = [...]string{
"mac_state.current_parameters.ping_slot_frequency",
"mac_state.current_parameters.rejoin_count_periodicity",
"mac_state.current_parameters.rejoin_time_periodicity",
+ "mac_state.current_parameters.relay",
+ "mac_state.current_parameters.relay.mode",
+ "mac_state.current_parameters.relay.mode.served",
+ "mac_state.current_parameters.relay.mode.served.backoff",
+ "mac_state.current_parameters.relay.mode.served.mode",
+ "mac_state.current_parameters.relay.mode.served.mode.always",
+ "mac_state.current_parameters.relay.mode.served.mode.dynamic",
+ "mac_state.current_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_state.current_parameters.relay.mode.served.mode.end_device_controlled",
+ "mac_state.current_parameters.relay.mode.served.second_channel",
+ "mac_state.current_parameters.relay.mode.served.second_channel.ack_offset",
+ "mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index",
+ "mac_state.current_parameters.relay.mode.served.second_channel.frequency",
+ "mac_state.current_parameters.relay.mode.served.serving_device_id",
+ "mac_state.current_parameters.relay.mode.serving",
+ "mac_state.current_parameters.relay.mode.serving.cad_periodicity",
+ "mac_state.current_parameters.relay.mode.serving.default_channel_index",
+ "mac_state.current_parameters.relay.mode.serving.limits",
+ "mac_state.current_parameters.relay.mode.serving.limits.join_requests",
+ "mac_state.current_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.limits.notifications",
+ "mac_state.current_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.limits.overall",
+ "mac_state.current_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.limits.reset_behavior",
+ "mac_state.current_parameters.relay.mode.serving.limits.uplink_messages",
+ "mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.second_channel",
+ "mac_state.current_parameters.relay.mode.serving.second_channel.ack_offset",
+ "mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "mac_state.current_parameters.relay.mode.serving.second_channel.frequency",
+ "mac_state.current_parameters.relay.mode.serving.uplink_forwarding_rules",
"mac_state.current_parameters.rx1_data_rate_offset",
"mac_state.current_parameters.rx1_delay",
"mac_state.current_parameters.rx2_data_rate_index",
@@ -232,6 +340,42 @@ var nsEndDeviceReadFieldPaths = [...]string{
"mac_state.desired_parameters.ping_slot_frequency",
"mac_state.desired_parameters.rejoin_count_periodicity",
"mac_state.desired_parameters.rejoin_time_periodicity",
+ "mac_state.desired_parameters.relay",
+ "mac_state.desired_parameters.relay.mode",
+ "mac_state.desired_parameters.relay.mode.served",
+ "mac_state.desired_parameters.relay.mode.served.backoff",
+ "mac_state.desired_parameters.relay.mode.served.mode",
+ "mac_state.desired_parameters.relay.mode.served.mode.always",
+ "mac_state.desired_parameters.relay.mode.served.mode.dynamic",
+ "mac_state.desired_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_state.desired_parameters.relay.mode.served.mode.end_device_controlled",
+ "mac_state.desired_parameters.relay.mode.served.second_channel",
+ "mac_state.desired_parameters.relay.mode.served.second_channel.ack_offset",
+ "mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index",
+ "mac_state.desired_parameters.relay.mode.served.second_channel.frequency",
+ "mac_state.desired_parameters.relay.mode.served.serving_device_id",
+ "mac_state.desired_parameters.relay.mode.serving",
+ "mac_state.desired_parameters.relay.mode.serving.cad_periodicity",
+ "mac_state.desired_parameters.relay.mode.serving.default_channel_index",
+ "mac_state.desired_parameters.relay.mode.serving.limits",
+ "mac_state.desired_parameters.relay.mode.serving.limits.join_requests",
+ "mac_state.desired_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.limits.notifications",
+ "mac_state.desired_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.limits.overall",
+ "mac_state.desired_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.limits.reset_behavior",
+ "mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages",
+ "mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel.ack_offset",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel.frequency",
+ "mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules",
"mac_state.desired_parameters.rx1_data_rate_offset",
"mac_state.desired_parameters.rx1_delay",
"mac_state.desired_parameters.rx2_data_rate_index",
@@ -256,6 +400,8 @@ var nsEndDeviceReadFieldPaths = [...]string{
"mac_state.pending_application_downlink.frm_payload",
"mac_state.pending_application_downlink.priority",
"mac_state.pending_application_downlink.session_key_id",
+ "mac_state.pending_relay_downlink",
+ "mac_state.pending_relay_downlink.raw_payload",
"mac_state.pending_requests",
"mac_state.ping_slot_periodicity",
"mac_state.ping_slot_periodicity.value",
@@ -291,6 +437,42 @@ var nsEndDeviceReadFieldPaths = [...]string{
"pending_mac_state.current_parameters.ping_slot_frequency",
"pending_mac_state.current_parameters.rejoin_count_periodicity",
"pending_mac_state.current_parameters.rejoin_time_periodicity",
+ "pending_mac_state.current_parameters.relay",
+ "pending_mac_state.current_parameters.relay.mode",
+ "pending_mac_state.current_parameters.relay.mode.served",
+ "pending_mac_state.current_parameters.relay.mode.served.backoff",
+ "pending_mac_state.current_parameters.relay.mode.served.mode",
+ "pending_mac_state.current_parameters.relay.mode.served.mode.always",
+ "pending_mac_state.current_parameters.relay.mode.served.mode.dynamic",
+ "pending_mac_state.current_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "pending_mac_state.current_parameters.relay.mode.served.mode.end_device_controlled",
+ "pending_mac_state.current_parameters.relay.mode.served.second_channel",
+ "pending_mac_state.current_parameters.relay.mode.served.second_channel.ack_offset",
+ "pending_mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index",
+ "pending_mac_state.current_parameters.relay.mode.served.second_channel.frequency",
+ "pending_mac_state.current_parameters.relay.mode.served.serving_device_id",
+ "pending_mac_state.current_parameters.relay.mode.serving",
+ "pending_mac_state.current_parameters.relay.mode.serving.cad_periodicity",
+ "pending_mac_state.current_parameters.relay.mode.serving.default_channel_index",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.notifications",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.overall",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.reset_behavior",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "pending_mac_state.current_parameters.relay.mode.serving.second_channel",
+ "pending_mac_state.current_parameters.relay.mode.serving.second_channel.ack_offset",
+ "pending_mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "pending_mac_state.current_parameters.relay.mode.serving.second_channel.frequency",
+ "pending_mac_state.current_parameters.relay.mode.serving.uplink_forwarding_rules",
"pending_mac_state.current_parameters.rx1_data_rate_offset",
"pending_mac_state.current_parameters.rx1_delay",
"pending_mac_state.current_parameters.rx2_data_rate_index",
@@ -316,6 +498,42 @@ var nsEndDeviceReadFieldPaths = [...]string{
"pending_mac_state.desired_parameters.ping_slot_frequency",
"pending_mac_state.desired_parameters.rejoin_count_periodicity",
"pending_mac_state.desired_parameters.rejoin_time_periodicity",
+ "pending_mac_state.desired_parameters.relay",
+ "pending_mac_state.desired_parameters.relay.mode",
+ "pending_mac_state.desired_parameters.relay.mode.served",
+ "pending_mac_state.desired_parameters.relay.mode.served.backoff",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode.always",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode.dynamic",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode.end_device_controlled",
+ "pending_mac_state.desired_parameters.relay.mode.served.second_channel",
+ "pending_mac_state.desired_parameters.relay.mode.served.second_channel.ack_offset",
+ "pending_mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index",
+ "pending_mac_state.desired_parameters.relay.mode.served.second_channel.frequency",
+ "pending_mac_state.desired_parameters.relay.mode.served.serving_device_id",
+ "pending_mac_state.desired_parameters.relay.mode.serving",
+ "pending_mac_state.desired_parameters.relay.mode.serving.cad_periodicity",
+ "pending_mac_state.desired_parameters.relay.mode.serving.default_channel_index",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.overall",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.reset_behavior",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "pending_mac_state.desired_parameters.relay.mode.serving.second_channel",
+ "pending_mac_state.desired_parameters.relay.mode.serving.second_channel.ack_offset",
+ "pending_mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "pending_mac_state.desired_parameters.relay.mode.serving.second_channel.frequency",
+ "pending_mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules",
"pending_mac_state.desired_parameters.rx1_data_rate_offset",
"pending_mac_state.desired_parameters.rx1_delay",
"pending_mac_state.desired_parameters.rx2_data_rate_index",
@@ -792,6 +1010,42 @@ var RPCFieldMaskPaths = map[string]RPCFieldMaskPathValue{
"mac_settings.desired_ping_slot_data_rate_index.value",
"mac_settings.desired_ping_slot_frequency",
"mac_settings.desired_ping_slot_frequency.value",
+ "mac_settings.desired_relay",
+ "mac_settings.desired_relay.mode",
+ "mac_settings.desired_relay.mode.served",
+ "mac_settings.desired_relay.mode.served.backoff",
+ "mac_settings.desired_relay.mode.served.mode",
+ "mac_settings.desired_relay.mode.served.mode.always",
+ "mac_settings.desired_relay.mode.served.mode.dynamic",
+ "mac_settings.desired_relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_settings.desired_relay.mode.served.mode.end_device_controlled",
+ "mac_settings.desired_relay.mode.served.second_channel",
+ "mac_settings.desired_relay.mode.served.second_channel.ack_offset",
+ "mac_settings.desired_relay.mode.served.second_channel.data_rate_index",
+ "mac_settings.desired_relay.mode.served.second_channel.frequency",
+ "mac_settings.desired_relay.mode.served.serving_device_id",
+ "mac_settings.desired_relay.mode.serving",
+ "mac_settings.desired_relay.mode.serving.cad_periodicity",
+ "mac_settings.desired_relay.mode.serving.default_channel_index",
+ "mac_settings.desired_relay.mode.serving.limits",
+ "mac_settings.desired_relay.mode.serving.limits.join_requests",
+ "mac_settings.desired_relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_settings.desired_relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_settings.desired_relay.mode.serving.limits.notifications",
+ "mac_settings.desired_relay.mode.serving.limits.notifications.bucket_size",
+ "mac_settings.desired_relay.mode.serving.limits.notifications.reload_rate",
+ "mac_settings.desired_relay.mode.serving.limits.overall",
+ "mac_settings.desired_relay.mode.serving.limits.overall.bucket_size",
+ "mac_settings.desired_relay.mode.serving.limits.overall.reload_rate",
+ "mac_settings.desired_relay.mode.serving.limits.reset_behavior",
+ "mac_settings.desired_relay.mode.serving.limits.uplink_messages",
+ "mac_settings.desired_relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_settings.desired_relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_settings.desired_relay.mode.serving.second_channel",
+ "mac_settings.desired_relay.mode.serving.second_channel.ack_offset",
+ "mac_settings.desired_relay.mode.serving.second_channel.data_rate_index",
+ "mac_settings.desired_relay.mode.serving.second_channel.frequency",
+ "mac_settings.desired_relay.mode.serving.uplink_forwarding_rules",
"mac_settings.desired_rx1_data_rate_offset",
"mac_settings.desired_rx1_data_rate_offset.value",
"mac_settings.desired_rx1_delay",
@@ -809,6 +1063,42 @@ var RPCFieldMaskPaths = map[string]RPCFieldMaskPathValue{
"mac_settings.ping_slot_frequency.value",
"mac_settings.ping_slot_periodicity",
"mac_settings.ping_slot_periodicity.value",
+ "mac_settings.relay",
+ "mac_settings.relay.mode",
+ "mac_settings.relay.mode.served",
+ "mac_settings.relay.mode.served.backoff",
+ "mac_settings.relay.mode.served.mode",
+ "mac_settings.relay.mode.served.mode.always",
+ "mac_settings.relay.mode.served.mode.dynamic",
+ "mac_settings.relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_settings.relay.mode.served.mode.end_device_controlled",
+ "mac_settings.relay.mode.served.second_channel",
+ "mac_settings.relay.mode.served.second_channel.ack_offset",
+ "mac_settings.relay.mode.served.second_channel.data_rate_index",
+ "mac_settings.relay.mode.served.second_channel.frequency",
+ "mac_settings.relay.mode.served.serving_device_id",
+ "mac_settings.relay.mode.serving",
+ "mac_settings.relay.mode.serving.cad_periodicity",
+ "mac_settings.relay.mode.serving.default_channel_index",
+ "mac_settings.relay.mode.serving.limits",
+ "mac_settings.relay.mode.serving.limits.join_requests",
+ "mac_settings.relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_settings.relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_settings.relay.mode.serving.limits.notifications",
+ "mac_settings.relay.mode.serving.limits.notifications.bucket_size",
+ "mac_settings.relay.mode.serving.limits.notifications.reload_rate",
+ "mac_settings.relay.mode.serving.limits.overall",
+ "mac_settings.relay.mode.serving.limits.overall.bucket_size",
+ "mac_settings.relay.mode.serving.limits.overall.reload_rate",
+ "mac_settings.relay.mode.serving.limits.reset_behavior",
+ "mac_settings.relay.mode.serving.limits.uplink_messages",
+ "mac_settings.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_settings.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_settings.relay.mode.serving.second_channel",
+ "mac_settings.relay.mode.serving.second_channel.ack_offset",
+ "mac_settings.relay.mode.serving.second_channel.data_rate_index",
+ "mac_settings.relay.mode.serving.second_channel.frequency",
+ "mac_settings.relay.mode.serving.uplink_forwarding_rules",
"mac_settings.resets_f_cnt",
"mac_settings.resets_f_cnt.value",
"mac_settings.rx1_data_rate_offset",
@@ -851,6 +1141,42 @@ var RPCFieldMaskPaths = map[string]RPCFieldMaskPathValue{
"mac_state.current_parameters.ping_slot_frequency",
"mac_state.current_parameters.rejoin_count_periodicity",
"mac_state.current_parameters.rejoin_time_periodicity",
+ "mac_state.current_parameters.relay",
+ "mac_state.current_parameters.relay.mode",
+ "mac_state.current_parameters.relay.mode.served",
+ "mac_state.current_parameters.relay.mode.served.backoff",
+ "mac_state.current_parameters.relay.mode.served.mode",
+ "mac_state.current_parameters.relay.mode.served.mode.always",
+ "mac_state.current_parameters.relay.mode.served.mode.dynamic",
+ "mac_state.current_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_state.current_parameters.relay.mode.served.mode.end_device_controlled",
+ "mac_state.current_parameters.relay.mode.served.second_channel",
+ "mac_state.current_parameters.relay.mode.served.second_channel.ack_offset",
+ "mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index",
+ "mac_state.current_parameters.relay.mode.served.second_channel.frequency",
+ "mac_state.current_parameters.relay.mode.served.serving_device_id",
+ "mac_state.current_parameters.relay.mode.serving",
+ "mac_state.current_parameters.relay.mode.serving.cad_periodicity",
+ "mac_state.current_parameters.relay.mode.serving.default_channel_index",
+ "mac_state.current_parameters.relay.mode.serving.limits",
+ "mac_state.current_parameters.relay.mode.serving.limits.join_requests",
+ "mac_state.current_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.limits.notifications",
+ "mac_state.current_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.limits.overall",
+ "mac_state.current_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.limits.reset_behavior",
+ "mac_state.current_parameters.relay.mode.serving.limits.uplink_messages",
+ "mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.second_channel",
+ "mac_state.current_parameters.relay.mode.serving.second_channel.ack_offset",
+ "mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "mac_state.current_parameters.relay.mode.serving.second_channel.frequency",
+ "mac_state.current_parameters.relay.mode.serving.uplink_forwarding_rules",
"mac_state.current_parameters.rx1_data_rate_offset",
"mac_state.current_parameters.rx1_delay",
"mac_state.current_parameters.rx2_data_rate_index",
@@ -876,6 +1202,42 @@ var RPCFieldMaskPaths = map[string]RPCFieldMaskPathValue{
"mac_state.desired_parameters.ping_slot_frequency",
"mac_state.desired_parameters.rejoin_count_periodicity",
"mac_state.desired_parameters.rejoin_time_periodicity",
+ "mac_state.desired_parameters.relay",
+ "mac_state.desired_parameters.relay.mode",
+ "mac_state.desired_parameters.relay.mode.served",
+ "mac_state.desired_parameters.relay.mode.served.backoff",
+ "mac_state.desired_parameters.relay.mode.served.mode",
+ "mac_state.desired_parameters.relay.mode.served.mode.always",
+ "mac_state.desired_parameters.relay.mode.served.mode.dynamic",
+ "mac_state.desired_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_state.desired_parameters.relay.mode.served.mode.end_device_controlled",
+ "mac_state.desired_parameters.relay.mode.served.second_channel",
+ "mac_state.desired_parameters.relay.mode.served.second_channel.ack_offset",
+ "mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index",
+ "mac_state.desired_parameters.relay.mode.served.second_channel.frequency",
+ "mac_state.desired_parameters.relay.mode.served.serving_device_id",
+ "mac_state.desired_parameters.relay.mode.serving",
+ "mac_state.desired_parameters.relay.mode.serving.cad_periodicity",
+ "mac_state.desired_parameters.relay.mode.serving.default_channel_index",
+ "mac_state.desired_parameters.relay.mode.serving.limits",
+ "mac_state.desired_parameters.relay.mode.serving.limits.join_requests",
+ "mac_state.desired_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.limits.notifications",
+ "mac_state.desired_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.limits.overall",
+ "mac_state.desired_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.limits.reset_behavior",
+ "mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages",
+ "mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel.ack_offset",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel.frequency",
+ "mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules",
"mac_state.desired_parameters.rx1_data_rate_offset",
"mac_state.desired_parameters.rx1_delay",
"mac_state.desired_parameters.rx2_data_rate_index",
@@ -900,6 +1262,8 @@ var RPCFieldMaskPaths = map[string]RPCFieldMaskPathValue{
"mac_state.pending_application_downlink.frm_payload",
"mac_state.pending_application_downlink.priority",
"mac_state.pending_application_downlink.session_key_id",
+ "mac_state.pending_relay_downlink",
+ "mac_state.pending_relay_downlink.raw_payload",
"mac_state.pending_requests",
"mac_state.ping_slot_periodicity",
"mac_state.ping_slot_periodicity.value",
@@ -935,6 +1299,42 @@ var RPCFieldMaskPaths = map[string]RPCFieldMaskPathValue{
"pending_mac_state.current_parameters.ping_slot_frequency",
"pending_mac_state.current_parameters.rejoin_count_periodicity",
"pending_mac_state.current_parameters.rejoin_time_periodicity",
+ "pending_mac_state.current_parameters.relay",
+ "pending_mac_state.current_parameters.relay.mode",
+ "pending_mac_state.current_parameters.relay.mode.served",
+ "pending_mac_state.current_parameters.relay.mode.served.backoff",
+ "pending_mac_state.current_parameters.relay.mode.served.mode",
+ "pending_mac_state.current_parameters.relay.mode.served.mode.always",
+ "pending_mac_state.current_parameters.relay.mode.served.mode.dynamic",
+ "pending_mac_state.current_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "pending_mac_state.current_parameters.relay.mode.served.mode.end_device_controlled",
+ "pending_mac_state.current_parameters.relay.mode.served.second_channel",
+ "pending_mac_state.current_parameters.relay.mode.served.second_channel.ack_offset",
+ "pending_mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index",
+ "pending_mac_state.current_parameters.relay.mode.served.second_channel.frequency",
+ "pending_mac_state.current_parameters.relay.mode.served.serving_device_id",
+ "pending_mac_state.current_parameters.relay.mode.serving",
+ "pending_mac_state.current_parameters.relay.mode.serving.cad_periodicity",
+ "pending_mac_state.current_parameters.relay.mode.serving.default_channel_index",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.notifications",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.overall",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.reset_behavior",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "pending_mac_state.current_parameters.relay.mode.serving.second_channel",
+ "pending_mac_state.current_parameters.relay.mode.serving.second_channel.ack_offset",
+ "pending_mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "pending_mac_state.current_parameters.relay.mode.serving.second_channel.frequency",
+ "pending_mac_state.current_parameters.relay.mode.serving.uplink_forwarding_rules",
"pending_mac_state.current_parameters.rx1_data_rate_offset",
"pending_mac_state.current_parameters.rx1_delay",
"pending_mac_state.current_parameters.rx2_data_rate_index",
@@ -960,6 +1360,42 @@ var RPCFieldMaskPaths = map[string]RPCFieldMaskPathValue{
"pending_mac_state.desired_parameters.ping_slot_frequency",
"pending_mac_state.desired_parameters.rejoin_count_periodicity",
"pending_mac_state.desired_parameters.rejoin_time_periodicity",
+ "pending_mac_state.desired_parameters.relay",
+ "pending_mac_state.desired_parameters.relay.mode",
+ "pending_mac_state.desired_parameters.relay.mode.served",
+ "pending_mac_state.desired_parameters.relay.mode.served.backoff",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode.always",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode.dynamic",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode.end_device_controlled",
+ "pending_mac_state.desired_parameters.relay.mode.served.second_channel",
+ "pending_mac_state.desired_parameters.relay.mode.served.second_channel.ack_offset",
+ "pending_mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index",
+ "pending_mac_state.desired_parameters.relay.mode.served.second_channel.frequency",
+ "pending_mac_state.desired_parameters.relay.mode.served.serving_device_id",
+ "pending_mac_state.desired_parameters.relay.mode.serving",
+ "pending_mac_state.desired_parameters.relay.mode.serving.cad_periodicity",
+ "pending_mac_state.desired_parameters.relay.mode.serving.default_channel_index",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.overall",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.reset_behavior",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "pending_mac_state.desired_parameters.relay.mode.serving.second_channel",
+ "pending_mac_state.desired_parameters.relay.mode.serving.second_channel.ack_offset",
+ "pending_mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "pending_mac_state.desired_parameters.relay.mode.serving.second_channel.frequency",
+ "pending_mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules",
"pending_mac_state.desired_parameters.rx1_data_rate_offset",
"pending_mac_state.desired_parameters.rx1_delay",
"pending_mac_state.desired_parameters.rx2_data_rate_index",
diff --git a/pkg/ttnpb/gateway_services.pb.go b/pkg/ttnpb/gateway_services.pb.go
index 18a89af65d..515c777438 100644
--- a/pkg/ttnpb/gateway_services.pb.go
+++ b/pkg/ttnpb/gateway_services.pb.go
@@ -231,7 +231,7 @@ var file_ttn_lorawan_v3_gateway_services_proto_rawDesc = []byte{
0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
0x2e, 0x76, 0x33, 0x2e, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74,
0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x0a, 0xfa, 0x42, 0x07, 0x92, 0x01, 0x04, 0x08, 0x01,
- 0x10, 0x14, 0x52, 0x0a, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x73, 0x12, 0x3c,
+ 0x10, 0x64, 0x52, 0x0a, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x73, 0x12, 0x3c,
0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x16, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
0x33, 0x2e, 0x52, 0x69, 0x67, 0x68, 0x74, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02,
diff --git a/pkg/ttnpb/gateway_services.pb.validate.go b/pkg/ttnpb/gateway_services.pb.validate.go
index 8d21dc3a21..ed9e539bb4 100644
--- a/pkg/ttnpb/gateway_services.pb.validate.go
+++ b/pkg/ttnpb/gateway_services.pb.validate.go
@@ -155,10 +155,10 @@ func (m *AssertGatewayRightsRequest) ValidateFields(paths ...string) error {
switch name {
case "gateway_ids":
- if l := len(m.GetGatewayIds()); l < 1 || l > 20 {
+ if l := len(m.GetGatewayIds()); l < 1 || l > 100 {
return AssertGatewayRightsRequestValidationError{
field: "gateway_ids",
- reason: "value must contain between 1 and 20 items, inclusive",
+ reason: "value must contain between 1 and 100 items, inclusive",
}
}
diff --git a/pkg/ttnpb/i18n.go b/pkg/ttnpb/i18n.go
index a9a67c0f7e..6c2b8d0296 100644
--- a/pkg/ttnpb/i18n.go
+++ b/pkg/ttnpb/i18n.go
@@ -87,6 +87,14 @@ func init() {
defineEnum(MACCommandIdentifier_CID_BEACON_FREQ, "beacon frequency")
defineEnum(MACCommandIdentifier_CID_DEVICE_MODE, "device mode")
+ defineEnum(MACCommandIdentifier_CID_RELAY_END_DEVICE_CONF, "end device relay configuration")
+ defineEnum(MACCommandIdentifier_CID_RELAY_UPDATE_UPLINK_LIST, "update uplink forwarding rules")
+ defineEnum(MACCommandIdentifier_CID_RELAY_CONF, "relay configuration")
+ defineEnum(MACCommandIdentifier_CID_RELAY_CTRL_UPLINK_LIST, "manage uplink forwarding rules")
+ defineEnum(MACCommandIdentifier_CID_RELAY_NOTIFY_NEW_END_DEVICE, "new end device under relay")
+ defineEnum(MACCommandIdentifier_CID_RELAY_FILTER_LIST, "manage join request forwarding rules")
+ defineEnum(MACCommandIdentifier_CID_RELAY_CONFIGURE_FWD_LIMIT, "manage uplink forwarding limits")
+
defineEnum(LocationSource_SOURCE_UNKNOWN, "unknown location source")
defineEnum(LocationSource_SOURCE_GPS, "determined by GPS")
defineEnum(LocationSource_SOURCE_REGISTRY, "set in and updated from a registry")
diff --git a/pkg/ttnpb/identifiers.pb.go b/pkg/ttnpb/identifiers.pb.go
index 50edfa43e1..7d605e5a1e 100644
--- a/pkg/ttnpb/identifiers.pb.go
+++ b/pkg/ttnpb/identifiers.pb.go
@@ -1198,7 +1198,7 @@ var file_ttn_lorawan_v3_identifiers_proto_rawDesc = []byte{
0x61, 0x6e, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28,
0x09, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x72, 0x03, 0x18, 0x80, 0x02, 0x52, 0x0d, 0x74, 0x65, 0x6e,
0x61, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04,
- 0x08, 0x01, 0x10, 0x00, 0x22, 0x69, 0x0a, 0x1e, 0x4c, 0x6f, 0x52, 0x61, 0x41, 0x6c, 0x6c, 0x69,
+ 0x08, 0x01, 0x10, 0x01, 0x22, 0x69, 0x0a, 0x1e, 0x4c, 0x6f, 0x52, 0x61, 0x41, 0x6c, 0x6c, 0x69,
0x61, 0x6e, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74,
0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72,
0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x76, 0x65, 0x6e, 0x64, 0x6f,
diff --git a/pkg/ttnpb/identifiers_flags.pb.go b/pkg/ttnpb/identifiers_flags.pb.go
index 7b7580ee87..f2e69fd0aa 100644
--- a/pkg/ttnpb/identifiers_flags.pb.go
+++ b/pkg/ttnpb/identifiers_flags.pb.go
@@ -481,3 +481,54 @@ func PathsFromSelectFlagsForNetworkIdentifiers(flags *pflag.FlagSet, prefix stri
}
return paths, nil
}
+
+// AddSetFlagsForNetworkIdentifiers adds flags to select fields in NetworkIdentifiers.
+func AddSetFlagsForNetworkIdentifiers(flags *pflag.FlagSet, prefix string, hidden bool) {
+ flags.AddFlag(customflags.New3BytesFlag(flagsplugin.Prefix("net-id", prefix), "", flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(customflags.New8BytesFlag(flagsplugin.Prefix("ns-id", prefix), "", flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewStringFlag(flagsplugin.Prefix("tenant-id", prefix), "", flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewStringFlag(flagsplugin.Prefix("cluster-id", prefix), "", flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewStringFlag(flagsplugin.Prefix("cluster-address", prefix), "", flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewStringFlag(flagsplugin.Prefix("tenant-address", prefix), "", flagsplugin.WithHidden(hidden)))
+}
+
+// SetFromFlags sets the NetworkIdentifiers message from flags.
+func (m *NetworkIdentifiers) SetFromFlags(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ if val, changed, err := customflags.GetExactBytes(flags, flagsplugin.Prefix("net_id", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.NetId = val
+ paths = append(paths, flagsplugin.Prefix("net_id", prefix))
+ }
+ if val, changed, err := customflags.GetExactBytes(flags, flagsplugin.Prefix("ns_id", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.NsId = val
+ paths = append(paths, flagsplugin.Prefix("ns_id", prefix))
+ }
+ if val, changed, err := flagsplugin.GetString(flags, flagsplugin.Prefix("tenant_id", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.TenantId = val
+ paths = append(paths, flagsplugin.Prefix("tenant_id", prefix))
+ }
+ if val, changed, err := flagsplugin.GetString(flags, flagsplugin.Prefix("cluster_id", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.ClusterId = val
+ paths = append(paths, flagsplugin.Prefix("cluster_id", prefix))
+ }
+ if val, changed, err := flagsplugin.GetString(flags, flagsplugin.Prefix("cluster_address", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.ClusterAddress = val
+ paths = append(paths, flagsplugin.Prefix("cluster_address", prefix))
+ }
+ if val, changed, err := flagsplugin.GetString(flags, flagsplugin.Prefix("tenant_address", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.TenantAddress = val
+ paths = append(paths, flagsplugin.Prefix("tenant_address", prefix))
+ }
+ return paths, nil
+}
diff --git a/pkg/ttnpb/lorawan.go b/pkg/ttnpb/lorawan.go
index c0f84555aa..2d13b350fc 100644
--- a/pkg/ttnpb/lorawan.go
+++ b/pkg/ttnpb/lorawan.go
@@ -1197,3 +1197,43 @@ func (m *Message) EndDeviceIdentifiers() *EndDeviceIdentifiers {
}
return nil
}
+
+// FieldIsZero returns whether path p is zero.
+func (v *RelaySecondChannel) FieldIsZero(p string) bool {
+ if v == nil {
+ return true
+ }
+ switch p {
+ case "ack_offset":
+ return v.AckOffset == 0
+ case "data_rate_index":
+ return v.DataRateIndex == 0
+ case "frequency":
+ return v.Frequency == 0
+ }
+ panic(fmt.Sprintf("unknown path '%s'", p))
+}
+
+// FieldIsZero returns whether path p is zero.
+func (v *RelayEndDeviceDynamicMode) FieldIsZero(p string) bool {
+ if v == nil {
+ return true
+ }
+ switch p {
+ case "smart_enable_level":
+ return v.SmartEnableLevel == 0
+ }
+ panic(fmt.Sprintf("unknown path '%s'", p))
+}
+
+// FieldIsZero returns whether path p is zero.
+func (v *RelayForwardDownlinkReq) FieldIsZero(p string) bool {
+ if v == nil {
+ return true
+ }
+ switch p {
+ case "raw_payload":
+ return v.RawPayload == nil
+ }
+ panic(fmt.Sprintf("unknown path '%s'", p))
+}
diff --git a/pkg/ttnpb/lorawan.pb.go b/pkg/ttnpb/lorawan.pb.go
index ad1fea9de8..04fc47efe9 100644
--- a/pkg/ttnpb/lorawan.pb.go
+++ b/pkg/ttnpb/lorawan.pb.go
@@ -720,27 +720,34 @@ func (TxSchedulePriority) EnumDescriptor() ([]byte, []int) {
type MACCommandIdentifier int32
const (
- MACCommandIdentifier_CID_RFU_0 MACCommandIdentifier = 0
- MACCommandIdentifier_CID_RESET MACCommandIdentifier = 1
- MACCommandIdentifier_CID_LINK_CHECK MACCommandIdentifier = 2
- MACCommandIdentifier_CID_LINK_ADR MACCommandIdentifier = 3
- MACCommandIdentifier_CID_DUTY_CYCLE MACCommandIdentifier = 4
- MACCommandIdentifier_CID_RX_PARAM_SETUP MACCommandIdentifier = 5
- MACCommandIdentifier_CID_DEV_STATUS MACCommandIdentifier = 6
- MACCommandIdentifier_CID_NEW_CHANNEL MACCommandIdentifier = 7
- MACCommandIdentifier_CID_RX_TIMING_SETUP MACCommandIdentifier = 8
- MACCommandIdentifier_CID_TX_PARAM_SETUP MACCommandIdentifier = 9
- MACCommandIdentifier_CID_DL_CHANNEL MACCommandIdentifier = 10
- MACCommandIdentifier_CID_REKEY MACCommandIdentifier = 11
- MACCommandIdentifier_CID_ADR_PARAM_SETUP MACCommandIdentifier = 12
- MACCommandIdentifier_CID_DEVICE_TIME MACCommandIdentifier = 13
- MACCommandIdentifier_CID_FORCE_REJOIN MACCommandIdentifier = 14
- MACCommandIdentifier_CID_REJOIN_PARAM_SETUP MACCommandIdentifier = 15
- MACCommandIdentifier_CID_PING_SLOT_INFO MACCommandIdentifier = 16
- MACCommandIdentifier_CID_PING_SLOT_CHANNEL MACCommandIdentifier = 17
- MACCommandIdentifier_CID_BEACON_TIMING MACCommandIdentifier = 18 // Deprecated
- MACCommandIdentifier_CID_BEACON_FREQ MACCommandIdentifier = 19
- MACCommandIdentifier_CID_DEVICE_MODE MACCommandIdentifier = 32
+ MACCommandIdentifier_CID_RFU_0 MACCommandIdentifier = 0
+ MACCommandIdentifier_CID_RESET MACCommandIdentifier = 1
+ MACCommandIdentifier_CID_LINK_CHECK MACCommandIdentifier = 2
+ MACCommandIdentifier_CID_LINK_ADR MACCommandIdentifier = 3
+ MACCommandIdentifier_CID_DUTY_CYCLE MACCommandIdentifier = 4
+ MACCommandIdentifier_CID_RX_PARAM_SETUP MACCommandIdentifier = 5
+ MACCommandIdentifier_CID_DEV_STATUS MACCommandIdentifier = 6
+ MACCommandIdentifier_CID_NEW_CHANNEL MACCommandIdentifier = 7
+ MACCommandIdentifier_CID_RX_TIMING_SETUP MACCommandIdentifier = 8
+ MACCommandIdentifier_CID_TX_PARAM_SETUP MACCommandIdentifier = 9
+ MACCommandIdentifier_CID_DL_CHANNEL MACCommandIdentifier = 10
+ MACCommandIdentifier_CID_REKEY MACCommandIdentifier = 11
+ MACCommandIdentifier_CID_ADR_PARAM_SETUP MACCommandIdentifier = 12
+ MACCommandIdentifier_CID_DEVICE_TIME MACCommandIdentifier = 13
+ MACCommandIdentifier_CID_FORCE_REJOIN MACCommandIdentifier = 14
+ MACCommandIdentifier_CID_REJOIN_PARAM_SETUP MACCommandIdentifier = 15
+ MACCommandIdentifier_CID_PING_SLOT_INFO MACCommandIdentifier = 16
+ MACCommandIdentifier_CID_PING_SLOT_CHANNEL MACCommandIdentifier = 17
+ MACCommandIdentifier_CID_BEACON_TIMING MACCommandIdentifier = 18 // Deprecated
+ MACCommandIdentifier_CID_BEACON_FREQ MACCommandIdentifier = 19
+ MACCommandIdentifier_CID_DEVICE_MODE MACCommandIdentifier = 32
+ MACCommandIdentifier_CID_RELAY_CONF MACCommandIdentifier = 64
+ MACCommandIdentifier_CID_RELAY_END_DEVICE_CONF MACCommandIdentifier = 65
+ MACCommandIdentifier_CID_RELAY_FILTER_LIST MACCommandIdentifier = 66
+ MACCommandIdentifier_CID_RELAY_UPDATE_UPLINK_LIST MACCommandIdentifier = 67
+ MACCommandIdentifier_CID_RELAY_CTRL_UPLINK_LIST MACCommandIdentifier = 68
+ MACCommandIdentifier_CID_RELAY_CONFIGURE_FWD_LIMIT MACCommandIdentifier = 69
+ MACCommandIdentifier_CID_RELAY_NOTIFY_NEW_END_DEVICE MACCommandIdentifier = 70
)
// Enum value maps for MACCommandIdentifier.
@@ -767,29 +774,43 @@ var (
18: "CID_BEACON_TIMING",
19: "CID_BEACON_FREQ",
32: "CID_DEVICE_MODE",
+ 64: "CID_RELAY_CONF",
+ 65: "CID_RELAY_END_DEVICE_CONF",
+ 66: "CID_RELAY_FILTER_LIST",
+ 67: "CID_RELAY_UPDATE_UPLINK_LIST",
+ 68: "CID_RELAY_CTRL_UPLINK_LIST",
+ 69: "CID_RELAY_CONFIGURE_FWD_LIMIT",
+ 70: "CID_RELAY_NOTIFY_NEW_END_DEVICE",
}
MACCommandIdentifier_value = map[string]int32{
- "CID_RFU_0": 0,
- "CID_RESET": 1,
- "CID_LINK_CHECK": 2,
- "CID_LINK_ADR": 3,
- "CID_DUTY_CYCLE": 4,
- "CID_RX_PARAM_SETUP": 5,
- "CID_DEV_STATUS": 6,
- "CID_NEW_CHANNEL": 7,
- "CID_RX_TIMING_SETUP": 8,
- "CID_TX_PARAM_SETUP": 9,
- "CID_DL_CHANNEL": 10,
- "CID_REKEY": 11,
- "CID_ADR_PARAM_SETUP": 12,
- "CID_DEVICE_TIME": 13,
- "CID_FORCE_REJOIN": 14,
- "CID_REJOIN_PARAM_SETUP": 15,
- "CID_PING_SLOT_INFO": 16,
- "CID_PING_SLOT_CHANNEL": 17,
- "CID_BEACON_TIMING": 18,
- "CID_BEACON_FREQ": 19,
- "CID_DEVICE_MODE": 32,
+ "CID_RFU_0": 0,
+ "CID_RESET": 1,
+ "CID_LINK_CHECK": 2,
+ "CID_LINK_ADR": 3,
+ "CID_DUTY_CYCLE": 4,
+ "CID_RX_PARAM_SETUP": 5,
+ "CID_DEV_STATUS": 6,
+ "CID_NEW_CHANNEL": 7,
+ "CID_RX_TIMING_SETUP": 8,
+ "CID_TX_PARAM_SETUP": 9,
+ "CID_DL_CHANNEL": 10,
+ "CID_REKEY": 11,
+ "CID_ADR_PARAM_SETUP": 12,
+ "CID_DEVICE_TIME": 13,
+ "CID_FORCE_REJOIN": 14,
+ "CID_REJOIN_PARAM_SETUP": 15,
+ "CID_PING_SLOT_INFO": 16,
+ "CID_PING_SLOT_CHANNEL": 17,
+ "CID_BEACON_TIMING": 18,
+ "CID_BEACON_FREQ": 19,
+ "CID_DEVICE_MODE": 32,
+ "CID_RELAY_CONF": 64,
+ "CID_RELAY_END_DEVICE_CONF": 65,
+ "CID_RELAY_FILTER_LIST": 66,
+ "CID_RELAY_UPDATE_UPLINK_LIST": 67,
+ "CID_RELAY_CTRL_UPLINK_LIST": 68,
+ "CID_RELAY_CONFIGURE_FWD_LIMIT": 69,
+ "CID_RELAY_NOTIFY_NEW_END_DEVICE": 70,
}
)
@@ -820,6 +841,370 @@ func (MACCommandIdentifier) EnumDescriptor() ([]byte, []int) {
return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{11}
}
+type RelayCADPeriodicity int32
+
+const (
+ RelayCADPeriodicity_RELAY_CAD_PERIODICITY_1_SECOND RelayCADPeriodicity = 0
+ RelayCADPeriodicity_RELAY_CAD_PERIODICITY_500_MILLISECONDS RelayCADPeriodicity = 1
+ RelayCADPeriodicity_RELAY_CAD_PERIODICITY_250_MILLISECONDS RelayCADPeriodicity = 2
+ RelayCADPeriodicity_RELAY_CAD_PERIODICITY_100_MILLISECONDS RelayCADPeriodicity = 3
+ RelayCADPeriodicity_RELAY_CAD_PERIODICITY_50_MILLISECONDS RelayCADPeriodicity = 4
+ RelayCADPeriodicity_RELAY_CAD_PERIODICITY_20_MILLISECONDS RelayCADPeriodicity = 5 // sic
+)
+
+// Enum value maps for RelayCADPeriodicity.
+var (
+ RelayCADPeriodicity_name = map[int32]string{
+ 0: "RELAY_CAD_PERIODICITY_1_SECOND",
+ 1: "RELAY_CAD_PERIODICITY_500_MILLISECONDS",
+ 2: "RELAY_CAD_PERIODICITY_250_MILLISECONDS",
+ 3: "RELAY_CAD_PERIODICITY_100_MILLISECONDS",
+ 4: "RELAY_CAD_PERIODICITY_50_MILLISECONDS",
+ 5: "RELAY_CAD_PERIODICITY_20_MILLISECONDS",
+ }
+ RelayCADPeriodicity_value = map[string]int32{
+ "RELAY_CAD_PERIODICITY_1_SECOND": 0,
+ "RELAY_CAD_PERIODICITY_500_MILLISECONDS": 1,
+ "RELAY_CAD_PERIODICITY_250_MILLISECONDS": 2,
+ "RELAY_CAD_PERIODICITY_100_MILLISECONDS": 3,
+ "RELAY_CAD_PERIODICITY_50_MILLISECONDS": 4,
+ "RELAY_CAD_PERIODICITY_20_MILLISECONDS": 5,
+ }
+)
+
+func (x RelayCADPeriodicity) Enum() *RelayCADPeriodicity {
+ p := new(RelayCADPeriodicity)
+ *p = x
+ return p
+}
+
+func (x RelayCADPeriodicity) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (RelayCADPeriodicity) Descriptor() protoreflect.EnumDescriptor {
+ return file_ttn_lorawan_v3_lorawan_proto_enumTypes[12].Descriptor()
+}
+
+func (RelayCADPeriodicity) Type() protoreflect.EnumType {
+ return &file_ttn_lorawan_v3_lorawan_proto_enumTypes[12]
+}
+
+func (x RelayCADPeriodicity) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use RelayCADPeriodicity.Descriptor instead.
+func (RelayCADPeriodicity) EnumDescriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{12}
+}
+
+type RelaySecondChAckOffset int32
+
+const (
+ RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_0 RelaySecondChAckOffset = 0 // 0 kHz
+ RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_200 RelaySecondChAckOffset = 1 // 200 kHz
+ RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_400 RelaySecondChAckOffset = 2 // 400 kHz
+ RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_800 RelaySecondChAckOffset = 3 // 800 kHz
+ RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_1600 RelaySecondChAckOffset = 4 // 1.6 MHz
+ RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_3200 RelaySecondChAckOffset = 5 // 3.2 MHz
+)
+
+// Enum value maps for RelaySecondChAckOffset.
+var (
+ RelaySecondChAckOffset_name = map[int32]string{
+ 0: "RELAY_SECOND_CH_ACK_OFFSET_0",
+ 1: "RELAY_SECOND_CH_ACK_OFFSET_200",
+ 2: "RELAY_SECOND_CH_ACK_OFFSET_400",
+ 3: "RELAY_SECOND_CH_ACK_OFFSET_800",
+ 4: "RELAY_SECOND_CH_ACK_OFFSET_1600",
+ 5: "RELAY_SECOND_CH_ACK_OFFSET_3200",
+ }
+ RelaySecondChAckOffset_value = map[string]int32{
+ "RELAY_SECOND_CH_ACK_OFFSET_0": 0,
+ "RELAY_SECOND_CH_ACK_OFFSET_200": 1,
+ "RELAY_SECOND_CH_ACK_OFFSET_400": 2,
+ "RELAY_SECOND_CH_ACK_OFFSET_800": 3,
+ "RELAY_SECOND_CH_ACK_OFFSET_1600": 4,
+ "RELAY_SECOND_CH_ACK_OFFSET_3200": 5,
+ }
+)
+
+func (x RelaySecondChAckOffset) Enum() *RelaySecondChAckOffset {
+ p := new(RelaySecondChAckOffset)
+ *p = x
+ return p
+}
+
+func (x RelaySecondChAckOffset) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (RelaySecondChAckOffset) Descriptor() protoreflect.EnumDescriptor {
+ return file_ttn_lorawan_v3_lorawan_proto_enumTypes[13].Descriptor()
+}
+
+func (RelaySecondChAckOffset) Type() protoreflect.EnumType {
+ return &file_ttn_lorawan_v3_lorawan_proto_enumTypes[13]
+}
+
+func (x RelaySecondChAckOffset) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use RelaySecondChAckOffset.Descriptor instead.
+func (RelaySecondChAckOffset) EnumDescriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{13}
+}
+
+type RelayLimitBucketSize int32
+
+const (
+ RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_1 RelayLimitBucketSize = 0
+ RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_2 RelayLimitBucketSize = 1
+ RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_4 RelayLimitBucketSize = 2
+ RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_12 RelayLimitBucketSize = 3 // sic
+)
+
+// Enum value maps for RelayLimitBucketSize.
+var (
+ RelayLimitBucketSize_name = map[int32]string{
+ 0: "RELAY_LIMIT_BUCKET_SIZE_1",
+ 1: "RELAY_LIMIT_BUCKET_SIZE_2",
+ 2: "RELAY_LIMIT_BUCKET_SIZE_4",
+ 3: "RELAY_LIMIT_BUCKET_SIZE_12",
+ }
+ RelayLimitBucketSize_value = map[string]int32{
+ "RELAY_LIMIT_BUCKET_SIZE_1": 0,
+ "RELAY_LIMIT_BUCKET_SIZE_2": 1,
+ "RELAY_LIMIT_BUCKET_SIZE_4": 2,
+ "RELAY_LIMIT_BUCKET_SIZE_12": 3,
+ }
+)
+
+func (x RelayLimitBucketSize) Enum() *RelayLimitBucketSize {
+ p := new(RelayLimitBucketSize)
+ *p = x
+ return p
+}
+
+func (x RelayLimitBucketSize) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (RelayLimitBucketSize) Descriptor() protoreflect.EnumDescriptor {
+ return file_ttn_lorawan_v3_lorawan_proto_enumTypes[14].Descriptor()
+}
+
+func (RelayLimitBucketSize) Type() protoreflect.EnumType {
+ return &file_ttn_lorawan_v3_lorawan_proto_enumTypes[14]
+}
+
+func (x RelayLimitBucketSize) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use RelayLimitBucketSize.Descriptor instead.
+func (RelayLimitBucketSize) EnumDescriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{14}
+}
+
+type RelaySmartEnableLevel int32
+
+const (
+ RelaySmartEnableLevel_RELAY_SMART_ENABLE_LEVEL_8 RelaySmartEnableLevel = 0
+ RelaySmartEnableLevel_RELAY_SMART_ENABLE_LEVEL_16 RelaySmartEnableLevel = 1
+ RelaySmartEnableLevel_RELAY_SMART_ENABLE_LEVEL_32 RelaySmartEnableLevel = 2
+ RelaySmartEnableLevel_RELAY_SMART_ENABLE_LEVEL_64 RelaySmartEnableLevel = 3
+)
+
+// Enum value maps for RelaySmartEnableLevel.
+var (
+ RelaySmartEnableLevel_name = map[int32]string{
+ 0: "RELAY_SMART_ENABLE_LEVEL_8",
+ 1: "RELAY_SMART_ENABLE_LEVEL_16",
+ 2: "RELAY_SMART_ENABLE_LEVEL_32",
+ 3: "RELAY_SMART_ENABLE_LEVEL_64",
+ }
+ RelaySmartEnableLevel_value = map[string]int32{
+ "RELAY_SMART_ENABLE_LEVEL_8": 0,
+ "RELAY_SMART_ENABLE_LEVEL_16": 1,
+ "RELAY_SMART_ENABLE_LEVEL_32": 2,
+ "RELAY_SMART_ENABLE_LEVEL_64": 3,
+ }
+)
+
+func (x RelaySmartEnableLevel) Enum() *RelaySmartEnableLevel {
+ p := new(RelaySmartEnableLevel)
+ *p = x
+ return p
+}
+
+func (x RelaySmartEnableLevel) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (RelaySmartEnableLevel) Descriptor() protoreflect.EnumDescriptor {
+ return file_ttn_lorawan_v3_lorawan_proto_enumTypes[15].Descriptor()
+}
+
+func (RelaySmartEnableLevel) Type() protoreflect.EnumType {
+ return &file_ttn_lorawan_v3_lorawan_proto_enumTypes[15]
+}
+
+func (x RelaySmartEnableLevel) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use RelaySmartEnableLevel.Descriptor instead.
+func (RelaySmartEnableLevel) EnumDescriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{15}
+}
+
+type RelayWORChannel int32
+
+const (
+ RelayWORChannel_RELAY_WOR_CHANNEL_DEFAULT RelayWORChannel = 0
+ RelayWORChannel_RELAY_WOR_CHANNEL_SECONDARY RelayWORChannel = 1
+)
+
+// Enum value maps for RelayWORChannel.
+var (
+ RelayWORChannel_name = map[int32]string{
+ 0: "RELAY_WOR_CHANNEL_DEFAULT",
+ 1: "RELAY_WOR_CHANNEL_SECONDARY",
+ }
+ RelayWORChannel_value = map[string]int32{
+ "RELAY_WOR_CHANNEL_DEFAULT": 0,
+ "RELAY_WOR_CHANNEL_SECONDARY": 1,
+ }
+)
+
+func (x RelayWORChannel) Enum() *RelayWORChannel {
+ p := new(RelayWORChannel)
+ *p = x
+ return p
+}
+
+func (x RelayWORChannel) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (RelayWORChannel) Descriptor() protoreflect.EnumDescriptor {
+ return file_ttn_lorawan_v3_lorawan_proto_enumTypes[16].Descriptor()
+}
+
+func (RelayWORChannel) Type() protoreflect.EnumType {
+ return &file_ttn_lorawan_v3_lorawan_proto_enumTypes[16]
+}
+
+func (x RelayWORChannel) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use RelayWORChannel.Descriptor instead.
+func (RelayWORChannel) EnumDescriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{16}
+}
+
+type RelayResetLimitCounter int32
+
+const (
+ RelayResetLimitCounter_RELAY_RESET_LIMIT_COUNTER_ZERO RelayResetLimitCounter = 0
+ RelayResetLimitCounter_RELAY_RESET_LIMIT_COUNTER_RELOAD_RATE RelayResetLimitCounter = 1
+ RelayResetLimitCounter_RELAY_RESET_LIMIT_COUNTER_MAX_VALUE RelayResetLimitCounter = 2
+ RelayResetLimitCounter_RELAY_RESET_LIMIT_COUNTER_NO_RESET RelayResetLimitCounter = 3
+)
+
+// Enum value maps for RelayResetLimitCounter.
+var (
+ RelayResetLimitCounter_name = map[int32]string{
+ 0: "RELAY_RESET_LIMIT_COUNTER_ZERO",
+ 1: "RELAY_RESET_LIMIT_COUNTER_RELOAD_RATE",
+ 2: "RELAY_RESET_LIMIT_COUNTER_MAX_VALUE",
+ 3: "RELAY_RESET_LIMIT_COUNTER_NO_RESET",
+ }
+ RelayResetLimitCounter_value = map[string]int32{
+ "RELAY_RESET_LIMIT_COUNTER_ZERO": 0,
+ "RELAY_RESET_LIMIT_COUNTER_RELOAD_RATE": 1,
+ "RELAY_RESET_LIMIT_COUNTER_MAX_VALUE": 2,
+ "RELAY_RESET_LIMIT_COUNTER_NO_RESET": 3,
+ }
+)
+
+func (x RelayResetLimitCounter) Enum() *RelayResetLimitCounter {
+ p := new(RelayResetLimitCounter)
+ *p = x
+ return p
+}
+
+func (x RelayResetLimitCounter) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (RelayResetLimitCounter) Descriptor() protoreflect.EnumDescriptor {
+ return file_ttn_lorawan_v3_lorawan_proto_enumTypes[17].Descriptor()
+}
+
+func (RelayResetLimitCounter) Type() protoreflect.EnumType {
+ return &file_ttn_lorawan_v3_lorawan_proto_enumTypes[17]
+}
+
+func (x RelayResetLimitCounter) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use RelayResetLimitCounter.Descriptor instead.
+func (RelayResetLimitCounter) EnumDescriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{17}
+}
+
+type RelayCtrlUplinkListAction int32
+
+const (
+ RelayCtrlUplinkListAction_RELAY_CTRL_UPLINK_LIST_ACTION_READ_W_F_CNT RelayCtrlUplinkListAction = 0
+ RelayCtrlUplinkListAction_RELAY_CTRL_UPLINK_LIST_ACTION_REMOVE_TRUSTED_END_DEVICE RelayCtrlUplinkListAction = 1
+)
+
+// Enum value maps for RelayCtrlUplinkListAction.
+var (
+ RelayCtrlUplinkListAction_name = map[int32]string{
+ 0: "RELAY_CTRL_UPLINK_LIST_ACTION_READ_W_F_CNT",
+ 1: "RELAY_CTRL_UPLINK_LIST_ACTION_REMOVE_TRUSTED_END_DEVICE",
+ }
+ RelayCtrlUplinkListAction_value = map[string]int32{
+ "RELAY_CTRL_UPLINK_LIST_ACTION_READ_W_F_CNT": 0,
+ "RELAY_CTRL_UPLINK_LIST_ACTION_REMOVE_TRUSTED_END_DEVICE": 1,
+ }
+)
+
+func (x RelayCtrlUplinkListAction) Enum() *RelayCtrlUplinkListAction {
+ p := new(RelayCtrlUplinkListAction)
+ *p = x
+ return p
+}
+
+func (x RelayCtrlUplinkListAction) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (RelayCtrlUplinkListAction) Descriptor() protoreflect.EnumDescriptor {
+ return file_ttn_lorawan_v3_lorawan_proto_enumTypes[18].Descriptor()
+}
+
+func (RelayCtrlUplinkListAction) Type() protoreflect.EnumType {
+ return &file_ttn_lorawan_v3_lorawan_proto_enumTypes[18]
+}
+
+func (x RelayCtrlUplinkListAction) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use RelayCtrlUplinkListAction.Descriptor instead.
+func (RelayCtrlUplinkListAction) EnumDescriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{18}
+}
+
type AggregatedDutyCycle int32
const (
@@ -892,11 +1277,11 @@ func (x AggregatedDutyCycle) String() string {
}
func (AggregatedDutyCycle) Descriptor() protoreflect.EnumDescriptor {
- return file_ttn_lorawan_v3_lorawan_proto_enumTypes[12].Descriptor()
+ return file_ttn_lorawan_v3_lorawan_proto_enumTypes[19].Descriptor()
}
func (AggregatedDutyCycle) Type() protoreflect.EnumType {
- return &file_ttn_lorawan_v3_lorawan_proto_enumTypes[12]
+ return &file_ttn_lorawan_v3_lorawan_proto_enumTypes[19]
}
func (x AggregatedDutyCycle) Number() protoreflect.EnumNumber {
@@ -905,7 +1290,7 @@ func (x AggregatedDutyCycle) Number() protoreflect.EnumNumber {
// Deprecated: Use AggregatedDutyCycle.Descriptor instead.
func (AggregatedDutyCycle) EnumDescriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{12}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{19}
}
type PingSlotPeriod int32
@@ -956,11 +1341,11 @@ func (x PingSlotPeriod) String() string {
}
func (PingSlotPeriod) Descriptor() protoreflect.EnumDescriptor {
- return file_ttn_lorawan_v3_lorawan_proto_enumTypes[13].Descriptor()
+ return file_ttn_lorawan_v3_lorawan_proto_enumTypes[20].Descriptor()
}
func (PingSlotPeriod) Type() protoreflect.EnumType {
- return &file_ttn_lorawan_v3_lorawan_proto_enumTypes[13]
+ return &file_ttn_lorawan_v3_lorawan_proto_enumTypes[20]
}
func (x PingSlotPeriod) Number() protoreflect.EnumNumber {
@@ -969,7 +1354,7 @@ func (x PingSlotPeriod) Number() protoreflect.EnumNumber {
// Deprecated: Use PingSlotPeriod.Descriptor instead.
func (PingSlotPeriod) EnumDescriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{13}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20}
}
type RejoinCountExponent int32
@@ -1044,11 +1429,11 @@ func (x RejoinCountExponent) String() string {
}
func (RejoinCountExponent) Descriptor() protoreflect.EnumDescriptor {
- return file_ttn_lorawan_v3_lorawan_proto_enumTypes[14].Descriptor()
+ return file_ttn_lorawan_v3_lorawan_proto_enumTypes[21].Descriptor()
}
func (RejoinCountExponent) Type() protoreflect.EnumType {
- return &file_ttn_lorawan_v3_lorawan_proto_enumTypes[14]
+ return &file_ttn_lorawan_v3_lorawan_proto_enumTypes[21]
}
func (x RejoinCountExponent) Number() protoreflect.EnumNumber {
@@ -1057,7 +1442,7 @@ func (x RejoinCountExponent) Number() protoreflect.EnumNumber {
// Deprecated: Use RejoinCountExponent.Descriptor instead.
func (RejoinCountExponent) EnumDescriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{14}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{21}
}
type RejoinTimeExponent int32
@@ -1132,11 +1517,11 @@ func (x RejoinTimeExponent) String() string {
}
func (RejoinTimeExponent) Descriptor() protoreflect.EnumDescriptor {
- return file_ttn_lorawan_v3_lorawan_proto_enumTypes[15].Descriptor()
+ return file_ttn_lorawan_v3_lorawan_proto_enumTypes[22].Descriptor()
}
func (RejoinTimeExponent) Type() protoreflect.EnumType {
- return &file_ttn_lorawan_v3_lorawan_proto_enumTypes[15]
+ return &file_ttn_lorawan_v3_lorawan_proto_enumTypes[22]
}
func (x RejoinTimeExponent) Number() protoreflect.EnumNumber {
@@ -1145,7 +1530,7 @@ func (x RejoinTimeExponent) Number() protoreflect.EnumNumber {
// Deprecated: Use RejoinTimeExponent.Descriptor instead.
func (RejoinTimeExponent) EnumDescriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{15}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{22}
}
type RejoinPeriodExponent int32
@@ -1196,11 +1581,11 @@ func (x RejoinPeriodExponent) String() string {
}
func (RejoinPeriodExponent) Descriptor() protoreflect.EnumDescriptor {
- return file_ttn_lorawan_v3_lorawan_proto_enumTypes[16].Descriptor()
+ return file_ttn_lorawan_v3_lorawan_proto_enumTypes[23].Descriptor()
}
func (RejoinPeriodExponent) Type() protoreflect.EnumType {
- return &file_ttn_lorawan_v3_lorawan_proto_enumTypes[16]
+ return &file_ttn_lorawan_v3_lorawan_proto_enumTypes[23]
}
func (x RejoinPeriodExponent) Number() protoreflect.EnumNumber {
@@ -1209,7 +1594,7 @@ func (x RejoinPeriodExponent) Number() protoreflect.EnumNumber {
// Deprecated: Use RejoinPeriodExponent.Descriptor instead.
func (RejoinPeriodExponent) EnumDescriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{16}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{23}
}
type DeviceEIRP int32
@@ -1284,11 +1669,11 @@ func (x DeviceEIRP) String() string {
}
func (DeviceEIRP) Descriptor() protoreflect.EnumDescriptor {
- return file_ttn_lorawan_v3_lorawan_proto_enumTypes[17].Descriptor()
+ return file_ttn_lorawan_v3_lorawan_proto_enumTypes[24].Descriptor()
}
func (DeviceEIRP) Type() protoreflect.EnumType {
- return &file_ttn_lorawan_v3_lorawan_proto_enumTypes[17]
+ return &file_ttn_lorawan_v3_lorawan_proto_enumTypes[24]
}
func (x DeviceEIRP) Number() protoreflect.EnumNumber {
@@ -1297,7 +1682,7 @@ func (x DeviceEIRP) Number() protoreflect.EnumNumber {
// Deprecated: Use DeviceEIRP.Descriptor instead.
func (DeviceEIRP) EnumDescriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{17}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{24}
}
type ADRAckLimitExponent int32
@@ -1372,11 +1757,11 @@ func (x ADRAckLimitExponent) String() string {
}
func (ADRAckLimitExponent) Descriptor() protoreflect.EnumDescriptor {
- return file_ttn_lorawan_v3_lorawan_proto_enumTypes[18].Descriptor()
+ return file_ttn_lorawan_v3_lorawan_proto_enumTypes[25].Descriptor()
}
func (ADRAckLimitExponent) Type() protoreflect.EnumType {
- return &file_ttn_lorawan_v3_lorawan_proto_enumTypes[18]
+ return &file_ttn_lorawan_v3_lorawan_proto_enumTypes[25]
}
func (x ADRAckLimitExponent) Number() protoreflect.EnumNumber {
@@ -1385,7 +1770,7 @@ func (x ADRAckLimitExponent) Number() protoreflect.EnumNumber {
// Deprecated: Use ADRAckLimitExponent.Descriptor instead.
func (ADRAckLimitExponent) EnumDescriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{18}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{25}
}
type ADRAckDelayExponent int32
@@ -1460,11 +1845,11 @@ func (x ADRAckDelayExponent) String() string {
}
func (ADRAckDelayExponent) Descriptor() protoreflect.EnumDescriptor {
- return file_ttn_lorawan_v3_lorawan_proto_enumTypes[19].Descriptor()
+ return file_ttn_lorawan_v3_lorawan_proto_enumTypes[26].Descriptor()
}
func (ADRAckDelayExponent) Type() protoreflect.EnumType {
- return &file_ttn_lorawan_v3_lorawan_proto_enumTypes[19]
+ return &file_ttn_lorawan_v3_lorawan_proto_enumTypes[26]
}
func (x ADRAckDelayExponent) Number() protoreflect.EnumNumber {
@@ -1473,7 +1858,7 @@ func (x ADRAckDelayExponent) Number() protoreflect.EnumNumber {
// Deprecated: Use ADRAckDelayExponent.Descriptor instead.
func (ADRAckDelayExponent) EnumDescriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{19}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26}
}
type RxDelay int32
@@ -1548,11 +1933,11 @@ func (x RxDelay) String() string {
}
func (RxDelay) Descriptor() protoreflect.EnumDescriptor {
- return file_ttn_lorawan_v3_lorawan_proto_enumTypes[20].Descriptor()
+ return file_ttn_lorawan_v3_lorawan_proto_enumTypes[27].Descriptor()
}
func (RxDelay) Type() protoreflect.EnumType {
- return &file_ttn_lorawan_v3_lorawan_proto_enumTypes[20]
+ return &file_ttn_lorawan_v3_lorawan_proto_enumTypes[27]
}
func (x RxDelay) Number() protoreflect.EnumNumber {
@@ -1561,7 +1946,7 @@ func (x RxDelay) Number() protoreflect.EnumNumber {
// Deprecated: Use RxDelay.Descriptor instead.
func (RxDelay) EnumDescriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{27}
}
type Minor int32
@@ -1636,11 +2021,11 @@ func (x Minor) String() string {
}
func (Minor) Descriptor() protoreflect.EnumDescriptor {
- return file_ttn_lorawan_v3_lorawan_proto_enumTypes[21].Descriptor()
+ return file_ttn_lorawan_v3_lorawan_proto_enumTypes[28].Descriptor()
}
func (Minor) Type() protoreflect.EnumType {
- return &file_ttn_lorawan_v3_lorawan_proto_enumTypes[21]
+ return &file_ttn_lorawan_v3_lorawan_proto_enumTypes[28]
}
func (x Minor) Number() protoreflect.EnumNumber {
@@ -1649,7 +2034,7 @@ func (x Minor) Number() protoreflect.EnumNumber {
// Deprecated: Use Minor.Descriptor instead.
func (Minor) EnumDescriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{21}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{28}
}
// Message represents a LoRaWAN message
@@ -3250,29 +3635,336 @@ func (x *TxRequest) GetAdvanced() *structpb.Struct {
return nil
}
-type MACCommand struct {
+type RelaySecondChannel struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
- Cid MACCommandIdentifier `protobuf:"varint,1,opt,name=cid,proto3,enum=ttn.lorawan.v3.MACCommandIdentifier" json:"cid,omitempty"`
- // Types that are assignable to Payload:
- // *MACCommand_RawPayload
- // *MACCommand_ResetInd_
- // *MACCommand_ResetConf_
- // *MACCommand_LinkCheckAns_
- // *MACCommand_LinkAdrReq
- // *MACCommand_LinkAdrAns
- // *MACCommand_DutyCycleReq_
- // *MACCommand_RxParamSetupReq_
- // *MACCommand_RxParamSetupAns_
- // *MACCommand_DevStatusAns_
- // *MACCommand_NewChannelReq_
- // *MACCommand_NewChannelAns_
- // *MACCommand_DlChannelReq
- // *MACCommand_DlChannelAns
- // *MACCommand_RxTimingSetupReq_
- // *MACCommand_TxParamSetupReq_
+ // The frequency (Hz) offset used for the WOR acknowledgement.
+ AckOffset RelaySecondChAckOffset `protobuf:"varint,1,opt,name=ack_offset,json=ackOffset,proto3,enum=ttn.lorawan.v3.RelaySecondChAckOffset" json:"ack_offset,omitempty"`
+ // The data rate index used by the WOR and WOR acknowledgement.
+ DataRateIndex DataRateIndex `protobuf:"varint,2,opt,name=data_rate_index,json=dataRateIndex,proto3,enum=ttn.lorawan.v3.DataRateIndex" json:"data_rate_index,omitempty"`
+ // The frequency (Hz) used by the wake on radio message.
+ Frequency uint64 `protobuf:"varint,3,opt,name=frequency,proto3" json:"frequency,omitempty"`
+}
+
+func (x *RelaySecondChannel) Reset() {
+ *x = RelaySecondChannel{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[20]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *RelaySecondChannel) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RelaySecondChannel) ProtoMessage() {}
+
+func (x *RelaySecondChannel) ProtoReflect() protoreflect.Message {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[20]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use RelaySecondChannel.ProtoReflect.Descriptor instead.
+func (*RelaySecondChannel) Descriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20}
+}
+
+func (x *RelaySecondChannel) GetAckOffset() RelaySecondChAckOffset {
+ if x != nil {
+ return x.AckOffset
+ }
+ return RelaySecondChAckOffset_RELAY_SECOND_CH_ACK_OFFSET_0
+}
+
+func (x *RelaySecondChannel) GetDataRateIndex() DataRateIndex {
+ if x != nil {
+ return x.DataRateIndex
+ }
+ return DataRateIndex_DATA_RATE_0
+}
+
+func (x *RelaySecondChannel) GetFrequency() uint64 {
+ if x != nil {
+ return x.Frequency
+ }
+ return 0
+}
+
+type RelayUplinkForwardLimits struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // The multiplier used to compute the total bucket size for the limits.
+ // The multiplier is multiplied by the reload rate in order to compute the total bucket size.
+ BucketSize RelayLimitBucketSize `protobuf:"varint,1,opt,name=bucket_size,json=bucketSize,proto3,enum=ttn.lorawan.v3.RelayLimitBucketSize" json:"bucket_size,omitempty"`
+ // The number of tokens which are replenished in the bucket every hour.
+ ReloadRate uint32 `protobuf:"varint,2,opt,name=reload_rate,json=reloadRate,proto3" json:"reload_rate,omitempty"`
+}
+
+func (x *RelayUplinkForwardLimits) Reset() {
+ *x = RelayUplinkForwardLimits{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[21]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *RelayUplinkForwardLimits) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RelayUplinkForwardLimits) ProtoMessage() {}
+
+func (x *RelayUplinkForwardLimits) ProtoReflect() protoreflect.Message {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[21]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use RelayUplinkForwardLimits.ProtoReflect.Descriptor instead.
+func (*RelayUplinkForwardLimits) Descriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{21}
+}
+
+func (x *RelayUplinkForwardLimits) GetBucketSize() RelayLimitBucketSize {
+ if x != nil {
+ return x.BucketSize
+ }
+ return RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_1
+}
+
+func (x *RelayUplinkForwardLimits) GetReloadRate() uint32 {
+ if x != nil {
+ return x.ReloadRate
+ }
+ return 0
+}
+
+type RelayForwardLimits struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // The multiplier used to compute the total bucket size for the limits.
+ // The multiplier is multiplied by the reload rate in order to compute the total bucket size.
+ BucketSize RelayLimitBucketSize `protobuf:"varint,1,opt,name=bucket_size,json=bucketSize,proto3,enum=ttn.lorawan.v3.RelayLimitBucketSize" json:"bucket_size,omitempty"`
+ // The number of tokens which are replenished in the bucket every hour.
+ ReloadRate uint32 `protobuf:"varint,2,opt,name=reload_rate,json=reloadRate,proto3" json:"reload_rate,omitempty"`
+}
+
+func (x *RelayForwardLimits) Reset() {
+ *x = RelayForwardLimits{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[22]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *RelayForwardLimits) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RelayForwardLimits) ProtoMessage() {}
+
+func (x *RelayForwardLimits) ProtoReflect() protoreflect.Message {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[22]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use RelayForwardLimits.ProtoReflect.Descriptor instead.
+func (*RelayForwardLimits) Descriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{22}
+}
+
+func (x *RelayForwardLimits) GetBucketSize() RelayLimitBucketSize {
+ if x != nil {
+ return x.BucketSize
+ }
+ return RelayLimitBucketSize_RELAY_LIMIT_BUCKET_SIZE_1
+}
+
+func (x *RelayForwardLimits) GetReloadRate() uint32 {
+ if x != nil {
+ return x.ReloadRate
+ }
+ return 0
+}
+
+type RelayEndDeviceAlwaysMode struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+}
+
+func (x *RelayEndDeviceAlwaysMode) Reset() {
+ *x = RelayEndDeviceAlwaysMode{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[23]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *RelayEndDeviceAlwaysMode) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RelayEndDeviceAlwaysMode) ProtoMessage() {}
+
+func (x *RelayEndDeviceAlwaysMode) ProtoReflect() protoreflect.Message {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[23]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use RelayEndDeviceAlwaysMode.ProtoReflect.Descriptor instead.
+func (*RelayEndDeviceAlwaysMode) Descriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{23}
+}
+
+type RelayEndDeviceDynamicMode struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // The number of consecutive uplinks without a valid downlink before the end device attempts
+ // to use the relay mode to transmit messages.
+ SmartEnableLevel RelaySmartEnableLevel `protobuf:"varint,1,opt,name=smart_enable_level,json=smartEnableLevel,proto3,enum=ttn.lorawan.v3.RelaySmartEnableLevel" json:"smart_enable_level,omitempty"`
+}
+
+func (x *RelayEndDeviceDynamicMode) Reset() {
+ *x = RelayEndDeviceDynamicMode{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[24]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *RelayEndDeviceDynamicMode) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RelayEndDeviceDynamicMode) ProtoMessage() {}
+
+func (x *RelayEndDeviceDynamicMode) ProtoReflect() protoreflect.Message {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[24]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use RelayEndDeviceDynamicMode.ProtoReflect.Descriptor instead.
+func (*RelayEndDeviceDynamicMode) Descriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{24}
+}
+
+func (x *RelayEndDeviceDynamicMode) GetSmartEnableLevel() RelaySmartEnableLevel {
+ if x != nil {
+ return x.SmartEnableLevel
+ }
+ return RelaySmartEnableLevel_RELAY_SMART_ENABLE_LEVEL_8
+}
+
+type RelayEndDeviceControlledMode struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+}
+
+func (x *RelayEndDeviceControlledMode) Reset() {
+ *x = RelayEndDeviceControlledMode{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[25]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *RelayEndDeviceControlledMode) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RelayEndDeviceControlledMode) ProtoMessage() {}
+
+func (x *RelayEndDeviceControlledMode) ProtoReflect() protoreflect.Message {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[25]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use RelayEndDeviceControlledMode.ProtoReflect.Descriptor instead.
+func (*RelayEndDeviceControlledMode) Descriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{25}
+}
+
+type MACCommand struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Cid MACCommandIdentifier `protobuf:"varint,1,opt,name=cid,proto3,enum=ttn.lorawan.v3.MACCommandIdentifier" json:"cid,omitempty"`
+ // Types that are assignable to Payload:
+ // *MACCommand_RawPayload
+ // *MACCommand_ResetInd_
+ // *MACCommand_ResetConf_
+ // *MACCommand_LinkCheckAns_
+ // *MACCommand_LinkAdrReq
+ // *MACCommand_LinkAdrAns
+ // *MACCommand_DutyCycleReq_
+ // *MACCommand_RxParamSetupReq_
+ // *MACCommand_RxParamSetupAns_
+ // *MACCommand_DevStatusAns_
+ // *MACCommand_NewChannelReq_
+ // *MACCommand_NewChannelAns_
+ // *MACCommand_DlChannelReq
+ // *MACCommand_DlChannelAns
+ // *MACCommand_RxTimingSetupReq_
+ // *MACCommand_TxParamSetupReq_
// *MACCommand_RekeyInd_
// *MACCommand_RekeyConf_
// *MACCommand_AdrParamSetupReq
@@ -3288,13 +3980,24 @@ type MACCommand struct {
// *MACCommand_BeaconFreqAns_
// *MACCommand_DeviceModeInd_
// *MACCommand_DeviceModeConf_
+ // *MACCommand_RelayConfReq_
+ // *MACCommand_RelayConfAns_
+ // *MACCommand_RelayEndDeviceConfReq_
+ // *MACCommand_RelayEndDeviceConfAns_
+ // *MACCommand_RelayUpdateUplinkListReq_
+ // *MACCommand_RelayUpdateUplinkListAns_
+ // *MACCommand_RelayCtrlUplinkListReq_
+ // *MACCommand_RelayCtrlUplinkListAns_
+ // *MACCommand_RelayConfigureFwdLimitReq_
+ // *MACCommand_RelayConfigureFwdLimitAns_
+ // *MACCommand_RelayNotifyNewEndDeviceReq_
Payload isMACCommand_Payload `protobuf_oneof:"payload"`
}
func (x *MACCommand) Reset() {
*x = MACCommand{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[20]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[26]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3307,7 +4010,7 @@ func (x *MACCommand) String() string {
func (*MACCommand) ProtoMessage() {}
func (x *MACCommand) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[20]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[26]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3320,7 +4023,7 @@ func (x *MACCommand) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACCommand.ProtoReflect.Descriptor instead.
func (*MACCommand) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26}
}
func (x *MACCommand) GetCid() MACCommandIdentifier {
@@ -3554,12 +4257,89 @@ func (x *MACCommand) GetDeviceModeConf() *MACCommand_DeviceModeConf {
return nil
}
-type isMACCommand_Payload interface {
- isMACCommand_Payload()
+func (x *MACCommand) GetRelayConfReq() *MACCommand_RelayConfReq {
+ if x, ok := x.GetPayload().(*MACCommand_RelayConfReq_); ok {
+ return x.RelayConfReq
+ }
+ return nil
}
-type MACCommand_RawPayload struct {
- RawPayload []byte `protobuf:"bytes,2,opt,name=raw_payload,json=rawPayload,proto3,oneof"`
+func (x *MACCommand) GetRelayConfAns() *MACCommand_RelayConfAns {
+ if x, ok := x.GetPayload().(*MACCommand_RelayConfAns_); ok {
+ return x.RelayConfAns
+ }
+ return nil
+}
+
+func (x *MACCommand) GetRelayEndDeviceConfReq() *MACCommand_RelayEndDeviceConfReq {
+ if x, ok := x.GetPayload().(*MACCommand_RelayEndDeviceConfReq_); ok {
+ return x.RelayEndDeviceConfReq
+ }
+ return nil
+}
+
+func (x *MACCommand) GetRelayEndDeviceConfAns() *MACCommand_RelayEndDeviceConfAns {
+ if x, ok := x.GetPayload().(*MACCommand_RelayEndDeviceConfAns_); ok {
+ return x.RelayEndDeviceConfAns
+ }
+ return nil
+}
+
+func (x *MACCommand) GetRelayUpdateUplinkListReq() *MACCommand_RelayUpdateUplinkListReq {
+ if x, ok := x.GetPayload().(*MACCommand_RelayUpdateUplinkListReq_); ok {
+ return x.RelayUpdateUplinkListReq
+ }
+ return nil
+}
+
+func (x *MACCommand) GetRelayUpdateUplinkListAns() *MACCommand_RelayUpdateUplinkListAns {
+ if x, ok := x.GetPayload().(*MACCommand_RelayUpdateUplinkListAns_); ok {
+ return x.RelayUpdateUplinkListAns
+ }
+ return nil
+}
+
+func (x *MACCommand) GetRelayCtrlUplinkListReq() *MACCommand_RelayCtrlUplinkListReq {
+ if x, ok := x.GetPayload().(*MACCommand_RelayCtrlUplinkListReq_); ok {
+ return x.RelayCtrlUplinkListReq
+ }
+ return nil
+}
+
+func (x *MACCommand) GetRelayCtrlUplinkListAns() *MACCommand_RelayCtrlUplinkListAns {
+ if x, ok := x.GetPayload().(*MACCommand_RelayCtrlUplinkListAns_); ok {
+ return x.RelayCtrlUplinkListAns
+ }
+ return nil
+}
+
+func (x *MACCommand) GetRelayConfigureFwdLimitReq() *MACCommand_RelayConfigureFwdLimitReq {
+ if x, ok := x.GetPayload().(*MACCommand_RelayConfigureFwdLimitReq_); ok {
+ return x.RelayConfigureFwdLimitReq
+ }
+ return nil
+}
+
+func (x *MACCommand) GetRelayConfigureFwdLimitAns() *MACCommand_RelayConfigureFwdLimitAns {
+ if x, ok := x.GetPayload().(*MACCommand_RelayConfigureFwdLimitAns_); ok {
+ return x.RelayConfigureFwdLimitAns
+ }
+ return nil
+}
+
+func (x *MACCommand) GetRelayNotifyNewEndDeviceReq() *MACCommand_RelayNotifyNewEndDeviceReq {
+ if x, ok := x.GetPayload().(*MACCommand_RelayNotifyNewEndDeviceReq_); ok {
+ return x.RelayNotifyNewEndDeviceReq
+ }
+ return nil
+}
+
+type isMACCommand_Payload interface {
+ isMACCommand_Payload()
+}
+
+type MACCommand_RawPayload struct {
+ RawPayload []byte `protobuf:"bytes,2,opt,name=raw_payload,json=rawPayload,proto3,oneof"`
}
type MACCommand_ResetInd_ struct {
@@ -3682,6 +4462,50 @@ type MACCommand_DeviceModeConf_ struct {
DeviceModeConf *MACCommand_DeviceModeConf `protobuf:"bytes,32,opt,name=device_mode_conf,json=deviceModeConf,proto3,oneof"`
}
+type MACCommand_RelayConfReq_ struct {
+ RelayConfReq *MACCommand_RelayConfReq `protobuf:"bytes,33,opt,name=relay_conf_req,json=relayConfReq,proto3,oneof"`
+}
+
+type MACCommand_RelayConfAns_ struct {
+ RelayConfAns *MACCommand_RelayConfAns `protobuf:"bytes,34,opt,name=relay_conf_ans,json=relayConfAns,proto3,oneof"`
+}
+
+type MACCommand_RelayEndDeviceConfReq_ struct {
+ RelayEndDeviceConfReq *MACCommand_RelayEndDeviceConfReq `protobuf:"bytes,35,opt,name=relay_end_device_conf_req,json=relayEndDeviceConfReq,proto3,oneof"`
+}
+
+type MACCommand_RelayEndDeviceConfAns_ struct {
+ RelayEndDeviceConfAns *MACCommand_RelayEndDeviceConfAns `protobuf:"bytes,36,opt,name=relay_end_device_conf_ans,json=relayEndDeviceConfAns,proto3,oneof"`
+}
+
+type MACCommand_RelayUpdateUplinkListReq_ struct {
+ RelayUpdateUplinkListReq *MACCommand_RelayUpdateUplinkListReq `protobuf:"bytes,39,opt,name=relay_update_uplink_list_req,json=relayUpdateUplinkListReq,proto3,oneof"`
+}
+
+type MACCommand_RelayUpdateUplinkListAns_ struct {
+ RelayUpdateUplinkListAns *MACCommand_RelayUpdateUplinkListAns `protobuf:"bytes,40,opt,name=relay_update_uplink_list_ans,json=relayUpdateUplinkListAns,proto3,oneof"`
+}
+
+type MACCommand_RelayCtrlUplinkListReq_ struct {
+ RelayCtrlUplinkListReq *MACCommand_RelayCtrlUplinkListReq `protobuf:"bytes,41,opt,name=relay_ctrl_uplink_list_req,json=relayCtrlUplinkListReq,proto3,oneof"`
+}
+
+type MACCommand_RelayCtrlUplinkListAns_ struct {
+ RelayCtrlUplinkListAns *MACCommand_RelayCtrlUplinkListAns `protobuf:"bytes,42,opt,name=relay_ctrl_uplink_list_ans,json=relayCtrlUplinkListAns,proto3,oneof"`
+}
+
+type MACCommand_RelayConfigureFwdLimitReq_ struct {
+ RelayConfigureFwdLimitReq *MACCommand_RelayConfigureFwdLimitReq `protobuf:"bytes,43,opt,name=relay_configure_fwd_limit_req,json=relayConfigureFwdLimitReq,proto3,oneof"`
+}
+
+type MACCommand_RelayConfigureFwdLimitAns_ struct {
+ RelayConfigureFwdLimitAns *MACCommand_RelayConfigureFwdLimitAns `protobuf:"bytes,44,opt,name=relay_configure_fwd_limit_ans,json=relayConfigureFwdLimitAns,proto3,oneof"`
+}
+
+type MACCommand_RelayNotifyNewEndDeviceReq_ struct {
+ RelayNotifyNewEndDeviceReq *MACCommand_RelayNotifyNewEndDeviceReq `protobuf:"bytes,45,opt,name=relay_notify_new_end_device_req,json=relayNotifyNewEndDeviceReq,proto3,oneof"`
+}
+
func (*MACCommand_RawPayload) isMACCommand_Payload() {}
func (*MACCommand_ResetInd_) isMACCommand_Payload() {}
@@ -3744,6 +4568,28 @@ func (*MACCommand_DeviceModeInd_) isMACCommand_Payload() {}
func (*MACCommand_DeviceModeConf_) isMACCommand_Payload() {}
+func (*MACCommand_RelayConfReq_) isMACCommand_Payload() {}
+
+func (*MACCommand_RelayConfAns_) isMACCommand_Payload() {}
+
+func (*MACCommand_RelayEndDeviceConfReq_) isMACCommand_Payload() {}
+
+func (*MACCommand_RelayEndDeviceConfAns_) isMACCommand_Payload() {}
+
+func (*MACCommand_RelayUpdateUplinkListReq_) isMACCommand_Payload() {}
+
+func (*MACCommand_RelayUpdateUplinkListAns_) isMACCommand_Payload() {}
+
+func (*MACCommand_RelayCtrlUplinkListReq_) isMACCommand_Payload() {}
+
+func (*MACCommand_RelayCtrlUplinkListAns_) isMACCommand_Payload() {}
+
+func (*MACCommand_RelayConfigureFwdLimitReq_) isMACCommand_Payload() {}
+
+func (*MACCommand_RelayConfigureFwdLimitAns_) isMACCommand_Payload() {}
+
+func (*MACCommand_RelayNotifyNewEndDeviceReq_) isMACCommand_Payload() {}
+
type MACCommands struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -3755,7 +4601,7 @@ type MACCommands struct {
func (x *MACCommands) Reset() {
*x = MACCommands{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[21]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[27]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3768,7 +4614,7 @@ func (x *MACCommands) String() string {
func (*MACCommands) ProtoMessage() {}
func (x *MACCommands) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[21]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[27]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3781,7 +4627,7 @@ func (x *MACCommands) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACCommands.ProtoReflect.Descriptor instead.
func (*MACCommands) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{21}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{27}
}
func (x *MACCommands) GetCommands() []*MACCommand {
@@ -3802,7 +4648,7 @@ type FrequencyValue struct {
func (x *FrequencyValue) Reset() {
*x = FrequencyValue{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[22]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[28]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3815,7 +4661,7 @@ func (x *FrequencyValue) String() string {
func (*FrequencyValue) ProtoMessage() {}
func (x *FrequencyValue) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[22]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[28]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3828,7 +4674,7 @@ func (x *FrequencyValue) ProtoReflect() protoreflect.Message {
// Deprecated: Use FrequencyValue.ProtoReflect.Descriptor instead.
func (*FrequencyValue) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{22}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{28}
}
func (x *FrequencyValue) GetValue() uint64 {
@@ -3849,7 +4695,7 @@ type ZeroableFrequencyValue struct {
func (x *ZeroableFrequencyValue) Reset() {
*x = ZeroableFrequencyValue{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[23]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[29]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3862,7 +4708,7 @@ func (x *ZeroableFrequencyValue) String() string {
func (*ZeroableFrequencyValue) ProtoMessage() {}
func (x *ZeroableFrequencyValue) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[23]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[29]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3875,7 +4721,7 @@ func (x *ZeroableFrequencyValue) ProtoReflect() protoreflect.Message {
// Deprecated: Use ZeroableFrequencyValue.ProtoReflect.Descriptor instead.
func (*ZeroableFrequencyValue) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{23}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{29}
}
func (x *ZeroableFrequencyValue) GetValue() uint64 {
@@ -3896,7 +4742,7 @@ type DataRateOffsetValue struct {
func (x *DataRateOffsetValue) Reset() {
*x = DataRateOffsetValue{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[24]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[30]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3909,7 +4755,7 @@ func (x *DataRateOffsetValue) String() string {
func (*DataRateOffsetValue) ProtoMessage() {}
func (x *DataRateOffsetValue) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[24]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[30]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3922,7 +4768,7 @@ func (x *DataRateOffsetValue) ProtoReflect() protoreflect.Message {
// Deprecated: Use DataRateOffsetValue.ProtoReflect.Descriptor instead.
func (*DataRateOffsetValue) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{24}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{30}
}
func (x *DataRateOffsetValue) GetValue() DataRateOffset {
@@ -3943,7 +4789,7 @@ type DataRateIndexValue struct {
func (x *DataRateIndexValue) Reset() {
*x = DataRateIndexValue{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[25]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[31]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -3956,7 +4802,7 @@ func (x *DataRateIndexValue) String() string {
func (*DataRateIndexValue) ProtoMessage() {}
func (x *DataRateIndexValue) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[25]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[31]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3969,7 +4815,7 @@ func (x *DataRateIndexValue) ProtoReflect() protoreflect.Message {
// Deprecated: Use DataRateIndexValue.ProtoReflect.Descriptor instead.
func (*DataRateIndexValue) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{25}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{31}
}
func (x *DataRateIndexValue) GetValue() DataRateIndex {
@@ -3990,7 +4836,7 @@ type PingSlotPeriodValue struct {
func (x *PingSlotPeriodValue) Reset() {
*x = PingSlotPeriodValue{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[26]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[32]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4003,7 +4849,7 @@ func (x *PingSlotPeriodValue) String() string {
func (*PingSlotPeriodValue) ProtoMessage() {}
func (x *PingSlotPeriodValue) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[26]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[32]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4016,7 +4862,7 @@ func (x *PingSlotPeriodValue) ProtoReflect() protoreflect.Message {
// Deprecated: Use PingSlotPeriodValue.ProtoReflect.Descriptor instead.
func (*PingSlotPeriodValue) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{32}
}
func (x *PingSlotPeriodValue) GetValue() PingSlotPeriod {
@@ -4037,7 +4883,7 @@ type AggregatedDutyCycleValue struct {
func (x *AggregatedDutyCycleValue) Reset() {
*x = AggregatedDutyCycleValue{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[27]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[33]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4050,7 +4896,7 @@ func (x *AggregatedDutyCycleValue) String() string {
func (*AggregatedDutyCycleValue) ProtoMessage() {}
func (x *AggregatedDutyCycleValue) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[27]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[33]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4063,7 +4909,7 @@ func (x *AggregatedDutyCycleValue) ProtoReflect() protoreflect.Message {
// Deprecated: Use AggregatedDutyCycleValue.ProtoReflect.Descriptor instead.
func (*AggregatedDutyCycleValue) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{27}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{33}
}
func (x *AggregatedDutyCycleValue) GetValue() AggregatedDutyCycle {
@@ -4084,7 +4930,7 @@ type RxDelayValue struct {
func (x *RxDelayValue) Reset() {
*x = RxDelayValue{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[28]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[34]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4097,7 +4943,7 @@ func (x *RxDelayValue) String() string {
func (*RxDelayValue) ProtoMessage() {}
func (x *RxDelayValue) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[28]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[34]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4110,7 +4956,7 @@ func (x *RxDelayValue) ProtoReflect() protoreflect.Message {
// Deprecated: Use RxDelayValue.ProtoReflect.Descriptor instead.
func (*RxDelayValue) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{28}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{34}
}
func (x *RxDelayValue) GetValue() RxDelay {
@@ -4131,7 +4977,7 @@ type ADRAckLimitExponentValue struct {
func (x *ADRAckLimitExponentValue) Reset() {
*x = ADRAckLimitExponentValue{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[29]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[35]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4144,7 +4990,7 @@ func (x *ADRAckLimitExponentValue) String() string {
func (*ADRAckLimitExponentValue) ProtoMessage() {}
func (x *ADRAckLimitExponentValue) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[29]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[35]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4157,7 +5003,7 @@ func (x *ADRAckLimitExponentValue) ProtoReflect() protoreflect.Message {
// Deprecated: Use ADRAckLimitExponentValue.ProtoReflect.Descriptor instead.
func (*ADRAckLimitExponentValue) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{29}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{35}
}
func (x *ADRAckLimitExponentValue) GetValue() ADRAckLimitExponent {
@@ -4178,7 +5024,7 @@ type ADRAckDelayExponentValue struct {
func (x *ADRAckDelayExponentValue) Reset() {
*x = ADRAckDelayExponentValue{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[30]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[36]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4191,7 +5037,7 @@ func (x *ADRAckDelayExponentValue) String() string {
func (*ADRAckDelayExponentValue) ProtoMessage() {}
func (x *ADRAckDelayExponentValue) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[30]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[36]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4204,7 +5050,7 @@ func (x *ADRAckDelayExponentValue) ProtoReflect() protoreflect.Message {
// Deprecated: Use ADRAckDelayExponentValue.ProtoReflect.Descriptor instead.
func (*ADRAckDelayExponentValue) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{30}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{36}
}
func (x *ADRAckDelayExponentValue) GetValue() ADRAckDelayExponent {
@@ -4225,7 +5071,7 @@ type DeviceEIRPValue struct {
func (x *DeviceEIRPValue) Reset() {
*x = DeviceEIRPValue{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[31]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[37]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4238,7 +5084,7 @@ func (x *DeviceEIRPValue) String() string {
func (*DeviceEIRPValue) ProtoMessage() {}
func (x *DeviceEIRPValue) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[31]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[37]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4251,7 +5097,7 @@ func (x *DeviceEIRPValue) ProtoReflect() protoreflect.Message {
// Deprecated: Use DeviceEIRPValue.ProtoReflect.Descriptor instead.
func (*DeviceEIRPValue) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{31}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{37}
}
func (x *DeviceEIRPValue) GetValue() DeviceEIRP {
@@ -4261,37 +5107,36 @@ func (x *DeviceEIRPValue) GetValue() DeviceEIRP {
return DeviceEIRP_DEVICE_EIRP_8
}
-// Transmission settings for downlink.
-type TxSettings_Downlink struct {
+type RelayForwardUplinkReq struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
- // Index of the antenna on which the uplink was received and/or downlink must be sent.
- AntennaIndex uint32 `protobuf:"varint,1,opt,name=antenna_index,json=antennaIndex,proto3" json:"antenna_index,omitempty"`
- // Transmission power (dBm). Only on downlink.
- TxPower float32 `protobuf:"fixed32,2,opt,name=tx_power,json=txPower,proto3" json:"tx_power,omitempty"`
- // Invert LoRa polarization; false for LoRaWAN uplink, true for downlink.
- InvertPolarization bool `protobuf:"varint,3,opt,name=invert_polarization,json=invertPolarization,proto3" json:"invert_polarization,omitempty"`
+ DataRate *DataRate `protobuf:"bytes,1,opt,name=data_rate,json=dataRate,proto3" json:"data_rate,omitempty"`
+ Snr int32 `protobuf:"varint,2,opt,name=snr,proto3" json:"snr,omitempty"`
+ Rssi int32 `protobuf:"varint,3,opt,name=rssi,proto3" json:"rssi,omitempty"`
+ WorChannel RelayWORChannel `protobuf:"varint,4,opt,name=wor_channel,json=worChannel,proto3,enum=ttn.lorawan.v3.RelayWORChannel" json:"wor_channel,omitempty"`
+ Frequency uint64 `protobuf:"varint,5,opt,name=frequency,proto3" json:"frequency,omitempty"` // Uplink channel frequency (Hz).
+ RawPayload []byte `protobuf:"bytes,6,opt,name=raw_payload,json=rawPayload,proto3" json:"raw_payload,omitempty"`
}
-func (x *TxSettings_Downlink) Reset() {
- *x = TxSettings_Downlink{}
+func (x *RelayForwardUplinkReq) Reset() {
+ *x = RelayForwardUplinkReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[32]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[38]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
-func (x *TxSettings_Downlink) String() string {
+func (x *RelayForwardUplinkReq) String() string {
return protoimpl.X.MessageStringOf(x)
}
-func (*TxSettings_Downlink) ProtoMessage() {}
+func (*RelayForwardUplinkReq) ProtoMessage() {}
-func (x *TxSettings_Downlink) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[32]
+func (x *RelayForwardUplinkReq) ProtoReflect() protoreflect.Message {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[38]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4302,57 +5147,78 @@ func (x *TxSettings_Downlink) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x)
}
-// Deprecated: Use TxSettings_Downlink.ProtoReflect.Descriptor instead.
-func (*TxSettings_Downlink) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{14, 0}
+// Deprecated: Use RelayForwardUplinkReq.ProtoReflect.Descriptor instead.
+func (*RelayForwardUplinkReq) Descriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{38}
}
-func (x *TxSettings_Downlink) GetAntennaIndex() uint32 {
+func (x *RelayForwardUplinkReq) GetDataRate() *DataRate {
if x != nil {
- return x.AntennaIndex
+ return x.DataRate
+ }
+ return nil
+}
+
+func (x *RelayForwardUplinkReq) GetSnr() int32 {
+ if x != nil {
+ return x.Snr
}
return 0
}
-func (x *TxSettings_Downlink) GetTxPower() float32 {
+func (x *RelayForwardUplinkReq) GetRssi() int32 {
if x != nil {
- return x.TxPower
+ return x.Rssi
}
return 0
}
-func (x *TxSettings_Downlink) GetInvertPolarization() bool {
+func (x *RelayForwardUplinkReq) GetWorChannel() RelayWORChannel {
if x != nil {
- return x.InvertPolarization
+ return x.WorChannel
}
- return false
+ return RelayWORChannel_RELAY_WOR_CHANNEL_DEFAULT
}
-type MACCommand_ResetInd struct {
+func (x *RelayForwardUplinkReq) GetFrequency() uint64 {
+ if x != nil {
+ return x.Frequency
+ }
+ return 0
+}
+
+func (x *RelayForwardUplinkReq) GetRawPayload() []byte {
+ if x != nil {
+ return x.RawPayload
+ }
+ return nil
+}
+
+type RelayForwardDownlinkReq struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
- MinorVersion Minor `protobuf:"varint,1,opt,name=minor_version,json=minorVersion,proto3,enum=ttn.lorawan.v3.Minor" json:"minor_version,omitempty"`
+ RawPayload []byte `protobuf:"bytes,1,opt,name=raw_payload,json=rawPayload,proto3" json:"raw_payload,omitempty"`
}
-func (x *MACCommand_ResetInd) Reset() {
- *x = MACCommand_ResetInd{}
+func (x *RelayForwardDownlinkReq) Reset() {
+ *x = RelayForwardDownlinkReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[33]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[39]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
-func (x *MACCommand_ResetInd) String() string {
+func (x *RelayForwardDownlinkReq) String() string {
return protoimpl.X.MessageStringOf(x)
}
-func (*MACCommand_ResetInd) ProtoMessage() {}
+func (*RelayForwardDownlinkReq) ProtoMessage() {}
-func (x *MACCommand_ResetInd) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[33]
+func (x *RelayForwardDownlinkReq) ProtoReflect() protoreflect.Message {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[39]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4363,43 +5229,45 @@ func (x *MACCommand_ResetInd) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x)
}
-// Deprecated: Use MACCommand_ResetInd.ProtoReflect.Descriptor instead.
-func (*MACCommand_ResetInd) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20, 0}
+// Deprecated: Use RelayForwardDownlinkReq.ProtoReflect.Descriptor instead.
+func (*RelayForwardDownlinkReq) Descriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{39}
}
-func (x *MACCommand_ResetInd) GetMinorVersion() Minor {
+func (x *RelayForwardDownlinkReq) GetRawPayload() []byte {
if x != nil {
- return x.MinorVersion
+ return x.RawPayload
}
- return Minor_MINOR_RFU_0
+ return nil
}
-type MACCommand_ResetConf struct {
+type RelayUplinkToken struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
- MinorVersion Minor `protobuf:"varint,1,opt,name=minor_version,json=minorVersion,proto3,enum=ttn.lorawan.v3.Minor" json:"minor_version,omitempty"`
+ Ids *EndDeviceIdentifiers `protobuf:"bytes,1,opt,name=ids,proto3" json:"ids,omitempty"`
+ SessionKeyId []byte `protobuf:"bytes,2,opt,name=session_key_id,json=sessionKeyId,proto3" json:"session_key_id,omitempty"`
+ FullFCnt uint32 `protobuf:"varint,3,opt,name=full_f_cnt,json=fullFCnt,proto3" json:"full_f_cnt,omitempty"`
}
-func (x *MACCommand_ResetConf) Reset() {
- *x = MACCommand_ResetConf{}
+func (x *RelayUplinkToken) Reset() {
+ *x = RelayUplinkToken{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[34]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[40]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
-func (x *MACCommand_ResetConf) String() string {
+func (x *RelayUplinkToken) String() string {
return protoimpl.X.MessageStringOf(x)
}
-func (*MACCommand_ResetConf) ProtoMessage() {}
+func (*RelayUplinkToken) ProtoMessage() {}
-func (x *MACCommand_ResetConf) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[34]
+func (x *RelayUplinkToken) ProtoReflect() protoreflect.Message {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[40]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4410,45 +5278,63 @@ func (x *MACCommand_ResetConf) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x)
}
-// Deprecated: Use MACCommand_ResetConf.ProtoReflect.Descriptor instead.
-func (*MACCommand_ResetConf) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20, 1}
+// Deprecated: Use RelayUplinkToken.ProtoReflect.Descriptor instead.
+func (*RelayUplinkToken) Descriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{40}
}
-func (x *MACCommand_ResetConf) GetMinorVersion() Minor {
+func (x *RelayUplinkToken) GetIds() *EndDeviceIdentifiers {
if x != nil {
- return x.MinorVersion
+ return x.Ids
}
- return Minor_MINOR_RFU_0
+ return nil
}
-type MACCommand_LinkCheckAns struct {
+func (x *RelayUplinkToken) GetSessionKeyId() []byte {
+ if x != nil {
+ return x.SessionKeyId
+ }
+ return nil
+}
+
+func (x *RelayUplinkToken) GetFullFCnt() uint32 {
+ if x != nil {
+ return x.FullFCnt
+ }
+ return 0
+}
+
+// Transmission settings for downlink.
+type TxSettings_Downlink struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
- // Indicates the link margin in dB of the received LinkCheckReq, relative to the demodulation floor.
- Margin uint32 `protobuf:"varint,1,opt,name=margin,proto3" json:"margin,omitempty"`
- GatewayCount uint32 `protobuf:"varint,2,opt,name=gateway_count,json=gatewayCount,proto3" json:"gateway_count,omitempty"`
+ // Index of the antenna on which the uplink was received and/or downlink must be sent.
+ AntennaIndex uint32 `protobuf:"varint,1,opt,name=antenna_index,json=antennaIndex,proto3" json:"antenna_index,omitempty"`
+ // Transmission power (dBm). Only on downlink.
+ TxPower float32 `protobuf:"fixed32,2,opt,name=tx_power,json=txPower,proto3" json:"tx_power,omitempty"`
+ // Invert LoRa polarization; false for LoRaWAN uplink, true for downlink.
+ InvertPolarization bool `protobuf:"varint,3,opt,name=invert_polarization,json=invertPolarization,proto3" json:"invert_polarization,omitempty"`
}
-func (x *MACCommand_LinkCheckAns) Reset() {
- *x = MACCommand_LinkCheckAns{}
+func (x *TxSettings_Downlink) Reset() {
+ *x = TxSettings_Downlink{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[35]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[41]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
-func (x *MACCommand_LinkCheckAns) String() string {
+func (x *TxSettings_Downlink) String() string {
return protoimpl.X.MessageStringOf(x)
}
-func (*MACCommand_LinkCheckAns) ProtoMessage() {}
+func (*TxSettings_Downlink) ProtoMessage() {}
-func (x *MACCommand_LinkCheckAns) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[35]
+func (x *TxSettings_Downlink) ProtoReflect() protoreflect.Message {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[41]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4459,9 +5345,166 @@ func (x *MACCommand_LinkCheckAns) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x)
}
-// Deprecated: Use MACCommand_LinkCheckAns.ProtoReflect.Descriptor instead.
+// Deprecated: Use TxSettings_Downlink.ProtoReflect.Descriptor instead.
+func (*TxSettings_Downlink) Descriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{14, 0}
+}
+
+func (x *TxSettings_Downlink) GetAntennaIndex() uint32 {
+ if x != nil {
+ return x.AntennaIndex
+ }
+ return 0
+}
+
+func (x *TxSettings_Downlink) GetTxPower() float32 {
+ if x != nil {
+ return x.TxPower
+ }
+ return 0
+}
+
+func (x *TxSettings_Downlink) GetInvertPolarization() bool {
+ if x != nil {
+ return x.InvertPolarization
+ }
+ return false
+}
+
+type MACCommand_ResetInd struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ MinorVersion Minor `protobuf:"varint,1,opt,name=minor_version,json=minorVersion,proto3,enum=ttn.lorawan.v3.Minor" json:"minor_version,omitempty"`
+}
+
+func (x *MACCommand_ResetInd) Reset() {
+ *x = MACCommand_ResetInd{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[42]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *MACCommand_ResetInd) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MACCommand_ResetInd) ProtoMessage() {}
+
+func (x *MACCommand_ResetInd) ProtoReflect() protoreflect.Message {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[42]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use MACCommand_ResetInd.ProtoReflect.Descriptor instead.
+func (*MACCommand_ResetInd) Descriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 0}
+}
+
+func (x *MACCommand_ResetInd) GetMinorVersion() Minor {
+ if x != nil {
+ return x.MinorVersion
+ }
+ return Minor_MINOR_RFU_0
+}
+
+type MACCommand_ResetConf struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ MinorVersion Minor `protobuf:"varint,1,opt,name=minor_version,json=minorVersion,proto3,enum=ttn.lorawan.v3.Minor" json:"minor_version,omitempty"`
+}
+
+func (x *MACCommand_ResetConf) Reset() {
+ *x = MACCommand_ResetConf{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[43]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *MACCommand_ResetConf) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MACCommand_ResetConf) ProtoMessage() {}
+
+func (x *MACCommand_ResetConf) ProtoReflect() protoreflect.Message {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[43]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use MACCommand_ResetConf.ProtoReflect.Descriptor instead.
+func (*MACCommand_ResetConf) Descriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 1}
+}
+
+func (x *MACCommand_ResetConf) GetMinorVersion() Minor {
+ if x != nil {
+ return x.MinorVersion
+ }
+ return Minor_MINOR_RFU_0
+}
+
+type MACCommand_LinkCheckAns struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // Indicates the link margin in dB of the received LinkCheckReq, relative to the demodulation floor.
+ Margin uint32 `protobuf:"varint,1,opt,name=margin,proto3" json:"margin,omitempty"`
+ GatewayCount uint32 `protobuf:"varint,2,opt,name=gateway_count,json=gatewayCount,proto3" json:"gateway_count,omitempty"`
+}
+
+func (x *MACCommand_LinkCheckAns) Reset() {
+ *x = MACCommand_LinkCheckAns{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[44]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *MACCommand_LinkCheckAns) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MACCommand_LinkCheckAns) ProtoMessage() {}
+
+func (x *MACCommand_LinkCheckAns) ProtoReflect() protoreflect.Message {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[44]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use MACCommand_LinkCheckAns.ProtoReflect.Descriptor instead.
func (*MACCommand_LinkCheckAns) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20, 2}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 2}
}
func (x *MACCommand_LinkCheckAns) GetMargin() uint32 {
@@ -4493,7 +5536,7 @@ type MACCommand_LinkADRReq struct {
func (x *MACCommand_LinkADRReq) Reset() {
*x = MACCommand_LinkADRReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[36]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[45]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4506,7 +5549,7 @@ func (x *MACCommand_LinkADRReq) String() string {
func (*MACCommand_LinkADRReq) ProtoMessage() {}
func (x *MACCommand_LinkADRReq) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[36]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[45]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4519,7 +5562,7 @@ func (x *MACCommand_LinkADRReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACCommand_LinkADRReq.ProtoReflect.Descriptor instead.
func (*MACCommand_LinkADRReq) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20, 3}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 3}
}
func (x *MACCommand_LinkADRReq) GetDataRateIndex() DataRateIndex {
@@ -4570,7 +5613,7 @@ type MACCommand_LinkADRAns struct {
func (x *MACCommand_LinkADRAns) Reset() {
*x = MACCommand_LinkADRAns{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[37]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[46]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4583,7 +5626,7 @@ func (x *MACCommand_LinkADRAns) String() string {
func (*MACCommand_LinkADRAns) ProtoMessage() {}
func (x *MACCommand_LinkADRAns) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[37]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[46]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4596,7 +5639,7 @@ func (x *MACCommand_LinkADRAns) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACCommand_LinkADRAns.ProtoReflect.Descriptor instead.
func (*MACCommand_LinkADRAns) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20, 4}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 4}
}
func (x *MACCommand_LinkADRAns) GetChannelMaskAck() bool {
@@ -4631,7 +5674,7 @@ type MACCommand_DutyCycleReq struct {
func (x *MACCommand_DutyCycleReq) Reset() {
*x = MACCommand_DutyCycleReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[38]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[47]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4644,7 +5687,7 @@ func (x *MACCommand_DutyCycleReq) String() string {
func (*MACCommand_DutyCycleReq) ProtoMessage() {}
func (x *MACCommand_DutyCycleReq) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[38]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[47]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4657,7 +5700,7 @@ func (x *MACCommand_DutyCycleReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACCommand_DutyCycleReq.ProtoReflect.Descriptor instead.
func (*MACCommand_DutyCycleReq) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20, 5}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 5}
}
func (x *MACCommand_DutyCycleReq) GetMaxDutyCycle() AggregatedDutyCycle {
@@ -4680,7 +5723,7 @@ type MACCommand_RxParamSetupReq struct {
func (x *MACCommand_RxParamSetupReq) Reset() {
*x = MACCommand_RxParamSetupReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[39]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[48]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4693,7 +5736,7 @@ func (x *MACCommand_RxParamSetupReq) String() string {
func (*MACCommand_RxParamSetupReq) ProtoMessage() {}
func (x *MACCommand_RxParamSetupReq) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[39]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[48]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4706,7 +5749,7 @@ func (x *MACCommand_RxParamSetupReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACCommand_RxParamSetupReq.ProtoReflect.Descriptor instead.
func (*MACCommand_RxParamSetupReq) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20, 6}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 6}
}
func (x *MACCommand_RxParamSetupReq) GetRx2DataRateIndex() DataRateIndex {
@@ -4743,7 +5786,7 @@ type MACCommand_RxParamSetupAns struct {
func (x *MACCommand_RxParamSetupAns) Reset() {
*x = MACCommand_RxParamSetupAns{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[40]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[49]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4756,7 +5799,7 @@ func (x *MACCommand_RxParamSetupAns) String() string {
func (*MACCommand_RxParamSetupAns) ProtoMessage() {}
func (x *MACCommand_RxParamSetupAns) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[40]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[49]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4769,7 +5812,7 @@ func (x *MACCommand_RxParamSetupAns) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACCommand_RxParamSetupAns.ProtoReflect.Descriptor instead.
func (*MACCommand_RxParamSetupAns) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20, 7}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 7}
}
func (x *MACCommand_RxParamSetupAns) GetRx2DataRateIndexAck() bool {
@@ -4810,7 +5853,7 @@ type MACCommand_DevStatusAns struct {
func (x *MACCommand_DevStatusAns) Reset() {
*x = MACCommand_DevStatusAns{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[41]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[50]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4823,7 +5866,7 @@ func (x *MACCommand_DevStatusAns) String() string {
func (*MACCommand_DevStatusAns) ProtoMessage() {}
func (x *MACCommand_DevStatusAns) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[41]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[50]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4836,7 +5879,7 @@ func (x *MACCommand_DevStatusAns) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACCommand_DevStatusAns.ProtoReflect.Descriptor instead.
func (*MACCommand_DevStatusAns) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20, 8}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 8}
}
func (x *MACCommand_DevStatusAns) GetBattery() uint32 {
@@ -4867,7 +5910,7 @@ type MACCommand_NewChannelReq struct {
func (x *MACCommand_NewChannelReq) Reset() {
*x = MACCommand_NewChannelReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[42]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[51]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4880,7 +5923,7 @@ func (x *MACCommand_NewChannelReq) String() string {
func (*MACCommand_NewChannelReq) ProtoMessage() {}
func (x *MACCommand_NewChannelReq) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[42]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[51]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4893,7 +5936,7 @@ func (x *MACCommand_NewChannelReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACCommand_NewChannelReq.ProtoReflect.Descriptor instead.
func (*MACCommand_NewChannelReq) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20, 9}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 9}
}
func (x *MACCommand_NewChannelReq) GetChannelIndex() uint32 {
@@ -4936,7 +5979,7 @@ type MACCommand_NewChannelAns struct {
func (x *MACCommand_NewChannelAns) Reset() {
*x = MACCommand_NewChannelAns{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[43]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[52]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -4949,7 +5992,7 @@ func (x *MACCommand_NewChannelAns) String() string {
func (*MACCommand_NewChannelAns) ProtoMessage() {}
func (x *MACCommand_NewChannelAns) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[43]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[52]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -4962,7 +6005,7 @@ func (x *MACCommand_NewChannelAns) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACCommand_NewChannelAns.ProtoReflect.Descriptor instead.
func (*MACCommand_NewChannelAns) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20, 10}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 10}
}
func (x *MACCommand_NewChannelAns) GetFrequencyAck() bool {
@@ -4991,7 +6034,7 @@ type MACCommand_DLChannelReq struct {
func (x *MACCommand_DLChannelReq) Reset() {
*x = MACCommand_DLChannelReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[44]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[53]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -5004,7 +6047,7 @@ func (x *MACCommand_DLChannelReq) String() string {
func (*MACCommand_DLChannelReq) ProtoMessage() {}
func (x *MACCommand_DLChannelReq) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[44]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[53]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -5017,7 +6060,7 @@ func (x *MACCommand_DLChannelReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACCommand_DLChannelReq.ProtoReflect.Descriptor instead.
func (*MACCommand_DLChannelReq) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20, 11}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 11}
}
func (x *MACCommand_DLChannelReq) GetChannelIndex() uint32 {
@@ -5046,7 +6089,7 @@ type MACCommand_DLChannelAns struct {
func (x *MACCommand_DLChannelAns) Reset() {
*x = MACCommand_DLChannelAns{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[45]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[54]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -5059,7 +6102,7 @@ func (x *MACCommand_DLChannelAns) String() string {
func (*MACCommand_DLChannelAns) ProtoMessage() {}
func (x *MACCommand_DLChannelAns) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[45]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[54]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -5072,7 +6115,7 @@ func (x *MACCommand_DLChannelAns) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACCommand_DLChannelAns.ProtoReflect.Descriptor instead.
func (*MACCommand_DLChannelAns) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20, 12}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 12}
}
func (x *MACCommand_DLChannelAns) GetChannelIndexAck() bool {
@@ -5100,7 +6143,7 @@ type MACCommand_RxTimingSetupReq struct {
func (x *MACCommand_RxTimingSetupReq) Reset() {
*x = MACCommand_RxTimingSetupReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[46]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[55]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -5113,7 +6156,7 @@ func (x *MACCommand_RxTimingSetupReq) String() string {
func (*MACCommand_RxTimingSetupReq) ProtoMessage() {}
func (x *MACCommand_RxTimingSetupReq) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[46]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[55]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -5126,7 +6169,7 @@ func (x *MACCommand_RxTimingSetupReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACCommand_RxTimingSetupReq.ProtoReflect.Descriptor instead.
func (*MACCommand_RxTimingSetupReq) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20, 13}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 13}
}
func (x *MACCommand_RxTimingSetupReq) GetDelay() RxDelay {
@@ -5151,7 +6194,7 @@ type MACCommand_TxParamSetupReq struct {
func (x *MACCommand_TxParamSetupReq) Reset() {
*x = MACCommand_TxParamSetupReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[47]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[56]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -5164,7 +6207,7 @@ func (x *MACCommand_TxParamSetupReq) String() string {
func (*MACCommand_TxParamSetupReq) ProtoMessage() {}
func (x *MACCommand_TxParamSetupReq) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[47]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[56]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -5177,7 +6220,7 @@ func (x *MACCommand_TxParamSetupReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACCommand_TxParamSetupReq.ProtoReflect.Descriptor instead.
func (*MACCommand_TxParamSetupReq) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20, 14}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 14}
}
func (x *MACCommand_TxParamSetupReq) GetMaxEirpIndex() DeviceEIRP {
@@ -5212,7 +6255,7 @@ type MACCommand_RekeyInd struct {
func (x *MACCommand_RekeyInd) Reset() {
*x = MACCommand_RekeyInd{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[48]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[57]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -5225,7 +6268,7 @@ func (x *MACCommand_RekeyInd) String() string {
func (*MACCommand_RekeyInd) ProtoMessage() {}
func (x *MACCommand_RekeyInd) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[48]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[57]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -5238,7 +6281,7 @@ func (x *MACCommand_RekeyInd) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACCommand_RekeyInd.ProtoReflect.Descriptor instead.
func (*MACCommand_RekeyInd) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20, 15}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 15}
}
func (x *MACCommand_RekeyInd) GetMinorVersion() Minor {
@@ -5259,7 +6302,7 @@ type MACCommand_RekeyConf struct {
func (x *MACCommand_RekeyConf) Reset() {
*x = MACCommand_RekeyConf{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[49]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[58]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -5272,7 +6315,7 @@ func (x *MACCommand_RekeyConf) String() string {
func (*MACCommand_RekeyConf) ProtoMessage() {}
func (x *MACCommand_RekeyConf) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[49]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[58]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -5285,7 +6328,7 @@ func (x *MACCommand_RekeyConf) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACCommand_RekeyConf.ProtoReflect.Descriptor instead.
func (*MACCommand_RekeyConf) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20, 16}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 16}
}
func (x *MACCommand_RekeyConf) GetMinorVersion() Minor {
@@ -5309,7 +6352,7 @@ type MACCommand_ADRParamSetupReq struct {
func (x *MACCommand_ADRParamSetupReq) Reset() {
*x = MACCommand_ADRParamSetupReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[50]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[59]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -5322,7 +6365,7 @@ func (x *MACCommand_ADRParamSetupReq) String() string {
func (*MACCommand_ADRParamSetupReq) ProtoMessage() {}
func (x *MACCommand_ADRParamSetupReq) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[50]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[59]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -5335,7 +6378,7 @@ func (x *MACCommand_ADRParamSetupReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACCommand_ADRParamSetupReq.ProtoReflect.Descriptor instead.
func (*MACCommand_ADRParamSetupReq) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20, 17}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 17}
}
func (x *MACCommand_ADRParamSetupReq) GetAdrAckLimitExponent() ADRAckLimitExponent {
@@ -5363,7 +6406,7 @@ type MACCommand_DeviceTimeAns struct {
func (x *MACCommand_DeviceTimeAns) Reset() {
*x = MACCommand_DeviceTimeAns{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[51]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[60]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -5376,7 +6419,7 @@ func (x *MACCommand_DeviceTimeAns) String() string {
func (*MACCommand_DeviceTimeAns) ProtoMessage() {}
func (x *MACCommand_DeviceTimeAns) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[51]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[60]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -5389,7 +6432,7 @@ func (x *MACCommand_DeviceTimeAns) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACCommand_DeviceTimeAns.ProtoReflect.Descriptor instead.
func (*MACCommand_DeviceTimeAns) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20, 18}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 18}
}
func (x *MACCommand_DeviceTimeAns) GetTime() *timestamppb.Timestamp {
@@ -5414,7 +6457,7 @@ type MACCommand_ForceRejoinReq struct {
func (x *MACCommand_ForceRejoinReq) Reset() {
*x = MACCommand_ForceRejoinReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[52]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[61]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -5427,7 +6470,7 @@ func (x *MACCommand_ForceRejoinReq) String() string {
func (*MACCommand_ForceRejoinReq) ProtoMessage() {}
func (x *MACCommand_ForceRejoinReq) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[52]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[61]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -5440,7 +6483,7 @@ func (x *MACCommand_ForceRejoinReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACCommand_ForceRejoinReq.ProtoReflect.Descriptor instead.
func (*MACCommand_ForceRejoinReq) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20, 19}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 19}
}
func (x *MACCommand_ForceRejoinReq) GetRejoinType() RejoinRequestType {
@@ -5485,7 +6528,7 @@ type MACCommand_RejoinParamSetupReq struct {
func (x *MACCommand_RejoinParamSetupReq) Reset() {
*x = MACCommand_RejoinParamSetupReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[53]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[62]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -5498,7 +6541,7 @@ func (x *MACCommand_RejoinParamSetupReq) String() string {
func (*MACCommand_RejoinParamSetupReq) ProtoMessage() {}
func (x *MACCommand_RejoinParamSetupReq) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[53]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[62]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -5511,7 +6554,7 @@ func (x *MACCommand_RejoinParamSetupReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACCommand_RejoinParamSetupReq.ProtoReflect.Descriptor instead.
func (*MACCommand_RejoinParamSetupReq) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20, 20}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 20}
}
func (x *MACCommand_RejoinParamSetupReq) GetMaxCountExponent() RejoinCountExponent {
@@ -5539,7 +6582,7 @@ type MACCommand_RejoinParamSetupAns struct {
func (x *MACCommand_RejoinParamSetupAns) Reset() {
*x = MACCommand_RejoinParamSetupAns{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[54]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[63]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -5552,7 +6595,7 @@ func (x *MACCommand_RejoinParamSetupAns) String() string {
func (*MACCommand_RejoinParamSetupAns) ProtoMessage() {}
func (x *MACCommand_RejoinParamSetupAns) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[54]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[63]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -5565,7 +6608,7 @@ func (x *MACCommand_RejoinParamSetupAns) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACCommand_RejoinParamSetupAns.ProtoReflect.Descriptor instead.
func (*MACCommand_RejoinParamSetupAns) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20, 21}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 21}
}
func (x *MACCommand_RejoinParamSetupAns) GetMaxTimeExponentAck() bool {
@@ -5586,7 +6629,7 @@ type MACCommand_PingSlotInfoReq struct {
func (x *MACCommand_PingSlotInfoReq) Reset() {
*x = MACCommand_PingSlotInfoReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[55]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[64]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -5599,7 +6642,7 @@ func (x *MACCommand_PingSlotInfoReq) String() string {
func (*MACCommand_PingSlotInfoReq) ProtoMessage() {}
func (x *MACCommand_PingSlotInfoReq) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[55]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[64]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -5612,7 +6655,7 @@ func (x *MACCommand_PingSlotInfoReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACCommand_PingSlotInfoReq.ProtoReflect.Descriptor instead.
func (*MACCommand_PingSlotInfoReq) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20, 22}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 22}
}
func (x *MACCommand_PingSlotInfoReq) GetPeriod() PingSlotPeriod {
@@ -5634,7 +6677,7 @@ type MACCommand_PingSlotChannelReq struct {
func (x *MACCommand_PingSlotChannelReq) Reset() {
*x = MACCommand_PingSlotChannelReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[56]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[65]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -5647,7 +6690,7 @@ func (x *MACCommand_PingSlotChannelReq) String() string {
func (*MACCommand_PingSlotChannelReq) ProtoMessage() {}
func (x *MACCommand_PingSlotChannelReq) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[56]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[65]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -5660,7 +6703,7 @@ func (x *MACCommand_PingSlotChannelReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACCommand_PingSlotChannelReq.ProtoReflect.Descriptor instead.
func (*MACCommand_PingSlotChannelReq) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20, 23}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 23}
}
func (x *MACCommand_PingSlotChannelReq) GetFrequency() uint64 {
@@ -5689,7 +6732,7 @@ type MACCommand_PingSlotChannelAns struct {
func (x *MACCommand_PingSlotChannelAns) Reset() {
*x = MACCommand_PingSlotChannelAns{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[57]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[66]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -5702,7 +6745,7 @@ func (x *MACCommand_PingSlotChannelAns) String() string {
func (*MACCommand_PingSlotChannelAns) ProtoMessage() {}
func (x *MACCommand_PingSlotChannelAns) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[57]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[66]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -5715,7 +6758,7 @@ func (x *MACCommand_PingSlotChannelAns) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACCommand_PingSlotChannelAns.ProtoReflect.Descriptor instead.
func (*MACCommand_PingSlotChannelAns) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20, 24}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 24}
}
func (x *MACCommand_PingSlotChannelAns) GetFrequencyAck() bool {
@@ -5744,7 +6787,7 @@ type MACCommand_BeaconTimingAns struct {
func (x *MACCommand_BeaconTimingAns) Reset() {
*x = MACCommand_BeaconTimingAns{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[58]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[67]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -5757,7 +6800,7 @@ func (x *MACCommand_BeaconTimingAns) String() string {
func (*MACCommand_BeaconTimingAns) ProtoMessage() {}
func (x *MACCommand_BeaconTimingAns) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[58]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[67]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -5770,7 +6813,7 @@ func (x *MACCommand_BeaconTimingAns) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACCommand_BeaconTimingAns.ProtoReflect.Descriptor instead.
func (*MACCommand_BeaconTimingAns) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20, 25}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 25}
}
func (x *MACCommand_BeaconTimingAns) GetDelay() uint32 {
@@ -5798,7 +6841,7 @@ type MACCommand_BeaconFreqReq struct {
func (x *MACCommand_BeaconFreqReq) Reset() {
*x = MACCommand_BeaconFreqReq{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[59]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[68]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -5811,7 +6854,7 @@ func (x *MACCommand_BeaconFreqReq) String() string {
func (*MACCommand_BeaconFreqReq) ProtoMessage() {}
func (x *MACCommand_BeaconFreqReq) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[59]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[68]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -5824,7 +6867,7 @@ func (x *MACCommand_BeaconFreqReq) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACCommand_BeaconFreqReq.ProtoReflect.Descriptor instead.
func (*MACCommand_BeaconFreqReq) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20, 26}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 26}
}
func (x *MACCommand_BeaconFreqReq) GetFrequency() uint64 {
@@ -5845,7 +6888,7 @@ type MACCommand_BeaconFreqAns struct {
func (x *MACCommand_BeaconFreqAns) Reset() {
*x = MACCommand_BeaconFreqAns{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[60]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[69]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -5858,7 +6901,7 @@ func (x *MACCommand_BeaconFreqAns) String() string {
func (*MACCommand_BeaconFreqAns) ProtoMessage() {}
func (x *MACCommand_BeaconFreqAns) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[60]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[69]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -5871,7 +6914,7 @@ func (x *MACCommand_BeaconFreqAns) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACCommand_BeaconFreqAns.ProtoReflect.Descriptor instead.
func (*MACCommand_BeaconFreqAns) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20, 27}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 27}
}
func (x *MACCommand_BeaconFreqAns) GetFrequencyAck() bool {
@@ -5892,7 +6935,7 @@ type MACCommand_DeviceModeInd struct {
func (x *MACCommand_DeviceModeInd) Reset() {
*x = MACCommand_DeviceModeInd{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[61]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[70]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -5905,7 +6948,7 @@ func (x *MACCommand_DeviceModeInd) String() string {
func (*MACCommand_DeviceModeInd) ProtoMessage() {}
func (x *MACCommand_DeviceModeInd) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[61]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[70]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -5918,7 +6961,7 @@ func (x *MACCommand_DeviceModeInd) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACCommand_DeviceModeInd.ProtoReflect.Descriptor instead.
func (*MACCommand_DeviceModeInd) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20, 28}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 28}
}
func (x *MACCommand_DeviceModeInd) GetClass() Class {
@@ -5939,7 +6982,7 @@ type MACCommand_DeviceModeConf struct {
func (x *MACCommand_DeviceModeConf) Reset() {
*x = MACCommand_DeviceModeConf{}
if protoimpl.UnsafeEnabled {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[62]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[71]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -5952,7 +6995,7 @@ func (x *MACCommand_DeviceModeConf) String() string {
func (*MACCommand_DeviceModeConf) ProtoMessage() {}
func (x *MACCommand_DeviceModeConf) ProtoReflect() protoreflect.Message {
- mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[62]
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[71]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -5965,7 +7008,7 @@ func (x *MACCommand_DeviceModeConf) ProtoReflect() protoreflect.Message {
// Deprecated: Use MACCommand_DeviceModeConf.ProtoReflect.Descriptor instead.
func (*MACCommand_DeviceModeConf) Descriptor() ([]byte, []int) {
- return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{20, 29}
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 29}
}
func (x *MACCommand_DeviceModeConf) GetClass() Class {
@@ -5975,14 +7018,873 @@ func (x *MACCommand_DeviceModeConf) GetClass() Class {
return Class_CLASS_A
}
-var File_ttn_lorawan_v3_lorawan_proto protoreflect.FileDescriptor
+type MACCommand_RelayConfReq struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
-var file_ttn_lorawan_v3_lorawan_proto_rawDesc = []byte{
- 0x0a, 0x1c, 0x74, 0x74, 0x6e, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2f, 0x76, 0x33,
- 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e,
- 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x1a, 0x1c,
- 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f,
- 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f,
+ Configuration *MACCommand_RelayConfReq_Configuration `protobuf:"bytes,1,opt,name=configuration,proto3" json:"configuration,omitempty"`
+}
+
+func (x *MACCommand_RelayConfReq) Reset() {
+ *x = MACCommand_RelayConfReq{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[72]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *MACCommand_RelayConfReq) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MACCommand_RelayConfReq) ProtoMessage() {}
+
+func (x *MACCommand_RelayConfReq) ProtoReflect() protoreflect.Message {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[72]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use MACCommand_RelayConfReq.ProtoReflect.Descriptor instead.
+func (*MACCommand_RelayConfReq) Descriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 30}
+}
+
+func (x *MACCommand_RelayConfReq) GetConfiguration() *MACCommand_RelayConfReq_Configuration {
+ if x != nil {
+ return x.Configuration
+ }
+ return nil
+}
+
+type MACCommand_RelayConfAns struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ SecondChannelFrequencyAck bool `protobuf:"varint,1,opt,name=second_channel_frequency_ack,json=secondChannelFrequencyAck,proto3" json:"second_channel_frequency_ack,omitempty"`
+ SecondChannelAckOffsetAck bool `protobuf:"varint,2,opt,name=second_channel_ack_offset_ack,json=secondChannelAckOffsetAck,proto3" json:"second_channel_ack_offset_ack,omitempty"`
+ SecondChannelDataRateIndexAck bool `protobuf:"varint,3,opt,name=second_channel_data_rate_index_ack,json=secondChannelDataRateIndexAck,proto3" json:"second_channel_data_rate_index_ack,omitempty"`
+ SecondChannelIndexAck bool `protobuf:"varint,4,opt,name=second_channel_index_ack,json=secondChannelIndexAck,proto3" json:"second_channel_index_ack,omitempty"`
+ DefaultChannelIndexAck bool `protobuf:"varint,5,opt,name=default_channel_index_ack,json=defaultChannelIndexAck,proto3" json:"default_channel_index_ack,omitempty"`
+ CadPeriodicityAck bool `protobuf:"varint,6,opt,name=cad_periodicity_ack,json=cadPeriodicityAck,proto3" json:"cad_periodicity_ack,omitempty"`
+}
+
+func (x *MACCommand_RelayConfAns) Reset() {
+ *x = MACCommand_RelayConfAns{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[73]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *MACCommand_RelayConfAns) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MACCommand_RelayConfAns) ProtoMessage() {}
+
+func (x *MACCommand_RelayConfAns) ProtoReflect() protoreflect.Message {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[73]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use MACCommand_RelayConfAns.ProtoReflect.Descriptor instead.
+func (*MACCommand_RelayConfAns) Descriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 31}
+}
+
+func (x *MACCommand_RelayConfAns) GetSecondChannelFrequencyAck() bool {
+ if x != nil {
+ return x.SecondChannelFrequencyAck
+ }
+ return false
+}
+
+func (x *MACCommand_RelayConfAns) GetSecondChannelAckOffsetAck() bool {
+ if x != nil {
+ return x.SecondChannelAckOffsetAck
+ }
+ return false
+}
+
+func (x *MACCommand_RelayConfAns) GetSecondChannelDataRateIndexAck() bool {
+ if x != nil {
+ return x.SecondChannelDataRateIndexAck
+ }
+ return false
+}
+
+func (x *MACCommand_RelayConfAns) GetSecondChannelIndexAck() bool {
+ if x != nil {
+ return x.SecondChannelIndexAck
+ }
+ return false
+}
+
+func (x *MACCommand_RelayConfAns) GetDefaultChannelIndexAck() bool {
+ if x != nil {
+ return x.DefaultChannelIndexAck
+ }
+ return false
+}
+
+func (x *MACCommand_RelayConfAns) GetCadPeriodicityAck() bool {
+ if x != nil {
+ return x.CadPeriodicityAck
+ }
+ return false
+}
+
+type MACCommand_RelayEndDeviceConfReq struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Configuration *MACCommand_RelayEndDeviceConfReq_Configuration `protobuf:"bytes,1,opt,name=configuration,proto3" json:"configuration,omitempty"`
+}
+
+func (x *MACCommand_RelayEndDeviceConfReq) Reset() {
+ *x = MACCommand_RelayEndDeviceConfReq{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[74]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *MACCommand_RelayEndDeviceConfReq) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MACCommand_RelayEndDeviceConfReq) ProtoMessage() {}
+
+func (x *MACCommand_RelayEndDeviceConfReq) ProtoReflect() protoreflect.Message {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[74]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use MACCommand_RelayEndDeviceConfReq.ProtoReflect.Descriptor instead.
+func (*MACCommand_RelayEndDeviceConfReq) Descriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 32}
+}
+
+func (x *MACCommand_RelayEndDeviceConfReq) GetConfiguration() *MACCommand_RelayEndDeviceConfReq_Configuration {
+ if x != nil {
+ return x.Configuration
+ }
+ return nil
+}
+
+type MACCommand_RelayEndDeviceConfAns struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ SecondChannelFrequencyAck bool `protobuf:"varint,1,opt,name=second_channel_frequency_ack,json=secondChannelFrequencyAck,proto3" json:"second_channel_frequency_ack,omitempty"`
+ SecondChannelDataRateIndexAck bool `protobuf:"varint,3,opt,name=second_channel_data_rate_index_ack,json=secondChannelDataRateIndexAck,proto3" json:"second_channel_data_rate_index_ack,omitempty"`
+ SecondChannelIndexAck bool `protobuf:"varint,4,opt,name=second_channel_index_ack,json=secondChannelIndexAck,proto3" json:"second_channel_index_ack,omitempty"`
+ BackoffAck bool `protobuf:"varint,5,opt,name=backoff_ack,json=backoffAck,proto3" json:"backoff_ack,omitempty"`
+}
+
+func (x *MACCommand_RelayEndDeviceConfAns) Reset() {
+ *x = MACCommand_RelayEndDeviceConfAns{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[75]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *MACCommand_RelayEndDeviceConfAns) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MACCommand_RelayEndDeviceConfAns) ProtoMessage() {}
+
+func (x *MACCommand_RelayEndDeviceConfAns) ProtoReflect() protoreflect.Message {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[75]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use MACCommand_RelayEndDeviceConfAns.ProtoReflect.Descriptor instead.
+func (*MACCommand_RelayEndDeviceConfAns) Descriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 33}
+}
+
+func (x *MACCommand_RelayEndDeviceConfAns) GetSecondChannelFrequencyAck() bool {
+ if x != nil {
+ return x.SecondChannelFrequencyAck
+ }
+ return false
+}
+
+func (x *MACCommand_RelayEndDeviceConfAns) GetSecondChannelDataRateIndexAck() bool {
+ if x != nil {
+ return x.SecondChannelDataRateIndexAck
+ }
+ return false
+}
+
+func (x *MACCommand_RelayEndDeviceConfAns) GetSecondChannelIndexAck() bool {
+ if x != nil {
+ return x.SecondChannelIndexAck
+ }
+ return false
+}
+
+func (x *MACCommand_RelayEndDeviceConfAns) GetBackoffAck() bool {
+ if x != nil {
+ return x.BackoffAck
+ }
+ return false
+}
+
+type MACCommand_RelayUpdateUplinkListReq struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ RuleIndex uint32 `protobuf:"varint,1,opt,name=rule_index,json=ruleIndex,proto3" json:"rule_index,omitempty"`
+ ForwardLimits *RelayUplinkForwardLimits `protobuf:"bytes,2,opt,name=forward_limits,json=forwardLimits,proto3" json:"forward_limits,omitempty"`
+ DevAddr []byte `protobuf:"bytes,3,opt,name=dev_addr,json=devAddr,proto3" json:"dev_addr,omitempty"`
+ WFCnt uint32 `protobuf:"varint,4,opt,name=w_f_cnt,json=wFCnt,proto3" json:"w_f_cnt,omitempty"`
+ RootWorSKey []byte `protobuf:"bytes,5,opt,name=root_wor_s_key,json=rootWorSKey,proto3" json:"root_wor_s_key,omitempty"`
+ DeviceId string `protobuf:"bytes,6,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"`
+ SessionKeyId []byte `protobuf:"bytes,7,opt,name=session_key_id,json=sessionKeyId,proto3" json:"session_key_id,omitempty"`
+}
+
+func (x *MACCommand_RelayUpdateUplinkListReq) Reset() {
+ *x = MACCommand_RelayUpdateUplinkListReq{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[76]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *MACCommand_RelayUpdateUplinkListReq) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MACCommand_RelayUpdateUplinkListReq) ProtoMessage() {}
+
+func (x *MACCommand_RelayUpdateUplinkListReq) ProtoReflect() protoreflect.Message {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[76]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use MACCommand_RelayUpdateUplinkListReq.ProtoReflect.Descriptor instead.
+func (*MACCommand_RelayUpdateUplinkListReq) Descriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 34}
+}
+
+func (x *MACCommand_RelayUpdateUplinkListReq) GetRuleIndex() uint32 {
+ if x != nil {
+ return x.RuleIndex
+ }
+ return 0
+}
+
+func (x *MACCommand_RelayUpdateUplinkListReq) GetForwardLimits() *RelayUplinkForwardLimits {
+ if x != nil {
+ return x.ForwardLimits
+ }
+ return nil
+}
+
+func (x *MACCommand_RelayUpdateUplinkListReq) GetDevAddr() []byte {
+ if x != nil {
+ return x.DevAddr
+ }
+ return nil
+}
+
+func (x *MACCommand_RelayUpdateUplinkListReq) GetWFCnt() uint32 {
+ if x != nil {
+ return x.WFCnt
+ }
+ return 0
+}
+
+func (x *MACCommand_RelayUpdateUplinkListReq) GetRootWorSKey() []byte {
+ if x != nil {
+ return x.RootWorSKey
+ }
+ return nil
+}
+
+func (x *MACCommand_RelayUpdateUplinkListReq) GetDeviceId() string {
+ if x != nil {
+ return x.DeviceId
+ }
+ return ""
+}
+
+func (x *MACCommand_RelayUpdateUplinkListReq) GetSessionKeyId() []byte {
+ if x != nil {
+ return x.SessionKeyId
+ }
+ return nil
+}
+
+type MACCommand_RelayUpdateUplinkListAns struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+}
+
+func (x *MACCommand_RelayUpdateUplinkListAns) Reset() {
+ *x = MACCommand_RelayUpdateUplinkListAns{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[77]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *MACCommand_RelayUpdateUplinkListAns) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MACCommand_RelayUpdateUplinkListAns) ProtoMessage() {}
+
+func (x *MACCommand_RelayUpdateUplinkListAns) ProtoReflect() protoreflect.Message {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[77]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use MACCommand_RelayUpdateUplinkListAns.ProtoReflect.Descriptor instead.
+func (*MACCommand_RelayUpdateUplinkListAns) Descriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 35}
+}
+
+type MACCommand_RelayCtrlUplinkListReq struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ RuleIndex uint32 `protobuf:"varint,1,opt,name=rule_index,json=ruleIndex,proto3" json:"rule_index,omitempty"`
+ Action RelayCtrlUplinkListAction `protobuf:"varint,2,opt,name=action,proto3,enum=ttn.lorawan.v3.RelayCtrlUplinkListAction" json:"action,omitempty"`
+}
+
+func (x *MACCommand_RelayCtrlUplinkListReq) Reset() {
+ *x = MACCommand_RelayCtrlUplinkListReq{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[78]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *MACCommand_RelayCtrlUplinkListReq) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MACCommand_RelayCtrlUplinkListReq) ProtoMessage() {}
+
+func (x *MACCommand_RelayCtrlUplinkListReq) ProtoReflect() protoreflect.Message {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[78]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use MACCommand_RelayCtrlUplinkListReq.ProtoReflect.Descriptor instead.
+func (*MACCommand_RelayCtrlUplinkListReq) Descriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 36}
+}
+
+func (x *MACCommand_RelayCtrlUplinkListReq) GetRuleIndex() uint32 {
+ if x != nil {
+ return x.RuleIndex
+ }
+ return 0
+}
+
+func (x *MACCommand_RelayCtrlUplinkListReq) GetAction() RelayCtrlUplinkListAction {
+ if x != nil {
+ return x.Action
+ }
+ return RelayCtrlUplinkListAction_RELAY_CTRL_UPLINK_LIST_ACTION_READ_W_F_CNT
+}
+
+type MACCommand_RelayCtrlUplinkListAns struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ RuleIndexAck bool `protobuf:"varint,1,opt,name=rule_index_ack,json=ruleIndexAck,proto3" json:"rule_index_ack,omitempty"`
+ WFCnt uint32 `protobuf:"varint,2,opt,name=w_f_cnt,json=wFCnt,proto3" json:"w_f_cnt,omitempty"`
+}
+
+func (x *MACCommand_RelayCtrlUplinkListAns) Reset() {
+ *x = MACCommand_RelayCtrlUplinkListAns{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[79]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *MACCommand_RelayCtrlUplinkListAns) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MACCommand_RelayCtrlUplinkListAns) ProtoMessage() {}
+
+func (x *MACCommand_RelayCtrlUplinkListAns) ProtoReflect() protoreflect.Message {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[79]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use MACCommand_RelayCtrlUplinkListAns.ProtoReflect.Descriptor instead.
+func (*MACCommand_RelayCtrlUplinkListAns) Descriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 37}
+}
+
+func (x *MACCommand_RelayCtrlUplinkListAns) GetRuleIndexAck() bool {
+ if x != nil {
+ return x.RuleIndexAck
+ }
+ return false
+}
+
+func (x *MACCommand_RelayCtrlUplinkListAns) GetWFCnt() uint32 {
+ if x != nil {
+ return x.WFCnt
+ }
+ return 0
+}
+
+type MACCommand_RelayConfigureFwdLimitReq struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ ResetLimitCounter RelayResetLimitCounter `protobuf:"varint,1,opt,name=reset_limit_counter,json=resetLimitCounter,proto3,enum=ttn.lorawan.v3.RelayResetLimitCounter" json:"reset_limit_counter,omitempty"`
+ JoinRequestLimits *RelayForwardLimits `protobuf:"bytes,2,opt,name=join_request_limits,json=joinRequestLimits,proto3" json:"join_request_limits,omitempty"`
+ NotifyLimits *RelayForwardLimits `protobuf:"bytes,3,opt,name=notify_limits,json=notifyLimits,proto3" json:"notify_limits,omitempty"`
+ GlobalUplinkLimits *RelayForwardLimits `protobuf:"bytes,4,opt,name=global_uplink_limits,json=globalUplinkLimits,proto3" json:"global_uplink_limits,omitempty"`
+ OverallLimits *RelayForwardLimits `protobuf:"bytes,5,opt,name=overall_limits,json=overallLimits,proto3" json:"overall_limits,omitempty"`
+}
+
+func (x *MACCommand_RelayConfigureFwdLimitReq) Reset() {
+ *x = MACCommand_RelayConfigureFwdLimitReq{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[80]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *MACCommand_RelayConfigureFwdLimitReq) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MACCommand_RelayConfigureFwdLimitReq) ProtoMessage() {}
+
+func (x *MACCommand_RelayConfigureFwdLimitReq) ProtoReflect() protoreflect.Message {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[80]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use MACCommand_RelayConfigureFwdLimitReq.ProtoReflect.Descriptor instead.
+func (*MACCommand_RelayConfigureFwdLimitReq) Descriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 38}
+}
+
+func (x *MACCommand_RelayConfigureFwdLimitReq) GetResetLimitCounter() RelayResetLimitCounter {
+ if x != nil {
+ return x.ResetLimitCounter
+ }
+ return RelayResetLimitCounter_RELAY_RESET_LIMIT_COUNTER_ZERO
+}
+
+func (x *MACCommand_RelayConfigureFwdLimitReq) GetJoinRequestLimits() *RelayForwardLimits {
+ if x != nil {
+ return x.JoinRequestLimits
+ }
+ return nil
+}
+
+func (x *MACCommand_RelayConfigureFwdLimitReq) GetNotifyLimits() *RelayForwardLimits {
+ if x != nil {
+ return x.NotifyLimits
+ }
+ return nil
+}
+
+func (x *MACCommand_RelayConfigureFwdLimitReq) GetGlobalUplinkLimits() *RelayForwardLimits {
+ if x != nil {
+ return x.GlobalUplinkLimits
+ }
+ return nil
+}
+
+func (x *MACCommand_RelayConfigureFwdLimitReq) GetOverallLimits() *RelayForwardLimits {
+ if x != nil {
+ return x.OverallLimits
+ }
+ return nil
+}
+
+type MACCommand_RelayConfigureFwdLimitAns struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+}
+
+func (x *MACCommand_RelayConfigureFwdLimitAns) Reset() {
+ *x = MACCommand_RelayConfigureFwdLimitAns{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[81]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *MACCommand_RelayConfigureFwdLimitAns) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MACCommand_RelayConfigureFwdLimitAns) ProtoMessage() {}
+
+func (x *MACCommand_RelayConfigureFwdLimitAns) ProtoReflect() protoreflect.Message {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[81]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use MACCommand_RelayConfigureFwdLimitAns.ProtoReflect.Descriptor instead.
+func (*MACCommand_RelayConfigureFwdLimitAns) Descriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 39}
+}
+
+type MACCommand_RelayNotifyNewEndDeviceReq struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ DevAddr []byte `protobuf:"bytes,1,opt,name=dev_addr,json=devAddr,proto3" json:"dev_addr,omitempty"`
+ Snr int32 `protobuf:"varint,2,opt,name=snr,proto3" json:"snr,omitempty"`
+ Rssi int32 `protobuf:"varint,3,opt,name=rssi,proto3" json:"rssi,omitempty"`
+}
+
+func (x *MACCommand_RelayNotifyNewEndDeviceReq) Reset() {
+ *x = MACCommand_RelayNotifyNewEndDeviceReq{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[82]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *MACCommand_RelayNotifyNewEndDeviceReq) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MACCommand_RelayNotifyNewEndDeviceReq) ProtoMessage() {}
+
+func (x *MACCommand_RelayNotifyNewEndDeviceReq) ProtoReflect() protoreflect.Message {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[82]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use MACCommand_RelayNotifyNewEndDeviceReq.ProtoReflect.Descriptor instead.
+func (*MACCommand_RelayNotifyNewEndDeviceReq) Descriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 40}
+}
+
+func (x *MACCommand_RelayNotifyNewEndDeviceReq) GetDevAddr() []byte {
+ if x != nil {
+ return x.DevAddr
+ }
+ return nil
+}
+
+func (x *MACCommand_RelayNotifyNewEndDeviceReq) GetSnr() int32 {
+ if x != nil {
+ return x.Snr
+ }
+ return 0
+}
+
+func (x *MACCommand_RelayNotifyNewEndDeviceReq) GetRssi() int32 {
+ if x != nil {
+ return x.Rssi
+ }
+ return 0
+}
+
+type MACCommand_RelayConfReq_Configuration struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ SecondChannel *RelaySecondChannel `protobuf:"bytes,1,opt,name=second_channel,json=secondChannel,proto3" json:"second_channel,omitempty"`
+ DefaultChannelIndex uint32 `protobuf:"varint,2,opt,name=default_channel_index,json=defaultChannelIndex,proto3" json:"default_channel_index,omitempty"`
+ CadPeriodicity RelayCADPeriodicity `protobuf:"varint,3,opt,name=cad_periodicity,json=cadPeriodicity,proto3,enum=ttn.lorawan.v3.RelayCADPeriodicity" json:"cad_periodicity,omitempty"`
+}
+
+func (x *MACCommand_RelayConfReq_Configuration) Reset() {
+ *x = MACCommand_RelayConfReq_Configuration{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[83]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *MACCommand_RelayConfReq_Configuration) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MACCommand_RelayConfReq_Configuration) ProtoMessage() {}
+
+func (x *MACCommand_RelayConfReq_Configuration) ProtoReflect() protoreflect.Message {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[83]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use MACCommand_RelayConfReq_Configuration.ProtoReflect.Descriptor instead.
+func (*MACCommand_RelayConfReq_Configuration) Descriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 30, 0}
+}
+
+func (x *MACCommand_RelayConfReq_Configuration) GetSecondChannel() *RelaySecondChannel {
+ if x != nil {
+ return x.SecondChannel
+ }
+ return nil
+}
+
+func (x *MACCommand_RelayConfReq_Configuration) GetDefaultChannelIndex() uint32 {
+ if x != nil {
+ return x.DefaultChannelIndex
+ }
+ return 0
+}
+
+func (x *MACCommand_RelayConfReq_Configuration) GetCadPeriodicity() RelayCADPeriodicity {
+ if x != nil {
+ return x.CadPeriodicity
+ }
+ return RelayCADPeriodicity_RELAY_CAD_PERIODICITY_1_SECOND
+}
+
+type MACCommand_RelayEndDeviceConfReq_Configuration struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // Types that are assignable to Mode:
+ // *MACCommand_RelayEndDeviceConfReq_Configuration_Always
+ // *MACCommand_RelayEndDeviceConfReq_Configuration_Dynamic
+ // *MACCommand_RelayEndDeviceConfReq_Configuration_EndDeviceControlled
+ Mode isMACCommand_RelayEndDeviceConfReq_Configuration_Mode `protobuf_oneof:"mode"`
+ Backoff uint32 `protobuf:"varint,4,opt,name=backoff,proto3" json:"backoff,omitempty"`
+ SecondChannel *RelaySecondChannel `protobuf:"bytes,5,opt,name=second_channel,json=secondChannel,proto3" json:"second_channel,omitempty"`
+ ServingDeviceId string `protobuf:"bytes,6,opt,name=serving_device_id,json=servingDeviceId,proto3" json:"serving_device_id,omitempty"`
+}
+
+func (x *MACCommand_RelayEndDeviceConfReq_Configuration) Reset() {
+ *x = MACCommand_RelayEndDeviceConfReq_Configuration{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[84]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *MACCommand_RelayEndDeviceConfReq_Configuration) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MACCommand_RelayEndDeviceConfReq_Configuration) ProtoMessage() {}
+
+func (x *MACCommand_RelayEndDeviceConfReq_Configuration) ProtoReflect() protoreflect.Message {
+ mi := &file_ttn_lorawan_v3_lorawan_proto_msgTypes[84]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use MACCommand_RelayEndDeviceConfReq_Configuration.ProtoReflect.Descriptor instead.
+func (*MACCommand_RelayEndDeviceConfReq_Configuration) Descriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP(), []int{26, 32, 0}
+}
+
+func (m *MACCommand_RelayEndDeviceConfReq_Configuration) GetMode() isMACCommand_RelayEndDeviceConfReq_Configuration_Mode {
+ if m != nil {
+ return m.Mode
+ }
+ return nil
+}
+
+func (x *MACCommand_RelayEndDeviceConfReq_Configuration) GetAlways() *RelayEndDeviceAlwaysMode {
+ if x, ok := x.GetMode().(*MACCommand_RelayEndDeviceConfReq_Configuration_Always); ok {
+ return x.Always
+ }
+ return nil
+}
+
+func (x *MACCommand_RelayEndDeviceConfReq_Configuration) GetDynamic() *RelayEndDeviceDynamicMode {
+ if x, ok := x.GetMode().(*MACCommand_RelayEndDeviceConfReq_Configuration_Dynamic); ok {
+ return x.Dynamic
+ }
+ return nil
+}
+
+func (x *MACCommand_RelayEndDeviceConfReq_Configuration) GetEndDeviceControlled() *RelayEndDeviceControlledMode {
+ if x, ok := x.GetMode().(*MACCommand_RelayEndDeviceConfReq_Configuration_EndDeviceControlled); ok {
+ return x.EndDeviceControlled
+ }
+ return nil
+}
+
+func (x *MACCommand_RelayEndDeviceConfReq_Configuration) GetBackoff() uint32 {
+ if x != nil {
+ return x.Backoff
+ }
+ return 0
+}
+
+func (x *MACCommand_RelayEndDeviceConfReq_Configuration) GetSecondChannel() *RelaySecondChannel {
+ if x != nil {
+ return x.SecondChannel
+ }
+ return nil
+}
+
+func (x *MACCommand_RelayEndDeviceConfReq_Configuration) GetServingDeviceId() string {
+ if x != nil {
+ return x.ServingDeviceId
+ }
+ return ""
+}
+
+type isMACCommand_RelayEndDeviceConfReq_Configuration_Mode interface {
+ isMACCommand_RelayEndDeviceConfReq_Configuration_Mode()
+}
+
+type MACCommand_RelayEndDeviceConfReq_Configuration_Always struct {
+ Always *RelayEndDeviceAlwaysMode `protobuf:"bytes,1,opt,name=always,proto3,oneof"`
+}
+
+type MACCommand_RelayEndDeviceConfReq_Configuration_Dynamic struct {
+ Dynamic *RelayEndDeviceDynamicMode `protobuf:"bytes,2,opt,name=dynamic,proto3,oneof"`
+}
+
+type MACCommand_RelayEndDeviceConfReq_Configuration_EndDeviceControlled struct {
+ EndDeviceControlled *RelayEndDeviceControlledMode `protobuf:"bytes,3,opt,name=end_device_controlled,json=endDeviceControlled,proto3,oneof"`
+}
+
+func (*MACCommand_RelayEndDeviceConfReq_Configuration_Always) isMACCommand_RelayEndDeviceConfReq_Configuration_Mode() {
+}
+
+func (*MACCommand_RelayEndDeviceConfReq_Configuration_Dynamic) isMACCommand_RelayEndDeviceConfReq_Configuration_Mode() {
+}
+
+func (*MACCommand_RelayEndDeviceConfReq_Configuration_EndDeviceControlled) isMACCommand_RelayEndDeviceConfReq_Configuration_Mode() {
+}
+
+var File_ttn_lorawan_v3_lorawan_proto protoreflect.FileDescriptor
+
+var file_ttn_lorawan_v3_lorawan_proto_rawDesc = []byte{
+ 0x0a, 0x1c, 0x74, 0x74, 0x6e, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2f, 0x76, 0x33,
+ 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e,
+ 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x1a, 0x1c,
+ 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f,
+ 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f,
0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69,
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70,
@@ -6345,10 +8247,10 @@ var file_ttn_lorawan_v3_lorawan_proto_rawDesc = []byte{
0x61, 0x64, 0x69, 0x6e, 0x67, 0x46, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x63,
0x6f, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
0x52, 0x0a, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x61, 0x74, 0x65, 0x3a, 0x08, 0xf2, 0xaa,
- 0x19, 0x04, 0x08, 0x01, 0x10, 0x00, 0x22, 0x32, 0x0a, 0x0b, 0x46, 0x53, 0x4b, 0x44, 0x61, 0x74,
+ 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x22, 0x32, 0x0a, 0x0b, 0x46, 0x53, 0x4b, 0x44, 0x61, 0x74,
0x61, 0x52, 0x61, 0x74, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x69, 0x74, 0x5f, 0x72, 0x61, 0x74,
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x62, 0x69, 0x74, 0x52, 0x61, 0x74, 0x65,
- 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x00, 0x22, 0x9c, 0x01, 0x0a, 0x0e, 0x4c,
+ 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x22, 0x9c, 0x01, 0x0a, 0x0e, 0x4c,
0x52, 0x46, 0x48, 0x53, 0x53, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x12, 0x27, 0x0a,
0x0f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69,
@@ -6358,7 +8260,7 @@ var file_ttn_lorawan_v3_lorawan_proto_rawDesc = []byte{
0x6e, 0x67, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x57, 0x69, 0x64, 0x74, 0x68, 0x12, 0x1f,
0x0a, 0x0b, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20,
0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x61, 0x74, 0x65, 0x3a,
- 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x00, 0x22, 0xc6, 0x01, 0x0a, 0x08, 0x44, 0x61,
+ 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x22, 0xc6, 0x01, 0x0a, 0x08, 0x44, 0x61,
0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x12, 0x32, 0x0a, 0x04, 0x6c, 0x6f, 0x72, 0x61, 0x18, 0x01,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x6f, 0x52, 0x61, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61,
@@ -6369,7 +8271,7 @@ var file_ttn_lorawan_v3_lorawan_proto_rawDesc = []byte{
0x72, 0x66, 0x68, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x74,
0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x52, 0x46,
0x48, 0x53, 0x53, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x48, 0x00, 0x52, 0x06, 0x6c,
- 0x72, 0x66, 0x68, 0x73, 0x73, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x00, 0x42,
+ 0x72, 0x66, 0x68, 0x73, 0x73, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x42,
0x11, 0x0a, 0x0a, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x03, 0xf8,
0x42, 0x01, 0x22, 0xf9, 0x03, 0x0a, 0x0a, 0x54, 0x78, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67,
0x73, 0x12, 0x3f, 0x0a, 0x09, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, 0x01,
@@ -6401,8 +8303,8 @@ var file_ttn_lorawan_v3_lorawan_proto_rawDesc = []byte{
0x13, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x5f, 0x70, 0x6f, 0x6c, 0x61, 0x72, 0x69, 0x7a, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x6e, 0x76, 0x65,
0x72, 0x74, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x08,
- 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x00, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01,
- 0x10, 0x00, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x22, 0x8f,
+ 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01,
+ 0x10, 0x01, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x22, 0x8f,
0x01, 0x0a, 0x19, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x41, 0x6e, 0x74, 0x65, 0x6e, 0x6e,
0x61, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x12, 0x4d, 0x0a, 0x0b,
0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28,
@@ -6490,879 +8392,1390 @@ var file_ttn_lorawan_v3_lorawan_proto_rawDesc = []byte{
0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x08, 0x61, 0x64, 0x76, 0x61, 0x6e, 0x63,
0x65, 0x64, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x4a, 0x04, 0x08, 0x06, 0x10, 0x07, 0x4a, 0x04,
- 0x08, 0x0b, 0x10, 0x0c, 0x22, 0xc2, 0x33, 0x0a, 0x0a, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d,
- 0x61, 0x6e, 0x64, 0x12, 0x42, 0x0a, 0x03, 0x63, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e,
- 0x32, 0x24, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
- 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x49, 0x64, 0x65, 0x6e,
- 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x42, 0x0a, 0xfa, 0x42, 0x07, 0x82, 0x01, 0x04, 0x10, 0x01,
- 0x20, 0x00, 0x52, 0x03, 0x63, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0b, 0x72, 0x61, 0x77, 0x5f, 0x70,
- 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0a,
- 0x72, 0x61, 0x77, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x42, 0x0a, 0x09, 0x72, 0x65,
- 0x73, 0x65, 0x74, 0x5f, 0x69, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e,
- 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d,
- 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x49,
- 0x6e, 0x64, 0x48, 0x00, 0x52, 0x08, 0x72, 0x65, 0x73, 0x65, 0x74, 0x49, 0x6e, 0x64, 0x12, 0x45,
- 0x0a, 0x0a, 0x72, 0x65, 0x73, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x18, 0x04, 0x20, 0x01,
- 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
- 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52,
- 0x65, 0x73, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x48, 0x00, 0x52, 0x09, 0x72, 0x65, 0x73, 0x65,
- 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x12, 0x4f, 0x0a, 0x0e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x63, 0x68,
- 0x65, 0x63, 0x6b, 0x5f, 0x61, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e,
+ 0x08, 0x0b, 0x10, 0x0c, 0x22, 0xe9, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x53, 0x65,
+ 0x63, 0x6f, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x4f, 0x0a, 0x0a, 0x61,
+ 0x63, 0x6b, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32,
+ 0x26, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
+ 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x43, 0x68, 0x41, 0x63,
+ 0x6b, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10,
+ 0x01, 0x52, 0x09, 0x61, 0x63, 0x6b, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x4f, 0x0a, 0x0f,
+ 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18,
+ 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
+ 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49,
+ 0x6e, 0x64, 0x65, 0x78, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0d,
+ 0x64, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x27, 0x0a,
+ 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04,
+ 0x42, 0x09, 0xfa, 0x42, 0x06, 0x32, 0x04, 0x28, 0xa0, 0x8d, 0x06, 0x52, 0x09, 0x66, 0x72, 0x65,
+ 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01,
+ 0x22, 0x9f, 0x01, 0x0a, 0x18, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b,
+ 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x4f, 0x0a,
+ 0x0b, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
+ 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x42, 0x75,
+ 0x63, 0x6b, 0x65, 0x74, 0x53, 0x69, 0x7a, 0x65, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02,
+ 0x10, 0x01, 0x52, 0x0a, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x28,
+ 0x0a, 0x0b, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20,
+ 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, 0x18, 0x3e, 0x52, 0x0a, 0x72, 0x65,
+ 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x61, 0x74, 0x65, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01,
+ 0x10, 0x01, 0x22, 0x99, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x46, 0x6f, 0x72, 0x77,
+ 0x61, 0x72, 0x64, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x4f, 0x0a, 0x0b, 0x62, 0x75, 0x63,
+ 0x6b, 0x65, 0x74, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24,
+ 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
+ 0x52, 0x65, 0x6c, 0x61, 0x79, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74,
+ 0x53, 0x69, 0x7a, 0x65, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0a,
+ 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x28, 0x0a, 0x0b, 0x72, 0x65,
+ 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x42,
+ 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, 0x18, 0x7e, 0x52, 0x0a, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64,
+ 0x52, 0x61, 0x74, 0x65, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x22, 0x24,
+ 0x0a, 0x18, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65,
+ 0x41, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x4d, 0x6f, 0x64, 0x65, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04,
+ 0x08, 0x01, 0x10, 0x01, 0x22, 0x84, 0x01, 0x0a, 0x19, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x45, 0x6e,
+ 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x4d, 0x6f,
+ 0x64, 0x65, 0x12, 0x5d, 0x0a, 0x12, 0x73, 0x6d, 0x61, 0x72, 0x74, 0x5f, 0x65, 0x6e, 0x61, 0x62,
+ 0x6c, 0x65, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25,
+ 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
+ 0x52, 0x65, 0x6c, 0x61, 0x79, 0x53, 0x6d, 0x61, 0x72, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65,
+ 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52,
+ 0x10, 0x73, 0x6d, 0x61, 0x72, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x65, 0x76, 0x65,
+ 0x6c, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x22, 0x28, 0x0a, 0x1c, 0x52,
+ 0x65, 0x6c, 0x61, 0x79, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e,
+ 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x3a, 0x08, 0xf2, 0xaa, 0x19,
+ 0x04, 0x08, 0x01, 0x10, 0x01, 0x22, 0xe5, 0x5b, 0x0a, 0x0a, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d,
+ 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x42, 0x0a, 0x03, 0x63, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x0e, 0x32, 0x24, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
+ 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x49, 0x64, 0x65,
+ 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x42, 0x0a, 0xfa, 0x42, 0x07, 0x82, 0x01, 0x04, 0x10,
+ 0x01, 0x20, 0x00, 0x52, 0x03, 0x63, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0b, 0x72, 0x61, 0x77, 0x5f,
+ 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52,
+ 0x0a, 0x72, 0x61, 0x77, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x42, 0x0a, 0x09, 0x72,
+ 0x65, 0x73, 0x65, 0x74, 0x5f, 0x69, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23,
+ 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
+ 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74,
+ 0x49, 0x6e, 0x64, 0x48, 0x00, 0x52, 0x08, 0x72, 0x65, 0x73, 0x65, 0x74, 0x49, 0x6e, 0x64, 0x12,
+ 0x45, 0x0a, 0x0a, 0x72, 0x65, 0x73, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x18, 0x04, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
+ 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e,
+ 0x52, 0x65, 0x73, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x48, 0x00, 0x52, 0x09, 0x72, 0x65, 0x73,
+ 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x12, 0x4f, 0x0a, 0x0e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x63,
+ 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x61, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27,
+ 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
+ 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x4c, 0x69, 0x6e, 0x6b, 0x43,
+ 0x68, 0x65, 0x63, 0x6b, 0x41, 0x6e, 0x73, 0x48, 0x00, 0x52, 0x0c, 0x6c, 0x69, 0x6e, 0x6b, 0x43,
+ 0x68, 0x65, 0x63, 0x6b, 0x41, 0x6e, 0x73, 0x12, 0x49, 0x0a, 0x0c, 0x6c, 0x69, 0x6e, 0x6b, 0x5f,
+ 0x61, 0x64, 0x72, 0x5f, 0x72, 0x65, 0x71, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e,
0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d,
- 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x4c, 0x69, 0x6e, 0x6b, 0x43, 0x68,
- 0x65, 0x63, 0x6b, 0x41, 0x6e, 0x73, 0x48, 0x00, 0x52, 0x0c, 0x6c, 0x69, 0x6e, 0x6b, 0x43, 0x68,
- 0x65, 0x63, 0x6b, 0x41, 0x6e, 0x73, 0x12, 0x49, 0x0a, 0x0c, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x61,
- 0x64, 0x72, 0x5f, 0x72, 0x65, 0x71, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x74,
+ 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x4c, 0x69, 0x6e, 0x6b, 0x41, 0x44,
+ 0x52, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x0a, 0x6c, 0x69, 0x6e, 0x6b, 0x41, 0x64, 0x72, 0x52,
+ 0x65, 0x71, 0x12, 0x49, 0x0a, 0x0c, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x61, 0x64, 0x72, 0x5f, 0x61,
+ 0x6e, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c,
+ 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d,
+ 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x4c, 0x69, 0x6e, 0x6b, 0x41, 0x44, 0x52, 0x41, 0x6e, 0x73, 0x48,
+ 0x00, 0x52, 0x0a, 0x6c, 0x69, 0x6e, 0x6b, 0x41, 0x64, 0x72, 0x41, 0x6e, 0x73, 0x12, 0x4f, 0x0a,
+ 0x0e, 0x64, 0x75, 0x74, 0x79, 0x5f, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x71, 0x18,
+ 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
+ 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
+ 0x64, 0x2e, 0x44, 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x48, 0x00,
+ 0x52, 0x0c, 0x64, 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x12, 0x59,
+ 0x0a, 0x12, 0x72, 0x78, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x5f, 0x73, 0x65, 0x74, 0x75, 0x70,
+ 0x5f, 0x72, 0x65, 0x71, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x74, 0x74, 0x6e,
+ 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43,
+ 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x78, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x65,
+ 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x0f, 0x72, 0x78, 0x50, 0x61, 0x72, 0x61,
+ 0x6d, 0x53, 0x65, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x12, 0x59, 0x0a, 0x12, 0x72, 0x78, 0x5f,
+ 0x70, 0x61, 0x72, 0x61, 0x6d, 0x5f, 0x73, 0x65, 0x74, 0x75, 0x70, 0x5f, 0x61, 0x6e, 0x73, 0x18,
+ 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
+ 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
+ 0x64, 0x2e, 0x52, 0x78, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x65, 0x74, 0x75, 0x70, 0x41, 0x6e,
+ 0x73, 0x48, 0x00, 0x52, 0x0f, 0x72, 0x78, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x65, 0x74, 0x75,
+ 0x70, 0x41, 0x6e, 0x73, 0x12, 0x4f, 0x0a, 0x0e, 0x64, 0x65, 0x76, 0x5f, 0x73, 0x74, 0x61, 0x74,
+ 0x75, 0x73, 0x5f, 0x61, 0x6e, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74,
0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41,
- 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x4c, 0x69, 0x6e, 0x6b, 0x41, 0x44, 0x52,
- 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x0a, 0x6c, 0x69, 0x6e, 0x6b, 0x41, 0x64, 0x72, 0x52, 0x65,
- 0x71, 0x12, 0x49, 0x0a, 0x0c, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x61, 0x64, 0x72, 0x5f, 0x61, 0x6e,
- 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
- 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d,
- 0x61, 0x6e, 0x64, 0x2e, 0x4c, 0x69, 0x6e, 0x6b, 0x41, 0x44, 0x52, 0x41, 0x6e, 0x73, 0x48, 0x00,
- 0x52, 0x0a, 0x6c, 0x69, 0x6e, 0x6b, 0x41, 0x64, 0x72, 0x41, 0x6e, 0x73, 0x12, 0x4f, 0x0a, 0x0e,
- 0x64, 0x75, 0x74, 0x79, 0x5f, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x71, 0x18, 0x08,
- 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
- 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64,
- 0x2e, 0x44, 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52,
- 0x0c, 0x64, 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x12, 0x59, 0x0a,
- 0x12, 0x72, 0x78, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x5f, 0x73, 0x65, 0x74, 0x75, 0x70, 0x5f,
- 0x72, 0x65, 0x71, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
+ 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x44, 0x65, 0x76, 0x53, 0x74, 0x61, 0x74,
+ 0x75, 0x73, 0x41, 0x6e, 0x73, 0x48, 0x00, 0x52, 0x0c, 0x64, 0x65, 0x76, 0x53, 0x74, 0x61, 0x74,
+ 0x75, 0x73, 0x41, 0x6e, 0x73, 0x12, 0x52, 0x0a, 0x0f, 0x6e, 0x65, 0x77, 0x5f, 0x63, 0x68, 0x61,
+ 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x72, 0x65, 0x71, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28,
+ 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
+ 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x4e, 0x65, 0x77, 0x43, 0x68,
+ 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x0d, 0x6e, 0x65, 0x77, 0x43,
+ 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x12, 0x52, 0x0a, 0x0f, 0x6e, 0x65, 0x77,
+ 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x61, 0x6e, 0x73, 0x18, 0x0d, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
+ 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x4e,
+ 0x65, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x41, 0x6e, 0x73, 0x48, 0x00, 0x52, 0x0d,
+ 0x6e, 0x65, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x41, 0x6e, 0x73, 0x12, 0x4f, 0x0a,
+ 0x0e, 0x64, 0x6c, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x72, 0x65, 0x71, 0x18,
+ 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
+ 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
+ 0x64, 0x2e, 0x44, 0x4c, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x48, 0x00,
+ 0x52, 0x0c, 0x64, 0x6c, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x12, 0x4f,
+ 0x0a, 0x0e, 0x64, 0x6c, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x61, 0x6e, 0x73,
+ 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
+ 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61,
+ 0x6e, 0x64, 0x2e, 0x44, 0x4c, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x41, 0x6e, 0x73, 0x48,
+ 0x00, 0x52, 0x0c, 0x64, 0x6c, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x41, 0x6e, 0x73, 0x12,
+ 0x5c, 0x0a, 0x13, 0x72, 0x78, 0x5f, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x74,
+ 0x75, 0x70, 0x5f, 0x72, 0x65, 0x71, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74,
+ 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41,
+ 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x78, 0x54, 0x69, 0x6d, 0x69, 0x6e,
+ 0x67, 0x53, 0x65, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x10, 0x72, 0x78, 0x54,
+ 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x12, 0x59, 0x0a,
+ 0x12, 0x74, 0x78, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x5f, 0x73, 0x65, 0x74, 0x75, 0x70, 0x5f,
+ 0x72, 0x65, 0x71, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f,
- 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x78, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x65, 0x74,
- 0x75, 0x70, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x0f, 0x72, 0x78, 0x50, 0x61, 0x72, 0x61, 0x6d,
- 0x53, 0x65, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x12, 0x59, 0x0a, 0x12, 0x72, 0x78, 0x5f, 0x70,
- 0x61, 0x72, 0x61, 0x6d, 0x5f, 0x73, 0x65, 0x74, 0x75, 0x70, 0x5f, 0x61, 0x6e, 0x73, 0x18, 0x0a,
- 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
- 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64,
- 0x2e, 0x52, 0x78, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x65, 0x74, 0x75, 0x70, 0x41, 0x6e, 0x73,
- 0x48, 0x00, 0x52, 0x0f, 0x72, 0x78, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x65, 0x74, 0x75, 0x70,
- 0x41, 0x6e, 0x73, 0x12, 0x4f, 0x0a, 0x0e, 0x64, 0x65, 0x76, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75,
- 0x73, 0x5f, 0x61, 0x6e, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x74,
+ 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x54, 0x78, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x65, 0x74,
+ 0x75, 0x70, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x0f, 0x74, 0x78, 0x50, 0x61, 0x72, 0x61, 0x6d,
+ 0x53, 0x65, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x12, 0x42, 0x0a, 0x09, 0x72, 0x65, 0x6b, 0x65,
+ 0x79, 0x5f, 0x69, 0x6e, 0x64, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x74,
0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43,
- 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x44, 0x65, 0x76, 0x53, 0x74, 0x61, 0x74, 0x75,
- 0x73, 0x41, 0x6e, 0x73, 0x48, 0x00, 0x52, 0x0c, 0x64, 0x65, 0x76, 0x53, 0x74, 0x61, 0x74, 0x75,
- 0x73, 0x41, 0x6e, 0x73, 0x12, 0x52, 0x0a, 0x0f, 0x6e, 0x65, 0x77, 0x5f, 0x63, 0x68, 0x61, 0x6e,
- 0x6e, 0x65, 0x6c, 0x5f, 0x72, 0x65, 0x71, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e,
- 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d,
- 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x4e, 0x65, 0x77, 0x43, 0x68, 0x61,
- 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x0d, 0x6e, 0x65, 0x77, 0x43, 0x68,
- 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x12, 0x52, 0x0a, 0x0f, 0x6e, 0x65, 0x77, 0x5f,
- 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x61, 0x6e, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28,
- 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
- 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x4e, 0x65,
- 0x77, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x41, 0x6e, 0x73, 0x48, 0x00, 0x52, 0x0d, 0x6e,
- 0x65, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x41, 0x6e, 0x73, 0x12, 0x4f, 0x0a, 0x0e,
- 0x64, 0x6c, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x72, 0x65, 0x71, 0x18, 0x0e,
- 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
+ 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x6b, 0x65, 0x79, 0x49, 0x6e, 0x64,
+ 0x48, 0x00, 0x52, 0x08, 0x72, 0x65, 0x6b, 0x65, 0x79, 0x49, 0x6e, 0x64, 0x12, 0x45, 0x0a, 0x0a,
+ 0x72, 0x65, 0x6b, 0x65, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x24, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
+ 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x6b,
+ 0x65, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x48, 0x00, 0x52, 0x09, 0x72, 0x65, 0x6b, 0x65, 0x79, 0x43,
+ 0x6f, 0x6e, 0x66, 0x12, 0x5c, 0x0a, 0x13, 0x61, 0x64, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d,
+ 0x5f, 0x73, 0x65, 0x74, 0x75, 0x70, 0x5f, 0x72, 0x65, 0x71, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x2b, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
+ 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x44, 0x52,
+ 0x50, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x65, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52,
+ 0x10, 0x61, 0x64, 0x72, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x65, 0x74, 0x75, 0x70, 0x52, 0x65,
+ 0x71, 0x12, 0x52, 0x0a, 0x0f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65,
+ 0x5f, 0x61, 0x6e, 0x73, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x74, 0x6e,
+ 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43,
+ 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x69, 0x6d,
+ 0x65, 0x41, 0x6e, 0x73, 0x48, 0x00, 0x52, 0x0d, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x69,
+ 0x6d, 0x65, 0x41, 0x6e, 0x73, 0x12, 0x55, 0x0a, 0x10, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x5f, 0x72,
+ 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x29, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
+ 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x46, 0x6f, 0x72, 0x63,
+ 0x65, 0x52, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x0e, 0x66, 0x6f,
+ 0x72, 0x63, 0x65, 0x52, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x65, 0x0a, 0x16,
+ 0x72, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x5f, 0x73, 0x65, 0x74,
+ 0x75, 0x70, 0x5f, 0x72, 0x65, 0x71, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x74,
+ 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41,
+ 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x50,
+ 0x61, 0x72, 0x61, 0x6d, 0x53, 0x65, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x13,
+ 0x72, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x65, 0x74, 0x75, 0x70,
+ 0x52, 0x65, 0x71, 0x12, 0x65, 0x0a, 0x16, 0x72, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x70, 0x61,
+ 0x72, 0x61, 0x6d, 0x5f, 0x73, 0x65, 0x74, 0x75, 0x70, 0x5f, 0x61, 0x6e, 0x73, 0x18, 0x18, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
+ 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e,
+ 0x52, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x65, 0x74, 0x75, 0x70,
+ 0x41, 0x6e, 0x73, 0x48, 0x00, 0x52, 0x13, 0x72, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x50, 0x61, 0x72,
+ 0x61, 0x6d, 0x53, 0x65, 0x74, 0x75, 0x70, 0x41, 0x6e, 0x73, 0x12, 0x59, 0x0a, 0x12, 0x70, 0x69,
+ 0x6e, 0x67, 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x72, 0x65, 0x71,
+ 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
+ 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61,
+ 0x6e, 0x64, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52,
+ 0x65, 0x71, 0x48, 0x00, 0x52, 0x0f, 0x70, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x49, 0x6e,
+ 0x66, 0x6f, 0x52, 0x65, 0x71, 0x12, 0x62, 0x0a, 0x15, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x6c,
+ 0x6f, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x72, 0x65, 0x71, 0x18, 0x1a,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64,
- 0x2e, 0x44, 0x4c, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52,
- 0x0c, 0x64, 0x6c, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x12, 0x4f, 0x0a,
- 0x0e, 0x64, 0x6c, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x61, 0x6e, 0x73, 0x18,
- 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
- 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
- 0x64, 0x2e, 0x44, 0x4c, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x41, 0x6e, 0x73, 0x48, 0x00,
- 0x52, 0x0c, 0x64, 0x6c, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x41, 0x6e, 0x73, 0x12, 0x5c,
- 0x0a, 0x13, 0x72, 0x78, 0x5f, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x74, 0x75,
- 0x70, 0x5f, 0x72, 0x65, 0x71, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x74,
- 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43,
- 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x78, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67,
- 0x53, 0x65, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x10, 0x72, 0x78, 0x54, 0x69,
- 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x12, 0x59, 0x0a, 0x12,
- 0x74, 0x78, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x5f, 0x73, 0x65, 0x74, 0x75, 0x70, 0x5f, 0x72,
- 0x65, 0x71, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c,
+ 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c,
+ 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x12, 0x70, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x43,
+ 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x12, 0x62, 0x0a, 0x15, 0x70, 0x69, 0x6e,
+ 0x67, 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x61,
+ 0x6e, 0x73, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c,
0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d,
- 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x54, 0x78, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x65, 0x74, 0x75,
- 0x70, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x0f, 0x74, 0x78, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x53,
- 0x65, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x12, 0x42, 0x0a, 0x09, 0x72, 0x65, 0x6b, 0x65, 0x79,
- 0x5f, 0x69, 0x6e, 0x64, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e,
- 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43,
- 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x6b, 0x65, 0x79, 0x49, 0x6e, 0x64, 0x48,
- 0x00, 0x52, 0x08, 0x72, 0x65, 0x6b, 0x65, 0x79, 0x49, 0x6e, 0x64, 0x12, 0x45, 0x0a, 0x0a, 0x72,
- 0x65, 0x6b, 0x65, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32,
- 0x24, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
- 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x6b, 0x65,
- 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x48, 0x00, 0x52, 0x09, 0x72, 0x65, 0x6b, 0x65, 0x79, 0x43, 0x6f,
- 0x6e, 0x66, 0x12, 0x5c, 0x0a, 0x13, 0x61, 0x64, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x5f,
- 0x73, 0x65, 0x74, 0x75, 0x70, 0x5f, 0x72, 0x65, 0x71, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32,
- 0x2b, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
- 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x44, 0x52, 0x50,
- 0x61, 0x72, 0x61, 0x6d, 0x53, 0x65, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x10,
- 0x61, 0x64, 0x72, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x65, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71,
- 0x12, 0x52, 0x0a, 0x0f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f,
- 0x61, 0x6e, 0x73, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
- 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f,
- 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x69, 0x6d, 0x65,
- 0x41, 0x6e, 0x73, 0x48, 0x00, 0x52, 0x0d, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x69, 0x6d,
- 0x65, 0x41, 0x6e, 0x73, 0x12, 0x55, 0x0a, 0x10, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x5f, 0x72, 0x65,
- 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29,
+ 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x43, 0x68, 0x61,
+ 0x6e, 0x6e, 0x65, 0x6c, 0x41, 0x6e, 0x73, 0x48, 0x00, 0x52, 0x12, 0x70, 0x69, 0x6e, 0x67, 0x53,
+ 0x6c, 0x6f, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x41, 0x6e, 0x73, 0x12, 0x58, 0x0a,
+ 0x11, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x5f, 0x61,
+ 0x6e, 0x73, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c,
+ 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d,
+ 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x69, 0x6e,
+ 0x67, 0x41, 0x6e, 0x73, 0x48, 0x00, 0x52, 0x0f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x54, 0x69,
+ 0x6d, 0x69, 0x6e, 0x67, 0x41, 0x6e, 0x73, 0x12, 0x52, 0x0a, 0x0f, 0x62, 0x65, 0x61, 0x63, 0x6f,
+ 0x6e, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x5f, 0x72, 0x65, 0x71, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x28, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
+ 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x42, 0x65, 0x61,
+ 0x63, 0x6f, 0x6e, 0x46, 0x72, 0x65, 0x71, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x0d, 0x62, 0x65,
+ 0x61, 0x63, 0x6f, 0x6e, 0x46, 0x72, 0x65, 0x71, 0x52, 0x65, 0x71, 0x12, 0x52, 0x0a, 0x0f, 0x62,
+ 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x5f, 0x61, 0x6e, 0x73, 0x18, 0x1e,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
+ 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64,
+ 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x46, 0x72, 0x65, 0x71, 0x41, 0x6e, 0x73, 0x48, 0x00,
+ 0x52, 0x0d, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x46, 0x72, 0x65, 0x71, 0x41, 0x6e, 0x73, 0x12,
+ 0x52, 0x0a, 0x0f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x5f, 0x69,
+ 0x6e, 0x64, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c,
+ 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d,
+ 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x49,
+ 0x6e, 0x64, 0x48, 0x00, 0x52, 0x0d, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65,
+ 0x49, 0x6e, 0x64, 0x12, 0x55, 0x0a, 0x10, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6d, 0x6f,
+ 0x64, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x18, 0x20, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e,
+ 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d,
+ 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65,
+ 0x4d, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x48, 0x00, 0x52, 0x0e, 0x64, 0x65, 0x76, 0x69,
+ 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x12, 0x4f, 0x0a, 0x0e, 0x72, 0x65,
+ 0x6c, 0x61, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x5f, 0x72, 0x65, 0x71, 0x18, 0x21, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
+ 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52,
+ 0x65, 0x6c, 0x61, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x0c, 0x72,
+ 0x65, 0x6c, 0x61, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x52, 0x65, 0x71, 0x12, 0x4f, 0x0a, 0x0e, 0x72,
+ 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x5f, 0x61, 0x6e, 0x73, 0x18, 0x22, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
+ 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e,
+ 0x52, 0x65, 0x6c, 0x61, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x41, 0x6e, 0x73, 0x48, 0x00, 0x52, 0x0c,
+ 0x72, 0x65, 0x6c, 0x61, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x41, 0x6e, 0x73, 0x12, 0x6c, 0x0a, 0x19,
+ 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x65, 0x6e, 0x64, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65,
+ 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x5f, 0x72, 0x65, 0x71, 0x18, 0x23, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x30, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
+ 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x6c, 0x61,
+ 0x79, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x52, 0x65,
+ 0x71, 0x48, 0x00, 0x52, 0x15, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76,
+ 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x52, 0x65, 0x71, 0x12, 0x6c, 0x0a, 0x19, 0x72, 0x65,
+ 0x6c, 0x61, 0x79, 0x5f, 0x65, 0x6e, 0x64, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x63,
+ 0x6f, 0x6e, 0x66, 0x5f, 0x61, 0x6e, 0x73, 0x18, 0x24, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e,
+ 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d,
+ 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x45,
+ 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x41, 0x6e, 0x73, 0x48,
+ 0x00, 0x52, 0x15, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63,
+ 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x41, 0x6e, 0x73, 0x12, 0x75, 0x0a, 0x1c, 0x72, 0x65, 0x6c, 0x61,
+ 0x79, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x5f,
+ 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x71, 0x18, 0x27, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33,
0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
- 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x46, 0x6f, 0x72, 0x63, 0x65,
- 0x52, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x0e, 0x66, 0x6f, 0x72,
- 0x63, 0x65, 0x52, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x65, 0x0a, 0x16, 0x72,
- 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x5f, 0x73, 0x65, 0x74, 0x75,
- 0x70, 0x5f, 0x72, 0x65, 0x71, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x74, 0x74,
+ 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79,
+ 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x4c, 0x69, 0x73, 0x74,
+ 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x18, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x55, 0x70, 0x64, 0x61,
+ 0x74, 0x65, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x12,
+ 0x75, 0x0a, 0x1c, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f,
+ 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x61, 0x6e, 0x73, 0x18,
+ 0x28, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
+ 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
+ 0x64, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x70, 0x6c,
+ 0x69, 0x6e, 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6e, 0x73, 0x48, 0x00, 0x52, 0x18, 0x72, 0x65,
+ 0x6c, 0x61, 0x79, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x4c,
+ 0x69, 0x73, 0x74, 0x41, 0x6e, 0x73, 0x12, 0x6f, 0x0a, 0x1a, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f,
+ 0x63, 0x74, 0x72, 0x6c, 0x5f, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6c, 0x69, 0x73, 0x74,
+ 0x5f, 0x72, 0x65, 0x71, 0x18, 0x29, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x74, 0x74, 0x6e,
+ 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43,
+ 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x43, 0x74, 0x72, 0x6c,
+ 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52,
+ 0x16, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x43, 0x74, 0x72, 0x6c, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b,
+ 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x12, 0x6f, 0x0a, 0x1a, 0x72, 0x65, 0x6c, 0x61, 0x79,
+ 0x5f, 0x63, 0x74, 0x72, 0x6c, 0x5f, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6c, 0x69, 0x73,
+ 0x74, 0x5f, 0x61, 0x6e, 0x73, 0x18, 0x2a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x74, 0x74,
0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43,
- 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x50, 0x61,
- 0x72, 0x61, 0x6d, 0x53, 0x65, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x13, 0x72,
- 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x65, 0x74, 0x75, 0x70, 0x52,
- 0x65, 0x71, 0x12, 0x65, 0x0a, 0x16, 0x72, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x70, 0x61, 0x72,
- 0x61, 0x6d, 0x5f, 0x73, 0x65, 0x74, 0x75, 0x70, 0x5f, 0x61, 0x6e, 0x73, 0x18, 0x18, 0x20, 0x01,
- 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
- 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52,
- 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x65, 0x74, 0x75, 0x70, 0x41,
- 0x6e, 0x73, 0x48, 0x00, 0x52, 0x13, 0x72, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x50, 0x61, 0x72, 0x61,
- 0x6d, 0x53, 0x65, 0x74, 0x75, 0x70, 0x41, 0x6e, 0x73, 0x12, 0x59, 0x0a, 0x12, 0x70, 0x69, 0x6e,
- 0x67, 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x72, 0x65, 0x71, 0x18,
- 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
+ 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x43, 0x74, 0x72,
+ 0x6c, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6e, 0x73, 0x48, 0x00,
+ 0x52, 0x16, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x43, 0x74, 0x72, 0x6c, 0x55, 0x70, 0x6c, 0x69, 0x6e,
+ 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6e, 0x73, 0x12, 0x78, 0x0a, 0x1d, 0x72, 0x65, 0x6c, 0x61,
+ 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x5f, 0x66, 0x77, 0x64, 0x5f,
+ 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x72, 0x65, 0x71, 0x18, 0x2b, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x34, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
+ 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x6c, 0x61,
+ 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x46, 0x77, 0x64, 0x4c, 0x69, 0x6d,
+ 0x69, 0x74, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x19, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x43, 0x6f,
+ 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x46, 0x77, 0x64, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52,
+ 0x65, 0x71, 0x12, 0x78, 0x0a, 0x1d, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x66,
+ 0x69, 0x67, 0x75, 0x72, 0x65, 0x5f, 0x66, 0x77, 0x64, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f,
+ 0x61, 0x6e, 0x73, 0x18, 0x2c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
+ 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f,
+ 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+ 0x67, 0x75, 0x72, 0x65, 0x46, 0x77, 0x64, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x41, 0x6e, 0x73, 0x48,
+ 0x00, 0x52, 0x19, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72,
+ 0x65, 0x46, 0x77, 0x64, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x41, 0x6e, 0x73, 0x12, 0x7c, 0x0a, 0x1f,
+ 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x5f, 0x6e, 0x65, 0x77,
+ 0x5f, 0x65, 0x6e, 0x64, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x71, 0x18,
+ 0x2d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
- 0x64, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65,
- 0x71, 0x48, 0x00, 0x52, 0x0f, 0x70, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x49, 0x6e, 0x66,
- 0x6f, 0x52, 0x65, 0x71, 0x12, 0x62, 0x0a, 0x15, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x6c, 0x6f,
- 0x74, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x72, 0x65, 0x71, 0x18, 0x1a, 0x20,
- 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
- 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e,
- 0x50, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52,
- 0x65, 0x71, 0x48, 0x00, 0x52, 0x12, 0x70, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x43, 0x68,
- 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x12, 0x62, 0x0a, 0x15, 0x70, 0x69, 0x6e, 0x67,
- 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x61, 0x6e,
- 0x73, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
- 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d,
- 0x61, 0x6e, 0x64, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x43, 0x68, 0x61, 0x6e,
- 0x6e, 0x65, 0x6c, 0x41, 0x6e, 0x73, 0x48, 0x00, 0x52, 0x12, 0x70, 0x69, 0x6e, 0x67, 0x53, 0x6c,
- 0x6f, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x41, 0x6e, 0x73, 0x12, 0x58, 0x0a, 0x11,
- 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x6e,
- 0x73, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
- 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d,
- 0x61, 0x6e, 0x64, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67,
- 0x41, 0x6e, 0x73, 0x48, 0x00, 0x52, 0x0f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x54, 0x69, 0x6d,
- 0x69, 0x6e, 0x67, 0x41, 0x6e, 0x73, 0x12, 0x52, 0x0a, 0x0f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e,
- 0x5f, 0x66, 0x72, 0x65, 0x71, 0x5f, 0x72, 0x65, 0x71, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x0b, 0x32,
- 0x28, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
- 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x42, 0x65, 0x61, 0x63,
- 0x6f, 0x6e, 0x46, 0x72, 0x65, 0x71, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x0d, 0x62, 0x65, 0x61,
- 0x63, 0x6f, 0x6e, 0x46, 0x72, 0x65, 0x71, 0x52, 0x65, 0x71, 0x12, 0x52, 0x0a, 0x0f, 0x62, 0x65,
- 0x61, 0x63, 0x6f, 0x6e, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x5f, 0x61, 0x6e, 0x73, 0x18, 0x1e, 0x20,
- 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
- 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e,
- 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x46, 0x72, 0x65, 0x71, 0x41, 0x6e, 0x73, 0x48, 0x00, 0x52,
- 0x0d, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x46, 0x72, 0x65, 0x71, 0x41, 0x6e, 0x73, 0x12, 0x52,
- 0x0a, 0x0f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x6e,
- 0x64, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
+ 0x64, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4e, 0x65, 0x77,
+ 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x1a,
+ 0x72, 0x65, 0x6c, 0x61, 0x79, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4e, 0x65, 0x77, 0x45, 0x6e,
+ 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x52, 0x0a, 0x08, 0x52, 0x65,
+ 0x73, 0x65, 0x74, 0x49, 0x6e, 0x64, 0x12, 0x46, 0x0a, 0x0d, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x5f,
+ 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e,
+ 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d,
+ 0x69, 0x6e, 0x6f, 0x72, 0x42, 0x0a, 0xfa, 0x42, 0x07, 0x82, 0x01, 0x04, 0x10, 0x01, 0x18, 0x01,
+ 0x52, 0x0c, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x53,
+ 0x0a, 0x09, 0x52, 0x65, 0x73, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x12, 0x46, 0x0a, 0x0d, 0x6d,
+ 0x69, 0x6e, 0x6f, 0x72, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
+ 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x69, 0x6e, 0x6f, 0x72, 0x42, 0x0a, 0xfa, 0x42, 0x07, 0x82, 0x01,
+ 0x04, 0x10, 0x01, 0x18, 0x01, 0x52, 0x0c, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x56, 0x65, 0x72, 0x73,
+ 0x69, 0x6f, 0x6e, 0x1a, 0x5f, 0x0a, 0x0c, 0x4c, 0x69, 0x6e, 0x6b, 0x43, 0x68, 0x65, 0x63, 0x6b,
+ 0x41, 0x6e, 0x73, 0x12, 0x20, 0x0a, 0x06, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x0d, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x2a, 0x03, 0x18, 0xfe, 0x01, 0x52, 0x06, 0x6d,
+ 0x61, 0x72, 0x67, 0x69, 0x6e, 0x12, 0x2d, 0x0a, 0x0d, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
+ 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x08, 0xfa, 0x42,
+ 0x05, 0x2a, 0x03, 0x18, 0xff, 0x01, 0x52, 0x0c, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x43,
+ 0x6f, 0x75, 0x6e, 0x74, 0x1a, 0x9e, 0x02, 0x0a, 0x0a, 0x4c, 0x69, 0x6e, 0x6b, 0x41, 0x44, 0x52,
+ 0x52, 0x65, 0x71, 0x12, 0x4f, 0x0a, 0x0f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65,
+ 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74,
+ 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61,
+ 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x42, 0x08, 0xfa, 0x42, 0x05,
+ 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0d, 0x64, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49,
+ 0x6e, 0x64, 0x65, 0x78, 0x12, 0x2d, 0x0a, 0x0e, 0x74, 0x78, 0x5f, 0x70, 0x6f, 0x77, 0x65, 0x72,
+ 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42,
+ 0x04, 0x2a, 0x02, 0x18, 0x0f, 0x52, 0x0c, 0x74, 0x78, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x49, 0x6e,
+ 0x64, 0x65, 0x78, 0x12, 0x2b, 0x0a, 0x0c, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x6d,
+ 0x61, 0x73, 0x6b, 0x18, 0x03, 0x20, 0x03, 0x28, 0x08, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x92, 0x01,
+ 0x02, 0x10, 0x10, 0x52, 0x0b, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x4d, 0x61, 0x73, 0x6b,
+ 0x12, 0x39, 0x0a, 0x14, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x6d, 0x61, 0x73, 0x6b,
+ 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07,
+ 0xfa, 0x42, 0x04, 0x2a, 0x02, 0x18, 0x07, 0x52, 0x12, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c,
+ 0x4d, 0x61, 0x73, 0x6b, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x12, 0x22, 0x0a, 0x08, 0x6e,
+ 0x62, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa,
+ 0x42, 0x04, 0x2a, 0x02, 0x18, 0x0f, 0x52, 0x07, 0x6e, 0x62, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4a,
+ 0x04, 0x08, 0x04, 0x10, 0x05, 0x1a, 0x92, 0x01, 0x0a, 0x0a, 0x4c, 0x69, 0x6e, 0x6b, 0x41, 0x44,
+ 0x52, 0x41, 0x6e, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f,
+ 0x6d, 0x61, 0x73, 0x6b, 0x5f, 0x61, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e,
+ 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x4d, 0x61, 0x73, 0x6b, 0x41, 0x63, 0x6b, 0x12, 0x2d,
+ 0x0a, 0x13, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65,
+ 0x78, 0x5f, 0x61, 0x63, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x64, 0x61, 0x74,
+ 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x41, 0x63, 0x6b, 0x12, 0x2b, 0x0a,
+ 0x12, 0x74, 0x78, 0x5f, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f,
+ 0x61, 0x63, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x74, 0x78, 0x50, 0x6f, 0x77,
+ 0x65, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x41, 0x63, 0x6b, 0x1a, 0x63, 0x0a, 0x0c, 0x44, 0x75,
+ 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x12, 0x53, 0x0a, 0x0e, 0x6d, 0x61,
+ 0x78, 0x5f, 0x64, 0x75, 0x74, 0x79, 0x5f, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
+ 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x44, 0x75,
+ 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10,
+ 0x01, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x44, 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x1a,
+ 0xf4, 0x01, 0x0a, 0x0f, 0x52, 0x78, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x65, 0x74, 0x75, 0x70,
+ 0x52, 0x65, 0x71, 0x12, 0x56, 0x0a, 0x13, 0x72, 0x78, 0x32, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f,
+ 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e,
+ 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
+ 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x42,
+ 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x10, 0x72, 0x78, 0x32, 0x44, 0x61,
+ 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x59, 0x0a, 0x14, 0x72,
+ 0x78, 0x31, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x6f, 0x66, 0x66,
+ 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
+ 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52,
+ 0x61, 0x74, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01,
+ 0x02, 0x10, 0x01, 0x52, 0x11, 0x72, 0x78, 0x31, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65,
+ 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x2e, 0x0a, 0x0d, 0x72, 0x78, 0x32, 0x5f, 0x66, 0x72,
+ 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x42, 0x09, 0xfa,
+ 0x42, 0x06, 0x32, 0x04, 0x28, 0xa0, 0x8d, 0x06, 0x52, 0x0c, 0x72, 0x78, 0x32, 0x46, 0x72, 0x65,
+ 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x1a, 0xab, 0x01, 0x0a, 0x0f, 0x52, 0x78, 0x50, 0x61, 0x72,
+ 0x61, 0x6d, 0x53, 0x65, 0x74, 0x75, 0x70, 0x41, 0x6e, 0x73, 0x12, 0x34, 0x0a, 0x17, 0x72, 0x78,
+ 0x32, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65,
+ 0x78, 0x5f, 0x61, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x72, 0x78, 0x32,
+ 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x41, 0x63, 0x6b,
+ 0x12, 0x36, 0x0a, 0x18, 0x72, 0x78, 0x31, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74,
+ 0x65, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x5f, 0x61, 0x63, 0x6b, 0x18, 0x02, 0x20, 0x01,
+ 0x28, 0x08, 0x52, 0x14, 0x72, 0x78, 0x31, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x4f,
+ 0x66, 0x66, 0x73, 0x65, 0x74, 0x41, 0x63, 0x6b, 0x12, 0x2a, 0x0a, 0x11, 0x72, 0x78, 0x32, 0x5f,
+ 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x61, 0x63, 0x6b, 0x18, 0x03, 0x20,
+ 0x01, 0x28, 0x08, 0x52, 0x0f, 0x72, 0x78, 0x32, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63,
+ 0x79, 0x41, 0x63, 0x6b, 0x1a, 0x5e, 0x0a, 0x0c, 0x44, 0x65, 0x76, 0x53, 0x74, 0x61, 0x74, 0x75,
+ 0x73, 0x41, 0x6e, 0x73, 0x12, 0x22, 0x0a, 0x07, 0x62, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x2a, 0x03, 0x18, 0xff, 0x01, 0x52,
+ 0x07, 0x62, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x12, 0x2a, 0x0a, 0x06, 0x6d, 0x61, 0x72, 0x67,
+ 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x42, 0x12, 0xfa, 0x42, 0x0f, 0x1a, 0x0d, 0x18,
+ 0x1f, 0x28, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x52, 0x06, 0x6d, 0x61,
+ 0x72, 0x67, 0x69, 0x6e, 0x1a, 0x99, 0x02, 0x0a, 0x0d, 0x4e, 0x65, 0x77, 0x43, 0x68, 0x61, 0x6e,
+ 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x12, 0x2d, 0x0a, 0x0d, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65,
+ 0x6c, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x08, 0xfa,
+ 0x42, 0x05, 0x2a, 0x03, 0x18, 0xff, 0x01, 0x52, 0x0c, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c,
+ 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x29, 0x0a, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e,
+ 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x42, 0x0b, 0xfa, 0x42, 0x08, 0x32, 0x06, 0x18,
+ 0x00, 0x28, 0xa0, 0x8d, 0x06, 0x52, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79,
+ 0x12, 0x56, 0x0a, 0x13, 0x6d, 0x69, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74,
+ 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e,
+ 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44,
+ 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x42, 0x08, 0xfa, 0x42,
+ 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x10, 0x6d, 0x69, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x52,
+ 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x56, 0x0a, 0x13, 0x6d, 0x61, 0x78, 0x5f,
+ 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18,
+ 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
+ 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49,
+ 0x6e, 0x64, 0x65, 0x78, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x10,
+ 0x6d, 0x61, 0x78, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78,
+ 0x1a, 0x58, 0x0a, 0x0d, 0x4e, 0x65, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x41, 0x6e,
+ 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x61,
+ 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65,
+ 0x6e, 0x63, 0x79, 0x41, 0x63, 0x6b, 0x12, 0x22, 0x0a, 0x0d, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72,
+ 0x61, 0x74, 0x65, 0x5f, 0x61, 0x63, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x64,
+ 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x41, 0x63, 0x6b, 0x1a, 0x66, 0x0a, 0x0c, 0x44, 0x4c,
+ 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x12, 0x2d, 0x0a, 0x0d, 0x63, 0x68,
+ 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x0d, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x2a, 0x03, 0x18, 0xff, 0x01, 0x52, 0x0c, 0x63, 0x68, 0x61,
+ 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x27, 0x0a, 0x09, 0x66, 0x72, 0x65,
+ 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x42, 0x09, 0xfa, 0x42,
+ 0x06, 0x32, 0x04, 0x28, 0xa0, 0x8d, 0x06, 0x52, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e,
+ 0x63, 0x79, 0x1a, 0x5f, 0x0a, 0x0c, 0x44, 0x4c, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x41,
+ 0x6e, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x6e,
+ 0x64, 0x65, 0x78, 0x5f, 0x61, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x63,
+ 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x41, 0x63, 0x6b, 0x12, 0x23,
+ 0x0a, 0x0d, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x61, 0x63, 0x6b, 0x18,
+ 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79,
+ 0x41, 0x63, 0x6b, 0x1a, 0x4b, 0x0a, 0x10, 0x52, 0x78, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x53,
+ 0x65, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x12, 0x37, 0x0a, 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
+ 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x78, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x42,
+ 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79,
+ 0x1a, 0xb9, 0x01, 0x0a, 0x0f, 0x54, 0x78, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x65, 0x74, 0x75,
+ 0x70, 0x52, 0x65, 0x71, 0x12, 0x4a, 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x65, 0x69, 0x72, 0x70,
+ 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74,
+ 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x65,
+ 0x76, 0x69, 0x63, 0x65, 0x45, 0x49, 0x52, 0x50, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02,
+ 0x10, 0x01, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x45, 0x69, 0x72, 0x70, 0x49, 0x6e, 0x64, 0x65, 0x78,
+ 0x12, 0x2a, 0x0a, 0x11, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x64, 0x77, 0x65, 0x6c, 0x6c,
+ 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x75, 0x70, 0x6c,
+ 0x69, 0x6e, 0x6b, 0x44, 0x77, 0x65, 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x13,
+ 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x64, 0x77, 0x65, 0x6c, 0x6c, 0x5f, 0x74,
+ 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x64, 0x6f, 0x77, 0x6e, 0x6c,
+ 0x69, 0x6e, 0x6b, 0x44, 0x77, 0x65, 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x1a, 0x50, 0x0a, 0x08,
+ 0x52, 0x65, 0x6b, 0x65, 0x79, 0x49, 0x6e, 0x64, 0x12, 0x44, 0x0a, 0x0d, 0x6d, 0x69, 0x6e, 0x6f,
+ 0x72, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32,
+ 0x15, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
+ 0x2e, 0x4d, 0x69, 0x6e, 0x6f, 0x72, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01,
+ 0x52, 0x0c, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x51,
+ 0x0a, 0x09, 0x52, 0x65, 0x6b, 0x65, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x12, 0x44, 0x0a, 0x0d, 0x6d,
+ 0x69, 0x6e, 0x6f, 0x72, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
+ 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x69, 0x6e, 0x6f, 0x72, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01,
+ 0x02, 0x10, 0x01, 0x52, 0x0c, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
+ 0x6e, 0x1a, 0xda, 0x01, 0x0a, 0x10, 0x41, 0x44, 0x52, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x65,
+ 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x12, 0x62, 0x0a, 0x16, 0x61, 0x64, 0x72, 0x5f, 0x61, 0x63,
+ 0x6b, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
+ 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x44, 0x52, 0x41, 0x63, 0x6b, 0x4c, 0x69,
+ 0x6d, 0x69, 0x74, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x42, 0x08, 0xfa, 0x42, 0x05,
+ 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x13, 0x61, 0x64, 0x72, 0x41, 0x63, 0x6b, 0x4c, 0x69, 0x6d,
+ 0x69, 0x74, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x62, 0x0a, 0x16, 0x61, 0x64,
+ 0x72, 0x5f, 0x61, 0x63, 0x6b, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x65, 0x78, 0x70, 0x6f,
+ 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e,
+ 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x44, 0x52, 0x41,
+ 0x63, 0x6b, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x42,
+ 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x13, 0x61, 0x64, 0x72, 0x41, 0x63,
+ 0x6b, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x1a, 0x49,
+ 0x0a, 0x0d, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x41, 0x6e, 0x73, 0x12,
+ 0x38, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
+ 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
+ 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x08, 0xfa, 0x42, 0x05, 0xb2, 0x01,
+ 0x02, 0x08, 0x01, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x1a, 0xb2, 0x02, 0x0a, 0x0e, 0x46, 0x6f,
+ 0x72, 0x63, 0x65, 0x52, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x4c, 0x0a, 0x0b,
+ 0x72, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x0e, 0x32, 0x21, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
+ 0x76, 0x33, 0x2e, 0x52, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+ 0x54, 0x79, 0x70, 0x65, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0a,
+ 0x72, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x4f, 0x0a, 0x0f, 0x64, 0x61,
+ 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20,
+ 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
+ 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64,
+ 0x65, 0x78, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0d, 0x64, 0x61,
+ 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x28, 0x0a, 0x0b, 0x6d,
+ 0x61, 0x78, 0x5f, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d,
+ 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, 0x18, 0x07, 0x52, 0x0a, 0x6d, 0x61, 0x78, 0x52, 0x65,
+ 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x57, 0x0a, 0x0f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x5f,
+ 0x65, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24,
+ 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
+ 0x52, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x45, 0x78, 0x70, 0x6f,
+ 0x6e, 0x65, 0x6e, 0x74, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0e,
+ 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x1a, 0xcc,
+ 0x01, 0x0a, 0x13, 0x52, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x65,
+ 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x12, 0x5b, 0x0a, 0x12, 0x6d, 0x61, 0x78, 0x5f, 0x63, 0x6f,
+ 0x75, 0x6e, 0x74, 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
+ 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x45,
+ 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10,
+ 0x01, 0x52, 0x10, 0x6d, 0x61, 0x78, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x45, 0x78, 0x70, 0x6f, 0x6e,
+ 0x65, 0x6e, 0x74, 0x12, 0x58, 0x0a, 0x11, 0x6d, 0x61, 0x78, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f,
+ 0x65, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22,
+ 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
+ 0x52, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65,
+ 0x6e, 0x74, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0f, 0x6d, 0x61,
+ 0x78, 0x54, 0x69, 0x6d, 0x65, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x1a, 0x48, 0x0a,
+ 0x13, 0x52, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x65, 0x74, 0x75,
+ 0x70, 0x41, 0x6e, 0x73, 0x12, 0x31, 0x0a, 0x15, 0x6d, 0x61, 0x78, 0x5f, 0x74, 0x69, 0x6d, 0x65,
+ 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x63, 0x6b, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x08, 0x52, 0x12, 0x6d, 0x61, 0x78, 0x54, 0x69, 0x6d, 0x65, 0x45, 0x78, 0x70, 0x6f,
+ 0x6e, 0x65, 0x6e, 0x74, 0x41, 0x63, 0x6b, 0x1a, 0x53, 0x0a, 0x0f, 0x50, 0x69, 0x6e, 0x67, 0x53,
+ 0x6c, 0x6f, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x12, 0x40, 0x0a, 0x06, 0x70, 0x65,
+ 0x72, 0x69, 0x6f, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x74, 0x74, 0x6e,
+ 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x50, 0x69, 0x6e, 0x67,
+ 0x53, 0x6c, 0x6f, 0x74, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82,
+ 0x01, 0x02, 0x10, 0x01, 0x52, 0x06, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x1a, 0x90, 0x01, 0x0a,
+ 0x12, 0x50, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c,
+ 0x52, 0x65, 0x71, 0x12, 0x29, 0x0a, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x42, 0x0b, 0xfa, 0x42, 0x08, 0x32, 0x06, 0x18, 0x00, 0x28,
+ 0xa0, 0x8d, 0x06, 0x52, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x4f,
+ 0x0a, 0x0f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65,
+ 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
+ 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74,
+ 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01,
+ 0x52, 0x0d, 0x64, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a,
+ 0x68, 0x0a, 0x12, 0x50, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x6e,
+ 0x65, 0x6c, 0x41, 0x6e, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e,
+ 0x63, 0x79, 0x5f, 0x61, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x66, 0x72,
+ 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x41, 0x63, 0x6b, 0x12, 0x2d, 0x0a, 0x13, 0x64, 0x61,
+ 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x61, 0x63,
+ 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x64, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74,
+ 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x41, 0x63, 0x6b, 0x1a, 0x61, 0x0a, 0x0f, 0x42, 0x65, 0x61,
+ 0x63, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x41, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x05,
+ 0x64, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x09, 0xfa, 0x42, 0x06,
+ 0x2a, 0x04, 0x18, 0xff, 0xff, 0x03, 0x52, 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x2d, 0x0a,
+ 0x0d, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x0d, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x2a, 0x03, 0x18, 0xff, 0x01, 0x52, 0x0c,
+ 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x3a, 0x0a, 0x0d,
+ 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x46, 0x72, 0x65, 0x71, 0x52, 0x65, 0x71, 0x12, 0x29, 0x0a,
+ 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04,
+ 0x42, 0x0b, 0xfa, 0x42, 0x08, 0x32, 0x06, 0x18, 0x00, 0x28, 0xa0, 0x8d, 0x06, 0x52, 0x09, 0x66,
+ 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x1a, 0x34, 0x0a, 0x0d, 0x42, 0x65, 0x61, 0x63,
+ 0x6f, 0x6e, 0x46, 0x72, 0x65, 0x71, 0x41, 0x6e, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x72, 0x65,
+ 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x61, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08,
+ 0x52, 0x0c, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x41, 0x63, 0x6b, 0x1a, 0x46,
+ 0x0a, 0x0d, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x64, 0x12,
+ 0x35, 0x0a, 0x05, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15,
+ 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
+ 0x43, 0x6c, 0x61, 0x73, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52,
+ 0x05, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x1a, 0x47, 0x0a, 0x0e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65,
+ 0x4d, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x12, 0x35, 0x0a, 0x05, 0x63, 0x6c, 0x61, 0x73,
+ 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
+ 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x42, 0x08,
+ 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x05, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x1a,
+ 0xde, 0x02, 0x0a, 0x0c, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x52, 0x65, 0x71,
+ 0x12, 0x5b, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d,
- 0x61, 0x6e, 0x64, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x49, 0x6e,
- 0x64, 0x48, 0x00, 0x52, 0x0d, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x49,
- 0x6e, 0x64, 0x12, 0x55, 0x0a, 0x10, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6d, 0x6f, 0x64,
- 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x18, 0x20, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x74,
- 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41,
- 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d,
- 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x48, 0x00, 0x52, 0x0e, 0x64, 0x65, 0x76, 0x69, 0x63,
- 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x1a, 0x52, 0x0a, 0x08, 0x52, 0x65, 0x73,
- 0x65, 0x74, 0x49, 0x6e, 0x64, 0x12, 0x46, 0x0a, 0x0d, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x5f, 0x76,
- 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x74,
- 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x69,
- 0x6e, 0x6f, 0x72, 0x42, 0x0a, 0xfa, 0x42, 0x07, 0x82, 0x01, 0x04, 0x10, 0x01, 0x18, 0x01, 0x52,
- 0x0c, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x53, 0x0a,
- 0x09, 0x52, 0x65, 0x73, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x12, 0x46, 0x0a, 0x0d, 0x6d, 0x69,
- 0x6e, 0x6f, 0x72, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28,
- 0x0e, 0x32, 0x15, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
- 0x76, 0x33, 0x2e, 0x4d, 0x69, 0x6e, 0x6f, 0x72, 0x42, 0x0a, 0xfa, 0x42, 0x07, 0x82, 0x01, 0x04,
- 0x10, 0x01, 0x18, 0x01, 0x52, 0x0c, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69,
- 0x6f, 0x6e, 0x1a, 0x5f, 0x0a, 0x0c, 0x4c, 0x69, 0x6e, 0x6b, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x41,
- 0x6e, 0x73, 0x12, 0x20, 0x0a, 0x06, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x0d, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x2a, 0x03, 0x18, 0xfe, 0x01, 0x52, 0x06, 0x6d, 0x61,
- 0x72, 0x67, 0x69, 0x6e, 0x12, 0x2d, 0x0a, 0x0d, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f,
- 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x08, 0xfa, 0x42, 0x05,
- 0x2a, 0x03, 0x18, 0xff, 0x01, 0x52, 0x0c, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x43, 0x6f,
- 0x75, 0x6e, 0x74, 0x1a, 0x9e, 0x02, 0x0a, 0x0a, 0x4c, 0x69, 0x6e, 0x6b, 0x41, 0x44, 0x52, 0x52,
- 0x65, 0x71, 0x12, 0x4f, 0x0a, 0x0f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f,
- 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74,
- 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74,
- 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82,
- 0x01, 0x02, 0x10, 0x01, 0x52, 0x0d, 0x64, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e,
- 0x64, 0x65, 0x78, 0x12, 0x2d, 0x0a, 0x0e, 0x74, 0x78, 0x5f, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x5f,
- 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04,
- 0x2a, 0x02, 0x18, 0x0f, 0x52, 0x0c, 0x74, 0x78, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x49, 0x6e, 0x64,
- 0x65, 0x78, 0x12, 0x2b, 0x0a, 0x0c, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x6d, 0x61,
- 0x73, 0x6b, 0x18, 0x03, 0x20, 0x03, 0x28, 0x08, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x92, 0x01, 0x02,
- 0x10, 0x10, 0x52, 0x0b, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x4d, 0x61, 0x73, 0x6b, 0x12,
- 0x39, 0x0a, 0x14, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x5f,
- 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa,
- 0x42, 0x04, 0x2a, 0x02, 0x18, 0x07, 0x52, 0x12, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x4d,
- 0x61, 0x73, 0x6b, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x12, 0x22, 0x0a, 0x08, 0x6e, 0x62,
- 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42,
- 0x04, 0x2a, 0x02, 0x18, 0x0f, 0x52, 0x07, 0x6e, 0x62, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4a, 0x04,
- 0x08, 0x04, 0x10, 0x05, 0x1a, 0x92, 0x01, 0x0a, 0x0a, 0x4c, 0x69, 0x6e, 0x6b, 0x41, 0x44, 0x52,
- 0x41, 0x6e, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x6d,
- 0x61, 0x73, 0x6b, 0x5f, 0x61, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x63,
- 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x4d, 0x61, 0x73, 0x6b, 0x41, 0x63, 0x6b, 0x12, 0x2d, 0x0a,
- 0x13, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78,
- 0x5f, 0x61, 0x63, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x64, 0x61, 0x74, 0x61,
- 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x41, 0x63, 0x6b, 0x12, 0x2b, 0x0a, 0x12,
- 0x74, 0x78, 0x5f, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x61,
- 0x63, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x74, 0x78, 0x50, 0x6f, 0x77, 0x65,
- 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x41, 0x63, 0x6b, 0x1a, 0x63, 0x0a, 0x0c, 0x44, 0x75, 0x74,
- 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x12, 0x53, 0x0a, 0x0e, 0x6d, 0x61, 0x78,
- 0x5f, 0x64, 0x75, 0x74, 0x79, 0x5f, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x52, 0x65, 0x71,
+ 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d,
+ 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0xf0, 0x01,
+ 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12,
+ 0x49, 0x0a, 0x0e, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65,
+ 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
+ 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x53, 0x65,
+ 0x63, 0x6f, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x0d, 0x73, 0x65, 0x63,
+ 0x6f, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x3c, 0x0a, 0x15, 0x64, 0x65,
+ 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x6e,
+ 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x2a, 0x03,
+ 0x18, 0xff, 0x01, 0x52, 0x13, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x43, 0x68, 0x61, 0x6e,
+ 0x6e, 0x65, 0x6c, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x56, 0x0a, 0x0f, 0x63, 0x61, 0x64, 0x5f,
+ 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28,
0x0e, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
- 0x76, 0x33, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x44, 0x75, 0x74,
- 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01,
- 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x44, 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x1a, 0xf4,
- 0x01, 0x0a, 0x0f, 0x52, 0x78, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x65, 0x74, 0x75, 0x70, 0x52,
- 0x65, 0x71, 0x12, 0x56, 0x0a, 0x13, 0x72, 0x78, 0x32, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72,
- 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32,
- 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
- 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x42, 0x08,
- 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x10, 0x72, 0x78, 0x32, 0x44, 0x61, 0x74,
- 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x59, 0x0a, 0x14, 0x72, 0x78,
- 0x31, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x6f, 0x66, 0x66, 0x73,
- 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c,
- 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61,
- 0x74, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02,
- 0x10, 0x01, 0x52, 0x11, 0x72, 0x78, 0x31, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x4f,
- 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x2e, 0x0a, 0x0d, 0x72, 0x78, 0x32, 0x5f, 0x66, 0x72, 0x65,
- 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x42, 0x09, 0xfa, 0x42,
- 0x06, 0x32, 0x04, 0x28, 0xa0, 0x8d, 0x06, 0x52, 0x0c, 0x72, 0x78, 0x32, 0x46, 0x72, 0x65, 0x71,
- 0x75, 0x65, 0x6e, 0x63, 0x79, 0x1a, 0xab, 0x01, 0x0a, 0x0f, 0x52, 0x78, 0x50, 0x61, 0x72, 0x61,
- 0x6d, 0x53, 0x65, 0x74, 0x75, 0x70, 0x41, 0x6e, 0x73, 0x12, 0x34, 0x0a, 0x17, 0x72, 0x78, 0x32,
- 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78,
- 0x5f, 0x61, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x72, 0x78, 0x32, 0x44,
+ 0x76, 0x33, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x43, 0x41, 0x44, 0x50, 0x65, 0x72, 0x69, 0x6f,
+ 0x64, 0x69, 0x63, 0x69, 0x74, 0x79, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01,
+ 0x52, 0x0e, 0x63, 0x61, 0x64, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63, 0x69, 0x74, 0x79,
+ 0x1a, 0x80, 0x03, 0x0a, 0x0c, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x41, 0x6e,
+ 0x73, 0x12, 0x3f, 0x0a, 0x1c, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x5f, 0x63, 0x68, 0x61, 0x6e,
+ 0x6e, 0x65, 0x6c, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x61, 0x63,
+ 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x43,
+ 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x41,
+ 0x63, 0x6b, 0x12, 0x40, 0x0a, 0x1d, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x5f, 0x63, 0x68, 0x61,
+ 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x61, 0x63, 0x6b, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x5f,
+ 0x61, 0x63, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x73, 0x65, 0x63, 0x6f, 0x6e,
+ 0x64, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x41, 0x63, 0x6b, 0x4f, 0x66, 0x66, 0x73, 0x65,
+ 0x74, 0x41, 0x63, 0x6b, 0x12, 0x49, 0x0a, 0x22, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x5f, 0x63,
+ 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65,
+ 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x61, 0x63, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08,
+ 0x52, 0x1d, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x44,
0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x41, 0x63, 0x6b, 0x12,
- 0x36, 0x0a, 0x18, 0x72, 0x78, 0x31, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65,
- 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x5f, 0x61, 0x63, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28,
- 0x08, 0x52, 0x14, 0x72, 0x78, 0x31, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x4f, 0x66,
- 0x66, 0x73, 0x65, 0x74, 0x41, 0x63, 0x6b, 0x12, 0x2a, 0x0a, 0x11, 0x72, 0x78, 0x32, 0x5f, 0x66,
- 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x61, 0x63, 0x6b, 0x18, 0x03, 0x20, 0x01,
- 0x28, 0x08, 0x52, 0x0f, 0x72, 0x78, 0x32, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79,
- 0x41, 0x63, 0x6b, 0x1a, 0x5e, 0x0a, 0x0c, 0x44, 0x65, 0x76, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
- 0x41, 0x6e, 0x73, 0x12, 0x22, 0x0a, 0x07, 0x62, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x18, 0x01,
- 0x20, 0x01, 0x28, 0x0d, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x2a, 0x03, 0x18, 0xff, 0x01, 0x52, 0x07,
- 0x62, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x12, 0x2a, 0x0a, 0x06, 0x6d, 0x61, 0x72, 0x67, 0x69,
- 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x42, 0x12, 0xfa, 0x42, 0x0f, 0x1a, 0x0d, 0x18, 0x1f,
- 0x28, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x52, 0x06, 0x6d, 0x61, 0x72,
- 0x67, 0x69, 0x6e, 0x1a, 0x99, 0x02, 0x0a, 0x0d, 0x4e, 0x65, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x6e,
- 0x65, 0x6c, 0x52, 0x65, 0x71, 0x12, 0x2d, 0x0a, 0x0d, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c,
- 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x08, 0xfa, 0x42,
- 0x05, 0x2a, 0x03, 0x18, 0xff, 0x01, 0x52, 0x0c, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x49,
- 0x6e, 0x64, 0x65, 0x78, 0x12, 0x29, 0x0a, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63,
- 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x42, 0x0b, 0xfa, 0x42, 0x08, 0x32, 0x06, 0x18, 0x00,
- 0x28, 0xa0, 0x8d, 0x06, 0x52, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12,
- 0x56, 0x0a, 0x13, 0x6d, 0x69, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65,
- 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74,
- 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61,
- 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x42, 0x08, 0xfa, 0x42, 0x05,
- 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x10, 0x6d, 0x69, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61,
- 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x56, 0x0a, 0x13, 0x6d, 0x61, 0x78, 0x5f, 0x64,
- 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x04,
- 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
- 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e,
- 0x64, 0x65, 0x78, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x10, 0x6d,
- 0x61, 0x78, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a,
- 0x58, 0x0a, 0x0d, 0x4e, 0x65, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x41, 0x6e, 0x73,
- 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x61, 0x63,
- 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e,
- 0x63, 0x79, 0x41, 0x63, 0x6b, 0x12, 0x22, 0x0a, 0x0d, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61,
- 0x74, 0x65, 0x5f, 0x61, 0x63, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x64, 0x61,
- 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x41, 0x63, 0x6b, 0x1a, 0x66, 0x0a, 0x0c, 0x44, 0x4c, 0x43,
- 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x12, 0x2d, 0x0a, 0x0d, 0x63, 0x68, 0x61,
- 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d,
- 0x42, 0x08, 0xfa, 0x42, 0x05, 0x2a, 0x03, 0x18, 0xff, 0x01, 0x52, 0x0c, 0x63, 0x68, 0x61, 0x6e,
- 0x6e, 0x65, 0x6c, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x27, 0x0a, 0x09, 0x66, 0x72, 0x65, 0x71,
- 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x42, 0x09, 0xfa, 0x42, 0x06,
- 0x32, 0x04, 0x28, 0xa0, 0x8d, 0x06, 0x52, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63,
- 0x79, 0x1a, 0x5f, 0x0a, 0x0c, 0x44, 0x4c, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x41, 0x6e,
- 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x6e, 0x64,
- 0x65, 0x78, 0x5f, 0x61, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x63, 0x68,
- 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x41, 0x63, 0x6b, 0x12, 0x23, 0x0a,
- 0x0d, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x61, 0x63, 0x6b, 0x18, 0x02,
- 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x41,
- 0x63, 0x6b, 0x1a, 0x4b, 0x0a, 0x10, 0x52, 0x78, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x65,
- 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x12, 0x37, 0x0a, 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x18,
- 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
- 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x78, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x42, 0x08,
- 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x1a,
- 0xb9, 0x01, 0x0a, 0x0f, 0x54, 0x78, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x65, 0x74, 0x75, 0x70,
- 0x52, 0x65, 0x71, 0x12, 0x4a, 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x65, 0x69, 0x72, 0x70, 0x5f,
- 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x74,
- 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x65, 0x76,
- 0x69, 0x63, 0x65, 0x45, 0x49, 0x52, 0x50, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10,
- 0x01, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x45, 0x69, 0x72, 0x70, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12,
- 0x2a, 0x0a, 0x11, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x64, 0x77, 0x65, 0x6c, 0x6c, 0x5f,
- 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x75, 0x70, 0x6c, 0x69,
- 0x6e, 0x6b, 0x44, 0x77, 0x65, 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x64,
- 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x64, 0x77, 0x65, 0x6c, 0x6c, 0x5f, 0x74, 0x69,
- 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69,
- 0x6e, 0x6b, 0x44, 0x77, 0x65, 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x1a, 0x50, 0x0a, 0x08, 0x52,
- 0x65, 0x6b, 0x65, 0x79, 0x49, 0x6e, 0x64, 0x12, 0x44, 0x0a, 0x0d, 0x6d, 0x69, 0x6e, 0x6f, 0x72,
- 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15,
+ 0x37, 0x0a, 0x18, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65,
+ 0x6c, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x61, 0x63, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28,
+ 0x08, 0x52, 0x15, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c,
+ 0x49, 0x6e, 0x64, 0x65, 0x78, 0x41, 0x63, 0x6b, 0x12, 0x39, 0x0a, 0x19, 0x64, 0x65, 0x66, 0x61,
+ 0x75, 0x6c, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x6e, 0x64, 0x65,
+ 0x78, 0x5f, 0x61, 0x63, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x64, 0x65, 0x66,
+ 0x61, 0x75, 0x6c, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x6e, 0x64, 0x65, 0x78,
+ 0x41, 0x63, 0x6b, 0x12, 0x2e, 0x0a, 0x13, 0x63, 0x61, 0x64, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f,
+ 0x64, 0x69, 0x63, 0x69, 0x74, 0x79, 0x5f, 0x61, 0x63, 0x6b, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08,
+ 0x52, 0x11, 0x63, 0x61, 0x64, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63, 0x69, 0x74, 0x79,
+ 0x41, 0x63, 0x6b, 0x1a, 0xce, 0x04, 0x0a, 0x15, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x45, 0x6e, 0x64,
+ 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x52, 0x65, 0x71, 0x12, 0x64, 0x0a,
+ 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
+ 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64,
+ 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43,
+ 0x6f, 0x6e, 0x66, 0x52, 0x65, 0x71, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x1a, 0xce, 0x03, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x42, 0x0a, 0x06, 0x61, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
+ 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x45, 0x6e, 0x64, 0x44,
+ 0x65, 0x76, 0x69, 0x63, 0x65, 0x41, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x4d, 0x6f, 0x64, 0x65, 0x48,
+ 0x00, 0x52, 0x06, 0x61, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x12, 0x45, 0x0a, 0x07, 0x64, 0x79, 0x6e,
+ 0x61, 0x6d, 0x69, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x74, 0x74, 0x6e,
+ 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65, 0x6c, 0x61,
+ 0x79, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69,
+ 0x63, 0x4d, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x07, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63,
+ 0x12, 0x62, 0x0a, 0x15, 0x65, 0x6e, 0x64, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x63,
+ 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x2c, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
+ 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43,
+ 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52,
+ 0x13, 0x65, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
+ 0x6c, 0x6c, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x07, 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x18,
+ 0x04, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, 0x18, 0x3f, 0x52, 0x07,
+ 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x12, 0x49, 0x0a, 0x0e, 0x73, 0x65, 0x63, 0x6f, 0x6e,
+ 0x64, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x22, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
+ 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e,
+ 0x6e, 0x65, 0x6c, 0x52, 0x0d, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x6e,
+ 0x65, 0x6c, 0x12, 0x53, 0x0a, 0x11, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x5f, 0x64, 0x65,
+ 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x42, 0x27, 0xfa,
+ 0x42, 0x24, 0x72, 0x22, 0x18, 0x24, 0x32, 0x1e, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39,
+ 0x5d, 0x28, 0x3f, 0x3a, 0x5b, 0x2d, 0x5d, 0x3f, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d,
+ 0x29, 0x7b, 0x32, 0x2c, 0x7d, 0x24, 0x52, 0x0f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x44,
+ 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x42, 0x0b, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12,
+ 0x03, 0xf8, 0x42, 0x01, 0x1a, 0xa2, 0x02, 0x0a, 0x15, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x45, 0x6e,
+ 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x41, 0x6e, 0x73, 0x12, 0x3f,
+ 0x0a, 0x1c, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c,
+ 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x61, 0x63, 0x6b, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e,
+ 0x6e, 0x65, 0x6c, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x41, 0x63, 0x6b, 0x12,
+ 0x49, 0x0a, 0x22, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65,
+ 0x6c, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65,
+ 0x78, 0x5f, 0x61, 0x63, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1d, 0x73, 0x65, 0x63,
+ 0x6f, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61,
+ 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x41, 0x63, 0x6b, 0x12, 0x37, 0x0a, 0x18, 0x73, 0x65,
+ 0x63, 0x6f, 0x6e, 0x64, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x6e, 0x64,
+ 0x65, 0x78, 0x5f, 0x61, 0x63, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x73, 0x65,
+ 0x63, 0x6f, 0x6e, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x6e, 0x64, 0x65, 0x78,
+ 0x41, 0x63, 0x6b, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x5f, 0x61,
+ 0x63, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66,
+ 0x66, 0x41, 0x63, 0x6b, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x1d, 0x73, 0x65, 0x63, 0x6f,
+ 0x6e, 0x64, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x61, 0x63, 0x6b, 0x5f, 0x6f,
+ 0x66, 0x66, 0x73, 0x65, 0x74, 0x5f, 0x61, 0x63, 0x6b, 0x1a, 0x9b, 0x08, 0x0a, 0x18, 0x52, 0x65,
+ 0x6c, 0x61, 0x79, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x4c,
+ 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x12, 0x26, 0x0a, 0x0a, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x69,
+ 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a,
+ 0x02, 0x18, 0x0f, 0x52, 0x09, 0x72, 0x75, 0x6c, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x4f,
+ 0x0a, 0x0e, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
+ 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x55, 0x70, 0x6c,
+ 0x69, 0x6e, 0x6b, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73,
+ 0x52, 0x0d, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x12,
+ 0xed, 0x02, 0x0a, 0x08, 0x64, 0x65, 0x76, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x03, 0x20, 0x01,
+ 0x28, 0x0c, 0x42, 0xd1, 0x02, 0x92, 0x41, 0x19, 0x4a, 0x0a, 0x22, 0x32, 0x36, 0x30, 0x30, 0x41,
+ 0x42, 0x43, 0x44, 0x22, 0x9a, 0x02, 0x01, 0x07, 0xa2, 0x02, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e,
+ 0x67, 0xfa, 0x42, 0x06, 0x7a, 0x04, 0x68, 0x04, 0x70, 0x01, 0xea, 0xaa, 0x19, 0x82, 0x01, 0x0a,
+ 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65,
+ 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74,
+ 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73,
+ 0x2e, 0x4d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x48, 0x45, 0x58, 0x42, 0x79, 0x74, 0x65, 0x73,
+ 0x12, 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e,
+ 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73,
+ 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x79, 0x70, 0x65,
+ 0x73, 0x2e, 0x55, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x34, 0x42, 0x79, 0x74, 0x65,
+ 0x73, 0xf2, 0xaa, 0x19, 0xa0, 0x01, 0x1a, 0x4e, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68,
+ 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72,
+ 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x63, 0x6d,
+ 0x64, 0x2f, 0x74, 0x74, 0x6e, 0x2d, 0x6c, 0x77, 0x2d, 0x63, 0x6c, 0x69, 0x2f, 0x63, 0x75, 0x73,
+ 0x74, 0x6f, 0x6d, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x2e, 0x4e, 0x65, 0x77, 0x34, 0x42, 0x79, 0x74,
+ 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x22, 0x4e, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68,
+ 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72,
+ 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x63, 0x6d,
+ 0x64, 0x2f, 0x74, 0x74, 0x6e, 0x2d, 0x6c, 0x77, 0x2d, 0x63, 0x6c, 0x69, 0x2f, 0x63, 0x75, 0x73,
+ 0x74, 0x6f, 0x6d, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, 0x61, 0x63,
+ 0x74, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x07, 0x64, 0x65, 0x76, 0x41, 0x64, 0x64, 0x72, 0x12,
+ 0x16, 0x0a, 0x07, 0x77, 0x5f, 0x66, 0x5f, 0x63, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d,
+ 0x52, 0x05, 0x77, 0x46, 0x43, 0x6e, 0x74, 0x12, 0x91, 0x03, 0x0a, 0x0e, 0x72, 0x6f, 0x6f, 0x74,
+ 0x5f, 0x77, 0x6f, 0x72, 0x5f, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c,
+ 0x42, 0xeb, 0x02, 0x92, 0x41, 0x31, 0x4a, 0x22, 0x22, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
+ 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
+ 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x22, 0x9a, 0x02, 0x01, 0x07, 0xa2, 0x02,
+ 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0xfa, 0x42, 0x06, 0x7a, 0x04, 0x68, 0x10, 0x70, 0x01,
+ 0xea, 0xaa, 0x19, 0x83, 0x01, 0x0a, 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69,
+ 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61,
+ 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67,
+ 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x48, 0x45,
+ 0x58, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x40, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68,
+ 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72,
+ 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b,
+ 0x67, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x55, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, 0x61,
+ 0x6c, 0x31, 0x36, 0x42, 0x79, 0x74, 0x65, 0x73, 0xf2, 0xaa, 0x19, 0xa1, 0x01, 0x1a, 0x4f, 0x67,
+ 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77,
+ 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63,
+ 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x74, 0x74, 0x6e, 0x2d, 0x6c, 0x77, 0x2d,
+ 0x63, 0x6c, 0x69, 0x2f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x2e,
+ 0x4e, 0x65, 0x77, 0x31, 0x36, 0x42, 0x79, 0x74, 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x22, 0x4e,
+ 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74,
+ 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61,
+ 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x74, 0x74, 0x6e, 0x2d, 0x6c, 0x77,
+ 0x2d, 0x63, 0x6c, 0x69, 0x2f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x66, 0x6c, 0x61, 0x67, 0x73,
+ 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, 0x61, 0x63, 0x74, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x0b,
+ 0x72, 0x6f, 0x6f, 0x74, 0x57, 0x6f, 0x72, 0x53, 0x4b, 0x65, 0x79, 0x12, 0x44, 0x0a, 0x09, 0x64,
+ 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x42, 0x27,
+ 0xfa, 0x42, 0x24, 0x72, 0x22, 0x18, 0x24, 0x32, 0x1e, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d,
+ 0x39, 0x5d, 0x28, 0x3f, 0x3a, 0x5b, 0x2d, 0x5d, 0x3f, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39,
+ 0x5d, 0x29, 0x7b, 0x32, 0x2c, 0x7d, 0x24, 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49,
+ 0x64, 0x12, 0x24, 0x0a, 0x0e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x65, 0x79,
+ 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x73, 0x65, 0x73, 0x73, 0x69,
+ 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x1a, 0x1a, 0x0a, 0x18, 0x52, 0x65, 0x6c, 0x61, 0x79,
+ 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x4c, 0x69, 0x73, 0x74,
+ 0x41, 0x6e, 0x73, 0x1a, 0x83, 0x01, 0x0a, 0x16, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x43, 0x74, 0x72,
+ 0x6c, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x12, 0x26,
+ 0x0a, 0x0a, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, 0x18, 0x0f, 0x52, 0x09, 0x72, 0x75, 0x6c,
+ 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x41, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x29, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
+ 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x43, 0x74, 0x72,
+ 0x6c, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f,
+ 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x56, 0x0a, 0x16, 0x52, 0x65, 0x6c,
+ 0x61, 0x79, 0x43, 0x74, 0x72, 0x6c, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x4c, 0x69, 0x73, 0x74,
+ 0x41, 0x6e, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65,
+ 0x78, 0x5f, 0x61, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x72, 0x75, 0x6c,
+ 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x41, 0x63, 0x6b, 0x12, 0x16, 0x0a, 0x07, 0x77, 0x5f, 0x66,
+ 0x5f, 0x63, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x77, 0x46, 0x43, 0x6e,
+ 0x74, 0x1a, 0xb1, 0x03, 0x0a, 0x19, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+ 0x67, 0x75, 0x72, 0x65, 0x46, 0x77, 0x64, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x12,
+ 0x56, 0x0a, 0x13, 0x72, 0x65, 0x73, 0x65, 0x74, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x63,
+ 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x74,
+ 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65,
+ 0x6c, 0x61, 0x79, 0x52, 0x65, 0x73, 0x65, 0x74, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x43, 0x6f, 0x75,
+ 0x6e, 0x74, 0x65, 0x72, 0x52, 0x11, 0x72, 0x65, 0x73, 0x65, 0x74, 0x4c, 0x69, 0x6d, 0x69, 0x74,
+ 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x52, 0x0a, 0x13, 0x6a, 0x6f, 0x69, 0x6e, 0x5f,
+ 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
+ 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x46, 0x6f, 0x72, 0x77, 0x61,
+ 0x72, 0x64, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x11, 0x6a, 0x6f, 0x69, 0x6e, 0x52, 0x65,
+ 0x71, 0x75, 0x65, 0x73, 0x74, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x47, 0x0a, 0x0d, 0x6e,
+ 0x6f, 0x74, 0x69, 0x66, 0x79, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
+ 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64,
+ 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x0c, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4c, 0x69,
+ 0x6d, 0x69, 0x74, 0x73, 0x12, 0x54, 0x0a, 0x14, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x75,
+ 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
+ 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64,
+ 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x12, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x55, 0x70,
+ 0x6c, 0x69, 0x6e, 0x6b, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x49, 0x0a, 0x0e, 0x6f, 0x76,
+ 0x65, 0x72, 0x61, 0x6c, 0x6c, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x05, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
+ 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64,
+ 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x0d, 0x6f, 0x76, 0x65, 0x72, 0x61, 0x6c, 0x6c, 0x4c,
+ 0x69, 0x6d, 0x69, 0x74, 0x73, 0x1a, 0x1b, 0x0a, 0x19, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x43, 0x6f,
+ 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x46, 0x77, 0x64, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x41,
+ 0x6e, 0x73, 0x1a, 0xe3, 0x03, 0x0a, 0x1a, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x4e, 0x6f, 0x74, 0x69,
+ 0x66, 0x79, 0x4e, 0x65, 0x77, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65,
+ 0x71, 0x12, 0xed, 0x02, 0x0a, 0x08, 0x64, 0x65, 0x76, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x0c, 0x42, 0xd1, 0x02, 0x92, 0x41, 0x19, 0x4a, 0x0a, 0x22, 0x32, 0x36, 0x30,
+ 0x30, 0x41, 0x42, 0x43, 0x44, 0x22, 0x9a, 0x02, 0x01, 0x07, 0xa2, 0x02, 0x06, 0x73, 0x74, 0x72,
+ 0x69, 0x6e, 0x67, 0xfa, 0x42, 0x06, 0x7a, 0x04, 0x68, 0x04, 0x70, 0x01, 0xea, 0xaa, 0x19, 0x82,
+ 0x01, 0x0a, 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e,
+ 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d,
+ 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x79, 0x70,
+ 0x65, 0x73, 0x2e, 0x4d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x48, 0x45, 0x58, 0x42, 0x79, 0x74,
+ 0x65, 0x73, 0x12, 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73,
+ 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
+ 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x79,
+ 0x70, 0x65, 0x73, 0x2e, 0x55, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x34, 0x42, 0x79,
+ 0x74, 0x65, 0x73, 0xf2, 0xaa, 0x19, 0xa0, 0x01, 0x1a, 0x4e, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65,
+ 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c,
+ 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f,
+ 0x63, 0x6d, 0x64, 0x2f, 0x74, 0x74, 0x6e, 0x2d, 0x6c, 0x77, 0x2d, 0x63, 0x6c, 0x69, 0x2f, 0x63,
+ 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x2e, 0x4e, 0x65, 0x77, 0x34, 0x42,
+ 0x79, 0x74, 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x22, 0x4e, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65,
+ 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c,
+ 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f,
+ 0x63, 0x6d, 0x64, 0x2f, 0x74, 0x74, 0x6e, 0x2d, 0x6c, 0x77, 0x2d, 0x63, 0x6c, 0x69, 0x2f, 0x63,
+ 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78,
+ 0x61, 0x63, 0x74, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x07, 0x64, 0x65, 0x76, 0x41, 0x64, 0x64,
+ 0x72, 0x12, 0x24, 0x0a, 0x03, 0x73, 0x6e, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x42, 0x12,
+ 0xfa, 0x42, 0x0f, 0x1a, 0x0d, 0x18, 0x0b, 0x28, 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0x01, 0x52, 0x03, 0x73, 0x6e, 0x72, 0x12, 0x2f, 0x0a, 0x04, 0x72, 0x73, 0x73, 0x69, 0x18,
+ 0x03, 0x20, 0x01, 0x28, 0x05, 0x42, 0x1b, 0xfa, 0x42, 0x18, 0x1a, 0x16, 0x18, 0xf1, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x28, 0xf2, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0x01, 0x52, 0x04, 0x72, 0x73, 0x73, 0x69, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c,
+ 0x6f, 0x61, 0x64, 0x4a, 0x04, 0x08, 0x25, 0x10, 0x26, 0x4a, 0x04, 0x08, 0x26, 0x10, 0x27, 0x52,
+ 0x15, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x5f, 0x6c, 0x69,
+ 0x73, 0x74, 0x5f, 0x72, 0x65, 0x71, 0x52, 0x15, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x66, 0x69,
+ 0x6c, 0x74, 0x65, 0x72, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x61, 0x6e, 0x73, 0x22, 0x45, 0x0a,
+ 0x0b, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x12, 0x36, 0x0a, 0x08,
+ 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a,
0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
- 0x4d, 0x69, 0x6e, 0x6f, 0x72, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52,
- 0x0c, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x51, 0x0a,
- 0x09, 0x52, 0x65, 0x6b, 0x65, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x12, 0x44, 0x0a, 0x0d, 0x6d, 0x69,
- 0x6e, 0x6f, 0x72, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28,
- 0x0e, 0x32, 0x15, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
- 0x76, 0x33, 0x2e, 0x4d, 0x69, 0x6e, 0x6f, 0x72, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02,
- 0x10, 0x01, 0x52, 0x0c, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
- 0x1a, 0xda, 0x01, 0x0a, 0x10, 0x41, 0x44, 0x52, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x65, 0x74,
- 0x75, 0x70, 0x52, 0x65, 0x71, 0x12, 0x62, 0x0a, 0x16, 0x61, 0x64, 0x72, 0x5f, 0x61, 0x63, 0x6b,
- 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18,
- 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
- 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x44, 0x52, 0x41, 0x63, 0x6b, 0x4c, 0x69, 0x6d,
- 0x69, 0x74, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82,
- 0x01, 0x02, 0x10, 0x01, 0x52, 0x13, 0x61, 0x64, 0x72, 0x41, 0x63, 0x6b, 0x4c, 0x69, 0x6d, 0x69,
- 0x74, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x62, 0x0a, 0x16, 0x61, 0x64, 0x72,
- 0x5f, 0x61, 0x63, 0x6b, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x6e,
- 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
- 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x44, 0x52, 0x41, 0x63,
- 0x6b, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x42, 0x08,
- 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x13, 0x61, 0x64, 0x72, 0x41, 0x63, 0x6b,
- 0x44, 0x65, 0x6c, 0x61, 0x79, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x1a, 0x49, 0x0a,
- 0x0d, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x41, 0x6e, 0x73, 0x12, 0x38,
- 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67,
- 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54,
- 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x08, 0xfa, 0x42, 0x05, 0xb2, 0x01, 0x02,
- 0x08, 0x01, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x1a, 0xb2, 0x02, 0x0a, 0x0e, 0x46, 0x6f, 0x72,
- 0x63, 0x65, 0x52, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x4c, 0x0a, 0x0b, 0x72,
- 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e,
- 0x32, 0x21, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
- 0x33, 0x2e, 0x52, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54,
- 0x79, 0x70, 0x65, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x72,
- 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x4f, 0x0a, 0x0f, 0x64, 0x61, 0x74,
- 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01,
- 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
- 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65,
- 0x78, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0d, 0x64, 0x61, 0x74,
- 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x28, 0x0a, 0x0b, 0x6d, 0x61,
- 0x78, 0x5f, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x42,
- 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, 0x18, 0x07, 0x52, 0x0a, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x74,
- 0x72, 0x69, 0x65, 0x73, 0x12, 0x57, 0x0a, 0x0f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x5f, 0x65,
- 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e,
- 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x52,
- 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x45, 0x78, 0x70, 0x6f, 0x6e,
- 0x65, 0x6e, 0x74, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0e, 0x70,
- 0x65, 0x72, 0x69, 0x6f, 0x64, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x1a, 0xcc, 0x01,
- 0x0a, 0x13, 0x52, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x65, 0x74,
- 0x75, 0x70, 0x52, 0x65, 0x71, 0x12, 0x5b, 0x0a, 0x12, 0x6d, 0x61, 0x78, 0x5f, 0x63, 0x6f, 0x75,
- 0x6e, 0x74, 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28,
- 0x0e, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
- 0x76, 0x33, 0x2e, 0x52, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x45, 0x78,
- 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01,
- 0x52, 0x10, 0x6d, 0x61, 0x78, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65,
- 0x6e, 0x74, 0x12, 0x58, 0x0a, 0x11, 0x6d, 0x61, 0x78, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x65,
- 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e,
- 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x52,
- 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e,
- 0x74, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0f, 0x6d, 0x61, 0x78,
- 0x54, 0x69, 0x6d, 0x65, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x1a, 0x48, 0x0a, 0x13,
- 0x52, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x65, 0x74, 0x75, 0x70,
- 0x41, 0x6e, 0x73, 0x12, 0x31, 0x0a, 0x15, 0x6d, 0x61, 0x78, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f,
- 0x65, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x08, 0x52, 0x12, 0x6d, 0x61, 0x78, 0x54, 0x69, 0x6d, 0x65, 0x45, 0x78, 0x70, 0x6f, 0x6e,
- 0x65, 0x6e, 0x74, 0x41, 0x63, 0x6b, 0x1a, 0x53, 0x0a, 0x0f, 0x50, 0x69, 0x6e, 0x67, 0x53, 0x6c,
- 0x6f, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x12, 0x40, 0x0a, 0x06, 0x70, 0x65, 0x72,
- 0x69, 0x6f, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
- 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x53,
- 0x6c, 0x6f, 0x74, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01,
- 0x02, 0x10, 0x01, 0x52, 0x06, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x1a, 0x90, 0x01, 0x0a, 0x12,
- 0x50, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52,
- 0x65, 0x71, 0x12, 0x29, 0x0a, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18,
- 0x01, 0x20, 0x01, 0x28, 0x04, 0x42, 0x0b, 0xfa, 0x42, 0x08, 0x32, 0x06, 0x18, 0x00, 0x28, 0xa0,
- 0x8d, 0x06, 0x52, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x4f, 0x0a,
- 0x0f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78,
- 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
+ 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d,
+ 0x61, 0x6e, 0x64, 0x73, 0x22, 0x43, 0x0a, 0x0e, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63,
+ 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1f, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x04, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x32, 0x04, 0x28, 0xa0, 0x8d, 0x06,
+ 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x10, 0xea, 0xaa, 0x19, 0x02, 0x18, 0x01, 0xf2,
+ 0xaa, 0x19, 0x06, 0x08, 0x01, 0x10, 0x01, 0x18, 0x01, 0x22, 0x4d, 0x0a, 0x16, 0x5a, 0x65, 0x72,
+ 0x6f, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x56, 0x61,
+ 0x6c, 0x75, 0x65, 0x12, 0x21, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x04, 0x42, 0x0b, 0xfa, 0x42, 0x08, 0x32, 0x06, 0x18, 0x00, 0x28, 0xa0, 0x8d, 0x06, 0x52,
+ 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x10, 0xea, 0xaa, 0x19, 0x02, 0x18, 0x01, 0xf2, 0xaa,
+ 0x19, 0x06, 0x08, 0x01, 0x10, 0x01, 0x18, 0x01, 0x22, 0x67, 0x0a, 0x13, 0x44, 0x61, 0x74, 0x61,
+ 0x52, 0x61, 0x74, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12,
+ 0x3e, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e,
+ 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
+ 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x42, 0x08,
+ 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a,
+ 0x10, 0xea, 0xaa, 0x19, 0x02, 0x18, 0x01, 0xf2, 0xaa, 0x19, 0x06, 0x08, 0x01, 0x10, 0x01, 0x18,
+ 0x01, 0x22, 0x65, 0x0a, 0x12, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64,
+ 0x65, 0x78, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65,
0x49, 0x6e, 0x64, 0x65, 0x78, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52,
- 0x0d, 0x64, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x68,
- 0x0a, 0x12, 0x50, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65,
- 0x6c, 0x41, 0x6e, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63,
- 0x79, 0x5f, 0x61, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x66, 0x72, 0x65,
- 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x41, 0x63, 0x6b, 0x12, 0x2d, 0x0a, 0x13, 0x64, 0x61, 0x74,
- 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x61, 0x63, 0x6b,
- 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x64, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65,
- 0x49, 0x6e, 0x64, 0x65, 0x78, 0x41, 0x63, 0x6b, 0x1a, 0x61, 0x0a, 0x0f, 0x42, 0x65, 0x61, 0x63,
- 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x41, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x05, 0x64,
- 0x65, 0x6c, 0x61, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x2a,
- 0x04, 0x18, 0xff, 0xff, 0x03, 0x52, 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x2d, 0x0a, 0x0d,
- 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20,
- 0x01, 0x28, 0x0d, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x2a, 0x03, 0x18, 0xff, 0x01, 0x52, 0x0c, 0x63,
- 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x3a, 0x0a, 0x0d, 0x42,
- 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x46, 0x72, 0x65, 0x71, 0x52, 0x65, 0x71, 0x12, 0x29, 0x0a, 0x09,
- 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x42,
- 0x0b, 0xfa, 0x42, 0x08, 0x32, 0x06, 0x18, 0x00, 0x28, 0xa0, 0x8d, 0x06, 0x52, 0x09, 0x66, 0x72,
- 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x1a, 0x34, 0x0a, 0x0d, 0x42, 0x65, 0x61, 0x63, 0x6f,
- 0x6e, 0x46, 0x72, 0x65, 0x71, 0x41, 0x6e, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x72, 0x65, 0x71,
- 0x75, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x61, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52,
- 0x0c, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x41, 0x63, 0x6b, 0x1a, 0x46, 0x0a,
- 0x0d, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x64, 0x12, 0x35,
- 0x0a, 0x05, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e,
- 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x43,
- 0x6c, 0x61, 0x73, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x05,
- 0x63, 0x6c, 0x61, 0x73, 0x73, 0x1a, 0x47, 0x0a, 0x0e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4d,
- 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x12, 0x35, 0x0a, 0x05, 0x63, 0x6c, 0x61, 0x73, 0x73,
- 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
- 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x42, 0x08, 0xfa,
- 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x05, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x42, 0x09,
- 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x45, 0x0a, 0x0b, 0x4d, 0x41, 0x43,
- 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x12, 0x36, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x6d,
- 0x61, 0x6e, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x74, 0x6e,
- 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x41, 0x43, 0x43,
- 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73,
- 0x22, 0x43, 0x0a, 0x0e, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x56, 0x61, 0x6c,
- 0x75, 0x65, 0x12, 0x1f, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
- 0x04, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x32, 0x04, 0x28, 0xa0, 0x8d, 0x06, 0x52, 0x05, 0x76, 0x61,
- 0x6c, 0x75, 0x65, 0x3a, 0x10, 0xea, 0xaa, 0x19, 0x02, 0x18, 0x01, 0xf2, 0xaa, 0x19, 0x06, 0x08,
- 0x01, 0x10, 0x01, 0x18, 0x01, 0x22, 0x4d, 0x0a, 0x16, 0x5a, 0x65, 0x72, 0x6f, 0x61, 0x62, 0x6c,
- 0x65, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12,
- 0x21, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x42, 0x0b,
- 0xfa, 0x42, 0x08, 0x32, 0x06, 0x18, 0x00, 0x28, 0xa0, 0x8d, 0x06, 0x52, 0x05, 0x76, 0x61, 0x6c,
- 0x75, 0x65, 0x3a, 0x10, 0xea, 0xaa, 0x19, 0x02, 0x18, 0x01, 0xf2, 0xaa, 0x19, 0x06, 0x08, 0x01,
- 0x10, 0x01, 0x18, 0x01, 0x22, 0x67, 0x0a, 0x13, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65,
- 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3e, 0x0a, 0x05, 0x76,
- 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x74, 0x74, 0x6e,
- 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61,
- 0x52, 0x61, 0x74, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82,
- 0x01, 0x02, 0x10, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x10, 0xea, 0xaa, 0x19,
- 0x02, 0x18, 0x01, 0xf2, 0xaa, 0x19, 0x06, 0x08, 0x01, 0x10, 0x01, 0x18, 0x01, 0x22, 0x65, 0x0a,
- 0x12, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x56, 0x61,
- 0x6c, 0x75, 0x65, 0x12, 0x3d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
- 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65,
- 0x78, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c,
- 0x75, 0x65, 0x3a, 0x10, 0xea, 0xaa, 0x19, 0x02, 0x18, 0x01, 0xf2, 0xaa, 0x19, 0x06, 0x08, 0x01,
- 0x10, 0x01, 0x18, 0x01, 0x22, 0x67, 0x0a, 0x13, 0x50, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74,
- 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3e, 0x0a, 0x05, 0x76,
- 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x74, 0x74, 0x6e,
- 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x50, 0x69, 0x6e, 0x67,
- 0x53, 0x6c, 0x6f, 0x74, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82,
- 0x01, 0x02, 0x10, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x10, 0xea, 0xaa, 0x19,
- 0x02, 0x18, 0x01, 0xf2, 0xaa, 0x19, 0x06, 0x08, 0x01, 0x10, 0x01, 0x18, 0x01, 0x22, 0x71, 0x0a,
- 0x18, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x44, 0x75, 0x74, 0x79, 0x43,
- 0x79, 0x63, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x43, 0x0a, 0x05, 0x76, 0x61, 0x6c,
- 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c,
- 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67,
- 0x61, 0x74, 0x65, 0x64, 0x44, 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x42, 0x08, 0xfa,
- 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x10,
- 0xea, 0xaa, 0x19, 0x02, 0x18, 0x01, 0xf2, 0xaa, 0x19, 0x06, 0x08, 0x01, 0x10, 0x01, 0x18, 0x01,
- 0x22, 0x59, 0x0a, 0x0c, 0x52, 0x78, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65,
- 0x12, 0x37, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32,
- 0x17, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
- 0x2e, 0x52, 0x78, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02,
- 0x10, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x10, 0xea, 0xaa, 0x19, 0x02, 0x18,
- 0x01, 0xf2, 0xaa, 0x19, 0x06, 0x08, 0x01, 0x10, 0x01, 0x18, 0x01, 0x22, 0x71, 0x0a, 0x18, 0x41,
- 0x44, 0x52, 0x41, 0x63, 0x6b, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65,
- 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x43, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
- 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
- 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x44, 0x52, 0x41, 0x63, 0x6b, 0x4c, 0x69,
- 0x6d, 0x69, 0x74, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x42, 0x08, 0xfa, 0x42, 0x05,
- 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x10, 0xea, 0xaa,
- 0x19, 0x02, 0x18, 0x01, 0xf2, 0xaa, 0x19, 0x06, 0x08, 0x01, 0x10, 0x01, 0x18, 0x01, 0x22, 0x71,
- 0x0a, 0x18, 0x41, 0x44, 0x52, 0x41, 0x63, 0x6b, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x45, 0x78, 0x70,
- 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x43, 0x0a, 0x05, 0x76, 0x61,
- 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
- 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x44, 0x52, 0x41, 0x63,
- 0x6b, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x42, 0x08,
+ 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x10, 0xea, 0xaa, 0x19, 0x02, 0x18, 0x01, 0xf2, 0xaa,
+ 0x19, 0x06, 0x08, 0x01, 0x10, 0x01, 0x18, 0x01, 0x22, 0x67, 0x0a, 0x13, 0x50, 0x69, 0x6e, 0x67,
+ 0x53, 0x6c, 0x6f, 0x74, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12,
+ 0x3e, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e,
+ 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
+ 0x50, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x42, 0x08,
0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a,
0x10, 0xea, 0xaa, 0x19, 0x02, 0x18, 0x01, 0xf2, 0xaa, 0x19, 0x06, 0x08, 0x01, 0x10, 0x01, 0x18,
- 0x01, 0x22, 0x5f, 0x0a, 0x0f, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, 0x49, 0x52, 0x50, 0x56,
- 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
- 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, 0x49, 0x52, 0x50, 0x42,
+ 0x01, 0x22, 0x71, 0x0a, 0x18, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x44,
+ 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x43, 0x0a,
+ 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x74,
+ 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x67,
+ 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x44, 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c,
+ 0x65, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c,
+ 0x75, 0x65, 0x3a, 0x10, 0xea, 0xaa, 0x19, 0x02, 0x18, 0x01, 0xf2, 0xaa, 0x19, 0x06, 0x08, 0x01,
+ 0x10, 0x01, 0x18, 0x01, 0x22, 0x59, 0x0a, 0x0c, 0x52, 0x78, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x56,
+ 0x61, 0x6c, 0x75, 0x65, 0x12, 0x37, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
+ 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x78, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x42, 0x08, 0xfa, 0x42,
+ 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x10, 0xea,
+ 0xaa, 0x19, 0x02, 0x18, 0x01, 0xf2, 0xaa, 0x19, 0x06, 0x08, 0x01, 0x10, 0x01, 0x18, 0x01, 0x22,
+ 0x71, 0x0a, 0x18, 0x41, 0x44, 0x52, 0x41, 0x63, 0x6b, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x45, 0x78,
+ 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x43, 0x0a, 0x05, 0x76,
+ 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e,
+ 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x44, 0x52, 0x41,
+ 0x63, 0x6b, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x42,
0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
0x3a, 0x10, 0xea, 0xaa, 0x19, 0x02, 0x18, 0x01, 0xf2, 0xaa, 0x19, 0x06, 0x08, 0x01, 0x10, 0x01,
- 0x18, 0x01, 0x2a, 0xa7, 0x01, 0x0a, 0x05, 0x4d, 0x54, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x0c,
- 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x10, 0x00, 0x12, 0x0f,
- 0x0a, 0x0b, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x10, 0x01, 0x12,
- 0x12, 0x0a, 0x0e, 0x55, 0x4e, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x52, 0x4d, 0x45, 0x44, 0x5f, 0x55,
- 0x50, 0x10, 0x02, 0x12, 0x14, 0x0a, 0x10, 0x55, 0x4e, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x52, 0x4d,
- 0x45, 0x44, 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x43, 0x4f, 0x4e,
- 0x46, 0x49, 0x52, 0x4d, 0x45, 0x44, 0x5f, 0x55, 0x50, 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x43,
- 0x4f, 0x4e, 0x46, 0x49, 0x52, 0x4d, 0x45, 0x44, 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x05, 0x12,
- 0x12, 0x0a, 0x0e, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53,
- 0x54, 0x10, 0x06, 0x12, 0x0f, 0x0a, 0x0b, 0x50, 0x52, 0x4f, 0x50, 0x52, 0x49, 0x45, 0x54, 0x41,
- 0x52, 0x59, 0x10, 0x07, 0x1a, 0x06, 0xea, 0xaa, 0x19, 0x02, 0x18, 0x01, 0x2a, 0x28, 0x0a, 0x05,
- 0x4d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x0e, 0x0a, 0x0a, 0x4c, 0x4f, 0x52, 0x41, 0x57, 0x41, 0x4e,
- 0x5f, 0x52, 0x31, 0x10, 0x00, 0x1a, 0x0f, 0xea, 0xaa, 0x19, 0x0b, 0x18, 0x01, 0x2a, 0x07, 0x4c,
- 0x4f, 0x52, 0x41, 0x57, 0x41, 0x4e, 0x2a, 0xb9, 0x02, 0x0a, 0x0a, 0x4d, 0x41, 0x43, 0x56, 0x65,
- 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0b, 0x4d, 0x41, 0x43, 0x5f, 0x55, 0x4e, 0x4b,
- 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x1a, 0x0d, 0xea, 0xaa, 0x19, 0x09, 0x12, 0x07, 0x75, 0x6e,
- 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x12, 0x1e, 0x0a, 0x08, 0x4d, 0x41, 0x43, 0x5f, 0x56, 0x31, 0x5f,
- 0x30, 0x10, 0x01, 0x1a, 0x10, 0xea, 0xaa, 0x19, 0x0c, 0x12, 0x03, 0x31, 0x2e, 0x30, 0x12, 0x05,
- 0x31, 0x2e, 0x30, 0x2e, 0x30, 0x12, 0x1b, 0x0a, 0x0a, 0x4d, 0x41, 0x43, 0x5f, 0x56, 0x31, 0x5f,
- 0x30, 0x5f, 0x31, 0x10, 0x02, 0x1a, 0x0b, 0xea, 0xaa, 0x19, 0x07, 0x12, 0x05, 0x31, 0x2e, 0x30,
- 0x2e, 0x31, 0x12, 0x1b, 0x0a, 0x0a, 0x4d, 0x41, 0x43, 0x5f, 0x56, 0x31, 0x5f, 0x30, 0x5f, 0x32,
- 0x10, 0x03, 0x1a, 0x0b, 0xea, 0xaa, 0x19, 0x07, 0x12, 0x05, 0x31, 0x2e, 0x30, 0x2e, 0x32, 0x12,
- 0x1e, 0x0a, 0x08, 0x4d, 0x41, 0x43, 0x5f, 0x56, 0x31, 0x5f, 0x31, 0x10, 0x04, 0x1a, 0x10, 0xea,
- 0xaa, 0x19, 0x0c, 0x12, 0x03, 0x31, 0x2e, 0x31, 0x12, 0x05, 0x31, 0x2e, 0x31, 0x2e, 0x30, 0x12,
- 0x1b, 0x0a, 0x0a, 0x4d, 0x41, 0x43, 0x5f, 0x56, 0x31, 0x5f, 0x30, 0x5f, 0x33, 0x10, 0x05, 0x1a,
- 0x0b, 0xea, 0xaa, 0x19, 0x07, 0x12, 0x05, 0x31, 0x2e, 0x30, 0x2e, 0x33, 0x12, 0x1b, 0x0a, 0x0a,
- 0x4d, 0x41, 0x43, 0x5f, 0x56, 0x31, 0x5f, 0x30, 0x5f, 0x34, 0x10, 0x06, 0x1a, 0x0b, 0xea, 0xaa,
- 0x19, 0x07, 0x12, 0x05, 0x31, 0x2e, 0x30, 0x2e, 0x34, 0x1a, 0x57, 0xea, 0xaa, 0x19, 0x07, 0x18,
- 0x01, 0x2a, 0x03, 0x4d, 0x41, 0x43, 0xf2, 0xaa, 0x19, 0x48, 0x0a, 0x46, 0x67, 0x6f, 0x2e, 0x74,
- 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
- 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76,
- 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74, 0x6e, 0x70, 0x62, 0x2e, 0x4d, 0x41, 0x43, 0x56,
- 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x76, 0x61, 0x6c,
- 0x75, 0x65, 0x2a, 0xcb, 0x05, 0x0a, 0x0a, 0x50, 0x48, 0x59, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
- 0x6e, 0x12, 0x1e, 0x0a, 0x0b, 0x50, 0x48, 0x59, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e,
- 0x10, 0x00, 0x1a, 0x0d, 0xea, 0xaa, 0x19, 0x09, 0x12, 0x07, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77,
- 0x6e, 0x12, 0x24, 0x0a, 0x08, 0x50, 0x48, 0x59, 0x5f, 0x56, 0x31, 0x5f, 0x30, 0x10, 0x01, 0x1a,
- 0x16, 0xea, 0xaa, 0x19, 0x12, 0x12, 0x03, 0x31, 0x2e, 0x30, 0x12, 0x05, 0x31, 0x2e, 0x30, 0x2e,
- 0x30, 0x12, 0x04, 0x56, 0x31, 0x5f, 0x30, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x53, 0x30, 0x30, 0x31,
- 0x5f, 0x56, 0x31, 0x5f, 0x30, 0x10, 0x01, 0x12, 0x23, 0x0a, 0x0a, 0x50, 0x48, 0x59, 0x5f, 0x56,
- 0x31, 0x5f, 0x30, 0x5f, 0x31, 0x10, 0x02, 0x1a, 0x13, 0xea, 0xaa, 0x19, 0x0f, 0x12, 0x05, 0x31,
- 0x2e, 0x30, 0x2e, 0x31, 0x12, 0x06, 0x56, 0x31, 0x5f, 0x30, 0x5f, 0x31, 0x12, 0x10, 0x0a, 0x0c,
- 0x54, 0x53, 0x30, 0x30, 0x31, 0x5f, 0x56, 0x31, 0x5f, 0x30, 0x5f, 0x31, 0x10, 0x02, 0x12, 0x40,
- 0x0a, 0x10, 0x50, 0x48, 0x59, 0x5f, 0x56, 0x31, 0x5f, 0x30, 0x5f, 0x32, 0x5f, 0x52, 0x45, 0x56,
- 0x5f, 0x41, 0x10, 0x03, 0x1a, 0x2a, 0xea, 0xaa, 0x19, 0x26, 0x12, 0x05, 0x31, 0x2e, 0x30, 0x2e,
- 0x32, 0x12, 0x07, 0x31, 0x2e, 0x30, 0x2e, 0x32, 0x2d, 0x61, 0x12, 0x06, 0x56, 0x31, 0x5f, 0x30,
- 0x5f, 0x32, 0x12, 0x0c, 0x56, 0x31, 0x5f, 0x30, 0x5f, 0x32, 0x5f, 0x52, 0x45, 0x56, 0x5f, 0x41,
- 0x12, 0x10, 0x0a, 0x0c, 0x52, 0x50, 0x30, 0x30, 0x31, 0x5f, 0x56, 0x31, 0x5f, 0x30, 0x5f, 0x32,
- 0x10, 0x03, 0x12, 0x31, 0x0a, 0x10, 0x50, 0x48, 0x59, 0x5f, 0x56, 0x31, 0x5f, 0x30, 0x5f, 0x32,
- 0x5f, 0x52, 0x45, 0x56, 0x5f, 0x42, 0x10, 0x04, 0x1a, 0x1b, 0xea, 0xaa, 0x19, 0x17, 0x12, 0x07,
- 0x31, 0x2e, 0x30, 0x2e, 0x32, 0x2d, 0x62, 0x12, 0x0c, 0x56, 0x31, 0x5f, 0x30, 0x5f, 0x32, 0x5f,
- 0x52, 0x45, 0x56, 0x5f, 0x42, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x50, 0x30, 0x30, 0x31, 0x5f, 0x56,
- 0x31, 0x5f, 0x30, 0x5f, 0x32, 0x5f, 0x52, 0x45, 0x56, 0x5f, 0x42, 0x10, 0x04, 0x12, 0x34, 0x0a,
- 0x0e, 0x50, 0x48, 0x59, 0x5f, 0x56, 0x31, 0x5f, 0x31, 0x5f, 0x52, 0x45, 0x56, 0x5f, 0x41, 0x10,
- 0x05, 0x1a, 0x20, 0xea, 0xaa, 0x19, 0x1c, 0x12, 0x05, 0x31, 0x2e, 0x31, 0x2d, 0x61, 0x12, 0x07,
- 0x31, 0x2e, 0x31, 0x2e, 0x30, 0x2d, 0x61, 0x12, 0x0a, 0x56, 0x31, 0x5f, 0x31, 0x5f, 0x52, 0x45,
- 0x56, 0x5f, 0x41, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x50, 0x30, 0x30, 0x31, 0x5f, 0x56, 0x31, 0x5f,
- 0x31, 0x5f, 0x52, 0x45, 0x56, 0x5f, 0x41, 0x10, 0x05, 0x12, 0x34, 0x0a, 0x0e, 0x50, 0x48, 0x59,
- 0x5f, 0x56, 0x31, 0x5f, 0x31, 0x5f, 0x52, 0x45, 0x56, 0x5f, 0x42, 0x10, 0x06, 0x1a, 0x20, 0xea,
- 0xaa, 0x19, 0x1c, 0x12, 0x05, 0x31, 0x2e, 0x31, 0x2d, 0x62, 0x12, 0x07, 0x31, 0x2e, 0x31, 0x2e,
- 0x30, 0x2d, 0x62, 0x12, 0x0a, 0x56, 0x31, 0x5f, 0x31, 0x5f, 0x52, 0x45, 0x56, 0x5f, 0x42, 0x12,
- 0x14, 0x0a, 0x10, 0x52, 0x50, 0x30, 0x30, 0x31, 0x5f, 0x56, 0x31, 0x5f, 0x31, 0x5f, 0x52, 0x45,
- 0x56, 0x5f, 0x42, 0x10, 0x06, 0x12, 0x31, 0x0a, 0x10, 0x50, 0x48, 0x59, 0x5f, 0x56, 0x31, 0x5f,
- 0x30, 0x5f, 0x33, 0x5f, 0x52, 0x45, 0x56, 0x5f, 0x41, 0x10, 0x07, 0x1a, 0x1b, 0xea, 0xaa, 0x19,
- 0x17, 0x12, 0x07, 0x31, 0x2e, 0x30, 0x2e, 0x33, 0x2d, 0x61, 0x12, 0x0c, 0x56, 0x31, 0x5f, 0x30,
- 0x5f, 0x33, 0x5f, 0x52, 0x45, 0x56, 0x5f, 0x41, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x50, 0x30, 0x30,
- 0x31, 0x5f, 0x56, 0x31, 0x5f, 0x30, 0x5f, 0x33, 0x5f, 0x52, 0x45, 0x56, 0x5f, 0x41, 0x10, 0x07,
- 0x12, 0x10, 0x0a, 0x0c, 0x52, 0x50, 0x30, 0x30, 0x32, 0x5f, 0x56, 0x31, 0x5f, 0x30, 0x5f, 0x30,
- 0x10, 0x08, 0x12, 0x10, 0x0a, 0x0c, 0x52, 0x50, 0x30, 0x30, 0x32, 0x5f, 0x56, 0x31, 0x5f, 0x30,
- 0x5f, 0x31, 0x10, 0x09, 0x12, 0x10, 0x0a, 0x0c, 0x52, 0x50, 0x30, 0x30, 0x32, 0x5f, 0x56, 0x31,
- 0x5f, 0x30, 0x5f, 0x32, 0x10, 0x0a, 0x12, 0x10, 0x0a, 0x0c, 0x52, 0x50, 0x30, 0x30, 0x32, 0x5f,
- 0x56, 0x31, 0x5f, 0x30, 0x5f, 0x33, 0x10, 0x0b, 0x12, 0x10, 0x0a, 0x0c, 0x52, 0x50, 0x30, 0x30,
- 0x32, 0x5f, 0x56, 0x31, 0x5f, 0x30, 0x5f, 0x34, 0x10, 0x0c, 0x1a, 0x54, 0xea, 0xaa, 0x19, 0x02,
- 0x18, 0x01, 0xf2, 0xaa, 0x19, 0x48, 0x0a, 0x46, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68,
+ 0x18, 0x01, 0x22, 0x71, 0x0a, 0x18, 0x41, 0x44, 0x52, 0x41, 0x63, 0x6b, 0x44, 0x65, 0x6c, 0x61,
+ 0x79, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x43,
+ 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e,
+ 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41,
+ 0x44, 0x52, 0x41, 0x63, 0x6b, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65,
+ 0x6e, 0x74, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x05, 0x76, 0x61,
+ 0x6c, 0x75, 0x65, 0x3a, 0x10, 0xea, 0xaa, 0x19, 0x02, 0x18, 0x01, 0xf2, 0xaa, 0x19, 0x06, 0x08,
+ 0x01, 0x10, 0x01, 0x18, 0x01, 0x22, 0x5f, 0x0a, 0x0f, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45,
+ 0x49, 0x52, 0x50, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
+ 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
+ 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45,
+ 0x49, 0x52, 0x50, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x05, 0x76,
+ 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x10, 0xea, 0xaa, 0x19, 0x02, 0x18, 0x01, 0xf2, 0xaa, 0x19, 0x06,
+ 0x08, 0x01, 0x10, 0x01, 0x18, 0x01, 0x22, 0xcf, 0x02, 0x0a, 0x15, 0x52, 0x65, 0x6c, 0x61, 0x79,
+ 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x71,
+ 0x12, 0x3f, 0x0a, 0x09, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
+ 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x42, 0x08, 0xfa,
+ 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74,
+ 0x65, 0x12, 0x24, 0x0a, 0x03, 0x73, 0x6e, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x42, 0x12,
+ 0xfa, 0x42, 0x0f, 0x1a, 0x0d, 0x18, 0x0b, 0x28, 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0x01, 0x52, 0x03, 0x73, 0x6e, 0x72, 0x12, 0x2f, 0x0a, 0x04, 0x72, 0x73, 0x73, 0x69, 0x18,
+ 0x03, 0x20, 0x01, 0x28, 0x05, 0x42, 0x1b, 0xfa, 0x42, 0x18, 0x1a, 0x16, 0x18, 0xf1, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x28, 0xf2, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0x01, 0x52, 0x04, 0x72, 0x73, 0x73, 0x69, 0x12, 0x4a, 0x0a, 0x0b, 0x77, 0x6f, 0x72, 0x5f,
+ 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e,
+ 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x52,
+ 0x65, 0x6c, 0x61, 0x79, 0x57, 0x4f, 0x52, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x42, 0x08,
+ 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x77, 0x6f, 0x72, 0x43, 0x68, 0x61,
+ 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x27, 0x0a, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63,
+ 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x32, 0x04, 0x28, 0xa0,
+ 0x8d, 0x06, 0x52, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x1f, 0x0a,
+ 0x0b, 0x72, 0x61, 0x77, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x06, 0x20, 0x01,
+ 0x28, 0x0c, 0x52, 0x0a, 0x72, 0x61, 0x77, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x3a, 0x08,
+ 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x22, 0x44, 0x0a, 0x17, 0x52, 0x65, 0x6c, 0x61,
+ 0x79, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b,
+ 0x52, 0x65, 0x71, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x61, 0x77, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f,
+ 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x72, 0x61, 0x77, 0x50, 0x61, 0x79,
+ 0x6c, 0x6f, 0x61, 0x64, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x22, 0x98,
+ 0x01, 0x0a, 0x10, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x54, 0x6f,
+ 0x6b, 0x65, 0x6e, 0x12, 0x40, 0x0a, 0x03, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x24, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
+ 0x33, 0x2e, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74,
+ 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01,
+ 0x52, 0x03, 0x69, 0x64, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e,
+ 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x73,
+ 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x0a, 0x66,
+ 0x75, 0x6c, 0x6c, 0x5f, 0x66, 0x5f, 0x63, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52,
+ 0x08, 0x66, 0x75, 0x6c, 0x6c, 0x46, 0x43, 0x6e, 0x74, 0x2a, 0xa7, 0x01, 0x0a, 0x05, 0x4d, 0x54,
+ 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x0c, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x52, 0x45, 0x51, 0x55,
+ 0x45, 0x53, 0x54, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x41, 0x43,
+ 0x43, 0x45, 0x50, 0x54, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x55, 0x4e, 0x43, 0x4f, 0x4e, 0x46,
+ 0x49, 0x52, 0x4d, 0x45, 0x44, 0x5f, 0x55, 0x50, 0x10, 0x02, 0x12, 0x14, 0x0a, 0x10, 0x55, 0x4e,
+ 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x52, 0x4d, 0x45, 0x44, 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x03,
+ 0x12, 0x10, 0x0a, 0x0c, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x52, 0x4d, 0x45, 0x44, 0x5f, 0x55, 0x50,
+ 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x52, 0x4d, 0x45, 0x44, 0x5f,
+ 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x05, 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e,
+ 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x10, 0x06, 0x12, 0x0f, 0x0a, 0x0b, 0x50, 0x52,
+ 0x4f, 0x50, 0x52, 0x49, 0x45, 0x54, 0x41, 0x52, 0x59, 0x10, 0x07, 0x1a, 0x06, 0xea, 0xaa, 0x19,
+ 0x02, 0x18, 0x01, 0x2a, 0x28, 0x0a, 0x05, 0x4d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x0e, 0x0a, 0x0a,
+ 0x4c, 0x4f, 0x52, 0x41, 0x57, 0x41, 0x4e, 0x5f, 0x52, 0x31, 0x10, 0x00, 0x1a, 0x0f, 0xea, 0xaa,
+ 0x19, 0x0b, 0x18, 0x01, 0x2a, 0x07, 0x4c, 0x4f, 0x52, 0x41, 0x57, 0x41, 0x4e, 0x2a, 0xb9, 0x02,
+ 0x0a, 0x0a, 0x4d, 0x41, 0x43, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0b,
+ 0x4d, 0x41, 0x43, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x1a, 0x0d, 0xea,
+ 0xaa, 0x19, 0x09, 0x12, 0x07, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x12, 0x1e, 0x0a, 0x08,
+ 0x4d, 0x41, 0x43, 0x5f, 0x56, 0x31, 0x5f, 0x30, 0x10, 0x01, 0x1a, 0x10, 0xea, 0xaa, 0x19, 0x0c,
+ 0x12, 0x03, 0x31, 0x2e, 0x30, 0x12, 0x05, 0x31, 0x2e, 0x30, 0x2e, 0x30, 0x12, 0x1b, 0x0a, 0x0a,
+ 0x4d, 0x41, 0x43, 0x5f, 0x56, 0x31, 0x5f, 0x30, 0x5f, 0x31, 0x10, 0x02, 0x1a, 0x0b, 0xea, 0xaa,
+ 0x19, 0x07, 0x12, 0x05, 0x31, 0x2e, 0x30, 0x2e, 0x31, 0x12, 0x1b, 0x0a, 0x0a, 0x4d, 0x41, 0x43,
+ 0x5f, 0x56, 0x31, 0x5f, 0x30, 0x5f, 0x32, 0x10, 0x03, 0x1a, 0x0b, 0xea, 0xaa, 0x19, 0x07, 0x12,
+ 0x05, 0x31, 0x2e, 0x30, 0x2e, 0x32, 0x12, 0x1e, 0x0a, 0x08, 0x4d, 0x41, 0x43, 0x5f, 0x56, 0x31,
+ 0x5f, 0x31, 0x10, 0x04, 0x1a, 0x10, 0xea, 0xaa, 0x19, 0x0c, 0x12, 0x03, 0x31, 0x2e, 0x31, 0x12,
+ 0x05, 0x31, 0x2e, 0x31, 0x2e, 0x30, 0x12, 0x1b, 0x0a, 0x0a, 0x4d, 0x41, 0x43, 0x5f, 0x56, 0x31,
+ 0x5f, 0x30, 0x5f, 0x33, 0x10, 0x05, 0x1a, 0x0b, 0xea, 0xaa, 0x19, 0x07, 0x12, 0x05, 0x31, 0x2e,
+ 0x30, 0x2e, 0x33, 0x12, 0x1b, 0x0a, 0x0a, 0x4d, 0x41, 0x43, 0x5f, 0x56, 0x31, 0x5f, 0x30, 0x5f,
+ 0x34, 0x10, 0x06, 0x1a, 0x0b, 0xea, 0xaa, 0x19, 0x07, 0x12, 0x05, 0x31, 0x2e, 0x30, 0x2e, 0x34,
+ 0x1a, 0x57, 0xea, 0xaa, 0x19, 0x07, 0x18, 0x01, 0x2a, 0x03, 0x4d, 0x41, 0x43, 0xf2, 0xaa, 0x19,
+ 0x48, 0x0a, 0x46, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e,
+ 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d,
+ 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74, 0x6e,
+ 0x70, 0x62, 0x2e, 0x4d, 0x41, 0x43, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x75,
+ 0x73, 0x74, 0x6f, 0x6d, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2a, 0xcb, 0x05, 0x0a, 0x0a, 0x50, 0x48,
+ 0x59, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0b, 0x50, 0x48, 0x59, 0x5f,
+ 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x1a, 0x0d, 0xea, 0xaa, 0x19, 0x09, 0x12,
+ 0x07, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x12, 0x24, 0x0a, 0x08, 0x50, 0x48, 0x59, 0x5f,
+ 0x56, 0x31, 0x5f, 0x30, 0x10, 0x01, 0x1a, 0x16, 0xea, 0xaa, 0x19, 0x12, 0x12, 0x03, 0x31, 0x2e,
+ 0x30, 0x12, 0x05, 0x31, 0x2e, 0x30, 0x2e, 0x30, 0x12, 0x04, 0x56, 0x31, 0x5f, 0x30, 0x12, 0x0e,
+ 0x0a, 0x0a, 0x54, 0x53, 0x30, 0x30, 0x31, 0x5f, 0x56, 0x31, 0x5f, 0x30, 0x10, 0x01, 0x12, 0x23,
+ 0x0a, 0x0a, 0x50, 0x48, 0x59, 0x5f, 0x56, 0x31, 0x5f, 0x30, 0x5f, 0x31, 0x10, 0x02, 0x1a, 0x13,
+ 0xea, 0xaa, 0x19, 0x0f, 0x12, 0x05, 0x31, 0x2e, 0x30, 0x2e, 0x31, 0x12, 0x06, 0x56, 0x31, 0x5f,
+ 0x30, 0x5f, 0x31, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x53, 0x30, 0x30, 0x31, 0x5f, 0x56, 0x31, 0x5f,
+ 0x30, 0x5f, 0x31, 0x10, 0x02, 0x12, 0x40, 0x0a, 0x10, 0x50, 0x48, 0x59, 0x5f, 0x56, 0x31, 0x5f,
+ 0x30, 0x5f, 0x32, 0x5f, 0x52, 0x45, 0x56, 0x5f, 0x41, 0x10, 0x03, 0x1a, 0x2a, 0xea, 0xaa, 0x19,
+ 0x26, 0x12, 0x05, 0x31, 0x2e, 0x30, 0x2e, 0x32, 0x12, 0x07, 0x31, 0x2e, 0x30, 0x2e, 0x32, 0x2d,
+ 0x61, 0x12, 0x06, 0x56, 0x31, 0x5f, 0x30, 0x5f, 0x32, 0x12, 0x0c, 0x56, 0x31, 0x5f, 0x30, 0x5f,
+ 0x32, 0x5f, 0x52, 0x45, 0x56, 0x5f, 0x41, 0x12, 0x10, 0x0a, 0x0c, 0x52, 0x50, 0x30, 0x30, 0x31,
+ 0x5f, 0x56, 0x31, 0x5f, 0x30, 0x5f, 0x32, 0x10, 0x03, 0x12, 0x31, 0x0a, 0x10, 0x50, 0x48, 0x59,
+ 0x5f, 0x56, 0x31, 0x5f, 0x30, 0x5f, 0x32, 0x5f, 0x52, 0x45, 0x56, 0x5f, 0x42, 0x10, 0x04, 0x1a,
+ 0x1b, 0xea, 0xaa, 0x19, 0x17, 0x12, 0x07, 0x31, 0x2e, 0x30, 0x2e, 0x32, 0x2d, 0x62, 0x12, 0x0c,
+ 0x56, 0x31, 0x5f, 0x30, 0x5f, 0x32, 0x5f, 0x52, 0x45, 0x56, 0x5f, 0x42, 0x12, 0x16, 0x0a, 0x12,
+ 0x52, 0x50, 0x30, 0x30, 0x31, 0x5f, 0x56, 0x31, 0x5f, 0x30, 0x5f, 0x32, 0x5f, 0x52, 0x45, 0x56,
+ 0x5f, 0x42, 0x10, 0x04, 0x12, 0x34, 0x0a, 0x0e, 0x50, 0x48, 0x59, 0x5f, 0x56, 0x31, 0x5f, 0x31,
+ 0x5f, 0x52, 0x45, 0x56, 0x5f, 0x41, 0x10, 0x05, 0x1a, 0x20, 0xea, 0xaa, 0x19, 0x1c, 0x12, 0x05,
+ 0x31, 0x2e, 0x31, 0x2d, 0x61, 0x12, 0x07, 0x31, 0x2e, 0x31, 0x2e, 0x30, 0x2d, 0x61, 0x12, 0x0a,
+ 0x56, 0x31, 0x5f, 0x31, 0x5f, 0x52, 0x45, 0x56, 0x5f, 0x41, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x50,
+ 0x30, 0x30, 0x31, 0x5f, 0x56, 0x31, 0x5f, 0x31, 0x5f, 0x52, 0x45, 0x56, 0x5f, 0x41, 0x10, 0x05,
+ 0x12, 0x34, 0x0a, 0x0e, 0x50, 0x48, 0x59, 0x5f, 0x56, 0x31, 0x5f, 0x31, 0x5f, 0x52, 0x45, 0x56,
+ 0x5f, 0x42, 0x10, 0x06, 0x1a, 0x20, 0xea, 0xaa, 0x19, 0x1c, 0x12, 0x05, 0x31, 0x2e, 0x31, 0x2d,
+ 0x62, 0x12, 0x07, 0x31, 0x2e, 0x31, 0x2e, 0x30, 0x2d, 0x62, 0x12, 0x0a, 0x56, 0x31, 0x5f, 0x31,
+ 0x5f, 0x52, 0x45, 0x56, 0x5f, 0x42, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x50, 0x30, 0x30, 0x31, 0x5f,
+ 0x56, 0x31, 0x5f, 0x31, 0x5f, 0x52, 0x45, 0x56, 0x5f, 0x42, 0x10, 0x06, 0x12, 0x31, 0x0a, 0x10,
+ 0x50, 0x48, 0x59, 0x5f, 0x56, 0x31, 0x5f, 0x30, 0x5f, 0x33, 0x5f, 0x52, 0x45, 0x56, 0x5f, 0x41,
+ 0x10, 0x07, 0x1a, 0x1b, 0xea, 0xaa, 0x19, 0x17, 0x12, 0x07, 0x31, 0x2e, 0x30, 0x2e, 0x33, 0x2d,
+ 0x61, 0x12, 0x0c, 0x56, 0x31, 0x5f, 0x30, 0x5f, 0x33, 0x5f, 0x52, 0x45, 0x56, 0x5f, 0x41, 0x12,
+ 0x16, 0x0a, 0x12, 0x52, 0x50, 0x30, 0x30, 0x31, 0x5f, 0x56, 0x31, 0x5f, 0x30, 0x5f, 0x33, 0x5f,
+ 0x52, 0x45, 0x56, 0x5f, 0x41, 0x10, 0x07, 0x12, 0x10, 0x0a, 0x0c, 0x52, 0x50, 0x30, 0x30, 0x32,
+ 0x5f, 0x56, 0x31, 0x5f, 0x30, 0x5f, 0x30, 0x10, 0x08, 0x12, 0x10, 0x0a, 0x0c, 0x52, 0x50, 0x30,
+ 0x30, 0x32, 0x5f, 0x56, 0x31, 0x5f, 0x30, 0x5f, 0x31, 0x10, 0x09, 0x12, 0x10, 0x0a, 0x0c, 0x52,
+ 0x50, 0x30, 0x30, 0x32, 0x5f, 0x56, 0x31, 0x5f, 0x30, 0x5f, 0x32, 0x10, 0x0a, 0x12, 0x10, 0x0a,
+ 0x0c, 0x52, 0x50, 0x30, 0x30, 0x32, 0x5f, 0x56, 0x31, 0x5f, 0x30, 0x5f, 0x33, 0x10, 0x0b, 0x12,
+ 0x10, 0x0a, 0x0c, 0x52, 0x50, 0x30, 0x30, 0x32, 0x5f, 0x56, 0x31, 0x5f, 0x30, 0x5f, 0x34, 0x10,
+ 0x0c, 0x1a, 0x54, 0xea, 0xaa, 0x19, 0x02, 0x18, 0x01, 0xf2, 0xaa, 0x19, 0x48, 0x0a, 0x46, 0x67,
+ 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77,
+ 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63,
+ 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74, 0x6e, 0x70, 0x62, 0x2e, 0x50,
+ 0x48, 0x59, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d,
+ 0x76, 0x61, 0x6c, 0x75, 0x65, 0x10, 0x01, 0x2a, 0x87, 0x03, 0x0a, 0x0d, 0x44, 0x61, 0x74, 0x61,
+ 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x0f, 0x0a, 0x0b, 0x44, 0x41, 0x54,
+ 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x30, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x44, 0x41,
+ 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x31, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x44,
+ 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b,
+ 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x33, 0x10, 0x03, 0x12, 0x0f, 0x0a,
+ 0x0b, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x34, 0x10, 0x04, 0x12, 0x0f,
+ 0x0a, 0x0b, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x35, 0x10, 0x05, 0x12,
+ 0x0f, 0x0a, 0x0b, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x36, 0x10, 0x06,
+ 0x12, 0x0f, 0x0a, 0x0b, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x37, 0x10,
+ 0x07, 0x12, 0x0f, 0x0a, 0x0b, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x38,
+ 0x10, 0x08, 0x12, 0x0f, 0x0a, 0x0b, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x5f,
+ 0x39, 0x10, 0x09, 0x12, 0x10, 0x0a, 0x0c, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45,
+ 0x5f, 0x31, 0x30, 0x10, 0x0a, 0x12, 0x10, 0x0a, 0x0c, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41,
+ 0x54, 0x45, 0x5f, 0x31, 0x31, 0x10, 0x0b, 0x12, 0x10, 0x0a, 0x0c, 0x44, 0x41, 0x54, 0x41, 0x5f,
+ 0x52, 0x41, 0x54, 0x45, 0x5f, 0x31, 0x32, 0x10, 0x0c, 0x12, 0x10, 0x0a, 0x0c, 0x44, 0x41, 0x54,
+ 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x31, 0x33, 0x10, 0x0d, 0x12, 0x10, 0x0a, 0x0c, 0x44,
+ 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x31, 0x34, 0x10, 0x0e, 0x12, 0x10, 0x0a,
+ 0x0c, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x31, 0x35, 0x10, 0x0f, 0x1a,
+ 0x60, 0xea, 0xaa, 0x19, 0x0d, 0x10, 0x01, 0x2a, 0x09, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41,
+ 0x54, 0x45, 0xf2, 0xaa, 0x19, 0x4b, 0x0a, 0x49, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68,
0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72,
0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b,
- 0x67, 0x2f, 0x74, 0x74, 0x6e, 0x70, 0x62, 0x2e, 0x50, 0x48, 0x59, 0x56, 0x65, 0x72, 0x73, 0x69,
- 0x6f, 0x6e, 0x5f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x10, 0x01,
- 0x2a, 0x87, 0x03, 0x0a, 0x0d, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64,
- 0x65, 0x78, 0x12, 0x0f, 0x0a, 0x0b, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x5f,
- 0x30, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45,
- 0x5f, 0x31, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54,
- 0x45, 0x5f, 0x32, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41,
- 0x54, 0x45, 0x5f, 0x33, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52,
- 0x41, 0x54, 0x45, 0x5f, 0x34, 0x10, 0x04, 0x12, 0x0f, 0x0a, 0x0b, 0x44, 0x41, 0x54, 0x41, 0x5f,
- 0x52, 0x41, 0x54, 0x45, 0x5f, 0x35, 0x10, 0x05, 0x12, 0x0f, 0x0a, 0x0b, 0x44, 0x41, 0x54, 0x41,
- 0x5f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x36, 0x10, 0x06, 0x12, 0x0f, 0x0a, 0x0b, 0x44, 0x41, 0x54,
- 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x37, 0x10, 0x07, 0x12, 0x0f, 0x0a, 0x0b, 0x44, 0x41,
- 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x38, 0x10, 0x08, 0x12, 0x0f, 0x0a, 0x0b, 0x44,
- 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x39, 0x10, 0x09, 0x12, 0x10, 0x0a, 0x0c,
- 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x31, 0x30, 0x10, 0x0a, 0x12, 0x10,
- 0x0a, 0x0c, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x31, 0x31, 0x10, 0x0b,
- 0x12, 0x10, 0x0a, 0x0c, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x31, 0x32,
- 0x10, 0x0c, 0x12, 0x10, 0x0a, 0x0c, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x5f,
- 0x31, 0x33, 0x10, 0x0d, 0x12, 0x10, 0x0a, 0x0c, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54,
- 0x45, 0x5f, 0x31, 0x34, 0x10, 0x0e, 0x12, 0x10, 0x0a, 0x0c, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52,
- 0x41, 0x54, 0x45, 0x5f, 0x31, 0x35, 0x10, 0x0f, 0x1a, 0x60, 0xea, 0xaa, 0x19, 0x0d, 0x10, 0x01,
- 0x2a, 0x09, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45, 0xf2, 0xaa, 0x19, 0x4b, 0x0a,
- 0x49, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65,
- 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74,
- 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74, 0x6e, 0x70, 0x62,
- 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x63,
- 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2a, 0xba, 0x02, 0x0a, 0x0e, 0x44,
- 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x16, 0x0a,
- 0x12, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x4f, 0x46, 0x46, 0x53, 0x45,
- 0x54, 0x5f, 0x30, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41,
- 0x54, 0x45, 0x5f, 0x4f, 0x46, 0x46, 0x53, 0x45, 0x54, 0x5f, 0x31, 0x10, 0x01, 0x12, 0x16, 0x0a,
- 0x12, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x4f, 0x46, 0x46, 0x53, 0x45,
- 0x54, 0x5f, 0x32, 0x10, 0x02, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41,
- 0x54, 0x45, 0x5f, 0x4f, 0x46, 0x46, 0x53, 0x45, 0x54, 0x5f, 0x33, 0x10, 0x03, 0x12, 0x16, 0x0a,
- 0x12, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x4f, 0x46, 0x46, 0x53, 0x45,
- 0x54, 0x5f, 0x34, 0x10, 0x04, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41,
- 0x54, 0x45, 0x5f, 0x4f, 0x46, 0x46, 0x53, 0x45, 0x54, 0x5f, 0x35, 0x10, 0x05, 0x12, 0x16, 0x0a,
- 0x12, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x4f, 0x46, 0x46, 0x53, 0x45,
- 0x54, 0x5f, 0x36, 0x10, 0x06, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41,
- 0x54, 0x45, 0x5f, 0x4f, 0x46, 0x46, 0x53, 0x45, 0x54, 0x5f, 0x37, 0x10, 0x07, 0x1a, 0x68, 0xea,
- 0xaa, 0x19, 0x14, 0x10, 0x01, 0x2a, 0x10, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45,
- 0x5f, 0x4f, 0x46, 0x46, 0x53, 0x45, 0x54, 0xf2, 0xaa, 0x19, 0x4c, 0x0a, 0x4a, 0x67, 0x6f, 0x2e,
- 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72,
- 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f,
- 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74, 0x6e, 0x70, 0x62, 0x2e, 0x44, 0x61, 0x74,
- 0x61, 0x52, 0x61, 0x74, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x5f, 0x63, 0x75, 0x73, 0x74,
- 0x6f, 0x6d, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2a, 0x5d, 0x0a, 0x0f, 0x4a, 0x6f, 0x69, 0x6e, 0x52,
- 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x45,
- 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x45, 0x58, 0x54, 0x10, 0x00, 0x12, 0x12,
- 0x0a, 0x0e, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e,
- 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x4b, 0x45, 0x59,
- 0x53, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x4a, 0x4f, 0x49, 0x4e, 0x10, 0xff, 0x01, 0x1a, 0x06,
- 0xea, 0xaa, 0x19, 0x02, 0x18, 0x01, 0x2a, 0x3f, 0x0a, 0x11, 0x52, 0x65, 0x6a, 0x6f, 0x69, 0x6e,
- 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x43,
- 0x4f, 0x4e, 0x54, 0x45, 0x58, 0x54, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x45, 0x53, 0x53,
- 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x4b, 0x45, 0x59, 0x53, 0x10, 0x02, 0x1a,
- 0x06, 0xea, 0xaa, 0x19, 0x02, 0x18, 0x01, 0x2a, 0x38, 0x0a, 0x0a, 0x43, 0x46, 0x4c, 0x69, 0x73,
- 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x46, 0x52, 0x45, 0x51, 0x55, 0x45, 0x4e,
- 0x43, 0x49, 0x45, 0x53, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x48, 0x41, 0x4e, 0x4e, 0x45,
- 0x4c, 0x5f, 0x4d, 0x41, 0x53, 0x4b, 0x53, 0x10, 0x01, 0x1a, 0x06, 0xea, 0xaa, 0x19, 0x02, 0x18,
- 0x01, 0x2a, 0x3d, 0x0a, 0x05, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4c,
- 0x41, 0x53, 0x53, 0x5f, 0x41, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4c, 0x41, 0x53, 0x53,
- 0x5f, 0x42, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4c, 0x41, 0x53, 0x53, 0x5f, 0x43, 0x10,
- 0x02, 0x1a, 0x0d, 0xea, 0xaa, 0x19, 0x09, 0x18, 0x01, 0x2a, 0x05, 0x43, 0x4c, 0x41, 0x53, 0x53,
- 0x2a, 0x78, 0x0a, 0x12, 0x54, 0x78, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x50, 0x72,
- 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x0a, 0x0a, 0x06, 0x4c, 0x4f, 0x57, 0x45, 0x53, 0x54,
- 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x4c, 0x4f, 0x57, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x42,
- 0x45, 0x4c, 0x4f, 0x57, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x02, 0x12, 0x0a, 0x0a,
- 0x06, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x41, 0x42, 0x4f,
- 0x56, 0x45, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x04, 0x12, 0x08, 0x0a, 0x04, 0x48,
- 0x49, 0x47, 0x48, 0x10, 0x05, 0x12, 0x0b, 0x0a, 0x07, 0x48, 0x49, 0x47, 0x48, 0x45, 0x53, 0x54,
- 0x10, 0x06, 0x1a, 0x06, 0xea, 0xaa, 0x19, 0x02, 0x18, 0x01, 0x2a, 0xe4, 0x03, 0x0a, 0x14, 0x4d,
- 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66,
- 0x69, 0x65, 0x72, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x49, 0x44, 0x5f, 0x52, 0x46, 0x55, 0x5f, 0x30,
- 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x49, 0x44, 0x5f, 0x52, 0x45, 0x53, 0x45, 0x54, 0x10,
- 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x49, 0x44, 0x5f, 0x4c, 0x49, 0x4e, 0x4b, 0x5f, 0x43, 0x48,
- 0x45, 0x43, 0x4b, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x43, 0x49, 0x44, 0x5f, 0x4c, 0x49, 0x4e,
- 0x4b, 0x5f, 0x41, 0x44, 0x52, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x49, 0x44, 0x5f, 0x44,
- 0x55, 0x54, 0x59, 0x5f, 0x43, 0x59, 0x43, 0x4c, 0x45, 0x10, 0x04, 0x12, 0x16, 0x0a, 0x12, 0x43,
- 0x49, 0x44, 0x5f, 0x52, 0x58, 0x5f, 0x50, 0x41, 0x52, 0x41, 0x4d, 0x5f, 0x53, 0x45, 0x54, 0x55,
- 0x50, 0x10, 0x05, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x49, 0x44, 0x5f, 0x44, 0x45, 0x56, 0x5f, 0x53,
- 0x54, 0x41, 0x54, 0x55, 0x53, 0x10, 0x06, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x49, 0x44, 0x5f, 0x4e,
- 0x45, 0x57, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x4e, 0x45, 0x4c, 0x10, 0x07, 0x12, 0x17, 0x0a, 0x13,
- 0x43, 0x49, 0x44, 0x5f, 0x52, 0x58, 0x5f, 0x54, 0x49, 0x4d, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x45,
- 0x54, 0x55, 0x50, 0x10, 0x08, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x49, 0x44, 0x5f, 0x54, 0x58, 0x5f,
- 0x50, 0x41, 0x52, 0x41, 0x4d, 0x5f, 0x53, 0x45, 0x54, 0x55, 0x50, 0x10, 0x09, 0x12, 0x12, 0x0a,
- 0x0e, 0x43, 0x49, 0x44, 0x5f, 0x44, 0x4c, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x4e, 0x45, 0x4c, 0x10,
- 0x0a, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x49, 0x44, 0x5f, 0x52, 0x45, 0x4b, 0x45, 0x59, 0x10, 0x0b,
- 0x12, 0x17, 0x0a, 0x13, 0x43, 0x49, 0x44, 0x5f, 0x41, 0x44, 0x52, 0x5f, 0x50, 0x41, 0x52, 0x41,
- 0x4d, 0x5f, 0x53, 0x45, 0x54, 0x55, 0x50, 0x10, 0x0c, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x49, 0x44,
- 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x10, 0x0d, 0x12, 0x14,
- 0x0a, 0x10, 0x43, 0x49, 0x44, 0x5f, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x5f, 0x52, 0x45, 0x4a, 0x4f,
- 0x49, 0x4e, 0x10, 0x0e, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x49, 0x44, 0x5f, 0x52, 0x45, 0x4a, 0x4f,
- 0x49, 0x4e, 0x5f, 0x50, 0x41, 0x52, 0x41, 0x4d, 0x5f, 0x53, 0x45, 0x54, 0x55, 0x50, 0x10, 0x0f,
- 0x12, 0x16, 0x0a, 0x12, 0x43, 0x49, 0x44, 0x5f, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x4c, 0x4f,
- 0x54, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x10, 0x12, 0x19, 0x0a, 0x15, 0x43, 0x49, 0x44, 0x5f,
- 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x4c, 0x4f, 0x54, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x4e, 0x45,
- 0x4c, 0x10, 0x11, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x49, 0x44, 0x5f, 0x42, 0x45, 0x41, 0x43, 0x4f,
- 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x49, 0x4e, 0x47, 0x10, 0x12, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x49,
- 0x44, 0x5f, 0x42, 0x45, 0x41, 0x43, 0x4f, 0x4e, 0x5f, 0x46, 0x52, 0x45, 0x51, 0x10, 0x13, 0x12,
- 0x13, 0x0a, 0x0f, 0x43, 0x49, 0x44, 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x4d, 0x4f,
- 0x44, 0x45, 0x10, 0x20, 0x1a, 0x0b, 0xea, 0xaa, 0x19, 0x07, 0x18, 0x01, 0x2a, 0x03, 0x43, 0x49,
- 0x44, 0x2a, 0xe6, 0x02, 0x0a, 0x13, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64,
- 0x44, 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x10, 0x0a, 0x0c, 0x44, 0x55, 0x54,
- 0x59, 0x5f, 0x43, 0x59, 0x43, 0x4c, 0x45, 0x5f, 0x31, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x44,
- 0x55, 0x54, 0x59, 0x5f, 0x43, 0x59, 0x43, 0x4c, 0x45, 0x5f, 0x32, 0x10, 0x01, 0x12, 0x10, 0x0a,
- 0x0c, 0x44, 0x55, 0x54, 0x59, 0x5f, 0x43, 0x59, 0x43, 0x4c, 0x45, 0x5f, 0x34, 0x10, 0x02, 0x12,
- 0x10, 0x0a, 0x0c, 0x44, 0x55, 0x54, 0x59, 0x5f, 0x43, 0x59, 0x43, 0x4c, 0x45, 0x5f, 0x38, 0x10,
- 0x03, 0x12, 0x11, 0x0a, 0x0d, 0x44, 0x55, 0x54, 0x59, 0x5f, 0x43, 0x59, 0x43, 0x4c, 0x45, 0x5f,
- 0x31, 0x36, 0x10, 0x04, 0x12, 0x11, 0x0a, 0x0d, 0x44, 0x55, 0x54, 0x59, 0x5f, 0x43, 0x59, 0x43,
- 0x4c, 0x45, 0x5f, 0x33, 0x32, 0x10, 0x05, 0x12, 0x11, 0x0a, 0x0d, 0x44, 0x55, 0x54, 0x59, 0x5f,
- 0x43, 0x59, 0x43, 0x4c, 0x45, 0x5f, 0x36, 0x34, 0x10, 0x06, 0x12, 0x12, 0x0a, 0x0e, 0x44, 0x55,
- 0x54, 0x59, 0x5f, 0x43, 0x59, 0x43, 0x4c, 0x45, 0x5f, 0x31, 0x32, 0x38, 0x10, 0x07, 0x12, 0x12,
- 0x0a, 0x0e, 0x44, 0x55, 0x54, 0x59, 0x5f, 0x43, 0x59, 0x43, 0x4c, 0x45, 0x5f, 0x32, 0x35, 0x36,
- 0x10, 0x08, 0x12, 0x12, 0x0a, 0x0e, 0x44, 0x55, 0x54, 0x59, 0x5f, 0x43, 0x59, 0x43, 0x4c, 0x45,
- 0x5f, 0x35, 0x31, 0x32, 0x10, 0x09, 0x12, 0x13, 0x0a, 0x0f, 0x44, 0x55, 0x54, 0x59, 0x5f, 0x43,
- 0x59, 0x43, 0x4c, 0x45, 0x5f, 0x31, 0x30, 0x32, 0x34, 0x10, 0x0a, 0x12, 0x13, 0x0a, 0x0f, 0x44,
- 0x55, 0x54, 0x59, 0x5f, 0x43, 0x59, 0x43, 0x4c, 0x45, 0x5f, 0x32, 0x30, 0x34, 0x38, 0x10, 0x0b,
- 0x12, 0x13, 0x0a, 0x0f, 0x44, 0x55, 0x54, 0x59, 0x5f, 0x43, 0x59, 0x43, 0x4c, 0x45, 0x5f, 0x34,
- 0x30, 0x39, 0x36, 0x10, 0x0c, 0x12, 0x13, 0x0a, 0x0f, 0x44, 0x55, 0x54, 0x59, 0x5f, 0x43, 0x59,
- 0x43, 0x4c, 0x45, 0x5f, 0x38, 0x31, 0x39, 0x32, 0x10, 0x0d, 0x12, 0x14, 0x0a, 0x10, 0x44, 0x55,
- 0x54, 0x59, 0x5f, 0x43, 0x59, 0x43, 0x4c, 0x45, 0x5f, 0x31, 0x36, 0x33, 0x38, 0x34, 0x10, 0x0e,
- 0x12, 0x14, 0x0a, 0x10, 0x44, 0x55, 0x54, 0x59, 0x5f, 0x43, 0x59, 0x43, 0x4c, 0x45, 0x5f, 0x33,
- 0x32, 0x37, 0x36, 0x38, 0x10, 0x0f, 0x1a, 0x12, 0xea, 0xaa, 0x19, 0x0e, 0x18, 0x01, 0x2a, 0x0a,
- 0x44, 0x55, 0x54, 0x59, 0x5f, 0x43, 0x59, 0x43, 0x4c, 0x45, 0x2a, 0xc1, 0x01, 0x0a, 0x0e, 0x50,
- 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x12, 0x11, 0x0a,
- 0x0d, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x45, 0x56, 0x45, 0x52, 0x59, 0x5f, 0x31, 0x53, 0x10, 0x00,
- 0x12, 0x11, 0x0a, 0x0d, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x45, 0x56, 0x45, 0x52, 0x59, 0x5f, 0x32,
- 0x53, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x45, 0x56, 0x45, 0x52,
- 0x59, 0x5f, 0x34, 0x53, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x45,
- 0x56, 0x45, 0x52, 0x59, 0x5f, 0x38, 0x53, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x50, 0x49, 0x4e,
- 0x47, 0x5f, 0x45, 0x56, 0x45, 0x52, 0x59, 0x5f, 0x31, 0x36, 0x53, 0x10, 0x04, 0x12, 0x12, 0x0a,
- 0x0e, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x45, 0x56, 0x45, 0x52, 0x59, 0x5f, 0x33, 0x32, 0x53, 0x10,
- 0x05, 0x12, 0x12, 0x0a, 0x0e, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x45, 0x56, 0x45, 0x52, 0x59, 0x5f,
- 0x36, 0x34, 0x53, 0x10, 0x06, 0x12, 0x13, 0x0a, 0x0f, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x45, 0x56,
- 0x45, 0x52, 0x59, 0x5f, 0x31, 0x32, 0x38, 0x53, 0x10, 0x07, 0x1a, 0x12, 0xea, 0xaa, 0x19, 0x0e,
- 0x18, 0x01, 0x2a, 0x0a, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x45, 0x56, 0x45, 0x52, 0x59, 0x2a, 0x9b,
- 0x03, 0x0a, 0x13, 0x52, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x45, 0x78,
+ 0x67, 0x2f, 0x74, 0x74, 0x6e, 0x70, 0x62, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65,
+ 0x49, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x76, 0x61, 0x6c, 0x75,
+ 0x65, 0x2a, 0xba, 0x02, 0x0a, 0x0e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x4f, 0x66,
+ 0x66, 0x73, 0x65, 0x74, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54,
+ 0x45, 0x5f, 0x4f, 0x46, 0x46, 0x53, 0x45, 0x54, 0x5f, 0x30, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12,
+ 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x4f, 0x46, 0x46, 0x53, 0x45, 0x54,
+ 0x5f, 0x31, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54,
+ 0x45, 0x5f, 0x4f, 0x46, 0x46, 0x53, 0x45, 0x54, 0x5f, 0x32, 0x10, 0x02, 0x12, 0x16, 0x0a, 0x12,
+ 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x4f, 0x46, 0x46, 0x53, 0x45, 0x54,
+ 0x5f, 0x33, 0x10, 0x03, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54,
+ 0x45, 0x5f, 0x4f, 0x46, 0x46, 0x53, 0x45, 0x54, 0x5f, 0x34, 0x10, 0x04, 0x12, 0x16, 0x0a, 0x12,
+ 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x4f, 0x46, 0x46, 0x53, 0x45, 0x54,
+ 0x5f, 0x35, 0x10, 0x05, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54,
+ 0x45, 0x5f, 0x4f, 0x46, 0x46, 0x53, 0x45, 0x54, 0x5f, 0x36, 0x10, 0x06, 0x12, 0x16, 0x0a, 0x12,
+ 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x4f, 0x46, 0x46, 0x53, 0x45, 0x54,
+ 0x5f, 0x37, 0x10, 0x07, 0x1a, 0x68, 0xea, 0xaa, 0x19, 0x14, 0x10, 0x01, 0x2a, 0x10, 0x44, 0x41,
+ 0x54, 0x41, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x5f, 0x4f, 0x46, 0x46, 0x53, 0x45, 0x54, 0xf2, 0xaa,
+ 0x19, 0x4c, 0x0a, 0x4a, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73,
+ 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
+ 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74,
+ 0x6e, 0x70, 0x62, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x4f, 0x66, 0x66, 0x73,
+ 0x65, 0x74, 0x5f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2a, 0x5d,
+ 0x0a, 0x0f, 0x4a, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70,
+ 0x65, 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x4e, 0x54,
+ 0x45, 0x58, 0x54, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f,
+ 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x52, 0x45, 0x4a,
+ 0x4f, 0x49, 0x4e, 0x5f, 0x4b, 0x45, 0x59, 0x53, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x4a, 0x4f,
+ 0x49, 0x4e, 0x10, 0xff, 0x01, 0x1a, 0x06, 0xea, 0xaa, 0x19, 0x02, 0x18, 0x01, 0x2a, 0x3f, 0x0a,
+ 0x11, 0x52, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79,
+ 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4f, 0x4e, 0x54, 0x45, 0x58, 0x54, 0x10, 0x00, 0x12,
+ 0x0b, 0x0a, 0x07, 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04,
+ 0x4b, 0x45, 0x59, 0x53, 0x10, 0x02, 0x1a, 0x06, 0xea, 0xaa, 0x19, 0x02, 0x18, 0x01, 0x2a, 0x38,
+ 0x0a, 0x0a, 0x43, 0x46, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0f, 0x0a, 0x0b,
+ 0x46, 0x52, 0x45, 0x51, 0x55, 0x45, 0x4e, 0x43, 0x49, 0x45, 0x53, 0x10, 0x00, 0x12, 0x11, 0x0a,
+ 0x0d, 0x43, 0x48, 0x41, 0x4e, 0x4e, 0x45, 0x4c, 0x5f, 0x4d, 0x41, 0x53, 0x4b, 0x53, 0x10, 0x01,
+ 0x1a, 0x06, 0xea, 0xaa, 0x19, 0x02, 0x18, 0x01, 0x2a, 0x3d, 0x0a, 0x05, 0x43, 0x6c, 0x61, 0x73,
+ 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4c, 0x41, 0x53, 0x53, 0x5f, 0x41, 0x10, 0x00, 0x12, 0x0b,
+ 0x0a, 0x07, 0x43, 0x4c, 0x41, 0x53, 0x53, 0x5f, 0x42, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x43,
+ 0x4c, 0x41, 0x53, 0x53, 0x5f, 0x43, 0x10, 0x02, 0x1a, 0x0d, 0xea, 0xaa, 0x19, 0x09, 0x18, 0x01,
+ 0x2a, 0x05, 0x43, 0x4c, 0x41, 0x53, 0x53, 0x2a, 0x78, 0x0a, 0x12, 0x54, 0x78, 0x53, 0x63, 0x68,
+ 0x65, 0x64, 0x75, 0x6c, 0x65, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x0a, 0x0a,
+ 0x06, 0x4c, 0x4f, 0x57, 0x45, 0x53, 0x54, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x4c, 0x4f, 0x57,
+ 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x42, 0x45, 0x4c, 0x4f, 0x57, 0x5f, 0x4e, 0x4f, 0x52, 0x4d,
+ 0x41, 0x4c, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x03,
+ 0x12, 0x10, 0x0a, 0x0c, 0x41, 0x42, 0x4f, 0x56, 0x45, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c,
+ 0x10, 0x04, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x49, 0x47, 0x48, 0x10, 0x05, 0x12, 0x0b, 0x0a, 0x07,
+ 0x48, 0x49, 0x47, 0x48, 0x45, 0x53, 0x54, 0x10, 0x06, 0x1a, 0x06, 0xea, 0xaa, 0x19, 0x02, 0x18,
+ 0x01, 0x2a, 0xbc, 0x05, 0x0a, 0x14, 0x4d, 0x41, 0x43, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64,
+ 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x49,
+ 0x44, 0x5f, 0x52, 0x46, 0x55, 0x5f, 0x30, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x49, 0x44,
+ 0x5f, 0x52, 0x45, 0x53, 0x45, 0x54, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x49, 0x44, 0x5f,
+ 0x4c, 0x49, 0x4e, 0x4b, 0x5f, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c,
+ 0x43, 0x49, 0x44, 0x5f, 0x4c, 0x49, 0x4e, 0x4b, 0x5f, 0x41, 0x44, 0x52, 0x10, 0x03, 0x12, 0x12,
+ 0x0a, 0x0e, 0x43, 0x49, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x59, 0x5f, 0x43, 0x59, 0x43, 0x4c, 0x45,
+ 0x10, 0x04, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x49, 0x44, 0x5f, 0x52, 0x58, 0x5f, 0x50, 0x41, 0x52,
+ 0x41, 0x4d, 0x5f, 0x53, 0x45, 0x54, 0x55, 0x50, 0x10, 0x05, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x49,
+ 0x44, 0x5f, 0x44, 0x45, 0x56, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x10, 0x06, 0x12, 0x13,
+ 0x0a, 0x0f, 0x43, 0x49, 0x44, 0x5f, 0x4e, 0x45, 0x57, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x4e, 0x45,
+ 0x4c, 0x10, 0x07, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x49, 0x44, 0x5f, 0x52, 0x58, 0x5f, 0x54, 0x49,
+ 0x4d, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x45, 0x54, 0x55, 0x50, 0x10, 0x08, 0x12, 0x16, 0x0a, 0x12,
+ 0x43, 0x49, 0x44, 0x5f, 0x54, 0x58, 0x5f, 0x50, 0x41, 0x52, 0x41, 0x4d, 0x5f, 0x53, 0x45, 0x54,
+ 0x55, 0x50, 0x10, 0x09, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x49, 0x44, 0x5f, 0x44, 0x4c, 0x5f, 0x43,
+ 0x48, 0x41, 0x4e, 0x4e, 0x45, 0x4c, 0x10, 0x0a, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x49, 0x44, 0x5f,
+ 0x52, 0x45, 0x4b, 0x45, 0x59, 0x10, 0x0b, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x49, 0x44, 0x5f, 0x41,
+ 0x44, 0x52, 0x5f, 0x50, 0x41, 0x52, 0x41, 0x4d, 0x5f, 0x53, 0x45, 0x54, 0x55, 0x50, 0x10, 0x0c,
+ 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x49, 0x44, 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x54,
+ 0x49, 0x4d, 0x45, 0x10, 0x0d, 0x12, 0x14, 0x0a, 0x10, 0x43, 0x49, 0x44, 0x5f, 0x46, 0x4f, 0x52,
+ 0x43, 0x45, 0x5f, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x10, 0x0e, 0x12, 0x1a, 0x0a, 0x16, 0x43,
+ 0x49, 0x44, 0x5f, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x50, 0x41, 0x52, 0x41, 0x4d, 0x5f,
+ 0x53, 0x45, 0x54, 0x55, 0x50, 0x10, 0x0f, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x49, 0x44, 0x5f, 0x50,
+ 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x4c, 0x4f, 0x54, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x10, 0x12,
+ 0x19, 0x0a, 0x15, 0x43, 0x49, 0x44, 0x5f, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x4c, 0x4f, 0x54,
+ 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x4e, 0x45, 0x4c, 0x10, 0x11, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x49,
+ 0x44, 0x5f, 0x42, 0x45, 0x41, 0x43, 0x4f, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x49, 0x4e, 0x47, 0x10,
+ 0x12, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x49, 0x44, 0x5f, 0x42, 0x45, 0x41, 0x43, 0x4f, 0x4e, 0x5f,
+ 0x46, 0x52, 0x45, 0x51, 0x10, 0x13, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x49, 0x44, 0x5f, 0x44, 0x45,
+ 0x56, 0x49, 0x43, 0x45, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x10, 0x20, 0x12, 0x12, 0x0a, 0x0e, 0x43,
+ 0x49, 0x44, 0x5f, 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x10, 0x40, 0x12,
+ 0x1d, 0x0a, 0x19, 0x43, 0x49, 0x44, 0x5f, 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x45, 0x4e, 0x44,
+ 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x10, 0x41, 0x12, 0x19,
+ 0x0a, 0x15, 0x43, 0x49, 0x44, 0x5f, 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x46, 0x49, 0x4c, 0x54,
+ 0x45, 0x52, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x42, 0x12, 0x20, 0x0a, 0x1c, 0x43, 0x49, 0x44,
+ 0x5f, 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x50,
+ 0x4c, 0x49, 0x4e, 0x4b, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x43, 0x12, 0x1e, 0x0a, 0x1a, 0x43,
+ 0x49, 0x44, 0x5f, 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x43, 0x54, 0x52, 0x4c, 0x5f, 0x55, 0x50,
+ 0x4c, 0x49, 0x4e, 0x4b, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x44, 0x12, 0x21, 0x0a, 0x1d, 0x43,
+ 0x49, 0x44, 0x5f, 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x55,
+ 0x52, 0x45, 0x5f, 0x46, 0x57, 0x44, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x10, 0x45, 0x12, 0x23,
+ 0x0a, 0x1f, 0x43, 0x49, 0x44, 0x5f, 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x4e, 0x4f, 0x54, 0x49,
+ 0x46, 0x59, 0x5f, 0x4e, 0x45, 0x57, 0x5f, 0x45, 0x4e, 0x44, 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43,
+ 0x45, 0x10, 0x46, 0x1a, 0x0b, 0xea, 0xaa, 0x19, 0x07, 0x18, 0x01, 0x2a, 0x03, 0x43, 0x49, 0x44,
+ 0x2a, 0xb2, 0x02, 0x0a, 0x13, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x43, 0x41, 0x44, 0x50, 0x65, 0x72,
+ 0x69, 0x6f, 0x64, 0x69, 0x63, 0x69, 0x74, 0x79, 0x12, 0x22, 0x0a, 0x1e, 0x52, 0x45, 0x4c, 0x41,
+ 0x59, 0x5f, 0x43, 0x41, 0x44, 0x5f, 0x50, 0x45, 0x52, 0x49, 0x4f, 0x44, 0x49, 0x43, 0x49, 0x54,
+ 0x59, 0x5f, 0x31, 0x5f, 0x53, 0x45, 0x43, 0x4f, 0x4e, 0x44, 0x10, 0x00, 0x12, 0x2a, 0x0a, 0x26,
+ 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x43, 0x41, 0x44, 0x5f, 0x50, 0x45, 0x52, 0x49, 0x4f, 0x44,
+ 0x49, 0x43, 0x49, 0x54, 0x59, 0x5f, 0x35, 0x30, 0x30, 0x5f, 0x4d, 0x49, 0x4c, 0x4c, 0x49, 0x53,
+ 0x45, 0x43, 0x4f, 0x4e, 0x44, 0x53, 0x10, 0x01, 0x12, 0x2a, 0x0a, 0x26, 0x52, 0x45, 0x4c, 0x41,
+ 0x59, 0x5f, 0x43, 0x41, 0x44, 0x5f, 0x50, 0x45, 0x52, 0x49, 0x4f, 0x44, 0x49, 0x43, 0x49, 0x54,
+ 0x59, 0x5f, 0x32, 0x35, 0x30, 0x5f, 0x4d, 0x49, 0x4c, 0x4c, 0x49, 0x53, 0x45, 0x43, 0x4f, 0x4e,
+ 0x44, 0x53, 0x10, 0x02, 0x12, 0x2a, 0x0a, 0x26, 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x43, 0x41,
+ 0x44, 0x5f, 0x50, 0x45, 0x52, 0x49, 0x4f, 0x44, 0x49, 0x43, 0x49, 0x54, 0x59, 0x5f, 0x31, 0x30,
+ 0x30, 0x5f, 0x4d, 0x49, 0x4c, 0x4c, 0x49, 0x53, 0x45, 0x43, 0x4f, 0x4e, 0x44, 0x53, 0x10, 0x03,
+ 0x12, 0x29, 0x0a, 0x25, 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x43, 0x41, 0x44, 0x5f, 0x50, 0x45,
+ 0x52, 0x49, 0x4f, 0x44, 0x49, 0x43, 0x49, 0x54, 0x59, 0x5f, 0x35, 0x30, 0x5f, 0x4d, 0x49, 0x4c,
+ 0x4c, 0x49, 0x53, 0x45, 0x43, 0x4f, 0x4e, 0x44, 0x53, 0x10, 0x04, 0x12, 0x29, 0x0a, 0x25, 0x52,
+ 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x43, 0x41, 0x44, 0x5f, 0x50, 0x45, 0x52, 0x49, 0x4f, 0x44, 0x49,
+ 0x43, 0x49, 0x54, 0x59, 0x5f, 0x32, 0x30, 0x5f, 0x4d, 0x49, 0x4c, 0x4c, 0x49, 0x53, 0x45, 0x43,
+ 0x4f, 0x4e, 0x44, 0x53, 0x10, 0x05, 0x1a, 0x1d, 0xea, 0xaa, 0x19, 0x19, 0x18, 0x01, 0x2a, 0x15,
+ 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x43, 0x41, 0x44, 0x5f, 0x50, 0x45, 0x52, 0x49, 0x4f, 0x44,
+ 0x49, 0x43, 0x49, 0x54, 0x59, 0x2a, 0x94, 0x02, 0x0a, 0x16, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x53,
+ 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x43, 0x68, 0x41, 0x63, 0x6b, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74,
+ 0x12, 0x20, 0x0a, 0x1c, 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x53, 0x45, 0x43, 0x4f, 0x4e, 0x44,
+ 0x5f, 0x43, 0x48, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x4f, 0x46, 0x46, 0x53, 0x45, 0x54, 0x5f, 0x30,
+ 0x10, 0x00, 0x12, 0x22, 0x0a, 0x1e, 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x53, 0x45, 0x43, 0x4f,
+ 0x4e, 0x44, 0x5f, 0x43, 0x48, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x4f, 0x46, 0x46, 0x53, 0x45, 0x54,
+ 0x5f, 0x32, 0x30, 0x30, 0x10, 0x01, 0x12, 0x22, 0x0a, 0x1e, 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f,
+ 0x53, 0x45, 0x43, 0x4f, 0x4e, 0x44, 0x5f, 0x43, 0x48, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x4f, 0x46,
+ 0x46, 0x53, 0x45, 0x54, 0x5f, 0x34, 0x30, 0x30, 0x10, 0x02, 0x12, 0x22, 0x0a, 0x1e, 0x52, 0x45,
+ 0x4c, 0x41, 0x59, 0x5f, 0x53, 0x45, 0x43, 0x4f, 0x4e, 0x44, 0x5f, 0x43, 0x48, 0x5f, 0x41, 0x43,
+ 0x4b, 0x5f, 0x4f, 0x46, 0x46, 0x53, 0x45, 0x54, 0x5f, 0x38, 0x30, 0x30, 0x10, 0x03, 0x12, 0x23,
+ 0x0a, 0x1f, 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x53, 0x45, 0x43, 0x4f, 0x4e, 0x44, 0x5f, 0x43,
+ 0x48, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x4f, 0x46, 0x46, 0x53, 0x45, 0x54, 0x5f, 0x31, 0x36, 0x30,
+ 0x30, 0x10, 0x04, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x53, 0x45, 0x43,
+ 0x4f, 0x4e, 0x44, 0x5f, 0x43, 0x48, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x4f, 0x46, 0x46, 0x53, 0x45,
+ 0x54, 0x5f, 0x33, 0x32, 0x30, 0x30, 0x10, 0x05, 0x1a, 0x22, 0xea, 0xaa, 0x19, 0x1e, 0x18, 0x01,
+ 0x2a, 0x1a, 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x53, 0x45, 0x43, 0x4f, 0x4e, 0x44, 0x5f, 0x43,
+ 0x48, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x4f, 0x46, 0x46, 0x53, 0x45, 0x54, 0x2a, 0xb4, 0x01, 0x0a,
+ 0x14, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x42, 0x75, 0x63, 0x6b, 0x65,
+ 0x74, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x4c,
+ 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x42, 0x55, 0x43, 0x4b, 0x45, 0x54, 0x5f, 0x53, 0x49, 0x5a, 0x45,
+ 0x5f, 0x31, 0x10, 0x00, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x4c, 0x49,
+ 0x4d, 0x49, 0x54, 0x5f, 0x42, 0x55, 0x43, 0x4b, 0x45, 0x54, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f,
+ 0x32, 0x10, 0x01, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x4c, 0x49, 0x4d,
+ 0x49, 0x54, 0x5f, 0x42, 0x55, 0x43, 0x4b, 0x45, 0x54, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x34,
+ 0x10, 0x02, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x4c, 0x49, 0x4d, 0x49,
+ 0x54, 0x5f, 0x42, 0x55, 0x43, 0x4b, 0x45, 0x54, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x31, 0x32,
+ 0x10, 0x03, 0x1a, 0x1f, 0xea, 0xaa, 0x19, 0x1b, 0x18, 0x01, 0x2a, 0x17, 0x52, 0x45, 0x4c, 0x41,
+ 0x59, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x42, 0x55, 0x43, 0x4b, 0x45, 0x54, 0x5f, 0x53,
+ 0x49, 0x5a, 0x45, 0x2a, 0xbc, 0x01, 0x0a, 0x15, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x53, 0x6d, 0x61,
+ 0x72, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x1e, 0x0a,
+ 0x1a, 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x53, 0x4d, 0x41, 0x52, 0x54, 0x5f, 0x45, 0x4e, 0x41,
+ 0x42, 0x4c, 0x45, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x38, 0x10, 0x00, 0x12, 0x1f, 0x0a,
+ 0x1b, 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x53, 0x4d, 0x41, 0x52, 0x54, 0x5f, 0x45, 0x4e, 0x41,
+ 0x42, 0x4c, 0x45, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x31, 0x36, 0x10, 0x01, 0x12, 0x1f,
+ 0x0a, 0x1b, 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x53, 0x4d, 0x41, 0x52, 0x54, 0x5f, 0x45, 0x4e,
+ 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x33, 0x32, 0x10, 0x02, 0x12,
+ 0x1f, 0x0a, 0x1b, 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x53, 0x4d, 0x41, 0x52, 0x54, 0x5f, 0x45,
+ 0x4e, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x36, 0x34, 0x10, 0x03,
+ 0x1a, 0x20, 0xea, 0xaa, 0x19, 0x1c, 0x18, 0x01, 0x2a, 0x18, 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f,
+ 0x53, 0x4d, 0x41, 0x52, 0x54, 0x5f, 0x45, 0x4e, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x4c, 0x45, 0x56,
+ 0x45, 0x4c, 0x2a, 0x6c, 0x0a, 0x0f, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x57, 0x4f, 0x52, 0x43, 0x68,
+ 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x57,
+ 0x4f, 0x52, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x4e, 0x45, 0x4c, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55,
+ 0x4c, 0x54, 0x10, 0x00, 0x12, 0x1f, 0x0a, 0x1b, 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x57, 0x4f,
+ 0x52, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x4e, 0x45, 0x4c, 0x5f, 0x53, 0x45, 0x43, 0x4f, 0x4e, 0x44,
+ 0x41, 0x52, 0x59, 0x10, 0x01, 0x1a, 0x19, 0xea, 0xaa, 0x19, 0x15, 0x18, 0x01, 0x2a, 0x11, 0x52,
+ 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x57, 0x4f, 0x52, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x4e, 0x45, 0x4c,
+ 0x2a, 0xdb, 0x01, 0x0a, 0x16, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x52, 0x65, 0x73, 0x65, 0x74, 0x4c,
+ 0x69, 0x6d, 0x69, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x1e, 0x52,
+ 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x52, 0x45, 0x53, 0x45, 0x54, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54,
+ 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x5a, 0x45, 0x52, 0x4f, 0x10, 0x00, 0x12,
+ 0x29, 0x0a, 0x25, 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x52, 0x45, 0x53, 0x45, 0x54, 0x5f, 0x4c,
+ 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x4c,
+ 0x4f, 0x41, 0x44, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x10, 0x01, 0x12, 0x27, 0x0a, 0x23, 0x52, 0x45,
+ 0x4c, 0x41, 0x59, 0x5f, 0x52, 0x45, 0x53, 0x45, 0x54, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f,
+ 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x4d, 0x41, 0x58, 0x5f, 0x56, 0x41, 0x4c, 0x55,
+ 0x45, 0x10, 0x02, 0x12, 0x26, 0x0a, 0x22, 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x52, 0x45, 0x53,
+ 0x45, 0x54, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52,
+ 0x5f, 0x4e, 0x4f, 0x5f, 0x52, 0x45, 0x53, 0x45, 0x54, 0x10, 0x03, 0x1a, 0x21, 0xea, 0xaa, 0x19,
+ 0x1d, 0x18, 0x01, 0x2a, 0x19, 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x52, 0x45, 0x53, 0x45, 0x54,
+ 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x2a, 0xaf,
+ 0x01, 0x0a, 0x19, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x43, 0x74, 0x72, 0x6c, 0x55, 0x70, 0x6c, 0x69,
+ 0x6e, 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x2a,
+ 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x43, 0x54, 0x52, 0x4c, 0x5f, 0x55, 0x50, 0x4c, 0x49, 0x4e,
+ 0x4b, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45,
+ 0x41, 0x44, 0x5f, 0x57, 0x5f, 0x46, 0x5f, 0x43, 0x4e, 0x54, 0x10, 0x00, 0x12, 0x3b, 0x0a, 0x37,
+ 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x43, 0x54, 0x52, 0x4c, 0x5f, 0x55, 0x50, 0x4c, 0x49, 0x4e,
+ 0x4b, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45,
+ 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x52, 0x55, 0x53, 0x54, 0x45, 0x44, 0x5f, 0x45, 0x4e, 0x44,
+ 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x10, 0x01, 0x1a, 0x25, 0xea, 0xaa, 0x19, 0x21, 0x18,
+ 0x01, 0x2a, 0x1d, 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x43, 0x54, 0x52, 0x4c, 0x5f, 0x55, 0x50,
+ 0x4c, 0x49, 0x4e, 0x4b, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e,
+ 0x2a, 0xe6, 0x02, 0x0a, 0x13, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x44,
+ 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x10, 0x0a, 0x0c, 0x44, 0x55, 0x54, 0x59,
+ 0x5f, 0x43, 0x59, 0x43, 0x4c, 0x45, 0x5f, 0x31, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x44, 0x55,
+ 0x54, 0x59, 0x5f, 0x43, 0x59, 0x43, 0x4c, 0x45, 0x5f, 0x32, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c,
+ 0x44, 0x55, 0x54, 0x59, 0x5f, 0x43, 0x59, 0x43, 0x4c, 0x45, 0x5f, 0x34, 0x10, 0x02, 0x12, 0x10,
+ 0x0a, 0x0c, 0x44, 0x55, 0x54, 0x59, 0x5f, 0x43, 0x59, 0x43, 0x4c, 0x45, 0x5f, 0x38, 0x10, 0x03,
+ 0x12, 0x11, 0x0a, 0x0d, 0x44, 0x55, 0x54, 0x59, 0x5f, 0x43, 0x59, 0x43, 0x4c, 0x45, 0x5f, 0x31,
+ 0x36, 0x10, 0x04, 0x12, 0x11, 0x0a, 0x0d, 0x44, 0x55, 0x54, 0x59, 0x5f, 0x43, 0x59, 0x43, 0x4c,
+ 0x45, 0x5f, 0x33, 0x32, 0x10, 0x05, 0x12, 0x11, 0x0a, 0x0d, 0x44, 0x55, 0x54, 0x59, 0x5f, 0x43,
+ 0x59, 0x43, 0x4c, 0x45, 0x5f, 0x36, 0x34, 0x10, 0x06, 0x12, 0x12, 0x0a, 0x0e, 0x44, 0x55, 0x54,
+ 0x59, 0x5f, 0x43, 0x59, 0x43, 0x4c, 0x45, 0x5f, 0x31, 0x32, 0x38, 0x10, 0x07, 0x12, 0x12, 0x0a,
+ 0x0e, 0x44, 0x55, 0x54, 0x59, 0x5f, 0x43, 0x59, 0x43, 0x4c, 0x45, 0x5f, 0x32, 0x35, 0x36, 0x10,
+ 0x08, 0x12, 0x12, 0x0a, 0x0e, 0x44, 0x55, 0x54, 0x59, 0x5f, 0x43, 0x59, 0x43, 0x4c, 0x45, 0x5f,
+ 0x35, 0x31, 0x32, 0x10, 0x09, 0x12, 0x13, 0x0a, 0x0f, 0x44, 0x55, 0x54, 0x59, 0x5f, 0x43, 0x59,
+ 0x43, 0x4c, 0x45, 0x5f, 0x31, 0x30, 0x32, 0x34, 0x10, 0x0a, 0x12, 0x13, 0x0a, 0x0f, 0x44, 0x55,
+ 0x54, 0x59, 0x5f, 0x43, 0x59, 0x43, 0x4c, 0x45, 0x5f, 0x32, 0x30, 0x34, 0x38, 0x10, 0x0b, 0x12,
+ 0x13, 0x0a, 0x0f, 0x44, 0x55, 0x54, 0x59, 0x5f, 0x43, 0x59, 0x43, 0x4c, 0x45, 0x5f, 0x34, 0x30,
+ 0x39, 0x36, 0x10, 0x0c, 0x12, 0x13, 0x0a, 0x0f, 0x44, 0x55, 0x54, 0x59, 0x5f, 0x43, 0x59, 0x43,
+ 0x4c, 0x45, 0x5f, 0x38, 0x31, 0x39, 0x32, 0x10, 0x0d, 0x12, 0x14, 0x0a, 0x10, 0x44, 0x55, 0x54,
+ 0x59, 0x5f, 0x43, 0x59, 0x43, 0x4c, 0x45, 0x5f, 0x31, 0x36, 0x33, 0x38, 0x34, 0x10, 0x0e, 0x12,
+ 0x14, 0x0a, 0x10, 0x44, 0x55, 0x54, 0x59, 0x5f, 0x43, 0x59, 0x43, 0x4c, 0x45, 0x5f, 0x33, 0x32,
+ 0x37, 0x36, 0x38, 0x10, 0x0f, 0x1a, 0x12, 0xea, 0xaa, 0x19, 0x0e, 0x18, 0x01, 0x2a, 0x0a, 0x44,
+ 0x55, 0x54, 0x59, 0x5f, 0x43, 0x59, 0x43, 0x4c, 0x45, 0x2a, 0xc1, 0x01, 0x0a, 0x0e, 0x50, 0x69,
+ 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x12, 0x11, 0x0a, 0x0d,
+ 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x45, 0x56, 0x45, 0x52, 0x59, 0x5f, 0x31, 0x53, 0x10, 0x00, 0x12,
+ 0x11, 0x0a, 0x0d, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x45, 0x56, 0x45, 0x52, 0x59, 0x5f, 0x32, 0x53,
+ 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x45, 0x56, 0x45, 0x52, 0x59,
+ 0x5f, 0x34, 0x53, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x45, 0x56,
+ 0x45, 0x52, 0x59, 0x5f, 0x38, 0x53, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x50, 0x49, 0x4e, 0x47,
+ 0x5f, 0x45, 0x56, 0x45, 0x52, 0x59, 0x5f, 0x31, 0x36, 0x53, 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e,
+ 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x45, 0x56, 0x45, 0x52, 0x59, 0x5f, 0x33, 0x32, 0x53, 0x10, 0x05,
+ 0x12, 0x12, 0x0a, 0x0e, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x45, 0x56, 0x45, 0x52, 0x59, 0x5f, 0x36,
+ 0x34, 0x53, 0x10, 0x06, 0x12, 0x13, 0x0a, 0x0f, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x45, 0x56, 0x45,
+ 0x52, 0x59, 0x5f, 0x31, 0x32, 0x38, 0x53, 0x10, 0x07, 0x1a, 0x12, 0xea, 0xaa, 0x19, 0x0e, 0x18,
+ 0x01, 0x2a, 0x0a, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x45, 0x56, 0x45, 0x52, 0x59, 0x2a, 0x9b, 0x03,
+ 0x0a, 0x13, 0x52, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x45, 0x78, 0x70,
+ 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f,
+ 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x31, 0x36, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x45,
+ 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x33, 0x32, 0x10, 0x01, 0x12,
+ 0x13, 0x0a, 0x0f, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f,
+ 0x36, 0x34, 0x10, 0x02, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x43,
+ 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x31, 0x32, 0x38, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x45,
+ 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x32, 0x35, 0x36, 0x10, 0x04,
+ 0x12, 0x14, 0x0a, 0x10, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54,
+ 0x5f, 0x35, 0x31, 0x32, 0x10, 0x05, 0x12, 0x15, 0x0a, 0x11, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e,
+ 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x31, 0x30, 0x32, 0x34, 0x10, 0x06, 0x12, 0x15, 0x0a,
+ 0x11, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x32, 0x30,
+ 0x34, 0x38, 0x10, 0x07, 0x12, 0x15, 0x0a, 0x11, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x43,
+ 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x34, 0x30, 0x39, 0x36, 0x10, 0x08, 0x12, 0x15, 0x0a, 0x11, 0x52,
+ 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x38, 0x31, 0x39, 0x32,
+ 0x10, 0x09, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55,
+ 0x4e, 0x54, 0x5f, 0x31, 0x36, 0x33, 0x38, 0x34, 0x10, 0x0a, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x45,
+ 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x33, 0x32, 0x37, 0x36, 0x38,
+ 0x10, 0x0b, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55,
+ 0x4e, 0x54, 0x5f, 0x36, 0x35, 0x35, 0x33, 0x36, 0x10, 0x0c, 0x12, 0x17, 0x0a, 0x13, 0x52, 0x45,
+ 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x31, 0x33, 0x31, 0x30, 0x37,
+ 0x32, 0x10, 0x0d, 0x12, 0x17, 0x0a, 0x13, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x43, 0x4f,
+ 0x55, 0x4e, 0x54, 0x5f, 0x32, 0x36, 0x32, 0x31, 0x34, 0x34, 0x10, 0x0e, 0x12, 0x17, 0x0a, 0x13,
+ 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x35, 0x32, 0x34,
+ 0x32, 0x38, 0x38, 0x10, 0x0f, 0x1a, 0x14, 0xea, 0xaa, 0x19, 0x10, 0x18, 0x01, 0x2a, 0x0c, 0x52,
+ 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x2a, 0xdf, 0x02, 0x0a, 0x12,
+ 0x52, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65,
+ 0x6e, 0x74, 0x12, 0x11, 0x0a, 0x0d, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x54, 0x49, 0x4d,
+ 0x45, 0x5f, 0x30, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f,
+ 0x54, 0x49, 0x4d, 0x45, 0x5f, 0x31, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x52, 0x45, 0x4a, 0x4f,
+ 0x49, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x5f, 0x32, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x52,
+ 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x5f, 0x33, 0x10, 0x03, 0x12, 0x11,
+ 0x0a, 0x0d, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x5f, 0x34, 0x10,
+ 0x04, 0x12, 0x11, 0x0a, 0x0d, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45,
+ 0x5f, 0x35, 0x10, 0x05, 0x12, 0x11, 0x0a, 0x0d, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x54,
+ 0x49, 0x4d, 0x45, 0x5f, 0x36, 0x10, 0x06, 0x12, 0x11, 0x0a, 0x0d, 0x52, 0x45, 0x4a, 0x4f, 0x49,
+ 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x5f, 0x37, 0x10, 0x07, 0x12, 0x11, 0x0a, 0x0d, 0x52, 0x45,
+ 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x5f, 0x38, 0x10, 0x08, 0x12, 0x11, 0x0a,
+ 0x0d, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x5f, 0x39, 0x10, 0x09,
+ 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x5f,
+ 0x31, 0x30, 0x10, 0x0a, 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x54,
+ 0x49, 0x4d, 0x45, 0x5f, 0x31, 0x31, 0x10, 0x0b, 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x45, 0x4a, 0x4f,
+ 0x49, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x5f, 0x31, 0x32, 0x10, 0x0c, 0x12, 0x12, 0x0a, 0x0e,
+ 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x5f, 0x31, 0x33, 0x10, 0x0d,
+ 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x5f,
+ 0x31, 0x34, 0x10, 0x0e, 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x54,
+ 0x49, 0x4d, 0x45, 0x5f, 0x31, 0x35, 0x10, 0x0f, 0x1a, 0x13, 0xea, 0xaa, 0x19, 0x0f, 0x18, 0x01,
+ 0x2a, 0x0b, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x2a, 0xd5, 0x01,
+ 0x0a, 0x14, 0x52, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x45, 0x78,
0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e,
- 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x31, 0x36, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x52,
- 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x33, 0x32, 0x10, 0x01,
- 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54,
- 0x5f, 0x36, 0x34, 0x10, 0x02, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f,
- 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x31, 0x32, 0x38, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x52,
- 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x32, 0x35, 0x36, 0x10,
- 0x04, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e,
- 0x54, 0x5f, 0x35, 0x31, 0x32, 0x10, 0x05, 0x12, 0x15, 0x0a, 0x11, 0x52, 0x45, 0x4a, 0x4f, 0x49,
- 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x31, 0x30, 0x32, 0x34, 0x10, 0x06, 0x12, 0x15,
- 0x0a, 0x11, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x32,
- 0x30, 0x34, 0x38, 0x10, 0x07, 0x12, 0x15, 0x0a, 0x11, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f,
- 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x34, 0x30, 0x39, 0x36, 0x10, 0x08, 0x12, 0x15, 0x0a, 0x11,
- 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x38, 0x31, 0x39,
- 0x32, 0x10, 0x09, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x43, 0x4f,
- 0x55, 0x4e, 0x54, 0x5f, 0x31, 0x36, 0x33, 0x38, 0x34, 0x10, 0x0a, 0x12, 0x16, 0x0a, 0x12, 0x52,
- 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x33, 0x32, 0x37, 0x36,
- 0x38, 0x10, 0x0b, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x43, 0x4f,
- 0x55, 0x4e, 0x54, 0x5f, 0x36, 0x35, 0x35, 0x33, 0x36, 0x10, 0x0c, 0x12, 0x17, 0x0a, 0x13, 0x52,
- 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x31, 0x33, 0x31, 0x30,
- 0x37, 0x32, 0x10, 0x0d, 0x12, 0x17, 0x0a, 0x13, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x43,
- 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x32, 0x36, 0x32, 0x31, 0x34, 0x34, 0x10, 0x0e, 0x12, 0x17, 0x0a,
- 0x13, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x35, 0x32,
- 0x34, 0x32, 0x38, 0x38, 0x10, 0x0f, 0x1a, 0x14, 0xea, 0xaa, 0x19, 0x10, 0x18, 0x01, 0x2a, 0x0c,
- 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x2a, 0xdf, 0x02, 0x0a,
- 0x12, 0x52, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x45, 0x78, 0x70, 0x6f, 0x6e,
- 0x65, 0x6e, 0x74, 0x12, 0x11, 0x0a, 0x0d, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x54, 0x49,
- 0x4d, 0x45, 0x5f, 0x30, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e,
- 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x5f, 0x31, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x52, 0x45, 0x4a,
- 0x4f, 0x49, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x5f, 0x32, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d,
- 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x5f, 0x33, 0x10, 0x03, 0x12,
- 0x11, 0x0a, 0x0d, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x5f, 0x34,
- 0x10, 0x04, 0x12, 0x11, 0x0a, 0x0d, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x54, 0x49, 0x4d,
- 0x45, 0x5f, 0x35, 0x10, 0x05, 0x12, 0x11, 0x0a, 0x0d, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f,
- 0x54, 0x49, 0x4d, 0x45, 0x5f, 0x36, 0x10, 0x06, 0x12, 0x11, 0x0a, 0x0d, 0x52, 0x45, 0x4a, 0x4f,
- 0x49, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x5f, 0x37, 0x10, 0x07, 0x12, 0x11, 0x0a, 0x0d, 0x52,
- 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x5f, 0x38, 0x10, 0x08, 0x12, 0x11,
- 0x0a, 0x0d, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x5f, 0x39, 0x10,
- 0x09, 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45,
- 0x5f, 0x31, 0x30, 0x10, 0x0a, 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f,
- 0x54, 0x49, 0x4d, 0x45, 0x5f, 0x31, 0x31, 0x10, 0x0b, 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x45, 0x4a,
- 0x4f, 0x49, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x5f, 0x31, 0x32, 0x10, 0x0c, 0x12, 0x12, 0x0a,
- 0x0e, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x5f, 0x31, 0x33, 0x10,
- 0x0d, 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45,
- 0x5f, 0x31, 0x34, 0x10, 0x0e, 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f,
- 0x54, 0x49, 0x4d, 0x45, 0x5f, 0x31, 0x35, 0x10, 0x0f, 0x1a, 0x13, 0xea, 0xaa, 0x19, 0x0f, 0x18,
- 0x01, 0x2a, 0x0b, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x2a, 0xd5,
- 0x01, 0x0a, 0x14, 0x52, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x45,
- 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x45, 0x4a, 0x4f, 0x49,
- 0x4e, 0x5f, 0x50, 0x45, 0x52, 0x49, 0x4f, 0x44, 0x5f, 0x30, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f,
- 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x50, 0x45, 0x52, 0x49, 0x4f, 0x44, 0x5f, 0x31, 0x10,
- 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x50, 0x45, 0x52, 0x49,
- 0x4f, 0x44, 0x5f, 0x32, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e,
- 0x5f, 0x50, 0x45, 0x52, 0x49, 0x4f, 0x44, 0x5f, 0x33, 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x52,
- 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x50, 0x45, 0x52, 0x49, 0x4f, 0x44, 0x5f, 0x34, 0x10, 0x04,
+ 0x5f, 0x50, 0x45, 0x52, 0x49, 0x4f, 0x44, 0x5f, 0x30, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x52,
+ 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x50, 0x45, 0x52, 0x49, 0x4f, 0x44, 0x5f, 0x31, 0x10, 0x01,
0x12, 0x13, 0x0a, 0x0f, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x50, 0x45, 0x52, 0x49, 0x4f,
- 0x44, 0x5f, 0x35, 0x10, 0x05, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f,
- 0x50, 0x45, 0x52, 0x49, 0x4f, 0x44, 0x5f, 0x36, 0x10, 0x06, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x45,
- 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x50, 0x45, 0x52, 0x49, 0x4f, 0x44, 0x5f, 0x37, 0x10, 0x07, 0x1a,
- 0x15, 0xea, 0xaa, 0x19, 0x11, 0x18, 0x01, 0x2a, 0x0d, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f,
- 0x50, 0x45, 0x52, 0x49, 0x4f, 0x44, 0x2a, 0xe0, 0x02, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x63,
- 0x65, 0x45, 0x49, 0x52, 0x50, 0x12, 0x11, 0x0a, 0x0d, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f,
- 0x45, 0x49, 0x52, 0x50, 0x5f, 0x38, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x44, 0x45, 0x56, 0x49,
- 0x43, 0x45, 0x5f, 0x45, 0x49, 0x52, 0x50, 0x5f, 0x31, 0x30, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e,
- 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x45, 0x49, 0x52, 0x50, 0x5f, 0x31, 0x32, 0x10, 0x02,
- 0x12, 0x12, 0x0a, 0x0e, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x45, 0x49, 0x52, 0x50, 0x5f,
- 0x31, 0x33, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x45,
- 0x49, 0x52, 0x50, 0x5f, 0x31, 0x34, 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x44, 0x45, 0x56, 0x49,
- 0x43, 0x45, 0x5f, 0x45, 0x49, 0x52, 0x50, 0x5f, 0x31, 0x36, 0x10, 0x05, 0x12, 0x12, 0x0a, 0x0e,
- 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x45, 0x49, 0x52, 0x50, 0x5f, 0x31, 0x38, 0x10, 0x06,
- 0x12, 0x12, 0x0a, 0x0e, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x45, 0x49, 0x52, 0x50, 0x5f,
- 0x32, 0x30, 0x10, 0x07, 0x12, 0x12, 0x0a, 0x0e, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x45,
- 0x49, 0x52, 0x50, 0x5f, 0x32, 0x31, 0x10, 0x08, 0x12, 0x12, 0x0a, 0x0e, 0x44, 0x45, 0x56, 0x49,
- 0x43, 0x45, 0x5f, 0x45, 0x49, 0x52, 0x50, 0x5f, 0x32, 0x34, 0x10, 0x09, 0x12, 0x12, 0x0a, 0x0e,
- 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x45, 0x49, 0x52, 0x50, 0x5f, 0x32, 0x36, 0x10, 0x0a,
- 0x12, 0x12, 0x0a, 0x0e, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x45, 0x49, 0x52, 0x50, 0x5f,
- 0x32, 0x37, 0x10, 0x0b, 0x12, 0x12, 0x0a, 0x0e, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x45,
- 0x49, 0x52, 0x50, 0x5f, 0x32, 0x39, 0x10, 0x0c, 0x12, 0x12, 0x0a, 0x0e, 0x44, 0x45, 0x56, 0x49,
- 0x43, 0x45, 0x5f, 0x45, 0x49, 0x52, 0x50, 0x5f, 0x33, 0x30, 0x10, 0x0d, 0x12, 0x12, 0x0a, 0x0e,
- 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x45, 0x49, 0x52, 0x50, 0x5f, 0x33, 0x33, 0x10, 0x0e,
- 0x12, 0x12, 0x0a, 0x0e, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x45, 0x49, 0x52, 0x50, 0x5f,
- 0x33, 0x36, 0x10, 0x0f, 0x1a, 0x13, 0xea, 0xaa, 0x19, 0x0f, 0x18, 0x01, 0x2a, 0x0b, 0x44, 0x45,
- 0x56, 0x49, 0x43, 0x45, 0x5f, 0x45, 0x49, 0x52, 0x50, 0x2a, 0x99, 0x03, 0x0a, 0x13, 0x41, 0x44,
- 0x52, 0x41, 0x63, 0x6b, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e,
- 0x74, 0x12, 0x13, 0x0a, 0x0f, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x4c, 0x49, 0x4d,
- 0x49, 0x54, 0x5f, 0x31, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43,
- 0x4b, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x32, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x41,
- 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x34, 0x10, 0x02,
+ 0x44, 0x5f, 0x32, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f,
+ 0x50, 0x45, 0x52, 0x49, 0x4f, 0x44, 0x5f, 0x33, 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x45,
+ 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x50, 0x45, 0x52, 0x49, 0x4f, 0x44, 0x5f, 0x34, 0x10, 0x04, 0x12,
+ 0x13, 0x0a, 0x0f, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x50, 0x45, 0x52, 0x49, 0x4f, 0x44,
+ 0x5f, 0x35, 0x10, 0x05, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x50,
+ 0x45, 0x52, 0x49, 0x4f, 0x44, 0x5f, 0x36, 0x10, 0x06, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x45, 0x4a,
+ 0x4f, 0x49, 0x4e, 0x5f, 0x50, 0x45, 0x52, 0x49, 0x4f, 0x44, 0x5f, 0x37, 0x10, 0x07, 0x1a, 0x15,
+ 0xea, 0xaa, 0x19, 0x11, 0x18, 0x01, 0x2a, 0x0d, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x50,
+ 0x45, 0x52, 0x49, 0x4f, 0x44, 0x2a, 0xe0, 0x02, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65,
+ 0x45, 0x49, 0x52, 0x50, 0x12, 0x11, 0x0a, 0x0d, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x45,
+ 0x49, 0x52, 0x50, 0x5f, 0x38, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x44, 0x45, 0x56, 0x49, 0x43,
+ 0x45, 0x5f, 0x45, 0x49, 0x52, 0x50, 0x5f, 0x31, 0x30, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x44,
+ 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x45, 0x49, 0x52, 0x50, 0x5f, 0x31, 0x32, 0x10, 0x02, 0x12,
+ 0x12, 0x0a, 0x0e, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x45, 0x49, 0x52, 0x50, 0x5f, 0x31,
+ 0x33, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x45, 0x49,
+ 0x52, 0x50, 0x5f, 0x31, 0x34, 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x44, 0x45, 0x56, 0x49, 0x43,
+ 0x45, 0x5f, 0x45, 0x49, 0x52, 0x50, 0x5f, 0x31, 0x36, 0x10, 0x05, 0x12, 0x12, 0x0a, 0x0e, 0x44,
+ 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x45, 0x49, 0x52, 0x50, 0x5f, 0x31, 0x38, 0x10, 0x06, 0x12,
+ 0x12, 0x0a, 0x0e, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x45, 0x49, 0x52, 0x50, 0x5f, 0x32,
+ 0x30, 0x10, 0x07, 0x12, 0x12, 0x0a, 0x0e, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x45, 0x49,
+ 0x52, 0x50, 0x5f, 0x32, 0x31, 0x10, 0x08, 0x12, 0x12, 0x0a, 0x0e, 0x44, 0x45, 0x56, 0x49, 0x43,
+ 0x45, 0x5f, 0x45, 0x49, 0x52, 0x50, 0x5f, 0x32, 0x34, 0x10, 0x09, 0x12, 0x12, 0x0a, 0x0e, 0x44,
+ 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x45, 0x49, 0x52, 0x50, 0x5f, 0x32, 0x36, 0x10, 0x0a, 0x12,
+ 0x12, 0x0a, 0x0e, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x45, 0x49, 0x52, 0x50, 0x5f, 0x32,
+ 0x37, 0x10, 0x0b, 0x12, 0x12, 0x0a, 0x0e, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x45, 0x49,
+ 0x52, 0x50, 0x5f, 0x32, 0x39, 0x10, 0x0c, 0x12, 0x12, 0x0a, 0x0e, 0x44, 0x45, 0x56, 0x49, 0x43,
+ 0x45, 0x5f, 0x45, 0x49, 0x52, 0x50, 0x5f, 0x33, 0x30, 0x10, 0x0d, 0x12, 0x12, 0x0a, 0x0e, 0x44,
+ 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x45, 0x49, 0x52, 0x50, 0x5f, 0x33, 0x33, 0x10, 0x0e, 0x12,
+ 0x12, 0x0a, 0x0e, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x45, 0x49, 0x52, 0x50, 0x5f, 0x33,
+ 0x36, 0x10, 0x0f, 0x1a, 0x13, 0xea, 0xaa, 0x19, 0x0f, 0x18, 0x01, 0x2a, 0x0b, 0x44, 0x45, 0x56,
+ 0x49, 0x43, 0x45, 0x5f, 0x45, 0x49, 0x52, 0x50, 0x2a, 0x99, 0x03, 0x0a, 0x13, 0x41, 0x44, 0x52,
+ 0x41, 0x63, 0x6b, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74,
0x12, 0x13, 0x0a, 0x0f, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x4c, 0x49, 0x4d, 0x49,
- 0x54, 0x5f, 0x38, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b,
- 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x31, 0x36, 0x10, 0x04, 0x12, 0x14, 0x0a, 0x10, 0x41,
- 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x33, 0x32, 0x10,
- 0x05, 0x12, 0x14, 0x0a, 0x10, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x4c, 0x49, 0x4d,
- 0x49, 0x54, 0x5f, 0x36, 0x34, 0x10, 0x06, 0x12, 0x15, 0x0a, 0x11, 0x41, 0x44, 0x52, 0x5f, 0x41,
- 0x43, 0x4b, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x31, 0x32, 0x38, 0x10, 0x07, 0x12, 0x15,
- 0x0a, 0x11, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f,
- 0x32, 0x35, 0x36, 0x10, 0x08, 0x12, 0x15, 0x0a, 0x11, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b,
- 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x35, 0x31, 0x32, 0x10, 0x09, 0x12, 0x16, 0x0a, 0x12,
- 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x31, 0x30,
- 0x32, 0x34, 0x10, 0x0a, 0x12, 0x16, 0x0a, 0x12, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f,
- 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x32, 0x30, 0x34, 0x38, 0x10, 0x0b, 0x12, 0x16, 0x0a, 0x12,
- 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x34, 0x30,
- 0x39, 0x36, 0x10, 0x0c, 0x12, 0x16, 0x0a, 0x12, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f,
- 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x38, 0x31, 0x39, 0x32, 0x10, 0x0d, 0x12, 0x17, 0x0a, 0x13,
- 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x31, 0x36,
- 0x33, 0x38, 0x34, 0x10, 0x0e, 0x12, 0x17, 0x0a, 0x13, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b,
- 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x33, 0x32, 0x37, 0x36, 0x38, 0x10, 0x0f, 0x1a, 0x15,
- 0xea, 0xaa, 0x19, 0x11, 0x18, 0x01, 0x2a, 0x0d, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f,
- 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x2a, 0x99, 0x03, 0x0a, 0x13, 0x41, 0x44, 0x52, 0x41, 0x63, 0x6b,
- 0x44, 0x65, 0x6c, 0x61, 0x79, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x13, 0x0a,
- 0x0f, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x31,
- 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x44, 0x45,
- 0x4c, 0x41, 0x59, 0x5f, 0x32, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x41, 0x44, 0x52, 0x5f, 0x41,
- 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x34, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f,
- 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x38, 0x10,
- 0x03, 0x12, 0x14, 0x0a, 0x10, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x4c,
- 0x41, 0x59, 0x5f, 0x31, 0x36, 0x10, 0x04, 0x12, 0x14, 0x0a, 0x10, 0x41, 0x44, 0x52, 0x5f, 0x41,
- 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x33, 0x32, 0x10, 0x05, 0x12, 0x14, 0x0a,
- 0x10, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x36,
- 0x34, 0x10, 0x06, 0x12, 0x15, 0x0a, 0x11, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x44,
- 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x31, 0x32, 0x38, 0x10, 0x07, 0x12, 0x15, 0x0a, 0x11, 0x41, 0x44,
- 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x32, 0x35, 0x36, 0x10,
- 0x08, 0x12, 0x15, 0x0a, 0x11, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x4c,
- 0x41, 0x59, 0x5f, 0x35, 0x31, 0x32, 0x10, 0x09, 0x12, 0x16, 0x0a, 0x12, 0x41, 0x44, 0x52, 0x5f,
- 0x41, 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x31, 0x30, 0x32, 0x34, 0x10, 0x0a,
- 0x12, 0x16, 0x0a, 0x12, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x4c, 0x41,
- 0x59, 0x5f, 0x32, 0x30, 0x34, 0x38, 0x10, 0x0b, 0x12, 0x16, 0x0a, 0x12, 0x41, 0x44, 0x52, 0x5f,
- 0x41, 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x34, 0x30, 0x39, 0x36, 0x10, 0x0c,
- 0x12, 0x16, 0x0a, 0x12, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x4c, 0x41,
- 0x59, 0x5f, 0x38, 0x31, 0x39, 0x32, 0x10, 0x0d, 0x12, 0x17, 0x0a, 0x13, 0x41, 0x44, 0x52, 0x5f,
- 0x41, 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x31, 0x36, 0x33, 0x38, 0x34, 0x10,
- 0x0e, 0x12, 0x17, 0x0a, 0x13, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x4c,
- 0x41, 0x59, 0x5f, 0x33, 0x32, 0x37, 0x36, 0x38, 0x10, 0x0f, 0x1a, 0x15, 0xea, 0xaa, 0x19, 0x11,
- 0x18, 0x01, 0x2a, 0x0d, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x4c, 0x41,
- 0x59, 0x2a, 0xea, 0x02, 0x0a, 0x07, 0x52, 0x78, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x0e, 0x0a,
- 0x0a, 0x52, 0x58, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x30, 0x10, 0x00, 0x12, 0x0e, 0x0a,
- 0x0a, 0x52, 0x58, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x31, 0x10, 0x01, 0x12, 0x0e, 0x0a,
- 0x0a, 0x52, 0x58, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x32, 0x10, 0x02, 0x12, 0x0e, 0x0a,
- 0x0a, 0x52, 0x58, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x33, 0x10, 0x03, 0x12, 0x0e, 0x0a,
- 0x0a, 0x52, 0x58, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x34, 0x10, 0x04, 0x12, 0x0e, 0x0a,
- 0x0a, 0x52, 0x58, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x35, 0x10, 0x05, 0x12, 0x0e, 0x0a,
- 0x0a, 0x52, 0x58, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x36, 0x10, 0x06, 0x12, 0x0e, 0x0a,
- 0x0a, 0x52, 0x58, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x37, 0x10, 0x07, 0x12, 0x0e, 0x0a,
- 0x0a, 0x52, 0x58, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x38, 0x10, 0x08, 0x12, 0x0e, 0x0a,
- 0x0a, 0x52, 0x58, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x39, 0x10, 0x09, 0x12, 0x0f, 0x0a,
- 0x0b, 0x52, 0x58, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x31, 0x30, 0x10, 0x0a, 0x12, 0x0f,
- 0x0a, 0x0b, 0x52, 0x58, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x31, 0x31, 0x10, 0x0b, 0x12,
- 0x0f, 0x0a, 0x0b, 0x52, 0x58, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x31, 0x32, 0x10, 0x0c,
- 0x12, 0x0f, 0x0a, 0x0b, 0x52, 0x58, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x31, 0x33, 0x10,
- 0x0d, 0x12, 0x0f, 0x0a, 0x0b, 0x52, 0x58, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x31, 0x34,
- 0x10, 0x0e, 0x12, 0x0f, 0x0a, 0x0b, 0x52, 0x58, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x31,
- 0x35, 0x10, 0x0f, 0x1a, 0x59, 0xea, 0xaa, 0x19, 0x0c, 0x10, 0x01, 0x2a, 0x08, 0x52, 0x58, 0x5f,
- 0x44, 0x45, 0x4c, 0x41, 0x59, 0xf2, 0xaa, 0x19, 0x45, 0x0a, 0x43, 0x67, 0x6f, 0x2e, 0x74, 0x68,
- 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f,
- 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33,
- 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x78, 0x44, 0x65, 0x6c,
- 0x61, 0x79, 0x5f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2a, 0xa8,
- 0x02, 0x0a, 0x05, 0x4d, 0x69, 0x6e, 0x6f, 0x72, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x49, 0x4e, 0x4f,
- 0x52, 0x5f, 0x52, 0x46, 0x55, 0x5f, 0x30, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x4d, 0x49, 0x4e,
- 0x4f, 0x52, 0x5f, 0x31, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x49, 0x4e, 0x4f, 0x52, 0x5f,
- 0x52, 0x46, 0x55, 0x5f, 0x32, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x49, 0x4e, 0x4f, 0x52,
- 0x5f, 0x52, 0x46, 0x55, 0x5f, 0x33, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x49, 0x4e, 0x4f,
- 0x52, 0x5f, 0x52, 0x46, 0x55, 0x5f, 0x34, 0x10, 0x04, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x49, 0x4e,
- 0x4f, 0x52, 0x5f, 0x52, 0x46, 0x55, 0x5f, 0x35, 0x10, 0x05, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x49,
- 0x4e, 0x4f, 0x52, 0x5f, 0x52, 0x46, 0x55, 0x5f, 0x36, 0x10, 0x06, 0x12, 0x0f, 0x0a, 0x0b, 0x4d,
- 0x49, 0x4e, 0x4f, 0x52, 0x5f, 0x52, 0x46, 0x55, 0x5f, 0x37, 0x10, 0x07, 0x12, 0x0f, 0x0a, 0x0b,
- 0x4d, 0x49, 0x4e, 0x4f, 0x52, 0x5f, 0x52, 0x46, 0x55, 0x5f, 0x38, 0x10, 0x08, 0x12, 0x0f, 0x0a,
- 0x0b, 0x4d, 0x49, 0x4e, 0x4f, 0x52, 0x5f, 0x52, 0x46, 0x55, 0x5f, 0x39, 0x10, 0x09, 0x12, 0x10,
- 0x0a, 0x0c, 0x4d, 0x49, 0x4e, 0x4f, 0x52, 0x5f, 0x52, 0x46, 0x55, 0x5f, 0x31, 0x30, 0x10, 0x0a,
- 0x12, 0x10, 0x0a, 0x0c, 0x4d, 0x49, 0x4e, 0x4f, 0x52, 0x5f, 0x52, 0x46, 0x55, 0x5f, 0x31, 0x31,
- 0x10, 0x0b, 0x12, 0x10, 0x0a, 0x0c, 0x4d, 0x49, 0x4e, 0x4f, 0x52, 0x5f, 0x52, 0x46, 0x55, 0x5f,
- 0x31, 0x32, 0x10, 0x0c, 0x12, 0x10, 0x0a, 0x0c, 0x4d, 0x49, 0x4e, 0x4f, 0x52, 0x5f, 0x52, 0x46,
- 0x55, 0x5f, 0x31, 0x33, 0x10, 0x0d, 0x12, 0x10, 0x0a, 0x0c, 0x4d, 0x49, 0x4e, 0x4f, 0x52, 0x5f,
- 0x52, 0x46, 0x55, 0x5f, 0x31, 0x34, 0x10, 0x0e, 0x12, 0x10, 0x0a, 0x0c, 0x4d, 0x49, 0x4e, 0x4f,
- 0x52, 0x5f, 0x52, 0x46, 0x55, 0x5f, 0x31, 0x35, 0x10, 0x0f, 0x1a, 0x0d, 0xea, 0xaa, 0x19, 0x09,
- 0x18, 0x01, 0x2a, 0x05, 0x4d, 0x49, 0x4e, 0x4f, 0x52, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x6f, 0x2e,
- 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72,
- 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f,
- 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74, 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72,
- 0x6f, 0x74, 0x6f, 0x33,
+ 0x54, 0x5f, 0x31, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b,
+ 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x32, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x41, 0x44,
+ 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x34, 0x10, 0x02, 0x12,
+ 0x13, 0x0a, 0x0f, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54,
+ 0x5f, 0x38, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f,
+ 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x31, 0x36, 0x10, 0x04, 0x12, 0x14, 0x0a, 0x10, 0x41, 0x44,
+ 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x33, 0x32, 0x10, 0x05,
+ 0x12, 0x14, 0x0a, 0x10, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x4c, 0x49, 0x4d, 0x49,
+ 0x54, 0x5f, 0x36, 0x34, 0x10, 0x06, 0x12, 0x15, 0x0a, 0x11, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43,
+ 0x4b, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x31, 0x32, 0x38, 0x10, 0x07, 0x12, 0x15, 0x0a,
+ 0x11, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x32,
+ 0x35, 0x36, 0x10, 0x08, 0x12, 0x15, 0x0a, 0x11, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f,
+ 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x35, 0x31, 0x32, 0x10, 0x09, 0x12, 0x16, 0x0a, 0x12, 0x41,
+ 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x31, 0x30, 0x32,
+ 0x34, 0x10, 0x0a, 0x12, 0x16, 0x0a, 0x12, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x4c,
+ 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x32, 0x30, 0x34, 0x38, 0x10, 0x0b, 0x12, 0x16, 0x0a, 0x12, 0x41,
+ 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x34, 0x30, 0x39,
+ 0x36, 0x10, 0x0c, 0x12, 0x16, 0x0a, 0x12, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x4c,
+ 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x38, 0x31, 0x39, 0x32, 0x10, 0x0d, 0x12, 0x17, 0x0a, 0x13, 0x41,
+ 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x31, 0x36, 0x33,
+ 0x38, 0x34, 0x10, 0x0e, 0x12, 0x17, 0x0a, 0x13, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f,
+ 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x33, 0x32, 0x37, 0x36, 0x38, 0x10, 0x0f, 0x1a, 0x15, 0xea,
+ 0xaa, 0x19, 0x11, 0x18, 0x01, 0x2a, 0x0d, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x4c,
+ 0x49, 0x4d, 0x49, 0x54, 0x2a, 0x99, 0x03, 0x0a, 0x13, 0x41, 0x44, 0x52, 0x41, 0x63, 0x6b, 0x44,
+ 0x65, 0x6c, 0x61, 0x79, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x13, 0x0a, 0x0f,
+ 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x31, 0x10,
+ 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x4c,
+ 0x41, 0x59, 0x5f, 0x32, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43,
+ 0x4b, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x34, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x41,
+ 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x38, 0x10, 0x03,
+ 0x12, 0x14, 0x0a, 0x10, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x4c, 0x41,
+ 0x59, 0x5f, 0x31, 0x36, 0x10, 0x04, 0x12, 0x14, 0x0a, 0x10, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43,
+ 0x4b, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x33, 0x32, 0x10, 0x05, 0x12, 0x14, 0x0a, 0x10,
+ 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x36, 0x34,
+ 0x10, 0x06, 0x12, 0x15, 0x0a, 0x11, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x44, 0x45,
+ 0x4c, 0x41, 0x59, 0x5f, 0x31, 0x32, 0x38, 0x10, 0x07, 0x12, 0x15, 0x0a, 0x11, 0x41, 0x44, 0x52,
+ 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x32, 0x35, 0x36, 0x10, 0x08,
+ 0x12, 0x15, 0x0a, 0x11, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x4c, 0x41,
+ 0x59, 0x5f, 0x35, 0x31, 0x32, 0x10, 0x09, 0x12, 0x16, 0x0a, 0x12, 0x41, 0x44, 0x52, 0x5f, 0x41,
+ 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x31, 0x30, 0x32, 0x34, 0x10, 0x0a, 0x12,
+ 0x16, 0x0a, 0x12, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59,
+ 0x5f, 0x32, 0x30, 0x34, 0x38, 0x10, 0x0b, 0x12, 0x16, 0x0a, 0x12, 0x41, 0x44, 0x52, 0x5f, 0x41,
+ 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x34, 0x30, 0x39, 0x36, 0x10, 0x0c, 0x12,
+ 0x16, 0x0a, 0x12, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59,
+ 0x5f, 0x38, 0x31, 0x39, 0x32, 0x10, 0x0d, 0x12, 0x17, 0x0a, 0x13, 0x41, 0x44, 0x52, 0x5f, 0x41,
+ 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x31, 0x36, 0x33, 0x38, 0x34, 0x10, 0x0e,
+ 0x12, 0x17, 0x0a, 0x13, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x4c, 0x41,
+ 0x59, 0x5f, 0x33, 0x32, 0x37, 0x36, 0x38, 0x10, 0x0f, 0x1a, 0x15, 0xea, 0xaa, 0x19, 0x11, 0x18,
+ 0x01, 0x2a, 0x0d, 0x41, 0x44, 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59,
+ 0x2a, 0xea, 0x02, 0x0a, 0x07, 0x52, 0x78, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x0e, 0x0a, 0x0a,
+ 0x52, 0x58, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x30, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a,
+ 0x52, 0x58, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x31, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a,
+ 0x52, 0x58, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x32, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a,
+ 0x52, 0x58, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x33, 0x10, 0x03, 0x12, 0x0e, 0x0a, 0x0a,
+ 0x52, 0x58, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x34, 0x10, 0x04, 0x12, 0x0e, 0x0a, 0x0a,
+ 0x52, 0x58, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x35, 0x10, 0x05, 0x12, 0x0e, 0x0a, 0x0a,
+ 0x52, 0x58, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x36, 0x10, 0x06, 0x12, 0x0e, 0x0a, 0x0a,
+ 0x52, 0x58, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x37, 0x10, 0x07, 0x12, 0x0e, 0x0a, 0x0a,
+ 0x52, 0x58, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x38, 0x10, 0x08, 0x12, 0x0e, 0x0a, 0x0a,
+ 0x52, 0x58, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x39, 0x10, 0x09, 0x12, 0x0f, 0x0a, 0x0b,
+ 0x52, 0x58, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x31, 0x30, 0x10, 0x0a, 0x12, 0x0f, 0x0a,
+ 0x0b, 0x52, 0x58, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x31, 0x31, 0x10, 0x0b, 0x12, 0x0f,
+ 0x0a, 0x0b, 0x52, 0x58, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x31, 0x32, 0x10, 0x0c, 0x12,
+ 0x0f, 0x0a, 0x0b, 0x52, 0x58, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x31, 0x33, 0x10, 0x0d,
+ 0x12, 0x0f, 0x0a, 0x0b, 0x52, 0x58, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x31, 0x34, 0x10,
+ 0x0e, 0x12, 0x0f, 0x0a, 0x0b, 0x52, 0x58, 0x5f, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x31, 0x35,
+ 0x10, 0x0f, 0x1a, 0x59, 0xea, 0xaa, 0x19, 0x0c, 0x10, 0x01, 0x2a, 0x08, 0x52, 0x58, 0x5f, 0x44,
+ 0x45, 0x4c, 0x41, 0x59, 0xf2, 0xaa, 0x19, 0x45, 0x0a, 0x43, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65,
+ 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c,
+ 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f,
+ 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74, 0x6e, 0x70, 0x62, 0x2e, 0x52, 0x78, 0x44, 0x65, 0x6c, 0x61,
+ 0x79, 0x5f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2a, 0xa8, 0x02,
+ 0x0a, 0x05, 0x4d, 0x69, 0x6e, 0x6f, 0x72, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x49, 0x4e, 0x4f, 0x52,
+ 0x5f, 0x52, 0x46, 0x55, 0x5f, 0x30, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x4d, 0x49, 0x4e, 0x4f,
+ 0x52, 0x5f, 0x31, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x49, 0x4e, 0x4f, 0x52, 0x5f, 0x52,
+ 0x46, 0x55, 0x5f, 0x32, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x49, 0x4e, 0x4f, 0x52, 0x5f,
+ 0x52, 0x46, 0x55, 0x5f, 0x33, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x49, 0x4e, 0x4f, 0x52,
+ 0x5f, 0x52, 0x46, 0x55, 0x5f, 0x34, 0x10, 0x04, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x49, 0x4e, 0x4f,
+ 0x52, 0x5f, 0x52, 0x46, 0x55, 0x5f, 0x35, 0x10, 0x05, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x49, 0x4e,
+ 0x4f, 0x52, 0x5f, 0x52, 0x46, 0x55, 0x5f, 0x36, 0x10, 0x06, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x49,
+ 0x4e, 0x4f, 0x52, 0x5f, 0x52, 0x46, 0x55, 0x5f, 0x37, 0x10, 0x07, 0x12, 0x0f, 0x0a, 0x0b, 0x4d,
+ 0x49, 0x4e, 0x4f, 0x52, 0x5f, 0x52, 0x46, 0x55, 0x5f, 0x38, 0x10, 0x08, 0x12, 0x0f, 0x0a, 0x0b,
+ 0x4d, 0x49, 0x4e, 0x4f, 0x52, 0x5f, 0x52, 0x46, 0x55, 0x5f, 0x39, 0x10, 0x09, 0x12, 0x10, 0x0a,
+ 0x0c, 0x4d, 0x49, 0x4e, 0x4f, 0x52, 0x5f, 0x52, 0x46, 0x55, 0x5f, 0x31, 0x30, 0x10, 0x0a, 0x12,
+ 0x10, 0x0a, 0x0c, 0x4d, 0x49, 0x4e, 0x4f, 0x52, 0x5f, 0x52, 0x46, 0x55, 0x5f, 0x31, 0x31, 0x10,
+ 0x0b, 0x12, 0x10, 0x0a, 0x0c, 0x4d, 0x49, 0x4e, 0x4f, 0x52, 0x5f, 0x52, 0x46, 0x55, 0x5f, 0x31,
+ 0x32, 0x10, 0x0c, 0x12, 0x10, 0x0a, 0x0c, 0x4d, 0x49, 0x4e, 0x4f, 0x52, 0x5f, 0x52, 0x46, 0x55,
+ 0x5f, 0x31, 0x33, 0x10, 0x0d, 0x12, 0x10, 0x0a, 0x0c, 0x4d, 0x49, 0x4e, 0x4f, 0x52, 0x5f, 0x52,
+ 0x46, 0x55, 0x5f, 0x31, 0x34, 0x10, 0x0e, 0x12, 0x10, 0x0a, 0x0c, 0x4d, 0x49, 0x4e, 0x4f, 0x52,
+ 0x5f, 0x52, 0x46, 0x55, 0x5f, 0x31, 0x35, 0x10, 0x0f, 0x1a, 0x0d, 0xea, 0xaa, 0x19, 0x09, 0x18,
+ 0x01, 0x2a, 0x05, 0x4d, 0x49, 0x4e, 0x4f, 0x52, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x6f, 0x2e, 0x74,
+ 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
+ 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76,
+ 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74, 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x33,
}
var (
@@ -7377,205 +9790,269 @@ func file_ttn_lorawan_v3_lorawan_proto_rawDescGZIP() []byte {
return file_ttn_lorawan_v3_lorawan_proto_rawDescData
}
-var file_ttn_lorawan_v3_lorawan_proto_enumTypes = make([]protoimpl.EnumInfo, 22)
-var file_ttn_lorawan_v3_lorawan_proto_msgTypes = make([]protoimpl.MessageInfo, 63)
+var file_ttn_lorawan_v3_lorawan_proto_enumTypes = make([]protoimpl.EnumInfo, 29)
+var file_ttn_lorawan_v3_lorawan_proto_msgTypes = make([]protoimpl.MessageInfo, 85)
var file_ttn_lorawan_v3_lorawan_proto_goTypes = []interface{}{
- (MType)(0), // 0: ttn.lorawan.v3.MType
- (Major)(0), // 1: ttn.lorawan.v3.Major
- (MACVersion)(0), // 2: ttn.lorawan.v3.MACVersion
- (PHYVersion)(0), // 3: ttn.lorawan.v3.PHYVersion
- (DataRateIndex)(0), // 4: ttn.lorawan.v3.DataRateIndex
- (DataRateOffset)(0), // 5: ttn.lorawan.v3.DataRateOffset
- (JoinRequestType)(0), // 6: ttn.lorawan.v3.JoinRequestType
- (RejoinRequestType)(0), // 7: ttn.lorawan.v3.RejoinRequestType
- (CFListType)(0), // 8: ttn.lorawan.v3.CFListType
- (Class)(0), // 9: ttn.lorawan.v3.Class
- (TxSchedulePriority)(0), // 10: ttn.lorawan.v3.TxSchedulePriority
- (MACCommandIdentifier)(0), // 11: ttn.lorawan.v3.MACCommandIdentifier
- (AggregatedDutyCycle)(0), // 12: ttn.lorawan.v3.AggregatedDutyCycle
- (PingSlotPeriod)(0), // 13: ttn.lorawan.v3.PingSlotPeriod
- (RejoinCountExponent)(0), // 14: ttn.lorawan.v3.RejoinCountExponent
- (RejoinTimeExponent)(0), // 15: ttn.lorawan.v3.RejoinTimeExponent
- (RejoinPeriodExponent)(0), // 16: ttn.lorawan.v3.RejoinPeriodExponent
- (DeviceEIRP)(0), // 17: ttn.lorawan.v3.DeviceEIRP
- (ADRAckLimitExponent)(0), // 18: ttn.lorawan.v3.ADRAckLimitExponent
- (ADRAckDelayExponent)(0), // 19: ttn.lorawan.v3.ADRAckDelayExponent
- (RxDelay)(0), // 20: ttn.lorawan.v3.RxDelay
- (Minor)(0), // 21: ttn.lorawan.v3.Minor
- (*Message)(nil), // 22: ttn.lorawan.v3.Message
- (*MHDR)(nil), // 23: ttn.lorawan.v3.MHDR
- (*MACPayload)(nil), // 24: ttn.lorawan.v3.MACPayload
- (*FHDR)(nil), // 25: ttn.lorawan.v3.FHDR
- (*FCtrl)(nil), // 26: ttn.lorawan.v3.FCtrl
- (*JoinRequestPayload)(nil), // 27: ttn.lorawan.v3.JoinRequestPayload
- (*RejoinRequestPayload)(nil), // 28: ttn.lorawan.v3.RejoinRequestPayload
- (*JoinAcceptPayload)(nil), // 29: ttn.lorawan.v3.JoinAcceptPayload
- (*DLSettings)(nil), // 30: ttn.lorawan.v3.DLSettings
- (*CFList)(nil), // 31: ttn.lorawan.v3.CFList
- (*LoRaDataRate)(nil), // 32: ttn.lorawan.v3.LoRaDataRate
- (*FSKDataRate)(nil), // 33: ttn.lorawan.v3.FSKDataRate
- (*LRFHSSDataRate)(nil), // 34: ttn.lorawan.v3.LRFHSSDataRate
- (*DataRate)(nil), // 35: ttn.lorawan.v3.DataRate
- (*TxSettings)(nil), // 36: ttn.lorawan.v3.TxSettings
- (*GatewayAntennaIdentifiers)(nil), // 37: ttn.lorawan.v3.GatewayAntennaIdentifiers
- (*ClassBCGatewayIdentifiers)(nil), // 38: ttn.lorawan.v3.ClassBCGatewayIdentifiers
- (*UplinkToken)(nil), // 39: ttn.lorawan.v3.UplinkToken
- (*DownlinkPath)(nil), // 40: ttn.lorawan.v3.DownlinkPath
- (*TxRequest)(nil), // 41: ttn.lorawan.v3.TxRequest
- (*MACCommand)(nil), // 42: ttn.lorawan.v3.MACCommand
- (*MACCommands)(nil), // 43: ttn.lorawan.v3.MACCommands
- (*FrequencyValue)(nil), // 44: ttn.lorawan.v3.FrequencyValue
- (*ZeroableFrequencyValue)(nil), // 45: ttn.lorawan.v3.ZeroableFrequencyValue
- (*DataRateOffsetValue)(nil), // 46: ttn.lorawan.v3.DataRateOffsetValue
- (*DataRateIndexValue)(nil), // 47: ttn.lorawan.v3.DataRateIndexValue
- (*PingSlotPeriodValue)(nil), // 48: ttn.lorawan.v3.PingSlotPeriodValue
- (*AggregatedDutyCycleValue)(nil), // 49: ttn.lorawan.v3.AggregatedDutyCycleValue
- (*RxDelayValue)(nil), // 50: ttn.lorawan.v3.RxDelayValue
- (*ADRAckLimitExponentValue)(nil), // 51: ttn.lorawan.v3.ADRAckLimitExponentValue
- (*ADRAckDelayExponentValue)(nil), // 52: ttn.lorawan.v3.ADRAckDelayExponentValue
- (*DeviceEIRPValue)(nil), // 53: ttn.lorawan.v3.DeviceEIRPValue
- (*TxSettings_Downlink)(nil), // 54: ttn.lorawan.v3.TxSettings.Downlink
- (*MACCommand_ResetInd)(nil), // 55: ttn.lorawan.v3.MACCommand.ResetInd
- (*MACCommand_ResetConf)(nil), // 56: ttn.lorawan.v3.MACCommand.ResetConf
- (*MACCommand_LinkCheckAns)(nil), // 57: ttn.lorawan.v3.MACCommand.LinkCheckAns
- (*MACCommand_LinkADRReq)(nil), // 58: ttn.lorawan.v3.MACCommand.LinkADRReq
- (*MACCommand_LinkADRAns)(nil), // 59: ttn.lorawan.v3.MACCommand.LinkADRAns
- (*MACCommand_DutyCycleReq)(nil), // 60: ttn.lorawan.v3.MACCommand.DutyCycleReq
- (*MACCommand_RxParamSetupReq)(nil), // 61: ttn.lorawan.v3.MACCommand.RxParamSetupReq
- (*MACCommand_RxParamSetupAns)(nil), // 62: ttn.lorawan.v3.MACCommand.RxParamSetupAns
- (*MACCommand_DevStatusAns)(nil), // 63: ttn.lorawan.v3.MACCommand.DevStatusAns
- (*MACCommand_NewChannelReq)(nil), // 64: ttn.lorawan.v3.MACCommand.NewChannelReq
- (*MACCommand_NewChannelAns)(nil), // 65: ttn.lorawan.v3.MACCommand.NewChannelAns
- (*MACCommand_DLChannelReq)(nil), // 66: ttn.lorawan.v3.MACCommand.DLChannelReq
- (*MACCommand_DLChannelAns)(nil), // 67: ttn.lorawan.v3.MACCommand.DLChannelAns
- (*MACCommand_RxTimingSetupReq)(nil), // 68: ttn.lorawan.v3.MACCommand.RxTimingSetupReq
- (*MACCommand_TxParamSetupReq)(nil), // 69: ttn.lorawan.v3.MACCommand.TxParamSetupReq
- (*MACCommand_RekeyInd)(nil), // 70: ttn.lorawan.v3.MACCommand.RekeyInd
- (*MACCommand_RekeyConf)(nil), // 71: ttn.lorawan.v3.MACCommand.RekeyConf
- (*MACCommand_ADRParamSetupReq)(nil), // 72: ttn.lorawan.v3.MACCommand.ADRParamSetupReq
- (*MACCommand_DeviceTimeAns)(nil), // 73: ttn.lorawan.v3.MACCommand.DeviceTimeAns
- (*MACCommand_ForceRejoinReq)(nil), // 74: ttn.lorawan.v3.MACCommand.ForceRejoinReq
- (*MACCommand_RejoinParamSetupReq)(nil), // 75: ttn.lorawan.v3.MACCommand.RejoinParamSetupReq
- (*MACCommand_RejoinParamSetupAns)(nil), // 76: ttn.lorawan.v3.MACCommand.RejoinParamSetupAns
- (*MACCommand_PingSlotInfoReq)(nil), // 77: ttn.lorawan.v3.MACCommand.PingSlotInfoReq
- (*MACCommand_PingSlotChannelReq)(nil), // 78: ttn.lorawan.v3.MACCommand.PingSlotChannelReq
- (*MACCommand_PingSlotChannelAns)(nil), // 79: ttn.lorawan.v3.MACCommand.PingSlotChannelAns
- (*MACCommand_BeaconTimingAns)(nil), // 80: ttn.lorawan.v3.MACCommand.BeaconTimingAns
- (*MACCommand_BeaconFreqReq)(nil), // 81: ttn.lorawan.v3.MACCommand.BeaconFreqReq
- (*MACCommand_BeaconFreqAns)(nil), // 82: ttn.lorawan.v3.MACCommand.BeaconFreqAns
- (*MACCommand_DeviceModeInd)(nil), // 83: ttn.lorawan.v3.MACCommand.DeviceModeInd
- (*MACCommand_DeviceModeConf)(nil), // 84: ttn.lorawan.v3.MACCommand.DeviceModeConf
- (*structpb.Struct)(nil), // 85: google.protobuf.Struct
- (*timestamppb.Timestamp)(nil), // 86: google.protobuf.Timestamp
- (*GatewayIdentifiers)(nil), // 87: ttn.lorawan.v3.GatewayIdentifiers
+ (MType)(0), // 0: ttn.lorawan.v3.MType
+ (Major)(0), // 1: ttn.lorawan.v3.Major
+ (MACVersion)(0), // 2: ttn.lorawan.v3.MACVersion
+ (PHYVersion)(0), // 3: ttn.lorawan.v3.PHYVersion
+ (DataRateIndex)(0), // 4: ttn.lorawan.v3.DataRateIndex
+ (DataRateOffset)(0), // 5: ttn.lorawan.v3.DataRateOffset
+ (JoinRequestType)(0), // 6: ttn.lorawan.v3.JoinRequestType
+ (RejoinRequestType)(0), // 7: ttn.lorawan.v3.RejoinRequestType
+ (CFListType)(0), // 8: ttn.lorawan.v3.CFListType
+ (Class)(0), // 9: ttn.lorawan.v3.Class
+ (TxSchedulePriority)(0), // 10: ttn.lorawan.v3.TxSchedulePriority
+ (MACCommandIdentifier)(0), // 11: ttn.lorawan.v3.MACCommandIdentifier
+ (RelayCADPeriodicity)(0), // 12: ttn.lorawan.v3.RelayCADPeriodicity
+ (RelaySecondChAckOffset)(0), // 13: ttn.lorawan.v3.RelaySecondChAckOffset
+ (RelayLimitBucketSize)(0), // 14: ttn.lorawan.v3.RelayLimitBucketSize
+ (RelaySmartEnableLevel)(0), // 15: ttn.lorawan.v3.RelaySmartEnableLevel
+ (RelayWORChannel)(0), // 16: ttn.lorawan.v3.RelayWORChannel
+ (RelayResetLimitCounter)(0), // 17: ttn.lorawan.v3.RelayResetLimitCounter
+ (RelayCtrlUplinkListAction)(0), // 18: ttn.lorawan.v3.RelayCtrlUplinkListAction
+ (AggregatedDutyCycle)(0), // 19: ttn.lorawan.v3.AggregatedDutyCycle
+ (PingSlotPeriod)(0), // 20: ttn.lorawan.v3.PingSlotPeriod
+ (RejoinCountExponent)(0), // 21: ttn.lorawan.v3.RejoinCountExponent
+ (RejoinTimeExponent)(0), // 22: ttn.lorawan.v3.RejoinTimeExponent
+ (RejoinPeriodExponent)(0), // 23: ttn.lorawan.v3.RejoinPeriodExponent
+ (DeviceEIRP)(0), // 24: ttn.lorawan.v3.DeviceEIRP
+ (ADRAckLimitExponent)(0), // 25: ttn.lorawan.v3.ADRAckLimitExponent
+ (ADRAckDelayExponent)(0), // 26: ttn.lorawan.v3.ADRAckDelayExponent
+ (RxDelay)(0), // 27: ttn.lorawan.v3.RxDelay
+ (Minor)(0), // 28: ttn.lorawan.v3.Minor
+ (*Message)(nil), // 29: ttn.lorawan.v3.Message
+ (*MHDR)(nil), // 30: ttn.lorawan.v3.MHDR
+ (*MACPayload)(nil), // 31: ttn.lorawan.v3.MACPayload
+ (*FHDR)(nil), // 32: ttn.lorawan.v3.FHDR
+ (*FCtrl)(nil), // 33: ttn.lorawan.v3.FCtrl
+ (*JoinRequestPayload)(nil), // 34: ttn.lorawan.v3.JoinRequestPayload
+ (*RejoinRequestPayload)(nil), // 35: ttn.lorawan.v3.RejoinRequestPayload
+ (*JoinAcceptPayload)(nil), // 36: ttn.lorawan.v3.JoinAcceptPayload
+ (*DLSettings)(nil), // 37: ttn.lorawan.v3.DLSettings
+ (*CFList)(nil), // 38: ttn.lorawan.v3.CFList
+ (*LoRaDataRate)(nil), // 39: ttn.lorawan.v3.LoRaDataRate
+ (*FSKDataRate)(nil), // 40: ttn.lorawan.v3.FSKDataRate
+ (*LRFHSSDataRate)(nil), // 41: ttn.lorawan.v3.LRFHSSDataRate
+ (*DataRate)(nil), // 42: ttn.lorawan.v3.DataRate
+ (*TxSettings)(nil), // 43: ttn.lorawan.v3.TxSettings
+ (*GatewayAntennaIdentifiers)(nil), // 44: ttn.lorawan.v3.GatewayAntennaIdentifiers
+ (*ClassBCGatewayIdentifiers)(nil), // 45: ttn.lorawan.v3.ClassBCGatewayIdentifiers
+ (*UplinkToken)(nil), // 46: ttn.lorawan.v3.UplinkToken
+ (*DownlinkPath)(nil), // 47: ttn.lorawan.v3.DownlinkPath
+ (*TxRequest)(nil), // 48: ttn.lorawan.v3.TxRequest
+ (*RelaySecondChannel)(nil), // 49: ttn.lorawan.v3.RelaySecondChannel
+ (*RelayUplinkForwardLimits)(nil), // 50: ttn.lorawan.v3.RelayUplinkForwardLimits
+ (*RelayForwardLimits)(nil), // 51: ttn.lorawan.v3.RelayForwardLimits
+ (*RelayEndDeviceAlwaysMode)(nil), // 52: ttn.lorawan.v3.RelayEndDeviceAlwaysMode
+ (*RelayEndDeviceDynamicMode)(nil), // 53: ttn.lorawan.v3.RelayEndDeviceDynamicMode
+ (*RelayEndDeviceControlledMode)(nil), // 54: ttn.lorawan.v3.RelayEndDeviceControlledMode
+ (*MACCommand)(nil), // 55: ttn.lorawan.v3.MACCommand
+ (*MACCommands)(nil), // 56: ttn.lorawan.v3.MACCommands
+ (*FrequencyValue)(nil), // 57: ttn.lorawan.v3.FrequencyValue
+ (*ZeroableFrequencyValue)(nil), // 58: ttn.lorawan.v3.ZeroableFrequencyValue
+ (*DataRateOffsetValue)(nil), // 59: ttn.lorawan.v3.DataRateOffsetValue
+ (*DataRateIndexValue)(nil), // 60: ttn.lorawan.v3.DataRateIndexValue
+ (*PingSlotPeriodValue)(nil), // 61: ttn.lorawan.v3.PingSlotPeriodValue
+ (*AggregatedDutyCycleValue)(nil), // 62: ttn.lorawan.v3.AggregatedDutyCycleValue
+ (*RxDelayValue)(nil), // 63: ttn.lorawan.v3.RxDelayValue
+ (*ADRAckLimitExponentValue)(nil), // 64: ttn.lorawan.v3.ADRAckLimitExponentValue
+ (*ADRAckDelayExponentValue)(nil), // 65: ttn.lorawan.v3.ADRAckDelayExponentValue
+ (*DeviceEIRPValue)(nil), // 66: ttn.lorawan.v3.DeviceEIRPValue
+ (*RelayForwardUplinkReq)(nil), // 67: ttn.lorawan.v3.RelayForwardUplinkReq
+ (*RelayForwardDownlinkReq)(nil), // 68: ttn.lorawan.v3.RelayForwardDownlinkReq
+ (*RelayUplinkToken)(nil), // 69: ttn.lorawan.v3.RelayUplinkToken
+ (*TxSettings_Downlink)(nil), // 70: ttn.lorawan.v3.TxSettings.Downlink
+ (*MACCommand_ResetInd)(nil), // 71: ttn.lorawan.v3.MACCommand.ResetInd
+ (*MACCommand_ResetConf)(nil), // 72: ttn.lorawan.v3.MACCommand.ResetConf
+ (*MACCommand_LinkCheckAns)(nil), // 73: ttn.lorawan.v3.MACCommand.LinkCheckAns
+ (*MACCommand_LinkADRReq)(nil), // 74: ttn.lorawan.v3.MACCommand.LinkADRReq
+ (*MACCommand_LinkADRAns)(nil), // 75: ttn.lorawan.v3.MACCommand.LinkADRAns
+ (*MACCommand_DutyCycleReq)(nil), // 76: ttn.lorawan.v3.MACCommand.DutyCycleReq
+ (*MACCommand_RxParamSetupReq)(nil), // 77: ttn.lorawan.v3.MACCommand.RxParamSetupReq
+ (*MACCommand_RxParamSetupAns)(nil), // 78: ttn.lorawan.v3.MACCommand.RxParamSetupAns
+ (*MACCommand_DevStatusAns)(nil), // 79: ttn.lorawan.v3.MACCommand.DevStatusAns
+ (*MACCommand_NewChannelReq)(nil), // 80: ttn.lorawan.v3.MACCommand.NewChannelReq
+ (*MACCommand_NewChannelAns)(nil), // 81: ttn.lorawan.v3.MACCommand.NewChannelAns
+ (*MACCommand_DLChannelReq)(nil), // 82: ttn.lorawan.v3.MACCommand.DLChannelReq
+ (*MACCommand_DLChannelAns)(nil), // 83: ttn.lorawan.v3.MACCommand.DLChannelAns
+ (*MACCommand_RxTimingSetupReq)(nil), // 84: ttn.lorawan.v3.MACCommand.RxTimingSetupReq
+ (*MACCommand_TxParamSetupReq)(nil), // 85: ttn.lorawan.v3.MACCommand.TxParamSetupReq
+ (*MACCommand_RekeyInd)(nil), // 86: ttn.lorawan.v3.MACCommand.RekeyInd
+ (*MACCommand_RekeyConf)(nil), // 87: ttn.lorawan.v3.MACCommand.RekeyConf
+ (*MACCommand_ADRParamSetupReq)(nil), // 88: ttn.lorawan.v3.MACCommand.ADRParamSetupReq
+ (*MACCommand_DeviceTimeAns)(nil), // 89: ttn.lorawan.v3.MACCommand.DeviceTimeAns
+ (*MACCommand_ForceRejoinReq)(nil), // 90: ttn.lorawan.v3.MACCommand.ForceRejoinReq
+ (*MACCommand_RejoinParamSetupReq)(nil), // 91: ttn.lorawan.v3.MACCommand.RejoinParamSetupReq
+ (*MACCommand_RejoinParamSetupAns)(nil), // 92: ttn.lorawan.v3.MACCommand.RejoinParamSetupAns
+ (*MACCommand_PingSlotInfoReq)(nil), // 93: ttn.lorawan.v3.MACCommand.PingSlotInfoReq
+ (*MACCommand_PingSlotChannelReq)(nil), // 94: ttn.lorawan.v3.MACCommand.PingSlotChannelReq
+ (*MACCommand_PingSlotChannelAns)(nil), // 95: ttn.lorawan.v3.MACCommand.PingSlotChannelAns
+ (*MACCommand_BeaconTimingAns)(nil), // 96: ttn.lorawan.v3.MACCommand.BeaconTimingAns
+ (*MACCommand_BeaconFreqReq)(nil), // 97: ttn.lorawan.v3.MACCommand.BeaconFreqReq
+ (*MACCommand_BeaconFreqAns)(nil), // 98: ttn.lorawan.v3.MACCommand.BeaconFreqAns
+ (*MACCommand_DeviceModeInd)(nil), // 99: ttn.lorawan.v3.MACCommand.DeviceModeInd
+ (*MACCommand_DeviceModeConf)(nil), // 100: ttn.lorawan.v3.MACCommand.DeviceModeConf
+ (*MACCommand_RelayConfReq)(nil), // 101: ttn.lorawan.v3.MACCommand.RelayConfReq
+ (*MACCommand_RelayConfAns)(nil), // 102: ttn.lorawan.v3.MACCommand.RelayConfAns
+ (*MACCommand_RelayEndDeviceConfReq)(nil), // 103: ttn.lorawan.v3.MACCommand.RelayEndDeviceConfReq
+ (*MACCommand_RelayEndDeviceConfAns)(nil), // 104: ttn.lorawan.v3.MACCommand.RelayEndDeviceConfAns
+ (*MACCommand_RelayUpdateUplinkListReq)(nil), // 105: ttn.lorawan.v3.MACCommand.RelayUpdateUplinkListReq
+ (*MACCommand_RelayUpdateUplinkListAns)(nil), // 106: ttn.lorawan.v3.MACCommand.RelayUpdateUplinkListAns
+ (*MACCommand_RelayCtrlUplinkListReq)(nil), // 107: ttn.lorawan.v3.MACCommand.RelayCtrlUplinkListReq
+ (*MACCommand_RelayCtrlUplinkListAns)(nil), // 108: ttn.lorawan.v3.MACCommand.RelayCtrlUplinkListAns
+ (*MACCommand_RelayConfigureFwdLimitReq)(nil), // 109: ttn.lorawan.v3.MACCommand.RelayConfigureFwdLimitReq
+ (*MACCommand_RelayConfigureFwdLimitAns)(nil), // 110: ttn.lorawan.v3.MACCommand.RelayConfigureFwdLimitAns
+ (*MACCommand_RelayNotifyNewEndDeviceReq)(nil), // 111: ttn.lorawan.v3.MACCommand.RelayNotifyNewEndDeviceReq
+ (*MACCommand_RelayConfReq_Configuration)(nil), // 112: ttn.lorawan.v3.MACCommand.RelayConfReq.Configuration
+ (*MACCommand_RelayEndDeviceConfReq_Configuration)(nil), // 113: ttn.lorawan.v3.MACCommand.RelayEndDeviceConfReq.Configuration
+ (*structpb.Struct)(nil), // 114: google.protobuf.Struct
+ (*timestamppb.Timestamp)(nil), // 115: google.protobuf.Timestamp
+ (*GatewayIdentifiers)(nil), // 116: ttn.lorawan.v3.GatewayIdentifiers
+ (*EndDeviceIdentifiers)(nil), // 117: ttn.lorawan.v3.EndDeviceIdentifiers
}
var file_ttn_lorawan_v3_lorawan_proto_depIdxs = []int32{
- 23, // 0: ttn.lorawan.v3.Message.m_hdr:type_name -> ttn.lorawan.v3.MHDR
- 24, // 1: ttn.lorawan.v3.Message.mac_payload:type_name -> ttn.lorawan.v3.MACPayload
- 27, // 2: ttn.lorawan.v3.Message.join_request_payload:type_name -> ttn.lorawan.v3.JoinRequestPayload
- 29, // 3: ttn.lorawan.v3.Message.join_accept_payload:type_name -> ttn.lorawan.v3.JoinAcceptPayload
- 28, // 4: ttn.lorawan.v3.Message.rejoin_request_payload:type_name -> ttn.lorawan.v3.RejoinRequestPayload
+ 30, // 0: ttn.lorawan.v3.Message.m_hdr:type_name -> ttn.lorawan.v3.MHDR
+ 31, // 1: ttn.lorawan.v3.Message.mac_payload:type_name -> ttn.lorawan.v3.MACPayload
+ 34, // 2: ttn.lorawan.v3.Message.join_request_payload:type_name -> ttn.lorawan.v3.JoinRequestPayload
+ 36, // 3: ttn.lorawan.v3.Message.join_accept_payload:type_name -> ttn.lorawan.v3.JoinAcceptPayload
+ 35, // 4: ttn.lorawan.v3.Message.rejoin_request_payload:type_name -> ttn.lorawan.v3.RejoinRequestPayload
0, // 5: ttn.lorawan.v3.MHDR.m_type:type_name -> ttn.lorawan.v3.MType
1, // 6: ttn.lorawan.v3.MHDR.major:type_name -> ttn.lorawan.v3.Major
- 25, // 7: ttn.lorawan.v3.MACPayload.f_hdr:type_name -> ttn.lorawan.v3.FHDR
- 85, // 8: ttn.lorawan.v3.MACPayload.decoded_payload:type_name -> google.protobuf.Struct
- 26, // 9: ttn.lorawan.v3.FHDR.f_ctrl:type_name -> ttn.lorawan.v3.FCtrl
+ 32, // 7: ttn.lorawan.v3.MACPayload.f_hdr:type_name -> ttn.lorawan.v3.FHDR
+ 114, // 8: ttn.lorawan.v3.MACPayload.decoded_payload:type_name -> google.protobuf.Struct
+ 33, // 9: ttn.lorawan.v3.FHDR.f_ctrl:type_name -> ttn.lorawan.v3.FCtrl
7, // 10: ttn.lorawan.v3.RejoinRequestPayload.rejoin_type:type_name -> ttn.lorawan.v3.RejoinRequestType
- 30, // 11: ttn.lorawan.v3.JoinAcceptPayload.dl_settings:type_name -> ttn.lorawan.v3.DLSettings
- 20, // 12: ttn.lorawan.v3.JoinAcceptPayload.rx_delay:type_name -> ttn.lorawan.v3.RxDelay
- 31, // 13: ttn.lorawan.v3.JoinAcceptPayload.cf_list:type_name -> ttn.lorawan.v3.CFList
+ 37, // 11: ttn.lorawan.v3.JoinAcceptPayload.dl_settings:type_name -> ttn.lorawan.v3.DLSettings
+ 27, // 12: ttn.lorawan.v3.JoinAcceptPayload.rx_delay:type_name -> ttn.lorawan.v3.RxDelay
+ 38, // 13: ttn.lorawan.v3.JoinAcceptPayload.cf_list:type_name -> ttn.lorawan.v3.CFList
5, // 14: ttn.lorawan.v3.DLSettings.rx1_dr_offset:type_name -> ttn.lorawan.v3.DataRateOffset
4, // 15: ttn.lorawan.v3.DLSettings.rx2_dr:type_name -> ttn.lorawan.v3.DataRateIndex
8, // 16: ttn.lorawan.v3.CFList.type:type_name -> ttn.lorawan.v3.CFListType
- 32, // 17: ttn.lorawan.v3.DataRate.lora:type_name -> ttn.lorawan.v3.LoRaDataRate
- 33, // 18: ttn.lorawan.v3.DataRate.fsk:type_name -> ttn.lorawan.v3.FSKDataRate
- 34, // 19: ttn.lorawan.v3.DataRate.lrfhss:type_name -> ttn.lorawan.v3.LRFHSSDataRate
- 35, // 20: ttn.lorawan.v3.TxSettings.data_rate:type_name -> ttn.lorawan.v3.DataRate
- 86, // 21: ttn.lorawan.v3.TxSettings.time:type_name -> google.protobuf.Timestamp
- 54, // 22: ttn.lorawan.v3.TxSettings.downlink:type_name -> ttn.lorawan.v3.TxSettings.Downlink
- 87, // 23: ttn.lorawan.v3.GatewayAntennaIdentifiers.gateway_ids:type_name -> ttn.lorawan.v3.GatewayIdentifiers
- 87, // 24: ttn.lorawan.v3.ClassBCGatewayIdentifiers.gateway_ids:type_name -> ttn.lorawan.v3.GatewayIdentifiers
- 37, // 25: ttn.lorawan.v3.UplinkToken.ids:type_name -> ttn.lorawan.v3.GatewayAntennaIdentifiers
- 86, // 26: ttn.lorawan.v3.UplinkToken.server_time:type_name -> google.protobuf.Timestamp
- 86, // 27: ttn.lorawan.v3.UplinkToken.gateway_time:type_name -> google.protobuf.Timestamp
- 37, // 28: ttn.lorawan.v3.DownlinkPath.fixed:type_name -> ttn.lorawan.v3.GatewayAntennaIdentifiers
+ 39, // 17: ttn.lorawan.v3.DataRate.lora:type_name -> ttn.lorawan.v3.LoRaDataRate
+ 40, // 18: ttn.lorawan.v3.DataRate.fsk:type_name -> ttn.lorawan.v3.FSKDataRate
+ 41, // 19: ttn.lorawan.v3.DataRate.lrfhss:type_name -> ttn.lorawan.v3.LRFHSSDataRate
+ 42, // 20: ttn.lorawan.v3.TxSettings.data_rate:type_name -> ttn.lorawan.v3.DataRate
+ 115, // 21: ttn.lorawan.v3.TxSettings.time:type_name -> google.protobuf.Timestamp
+ 70, // 22: ttn.lorawan.v3.TxSettings.downlink:type_name -> ttn.lorawan.v3.TxSettings.Downlink
+ 116, // 23: ttn.lorawan.v3.GatewayAntennaIdentifiers.gateway_ids:type_name -> ttn.lorawan.v3.GatewayIdentifiers
+ 116, // 24: ttn.lorawan.v3.ClassBCGatewayIdentifiers.gateway_ids:type_name -> ttn.lorawan.v3.GatewayIdentifiers
+ 44, // 25: ttn.lorawan.v3.UplinkToken.ids:type_name -> ttn.lorawan.v3.GatewayAntennaIdentifiers
+ 115, // 26: ttn.lorawan.v3.UplinkToken.server_time:type_name -> google.protobuf.Timestamp
+ 115, // 27: ttn.lorawan.v3.UplinkToken.gateway_time:type_name -> google.protobuf.Timestamp
+ 44, // 28: ttn.lorawan.v3.DownlinkPath.fixed:type_name -> ttn.lorawan.v3.GatewayAntennaIdentifiers
9, // 29: ttn.lorawan.v3.TxRequest.class:type_name -> ttn.lorawan.v3.Class
- 40, // 30: ttn.lorawan.v3.TxRequest.downlink_paths:type_name -> ttn.lorawan.v3.DownlinkPath
- 20, // 31: ttn.lorawan.v3.TxRequest.rx1_delay:type_name -> ttn.lorawan.v3.RxDelay
- 35, // 32: ttn.lorawan.v3.TxRequest.rx1_data_rate:type_name -> ttn.lorawan.v3.DataRate
- 35, // 33: ttn.lorawan.v3.TxRequest.rx2_data_rate:type_name -> ttn.lorawan.v3.DataRate
+ 47, // 30: ttn.lorawan.v3.TxRequest.downlink_paths:type_name -> ttn.lorawan.v3.DownlinkPath
+ 27, // 31: ttn.lorawan.v3.TxRequest.rx1_delay:type_name -> ttn.lorawan.v3.RxDelay
+ 42, // 32: ttn.lorawan.v3.TxRequest.rx1_data_rate:type_name -> ttn.lorawan.v3.DataRate
+ 42, // 33: ttn.lorawan.v3.TxRequest.rx2_data_rate:type_name -> ttn.lorawan.v3.DataRate
10, // 34: ttn.lorawan.v3.TxRequest.priority:type_name -> ttn.lorawan.v3.TxSchedulePriority
- 86, // 35: ttn.lorawan.v3.TxRequest.absolute_time:type_name -> google.protobuf.Timestamp
- 85, // 36: ttn.lorawan.v3.TxRequest.advanced:type_name -> google.protobuf.Struct
- 11, // 37: ttn.lorawan.v3.MACCommand.cid:type_name -> ttn.lorawan.v3.MACCommandIdentifier
- 55, // 38: ttn.lorawan.v3.MACCommand.reset_ind:type_name -> ttn.lorawan.v3.MACCommand.ResetInd
- 56, // 39: ttn.lorawan.v3.MACCommand.reset_conf:type_name -> ttn.lorawan.v3.MACCommand.ResetConf
- 57, // 40: ttn.lorawan.v3.MACCommand.link_check_ans:type_name -> ttn.lorawan.v3.MACCommand.LinkCheckAns
- 58, // 41: ttn.lorawan.v3.MACCommand.link_adr_req:type_name -> ttn.lorawan.v3.MACCommand.LinkADRReq
- 59, // 42: ttn.lorawan.v3.MACCommand.link_adr_ans:type_name -> ttn.lorawan.v3.MACCommand.LinkADRAns
- 60, // 43: ttn.lorawan.v3.MACCommand.duty_cycle_req:type_name -> ttn.lorawan.v3.MACCommand.DutyCycleReq
- 61, // 44: ttn.lorawan.v3.MACCommand.rx_param_setup_req:type_name -> ttn.lorawan.v3.MACCommand.RxParamSetupReq
- 62, // 45: ttn.lorawan.v3.MACCommand.rx_param_setup_ans:type_name -> ttn.lorawan.v3.MACCommand.RxParamSetupAns
- 63, // 46: ttn.lorawan.v3.MACCommand.dev_status_ans:type_name -> ttn.lorawan.v3.MACCommand.DevStatusAns
- 64, // 47: ttn.lorawan.v3.MACCommand.new_channel_req:type_name -> ttn.lorawan.v3.MACCommand.NewChannelReq
- 65, // 48: ttn.lorawan.v3.MACCommand.new_channel_ans:type_name -> ttn.lorawan.v3.MACCommand.NewChannelAns
- 66, // 49: ttn.lorawan.v3.MACCommand.dl_channel_req:type_name -> ttn.lorawan.v3.MACCommand.DLChannelReq
- 67, // 50: ttn.lorawan.v3.MACCommand.dl_channel_ans:type_name -> ttn.lorawan.v3.MACCommand.DLChannelAns
- 68, // 51: ttn.lorawan.v3.MACCommand.rx_timing_setup_req:type_name -> ttn.lorawan.v3.MACCommand.RxTimingSetupReq
- 69, // 52: ttn.lorawan.v3.MACCommand.tx_param_setup_req:type_name -> ttn.lorawan.v3.MACCommand.TxParamSetupReq
- 70, // 53: ttn.lorawan.v3.MACCommand.rekey_ind:type_name -> ttn.lorawan.v3.MACCommand.RekeyInd
- 71, // 54: ttn.lorawan.v3.MACCommand.rekey_conf:type_name -> ttn.lorawan.v3.MACCommand.RekeyConf
- 72, // 55: ttn.lorawan.v3.MACCommand.adr_param_setup_req:type_name -> ttn.lorawan.v3.MACCommand.ADRParamSetupReq
- 73, // 56: ttn.lorawan.v3.MACCommand.device_time_ans:type_name -> ttn.lorawan.v3.MACCommand.DeviceTimeAns
- 74, // 57: ttn.lorawan.v3.MACCommand.force_rejoin_req:type_name -> ttn.lorawan.v3.MACCommand.ForceRejoinReq
- 75, // 58: ttn.lorawan.v3.MACCommand.rejoin_param_setup_req:type_name -> ttn.lorawan.v3.MACCommand.RejoinParamSetupReq
- 76, // 59: ttn.lorawan.v3.MACCommand.rejoin_param_setup_ans:type_name -> ttn.lorawan.v3.MACCommand.RejoinParamSetupAns
- 77, // 60: ttn.lorawan.v3.MACCommand.ping_slot_info_req:type_name -> ttn.lorawan.v3.MACCommand.PingSlotInfoReq
- 78, // 61: ttn.lorawan.v3.MACCommand.ping_slot_channel_req:type_name -> ttn.lorawan.v3.MACCommand.PingSlotChannelReq
- 79, // 62: ttn.lorawan.v3.MACCommand.ping_slot_channel_ans:type_name -> ttn.lorawan.v3.MACCommand.PingSlotChannelAns
- 80, // 63: ttn.lorawan.v3.MACCommand.beacon_timing_ans:type_name -> ttn.lorawan.v3.MACCommand.BeaconTimingAns
- 81, // 64: ttn.lorawan.v3.MACCommand.beacon_freq_req:type_name -> ttn.lorawan.v3.MACCommand.BeaconFreqReq
- 82, // 65: ttn.lorawan.v3.MACCommand.beacon_freq_ans:type_name -> ttn.lorawan.v3.MACCommand.BeaconFreqAns
- 83, // 66: ttn.lorawan.v3.MACCommand.device_mode_ind:type_name -> ttn.lorawan.v3.MACCommand.DeviceModeInd
- 84, // 67: ttn.lorawan.v3.MACCommand.device_mode_conf:type_name -> ttn.lorawan.v3.MACCommand.DeviceModeConf
- 42, // 68: ttn.lorawan.v3.MACCommands.commands:type_name -> ttn.lorawan.v3.MACCommand
- 5, // 69: ttn.lorawan.v3.DataRateOffsetValue.value:type_name -> ttn.lorawan.v3.DataRateOffset
- 4, // 70: ttn.lorawan.v3.DataRateIndexValue.value:type_name -> ttn.lorawan.v3.DataRateIndex
- 13, // 71: ttn.lorawan.v3.PingSlotPeriodValue.value:type_name -> ttn.lorawan.v3.PingSlotPeriod
- 12, // 72: ttn.lorawan.v3.AggregatedDutyCycleValue.value:type_name -> ttn.lorawan.v3.AggregatedDutyCycle
- 20, // 73: ttn.lorawan.v3.RxDelayValue.value:type_name -> ttn.lorawan.v3.RxDelay
- 18, // 74: ttn.lorawan.v3.ADRAckLimitExponentValue.value:type_name -> ttn.lorawan.v3.ADRAckLimitExponent
- 19, // 75: ttn.lorawan.v3.ADRAckDelayExponentValue.value:type_name -> ttn.lorawan.v3.ADRAckDelayExponent
- 17, // 76: ttn.lorawan.v3.DeviceEIRPValue.value:type_name -> ttn.lorawan.v3.DeviceEIRP
- 21, // 77: ttn.lorawan.v3.MACCommand.ResetInd.minor_version:type_name -> ttn.lorawan.v3.Minor
- 21, // 78: ttn.lorawan.v3.MACCommand.ResetConf.minor_version:type_name -> ttn.lorawan.v3.Minor
- 4, // 79: ttn.lorawan.v3.MACCommand.LinkADRReq.data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
- 12, // 80: ttn.lorawan.v3.MACCommand.DutyCycleReq.max_duty_cycle:type_name -> ttn.lorawan.v3.AggregatedDutyCycle
- 4, // 81: ttn.lorawan.v3.MACCommand.RxParamSetupReq.rx2_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
- 5, // 82: ttn.lorawan.v3.MACCommand.RxParamSetupReq.rx1_data_rate_offset:type_name -> ttn.lorawan.v3.DataRateOffset
- 4, // 83: ttn.lorawan.v3.MACCommand.NewChannelReq.min_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
- 4, // 84: ttn.lorawan.v3.MACCommand.NewChannelReq.max_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
- 20, // 85: ttn.lorawan.v3.MACCommand.RxTimingSetupReq.delay:type_name -> ttn.lorawan.v3.RxDelay
- 17, // 86: ttn.lorawan.v3.MACCommand.TxParamSetupReq.max_eirp_index:type_name -> ttn.lorawan.v3.DeviceEIRP
- 21, // 87: ttn.lorawan.v3.MACCommand.RekeyInd.minor_version:type_name -> ttn.lorawan.v3.Minor
- 21, // 88: ttn.lorawan.v3.MACCommand.RekeyConf.minor_version:type_name -> ttn.lorawan.v3.Minor
- 18, // 89: ttn.lorawan.v3.MACCommand.ADRParamSetupReq.adr_ack_limit_exponent:type_name -> ttn.lorawan.v3.ADRAckLimitExponent
- 19, // 90: ttn.lorawan.v3.MACCommand.ADRParamSetupReq.adr_ack_delay_exponent:type_name -> ttn.lorawan.v3.ADRAckDelayExponent
- 86, // 91: ttn.lorawan.v3.MACCommand.DeviceTimeAns.time:type_name -> google.protobuf.Timestamp
- 7, // 92: ttn.lorawan.v3.MACCommand.ForceRejoinReq.rejoin_type:type_name -> ttn.lorawan.v3.RejoinRequestType
- 4, // 93: ttn.lorawan.v3.MACCommand.ForceRejoinReq.data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
- 16, // 94: ttn.lorawan.v3.MACCommand.ForceRejoinReq.period_exponent:type_name -> ttn.lorawan.v3.RejoinPeriodExponent
- 14, // 95: ttn.lorawan.v3.MACCommand.RejoinParamSetupReq.max_count_exponent:type_name -> ttn.lorawan.v3.RejoinCountExponent
- 15, // 96: ttn.lorawan.v3.MACCommand.RejoinParamSetupReq.max_time_exponent:type_name -> ttn.lorawan.v3.RejoinTimeExponent
- 13, // 97: ttn.lorawan.v3.MACCommand.PingSlotInfoReq.period:type_name -> ttn.lorawan.v3.PingSlotPeriod
- 4, // 98: ttn.lorawan.v3.MACCommand.PingSlotChannelReq.data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
- 9, // 99: ttn.lorawan.v3.MACCommand.DeviceModeInd.class:type_name -> ttn.lorawan.v3.Class
- 9, // 100: ttn.lorawan.v3.MACCommand.DeviceModeConf.class:type_name -> ttn.lorawan.v3.Class
- 101, // [101:101] is the sub-list for method output_type
- 101, // [101:101] is the sub-list for method input_type
- 101, // [101:101] is the sub-list for extension type_name
- 101, // [101:101] is the sub-list for extension extendee
- 0, // [0:101] is the sub-list for field type_name
+ 115, // 35: ttn.lorawan.v3.TxRequest.absolute_time:type_name -> google.protobuf.Timestamp
+ 114, // 36: ttn.lorawan.v3.TxRequest.advanced:type_name -> google.protobuf.Struct
+ 13, // 37: ttn.lorawan.v3.RelaySecondChannel.ack_offset:type_name -> ttn.lorawan.v3.RelaySecondChAckOffset
+ 4, // 38: ttn.lorawan.v3.RelaySecondChannel.data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
+ 14, // 39: ttn.lorawan.v3.RelayUplinkForwardLimits.bucket_size:type_name -> ttn.lorawan.v3.RelayLimitBucketSize
+ 14, // 40: ttn.lorawan.v3.RelayForwardLimits.bucket_size:type_name -> ttn.lorawan.v3.RelayLimitBucketSize
+ 15, // 41: ttn.lorawan.v3.RelayEndDeviceDynamicMode.smart_enable_level:type_name -> ttn.lorawan.v3.RelaySmartEnableLevel
+ 11, // 42: ttn.lorawan.v3.MACCommand.cid:type_name -> ttn.lorawan.v3.MACCommandIdentifier
+ 71, // 43: ttn.lorawan.v3.MACCommand.reset_ind:type_name -> ttn.lorawan.v3.MACCommand.ResetInd
+ 72, // 44: ttn.lorawan.v3.MACCommand.reset_conf:type_name -> ttn.lorawan.v3.MACCommand.ResetConf
+ 73, // 45: ttn.lorawan.v3.MACCommand.link_check_ans:type_name -> ttn.lorawan.v3.MACCommand.LinkCheckAns
+ 74, // 46: ttn.lorawan.v3.MACCommand.link_adr_req:type_name -> ttn.lorawan.v3.MACCommand.LinkADRReq
+ 75, // 47: ttn.lorawan.v3.MACCommand.link_adr_ans:type_name -> ttn.lorawan.v3.MACCommand.LinkADRAns
+ 76, // 48: ttn.lorawan.v3.MACCommand.duty_cycle_req:type_name -> ttn.lorawan.v3.MACCommand.DutyCycleReq
+ 77, // 49: ttn.lorawan.v3.MACCommand.rx_param_setup_req:type_name -> ttn.lorawan.v3.MACCommand.RxParamSetupReq
+ 78, // 50: ttn.lorawan.v3.MACCommand.rx_param_setup_ans:type_name -> ttn.lorawan.v3.MACCommand.RxParamSetupAns
+ 79, // 51: ttn.lorawan.v3.MACCommand.dev_status_ans:type_name -> ttn.lorawan.v3.MACCommand.DevStatusAns
+ 80, // 52: ttn.lorawan.v3.MACCommand.new_channel_req:type_name -> ttn.lorawan.v3.MACCommand.NewChannelReq
+ 81, // 53: ttn.lorawan.v3.MACCommand.new_channel_ans:type_name -> ttn.lorawan.v3.MACCommand.NewChannelAns
+ 82, // 54: ttn.lorawan.v3.MACCommand.dl_channel_req:type_name -> ttn.lorawan.v3.MACCommand.DLChannelReq
+ 83, // 55: ttn.lorawan.v3.MACCommand.dl_channel_ans:type_name -> ttn.lorawan.v3.MACCommand.DLChannelAns
+ 84, // 56: ttn.lorawan.v3.MACCommand.rx_timing_setup_req:type_name -> ttn.lorawan.v3.MACCommand.RxTimingSetupReq
+ 85, // 57: ttn.lorawan.v3.MACCommand.tx_param_setup_req:type_name -> ttn.lorawan.v3.MACCommand.TxParamSetupReq
+ 86, // 58: ttn.lorawan.v3.MACCommand.rekey_ind:type_name -> ttn.lorawan.v3.MACCommand.RekeyInd
+ 87, // 59: ttn.lorawan.v3.MACCommand.rekey_conf:type_name -> ttn.lorawan.v3.MACCommand.RekeyConf
+ 88, // 60: ttn.lorawan.v3.MACCommand.adr_param_setup_req:type_name -> ttn.lorawan.v3.MACCommand.ADRParamSetupReq
+ 89, // 61: ttn.lorawan.v3.MACCommand.device_time_ans:type_name -> ttn.lorawan.v3.MACCommand.DeviceTimeAns
+ 90, // 62: ttn.lorawan.v3.MACCommand.force_rejoin_req:type_name -> ttn.lorawan.v3.MACCommand.ForceRejoinReq
+ 91, // 63: ttn.lorawan.v3.MACCommand.rejoin_param_setup_req:type_name -> ttn.lorawan.v3.MACCommand.RejoinParamSetupReq
+ 92, // 64: ttn.lorawan.v3.MACCommand.rejoin_param_setup_ans:type_name -> ttn.lorawan.v3.MACCommand.RejoinParamSetupAns
+ 93, // 65: ttn.lorawan.v3.MACCommand.ping_slot_info_req:type_name -> ttn.lorawan.v3.MACCommand.PingSlotInfoReq
+ 94, // 66: ttn.lorawan.v3.MACCommand.ping_slot_channel_req:type_name -> ttn.lorawan.v3.MACCommand.PingSlotChannelReq
+ 95, // 67: ttn.lorawan.v3.MACCommand.ping_slot_channel_ans:type_name -> ttn.lorawan.v3.MACCommand.PingSlotChannelAns
+ 96, // 68: ttn.lorawan.v3.MACCommand.beacon_timing_ans:type_name -> ttn.lorawan.v3.MACCommand.BeaconTimingAns
+ 97, // 69: ttn.lorawan.v3.MACCommand.beacon_freq_req:type_name -> ttn.lorawan.v3.MACCommand.BeaconFreqReq
+ 98, // 70: ttn.lorawan.v3.MACCommand.beacon_freq_ans:type_name -> ttn.lorawan.v3.MACCommand.BeaconFreqAns
+ 99, // 71: ttn.lorawan.v3.MACCommand.device_mode_ind:type_name -> ttn.lorawan.v3.MACCommand.DeviceModeInd
+ 100, // 72: ttn.lorawan.v3.MACCommand.device_mode_conf:type_name -> ttn.lorawan.v3.MACCommand.DeviceModeConf
+ 101, // 73: ttn.lorawan.v3.MACCommand.relay_conf_req:type_name -> ttn.lorawan.v3.MACCommand.RelayConfReq
+ 102, // 74: ttn.lorawan.v3.MACCommand.relay_conf_ans:type_name -> ttn.lorawan.v3.MACCommand.RelayConfAns
+ 103, // 75: ttn.lorawan.v3.MACCommand.relay_end_device_conf_req:type_name -> ttn.lorawan.v3.MACCommand.RelayEndDeviceConfReq
+ 104, // 76: ttn.lorawan.v3.MACCommand.relay_end_device_conf_ans:type_name -> ttn.lorawan.v3.MACCommand.RelayEndDeviceConfAns
+ 105, // 77: ttn.lorawan.v3.MACCommand.relay_update_uplink_list_req:type_name -> ttn.lorawan.v3.MACCommand.RelayUpdateUplinkListReq
+ 106, // 78: ttn.lorawan.v3.MACCommand.relay_update_uplink_list_ans:type_name -> ttn.lorawan.v3.MACCommand.RelayUpdateUplinkListAns
+ 107, // 79: ttn.lorawan.v3.MACCommand.relay_ctrl_uplink_list_req:type_name -> ttn.lorawan.v3.MACCommand.RelayCtrlUplinkListReq
+ 108, // 80: ttn.lorawan.v3.MACCommand.relay_ctrl_uplink_list_ans:type_name -> ttn.lorawan.v3.MACCommand.RelayCtrlUplinkListAns
+ 109, // 81: ttn.lorawan.v3.MACCommand.relay_configure_fwd_limit_req:type_name -> ttn.lorawan.v3.MACCommand.RelayConfigureFwdLimitReq
+ 110, // 82: ttn.lorawan.v3.MACCommand.relay_configure_fwd_limit_ans:type_name -> ttn.lorawan.v3.MACCommand.RelayConfigureFwdLimitAns
+ 111, // 83: ttn.lorawan.v3.MACCommand.relay_notify_new_end_device_req:type_name -> ttn.lorawan.v3.MACCommand.RelayNotifyNewEndDeviceReq
+ 55, // 84: ttn.lorawan.v3.MACCommands.commands:type_name -> ttn.lorawan.v3.MACCommand
+ 5, // 85: ttn.lorawan.v3.DataRateOffsetValue.value:type_name -> ttn.lorawan.v3.DataRateOffset
+ 4, // 86: ttn.lorawan.v3.DataRateIndexValue.value:type_name -> ttn.lorawan.v3.DataRateIndex
+ 20, // 87: ttn.lorawan.v3.PingSlotPeriodValue.value:type_name -> ttn.lorawan.v3.PingSlotPeriod
+ 19, // 88: ttn.lorawan.v3.AggregatedDutyCycleValue.value:type_name -> ttn.lorawan.v3.AggregatedDutyCycle
+ 27, // 89: ttn.lorawan.v3.RxDelayValue.value:type_name -> ttn.lorawan.v3.RxDelay
+ 25, // 90: ttn.lorawan.v3.ADRAckLimitExponentValue.value:type_name -> ttn.lorawan.v3.ADRAckLimitExponent
+ 26, // 91: ttn.lorawan.v3.ADRAckDelayExponentValue.value:type_name -> ttn.lorawan.v3.ADRAckDelayExponent
+ 24, // 92: ttn.lorawan.v3.DeviceEIRPValue.value:type_name -> ttn.lorawan.v3.DeviceEIRP
+ 42, // 93: ttn.lorawan.v3.RelayForwardUplinkReq.data_rate:type_name -> ttn.lorawan.v3.DataRate
+ 16, // 94: ttn.lorawan.v3.RelayForwardUplinkReq.wor_channel:type_name -> ttn.lorawan.v3.RelayWORChannel
+ 117, // 95: ttn.lorawan.v3.RelayUplinkToken.ids:type_name -> ttn.lorawan.v3.EndDeviceIdentifiers
+ 28, // 96: ttn.lorawan.v3.MACCommand.ResetInd.minor_version:type_name -> ttn.lorawan.v3.Minor
+ 28, // 97: ttn.lorawan.v3.MACCommand.ResetConf.minor_version:type_name -> ttn.lorawan.v3.Minor
+ 4, // 98: ttn.lorawan.v3.MACCommand.LinkADRReq.data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
+ 19, // 99: ttn.lorawan.v3.MACCommand.DutyCycleReq.max_duty_cycle:type_name -> ttn.lorawan.v3.AggregatedDutyCycle
+ 4, // 100: ttn.lorawan.v3.MACCommand.RxParamSetupReq.rx2_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
+ 5, // 101: ttn.lorawan.v3.MACCommand.RxParamSetupReq.rx1_data_rate_offset:type_name -> ttn.lorawan.v3.DataRateOffset
+ 4, // 102: ttn.lorawan.v3.MACCommand.NewChannelReq.min_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
+ 4, // 103: ttn.lorawan.v3.MACCommand.NewChannelReq.max_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
+ 27, // 104: ttn.lorawan.v3.MACCommand.RxTimingSetupReq.delay:type_name -> ttn.lorawan.v3.RxDelay
+ 24, // 105: ttn.lorawan.v3.MACCommand.TxParamSetupReq.max_eirp_index:type_name -> ttn.lorawan.v3.DeviceEIRP
+ 28, // 106: ttn.lorawan.v3.MACCommand.RekeyInd.minor_version:type_name -> ttn.lorawan.v3.Minor
+ 28, // 107: ttn.lorawan.v3.MACCommand.RekeyConf.minor_version:type_name -> ttn.lorawan.v3.Minor
+ 25, // 108: ttn.lorawan.v3.MACCommand.ADRParamSetupReq.adr_ack_limit_exponent:type_name -> ttn.lorawan.v3.ADRAckLimitExponent
+ 26, // 109: ttn.lorawan.v3.MACCommand.ADRParamSetupReq.adr_ack_delay_exponent:type_name -> ttn.lorawan.v3.ADRAckDelayExponent
+ 115, // 110: ttn.lorawan.v3.MACCommand.DeviceTimeAns.time:type_name -> google.protobuf.Timestamp
+ 7, // 111: ttn.lorawan.v3.MACCommand.ForceRejoinReq.rejoin_type:type_name -> ttn.lorawan.v3.RejoinRequestType
+ 4, // 112: ttn.lorawan.v3.MACCommand.ForceRejoinReq.data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
+ 23, // 113: ttn.lorawan.v3.MACCommand.ForceRejoinReq.period_exponent:type_name -> ttn.lorawan.v3.RejoinPeriodExponent
+ 21, // 114: ttn.lorawan.v3.MACCommand.RejoinParamSetupReq.max_count_exponent:type_name -> ttn.lorawan.v3.RejoinCountExponent
+ 22, // 115: ttn.lorawan.v3.MACCommand.RejoinParamSetupReq.max_time_exponent:type_name -> ttn.lorawan.v3.RejoinTimeExponent
+ 20, // 116: ttn.lorawan.v3.MACCommand.PingSlotInfoReq.period:type_name -> ttn.lorawan.v3.PingSlotPeriod
+ 4, // 117: ttn.lorawan.v3.MACCommand.PingSlotChannelReq.data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex
+ 9, // 118: ttn.lorawan.v3.MACCommand.DeviceModeInd.class:type_name -> ttn.lorawan.v3.Class
+ 9, // 119: ttn.lorawan.v3.MACCommand.DeviceModeConf.class:type_name -> ttn.lorawan.v3.Class
+ 112, // 120: ttn.lorawan.v3.MACCommand.RelayConfReq.configuration:type_name -> ttn.lorawan.v3.MACCommand.RelayConfReq.Configuration
+ 113, // 121: ttn.lorawan.v3.MACCommand.RelayEndDeviceConfReq.configuration:type_name -> ttn.lorawan.v3.MACCommand.RelayEndDeviceConfReq.Configuration
+ 50, // 122: ttn.lorawan.v3.MACCommand.RelayUpdateUplinkListReq.forward_limits:type_name -> ttn.lorawan.v3.RelayUplinkForwardLimits
+ 18, // 123: ttn.lorawan.v3.MACCommand.RelayCtrlUplinkListReq.action:type_name -> ttn.lorawan.v3.RelayCtrlUplinkListAction
+ 17, // 124: ttn.lorawan.v3.MACCommand.RelayConfigureFwdLimitReq.reset_limit_counter:type_name -> ttn.lorawan.v3.RelayResetLimitCounter
+ 51, // 125: ttn.lorawan.v3.MACCommand.RelayConfigureFwdLimitReq.join_request_limits:type_name -> ttn.lorawan.v3.RelayForwardLimits
+ 51, // 126: ttn.lorawan.v3.MACCommand.RelayConfigureFwdLimitReq.notify_limits:type_name -> ttn.lorawan.v3.RelayForwardLimits
+ 51, // 127: ttn.lorawan.v3.MACCommand.RelayConfigureFwdLimitReq.global_uplink_limits:type_name -> ttn.lorawan.v3.RelayForwardLimits
+ 51, // 128: ttn.lorawan.v3.MACCommand.RelayConfigureFwdLimitReq.overall_limits:type_name -> ttn.lorawan.v3.RelayForwardLimits
+ 49, // 129: ttn.lorawan.v3.MACCommand.RelayConfReq.Configuration.second_channel:type_name -> ttn.lorawan.v3.RelaySecondChannel
+ 12, // 130: ttn.lorawan.v3.MACCommand.RelayConfReq.Configuration.cad_periodicity:type_name -> ttn.lorawan.v3.RelayCADPeriodicity
+ 52, // 131: ttn.lorawan.v3.MACCommand.RelayEndDeviceConfReq.Configuration.always:type_name -> ttn.lorawan.v3.RelayEndDeviceAlwaysMode
+ 53, // 132: ttn.lorawan.v3.MACCommand.RelayEndDeviceConfReq.Configuration.dynamic:type_name -> ttn.lorawan.v3.RelayEndDeviceDynamicMode
+ 54, // 133: ttn.lorawan.v3.MACCommand.RelayEndDeviceConfReq.Configuration.end_device_controlled:type_name -> ttn.lorawan.v3.RelayEndDeviceControlledMode
+ 49, // 134: ttn.lorawan.v3.MACCommand.RelayEndDeviceConfReq.Configuration.second_channel:type_name -> ttn.lorawan.v3.RelaySecondChannel
+ 135, // [135:135] is the sub-list for method output_type
+ 135, // [135:135] is the sub-list for method input_type
+ 135, // [135:135] is the sub-list for extension type_name
+ 135, // [135:135] is the sub-list for extension extendee
+ 0, // [0:135] is the sub-list for field type_name
}
func init() { file_ttn_lorawan_v3_lorawan_proto_init() }
@@ -7597,8 +10074,224 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MHDR); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MHDR); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACPayload); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*FHDR); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*FCtrl); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*JoinRequestPayload); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*RejoinRequestPayload); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*JoinAcceptPayload); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*DLSettings); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*CFList); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*LoRaDataRate); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*FSKDataRate); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*LRFHSSDataRate); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*DataRate); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*TxSettings); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*GatewayAntennaIdentifiers); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ClassBCGatewayIdentifiers); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*UplinkToken); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*DownlinkPath); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*TxRequest); i {
case 0:
return &v.state
case 1:
@@ -7609,8 +10302,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACPayload); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*RelaySecondChannel); i {
case 0:
return &v.state
case 1:
@@ -7621,8 +10314,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*FHDR); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*RelayUplinkForwardLimits); i {
case 0:
return &v.state
case 1:
@@ -7633,8 +10326,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*FCtrl); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*RelayForwardLimits); i {
case 0:
return &v.state
case 1:
@@ -7645,8 +10338,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*JoinRequestPayload); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*RelayEndDeviceAlwaysMode); i {
case 0:
return &v.state
case 1:
@@ -7657,8 +10350,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*RejoinRequestPayload); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*RelayEndDeviceDynamicMode); i {
case 0:
return &v.state
case 1:
@@ -7669,8 +10362,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*JoinAcceptPayload); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*RelayEndDeviceControlledMode); i {
case 0:
return &v.state
case 1:
@@ -7681,8 +10374,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*DLSettings); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand); i {
case 0:
return &v.state
case 1:
@@ -7693,8 +10386,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*CFList); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommands); i {
case 0:
return &v.state
case 1:
@@ -7705,8 +10398,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*LoRaDataRate); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*FrequencyValue); i {
case 0:
return &v.state
case 1:
@@ -7717,8 +10410,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*FSKDataRate); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ZeroableFrequencyValue); i {
case 0:
return &v.state
case 1:
@@ -7729,8 +10422,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*LRFHSSDataRate); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*DataRateOffsetValue); i {
case 0:
return &v.state
case 1:
@@ -7741,8 +10434,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*DataRate); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*DataRateIndexValue); i {
case 0:
return &v.state
case 1:
@@ -7753,8 +10446,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*TxSettings); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*PingSlotPeriodValue); i {
case 0:
return &v.state
case 1:
@@ -7765,8 +10458,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*GatewayAntennaIdentifiers); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*AggregatedDutyCycleValue); i {
case 0:
return &v.state
case 1:
@@ -7777,8 +10470,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*ClassBCGatewayIdentifiers); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*RxDelayValue); i {
case 0:
return &v.state
case 1:
@@ -7789,8 +10482,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*UplinkToken); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ADRAckLimitExponentValue); i {
case 0:
return &v.state
case 1:
@@ -7801,8 +10494,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*DownlinkPath); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ADRAckDelayExponentValue); i {
case 0:
return &v.state
case 1:
@@ -7813,8 +10506,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*TxRequest); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*DeviceEIRPValue); i {
case 0:
return &v.state
case 1:
@@ -7825,8 +10518,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACCommand); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*RelayForwardUplinkReq); i {
case 0:
return &v.state
case 1:
@@ -7837,8 +10530,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACCommands); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*RelayForwardDownlinkReq); i {
case 0:
return &v.state
case 1:
@@ -7849,8 +10542,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*FrequencyValue); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*RelayUplinkToken); i {
case 0:
return &v.state
case 1:
@@ -7861,8 +10554,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*ZeroableFrequencyValue); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*TxSettings_Downlink); i {
case 0:
return &v.state
case 1:
@@ -7873,8 +10566,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*DataRateOffsetValue); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_ResetInd); i {
case 0:
return &v.state
case 1:
@@ -7885,8 +10578,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*DataRateIndexValue); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_ResetConf); i {
case 0:
return &v.state
case 1:
@@ -7897,8 +10590,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*PingSlotPeriodValue); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_LinkCheckAns); i {
case 0:
return &v.state
case 1:
@@ -7909,8 +10602,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*AggregatedDutyCycleValue); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_LinkADRReq); i {
case 0:
return &v.state
case 1:
@@ -7921,8 +10614,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*RxDelayValue); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_LinkADRAns); i {
case 0:
return &v.state
case 1:
@@ -7933,8 +10626,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*ADRAckLimitExponentValue); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_DutyCycleReq); i {
case 0:
return &v.state
case 1:
@@ -7945,8 +10638,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*ADRAckDelayExponentValue); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_RxParamSetupReq); i {
case 0:
return &v.state
case 1:
@@ -7957,8 +10650,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*DeviceEIRPValue); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_RxParamSetupAns); i {
case 0:
return &v.state
case 1:
@@ -7969,8 +10662,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*TxSettings_Downlink); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_DevStatusAns); i {
case 0:
return &v.state
case 1:
@@ -7981,8 +10674,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACCommand_ResetInd); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[51].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_NewChannelReq); i {
case 0:
return &v.state
case 1:
@@ -7993,8 +10686,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACCommand_ResetConf); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[52].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_NewChannelAns); i {
case 0:
return &v.state
case 1:
@@ -8005,8 +10698,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACCommand_LinkCheckAns); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[53].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_DLChannelReq); i {
case 0:
return &v.state
case 1:
@@ -8017,8 +10710,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACCommand_LinkADRReq); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[54].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_DLChannelAns); i {
case 0:
return &v.state
case 1:
@@ -8029,8 +10722,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACCommand_LinkADRAns); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[55].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_RxTimingSetupReq); i {
case 0:
return &v.state
case 1:
@@ -8041,8 +10734,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACCommand_DutyCycleReq); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[56].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_TxParamSetupReq); i {
case 0:
return &v.state
case 1:
@@ -8053,8 +10746,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACCommand_RxParamSetupReq); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[57].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_RekeyInd); i {
case 0:
return &v.state
case 1:
@@ -8065,8 +10758,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACCommand_RxParamSetupAns); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[58].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_RekeyConf); i {
case 0:
return &v.state
case 1:
@@ -8077,8 +10770,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACCommand_DevStatusAns); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[59].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_ADRParamSetupReq); i {
case 0:
return &v.state
case 1:
@@ -8089,8 +10782,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACCommand_NewChannelReq); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[60].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_DeviceTimeAns); i {
case 0:
return &v.state
case 1:
@@ -8101,8 +10794,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACCommand_NewChannelAns); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[61].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_ForceRejoinReq); i {
case 0:
return &v.state
case 1:
@@ -8113,8 +10806,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACCommand_DLChannelReq); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[62].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_RejoinParamSetupReq); i {
case 0:
return &v.state
case 1:
@@ -8125,8 +10818,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACCommand_DLChannelAns); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[63].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_RejoinParamSetupAns); i {
case 0:
return &v.state
case 1:
@@ -8137,8 +10830,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACCommand_RxTimingSetupReq); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[64].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_PingSlotInfoReq); i {
case 0:
return &v.state
case 1:
@@ -8149,8 +10842,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACCommand_TxParamSetupReq); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[65].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_PingSlotChannelReq); i {
case 0:
return &v.state
case 1:
@@ -8161,8 +10854,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACCommand_RekeyInd); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[66].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_PingSlotChannelAns); i {
case 0:
return &v.state
case 1:
@@ -8173,8 +10866,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACCommand_RekeyConf); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[67].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_BeaconTimingAns); i {
case 0:
return &v.state
case 1:
@@ -8185,8 +10878,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACCommand_ADRParamSetupReq); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[68].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_BeaconFreqReq); i {
case 0:
return &v.state
case 1:
@@ -8197,8 +10890,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[51].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACCommand_DeviceTimeAns); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[69].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_BeaconFreqAns); i {
case 0:
return &v.state
case 1:
@@ -8209,8 +10902,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[52].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACCommand_ForceRejoinReq); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[70].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_DeviceModeInd); i {
case 0:
return &v.state
case 1:
@@ -8221,8 +10914,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[53].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACCommand_RejoinParamSetupReq); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[71].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_DeviceModeConf); i {
case 0:
return &v.state
case 1:
@@ -8233,8 +10926,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[54].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACCommand_RejoinParamSetupAns); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[72].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_RelayConfReq); i {
case 0:
return &v.state
case 1:
@@ -8245,8 +10938,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[55].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACCommand_PingSlotInfoReq); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[73].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_RelayConfAns); i {
case 0:
return &v.state
case 1:
@@ -8257,8 +10950,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[56].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACCommand_PingSlotChannelReq); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[74].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_RelayEndDeviceConfReq); i {
case 0:
return &v.state
case 1:
@@ -8269,8 +10962,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[57].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACCommand_PingSlotChannelAns); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[75].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_RelayEndDeviceConfAns); i {
case 0:
return &v.state
case 1:
@@ -8281,8 +10974,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[58].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACCommand_BeaconTimingAns); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[76].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_RelayUpdateUplinkListReq); i {
case 0:
return &v.state
case 1:
@@ -8293,8 +10986,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[59].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACCommand_BeaconFreqReq); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[77].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_RelayUpdateUplinkListAns); i {
case 0:
return &v.state
case 1:
@@ -8305,8 +10998,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[60].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACCommand_BeaconFreqAns); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[78].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_RelayCtrlUplinkListReq); i {
case 0:
return &v.state
case 1:
@@ -8317,8 +11010,8 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[61].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACCommand_DeviceModeInd); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[79].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_RelayCtrlUplinkListAns); i {
case 0:
return &v.state
case 1:
@@ -8329,8 +11022,56 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
return nil
}
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[62].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*MACCommand_DeviceModeConf); i {
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[80].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_RelayConfigureFwdLimitReq); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[81].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_RelayConfigureFwdLimitAns); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[82].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_RelayNotifyNewEndDeviceReq); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[83].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_RelayConfReq_Configuration); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[84].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MACCommand_RelayEndDeviceConfReq_Configuration); i {
case 0:
return &v.state
case 1:
@@ -8357,7 +11098,7 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
(*DownlinkPath_UplinkToken)(nil),
(*DownlinkPath_Fixed)(nil),
}
- file_ttn_lorawan_v3_lorawan_proto_msgTypes[20].OneofWrappers = []interface{}{
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[26].OneofWrappers = []interface{}{
(*MACCommand_RawPayload)(nil),
(*MACCommand_ResetInd_)(nil),
(*MACCommand_ResetConf_)(nil),
@@ -8389,14 +11130,30 @@ func file_ttn_lorawan_v3_lorawan_proto_init() {
(*MACCommand_BeaconFreqAns_)(nil),
(*MACCommand_DeviceModeInd_)(nil),
(*MACCommand_DeviceModeConf_)(nil),
+ (*MACCommand_RelayConfReq_)(nil),
+ (*MACCommand_RelayConfAns_)(nil),
+ (*MACCommand_RelayEndDeviceConfReq_)(nil),
+ (*MACCommand_RelayEndDeviceConfAns_)(nil),
+ (*MACCommand_RelayUpdateUplinkListReq_)(nil),
+ (*MACCommand_RelayUpdateUplinkListAns_)(nil),
+ (*MACCommand_RelayCtrlUplinkListReq_)(nil),
+ (*MACCommand_RelayCtrlUplinkListAns_)(nil),
+ (*MACCommand_RelayConfigureFwdLimitReq_)(nil),
+ (*MACCommand_RelayConfigureFwdLimitAns_)(nil),
+ (*MACCommand_RelayNotifyNewEndDeviceReq_)(nil),
+ }
+ file_ttn_lorawan_v3_lorawan_proto_msgTypes[84].OneofWrappers = []interface{}{
+ (*MACCommand_RelayEndDeviceConfReq_Configuration_Always)(nil),
+ (*MACCommand_RelayEndDeviceConfReq_Configuration_Dynamic)(nil),
+ (*MACCommand_RelayEndDeviceConfReq_Configuration_EndDeviceControlled)(nil),
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_ttn_lorawan_v3_lorawan_proto_rawDesc,
- NumEnums: 22,
- NumMessages: 63,
+ NumEnums: 29,
+ NumMessages: 85,
NumExtensions: 0,
NumServices: 0,
},
diff --git a/pkg/ttnpb/lorawan.pb.paths.fm.go b/pkg/ttnpb/lorawan.pb.paths.fm.go
index 477846bc13..ca77ac871e 100644
--- a/pkg/ttnpb/lorawan.pb.paths.fm.go
+++ b/pkg/ttnpb/lorawan.pb.paths.fm.go
@@ -377,6 +377,46 @@ var TxRequestFieldPathsTopLevel = []string{
"rx2_data_rate",
"rx2_frequency",
}
+var RelaySecondChannelFieldPathsNested = []string{
+ "ack_offset",
+ "data_rate_index",
+ "frequency",
+}
+
+var RelaySecondChannelFieldPathsTopLevel = []string{
+ "ack_offset",
+ "data_rate_index",
+ "frequency",
+}
+var RelayUplinkForwardLimitsFieldPathsNested = []string{
+ "bucket_size",
+ "reload_rate",
+}
+
+var RelayUplinkForwardLimitsFieldPathsTopLevel = []string{
+ "bucket_size",
+ "reload_rate",
+}
+var RelayForwardLimitsFieldPathsNested = []string{
+ "bucket_size",
+ "reload_rate",
+}
+
+var RelayForwardLimitsFieldPathsTopLevel = []string{
+ "bucket_size",
+ "reload_rate",
+}
+var RelayEndDeviceAlwaysModeFieldPathsNested []string
+var RelayEndDeviceAlwaysModeFieldPathsTopLevel []string
+var RelayEndDeviceDynamicModeFieldPathsNested = []string{
+ "smart_enable_level",
+}
+
+var RelayEndDeviceDynamicModeFieldPathsTopLevel = []string{
+ "smart_enable_level",
+}
+var RelayEndDeviceControlledModeFieldPathsNested []string
+var RelayEndDeviceControlledModeFieldPathsTopLevel []string
var MACCommandFieldPathsNested = []string{
"cid",
"payload",
@@ -451,6 +491,75 @@ var MACCommandFieldPathsNested = []string{
"payload.rekey_conf.minor_version",
"payload.rekey_ind",
"payload.rekey_ind.minor_version",
+ "payload.relay_conf_ans",
+ "payload.relay_conf_ans.cad_periodicity_ack",
+ "payload.relay_conf_ans.default_channel_index_ack",
+ "payload.relay_conf_ans.second_channel_ack_offset_ack",
+ "payload.relay_conf_ans.second_channel_data_rate_index_ack",
+ "payload.relay_conf_ans.second_channel_frequency_ack",
+ "payload.relay_conf_ans.second_channel_index_ack",
+ "payload.relay_conf_req",
+ "payload.relay_conf_req.configuration",
+ "payload.relay_conf_req.configuration.cad_periodicity",
+ "payload.relay_conf_req.configuration.default_channel_index",
+ "payload.relay_conf_req.configuration.second_channel",
+ "payload.relay_conf_req.configuration.second_channel.ack_offset",
+ "payload.relay_conf_req.configuration.second_channel.data_rate_index",
+ "payload.relay_conf_req.configuration.second_channel.frequency",
+ "payload.relay_configure_fwd_limit_ans",
+ "payload.relay_configure_fwd_limit_req",
+ "payload.relay_configure_fwd_limit_req.global_uplink_limits",
+ "payload.relay_configure_fwd_limit_req.global_uplink_limits.bucket_size",
+ "payload.relay_configure_fwd_limit_req.global_uplink_limits.reload_rate",
+ "payload.relay_configure_fwd_limit_req.join_request_limits",
+ "payload.relay_configure_fwd_limit_req.join_request_limits.bucket_size",
+ "payload.relay_configure_fwd_limit_req.join_request_limits.reload_rate",
+ "payload.relay_configure_fwd_limit_req.notify_limits",
+ "payload.relay_configure_fwd_limit_req.notify_limits.bucket_size",
+ "payload.relay_configure_fwd_limit_req.notify_limits.reload_rate",
+ "payload.relay_configure_fwd_limit_req.overall_limits",
+ "payload.relay_configure_fwd_limit_req.overall_limits.bucket_size",
+ "payload.relay_configure_fwd_limit_req.overall_limits.reload_rate",
+ "payload.relay_configure_fwd_limit_req.reset_limit_counter",
+ "payload.relay_ctrl_uplink_list_ans",
+ "payload.relay_ctrl_uplink_list_ans.rule_index_ack",
+ "payload.relay_ctrl_uplink_list_ans.w_f_cnt",
+ "payload.relay_ctrl_uplink_list_req",
+ "payload.relay_ctrl_uplink_list_req.action",
+ "payload.relay_ctrl_uplink_list_req.rule_index",
+ "payload.relay_end_device_conf_ans",
+ "payload.relay_end_device_conf_ans.backoff_ack",
+ "payload.relay_end_device_conf_ans.second_channel_data_rate_index_ack",
+ "payload.relay_end_device_conf_ans.second_channel_frequency_ack",
+ "payload.relay_end_device_conf_ans.second_channel_index_ack",
+ "payload.relay_end_device_conf_req",
+ "payload.relay_end_device_conf_req.configuration",
+ "payload.relay_end_device_conf_req.configuration.backoff",
+ "payload.relay_end_device_conf_req.configuration.mode",
+ "payload.relay_end_device_conf_req.configuration.mode.always",
+ "payload.relay_end_device_conf_req.configuration.mode.dynamic",
+ "payload.relay_end_device_conf_req.configuration.mode.dynamic.smart_enable_level",
+ "payload.relay_end_device_conf_req.configuration.mode.end_device_controlled",
+ "payload.relay_end_device_conf_req.configuration.second_channel",
+ "payload.relay_end_device_conf_req.configuration.second_channel.ack_offset",
+ "payload.relay_end_device_conf_req.configuration.second_channel.data_rate_index",
+ "payload.relay_end_device_conf_req.configuration.second_channel.frequency",
+ "payload.relay_end_device_conf_req.configuration.serving_device_id",
+ "payload.relay_notify_new_end_device_req",
+ "payload.relay_notify_new_end_device_req.dev_addr",
+ "payload.relay_notify_new_end_device_req.rssi",
+ "payload.relay_notify_new_end_device_req.snr",
+ "payload.relay_update_uplink_list_ans",
+ "payload.relay_update_uplink_list_req",
+ "payload.relay_update_uplink_list_req.dev_addr",
+ "payload.relay_update_uplink_list_req.device_id",
+ "payload.relay_update_uplink_list_req.forward_limits",
+ "payload.relay_update_uplink_list_req.forward_limits.bucket_size",
+ "payload.relay_update_uplink_list_req.forward_limits.reload_rate",
+ "payload.relay_update_uplink_list_req.root_wor_s_key",
+ "payload.relay_update_uplink_list_req.rule_index",
+ "payload.relay_update_uplink_list_req.session_key_id",
+ "payload.relay_update_uplink_list_req.w_f_cnt",
"payload.reset_conf",
"payload.reset_conf.minor_version",
"payload.reset_ind",
@@ -552,6 +661,58 @@ var DeviceEIRPValueFieldPathsNested = []string{
var DeviceEIRPValueFieldPathsTopLevel = []string{
"value",
}
+var RelayForwardUplinkReqFieldPathsNested = []string{
+ "data_rate",
+ "data_rate.modulation",
+ "data_rate.modulation.fsk",
+ "data_rate.modulation.fsk.bit_rate",
+ "data_rate.modulation.lora",
+ "data_rate.modulation.lora.bandwidth",
+ "data_rate.modulation.lora.coding_rate",
+ "data_rate.modulation.lora.spreading_factor",
+ "data_rate.modulation.lrfhss",
+ "data_rate.modulation.lrfhss.coding_rate",
+ "data_rate.modulation.lrfhss.modulation_type",
+ "data_rate.modulation.lrfhss.operating_channel_width",
+ "frequency",
+ "raw_payload",
+ "rssi",
+ "snr",
+ "wor_channel",
+}
+
+var RelayForwardUplinkReqFieldPathsTopLevel = []string{
+ "data_rate",
+ "frequency",
+ "raw_payload",
+ "rssi",
+ "snr",
+ "wor_channel",
+}
+var RelayForwardDownlinkReqFieldPathsNested = []string{
+ "raw_payload",
+}
+
+var RelayForwardDownlinkReqFieldPathsTopLevel = []string{
+ "raw_payload",
+}
+var RelayUplinkTokenFieldPathsNested = []string{
+ "full_f_cnt",
+ "ids",
+ "ids.application_ids",
+ "ids.application_ids.application_id",
+ "ids.dev_addr",
+ "ids.dev_eui",
+ "ids.device_id",
+ "ids.join_eui",
+ "session_key_id",
+}
+
+var RelayUplinkTokenFieldPathsTopLevel = []string{
+ "full_f_cnt",
+ "ids",
+ "session_key_id",
+}
var TxSettings_DownlinkFieldPathsNested = []string{
"antenna_index",
"invert_polarization",
@@ -829,3 +990,175 @@ var MACCommand_DeviceModeConfFieldPathsNested = []string{
var MACCommand_DeviceModeConfFieldPathsTopLevel = []string{
"class",
}
+var MACCommand_RelayConfReqFieldPathsNested = []string{
+ "configuration",
+ "configuration.cad_periodicity",
+ "configuration.default_channel_index",
+ "configuration.second_channel",
+ "configuration.second_channel.ack_offset",
+ "configuration.second_channel.data_rate_index",
+ "configuration.second_channel.frequency",
+}
+
+var MACCommand_RelayConfReqFieldPathsTopLevel = []string{
+ "configuration",
+}
+var MACCommand_RelayConfAnsFieldPathsNested = []string{
+ "cad_periodicity_ack",
+ "default_channel_index_ack",
+ "second_channel_ack_offset_ack",
+ "second_channel_data_rate_index_ack",
+ "second_channel_frequency_ack",
+ "second_channel_index_ack",
+}
+
+var MACCommand_RelayConfAnsFieldPathsTopLevel = []string{
+ "cad_periodicity_ack",
+ "default_channel_index_ack",
+ "second_channel_ack_offset_ack",
+ "second_channel_data_rate_index_ack",
+ "second_channel_frequency_ack",
+ "second_channel_index_ack",
+}
+var MACCommand_RelayEndDeviceConfReqFieldPathsNested = []string{
+ "configuration",
+ "configuration.backoff",
+ "configuration.mode",
+ "configuration.mode.always",
+ "configuration.mode.dynamic",
+ "configuration.mode.dynamic.smart_enable_level",
+ "configuration.mode.end_device_controlled",
+ "configuration.second_channel",
+ "configuration.second_channel.ack_offset",
+ "configuration.second_channel.data_rate_index",
+ "configuration.second_channel.frequency",
+ "configuration.serving_device_id",
+}
+
+var MACCommand_RelayEndDeviceConfReqFieldPathsTopLevel = []string{
+ "configuration",
+}
+var MACCommand_RelayEndDeviceConfAnsFieldPathsNested = []string{
+ "backoff_ack",
+ "second_channel_data_rate_index_ack",
+ "second_channel_frequency_ack",
+ "second_channel_index_ack",
+}
+
+var MACCommand_RelayEndDeviceConfAnsFieldPathsTopLevel = []string{
+ "backoff_ack",
+ "second_channel_data_rate_index_ack",
+ "second_channel_frequency_ack",
+ "second_channel_index_ack",
+}
+var MACCommand_RelayUpdateUplinkListReqFieldPathsNested = []string{
+ "dev_addr",
+ "device_id",
+ "forward_limits",
+ "forward_limits.bucket_size",
+ "forward_limits.reload_rate",
+ "root_wor_s_key",
+ "rule_index",
+ "session_key_id",
+ "w_f_cnt",
+}
+
+var MACCommand_RelayUpdateUplinkListReqFieldPathsTopLevel = []string{
+ "dev_addr",
+ "device_id",
+ "forward_limits",
+ "root_wor_s_key",
+ "rule_index",
+ "session_key_id",
+ "w_f_cnt",
+}
+var MACCommand_RelayUpdateUplinkListAnsFieldPathsNested []string
+var MACCommand_RelayUpdateUplinkListAnsFieldPathsTopLevel []string
+var MACCommand_RelayCtrlUplinkListReqFieldPathsNested = []string{
+ "action",
+ "rule_index",
+}
+
+var MACCommand_RelayCtrlUplinkListReqFieldPathsTopLevel = []string{
+ "action",
+ "rule_index",
+}
+var MACCommand_RelayCtrlUplinkListAnsFieldPathsNested = []string{
+ "rule_index_ack",
+ "w_f_cnt",
+}
+
+var MACCommand_RelayCtrlUplinkListAnsFieldPathsTopLevel = []string{
+ "rule_index_ack",
+ "w_f_cnt",
+}
+var MACCommand_RelayConfigureFwdLimitReqFieldPathsNested = []string{
+ "global_uplink_limits",
+ "global_uplink_limits.bucket_size",
+ "global_uplink_limits.reload_rate",
+ "join_request_limits",
+ "join_request_limits.bucket_size",
+ "join_request_limits.reload_rate",
+ "notify_limits",
+ "notify_limits.bucket_size",
+ "notify_limits.reload_rate",
+ "overall_limits",
+ "overall_limits.bucket_size",
+ "overall_limits.reload_rate",
+ "reset_limit_counter",
+}
+
+var MACCommand_RelayConfigureFwdLimitReqFieldPathsTopLevel = []string{
+ "global_uplink_limits",
+ "join_request_limits",
+ "notify_limits",
+ "overall_limits",
+ "reset_limit_counter",
+}
+var MACCommand_RelayConfigureFwdLimitAnsFieldPathsNested []string
+var MACCommand_RelayConfigureFwdLimitAnsFieldPathsTopLevel []string
+var MACCommand_RelayNotifyNewEndDeviceReqFieldPathsNested = []string{
+ "dev_addr",
+ "rssi",
+ "snr",
+}
+
+var MACCommand_RelayNotifyNewEndDeviceReqFieldPathsTopLevel = []string{
+ "dev_addr",
+ "rssi",
+ "snr",
+}
+var MACCommand_RelayConfReq_ConfigurationFieldPathsNested = []string{
+ "cad_periodicity",
+ "default_channel_index",
+ "second_channel",
+ "second_channel.ack_offset",
+ "second_channel.data_rate_index",
+ "second_channel.frequency",
+}
+
+var MACCommand_RelayConfReq_ConfigurationFieldPathsTopLevel = []string{
+ "cad_periodicity",
+ "default_channel_index",
+ "second_channel",
+}
+var MACCommand_RelayEndDeviceConfReq_ConfigurationFieldPathsNested = []string{
+ "backoff",
+ "mode",
+ "mode.always",
+ "mode.dynamic",
+ "mode.dynamic.smart_enable_level",
+ "mode.end_device_controlled",
+ "second_channel",
+ "second_channel.ack_offset",
+ "second_channel.data_rate_index",
+ "second_channel.frequency",
+ "serving_device_id",
+}
+
+var MACCommand_RelayEndDeviceConfReq_ConfigurationFieldPathsTopLevel = []string{
+ "backoff",
+ "mode",
+ "second_channel",
+ "serving_device_id",
+}
diff --git a/pkg/ttnpb/lorawan.pb.setters.fm.go b/pkg/ttnpb/lorawan.pb.setters.fm.go
index cfba782da7..69b540cbae 100644
--- a/pkg/ttnpb/lorawan.pb.setters.fm.go
+++ b/pkg/ttnpb/lorawan.pb.setters.fm.go
@@ -1482,6 +1482,139 @@ func (dst *TxRequest) SetFields(src *TxRequest, paths ...string) error {
return nil
}
+func (dst *RelaySecondChannel) SetFields(src *RelaySecondChannel, paths ...string) error {
+ for name, subs := range _processPaths(paths) {
+ switch name {
+ case "ack_offset":
+ if len(subs) > 0 {
+ return fmt.Errorf("'ack_offset' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.AckOffset = src.AckOffset
+ } else {
+ dst.AckOffset = 0
+ }
+ case "data_rate_index":
+ if len(subs) > 0 {
+ return fmt.Errorf("'data_rate_index' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.DataRateIndex = src.DataRateIndex
+ } else {
+ dst.DataRateIndex = 0
+ }
+ case "frequency":
+ if len(subs) > 0 {
+ return fmt.Errorf("'frequency' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.Frequency = src.Frequency
+ } else {
+ var zero uint64
+ dst.Frequency = zero
+ }
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *RelayUplinkForwardLimits) SetFields(src *RelayUplinkForwardLimits, paths ...string) error {
+ for name, subs := range _processPaths(paths) {
+ switch name {
+ case "bucket_size":
+ if len(subs) > 0 {
+ return fmt.Errorf("'bucket_size' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.BucketSize = src.BucketSize
+ } else {
+ dst.BucketSize = 0
+ }
+ case "reload_rate":
+ if len(subs) > 0 {
+ return fmt.Errorf("'reload_rate' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.ReloadRate = src.ReloadRate
+ } else {
+ var zero uint32
+ dst.ReloadRate = zero
+ }
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *RelayForwardLimits) SetFields(src *RelayForwardLimits, paths ...string) error {
+ for name, subs := range _processPaths(paths) {
+ switch name {
+ case "bucket_size":
+ if len(subs) > 0 {
+ return fmt.Errorf("'bucket_size' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.BucketSize = src.BucketSize
+ } else {
+ dst.BucketSize = 0
+ }
+ case "reload_rate":
+ if len(subs) > 0 {
+ return fmt.Errorf("'reload_rate' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.ReloadRate = src.ReloadRate
+ } else {
+ var zero uint32
+ dst.ReloadRate = zero
+ }
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *RelayEndDeviceAlwaysMode) SetFields(src *RelayEndDeviceAlwaysMode, paths ...string) error {
+ if len(paths) != 0 {
+ return fmt.Errorf("message RelayEndDeviceAlwaysMode has no fields, but paths %s were specified", paths)
+ }
+ return nil
+}
+
+func (dst *RelayEndDeviceDynamicMode) SetFields(src *RelayEndDeviceDynamicMode, paths ...string) error {
+ for name, subs := range _processPaths(paths) {
+ switch name {
+ case "smart_enable_level":
+ if len(subs) > 0 {
+ return fmt.Errorf("'smart_enable_level' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.SmartEnableLevel = src.SmartEnableLevel
+ } else {
+ dst.SmartEnableLevel = 0
+ }
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *RelayEndDeviceControlledMode) SetFields(src *RelayEndDeviceControlledMode, paths ...string) error {
+ if len(paths) != 0 {
+ return fmt.Errorf("message RelayEndDeviceControlledMode has no fields, but paths %s were specified", paths)
+ }
+ return nil
+}
+
func (dst *MACCommand) SetFields(src *MACCommand, paths ...string) error {
for name, subs := range _processPaths(paths) {
switch name {
@@ -2610,172 +2743,999 @@ func (dst *MACCommand) SetFields(src *MACCommand, paths ...string) error {
dst.Payload = nil
}
}
-
- default:
- return fmt.Errorf("invalid oneof field: '%s.%s'", name, oneofName)
- }
- }
-
- default:
- return fmt.Errorf("invalid field: '%s'", name)
- }
- }
- return nil
-}
-
-func (dst *MACCommands) SetFields(src *MACCommands, paths ...string) error {
- for name, subs := range _processPaths(paths) {
- switch name {
- case "commands":
- if len(subs) > 0 {
- return fmt.Errorf("'commands' has no subfields, but %s were specified", subs)
- }
- if src != nil {
- dst.Commands = src.Commands
- } else {
- dst.Commands = nil
- }
-
- default:
- return fmt.Errorf("invalid field: '%s'", name)
- }
- }
- return nil
-}
-
-func (dst *FrequencyValue) SetFields(src *FrequencyValue, paths ...string) error {
- for name, subs := range _processPaths(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 uint64
- dst.Value = zero
- }
-
- default:
- return fmt.Errorf("invalid field: '%s'", name)
- }
- }
- return nil
-}
-
-func (dst *ZeroableFrequencyValue) SetFields(src *ZeroableFrequencyValue, paths ...string) error {
- for name, subs := range _processPaths(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 uint64
- dst.Value = zero
- }
-
- default:
- return fmt.Errorf("invalid field: '%s'", name)
- }
- }
- return nil
-}
-
-func (dst *DataRateOffsetValue) SetFields(src *DataRateOffsetValue, paths ...string) error {
- for name, subs := range _processPaths(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 {
- dst.Value = 0
- }
-
- default:
- return fmt.Errorf("invalid field: '%s'", name)
- }
- }
- return nil
-}
-
-func (dst *DataRateIndexValue) SetFields(src *DataRateIndexValue, paths ...string) error {
- for name, subs := range _processPaths(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 {
- dst.Value = 0
- }
-
- default:
- return fmt.Errorf("invalid field: '%s'", name)
- }
- }
- return nil
-}
-
-func (dst *PingSlotPeriodValue) SetFields(src *PingSlotPeriodValue, paths ...string) error {
- for name, subs := range _processPaths(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 {
- dst.Value = 0
- }
-
- default:
- return fmt.Errorf("invalid field: '%s'", name)
- }
- }
- return nil
-}
-
-func (dst *AggregatedDutyCycleValue) SetFields(src *AggregatedDutyCycleValue, paths ...string) error {
- for name, subs := range _processPaths(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 {
- dst.Value = 0
- }
-
- default:
- return fmt.Errorf("invalid field: '%s'", name)
- }
- }
- return nil
-}
-
-func (dst *RxDelayValue) SetFields(src *RxDelayValue, paths ...string) error {
- for name, subs := range _processPaths(paths) {
+ case "relay_conf_req":
+ var srcTypeOk bool
+ if src != nil {
+ _, srcTypeOk = src.Payload.(*MACCommand_RelayConfReq_)
+ }
+ if srcValid := srcTypeOk || src == nil || src.Payload == nil || len(oneofSubs) == 0; !srcValid {
+ return fmt.Errorf("attempt to set oneof 'relay_conf_req', while different oneof is set in source")
+ }
+ _, dstTypeOk := dst.Payload.(*MACCommand_RelayConfReq_)
+ if dstValid := dstTypeOk || dst.Payload == nil || len(oneofSubs) == 0; !dstValid {
+ return fmt.Errorf("attempt to set oneof 'relay_conf_req', while different oneof is set in destination")
+ }
+ if len(oneofSubs) > 0 {
+ var newDst, newSrc *MACCommand_RelayConfReq
+ if srcTypeOk {
+ newSrc = src.Payload.(*MACCommand_RelayConfReq_).RelayConfReq
+ }
+ if dstTypeOk {
+ newDst = dst.Payload.(*MACCommand_RelayConfReq_).RelayConfReq
+ } else if srcTypeOk {
+ newDst = &MACCommand_RelayConfReq{}
+ dst.Payload = &MACCommand_RelayConfReq_{RelayConfReq: newDst}
+ } else {
+ dst.Payload = nil
+ continue
+ }
+ if err := newDst.SetFields(newSrc, oneofSubs...); err != nil {
+ return err
+ }
+ } else {
+ if srcTypeOk {
+ dst.Payload = src.Payload
+ } else {
+ dst.Payload = nil
+ }
+ }
+ case "relay_conf_ans":
+ var srcTypeOk bool
+ if src != nil {
+ _, srcTypeOk = src.Payload.(*MACCommand_RelayConfAns_)
+ }
+ if srcValid := srcTypeOk || src == nil || src.Payload == nil || len(oneofSubs) == 0; !srcValid {
+ return fmt.Errorf("attempt to set oneof 'relay_conf_ans', while different oneof is set in source")
+ }
+ _, dstTypeOk := dst.Payload.(*MACCommand_RelayConfAns_)
+ if dstValid := dstTypeOk || dst.Payload == nil || len(oneofSubs) == 0; !dstValid {
+ return fmt.Errorf("attempt to set oneof 'relay_conf_ans', while different oneof is set in destination")
+ }
+ if len(oneofSubs) > 0 {
+ var newDst, newSrc *MACCommand_RelayConfAns
+ if srcTypeOk {
+ newSrc = src.Payload.(*MACCommand_RelayConfAns_).RelayConfAns
+ }
+ if dstTypeOk {
+ newDst = dst.Payload.(*MACCommand_RelayConfAns_).RelayConfAns
+ } else if srcTypeOk {
+ newDst = &MACCommand_RelayConfAns{}
+ dst.Payload = &MACCommand_RelayConfAns_{RelayConfAns: newDst}
+ } else {
+ dst.Payload = nil
+ continue
+ }
+ if err := newDst.SetFields(newSrc, oneofSubs...); err != nil {
+ return err
+ }
+ } else {
+ if srcTypeOk {
+ dst.Payload = src.Payload
+ } else {
+ dst.Payload = nil
+ }
+ }
+ case "relay_end_device_conf_req":
+ var srcTypeOk bool
+ if src != nil {
+ _, srcTypeOk = src.Payload.(*MACCommand_RelayEndDeviceConfReq_)
+ }
+ if srcValid := srcTypeOk || src == nil || src.Payload == nil || len(oneofSubs) == 0; !srcValid {
+ return fmt.Errorf("attempt to set oneof 'relay_end_device_conf_req', while different oneof is set in source")
+ }
+ _, dstTypeOk := dst.Payload.(*MACCommand_RelayEndDeviceConfReq_)
+ if dstValid := dstTypeOk || dst.Payload == nil || len(oneofSubs) == 0; !dstValid {
+ return fmt.Errorf("attempt to set oneof 'relay_end_device_conf_req', while different oneof is set in destination")
+ }
+ if len(oneofSubs) > 0 {
+ var newDst, newSrc *MACCommand_RelayEndDeviceConfReq
+ if srcTypeOk {
+ newSrc = src.Payload.(*MACCommand_RelayEndDeviceConfReq_).RelayEndDeviceConfReq
+ }
+ if dstTypeOk {
+ newDst = dst.Payload.(*MACCommand_RelayEndDeviceConfReq_).RelayEndDeviceConfReq
+ } else if srcTypeOk {
+ newDst = &MACCommand_RelayEndDeviceConfReq{}
+ dst.Payload = &MACCommand_RelayEndDeviceConfReq_{RelayEndDeviceConfReq: newDst}
+ } else {
+ dst.Payload = nil
+ continue
+ }
+ if err := newDst.SetFields(newSrc, oneofSubs...); err != nil {
+ return err
+ }
+ } else {
+ if srcTypeOk {
+ dst.Payload = src.Payload
+ } else {
+ dst.Payload = nil
+ }
+ }
+ case "relay_end_device_conf_ans":
+ var srcTypeOk bool
+ if src != nil {
+ _, srcTypeOk = src.Payload.(*MACCommand_RelayEndDeviceConfAns_)
+ }
+ if srcValid := srcTypeOk || src == nil || src.Payload == nil || len(oneofSubs) == 0; !srcValid {
+ return fmt.Errorf("attempt to set oneof 'relay_end_device_conf_ans', while different oneof is set in source")
+ }
+ _, dstTypeOk := dst.Payload.(*MACCommand_RelayEndDeviceConfAns_)
+ if dstValid := dstTypeOk || dst.Payload == nil || len(oneofSubs) == 0; !dstValid {
+ return fmt.Errorf("attempt to set oneof 'relay_end_device_conf_ans', while different oneof is set in destination")
+ }
+ if len(oneofSubs) > 0 {
+ var newDst, newSrc *MACCommand_RelayEndDeviceConfAns
+ if srcTypeOk {
+ newSrc = src.Payload.(*MACCommand_RelayEndDeviceConfAns_).RelayEndDeviceConfAns
+ }
+ if dstTypeOk {
+ newDst = dst.Payload.(*MACCommand_RelayEndDeviceConfAns_).RelayEndDeviceConfAns
+ } else if srcTypeOk {
+ newDst = &MACCommand_RelayEndDeviceConfAns{}
+ dst.Payload = &MACCommand_RelayEndDeviceConfAns_{RelayEndDeviceConfAns: newDst}
+ } else {
+ dst.Payload = nil
+ continue
+ }
+ if err := newDst.SetFields(newSrc, oneofSubs...); err != nil {
+ return err
+ }
+ } else {
+ if srcTypeOk {
+ dst.Payload = src.Payload
+ } else {
+ dst.Payload = nil
+ }
+ }
+ case "relay_update_uplink_list_req":
+ var srcTypeOk bool
+ if src != nil {
+ _, srcTypeOk = src.Payload.(*MACCommand_RelayUpdateUplinkListReq_)
+ }
+ if srcValid := srcTypeOk || src == nil || src.Payload == nil || len(oneofSubs) == 0; !srcValid {
+ return fmt.Errorf("attempt to set oneof 'relay_update_uplink_list_req', while different oneof is set in source")
+ }
+ _, dstTypeOk := dst.Payload.(*MACCommand_RelayUpdateUplinkListReq_)
+ if dstValid := dstTypeOk || dst.Payload == nil || len(oneofSubs) == 0; !dstValid {
+ return fmt.Errorf("attempt to set oneof 'relay_update_uplink_list_req', while different oneof is set in destination")
+ }
+ if len(oneofSubs) > 0 {
+ var newDst, newSrc *MACCommand_RelayUpdateUplinkListReq
+ if srcTypeOk {
+ newSrc = src.Payload.(*MACCommand_RelayUpdateUplinkListReq_).RelayUpdateUplinkListReq
+ }
+ if dstTypeOk {
+ newDst = dst.Payload.(*MACCommand_RelayUpdateUplinkListReq_).RelayUpdateUplinkListReq
+ } else if srcTypeOk {
+ newDst = &MACCommand_RelayUpdateUplinkListReq{}
+ dst.Payload = &MACCommand_RelayUpdateUplinkListReq_{RelayUpdateUplinkListReq: newDst}
+ } else {
+ dst.Payload = nil
+ continue
+ }
+ if err := newDst.SetFields(newSrc, oneofSubs...); err != nil {
+ return err
+ }
+ } else {
+ if srcTypeOk {
+ dst.Payload = src.Payload
+ } else {
+ dst.Payload = nil
+ }
+ }
+ case "relay_update_uplink_list_ans":
+ var srcTypeOk bool
+ if src != nil {
+ _, srcTypeOk = src.Payload.(*MACCommand_RelayUpdateUplinkListAns_)
+ }
+ if srcValid := srcTypeOk || src == nil || src.Payload == nil || len(oneofSubs) == 0; !srcValid {
+ return fmt.Errorf("attempt to set oneof 'relay_update_uplink_list_ans', while different oneof is set in source")
+ }
+ _, dstTypeOk := dst.Payload.(*MACCommand_RelayUpdateUplinkListAns_)
+ if dstValid := dstTypeOk || dst.Payload == nil || len(oneofSubs) == 0; !dstValid {
+ return fmt.Errorf("attempt to set oneof 'relay_update_uplink_list_ans', while different oneof is set in destination")
+ }
+ if len(oneofSubs) > 0 {
+ var newDst, newSrc *MACCommand_RelayUpdateUplinkListAns
+ if srcTypeOk {
+ newSrc = src.Payload.(*MACCommand_RelayUpdateUplinkListAns_).RelayUpdateUplinkListAns
+ }
+ if dstTypeOk {
+ newDst = dst.Payload.(*MACCommand_RelayUpdateUplinkListAns_).RelayUpdateUplinkListAns
+ } else if srcTypeOk {
+ newDst = &MACCommand_RelayUpdateUplinkListAns{}
+ dst.Payload = &MACCommand_RelayUpdateUplinkListAns_{RelayUpdateUplinkListAns: newDst}
+ } else {
+ dst.Payload = nil
+ continue
+ }
+ if err := newDst.SetFields(newSrc, oneofSubs...); err != nil {
+ return err
+ }
+ } else {
+ if srcTypeOk {
+ dst.Payload = src.Payload
+ } else {
+ dst.Payload = nil
+ }
+ }
+ case "relay_ctrl_uplink_list_req":
+ var srcTypeOk bool
+ if src != nil {
+ _, srcTypeOk = src.Payload.(*MACCommand_RelayCtrlUplinkListReq_)
+ }
+ if srcValid := srcTypeOk || src == nil || src.Payload == nil || len(oneofSubs) == 0; !srcValid {
+ return fmt.Errorf("attempt to set oneof 'relay_ctrl_uplink_list_req', while different oneof is set in source")
+ }
+ _, dstTypeOk := dst.Payload.(*MACCommand_RelayCtrlUplinkListReq_)
+ if dstValid := dstTypeOk || dst.Payload == nil || len(oneofSubs) == 0; !dstValid {
+ return fmt.Errorf("attempt to set oneof 'relay_ctrl_uplink_list_req', while different oneof is set in destination")
+ }
+ if len(oneofSubs) > 0 {
+ var newDst, newSrc *MACCommand_RelayCtrlUplinkListReq
+ if srcTypeOk {
+ newSrc = src.Payload.(*MACCommand_RelayCtrlUplinkListReq_).RelayCtrlUplinkListReq
+ }
+ if dstTypeOk {
+ newDst = dst.Payload.(*MACCommand_RelayCtrlUplinkListReq_).RelayCtrlUplinkListReq
+ } else if srcTypeOk {
+ newDst = &MACCommand_RelayCtrlUplinkListReq{}
+ dst.Payload = &MACCommand_RelayCtrlUplinkListReq_{RelayCtrlUplinkListReq: newDst}
+ } else {
+ dst.Payload = nil
+ continue
+ }
+ if err := newDst.SetFields(newSrc, oneofSubs...); err != nil {
+ return err
+ }
+ } else {
+ if srcTypeOk {
+ dst.Payload = src.Payload
+ } else {
+ dst.Payload = nil
+ }
+ }
+ case "relay_ctrl_uplink_list_ans":
+ var srcTypeOk bool
+ if src != nil {
+ _, srcTypeOk = src.Payload.(*MACCommand_RelayCtrlUplinkListAns_)
+ }
+ if srcValid := srcTypeOk || src == nil || src.Payload == nil || len(oneofSubs) == 0; !srcValid {
+ return fmt.Errorf("attempt to set oneof 'relay_ctrl_uplink_list_ans', while different oneof is set in source")
+ }
+ _, dstTypeOk := dst.Payload.(*MACCommand_RelayCtrlUplinkListAns_)
+ if dstValid := dstTypeOk || dst.Payload == nil || len(oneofSubs) == 0; !dstValid {
+ return fmt.Errorf("attempt to set oneof 'relay_ctrl_uplink_list_ans', while different oneof is set in destination")
+ }
+ if len(oneofSubs) > 0 {
+ var newDst, newSrc *MACCommand_RelayCtrlUplinkListAns
+ if srcTypeOk {
+ newSrc = src.Payload.(*MACCommand_RelayCtrlUplinkListAns_).RelayCtrlUplinkListAns
+ }
+ if dstTypeOk {
+ newDst = dst.Payload.(*MACCommand_RelayCtrlUplinkListAns_).RelayCtrlUplinkListAns
+ } else if srcTypeOk {
+ newDst = &MACCommand_RelayCtrlUplinkListAns{}
+ dst.Payload = &MACCommand_RelayCtrlUplinkListAns_{RelayCtrlUplinkListAns: newDst}
+ } else {
+ dst.Payload = nil
+ continue
+ }
+ if err := newDst.SetFields(newSrc, oneofSubs...); err != nil {
+ return err
+ }
+ } else {
+ if srcTypeOk {
+ dst.Payload = src.Payload
+ } else {
+ dst.Payload = nil
+ }
+ }
+ case "relay_configure_fwd_limit_req":
+ var srcTypeOk bool
+ if src != nil {
+ _, srcTypeOk = src.Payload.(*MACCommand_RelayConfigureFwdLimitReq_)
+ }
+ if srcValid := srcTypeOk || src == nil || src.Payload == nil || len(oneofSubs) == 0; !srcValid {
+ return fmt.Errorf("attempt to set oneof 'relay_configure_fwd_limit_req', while different oneof is set in source")
+ }
+ _, dstTypeOk := dst.Payload.(*MACCommand_RelayConfigureFwdLimitReq_)
+ if dstValid := dstTypeOk || dst.Payload == nil || len(oneofSubs) == 0; !dstValid {
+ return fmt.Errorf("attempt to set oneof 'relay_configure_fwd_limit_req', while different oneof is set in destination")
+ }
+ if len(oneofSubs) > 0 {
+ var newDst, newSrc *MACCommand_RelayConfigureFwdLimitReq
+ if srcTypeOk {
+ newSrc = src.Payload.(*MACCommand_RelayConfigureFwdLimitReq_).RelayConfigureFwdLimitReq
+ }
+ if dstTypeOk {
+ newDst = dst.Payload.(*MACCommand_RelayConfigureFwdLimitReq_).RelayConfigureFwdLimitReq
+ } else if srcTypeOk {
+ newDst = &MACCommand_RelayConfigureFwdLimitReq{}
+ dst.Payload = &MACCommand_RelayConfigureFwdLimitReq_{RelayConfigureFwdLimitReq: newDst}
+ } else {
+ dst.Payload = nil
+ continue
+ }
+ if err := newDst.SetFields(newSrc, oneofSubs...); err != nil {
+ return err
+ }
+ } else {
+ if srcTypeOk {
+ dst.Payload = src.Payload
+ } else {
+ dst.Payload = nil
+ }
+ }
+ case "relay_configure_fwd_limit_ans":
+ var srcTypeOk bool
+ if src != nil {
+ _, srcTypeOk = src.Payload.(*MACCommand_RelayConfigureFwdLimitAns_)
+ }
+ if srcValid := srcTypeOk || src == nil || src.Payload == nil || len(oneofSubs) == 0; !srcValid {
+ return fmt.Errorf("attempt to set oneof 'relay_configure_fwd_limit_ans', while different oneof is set in source")
+ }
+ _, dstTypeOk := dst.Payload.(*MACCommand_RelayConfigureFwdLimitAns_)
+ if dstValid := dstTypeOk || dst.Payload == nil || len(oneofSubs) == 0; !dstValid {
+ return fmt.Errorf("attempt to set oneof 'relay_configure_fwd_limit_ans', while different oneof is set in destination")
+ }
+ if len(oneofSubs) > 0 {
+ var newDst, newSrc *MACCommand_RelayConfigureFwdLimitAns
+ if srcTypeOk {
+ newSrc = src.Payload.(*MACCommand_RelayConfigureFwdLimitAns_).RelayConfigureFwdLimitAns
+ }
+ if dstTypeOk {
+ newDst = dst.Payload.(*MACCommand_RelayConfigureFwdLimitAns_).RelayConfigureFwdLimitAns
+ } else if srcTypeOk {
+ newDst = &MACCommand_RelayConfigureFwdLimitAns{}
+ dst.Payload = &MACCommand_RelayConfigureFwdLimitAns_{RelayConfigureFwdLimitAns: newDst}
+ } else {
+ dst.Payload = nil
+ continue
+ }
+ if err := newDst.SetFields(newSrc, oneofSubs...); err != nil {
+ return err
+ }
+ } else {
+ if srcTypeOk {
+ dst.Payload = src.Payload
+ } else {
+ dst.Payload = nil
+ }
+ }
+ case "relay_notify_new_end_device_req":
+ var srcTypeOk bool
+ if src != nil {
+ _, srcTypeOk = src.Payload.(*MACCommand_RelayNotifyNewEndDeviceReq_)
+ }
+ if srcValid := srcTypeOk || src == nil || src.Payload == nil || len(oneofSubs) == 0; !srcValid {
+ return fmt.Errorf("attempt to set oneof 'relay_notify_new_end_device_req', while different oneof is set in source")
+ }
+ _, dstTypeOk := dst.Payload.(*MACCommand_RelayNotifyNewEndDeviceReq_)
+ if dstValid := dstTypeOk || dst.Payload == nil || len(oneofSubs) == 0; !dstValid {
+ return fmt.Errorf("attempt to set oneof 'relay_notify_new_end_device_req', while different oneof is set in destination")
+ }
+ if len(oneofSubs) > 0 {
+ var newDst, newSrc *MACCommand_RelayNotifyNewEndDeviceReq
+ if srcTypeOk {
+ newSrc = src.Payload.(*MACCommand_RelayNotifyNewEndDeviceReq_).RelayNotifyNewEndDeviceReq
+ }
+ if dstTypeOk {
+ newDst = dst.Payload.(*MACCommand_RelayNotifyNewEndDeviceReq_).RelayNotifyNewEndDeviceReq
+ } else if srcTypeOk {
+ newDst = &MACCommand_RelayNotifyNewEndDeviceReq{}
+ dst.Payload = &MACCommand_RelayNotifyNewEndDeviceReq_{RelayNotifyNewEndDeviceReq: newDst}
+ } else {
+ dst.Payload = nil
+ continue
+ }
+ if err := newDst.SetFields(newSrc, oneofSubs...); err != nil {
+ return err
+ }
+ } else {
+ if srcTypeOk {
+ dst.Payload = src.Payload
+ } else {
+ dst.Payload = nil
+ }
+ }
+
+ default:
+ return fmt.Errorf("invalid oneof field: '%s.%s'", name, oneofName)
+ }
+ }
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *MACCommands) SetFields(src *MACCommands, paths ...string) error {
+ for name, subs := range _processPaths(paths) {
+ switch name {
+ case "commands":
+ if len(subs) > 0 {
+ return fmt.Errorf("'commands' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.Commands = src.Commands
+ } else {
+ dst.Commands = nil
+ }
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *FrequencyValue) SetFields(src *FrequencyValue, paths ...string) error {
+ for name, subs := range _processPaths(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 uint64
+ dst.Value = zero
+ }
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *ZeroableFrequencyValue) SetFields(src *ZeroableFrequencyValue, paths ...string) error {
+ for name, subs := range _processPaths(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 uint64
+ dst.Value = zero
+ }
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *DataRateOffsetValue) SetFields(src *DataRateOffsetValue, paths ...string) error {
+ for name, subs := range _processPaths(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 {
+ dst.Value = 0
+ }
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *DataRateIndexValue) SetFields(src *DataRateIndexValue, paths ...string) error {
+ for name, subs := range _processPaths(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 {
+ dst.Value = 0
+ }
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *PingSlotPeriodValue) SetFields(src *PingSlotPeriodValue, paths ...string) error {
+ for name, subs := range _processPaths(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 {
+ dst.Value = 0
+ }
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *AggregatedDutyCycleValue) SetFields(src *AggregatedDutyCycleValue, paths ...string) error {
+ for name, subs := range _processPaths(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 {
+ dst.Value = 0
+ }
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *RxDelayValue) SetFields(src *RxDelayValue, paths ...string) error {
+ for name, subs := range _processPaths(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 {
+ dst.Value = 0
+ }
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *ADRAckLimitExponentValue) SetFields(src *ADRAckLimitExponentValue, paths ...string) error {
+ for name, subs := range _processPaths(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 {
+ dst.Value = 0
+ }
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *ADRAckDelayExponentValue) SetFields(src *ADRAckDelayExponentValue, paths ...string) error {
+ for name, subs := range _processPaths(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 {
+ dst.Value = 0
+ }
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *DeviceEIRPValue) SetFields(src *DeviceEIRPValue, paths ...string) error {
+ for name, subs := range _processPaths(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 {
+ dst.Value = 0
+ }
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *RelayForwardUplinkReq) SetFields(src *RelayForwardUplinkReq, paths ...string) error {
+ for name, subs := range _processPaths(paths) {
+ switch name {
+ case "data_rate":
+ if len(subs) > 0 {
+ var newDst, newSrc *DataRate
+ if (src == nil || src.DataRate == nil) && dst.DataRate == nil {
+ continue
+ }
+ if src != nil {
+ newSrc = src.DataRate
+ }
+ if dst.DataRate != nil {
+ newDst = dst.DataRate
+ } else {
+ newDst = &DataRate{}
+ dst.DataRate = newDst
+ }
+ if err := newDst.SetFields(newSrc, subs...); err != nil {
+ return err
+ }
+ } else {
+ if src != nil {
+ dst.DataRate = src.DataRate
+ } else {
+ dst.DataRate = nil
+ }
+ }
+ case "snr":
+ if len(subs) > 0 {
+ return fmt.Errorf("'snr' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.Snr = src.Snr
+ } else {
+ var zero int32
+ dst.Snr = zero
+ }
+ case "rssi":
+ if len(subs) > 0 {
+ return fmt.Errorf("'rssi' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.Rssi = src.Rssi
+ } else {
+ var zero int32
+ dst.Rssi = zero
+ }
+ case "wor_channel":
+ if len(subs) > 0 {
+ return fmt.Errorf("'wor_channel' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.WorChannel = src.WorChannel
+ } else {
+ dst.WorChannel = 0
+ }
+ case "frequency":
+ if len(subs) > 0 {
+ return fmt.Errorf("'frequency' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.Frequency = src.Frequency
+ } else {
+ var zero uint64
+ dst.Frequency = zero
+ }
+ case "raw_payload":
+ if len(subs) > 0 {
+ return fmt.Errorf("'raw_payload' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.RawPayload = src.RawPayload
+ } else {
+ dst.RawPayload = nil
+ }
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *RelayForwardDownlinkReq) SetFields(src *RelayForwardDownlinkReq, paths ...string) error {
+ for name, subs := range _processPaths(paths) {
+ switch name {
+ case "raw_payload":
+ if len(subs) > 0 {
+ return fmt.Errorf("'raw_payload' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.RawPayload = src.RawPayload
+ } else {
+ dst.RawPayload = nil
+ }
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *RelayUplinkToken) SetFields(src *RelayUplinkToken, paths ...string) error {
+ for name, subs := range _processPaths(paths) {
+ switch name {
+ case "ids":
+ if len(subs) > 0 {
+ var newDst, newSrc *EndDeviceIdentifiers
+ if (src == nil || src.Ids == nil) && dst.Ids == nil {
+ continue
+ }
+ if src != nil {
+ newSrc = src.Ids
+ }
+ if dst.Ids != nil {
+ newDst = dst.Ids
+ } else {
+ newDst = &EndDeviceIdentifiers{}
+ dst.Ids = newDst
+ }
+ if err := newDst.SetFields(newSrc, subs...); err != nil {
+ return err
+ }
+ } else {
+ if src != nil {
+ dst.Ids = src.Ids
+ } else {
+ dst.Ids = nil
+ }
+ }
+ case "session_key_id":
+ if len(subs) > 0 {
+ return fmt.Errorf("'session_key_id' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.SessionKeyId = src.SessionKeyId
+ } else {
+ dst.SessionKeyId = nil
+ }
+ case "full_f_cnt":
+ if len(subs) > 0 {
+ return fmt.Errorf("'full_f_cnt' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.FullFCnt = src.FullFCnt
+ } else {
+ var zero uint32
+ dst.FullFCnt = zero
+ }
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *TxSettings_Downlink) SetFields(src *TxSettings_Downlink, paths ...string) error {
+ for name, subs := range _processPaths(paths) {
+ switch name {
+ case "antenna_index":
+ if len(subs) > 0 {
+ return fmt.Errorf("'antenna_index' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.AntennaIndex = src.AntennaIndex
+ } else {
+ var zero uint32
+ dst.AntennaIndex = zero
+ }
+ case "tx_power":
+ if len(subs) > 0 {
+ return fmt.Errorf("'tx_power' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.TxPower = src.TxPower
+ } else {
+ var zero float32
+ dst.TxPower = zero
+ }
+ case "invert_polarization":
+ if len(subs) > 0 {
+ return fmt.Errorf("'invert_polarization' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.InvertPolarization = src.InvertPolarization
+ } else {
+ var zero bool
+ dst.InvertPolarization = zero
+ }
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *MACCommand_ResetInd) SetFields(src *MACCommand_ResetInd, paths ...string) error {
+ for name, subs := range _processPaths(paths) {
+ switch name {
+ case "minor_version":
+ if len(subs) > 0 {
+ return fmt.Errorf("'minor_version' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.MinorVersion = src.MinorVersion
+ } else {
+ dst.MinorVersion = 0
+ }
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *MACCommand_ResetConf) SetFields(src *MACCommand_ResetConf, paths ...string) error {
+ for name, subs := range _processPaths(paths) {
+ switch name {
+ case "minor_version":
+ if len(subs) > 0 {
+ return fmt.Errorf("'minor_version' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.MinorVersion = src.MinorVersion
+ } else {
+ dst.MinorVersion = 0
+ }
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *MACCommand_LinkCheckAns) SetFields(src *MACCommand_LinkCheckAns, paths ...string) error {
+ for name, subs := range _processPaths(paths) {
+ switch name {
+ case "margin":
+ if len(subs) > 0 {
+ return fmt.Errorf("'margin' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.Margin = src.Margin
+ } else {
+ var zero uint32
+ dst.Margin = zero
+ }
+ case "gateway_count":
+ if len(subs) > 0 {
+ return fmt.Errorf("'gateway_count' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.GatewayCount = src.GatewayCount
+ } else {
+ var zero uint32
+ dst.GatewayCount = zero
+ }
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *MACCommand_LinkADRReq) SetFields(src *MACCommand_LinkADRReq, paths ...string) error {
+ for name, subs := range _processPaths(paths) {
+ switch name {
+ case "data_rate_index":
+ if len(subs) > 0 {
+ return fmt.Errorf("'data_rate_index' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.DataRateIndex = src.DataRateIndex
+ } else {
+ dst.DataRateIndex = 0
+ }
+ case "tx_power_index":
+ if len(subs) > 0 {
+ return fmt.Errorf("'tx_power_index' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.TxPowerIndex = src.TxPowerIndex
+ } else {
+ var zero uint32
+ dst.TxPowerIndex = zero
+ }
+ case "channel_mask":
+ if len(subs) > 0 {
+ return fmt.Errorf("'channel_mask' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.ChannelMask = src.ChannelMask
+ } else {
+ dst.ChannelMask = nil
+ }
+ case "channel_mask_control":
+ if len(subs) > 0 {
+ return fmt.Errorf("'channel_mask_control' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.ChannelMaskControl = src.ChannelMaskControl
+ } else {
+ var zero uint32
+ dst.ChannelMaskControl = zero
+ }
+ case "nb_trans":
+ if len(subs) > 0 {
+ return fmt.Errorf("'nb_trans' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.NbTrans = src.NbTrans
+ } else {
+ var zero uint32
+ dst.NbTrans = zero
+ }
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *MACCommand_LinkADRAns) SetFields(src *MACCommand_LinkADRAns, paths ...string) error {
+ for name, subs := range _processPaths(paths) {
switch name {
- case "value":
+ case "channel_mask_ack":
if len(subs) > 0 {
- return fmt.Errorf("'value' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'channel_mask_ack' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.Value = src.Value
+ dst.ChannelMaskAck = src.ChannelMaskAck
} else {
- dst.Value = 0
+ var zero bool
+ dst.ChannelMaskAck = zero
+ }
+ case "data_rate_index_ack":
+ if len(subs) > 0 {
+ return fmt.Errorf("'data_rate_index_ack' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.DataRateIndexAck = src.DataRateIndexAck
+ } else {
+ var zero bool
+ dst.DataRateIndexAck = zero
+ }
+ case "tx_power_index_ack":
+ if len(subs) > 0 {
+ return fmt.Errorf("'tx_power_index_ack' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.TxPowerIndexAck = src.TxPowerIndexAck
+ } else {
+ var zero bool
+ dst.TxPowerIndexAck = zero
}
default:
@@ -2785,17 +3745,17 @@ func (dst *RxDelayValue) SetFields(src *RxDelayValue, paths ...string) error {
return nil
}
-func (dst *ADRAckLimitExponentValue) SetFields(src *ADRAckLimitExponentValue, paths ...string) error {
+func (dst *MACCommand_DutyCycleReq) SetFields(src *MACCommand_DutyCycleReq, paths ...string) error {
for name, subs := range _processPaths(paths) {
switch name {
- case "value":
+ case "max_duty_cycle":
if len(subs) > 0 {
- return fmt.Errorf("'value' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'max_duty_cycle' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.Value = src.Value
+ dst.MaxDutyCycle = src.MaxDutyCycle
} else {
- dst.Value = 0
+ dst.MaxDutyCycle = 0
}
default:
@@ -2805,17 +3765,36 @@ func (dst *ADRAckLimitExponentValue) SetFields(src *ADRAckLimitExponentValue, pa
return nil
}
-func (dst *ADRAckDelayExponentValue) SetFields(src *ADRAckDelayExponentValue, paths ...string) error {
+func (dst *MACCommand_RxParamSetupReq) SetFields(src *MACCommand_RxParamSetupReq, paths ...string) error {
for name, subs := range _processPaths(paths) {
switch name {
- case "value":
+ case "rx2_data_rate_index":
if len(subs) > 0 {
- return fmt.Errorf("'value' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'rx2_data_rate_index' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.Value = src.Value
+ dst.Rx2DataRateIndex = src.Rx2DataRateIndex
} else {
- dst.Value = 0
+ dst.Rx2DataRateIndex = 0
+ }
+ 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 = 0
+ }
+ 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
}
default:
@@ -2825,17 +3804,38 @@ func (dst *ADRAckDelayExponentValue) SetFields(src *ADRAckDelayExponentValue, pa
return nil
}
-func (dst *DeviceEIRPValue) SetFields(src *DeviceEIRPValue, paths ...string) error {
+func (dst *MACCommand_RxParamSetupAns) SetFields(src *MACCommand_RxParamSetupAns, paths ...string) error {
for name, subs := range _processPaths(paths) {
switch name {
- case "value":
+ case "rx2_data_rate_index_ack":
if len(subs) > 0 {
- return fmt.Errorf("'value' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'rx2_data_rate_index_ack' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.Value = src.Value
+ dst.Rx2DataRateIndexAck = src.Rx2DataRateIndexAck
} else {
- dst.Value = 0
+ var zero bool
+ dst.Rx2DataRateIndexAck = zero
+ }
+ case "rx1_data_rate_offset_ack":
+ if len(subs) > 0 {
+ return fmt.Errorf("'rx1_data_rate_offset_ack' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.Rx1DataRateOffsetAck = src.Rx1DataRateOffsetAck
+ } else {
+ var zero bool
+ dst.Rx1DataRateOffsetAck = zero
+ }
+ case "rx2_frequency_ack":
+ if len(subs) > 0 {
+ return fmt.Errorf("'rx2_frequency_ack' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.Rx2FrequencyAck = src.Rx2FrequencyAck
+ } else {
+ var zero bool
+ dst.Rx2FrequencyAck = zero
}
default:
@@ -2845,38 +3845,77 @@ func (dst *DeviceEIRPValue) SetFields(src *DeviceEIRPValue, paths ...string) err
return nil
}
-func (dst *TxSettings_Downlink) SetFields(src *TxSettings_Downlink, paths ...string) error {
+func (dst *MACCommand_DevStatusAns) SetFields(src *MACCommand_DevStatusAns, paths ...string) error {
for name, subs := range _processPaths(paths) {
switch name {
- case "antenna_index":
+ case "battery":
if len(subs) > 0 {
- return fmt.Errorf("'antenna_index' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'battery' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.AntennaIndex = src.AntennaIndex
+ dst.Battery = src.Battery
} else {
var zero uint32
- dst.AntennaIndex = zero
+ dst.Battery = zero
}
- case "tx_power":
+ case "margin":
if len(subs) > 0 {
- return fmt.Errorf("'tx_power' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'margin' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.TxPower = src.TxPower
+ dst.Margin = src.Margin
} else {
- var zero float32
- dst.TxPower = zero
+ var zero int32
+ dst.Margin = zero
}
- case "invert_polarization":
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *MACCommand_NewChannelReq) SetFields(src *MACCommand_NewChannelReq, paths ...string) error {
+ for name, subs := range _processPaths(paths) {
+ switch name {
+ case "channel_index":
if len(subs) > 0 {
- return fmt.Errorf("'invert_polarization' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'channel_index' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.InvertPolarization = src.InvertPolarization
+ dst.ChannelIndex = src.ChannelIndex
} else {
- var zero bool
- dst.InvertPolarization = zero
+ var zero uint32
+ dst.ChannelIndex = zero
+ }
+ case "frequency":
+ if len(subs) > 0 {
+ return fmt.Errorf("'frequency' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.Frequency = src.Frequency
+ } else {
+ var zero uint64
+ dst.Frequency = zero
+ }
+ case "min_data_rate_index":
+ if len(subs) > 0 {
+ return fmt.Errorf("'min_data_rate_index' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.MinDataRateIndex = src.MinDataRateIndex
+ } else {
+ dst.MinDataRateIndex = 0
+ }
+ case "max_data_rate_index":
+ if len(subs) > 0 {
+ return fmt.Errorf("'max_data_rate_index' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.MaxDataRateIndex = src.MaxDataRateIndex
+ } else {
+ dst.MaxDataRateIndex = 0
}
default:
@@ -2886,17 +3925,28 @@ func (dst *TxSettings_Downlink) SetFields(src *TxSettings_Downlink, paths ...str
return nil
}
-func (dst *MACCommand_ResetInd) SetFields(src *MACCommand_ResetInd, paths ...string) error {
+func (dst *MACCommand_NewChannelAns) SetFields(src *MACCommand_NewChannelAns, paths ...string) error {
for name, subs := range _processPaths(paths) {
switch name {
- case "minor_version":
+ case "frequency_ack":
if len(subs) > 0 {
- return fmt.Errorf("'minor_version' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'frequency_ack' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.MinorVersion = src.MinorVersion
+ dst.FrequencyAck = src.FrequencyAck
} else {
- dst.MinorVersion = 0
+ var zero bool
+ dst.FrequencyAck = zero
+ }
+ case "data_rate_ack":
+ if len(subs) > 0 {
+ return fmt.Errorf("'data_rate_ack' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.DataRateAck = src.DataRateAck
+ } else {
+ var zero bool
+ dst.DataRateAck = zero
}
default:
@@ -2906,17 +3956,28 @@ func (dst *MACCommand_ResetInd) SetFields(src *MACCommand_ResetInd, paths ...str
return nil
}
-func (dst *MACCommand_ResetConf) SetFields(src *MACCommand_ResetConf, paths ...string) error {
+func (dst *MACCommand_DLChannelReq) SetFields(src *MACCommand_DLChannelReq, paths ...string) error {
for name, subs := range _processPaths(paths) {
switch name {
- case "minor_version":
+ case "channel_index":
if len(subs) > 0 {
- return fmt.Errorf("'minor_version' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'channel_index' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.MinorVersion = src.MinorVersion
+ dst.ChannelIndex = src.ChannelIndex
} else {
- dst.MinorVersion = 0
+ var zero uint32
+ dst.ChannelIndex = zero
+ }
+ case "frequency":
+ if len(subs) > 0 {
+ return fmt.Errorf("'frequency' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.Frequency = src.Frequency
+ } else {
+ var zero uint64
+ dst.Frequency = zero
}
default:
@@ -2926,28 +3987,28 @@ func (dst *MACCommand_ResetConf) SetFields(src *MACCommand_ResetConf, paths ...s
return nil
}
-func (dst *MACCommand_LinkCheckAns) SetFields(src *MACCommand_LinkCheckAns, paths ...string) error {
+func (dst *MACCommand_DLChannelAns) SetFields(src *MACCommand_DLChannelAns, paths ...string) error {
for name, subs := range _processPaths(paths) {
switch name {
- case "margin":
+ case "channel_index_ack":
if len(subs) > 0 {
- return fmt.Errorf("'margin' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'channel_index_ack' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.Margin = src.Margin
+ dst.ChannelIndexAck = src.ChannelIndexAck
} else {
- var zero uint32
- dst.Margin = zero
+ var zero bool
+ dst.ChannelIndexAck = zero
}
- case "gateway_count":
+ case "frequency_ack":
if len(subs) > 0 {
- return fmt.Errorf("'gateway_count' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'frequency_ack' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.GatewayCount = src.GatewayCount
+ dst.FrequencyAck = src.FrequencyAck
} else {
- var zero uint32
- dst.GatewayCount = zero
+ var zero bool
+ dst.FrequencyAck = zero
}
default:
@@ -2957,56 +4018,77 @@ func (dst *MACCommand_LinkCheckAns) SetFields(src *MACCommand_LinkCheckAns, path
return nil
}
-func (dst *MACCommand_LinkADRReq) SetFields(src *MACCommand_LinkADRReq, paths ...string) error {
+func (dst *MACCommand_RxTimingSetupReq) SetFields(src *MACCommand_RxTimingSetupReq, paths ...string) error {
for name, subs := range _processPaths(paths) {
switch name {
- case "data_rate_index":
+ case "delay":
if len(subs) > 0 {
- return fmt.Errorf("'data_rate_index' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'delay' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.DataRateIndex = src.DataRateIndex
+ dst.Delay = src.Delay
} else {
- dst.DataRateIndex = 0
+ dst.Delay = 0
}
- case "tx_power_index":
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *MACCommand_TxParamSetupReq) SetFields(src *MACCommand_TxParamSetupReq, paths ...string) error {
+ for name, subs := range _processPaths(paths) {
+ switch name {
+ case "max_eirp_index":
if len(subs) > 0 {
- return fmt.Errorf("'tx_power_index' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'max_eirp_index' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.TxPowerIndex = src.TxPowerIndex
+ dst.MaxEirpIndex = src.MaxEirpIndex
} else {
- var zero uint32
- dst.TxPowerIndex = zero
+ dst.MaxEirpIndex = 0
}
- case "channel_mask":
+ case "uplink_dwell_time":
if len(subs) > 0 {
- return fmt.Errorf("'channel_mask' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'uplink_dwell_time' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.ChannelMask = src.ChannelMask
+ dst.UplinkDwellTime = src.UplinkDwellTime
} else {
- dst.ChannelMask = nil
+ var zero bool
+ dst.UplinkDwellTime = zero
}
- case "channel_mask_control":
+ case "downlink_dwell_time":
if len(subs) > 0 {
- return fmt.Errorf("'channel_mask_control' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'downlink_dwell_time' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.ChannelMaskControl = src.ChannelMaskControl
+ dst.DownlinkDwellTime = src.DownlinkDwellTime
} else {
- var zero uint32
- dst.ChannelMaskControl = zero
+ var zero bool
+ dst.DownlinkDwellTime = zero
}
- case "nb_trans":
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *MACCommand_RekeyInd) SetFields(src *MACCommand_RekeyInd, paths ...string) error {
+ for name, subs := range _processPaths(paths) {
+ switch name {
+ case "minor_version":
if len(subs) > 0 {
- return fmt.Errorf("'nb_trans' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'minor_version' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.NbTrans = src.NbTrans
+ dst.MinorVersion = src.MinorVersion
} else {
- var zero uint32
- dst.NbTrans = zero
+ dst.MinorVersion = 0
}
default:
@@ -3016,38 +4098,46 @@ func (dst *MACCommand_LinkADRReq) SetFields(src *MACCommand_LinkADRReq, paths ..
return nil
}
-func (dst *MACCommand_LinkADRAns) SetFields(src *MACCommand_LinkADRAns, paths ...string) error {
+func (dst *MACCommand_RekeyConf) SetFields(src *MACCommand_RekeyConf, paths ...string) error {
for name, subs := range _processPaths(paths) {
switch name {
- case "channel_mask_ack":
+ case "minor_version":
if len(subs) > 0 {
- return fmt.Errorf("'channel_mask_ack' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'minor_version' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.ChannelMaskAck = src.ChannelMaskAck
+ dst.MinorVersion = src.MinorVersion
} else {
- var zero bool
- dst.ChannelMaskAck = zero
+ dst.MinorVersion = 0
}
- case "data_rate_index_ack":
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *MACCommand_ADRParamSetupReq) SetFields(src *MACCommand_ADRParamSetupReq, paths ...string) error {
+ for name, subs := range _processPaths(paths) {
+ switch name {
+ case "adr_ack_limit_exponent":
if len(subs) > 0 {
- return fmt.Errorf("'data_rate_index_ack' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'adr_ack_limit_exponent' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.DataRateIndexAck = src.DataRateIndexAck
+ dst.AdrAckLimitExponent = src.AdrAckLimitExponent
} else {
- var zero bool
- dst.DataRateIndexAck = zero
+ dst.AdrAckLimitExponent = 0
}
- case "tx_power_index_ack":
+ case "adr_ack_delay_exponent":
if len(subs) > 0 {
- return fmt.Errorf("'tx_power_index_ack' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'adr_ack_delay_exponent' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.TxPowerIndexAck = src.TxPowerIndexAck
+ dst.AdrAckDelayExponent = src.AdrAckDelayExponent
} else {
- var zero bool
- dst.TxPowerIndexAck = zero
+ dst.AdrAckDelayExponent = 0
}
default:
@@ -3057,17 +4147,17 @@ func (dst *MACCommand_LinkADRAns) SetFields(src *MACCommand_LinkADRAns, paths ..
return nil
}
-func (dst *MACCommand_DutyCycleReq) SetFields(src *MACCommand_DutyCycleReq, paths ...string) error {
+func (dst *MACCommand_DeviceTimeAns) SetFields(src *MACCommand_DeviceTimeAns, paths ...string) error {
for name, subs := range _processPaths(paths) {
switch name {
- case "max_duty_cycle":
+ case "time":
if len(subs) > 0 {
- return fmt.Errorf("'max_duty_cycle' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'time' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.MaxDutyCycle = src.MaxDutyCycle
+ dst.Time = src.Time
} else {
- dst.MaxDutyCycle = 0
+ dst.Time = nil
}
default:
@@ -3077,36 +4167,45 @@ func (dst *MACCommand_DutyCycleReq) SetFields(src *MACCommand_DutyCycleReq, path
return nil
}
-func (dst *MACCommand_RxParamSetupReq) SetFields(src *MACCommand_RxParamSetupReq, paths ...string) error {
+func (dst *MACCommand_ForceRejoinReq) SetFields(src *MACCommand_ForceRejoinReq, paths ...string) error {
for name, subs := range _processPaths(paths) {
switch name {
- case "rx2_data_rate_index":
+ case "rejoin_type":
if len(subs) > 0 {
- return fmt.Errorf("'rx2_data_rate_index' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'rejoin_type' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.Rx2DataRateIndex = src.Rx2DataRateIndex
+ dst.RejoinType = src.RejoinType
} else {
- dst.Rx2DataRateIndex = 0
+ dst.RejoinType = 0
}
- case "rx1_data_rate_offset":
+ case "data_rate_index":
if len(subs) > 0 {
- return fmt.Errorf("'rx1_data_rate_offset' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'data_rate_index' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.Rx1DataRateOffset = src.Rx1DataRateOffset
+ dst.DataRateIndex = src.DataRateIndex
} else {
- dst.Rx1DataRateOffset = 0
+ dst.DataRateIndex = 0
}
- case "rx2_frequency":
+ case "max_retries":
if len(subs) > 0 {
- return fmt.Errorf("'rx2_frequency' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'max_retries' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.Rx2Frequency = src.Rx2Frequency
+ dst.MaxRetries = src.MaxRetries
} else {
- var zero uint64
- dst.Rx2Frequency = zero
+ var zero uint32
+ dst.MaxRetries = zero
+ }
+ case "period_exponent":
+ if len(subs) > 0 {
+ return fmt.Errorf("'period_exponent' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.PeriodExponent = src.PeriodExponent
+ } else {
+ dst.PeriodExponent = 0
}
default:
@@ -3116,38 +4215,47 @@ func (dst *MACCommand_RxParamSetupReq) SetFields(src *MACCommand_RxParamSetupReq
return nil
}
-func (dst *MACCommand_RxParamSetupAns) SetFields(src *MACCommand_RxParamSetupAns, paths ...string) error {
+func (dst *MACCommand_RejoinParamSetupReq) SetFields(src *MACCommand_RejoinParamSetupReq, paths ...string) error {
for name, subs := range _processPaths(paths) {
switch name {
- case "rx2_data_rate_index_ack":
+ case "max_count_exponent":
if len(subs) > 0 {
- return fmt.Errorf("'rx2_data_rate_index_ack' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'max_count_exponent' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.Rx2DataRateIndexAck = src.Rx2DataRateIndexAck
+ dst.MaxCountExponent = src.MaxCountExponent
} else {
- var zero bool
- dst.Rx2DataRateIndexAck = zero
+ dst.MaxCountExponent = 0
}
- case "rx1_data_rate_offset_ack":
+ case "max_time_exponent":
if len(subs) > 0 {
- return fmt.Errorf("'rx1_data_rate_offset_ack' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'max_time_exponent' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.Rx1DataRateOffsetAck = src.Rx1DataRateOffsetAck
+ dst.MaxTimeExponent = src.MaxTimeExponent
} else {
- var zero bool
- dst.Rx1DataRateOffsetAck = zero
+ dst.MaxTimeExponent = 0
}
- case "rx2_frequency_ack":
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *MACCommand_RejoinParamSetupAns) SetFields(src *MACCommand_RejoinParamSetupAns, paths ...string) error {
+ for name, subs := range _processPaths(paths) {
+ switch name {
+ case "max_time_exponent_ack":
if len(subs) > 0 {
- return fmt.Errorf("'rx2_frequency_ack' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'max_time_exponent_ack' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.Rx2FrequencyAck = src.Rx2FrequencyAck
+ dst.MaxTimeExponentAck = src.MaxTimeExponentAck
} else {
var zero bool
- dst.Rx2FrequencyAck = zero
+ dst.MaxTimeExponentAck = zero
}
default:
@@ -3157,28 +4265,17 @@ func (dst *MACCommand_RxParamSetupAns) SetFields(src *MACCommand_RxParamSetupAns
return nil
}
-func (dst *MACCommand_DevStatusAns) SetFields(src *MACCommand_DevStatusAns, paths ...string) error {
+func (dst *MACCommand_PingSlotInfoReq) SetFields(src *MACCommand_PingSlotInfoReq, paths ...string) error {
for name, subs := range _processPaths(paths) {
switch name {
- case "battery":
- if len(subs) > 0 {
- return fmt.Errorf("'battery' has no subfields, but %s were specified", subs)
- }
- if src != nil {
- dst.Battery = src.Battery
- } else {
- var zero uint32
- dst.Battery = zero
- }
- case "margin":
+ case "period":
if len(subs) > 0 {
- return fmt.Errorf("'margin' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'period' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.Margin = src.Margin
+ dst.Period = src.Period
} else {
- var zero int32
- dst.Margin = zero
+ dst.Period = 0
}
default:
@@ -3188,19 +4285,9 @@ func (dst *MACCommand_DevStatusAns) SetFields(src *MACCommand_DevStatusAns, path
return nil
}
-func (dst *MACCommand_NewChannelReq) SetFields(src *MACCommand_NewChannelReq, paths ...string) error {
+func (dst *MACCommand_PingSlotChannelReq) SetFields(src *MACCommand_PingSlotChannelReq, paths ...string) error {
for name, subs := range _processPaths(paths) {
switch name {
- case "channel_index":
- if len(subs) > 0 {
- return fmt.Errorf("'channel_index' has no subfields, but %s were specified", subs)
- }
- if src != nil {
- dst.ChannelIndex = src.ChannelIndex
- } else {
- var zero uint32
- dst.ChannelIndex = zero
- }
case "frequency":
if len(subs) > 0 {
return fmt.Errorf("'frequency' has no subfields, but %s were specified", subs)
@@ -3211,23 +4298,14 @@ func (dst *MACCommand_NewChannelReq) SetFields(src *MACCommand_NewChannelReq, pa
var zero uint64
dst.Frequency = zero
}
- case "min_data_rate_index":
- if len(subs) > 0 {
- return fmt.Errorf("'min_data_rate_index' has no subfields, but %s were specified", subs)
- }
- if src != nil {
- dst.MinDataRateIndex = src.MinDataRateIndex
- } else {
- dst.MinDataRateIndex = 0
- }
- case "max_data_rate_index":
+ case "data_rate_index":
if len(subs) > 0 {
- return fmt.Errorf("'max_data_rate_index' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'data_rate_index' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.MaxDataRateIndex = src.MaxDataRateIndex
+ dst.DataRateIndex = src.DataRateIndex
} else {
- dst.MaxDataRateIndex = 0
+ dst.DataRateIndex = 0
}
default:
@@ -3237,7 +4315,7 @@ func (dst *MACCommand_NewChannelReq) SetFields(src *MACCommand_NewChannelReq, pa
return nil
}
-func (dst *MACCommand_NewChannelAns) SetFields(src *MACCommand_NewChannelAns, paths ...string) error {
+func (dst *MACCommand_PingSlotChannelAns) SetFields(src *MACCommand_PingSlotChannelAns, paths ...string) error {
for name, subs := range _processPaths(paths) {
switch name {
case "frequency_ack":
@@ -3250,15 +4328,46 @@ func (dst *MACCommand_NewChannelAns) SetFields(src *MACCommand_NewChannelAns, pa
var zero bool
dst.FrequencyAck = zero
}
- case "data_rate_ack":
+ case "data_rate_index_ack":
+ if len(subs) > 0 {
+ return fmt.Errorf("'data_rate_index_ack' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.DataRateIndexAck = src.DataRateIndexAck
+ } else {
+ var zero bool
+ dst.DataRateIndexAck = zero
+ }
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
+
+func (dst *MACCommand_BeaconTimingAns) SetFields(src *MACCommand_BeaconTimingAns, paths ...string) error {
+ for name, subs := range _processPaths(paths) {
+ switch name {
+ case "delay":
+ if len(subs) > 0 {
+ return fmt.Errorf("'delay' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.Delay = src.Delay
+ } else {
+ var zero uint32
+ dst.Delay = zero
+ }
+ case "channel_index":
if len(subs) > 0 {
- return fmt.Errorf("'data_rate_ack' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'channel_index' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.DataRateAck = src.DataRateAck
+ dst.ChannelIndex = src.ChannelIndex
} else {
- var zero bool
- dst.DataRateAck = zero
+ var zero uint32
+ dst.ChannelIndex = zero
}
default:
@@ -3268,19 +4377,9 @@ func (dst *MACCommand_NewChannelAns) SetFields(src *MACCommand_NewChannelAns, pa
return nil
}
-func (dst *MACCommand_DLChannelReq) SetFields(src *MACCommand_DLChannelReq, paths ...string) error {
+func (dst *MACCommand_BeaconFreqReq) SetFields(src *MACCommand_BeaconFreqReq, paths ...string) error {
for name, subs := range _processPaths(paths) {
switch name {
- case "channel_index":
- if len(subs) > 0 {
- return fmt.Errorf("'channel_index' has no subfields, but %s were specified", subs)
- }
- if src != nil {
- dst.ChannelIndex = src.ChannelIndex
- } else {
- var zero uint32
- dst.ChannelIndex = zero
- }
case "frequency":
if len(subs) > 0 {
return fmt.Errorf("'frequency' has no subfields, but %s were specified", subs)
@@ -3299,19 +4398,9 @@ func (dst *MACCommand_DLChannelReq) SetFields(src *MACCommand_DLChannelReq, path
return nil
}
-func (dst *MACCommand_DLChannelAns) SetFields(src *MACCommand_DLChannelAns, paths ...string) error {
+func (dst *MACCommand_BeaconFreqAns) SetFields(src *MACCommand_BeaconFreqAns, paths ...string) error {
for name, subs := range _processPaths(paths) {
switch name {
- case "channel_index_ack":
- if len(subs) > 0 {
- return fmt.Errorf("'channel_index_ack' has no subfields, but %s were specified", subs)
- }
- if src != nil {
- dst.ChannelIndexAck = src.ChannelIndexAck
- } else {
- var zero bool
- dst.ChannelIndexAck = zero
- }
case "frequency_ack":
if len(subs) > 0 {
return fmt.Errorf("'frequency_ack' has no subfields, but %s were specified", subs)
@@ -3330,17 +4419,17 @@ func (dst *MACCommand_DLChannelAns) SetFields(src *MACCommand_DLChannelAns, path
return nil
}
-func (dst *MACCommand_RxTimingSetupReq) SetFields(src *MACCommand_RxTimingSetupReq, paths ...string) error {
+func (dst *MACCommand_DeviceModeInd) SetFields(src *MACCommand_DeviceModeInd, paths ...string) error {
for name, subs := range _processPaths(paths) {
switch name {
- case "delay":
+ case "class":
if len(subs) > 0 {
- return fmt.Errorf("'delay' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'class' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.Delay = src.Delay
+ dst.Class = src.Class
} else {
- dst.Delay = 0
+ dst.Class = 0
}
default:
@@ -3350,37 +4439,17 @@ func (dst *MACCommand_RxTimingSetupReq) SetFields(src *MACCommand_RxTimingSetupR
return nil
}
-func (dst *MACCommand_TxParamSetupReq) SetFields(src *MACCommand_TxParamSetupReq, paths ...string) error {
+func (dst *MACCommand_DeviceModeConf) SetFields(src *MACCommand_DeviceModeConf, paths ...string) error {
for name, subs := range _processPaths(paths) {
switch name {
- case "max_eirp_index":
- if len(subs) > 0 {
- return fmt.Errorf("'max_eirp_index' has no subfields, but %s were specified", subs)
- }
- if src != nil {
- dst.MaxEirpIndex = src.MaxEirpIndex
- } else {
- dst.MaxEirpIndex = 0
- }
- case "uplink_dwell_time":
- if len(subs) > 0 {
- return fmt.Errorf("'uplink_dwell_time' has no subfields, but %s were specified", subs)
- }
- if src != nil {
- dst.UplinkDwellTime = src.UplinkDwellTime
- } else {
- var zero bool
- dst.UplinkDwellTime = zero
- }
- case "downlink_dwell_time":
+ case "class":
if len(subs) > 0 {
- return fmt.Errorf("'downlink_dwell_time' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'class' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.DownlinkDwellTime = src.DownlinkDwellTime
+ dst.Class = src.Class
} else {
- var zero bool
- dst.DownlinkDwellTime = zero
+ dst.Class = 0
}
default:
@@ -3390,17 +4459,33 @@ func (dst *MACCommand_TxParamSetupReq) SetFields(src *MACCommand_TxParamSetupReq
return nil
}
-func (dst *MACCommand_RekeyInd) SetFields(src *MACCommand_RekeyInd, paths ...string) error {
+func (dst *MACCommand_RelayConfReq) SetFields(src *MACCommand_RelayConfReq, paths ...string) error {
for name, subs := range _processPaths(paths) {
switch name {
- case "minor_version":
+ case "configuration":
if len(subs) > 0 {
- return fmt.Errorf("'minor_version' has no subfields, but %s were specified", subs)
- }
- if src != nil {
- dst.MinorVersion = src.MinorVersion
+ var newDst, newSrc *MACCommand_RelayConfReq_Configuration
+ if (src == nil || src.Configuration == nil) && dst.Configuration == nil {
+ continue
+ }
+ if src != nil {
+ newSrc = src.Configuration
+ }
+ if dst.Configuration != nil {
+ newDst = dst.Configuration
+ } else {
+ newDst = &MACCommand_RelayConfReq_Configuration{}
+ dst.Configuration = newDst
+ }
+ if err := newDst.SetFields(newSrc, subs...); err != nil {
+ return err
+ }
} else {
- dst.MinorVersion = 0
+ if src != nil {
+ dst.Configuration = src.Configuration
+ } else {
+ dst.Configuration = nil
+ }
}
default:
@@ -3410,46 +4495,68 @@ func (dst *MACCommand_RekeyInd) SetFields(src *MACCommand_RekeyInd, paths ...str
return nil
}
-func (dst *MACCommand_RekeyConf) SetFields(src *MACCommand_RekeyConf, paths ...string) error {
+func (dst *MACCommand_RelayConfAns) SetFields(src *MACCommand_RelayConfAns, paths ...string) error {
for name, subs := range _processPaths(paths) {
switch name {
- case "minor_version":
+ case "second_channel_frequency_ack":
if len(subs) > 0 {
- return fmt.Errorf("'minor_version' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'second_channel_frequency_ack' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.MinorVersion = src.MinorVersion
+ dst.SecondChannelFrequencyAck = src.SecondChannelFrequencyAck
} else {
- dst.MinorVersion = 0
+ var zero bool
+ dst.SecondChannelFrequencyAck = zero
}
-
- default:
- return fmt.Errorf("invalid field: '%s'", name)
- }
- }
- return nil
-}
-
-func (dst *MACCommand_ADRParamSetupReq) SetFields(src *MACCommand_ADRParamSetupReq, paths ...string) error {
- for name, subs := range _processPaths(paths) {
- switch name {
- case "adr_ack_limit_exponent":
+ case "second_channel_ack_offset_ack":
if len(subs) > 0 {
- return fmt.Errorf("'adr_ack_limit_exponent' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'second_channel_ack_offset_ack' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.AdrAckLimitExponent = src.AdrAckLimitExponent
+ dst.SecondChannelAckOffsetAck = src.SecondChannelAckOffsetAck
} else {
- dst.AdrAckLimitExponent = 0
+ var zero bool
+ dst.SecondChannelAckOffsetAck = zero
}
- case "adr_ack_delay_exponent":
+ case "second_channel_data_rate_index_ack":
if len(subs) > 0 {
- return fmt.Errorf("'adr_ack_delay_exponent' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'second_channel_data_rate_index_ack' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.AdrAckDelayExponent = src.AdrAckDelayExponent
+ dst.SecondChannelDataRateIndexAck = src.SecondChannelDataRateIndexAck
} else {
- dst.AdrAckDelayExponent = 0
+ var zero bool
+ dst.SecondChannelDataRateIndexAck = zero
+ }
+ case "second_channel_index_ack":
+ if len(subs) > 0 {
+ return fmt.Errorf("'second_channel_index_ack' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.SecondChannelIndexAck = src.SecondChannelIndexAck
+ } else {
+ var zero bool
+ dst.SecondChannelIndexAck = zero
+ }
+ case "default_channel_index_ack":
+ if len(subs) > 0 {
+ return fmt.Errorf("'default_channel_index_ack' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.DefaultChannelIndexAck = src.DefaultChannelIndexAck
+ } else {
+ var zero bool
+ dst.DefaultChannelIndexAck = zero
+ }
+ case "cad_periodicity_ack":
+ if len(subs) > 0 {
+ return fmt.Errorf("'cad_periodicity_ack' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.CadPeriodicityAck = src.CadPeriodicityAck
+ } else {
+ var zero bool
+ dst.CadPeriodicityAck = zero
}
default:
@@ -3459,17 +4566,33 @@ func (dst *MACCommand_ADRParamSetupReq) SetFields(src *MACCommand_ADRParamSetupR
return nil
}
-func (dst *MACCommand_DeviceTimeAns) SetFields(src *MACCommand_DeviceTimeAns, paths ...string) error {
+func (dst *MACCommand_RelayEndDeviceConfReq) SetFields(src *MACCommand_RelayEndDeviceConfReq, paths ...string) error {
for name, subs := range _processPaths(paths) {
switch name {
- case "time":
+ case "configuration":
if len(subs) > 0 {
- return fmt.Errorf("'time' has no subfields, but %s were specified", subs)
- }
- if src != nil {
- dst.Time = src.Time
+ var newDst, newSrc *MACCommand_RelayEndDeviceConfReq_Configuration
+ if (src == nil || src.Configuration == nil) && dst.Configuration == nil {
+ continue
+ }
+ if src != nil {
+ newSrc = src.Configuration
+ }
+ if dst.Configuration != nil {
+ newDst = dst.Configuration
+ } else {
+ newDst = &MACCommand_RelayEndDeviceConfReq_Configuration{}
+ dst.Configuration = newDst
+ }
+ if err := newDst.SetFields(newSrc, subs...); err != nil {
+ return err
+ }
} else {
- dst.Time = nil
+ if src != nil {
+ dst.Configuration = src.Configuration
+ } else {
+ dst.Configuration = nil
+ }
}
default:
@@ -3479,45 +4602,48 @@ func (dst *MACCommand_DeviceTimeAns) SetFields(src *MACCommand_DeviceTimeAns, pa
return nil
}
-func (dst *MACCommand_ForceRejoinReq) SetFields(src *MACCommand_ForceRejoinReq, paths ...string) error {
+func (dst *MACCommand_RelayEndDeviceConfAns) SetFields(src *MACCommand_RelayEndDeviceConfAns, paths ...string) error {
for name, subs := range _processPaths(paths) {
switch name {
- case "rejoin_type":
+ case "second_channel_frequency_ack":
if len(subs) > 0 {
- return fmt.Errorf("'rejoin_type' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'second_channel_frequency_ack' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.RejoinType = src.RejoinType
+ dst.SecondChannelFrequencyAck = src.SecondChannelFrequencyAck
} else {
- dst.RejoinType = 0
+ var zero bool
+ dst.SecondChannelFrequencyAck = zero
}
- case "data_rate_index":
+ case "second_channel_data_rate_index_ack":
if len(subs) > 0 {
- return fmt.Errorf("'data_rate_index' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'second_channel_data_rate_index_ack' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.DataRateIndex = src.DataRateIndex
+ dst.SecondChannelDataRateIndexAck = src.SecondChannelDataRateIndexAck
} else {
- dst.DataRateIndex = 0
+ var zero bool
+ dst.SecondChannelDataRateIndexAck = zero
}
- case "max_retries":
+ case "second_channel_index_ack":
if len(subs) > 0 {
- return fmt.Errorf("'max_retries' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'second_channel_index_ack' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.MaxRetries = src.MaxRetries
+ dst.SecondChannelIndexAck = src.SecondChannelIndexAck
} else {
- var zero uint32
- dst.MaxRetries = zero
+ var zero bool
+ dst.SecondChannelIndexAck = zero
}
- case "period_exponent":
+ case "backoff_ack":
if len(subs) > 0 {
- return fmt.Errorf("'period_exponent' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'backoff_ack' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.PeriodExponent = src.PeriodExponent
+ dst.BackoffAck = src.BackoffAck
} else {
- dst.PeriodExponent = 0
+ var zero bool
+ dst.BackoffAck = zero
}
default:
@@ -3527,97 +4653,90 @@ func (dst *MACCommand_ForceRejoinReq) SetFields(src *MACCommand_ForceRejoinReq,
return nil
}
-func (dst *MACCommand_RejoinParamSetupReq) SetFields(src *MACCommand_RejoinParamSetupReq, paths ...string) error {
+func (dst *MACCommand_RelayUpdateUplinkListReq) SetFields(src *MACCommand_RelayUpdateUplinkListReq, paths ...string) error {
for name, subs := range _processPaths(paths) {
switch name {
- case "max_count_exponent":
+ case "rule_index":
if len(subs) > 0 {
- return fmt.Errorf("'max_count_exponent' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'rule_index' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.MaxCountExponent = src.MaxCountExponent
+ dst.RuleIndex = src.RuleIndex
} else {
- dst.MaxCountExponent = 0
+ var zero uint32
+ dst.RuleIndex = zero
}
- case "max_time_exponent":
+ case "forward_limits":
if len(subs) > 0 {
- return fmt.Errorf("'max_time_exponent' has no subfields, but %s were specified", subs)
+ var newDst, newSrc *RelayUplinkForwardLimits
+ if (src == nil || src.ForwardLimits == nil) && dst.ForwardLimits == nil {
+ continue
+ }
+ if src != nil {
+ newSrc = src.ForwardLimits
+ }
+ if dst.ForwardLimits != nil {
+ newDst = dst.ForwardLimits
+ } else {
+ newDst = &RelayUplinkForwardLimits{}
+ dst.ForwardLimits = newDst
+ }
+ if err := newDst.SetFields(newSrc, subs...); err != nil {
+ return err
+ }
+ } else {
+ if src != nil {
+ dst.ForwardLimits = src.ForwardLimits
+ } else {
+ dst.ForwardLimits = nil
+ }
+ }
+ case "dev_addr":
+ if len(subs) > 0 {
+ return fmt.Errorf("'dev_addr' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.MaxTimeExponent = src.MaxTimeExponent
+ dst.DevAddr = src.DevAddr
} else {
- dst.MaxTimeExponent = 0
+ dst.DevAddr = nil
}
-
- default:
- return fmt.Errorf("invalid field: '%s'", name)
- }
- }
- return nil
-}
-
-func (dst *MACCommand_RejoinParamSetupAns) SetFields(src *MACCommand_RejoinParamSetupAns, paths ...string) error {
- for name, subs := range _processPaths(paths) {
- switch name {
- case "max_time_exponent_ack":
+ case "w_f_cnt":
if len(subs) > 0 {
- return fmt.Errorf("'max_time_exponent_ack' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'w_f_cnt' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.MaxTimeExponentAck = src.MaxTimeExponentAck
+ dst.WFCnt = src.WFCnt
} else {
- var zero bool
- dst.MaxTimeExponentAck = zero
+ var zero uint32
+ dst.WFCnt = zero
}
-
- default:
- return fmt.Errorf("invalid field: '%s'", name)
- }
- }
- return nil
-}
-
-func (dst *MACCommand_PingSlotInfoReq) SetFields(src *MACCommand_PingSlotInfoReq, paths ...string) error {
- for name, subs := range _processPaths(paths) {
- switch name {
- case "period":
+ case "root_wor_s_key":
if len(subs) > 0 {
- return fmt.Errorf("'period' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'root_wor_s_key' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.Period = src.Period
+ dst.RootWorSKey = src.RootWorSKey
} else {
- dst.Period = 0
+ dst.RootWorSKey = nil
}
-
- default:
- return fmt.Errorf("invalid field: '%s'", name)
- }
- }
- return nil
-}
-
-func (dst *MACCommand_PingSlotChannelReq) SetFields(src *MACCommand_PingSlotChannelReq, paths ...string) error {
- for name, subs := range _processPaths(paths) {
- switch name {
- case "frequency":
+ case "device_id":
if len(subs) > 0 {
- return fmt.Errorf("'frequency' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'device_id' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.Frequency = src.Frequency
+ dst.DeviceId = src.DeviceId
} else {
- var zero uint64
- dst.Frequency = zero
+ var zero string
+ dst.DeviceId = zero
}
- case "data_rate_index":
+ case "session_key_id":
if len(subs) > 0 {
- return fmt.Errorf("'data_rate_index' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'session_key_id' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.DataRateIndex = src.DataRateIndex
+ dst.SessionKeyId = src.SessionKeyId
} else {
- dst.DataRateIndex = 0
+ dst.SessionKeyId = nil
}
default:
@@ -3627,28 +4746,34 @@ func (dst *MACCommand_PingSlotChannelReq) SetFields(src *MACCommand_PingSlotChan
return nil
}
-func (dst *MACCommand_PingSlotChannelAns) SetFields(src *MACCommand_PingSlotChannelAns, paths ...string) error {
+func (dst *MACCommand_RelayUpdateUplinkListAns) SetFields(src *MACCommand_RelayUpdateUplinkListAns, paths ...string) error {
+ if len(paths) != 0 {
+ return fmt.Errorf("message MACCommand_RelayUpdateUplinkListAns has no fields, but paths %s were specified", paths)
+ }
+ return nil
+}
+
+func (dst *MACCommand_RelayCtrlUplinkListReq) SetFields(src *MACCommand_RelayCtrlUplinkListReq, paths ...string) error {
for name, subs := range _processPaths(paths) {
switch name {
- case "frequency_ack":
+ case "rule_index":
if len(subs) > 0 {
- return fmt.Errorf("'frequency_ack' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'rule_index' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.FrequencyAck = src.FrequencyAck
+ dst.RuleIndex = src.RuleIndex
} else {
- var zero bool
- dst.FrequencyAck = zero
+ var zero uint32
+ dst.RuleIndex = zero
}
- case "data_rate_index_ack":
+ case "action":
if len(subs) > 0 {
- return fmt.Errorf("'data_rate_index_ack' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'action' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.DataRateIndexAck = src.DataRateIndexAck
+ dst.Action = src.Action
} else {
- var zero bool
- dst.DataRateIndexAck = zero
+ dst.Action = 0
}
default:
@@ -3658,28 +4783,28 @@ func (dst *MACCommand_PingSlotChannelAns) SetFields(src *MACCommand_PingSlotChan
return nil
}
-func (dst *MACCommand_BeaconTimingAns) SetFields(src *MACCommand_BeaconTimingAns, paths ...string) error {
+func (dst *MACCommand_RelayCtrlUplinkListAns) SetFields(src *MACCommand_RelayCtrlUplinkListAns, paths ...string) error {
for name, subs := range _processPaths(paths) {
switch name {
- case "delay":
+ case "rule_index_ack":
if len(subs) > 0 {
- return fmt.Errorf("'delay' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'rule_index_ack' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.Delay = src.Delay
+ dst.RuleIndexAck = src.RuleIndexAck
} else {
- var zero uint32
- dst.Delay = zero
+ var zero bool
+ dst.RuleIndexAck = zero
}
- case "channel_index":
+ case "w_f_cnt":
if len(subs) > 0 {
- return fmt.Errorf("'channel_index' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'w_f_cnt' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.ChannelIndex = src.ChannelIndex
+ dst.WFCnt = src.WFCnt
} else {
var zero uint32
- dst.ChannelIndex = zero
+ dst.WFCnt = zero
}
default:
@@ -3689,18 +4814,117 @@ func (dst *MACCommand_BeaconTimingAns) SetFields(src *MACCommand_BeaconTimingAns
return nil
}
-func (dst *MACCommand_BeaconFreqReq) SetFields(src *MACCommand_BeaconFreqReq, paths ...string) error {
+func (dst *MACCommand_RelayConfigureFwdLimitReq) SetFields(src *MACCommand_RelayConfigureFwdLimitReq, paths ...string) error {
for name, subs := range _processPaths(paths) {
switch name {
- case "frequency":
+ case "reset_limit_counter":
if len(subs) > 0 {
- return fmt.Errorf("'frequency' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'reset_limit_counter' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.Frequency = src.Frequency
+ dst.ResetLimitCounter = src.ResetLimitCounter
} else {
- var zero uint64
- dst.Frequency = zero
+ dst.ResetLimitCounter = 0
+ }
+ case "join_request_limits":
+ if len(subs) > 0 {
+ var newDst, newSrc *RelayForwardLimits
+ if (src == nil || src.JoinRequestLimits == nil) && dst.JoinRequestLimits == nil {
+ continue
+ }
+ if src != nil {
+ newSrc = src.JoinRequestLimits
+ }
+ if dst.JoinRequestLimits != nil {
+ newDst = dst.JoinRequestLimits
+ } else {
+ newDst = &RelayForwardLimits{}
+ dst.JoinRequestLimits = newDst
+ }
+ if err := newDst.SetFields(newSrc, subs...); err != nil {
+ return err
+ }
+ } else {
+ if src != nil {
+ dst.JoinRequestLimits = src.JoinRequestLimits
+ } else {
+ dst.JoinRequestLimits = nil
+ }
+ }
+ case "notify_limits":
+ if len(subs) > 0 {
+ var newDst, newSrc *RelayForwardLimits
+ if (src == nil || src.NotifyLimits == nil) && dst.NotifyLimits == nil {
+ continue
+ }
+ if src != nil {
+ newSrc = src.NotifyLimits
+ }
+ if dst.NotifyLimits != nil {
+ newDst = dst.NotifyLimits
+ } else {
+ newDst = &RelayForwardLimits{}
+ dst.NotifyLimits = newDst
+ }
+ if err := newDst.SetFields(newSrc, subs...); err != nil {
+ return err
+ }
+ } else {
+ if src != nil {
+ dst.NotifyLimits = src.NotifyLimits
+ } else {
+ dst.NotifyLimits = nil
+ }
+ }
+ case "global_uplink_limits":
+ if len(subs) > 0 {
+ var newDst, newSrc *RelayForwardLimits
+ if (src == nil || src.GlobalUplinkLimits == nil) && dst.GlobalUplinkLimits == nil {
+ continue
+ }
+ if src != nil {
+ newSrc = src.GlobalUplinkLimits
+ }
+ if dst.GlobalUplinkLimits != nil {
+ newDst = dst.GlobalUplinkLimits
+ } else {
+ newDst = &RelayForwardLimits{}
+ dst.GlobalUplinkLimits = newDst
+ }
+ if err := newDst.SetFields(newSrc, subs...); err != nil {
+ return err
+ }
+ } else {
+ if src != nil {
+ dst.GlobalUplinkLimits = src.GlobalUplinkLimits
+ } else {
+ dst.GlobalUplinkLimits = nil
+ }
+ }
+ case "overall_limits":
+ if len(subs) > 0 {
+ var newDst, newSrc *RelayForwardLimits
+ if (src == nil || src.OverallLimits == nil) && dst.OverallLimits == nil {
+ continue
+ }
+ if src != nil {
+ newSrc = src.OverallLimits
+ }
+ if dst.OverallLimits != nil {
+ newDst = dst.OverallLimits
+ } else {
+ newDst = &RelayForwardLimits{}
+ dst.OverallLimits = newDst
+ }
+ if err := newDst.SetFields(newSrc, subs...); err != nil {
+ return err
+ }
+ } else {
+ if src != nil {
+ dst.OverallLimits = src.OverallLimits
+ } else {
+ dst.OverallLimits = nil
+ }
}
default:
@@ -3710,18 +4934,44 @@ func (dst *MACCommand_BeaconFreqReq) SetFields(src *MACCommand_BeaconFreqReq, pa
return nil
}
-func (dst *MACCommand_BeaconFreqAns) SetFields(src *MACCommand_BeaconFreqAns, paths ...string) error {
+func (dst *MACCommand_RelayConfigureFwdLimitAns) SetFields(src *MACCommand_RelayConfigureFwdLimitAns, paths ...string) error {
+ if len(paths) != 0 {
+ return fmt.Errorf("message MACCommand_RelayConfigureFwdLimitAns has no fields, but paths %s were specified", paths)
+ }
+ return nil
+}
+
+func (dst *MACCommand_RelayNotifyNewEndDeviceReq) SetFields(src *MACCommand_RelayNotifyNewEndDeviceReq, paths ...string) error {
for name, subs := range _processPaths(paths) {
switch name {
- case "frequency_ack":
+ case "dev_addr":
if len(subs) > 0 {
- return fmt.Errorf("'frequency_ack' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'dev_addr' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.FrequencyAck = src.FrequencyAck
+ dst.DevAddr = src.DevAddr
} else {
- var zero bool
- dst.FrequencyAck = zero
+ dst.DevAddr = nil
+ }
+ case "snr":
+ if len(subs) > 0 {
+ return fmt.Errorf("'snr' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.Snr = src.Snr
+ } else {
+ var zero int32
+ dst.Snr = zero
+ }
+ case "rssi":
+ if len(subs) > 0 {
+ return fmt.Errorf("'rssi' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.Rssi = src.Rssi
+ } else {
+ var zero int32
+ dst.Rssi = zero
}
default:
@@ -3731,17 +4981,52 @@ func (dst *MACCommand_BeaconFreqAns) SetFields(src *MACCommand_BeaconFreqAns, pa
return nil
}
-func (dst *MACCommand_DeviceModeInd) SetFields(src *MACCommand_DeviceModeInd, paths ...string) error {
+func (dst *MACCommand_RelayConfReq_Configuration) SetFields(src *MACCommand_RelayConfReq_Configuration, paths ...string) error {
for name, subs := range _processPaths(paths) {
switch name {
- case "class":
+ case "second_channel":
if len(subs) > 0 {
- return fmt.Errorf("'class' has no subfields, but %s were specified", subs)
+ var newDst, newSrc *RelaySecondChannel
+ if (src == nil || src.SecondChannel == nil) && dst.SecondChannel == nil {
+ continue
+ }
+ if src != nil {
+ newSrc = src.SecondChannel
+ }
+ if dst.SecondChannel != nil {
+ newDst = dst.SecondChannel
+ } else {
+ newDst = &RelaySecondChannel{}
+ dst.SecondChannel = newDst
+ }
+ if err := newDst.SetFields(newSrc, subs...); err != nil {
+ return err
+ }
+ } else {
+ if src != nil {
+ dst.SecondChannel = src.SecondChannel
+ } else {
+ dst.SecondChannel = nil
+ }
+ }
+ case "default_channel_index":
+ if len(subs) > 0 {
+ return fmt.Errorf("'default_channel_index' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.Class = src.Class
+ dst.DefaultChannelIndex = src.DefaultChannelIndex
} else {
- dst.Class = 0
+ var zero uint32
+ dst.DefaultChannelIndex = zero
+ }
+ case "cad_periodicity":
+ if len(subs) > 0 {
+ return fmt.Errorf("'cad_periodicity' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.CadPeriodicity = src.CadPeriodicity
+ } else {
+ dst.CadPeriodicity = 0
}
default:
@@ -3751,17 +5036,182 @@ func (dst *MACCommand_DeviceModeInd) SetFields(src *MACCommand_DeviceModeInd, pa
return nil
}
-func (dst *MACCommand_DeviceModeConf) SetFields(src *MACCommand_DeviceModeConf, paths ...string) error {
+func (dst *MACCommand_RelayEndDeviceConfReq_Configuration) SetFields(src *MACCommand_RelayEndDeviceConfReq_Configuration, paths ...string) error {
for name, subs := range _processPaths(paths) {
switch name {
- case "class":
+ case "backoff":
if len(subs) > 0 {
- return fmt.Errorf("'class' has no subfields, but %s were specified", subs)
+ return fmt.Errorf("'backoff' has no subfields, but %s were specified", subs)
}
if src != nil {
- dst.Class = src.Class
+ dst.Backoff = src.Backoff
} else {
- dst.Class = 0
+ var zero uint32
+ dst.Backoff = zero
+ }
+ case "second_channel":
+ if len(subs) > 0 {
+ var newDst, newSrc *RelaySecondChannel
+ if (src == nil || src.SecondChannel == nil) && dst.SecondChannel == nil {
+ continue
+ }
+ if src != nil {
+ newSrc = src.SecondChannel
+ }
+ if dst.SecondChannel != nil {
+ newDst = dst.SecondChannel
+ } else {
+ newDst = &RelaySecondChannel{}
+ dst.SecondChannel = newDst
+ }
+ if err := newDst.SetFields(newSrc, subs...); err != nil {
+ return err
+ }
+ } else {
+ if src != nil {
+ dst.SecondChannel = src.SecondChannel
+ } else {
+ dst.SecondChannel = nil
+ }
+ }
+ case "serving_device_id":
+ if len(subs) > 0 {
+ return fmt.Errorf("'serving_device_id' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.ServingDeviceId = src.ServingDeviceId
+ } else {
+ var zero string
+ dst.ServingDeviceId = zero
+ }
+
+ case "mode":
+ if len(subs) == 0 && src == nil {
+ dst.Mode = nil
+ continue
+ } else if len(subs) == 0 {
+ dst.Mode = src.Mode
+ continue
+ }
+
+ subPathMap := _processPaths(subs)
+ if len(subPathMap) > 1 {
+ return fmt.Errorf("more than one field specified for oneof field '%s'", name)
+ }
+ for oneofName, oneofSubs := range subPathMap {
+ switch oneofName {
+ case "always":
+ var srcTypeOk bool
+ if src != nil {
+ _, srcTypeOk = src.Mode.(*MACCommand_RelayEndDeviceConfReq_Configuration_Always)
+ }
+ if srcValid := srcTypeOk || src == nil || src.Mode == nil || len(oneofSubs) == 0; !srcValid {
+ return fmt.Errorf("attempt to set oneof 'always', while different oneof is set in source")
+ }
+ _, dstTypeOk := dst.Mode.(*MACCommand_RelayEndDeviceConfReq_Configuration_Always)
+ if dstValid := dstTypeOk || dst.Mode == nil || len(oneofSubs) == 0; !dstValid {
+ return fmt.Errorf("attempt to set oneof 'always', while different oneof is set in destination")
+ }
+ if len(oneofSubs) > 0 {
+ var newDst, newSrc *RelayEndDeviceAlwaysMode
+ if srcTypeOk {
+ newSrc = src.Mode.(*MACCommand_RelayEndDeviceConfReq_Configuration_Always).Always
+ }
+ if dstTypeOk {
+ newDst = dst.Mode.(*MACCommand_RelayEndDeviceConfReq_Configuration_Always).Always
+ } else if srcTypeOk {
+ newDst = &RelayEndDeviceAlwaysMode{}
+ dst.Mode = &MACCommand_RelayEndDeviceConfReq_Configuration_Always{Always: newDst}
+ } else {
+ dst.Mode = nil
+ continue
+ }
+ if err := newDst.SetFields(newSrc, oneofSubs...); err != nil {
+ return err
+ }
+ } else {
+ if srcTypeOk {
+ dst.Mode = src.Mode
+ } else {
+ dst.Mode = nil
+ }
+ }
+ case "dynamic":
+ var srcTypeOk bool
+ if src != nil {
+ _, srcTypeOk = src.Mode.(*MACCommand_RelayEndDeviceConfReq_Configuration_Dynamic)
+ }
+ if srcValid := srcTypeOk || src == nil || src.Mode == nil || len(oneofSubs) == 0; !srcValid {
+ return fmt.Errorf("attempt to set oneof 'dynamic', while different oneof is set in source")
+ }
+ _, dstTypeOk := dst.Mode.(*MACCommand_RelayEndDeviceConfReq_Configuration_Dynamic)
+ if dstValid := dstTypeOk || dst.Mode == nil || len(oneofSubs) == 0; !dstValid {
+ return fmt.Errorf("attempt to set oneof 'dynamic', while different oneof is set in destination")
+ }
+ if len(oneofSubs) > 0 {
+ var newDst, newSrc *RelayEndDeviceDynamicMode
+ if srcTypeOk {
+ newSrc = src.Mode.(*MACCommand_RelayEndDeviceConfReq_Configuration_Dynamic).Dynamic
+ }
+ if dstTypeOk {
+ newDst = dst.Mode.(*MACCommand_RelayEndDeviceConfReq_Configuration_Dynamic).Dynamic
+ } else if srcTypeOk {
+ newDst = &RelayEndDeviceDynamicMode{}
+ dst.Mode = &MACCommand_RelayEndDeviceConfReq_Configuration_Dynamic{Dynamic: newDst}
+ } else {
+ dst.Mode = nil
+ continue
+ }
+ if err := newDst.SetFields(newSrc, oneofSubs...); err != nil {
+ return err
+ }
+ } else {
+ if srcTypeOk {
+ dst.Mode = src.Mode
+ } else {
+ dst.Mode = nil
+ }
+ }
+ case "end_device_controlled":
+ var srcTypeOk bool
+ if src != nil {
+ _, srcTypeOk = src.Mode.(*MACCommand_RelayEndDeviceConfReq_Configuration_EndDeviceControlled)
+ }
+ if srcValid := srcTypeOk || src == nil || src.Mode == nil || len(oneofSubs) == 0; !srcValid {
+ return fmt.Errorf("attempt to set oneof 'end_device_controlled', while different oneof is set in source")
+ }
+ _, dstTypeOk := dst.Mode.(*MACCommand_RelayEndDeviceConfReq_Configuration_EndDeviceControlled)
+ if dstValid := dstTypeOk || dst.Mode == nil || len(oneofSubs) == 0; !dstValid {
+ return fmt.Errorf("attempt to set oneof 'end_device_controlled', while different oneof is set in destination")
+ }
+ if len(oneofSubs) > 0 {
+ var newDst, newSrc *RelayEndDeviceControlledMode
+ if srcTypeOk {
+ newSrc = src.Mode.(*MACCommand_RelayEndDeviceConfReq_Configuration_EndDeviceControlled).EndDeviceControlled
+ }
+ if dstTypeOk {
+ newDst = dst.Mode.(*MACCommand_RelayEndDeviceConfReq_Configuration_EndDeviceControlled).EndDeviceControlled
+ } else if srcTypeOk {
+ newDst = &RelayEndDeviceControlledMode{}
+ dst.Mode = &MACCommand_RelayEndDeviceConfReq_Configuration_EndDeviceControlled{EndDeviceControlled: newDst}
+ } else {
+ dst.Mode = nil
+ continue
+ }
+ if err := newDst.SetFields(newSrc, oneofSubs...); err != nil {
+ return err
+ }
+ } else {
+ if srcTypeOk {
+ dst.Mode = src.Mode
+ } else {
+ dst.Mode = nil
+ }
+ }
+
+ default:
+ return fmt.Errorf("invalid oneof field: '%s.%s'", name, oneofName)
+ }
}
default:
diff --git a/pkg/ttnpb/lorawan.pb.validate.go b/pkg/ttnpb/lorawan.pb.validate.go
index cb1ee3b620..637c773803 100644
--- a/pkg/ttnpb/lorawan.pb.validate.go
+++ b/pkg/ttnpb/lorawan.pb.validate.go
@@ -2421,536 +2421,2649 @@ var _ interface {
ErrorName() string
} = TxRequestValidationError{}
-// ValidateFields checks the field values on MACCommand with the rules defined
-// in the proto definition for this message. If any rules are violated, an
-// error is returned.
-func (m *MACCommand) ValidateFields(paths ...string) error {
+// ValidateFields checks the field values on RelaySecondChannel with the rules
+// defined in the proto definition for this message. If any rules are
+// violated, an error is returned.
+func (m *RelaySecondChannel) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = MACCommandFieldPathsNested
+ paths = RelaySecondChannelFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "cid":
+ case "ack_offset":
- if _, ok := _MACCommand_Cid_NotInLookup[m.GetCid()]; ok {
- return MACCommandValidationError{
- field: "cid",
- reason: "value must not be in list [0]",
+ if _, ok := RelaySecondChAckOffset_name[int32(m.GetAckOffset())]; !ok {
+ return RelaySecondChannelValidationError{
+ field: "ack_offset",
+ reason: "value must be one of the defined enum values",
}
}
- if _, ok := MACCommandIdentifier_name[int32(m.GetCid())]; !ok {
- return MACCommandValidationError{
- field: "cid",
+ case "data_rate_index":
+
+ if _, ok := DataRateIndex_name[int32(m.GetDataRateIndex())]; !ok {
+ return RelaySecondChannelValidationError{
+ field: "data_rate_index",
reason: "value must be one of the defined enum values",
}
}
- case "payload":
- if len(subs) == 0 {
- subs = []string{
- "raw_payload", "reset_ind", "reset_conf", "link_check_ans", "link_adr_req", "link_adr_ans", "duty_cycle_req", "rx_param_setup_req", "rx_param_setup_ans", "dev_status_ans", "new_channel_req", "new_channel_ans", "dl_channel_req", "dl_channel_ans", "rx_timing_setup_req", "tx_param_setup_req", "rekey_ind", "rekey_conf", "adr_param_setup_req", "device_time_ans", "force_rejoin_req", "rejoin_param_setup_req", "rejoin_param_setup_ans", "ping_slot_info_req", "ping_slot_channel_req", "ping_slot_channel_ans", "beacon_timing_ans", "beacon_freq_req", "beacon_freq_ans", "device_mode_ind", "device_mode_conf",
+ case "frequency":
+
+ if m.GetFrequency() < 100000 {
+ return RelaySecondChannelValidationError{
+ field: "frequency",
+ reason: "value must be greater than or equal to 100000",
}
}
- for name, subs := range _processPaths(subs) {
- _ = subs
- switch name {
- case "raw_payload":
- w, ok := m.Payload.(*MACCommand_RawPayload)
- if !ok || w == nil {
- continue
- }
- // no validation rules for RawPayload
- case "reset_ind":
- w, ok := m.Payload.(*MACCommand_ResetInd_)
- if !ok || w == nil {
- continue
- }
- if v, ok := interface{}(m.GetResetInd()).(interface{ ValidateFields(...string) error }); ok {
- if err := v.ValidateFields(subs...); err != nil {
- return MACCommandValidationError{
- field: "reset_ind",
- reason: "embedded message failed validation",
- cause: err,
- }
- }
- }
+ default:
+ return RelaySecondChannelValidationError{
+ field: name,
+ reason: "invalid field path",
+ }
+ }
+ }
+ return nil
+}
- case "reset_conf":
- w, ok := m.Payload.(*MACCommand_ResetConf_)
- if !ok || w == nil {
- continue
- }
+// RelaySecondChannelValidationError is the validation error returned by
+// RelaySecondChannel.ValidateFields if the designated constraints aren't met.
+type RelaySecondChannelValidationError struct {
+ field string
+ reason string
+ cause error
+ key bool
+}
- if v, ok := interface{}(m.GetResetConf()).(interface{ ValidateFields(...string) error }); ok {
- if err := v.ValidateFields(subs...); err != nil {
- return MACCommandValidationError{
- field: "reset_conf",
- reason: "embedded message failed validation",
- cause: err,
- }
- }
- }
+// Field function returns field value.
+func (e RelaySecondChannelValidationError) Field() string { return e.field }
- case "link_check_ans":
- w, ok := m.Payload.(*MACCommand_LinkCheckAns_)
- if !ok || w == nil {
- continue
- }
+// Reason function returns reason value.
+func (e RelaySecondChannelValidationError) Reason() string { return e.reason }
- if v, ok := interface{}(m.GetLinkCheckAns()).(interface{ ValidateFields(...string) error }); ok {
- if err := v.ValidateFields(subs...); err != nil {
- return MACCommandValidationError{
- field: "link_check_ans",
- reason: "embedded message failed validation",
- cause: err,
- }
- }
- }
+// Cause function returns cause value.
+func (e RelaySecondChannelValidationError) Cause() error { return e.cause }
- case "link_adr_req":
- w, ok := m.Payload.(*MACCommand_LinkAdrReq)
- if !ok || w == nil {
- continue
- }
+// Key function returns key value.
+func (e RelaySecondChannelValidationError) Key() bool { return e.key }
- if v, ok := interface{}(m.GetLinkAdrReq()).(interface{ ValidateFields(...string) error }); ok {
- if err := v.ValidateFields(subs...); err != nil {
- return MACCommandValidationError{
- field: "link_adr_req",
- reason: "embedded message failed validation",
- cause: err,
- }
- }
- }
+// ErrorName returns error name.
+func (e RelaySecondChannelValidationError) ErrorName() string {
+ return "RelaySecondChannelValidationError"
+}
- case "link_adr_ans":
- w, ok := m.Payload.(*MACCommand_LinkAdrAns)
- if !ok || w == nil {
- continue
- }
+// Error satisfies the builtin error interface
+func (e RelaySecondChannelValidationError) Error() string {
+ cause := ""
+ if e.cause != nil {
+ cause = fmt.Sprintf(" | caused by: %v", e.cause)
+ }
- if v, ok := interface{}(m.GetLinkAdrAns()).(interface{ ValidateFields(...string) error }); ok {
- if err := v.ValidateFields(subs...); err != nil {
- return MACCommandValidationError{
- field: "link_adr_ans",
- reason: "embedded message failed validation",
- cause: err,
- }
- }
- }
+ key := ""
+ if e.key {
+ key = "key for "
+ }
- case "duty_cycle_req":
- w, ok := m.Payload.(*MACCommand_DutyCycleReq_)
- if !ok || w == nil {
- continue
- }
+ return fmt.Sprintf(
+ "invalid %sRelaySecondChannel.%s: %s%s",
+ key,
+ e.field,
+ e.reason,
+ cause)
+}
- if v, ok := interface{}(m.GetDutyCycleReq()).(interface{ ValidateFields(...string) error }); ok {
- if err := v.ValidateFields(subs...); err != nil {
- return MACCommandValidationError{
- field: "duty_cycle_req",
- reason: "embedded message failed validation",
- cause: err,
- }
- }
- }
+var _ error = RelaySecondChannelValidationError{}
- case "rx_param_setup_req":
- w, ok := m.Payload.(*MACCommand_RxParamSetupReq_)
- if !ok || w == nil {
- continue
- }
+var _ interface {
+ Field() string
+ Reason() string
+ Key() bool
+ Cause() error
+ ErrorName() string
+} = RelaySecondChannelValidationError{}
- if v, ok := interface{}(m.GetRxParamSetupReq()).(interface{ ValidateFields(...string) error }); ok {
- if err := v.ValidateFields(subs...); err != nil {
- return MACCommandValidationError{
- field: "rx_param_setup_req",
- reason: "embedded message failed validation",
- cause: err,
- }
- }
- }
+// ValidateFields checks the field values on RelayUplinkForwardLimits with the
+// rules defined in the proto definition for this message. If any rules are
+// violated, an error is returned.
+func (m *RelayUplinkForwardLimits) ValidateFields(paths ...string) error {
+ if m == nil {
+ return nil
+ }
- case "rx_param_setup_ans":
- w, ok := m.Payload.(*MACCommand_RxParamSetupAns_)
- if !ok || w == nil {
- continue
- }
+ if len(paths) == 0 {
+ paths = RelayUplinkForwardLimitsFieldPathsNested
+ }
- if v, ok := interface{}(m.GetRxParamSetupAns()).(interface{ ValidateFields(...string) error }); ok {
- if err := v.ValidateFields(subs...); err != nil {
- return MACCommandValidationError{
- field: "rx_param_setup_ans",
- reason: "embedded message failed validation",
- cause: err,
- }
- }
- }
+ for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
+ _ = subs
+ switch name {
+ case "bucket_size":
- case "dev_status_ans":
- w, ok := m.Payload.(*MACCommand_DevStatusAns_)
- if !ok || w == nil {
- continue
- }
+ if _, ok := RelayLimitBucketSize_name[int32(m.GetBucketSize())]; !ok {
+ return RelayUplinkForwardLimitsValidationError{
+ field: "bucket_size",
+ reason: "value must be one of the defined enum values",
+ }
+ }
- if v, ok := interface{}(m.GetDevStatusAns()).(interface{ ValidateFields(...string) error }); ok {
- if err := v.ValidateFields(subs...); err != nil {
- return MACCommandValidationError{
- field: "dev_status_ans",
- reason: "embedded message failed validation",
- cause: err,
- }
- }
- }
+ case "reload_rate":
- case "new_channel_req":
- w, ok := m.Payload.(*MACCommand_NewChannelReq_)
- if !ok || w == nil {
- continue
- }
+ if m.GetReloadRate() > 62 {
+ return RelayUplinkForwardLimitsValidationError{
+ field: "reload_rate",
+ reason: "value must be less than or equal to 62",
+ }
+ }
- if v, ok := interface{}(m.GetNewChannelReq()).(interface{ ValidateFields(...string) error }); ok {
- if err := v.ValidateFields(subs...); err != nil {
- return MACCommandValidationError{
- field: "new_channel_req",
- reason: "embedded message failed validation",
- cause: err,
- }
- }
- }
+ default:
+ return RelayUplinkForwardLimitsValidationError{
+ field: name,
+ reason: "invalid field path",
+ }
+ }
+ }
+ return nil
+}
- case "new_channel_ans":
- w, ok := m.Payload.(*MACCommand_NewChannelAns_)
- if !ok || w == nil {
- continue
- }
+// RelayUplinkForwardLimitsValidationError is the validation error returned by
+// RelayUplinkForwardLimits.ValidateFields if the designated constraints
+// aren't met.
+type RelayUplinkForwardLimitsValidationError struct {
+ field string
+ reason string
+ cause error
+ key bool
+}
- if v, ok := interface{}(m.GetNewChannelAns()).(interface{ ValidateFields(...string) error }); ok {
- if err := v.ValidateFields(subs...); err != nil {
- return MACCommandValidationError{
- field: "new_channel_ans",
- reason: "embedded message failed validation",
+// Field function returns field value.
+func (e RelayUplinkForwardLimitsValidationError) Field() string { return e.field }
+
+// Reason function returns reason value.
+func (e RelayUplinkForwardLimitsValidationError) Reason() string { return e.reason }
+
+// Cause function returns cause value.
+func (e RelayUplinkForwardLimitsValidationError) Cause() error { return e.cause }
+
+// Key function returns key value.
+func (e RelayUplinkForwardLimitsValidationError) Key() bool { return e.key }
+
+// ErrorName returns error name.
+func (e RelayUplinkForwardLimitsValidationError) ErrorName() string {
+ return "RelayUplinkForwardLimitsValidationError"
+}
+
+// Error satisfies the builtin error interface
+func (e RelayUplinkForwardLimitsValidationError) Error() string {
+ cause := ""
+ if e.cause != nil {
+ cause = fmt.Sprintf(" | caused by: %v", e.cause)
+ }
+
+ key := ""
+ if e.key {
+ key = "key for "
+ }
+
+ return fmt.Sprintf(
+ "invalid %sRelayUplinkForwardLimits.%s: %s%s",
+ key,
+ e.field,
+ e.reason,
+ cause)
+}
+
+var _ error = RelayUplinkForwardLimitsValidationError{}
+
+var _ interface {
+ Field() string
+ Reason() string
+ Key() bool
+ Cause() error
+ ErrorName() string
+} = RelayUplinkForwardLimitsValidationError{}
+
+// ValidateFields checks the field values on RelayForwardLimits with the rules
+// defined in the proto definition for this message. If any rules are
+// violated, an error is returned.
+func (m *RelayForwardLimits) ValidateFields(paths ...string) error {
+ if m == nil {
+ return nil
+ }
+
+ if len(paths) == 0 {
+ paths = RelayForwardLimitsFieldPathsNested
+ }
+
+ for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
+ _ = subs
+ switch name {
+ case "bucket_size":
+
+ if _, ok := RelayLimitBucketSize_name[int32(m.GetBucketSize())]; !ok {
+ return RelayForwardLimitsValidationError{
+ field: "bucket_size",
+ reason: "value must be one of the defined enum values",
+ }
+ }
+
+ case "reload_rate":
+
+ if m.GetReloadRate() > 126 {
+ return RelayForwardLimitsValidationError{
+ field: "reload_rate",
+ reason: "value must be less than or equal to 126",
+ }
+ }
+
+ default:
+ return RelayForwardLimitsValidationError{
+ field: name,
+ reason: "invalid field path",
+ }
+ }
+ }
+ return nil
+}
+
+// RelayForwardLimitsValidationError is the validation error returned by
+// RelayForwardLimits.ValidateFields if the designated constraints aren't met.
+type RelayForwardLimitsValidationError struct {
+ field string
+ reason string
+ cause error
+ key bool
+}
+
+// Field function returns field value.
+func (e RelayForwardLimitsValidationError) Field() string { return e.field }
+
+// Reason function returns reason value.
+func (e RelayForwardLimitsValidationError) Reason() string { return e.reason }
+
+// Cause function returns cause value.
+func (e RelayForwardLimitsValidationError) Cause() error { return e.cause }
+
+// Key function returns key value.
+func (e RelayForwardLimitsValidationError) Key() bool { return e.key }
+
+// ErrorName returns error name.
+func (e RelayForwardLimitsValidationError) ErrorName() string {
+ return "RelayForwardLimitsValidationError"
+}
+
+// Error satisfies the builtin error interface
+func (e RelayForwardLimitsValidationError) Error() string {
+ cause := ""
+ if e.cause != nil {
+ cause = fmt.Sprintf(" | caused by: %v", e.cause)
+ }
+
+ key := ""
+ if e.key {
+ key = "key for "
+ }
+
+ return fmt.Sprintf(
+ "invalid %sRelayForwardLimits.%s: %s%s",
+ key,
+ e.field,
+ e.reason,
+ cause)
+}
+
+var _ error = RelayForwardLimitsValidationError{}
+
+var _ interface {
+ Field() string
+ Reason() string
+ Key() bool
+ Cause() error
+ ErrorName() string
+} = RelayForwardLimitsValidationError{}
+
+// ValidateFields checks the field values on RelayEndDeviceAlwaysMode with the
+// rules defined in the proto definition for this message. If any rules are
+// violated, an error is returned.
+func (m *RelayEndDeviceAlwaysMode) ValidateFields(paths ...string) error {
+ if len(paths) > 0 {
+ return fmt.Errorf("message RelayEndDeviceAlwaysMode has no fields, but paths %s were specified", paths)
+ }
+ return nil
+}
+
+// RelayEndDeviceAlwaysModeValidationError is the validation error returned by
+// RelayEndDeviceAlwaysMode.ValidateFields if the designated constraints
+// aren't met.
+type RelayEndDeviceAlwaysModeValidationError struct {
+ field string
+ reason string
+ cause error
+ key bool
+}
+
+// Field function returns field value.
+func (e RelayEndDeviceAlwaysModeValidationError) Field() string { return e.field }
+
+// Reason function returns reason value.
+func (e RelayEndDeviceAlwaysModeValidationError) Reason() string { return e.reason }
+
+// Cause function returns cause value.
+func (e RelayEndDeviceAlwaysModeValidationError) Cause() error { return e.cause }
+
+// Key function returns key value.
+func (e RelayEndDeviceAlwaysModeValidationError) Key() bool { return e.key }
+
+// ErrorName returns error name.
+func (e RelayEndDeviceAlwaysModeValidationError) ErrorName() string {
+ return "RelayEndDeviceAlwaysModeValidationError"
+}
+
+// Error satisfies the builtin error interface
+func (e RelayEndDeviceAlwaysModeValidationError) Error() string {
+ cause := ""
+ if e.cause != nil {
+ cause = fmt.Sprintf(" | caused by: %v", e.cause)
+ }
+
+ key := ""
+ if e.key {
+ key = "key for "
+ }
+
+ return fmt.Sprintf(
+ "invalid %sRelayEndDeviceAlwaysMode.%s: %s%s",
+ key,
+ e.field,
+ e.reason,
+ cause)
+}
+
+var _ error = RelayEndDeviceAlwaysModeValidationError{}
+
+var _ interface {
+ Field() string
+ Reason() string
+ Key() bool
+ Cause() error
+ ErrorName() string
+} = RelayEndDeviceAlwaysModeValidationError{}
+
+// ValidateFields checks the field values on RelayEndDeviceDynamicMode with the
+// rules defined in the proto definition for this message. If any rules are
+// violated, an error is returned.
+func (m *RelayEndDeviceDynamicMode) ValidateFields(paths ...string) error {
+ if m == nil {
+ return nil
+ }
+
+ if len(paths) == 0 {
+ paths = RelayEndDeviceDynamicModeFieldPathsNested
+ }
+
+ for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
+ _ = subs
+ switch name {
+ case "smart_enable_level":
+
+ if _, ok := RelaySmartEnableLevel_name[int32(m.GetSmartEnableLevel())]; !ok {
+ return RelayEndDeviceDynamicModeValidationError{
+ field: "smart_enable_level",
+ reason: "value must be one of the defined enum values",
+ }
+ }
+
+ default:
+ return RelayEndDeviceDynamicModeValidationError{
+ field: name,
+ reason: "invalid field path",
+ }
+ }
+ }
+ return nil
+}
+
+// RelayEndDeviceDynamicModeValidationError is the validation error returned by
+// RelayEndDeviceDynamicMode.ValidateFields if the designated constraints
+// aren't met.
+type RelayEndDeviceDynamicModeValidationError struct {
+ field string
+ reason string
+ cause error
+ key bool
+}
+
+// Field function returns field value.
+func (e RelayEndDeviceDynamicModeValidationError) Field() string { return e.field }
+
+// Reason function returns reason value.
+func (e RelayEndDeviceDynamicModeValidationError) Reason() string { return e.reason }
+
+// Cause function returns cause value.
+func (e RelayEndDeviceDynamicModeValidationError) Cause() error { return e.cause }
+
+// Key function returns key value.
+func (e RelayEndDeviceDynamicModeValidationError) Key() bool { return e.key }
+
+// ErrorName returns error name.
+func (e RelayEndDeviceDynamicModeValidationError) ErrorName() string {
+ return "RelayEndDeviceDynamicModeValidationError"
+}
+
+// Error satisfies the builtin error interface
+func (e RelayEndDeviceDynamicModeValidationError) Error() string {
+ cause := ""
+ if e.cause != nil {
+ cause = fmt.Sprintf(" | caused by: %v", e.cause)
+ }
+
+ key := ""
+ if e.key {
+ key = "key for "
+ }
+
+ return fmt.Sprintf(
+ "invalid %sRelayEndDeviceDynamicMode.%s: %s%s",
+ key,
+ e.field,
+ e.reason,
+ cause)
+}
+
+var _ error = RelayEndDeviceDynamicModeValidationError{}
+
+var _ interface {
+ Field() string
+ Reason() string
+ Key() bool
+ Cause() error
+ ErrorName() string
+} = RelayEndDeviceDynamicModeValidationError{}
+
+// ValidateFields checks the field values on RelayEndDeviceControlledMode with
+// the rules defined in the proto definition for this message. If any rules
+// are violated, an error is returned.
+func (m *RelayEndDeviceControlledMode) ValidateFields(paths ...string) error {
+ if len(paths) > 0 {
+ return fmt.Errorf("message RelayEndDeviceControlledMode has no fields, but paths %s were specified", paths)
+ }
+ return nil
+}
+
+// RelayEndDeviceControlledModeValidationError is the validation error returned
+// by RelayEndDeviceControlledMode.ValidateFields if the designated
+// constraints aren't met.
+type RelayEndDeviceControlledModeValidationError struct {
+ field string
+ reason string
+ cause error
+ key bool
+}
+
+// Field function returns field value.
+func (e RelayEndDeviceControlledModeValidationError) Field() string { return e.field }
+
+// Reason function returns reason value.
+func (e RelayEndDeviceControlledModeValidationError) Reason() string { return e.reason }
+
+// Cause function returns cause value.
+func (e RelayEndDeviceControlledModeValidationError) Cause() error { return e.cause }
+
+// Key function returns key value.
+func (e RelayEndDeviceControlledModeValidationError) Key() bool { return e.key }
+
+// ErrorName returns error name.
+func (e RelayEndDeviceControlledModeValidationError) ErrorName() string {
+ return "RelayEndDeviceControlledModeValidationError"
+}
+
+// Error satisfies the builtin error interface
+func (e RelayEndDeviceControlledModeValidationError) Error() string {
+ cause := ""
+ if e.cause != nil {
+ cause = fmt.Sprintf(" | caused by: %v", e.cause)
+ }
+
+ key := ""
+ if e.key {
+ key = "key for "
+ }
+
+ return fmt.Sprintf(
+ "invalid %sRelayEndDeviceControlledMode.%s: %s%s",
+ key,
+ e.field,
+ e.reason,
+ cause)
+}
+
+var _ error = RelayEndDeviceControlledModeValidationError{}
+
+var _ interface {
+ Field() string
+ Reason() string
+ Key() bool
+ Cause() error
+ ErrorName() string
+} = RelayEndDeviceControlledModeValidationError{}
+
+// ValidateFields checks the field values on MACCommand with the rules defined
+// in the proto definition for this message. If any rules are violated, an
+// error is returned.
+func (m *MACCommand) ValidateFields(paths ...string) error {
+ if m == nil {
+ return nil
+ }
+
+ if len(paths) == 0 {
+ paths = MACCommandFieldPathsNested
+ }
+
+ for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
+ _ = subs
+ switch name {
+ case "cid":
+
+ if _, ok := _MACCommand_Cid_NotInLookup[m.GetCid()]; ok {
+ return MACCommandValidationError{
+ field: "cid",
+ reason: "value must not be in list [0]",
+ }
+ }
+
+ if _, ok := MACCommandIdentifier_name[int32(m.GetCid())]; !ok {
+ return MACCommandValidationError{
+ field: "cid",
+ reason: "value must be one of the defined enum values",
+ }
+ }
+
+ case "payload":
+ if len(subs) == 0 {
+ subs = []string{
+ "raw_payload", "reset_ind", "reset_conf", "link_check_ans", "link_adr_req", "link_adr_ans", "duty_cycle_req", "rx_param_setup_req", "rx_param_setup_ans", "dev_status_ans", "new_channel_req", "new_channel_ans", "dl_channel_req", "dl_channel_ans", "rx_timing_setup_req", "tx_param_setup_req", "rekey_ind", "rekey_conf", "adr_param_setup_req", "device_time_ans", "force_rejoin_req", "rejoin_param_setup_req", "rejoin_param_setup_ans", "ping_slot_info_req", "ping_slot_channel_req", "ping_slot_channel_ans", "beacon_timing_ans", "beacon_freq_req", "beacon_freq_ans", "device_mode_ind", "device_mode_conf", "relay_conf_req", "relay_conf_ans", "relay_end_device_conf_req", "relay_end_device_conf_ans", "relay_update_uplink_list_req", "relay_update_uplink_list_ans", "relay_ctrl_uplink_list_req", "relay_ctrl_uplink_list_ans", "relay_configure_fwd_limit_req", "relay_configure_fwd_limit_ans", "relay_notify_new_end_device_req",
+ }
+ }
+ for name, subs := range _processPaths(subs) {
+ _ = subs
+ switch name {
+ case "raw_payload":
+ w, ok := m.Payload.(*MACCommand_RawPayload)
+ if !ok || w == nil {
+ continue
+ }
+ // no validation rules for RawPayload
+ case "reset_ind":
+ w, ok := m.Payload.(*MACCommand_ResetInd_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetResetInd()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "reset_ind",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "reset_conf":
+ w, ok := m.Payload.(*MACCommand_ResetConf_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetResetConf()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "reset_conf",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "link_check_ans":
+ w, ok := m.Payload.(*MACCommand_LinkCheckAns_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetLinkCheckAns()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "link_check_ans",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "link_adr_req":
+ w, ok := m.Payload.(*MACCommand_LinkAdrReq)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetLinkAdrReq()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "link_adr_req",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "link_adr_ans":
+ w, ok := m.Payload.(*MACCommand_LinkAdrAns)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetLinkAdrAns()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "link_adr_ans",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "duty_cycle_req":
+ w, ok := m.Payload.(*MACCommand_DutyCycleReq_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetDutyCycleReq()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "duty_cycle_req",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "rx_param_setup_req":
+ w, ok := m.Payload.(*MACCommand_RxParamSetupReq_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetRxParamSetupReq()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "rx_param_setup_req",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "rx_param_setup_ans":
+ w, ok := m.Payload.(*MACCommand_RxParamSetupAns_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetRxParamSetupAns()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "rx_param_setup_ans",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "dev_status_ans":
+ w, ok := m.Payload.(*MACCommand_DevStatusAns_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetDevStatusAns()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "dev_status_ans",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "new_channel_req":
+ w, ok := m.Payload.(*MACCommand_NewChannelReq_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetNewChannelReq()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "new_channel_req",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "new_channel_ans":
+ w, ok := m.Payload.(*MACCommand_NewChannelAns_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetNewChannelAns()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "new_channel_ans",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "dl_channel_req":
+ w, ok := m.Payload.(*MACCommand_DlChannelReq)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetDlChannelReq()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "dl_channel_req",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "dl_channel_ans":
+ w, ok := m.Payload.(*MACCommand_DlChannelAns)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetDlChannelAns()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "dl_channel_ans",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "rx_timing_setup_req":
+ w, ok := m.Payload.(*MACCommand_RxTimingSetupReq_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetRxTimingSetupReq()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "rx_timing_setup_req",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "tx_param_setup_req":
+ w, ok := m.Payload.(*MACCommand_TxParamSetupReq_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetTxParamSetupReq()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "tx_param_setup_req",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "rekey_ind":
+ w, ok := m.Payload.(*MACCommand_RekeyInd_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetRekeyInd()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "rekey_ind",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "rekey_conf":
+ w, ok := m.Payload.(*MACCommand_RekeyConf_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetRekeyConf()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "rekey_conf",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "adr_param_setup_req":
+ w, ok := m.Payload.(*MACCommand_AdrParamSetupReq)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetAdrParamSetupReq()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "adr_param_setup_req",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "device_time_ans":
+ w, ok := m.Payload.(*MACCommand_DeviceTimeAns_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetDeviceTimeAns()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "device_time_ans",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "force_rejoin_req":
+ w, ok := m.Payload.(*MACCommand_ForceRejoinReq_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetForceRejoinReq()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "force_rejoin_req",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "rejoin_param_setup_req":
+ w, ok := m.Payload.(*MACCommand_RejoinParamSetupReq_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetRejoinParamSetupReq()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "rejoin_param_setup_req",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "rejoin_param_setup_ans":
+ w, ok := m.Payload.(*MACCommand_RejoinParamSetupAns_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetRejoinParamSetupAns()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "rejoin_param_setup_ans",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "ping_slot_info_req":
+ w, ok := m.Payload.(*MACCommand_PingSlotInfoReq_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetPingSlotInfoReq()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "ping_slot_info_req",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "ping_slot_channel_req":
+ w, ok := m.Payload.(*MACCommand_PingSlotChannelReq_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetPingSlotChannelReq()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "ping_slot_channel_req",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "ping_slot_channel_ans":
+ w, ok := m.Payload.(*MACCommand_PingSlotChannelAns_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetPingSlotChannelAns()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "ping_slot_channel_ans",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "beacon_timing_ans":
+ w, ok := m.Payload.(*MACCommand_BeaconTimingAns_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetBeaconTimingAns()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "beacon_timing_ans",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "beacon_freq_req":
+ w, ok := m.Payload.(*MACCommand_BeaconFreqReq_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetBeaconFreqReq()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "beacon_freq_req",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "beacon_freq_ans":
+ w, ok := m.Payload.(*MACCommand_BeaconFreqAns_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetBeaconFreqAns()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "beacon_freq_ans",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "device_mode_ind":
+ w, ok := m.Payload.(*MACCommand_DeviceModeInd_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetDeviceModeInd()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "device_mode_ind",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "device_mode_conf":
+ w, ok := m.Payload.(*MACCommand_DeviceModeConf_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetDeviceModeConf()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "device_mode_conf",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "relay_conf_req":
+ w, ok := m.Payload.(*MACCommand_RelayConfReq_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetRelayConfReq()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "relay_conf_req",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "relay_conf_ans":
+ w, ok := m.Payload.(*MACCommand_RelayConfAns_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetRelayConfAns()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "relay_conf_ans",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "relay_end_device_conf_req":
+ w, ok := m.Payload.(*MACCommand_RelayEndDeviceConfReq_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetRelayEndDeviceConfReq()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "relay_end_device_conf_req",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "relay_end_device_conf_ans":
+ w, ok := m.Payload.(*MACCommand_RelayEndDeviceConfAns_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetRelayEndDeviceConfAns()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "relay_end_device_conf_ans",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "relay_update_uplink_list_req":
+ w, ok := m.Payload.(*MACCommand_RelayUpdateUplinkListReq_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetRelayUpdateUplinkListReq()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "relay_update_uplink_list_req",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "relay_update_uplink_list_ans":
+ w, ok := m.Payload.(*MACCommand_RelayUpdateUplinkListAns_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetRelayUpdateUplinkListAns()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "relay_update_uplink_list_ans",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "relay_ctrl_uplink_list_req":
+ w, ok := m.Payload.(*MACCommand_RelayCtrlUplinkListReq_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetRelayCtrlUplinkListReq()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "relay_ctrl_uplink_list_req",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "relay_ctrl_uplink_list_ans":
+ w, ok := m.Payload.(*MACCommand_RelayCtrlUplinkListAns_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetRelayCtrlUplinkListAns()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "relay_ctrl_uplink_list_ans",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "relay_configure_fwd_limit_req":
+ w, ok := m.Payload.(*MACCommand_RelayConfigureFwdLimitReq_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetRelayConfigureFwdLimitReq()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "relay_configure_fwd_limit_req",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "relay_configure_fwd_limit_ans":
+ w, ok := m.Payload.(*MACCommand_RelayConfigureFwdLimitAns_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetRelayConfigureFwdLimitAns()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "relay_configure_fwd_limit_ans",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "relay_notify_new_end_device_req":
+ w, ok := m.Payload.(*MACCommand_RelayNotifyNewEndDeviceReq_)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetRelayNotifyNewEndDeviceReq()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandValidationError{
+ field: "relay_notify_new_end_device_req",
+ reason: "embedded message failed validation",
cause: err,
}
}
}
- case "dl_channel_req":
- w, ok := m.Payload.(*MACCommand_DlChannelReq)
- if !ok || w == nil {
- continue
- }
+ }
+ }
+ default:
+ return MACCommandValidationError{
+ field: name,
+ reason: "invalid field path",
+ }
+ }
+ }
+ return nil
+}
+
+// MACCommandValidationError is the validation error returned by
+// MACCommand.ValidateFields if the designated constraints aren't met.
+type MACCommandValidationError struct {
+ field string
+ reason string
+ cause error
+ key bool
+}
+
+// Field function returns field value.
+func (e MACCommandValidationError) Field() string { return e.field }
+
+// Reason function returns reason value.
+func (e MACCommandValidationError) Reason() string { return e.reason }
+
+// Cause function returns cause value.
+func (e MACCommandValidationError) Cause() error { return e.cause }
+
+// Key function returns key value.
+func (e MACCommandValidationError) Key() bool { return e.key }
+
+// ErrorName returns error name.
+func (e MACCommandValidationError) ErrorName() string { return "MACCommandValidationError" }
+
+// Error satisfies the builtin error interface
+func (e MACCommandValidationError) Error() string {
+ cause := ""
+ if e.cause != nil {
+ cause = fmt.Sprintf(" | caused by: %v", e.cause)
+ }
+
+ key := ""
+ if e.key {
+ key = "key for "
+ }
+
+ return fmt.Sprintf(
+ "invalid %sMACCommand.%s: %s%s",
+ key,
+ e.field,
+ e.reason,
+ cause)
+}
+
+var _ error = MACCommandValidationError{}
+
+var _ interface {
+ Field() string
+ Reason() string
+ Key() bool
+ Cause() error
+ ErrorName() string
+} = MACCommandValidationError{}
+
+var _MACCommand_Cid_NotInLookup = map[MACCommandIdentifier]struct{}{
+ 0: {},
+}
+
+// ValidateFields checks the field values on MACCommands with the rules defined
+// in the proto definition for this message. If any rules are violated, an
+// error is returned.
+func (m *MACCommands) ValidateFields(paths ...string) error {
+ if m == nil {
+ return nil
+ }
+
+ if len(paths) == 0 {
+ paths = MACCommandsFieldPathsNested
+ }
+
+ for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
+ _ = subs
+ switch name {
+ case "commands":
+
+ for idx, item := range m.GetCommands() {
+ _, _ = idx, item
+
+ if v, ok := interface{}(item).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommandsValidationError{
+ field: fmt.Sprintf("commands[%v]", idx),
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ }
+
+ default:
+ return MACCommandsValidationError{
+ field: name,
+ reason: "invalid field path",
+ }
+ }
+ }
+ return nil
+}
+
+// MACCommandsValidationError is the validation error returned by
+// MACCommands.ValidateFields if the designated constraints aren't met.
+type MACCommandsValidationError struct {
+ field string
+ reason string
+ cause error
+ key bool
+}
+
+// Field function returns field value.
+func (e MACCommandsValidationError) Field() string { return e.field }
+
+// Reason function returns reason value.
+func (e MACCommandsValidationError) Reason() string { return e.reason }
+
+// Cause function returns cause value.
+func (e MACCommandsValidationError) Cause() error { return e.cause }
+
+// Key function returns key value.
+func (e MACCommandsValidationError) Key() bool { return e.key }
+
+// ErrorName returns error name.
+func (e MACCommandsValidationError) ErrorName() string { return "MACCommandsValidationError" }
+
+// Error satisfies the builtin error interface
+func (e MACCommandsValidationError) Error() string {
+ cause := ""
+ if e.cause != nil {
+ cause = fmt.Sprintf(" | caused by: %v", e.cause)
+ }
+
+ key := ""
+ if e.key {
+ key = "key for "
+ }
+
+ return fmt.Sprintf(
+ "invalid %sMACCommands.%s: %s%s",
+ key,
+ e.field,
+ e.reason,
+ cause)
+}
+
+var _ error = MACCommandsValidationError{}
+
+var _ interface {
+ Field() string
+ Reason() string
+ Key() bool
+ Cause() error
+ ErrorName() string
+} = MACCommandsValidationError{}
+
+// ValidateFields checks the field values on FrequencyValue with the rules
+// defined in the proto definition for this message. If any rules are
+// violated, an error is returned.
+func (m *FrequencyValue) ValidateFields(paths ...string) error {
+ if m == nil {
+ return nil
+ }
+
+ if len(paths) == 0 {
+ paths = FrequencyValueFieldPathsNested
+ }
+
+ for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
+ _ = subs
+ switch name {
+ case "value":
+
+ if m.GetValue() < 100000 {
+ return FrequencyValueValidationError{
+ field: "value",
+ reason: "value must be greater than or equal to 100000",
+ }
+ }
+
+ default:
+ return FrequencyValueValidationError{
+ field: name,
+ reason: "invalid field path",
+ }
+ }
+ }
+ return nil
+}
+
+// FrequencyValueValidationError is the validation error returned by
+// FrequencyValue.ValidateFields if the designated constraints aren't met.
+type FrequencyValueValidationError struct {
+ field string
+ reason string
+ cause error
+ key bool
+}
+
+// Field function returns field value.
+func (e FrequencyValueValidationError) Field() string { return e.field }
+
+// Reason function returns reason value.
+func (e FrequencyValueValidationError) Reason() string { return e.reason }
+
+// Cause function returns cause value.
+func (e FrequencyValueValidationError) Cause() error { return e.cause }
+
+// Key function returns key value.
+func (e FrequencyValueValidationError) Key() bool { return e.key }
+
+// ErrorName returns error name.
+func (e FrequencyValueValidationError) ErrorName() string { return "FrequencyValueValidationError" }
+
+// Error satisfies the builtin error interface
+func (e FrequencyValueValidationError) Error() string {
+ cause := ""
+ if e.cause != nil {
+ cause = fmt.Sprintf(" | caused by: %v", e.cause)
+ }
+
+ key := ""
+ if e.key {
+ key = "key for "
+ }
+
+ return fmt.Sprintf(
+ "invalid %sFrequencyValue.%s: %s%s",
+ key,
+ e.field,
+ e.reason,
+ cause)
+}
+
+var _ error = FrequencyValueValidationError{}
+
+var _ interface {
+ Field() string
+ Reason() string
+ Key() bool
+ Cause() error
+ ErrorName() string
+} = FrequencyValueValidationError{}
+
+// ValidateFields checks the field values on ZeroableFrequencyValue with the
+// rules defined in the proto definition for this message. If any rules are
+// violated, an error is returned.
+func (m *ZeroableFrequencyValue) ValidateFields(paths ...string) error {
+ if m == nil {
+ return nil
+ }
+
+ if len(paths) == 0 {
+ paths = ZeroableFrequencyValueFieldPathsNested
+ }
+
+ for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
+ _ = subs
+ switch name {
+ case "value":
+
+ if val := m.GetValue(); val > 0 && val < 100000 {
+ return ZeroableFrequencyValueValidationError{
+ field: "value",
+ reason: "value must be outside range (0, 100000)",
+ }
+ }
+
+ default:
+ return ZeroableFrequencyValueValidationError{
+ field: name,
+ reason: "invalid field path",
+ }
+ }
+ }
+ return nil
+}
+
+// ZeroableFrequencyValueValidationError is the validation error returned by
+// ZeroableFrequencyValue.ValidateFields if the designated constraints aren't met.
+type ZeroableFrequencyValueValidationError struct {
+ field string
+ reason string
+ cause error
+ key bool
+}
+
+// Field function returns field value.
+func (e ZeroableFrequencyValueValidationError) Field() string { return e.field }
+
+// Reason function returns reason value.
+func (e ZeroableFrequencyValueValidationError) Reason() string { return e.reason }
+
+// Cause function returns cause value.
+func (e ZeroableFrequencyValueValidationError) Cause() error { return e.cause }
+
+// Key function returns key value.
+func (e ZeroableFrequencyValueValidationError) Key() bool { return e.key }
+
+// ErrorName returns error name.
+func (e ZeroableFrequencyValueValidationError) ErrorName() string {
+ return "ZeroableFrequencyValueValidationError"
+}
+
+// Error satisfies the builtin error interface
+func (e ZeroableFrequencyValueValidationError) Error() string {
+ cause := ""
+ if e.cause != nil {
+ cause = fmt.Sprintf(" | caused by: %v", e.cause)
+ }
+
+ key := ""
+ if e.key {
+ key = "key for "
+ }
+
+ return fmt.Sprintf(
+ "invalid %sZeroableFrequencyValue.%s: %s%s",
+ key,
+ e.field,
+ e.reason,
+ cause)
+}
+
+var _ error = ZeroableFrequencyValueValidationError{}
+
+var _ interface {
+ Field() string
+ Reason() string
+ Key() bool
+ Cause() error
+ ErrorName() string
+} = ZeroableFrequencyValueValidationError{}
+
+// ValidateFields checks the field values on DataRateOffsetValue with the rules
+// defined in the proto definition for this message. If any rules are
+// violated, an error is returned.
+func (m *DataRateOffsetValue) ValidateFields(paths ...string) error {
+ if m == nil {
+ return nil
+ }
+
+ if len(paths) == 0 {
+ paths = DataRateOffsetValueFieldPathsNested
+ }
+
+ for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
+ _ = subs
+ switch name {
+ case "value":
+
+ if _, ok := DataRateOffset_name[int32(m.GetValue())]; !ok {
+ return DataRateOffsetValueValidationError{
+ field: "value",
+ reason: "value must be one of the defined enum values",
+ }
+ }
+
+ default:
+ return DataRateOffsetValueValidationError{
+ field: name,
+ reason: "invalid field path",
+ }
+ }
+ }
+ return nil
+}
+
+// DataRateOffsetValueValidationError is the validation error returned by
+// DataRateOffsetValue.ValidateFields if the designated constraints aren't met.
+type DataRateOffsetValueValidationError struct {
+ field string
+ reason string
+ cause error
+ key bool
+}
+
+// Field function returns field value.
+func (e DataRateOffsetValueValidationError) Field() string { return e.field }
+
+// Reason function returns reason value.
+func (e DataRateOffsetValueValidationError) Reason() string { return e.reason }
+
+// Cause function returns cause value.
+func (e DataRateOffsetValueValidationError) Cause() error { return e.cause }
+
+// Key function returns key value.
+func (e DataRateOffsetValueValidationError) Key() bool { return e.key }
+
+// ErrorName returns error name.
+func (e DataRateOffsetValueValidationError) ErrorName() string {
+ return "DataRateOffsetValueValidationError"
+}
+
+// Error satisfies the builtin error interface
+func (e DataRateOffsetValueValidationError) Error() string {
+ cause := ""
+ if e.cause != nil {
+ cause = fmt.Sprintf(" | caused by: %v", e.cause)
+ }
+
+ key := ""
+ if e.key {
+ key = "key for "
+ }
+
+ return fmt.Sprintf(
+ "invalid %sDataRateOffsetValue.%s: %s%s",
+ key,
+ e.field,
+ e.reason,
+ cause)
+}
+
+var _ error = DataRateOffsetValueValidationError{}
+
+var _ interface {
+ Field() string
+ Reason() string
+ Key() bool
+ Cause() error
+ ErrorName() string
+} = DataRateOffsetValueValidationError{}
+
+// ValidateFields checks the field values on DataRateIndexValue with the rules
+// defined in the proto definition for this message. If any rules are
+// violated, an error is returned.
+func (m *DataRateIndexValue) ValidateFields(paths ...string) error {
+ if m == nil {
+ return nil
+ }
+
+ if len(paths) == 0 {
+ paths = DataRateIndexValueFieldPathsNested
+ }
+
+ for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
+ _ = subs
+ switch name {
+ case "value":
+
+ if _, ok := DataRateIndex_name[int32(m.GetValue())]; !ok {
+ return DataRateIndexValueValidationError{
+ field: "value",
+ reason: "value must be one of the defined enum values",
+ }
+ }
+
+ default:
+ return DataRateIndexValueValidationError{
+ field: name,
+ reason: "invalid field path",
+ }
+ }
+ }
+ return nil
+}
+
+// DataRateIndexValueValidationError is the validation error returned by
+// DataRateIndexValue.ValidateFields if the designated constraints aren't met.
+type DataRateIndexValueValidationError struct {
+ field string
+ reason string
+ cause error
+ key bool
+}
+
+// Field function returns field value.
+func (e DataRateIndexValueValidationError) Field() string { return e.field }
+
+// Reason function returns reason value.
+func (e DataRateIndexValueValidationError) Reason() string { return e.reason }
+
+// Cause function returns cause value.
+func (e DataRateIndexValueValidationError) Cause() error { return e.cause }
+
+// Key function returns key value.
+func (e DataRateIndexValueValidationError) Key() bool { return e.key }
+
+// ErrorName returns error name.
+func (e DataRateIndexValueValidationError) ErrorName() string {
+ return "DataRateIndexValueValidationError"
+}
+
+// Error satisfies the builtin error interface
+func (e DataRateIndexValueValidationError) Error() string {
+ cause := ""
+ if e.cause != nil {
+ cause = fmt.Sprintf(" | caused by: %v", e.cause)
+ }
+
+ key := ""
+ if e.key {
+ key = "key for "
+ }
+
+ return fmt.Sprintf(
+ "invalid %sDataRateIndexValue.%s: %s%s",
+ key,
+ e.field,
+ e.reason,
+ cause)
+}
+
+var _ error = DataRateIndexValueValidationError{}
+
+var _ interface {
+ Field() string
+ Reason() string
+ Key() bool
+ Cause() error
+ ErrorName() string
+} = DataRateIndexValueValidationError{}
+
+// ValidateFields checks the field values on PingSlotPeriodValue with the rules
+// defined in the proto definition for this message. If any rules are
+// violated, an error is returned.
+func (m *PingSlotPeriodValue) ValidateFields(paths ...string) error {
+ if m == nil {
+ return nil
+ }
+
+ if len(paths) == 0 {
+ paths = PingSlotPeriodValueFieldPathsNested
+ }
+
+ for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
+ _ = subs
+ switch name {
+ case "value":
+
+ if _, ok := PingSlotPeriod_name[int32(m.GetValue())]; !ok {
+ return PingSlotPeriodValueValidationError{
+ field: "value",
+ reason: "value must be one of the defined enum values",
+ }
+ }
+
+ default:
+ return PingSlotPeriodValueValidationError{
+ field: name,
+ reason: "invalid field path",
+ }
+ }
+ }
+ return nil
+}
+
+// PingSlotPeriodValueValidationError is the validation error returned by
+// PingSlotPeriodValue.ValidateFields if the designated constraints aren't met.
+type PingSlotPeriodValueValidationError struct {
+ field string
+ reason string
+ cause error
+ key bool
+}
+
+// Field function returns field value.
+func (e PingSlotPeriodValueValidationError) Field() string { return e.field }
+
+// Reason function returns reason value.
+func (e PingSlotPeriodValueValidationError) Reason() string { return e.reason }
+
+// Cause function returns cause value.
+func (e PingSlotPeriodValueValidationError) Cause() error { return e.cause }
+
+// Key function returns key value.
+func (e PingSlotPeriodValueValidationError) Key() bool { return e.key }
+
+// ErrorName returns error name.
+func (e PingSlotPeriodValueValidationError) ErrorName() string {
+ return "PingSlotPeriodValueValidationError"
+}
+
+// Error satisfies the builtin error interface
+func (e PingSlotPeriodValueValidationError) Error() string {
+ cause := ""
+ if e.cause != nil {
+ cause = fmt.Sprintf(" | caused by: %v", e.cause)
+ }
+
+ key := ""
+ if e.key {
+ key = "key for "
+ }
+
+ return fmt.Sprintf(
+ "invalid %sPingSlotPeriodValue.%s: %s%s",
+ key,
+ e.field,
+ e.reason,
+ cause)
+}
+
+var _ error = PingSlotPeriodValueValidationError{}
+
+var _ interface {
+ Field() string
+ Reason() string
+ Key() bool
+ Cause() error
+ ErrorName() string
+} = PingSlotPeriodValueValidationError{}
+
+// ValidateFields checks the field values on AggregatedDutyCycleValue with the
+// rules defined in the proto definition for this message. If any rules are
+// violated, an error is returned.
+func (m *AggregatedDutyCycleValue) ValidateFields(paths ...string) error {
+ if m == nil {
+ return nil
+ }
+
+ if len(paths) == 0 {
+ paths = AggregatedDutyCycleValueFieldPathsNested
+ }
+
+ for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
+ _ = subs
+ switch name {
+ case "value":
+
+ if _, ok := AggregatedDutyCycle_name[int32(m.GetValue())]; !ok {
+ return AggregatedDutyCycleValueValidationError{
+ field: "value",
+ reason: "value must be one of the defined enum values",
+ }
+ }
+
+ default:
+ return AggregatedDutyCycleValueValidationError{
+ field: name,
+ reason: "invalid field path",
+ }
+ }
+ }
+ return nil
+}
+
+// AggregatedDutyCycleValueValidationError is the validation error returned by
+// AggregatedDutyCycleValue.ValidateFields if the designated constraints
+// aren't met.
+type AggregatedDutyCycleValueValidationError struct {
+ field string
+ reason string
+ cause error
+ key bool
+}
+
+// Field function returns field value.
+func (e AggregatedDutyCycleValueValidationError) Field() string { return e.field }
+
+// Reason function returns reason value.
+func (e AggregatedDutyCycleValueValidationError) Reason() string { return e.reason }
+
+// Cause function returns cause value.
+func (e AggregatedDutyCycleValueValidationError) Cause() error { return e.cause }
+
+// Key function returns key value.
+func (e AggregatedDutyCycleValueValidationError) Key() bool { return e.key }
+
+// ErrorName returns error name.
+func (e AggregatedDutyCycleValueValidationError) ErrorName() string {
+ return "AggregatedDutyCycleValueValidationError"
+}
+
+// Error satisfies the builtin error interface
+func (e AggregatedDutyCycleValueValidationError) Error() string {
+ cause := ""
+ if e.cause != nil {
+ cause = fmt.Sprintf(" | caused by: %v", e.cause)
+ }
+
+ key := ""
+ if e.key {
+ key = "key for "
+ }
+
+ return fmt.Sprintf(
+ "invalid %sAggregatedDutyCycleValue.%s: %s%s",
+ key,
+ e.field,
+ e.reason,
+ cause)
+}
+
+var _ error = AggregatedDutyCycleValueValidationError{}
+
+var _ interface {
+ Field() string
+ Reason() string
+ Key() bool
+ Cause() error
+ ErrorName() string
+} = AggregatedDutyCycleValueValidationError{}
+
+// ValidateFields checks the field values on RxDelayValue with the rules
+// defined in the proto definition for this message. If any rules are
+// violated, an error is returned.
+func (m *RxDelayValue) ValidateFields(paths ...string) error {
+ if m == nil {
+ return nil
+ }
+
+ if len(paths) == 0 {
+ paths = RxDelayValueFieldPathsNested
+ }
+
+ for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
+ _ = subs
+ switch name {
+ case "value":
+
+ if _, ok := RxDelay_name[int32(m.GetValue())]; !ok {
+ return RxDelayValueValidationError{
+ field: "value",
+ reason: "value must be one of the defined enum values",
+ }
+ }
+
+ default:
+ return RxDelayValueValidationError{
+ field: name,
+ reason: "invalid field path",
+ }
+ }
+ }
+ return nil
+}
+
+// RxDelayValueValidationError is the validation error returned by
+// RxDelayValue.ValidateFields if the designated constraints aren't met.
+type RxDelayValueValidationError struct {
+ field string
+ reason string
+ cause error
+ key bool
+}
+
+// Field function returns field value.
+func (e RxDelayValueValidationError) Field() string { return e.field }
+
+// Reason function returns reason value.
+func (e RxDelayValueValidationError) Reason() string { return e.reason }
+
+// Cause function returns cause value.
+func (e RxDelayValueValidationError) Cause() error { return e.cause }
+
+// Key function returns key value.
+func (e RxDelayValueValidationError) Key() bool { return e.key }
+
+// ErrorName returns error name.
+func (e RxDelayValueValidationError) ErrorName() string { return "RxDelayValueValidationError" }
+
+// Error satisfies the builtin error interface
+func (e RxDelayValueValidationError) Error() string {
+ cause := ""
+ if e.cause != nil {
+ cause = fmt.Sprintf(" | caused by: %v", e.cause)
+ }
+
+ key := ""
+ if e.key {
+ key = "key for "
+ }
+
+ return fmt.Sprintf(
+ "invalid %sRxDelayValue.%s: %s%s",
+ key,
+ e.field,
+ e.reason,
+ cause)
+}
+
+var _ error = RxDelayValueValidationError{}
+
+var _ interface {
+ Field() string
+ Reason() string
+ Key() bool
+ Cause() error
+ ErrorName() string
+} = RxDelayValueValidationError{}
+
+// ValidateFields checks the field values on ADRAckLimitExponentValue with the
+// rules defined in the proto definition for this message. If any rules are
+// violated, an error is returned.
+func (m *ADRAckLimitExponentValue) ValidateFields(paths ...string) error {
+ if m == nil {
+ return nil
+ }
+
+ if len(paths) == 0 {
+ paths = ADRAckLimitExponentValueFieldPathsNested
+ }
+
+ for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
+ _ = subs
+ switch name {
+ case "value":
+
+ if _, ok := ADRAckLimitExponent_name[int32(m.GetValue())]; !ok {
+ return ADRAckLimitExponentValueValidationError{
+ field: "value",
+ reason: "value must be one of the defined enum values",
+ }
+ }
+
+ default:
+ return ADRAckLimitExponentValueValidationError{
+ field: name,
+ reason: "invalid field path",
+ }
+ }
+ }
+ return nil
+}
+
+// ADRAckLimitExponentValueValidationError is the validation error returned by
+// ADRAckLimitExponentValue.ValidateFields if the designated constraints
+// aren't met.
+type ADRAckLimitExponentValueValidationError struct {
+ field string
+ reason string
+ cause error
+ key bool
+}
+
+// Field function returns field value.
+func (e ADRAckLimitExponentValueValidationError) Field() string { return e.field }
+
+// Reason function returns reason value.
+func (e ADRAckLimitExponentValueValidationError) Reason() string { return e.reason }
+
+// Cause function returns cause value.
+func (e ADRAckLimitExponentValueValidationError) Cause() error { return e.cause }
+
+// Key function returns key value.
+func (e ADRAckLimitExponentValueValidationError) Key() bool { return e.key }
+
+// ErrorName returns error name.
+func (e ADRAckLimitExponentValueValidationError) ErrorName() string {
+ return "ADRAckLimitExponentValueValidationError"
+}
+
+// Error satisfies the builtin error interface
+func (e ADRAckLimitExponentValueValidationError) Error() string {
+ cause := ""
+ if e.cause != nil {
+ cause = fmt.Sprintf(" | caused by: %v", e.cause)
+ }
+
+ key := ""
+ if e.key {
+ key = "key for "
+ }
+
+ return fmt.Sprintf(
+ "invalid %sADRAckLimitExponentValue.%s: %s%s",
+ key,
+ e.field,
+ e.reason,
+ cause)
+}
+
+var _ error = ADRAckLimitExponentValueValidationError{}
+
+var _ interface {
+ Field() string
+ Reason() string
+ Key() bool
+ Cause() error
+ ErrorName() string
+} = ADRAckLimitExponentValueValidationError{}
+
+// ValidateFields checks the field values on ADRAckDelayExponentValue with the
+// rules defined in the proto definition for this message. If any rules are
+// violated, an error is returned.
+func (m *ADRAckDelayExponentValue) ValidateFields(paths ...string) error {
+ if m == nil {
+ return nil
+ }
+
+ if len(paths) == 0 {
+ paths = ADRAckDelayExponentValueFieldPathsNested
+ }
+
+ for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
+ _ = subs
+ switch name {
+ case "value":
+
+ if _, ok := ADRAckDelayExponent_name[int32(m.GetValue())]; !ok {
+ return ADRAckDelayExponentValueValidationError{
+ field: "value",
+ reason: "value must be one of the defined enum values",
+ }
+ }
+
+ default:
+ return ADRAckDelayExponentValueValidationError{
+ field: name,
+ reason: "invalid field path",
+ }
+ }
+ }
+ return nil
+}
+
+// ADRAckDelayExponentValueValidationError is the validation error returned by
+// ADRAckDelayExponentValue.ValidateFields if the designated constraints
+// aren't met.
+type ADRAckDelayExponentValueValidationError struct {
+ field string
+ reason string
+ cause error
+ key bool
+}
+
+// Field function returns field value.
+func (e ADRAckDelayExponentValueValidationError) Field() string { return e.field }
+
+// Reason function returns reason value.
+func (e ADRAckDelayExponentValueValidationError) Reason() string { return e.reason }
+
+// Cause function returns cause value.
+func (e ADRAckDelayExponentValueValidationError) Cause() error { return e.cause }
+
+// Key function returns key value.
+func (e ADRAckDelayExponentValueValidationError) Key() bool { return e.key }
+
+// ErrorName returns error name.
+func (e ADRAckDelayExponentValueValidationError) ErrorName() string {
+ return "ADRAckDelayExponentValueValidationError"
+}
+
+// Error satisfies the builtin error interface
+func (e ADRAckDelayExponentValueValidationError) Error() string {
+ cause := ""
+ if e.cause != nil {
+ cause = fmt.Sprintf(" | caused by: %v", e.cause)
+ }
+
+ key := ""
+ if e.key {
+ key = "key for "
+ }
+
+ return fmt.Sprintf(
+ "invalid %sADRAckDelayExponentValue.%s: %s%s",
+ key,
+ e.field,
+ e.reason,
+ cause)
+}
+
+var _ error = ADRAckDelayExponentValueValidationError{}
+
+var _ interface {
+ Field() string
+ Reason() string
+ Key() bool
+ Cause() error
+ ErrorName() string
+} = ADRAckDelayExponentValueValidationError{}
+
+// ValidateFields checks the field values on DeviceEIRPValue with the rules
+// defined in the proto definition for this message. If any rules are
+// violated, an error is returned.
+func (m *DeviceEIRPValue) ValidateFields(paths ...string) error {
+ if m == nil {
+ return nil
+ }
+
+ if len(paths) == 0 {
+ paths = DeviceEIRPValueFieldPathsNested
+ }
+
+ for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
+ _ = subs
+ switch name {
+ case "value":
+
+ if _, ok := DeviceEIRP_name[int32(m.GetValue())]; !ok {
+ return DeviceEIRPValueValidationError{
+ field: "value",
+ reason: "value must be one of the defined enum values",
+ }
+ }
+
+ default:
+ return DeviceEIRPValueValidationError{
+ field: name,
+ reason: "invalid field path",
+ }
+ }
+ }
+ return nil
+}
+
+// DeviceEIRPValueValidationError is the validation error returned by
+// DeviceEIRPValue.ValidateFields if the designated constraints aren't met.
+type DeviceEIRPValueValidationError struct {
+ field string
+ reason string
+ cause error
+ key bool
+}
+
+// Field function returns field value.
+func (e DeviceEIRPValueValidationError) Field() string { return e.field }
+
+// Reason function returns reason value.
+func (e DeviceEIRPValueValidationError) Reason() string { return e.reason }
+
+// Cause function returns cause value.
+func (e DeviceEIRPValueValidationError) Cause() error { return e.cause }
+
+// Key function returns key value.
+func (e DeviceEIRPValueValidationError) Key() bool { return e.key }
+
+// ErrorName returns error name.
+func (e DeviceEIRPValueValidationError) ErrorName() string { return "DeviceEIRPValueValidationError" }
+
+// Error satisfies the builtin error interface
+func (e DeviceEIRPValueValidationError) Error() string {
+ cause := ""
+ if e.cause != nil {
+ cause = fmt.Sprintf(" | caused by: %v", e.cause)
+ }
+
+ key := ""
+ if e.key {
+ key = "key for "
+ }
+
+ return fmt.Sprintf(
+ "invalid %sDeviceEIRPValue.%s: %s%s",
+ key,
+ e.field,
+ e.reason,
+ cause)
+}
+
+var _ error = DeviceEIRPValueValidationError{}
+
+var _ interface {
+ Field() string
+ Reason() string
+ Key() bool
+ Cause() error
+ ErrorName() string
+} = DeviceEIRPValueValidationError{}
+
+// ValidateFields checks the field values on RelayForwardUplinkReq with the
+// rules defined in the proto definition for this message. If any rules are
+// violated, an error is returned.
+func (m *RelayForwardUplinkReq) ValidateFields(paths ...string) error {
+ if m == nil {
+ return nil
+ }
+
+ if len(paths) == 0 {
+ paths = RelayForwardUplinkReqFieldPathsNested
+ }
+
+ for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
+ _ = subs
+ switch name {
+ case "data_rate":
+
+ if m.GetDataRate() == nil {
+ return RelayForwardUplinkReqValidationError{
+ field: "data_rate",
+ reason: "value is required",
+ }
+ }
+
+ if v, ok := interface{}(m.GetDataRate()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return RelayForwardUplinkReqValidationError{
+ field: "data_rate",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "snr":
+
+ if val := m.GetSnr(); val < -20 || val > 11 {
+ return RelayForwardUplinkReqValidationError{
+ field: "snr",
+ reason: "value must be inside range [-20, 11]",
+ }
+ }
+
+ case "rssi":
+
+ if val := m.GetRssi(); val < -142 || val > -15 {
+ return RelayForwardUplinkReqValidationError{
+ field: "rssi",
+ reason: "value must be inside range [-142, -15]",
+ }
+ }
+
+ case "wor_channel":
+
+ if _, ok := RelayWORChannel_name[int32(m.GetWorChannel())]; !ok {
+ return RelayForwardUplinkReqValidationError{
+ field: "wor_channel",
+ reason: "value must be one of the defined enum values",
+ }
+ }
+
+ case "frequency":
+
+ if m.GetFrequency() < 100000 {
+ return RelayForwardUplinkReqValidationError{
+ field: "frequency",
+ reason: "value must be greater than or equal to 100000",
+ }
+ }
+
+ case "raw_payload":
+ // no validation rules for RawPayload
+ default:
+ return RelayForwardUplinkReqValidationError{
+ field: name,
+ reason: "invalid field path",
+ }
+ }
+ }
+ return nil
+}
+
+// RelayForwardUplinkReqValidationError is the validation error returned by
+// RelayForwardUplinkReq.ValidateFields if the designated constraints aren't met.
+type RelayForwardUplinkReqValidationError struct {
+ field string
+ reason string
+ cause error
+ key bool
+}
- if v, ok := interface{}(m.GetDlChannelReq()).(interface{ ValidateFields(...string) error }); ok {
- if err := v.ValidateFields(subs...); err != nil {
- return MACCommandValidationError{
- field: "dl_channel_req",
- reason: "embedded message failed validation",
- cause: err,
- }
- }
- }
+// Field function returns field value.
+func (e RelayForwardUplinkReqValidationError) Field() string { return e.field }
- case "dl_channel_ans":
- w, ok := m.Payload.(*MACCommand_DlChannelAns)
- if !ok || w == nil {
- continue
- }
+// Reason function returns reason value.
+func (e RelayForwardUplinkReqValidationError) Reason() string { return e.reason }
- if v, ok := interface{}(m.GetDlChannelAns()).(interface{ ValidateFields(...string) error }); ok {
- if err := v.ValidateFields(subs...); err != nil {
- return MACCommandValidationError{
- field: "dl_channel_ans",
- reason: "embedded message failed validation",
- cause: err,
- }
- }
- }
+// Cause function returns cause value.
+func (e RelayForwardUplinkReqValidationError) Cause() error { return e.cause }
- case "rx_timing_setup_req":
- w, ok := m.Payload.(*MACCommand_RxTimingSetupReq_)
- if !ok || w == nil {
- continue
- }
+// Key function returns key value.
+func (e RelayForwardUplinkReqValidationError) Key() bool { return e.key }
- if v, ok := interface{}(m.GetRxTimingSetupReq()).(interface{ ValidateFields(...string) error }); ok {
- if err := v.ValidateFields(subs...); err != nil {
- return MACCommandValidationError{
- field: "rx_timing_setup_req",
- reason: "embedded message failed validation",
- cause: err,
- }
- }
- }
+// ErrorName returns error name.
+func (e RelayForwardUplinkReqValidationError) ErrorName() string {
+ return "RelayForwardUplinkReqValidationError"
+}
- case "tx_param_setup_req":
- w, ok := m.Payload.(*MACCommand_TxParamSetupReq_)
- if !ok || w == nil {
- continue
- }
+// Error satisfies the builtin error interface
+func (e RelayForwardUplinkReqValidationError) Error() string {
+ cause := ""
+ if e.cause != nil {
+ cause = fmt.Sprintf(" | caused by: %v", e.cause)
+ }
- if v, ok := interface{}(m.GetTxParamSetupReq()).(interface{ ValidateFields(...string) error }); ok {
- if err := v.ValidateFields(subs...); err != nil {
- return MACCommandValidationError{
- field: "tx_param_setup_req",
- reason: "embedded message failed validation",
- cause: err,
- }
- }
- }
+ key := ""
+ if e.key {
+ key = "key for "
+ }
- case "rekey_ind":
- w, ok := m.Payload.(*MACCommand_RekeyInd_)
- if !ok || w == nil {
- continue
- }
+ return fmt.Sprintf(
+ "invalid %sRelayForwardUplinkReq.%s: %s%s",
+ key,
+ e.field,
+ e.reason,
+ cause)
+}
- if v, ok := interface{}(m.GetRekeyInd()).(interface{ ValidateFields(...string) error }); ok {
- if err := v.ValidateFields(subs...); err != nil {
- return MACCommandValidationError{
- field: "rekey_ind",
- reason: "embedded message failed validation",
- cause: err,
- }
- }
- }
+var _ error = RelayForwardUplinkReqValidationError{}
- case "rekey_conf":
- w, ok := m.Payload.(*MACCommand_RekeyConf_)
- if !ok || w == nil {
- continue
- }
+var _ interface {
+ Field() string
+ Reason() string
+ Key() bool
+ Cause() error
+ ErrorName() string
+} = RelayForwardUplinkReqValidationError{}
- if v, ok := interface{}(m.GetRekeyConf()).(interface{ ValidateFields(...string) error }); ok {
- if err := v.ValidateFields(subs...); err != nil {
- return MACCommandValidationError{
- field: "rekey_conf",
- reason: "embedded message failed validation",
- cause: err,
- }
- }
- }
+// ValidateFields checks the field values on RelayForwardDownlinkReq with the
+// rules defined in the proto definition for this message. If any rules are
+// violated, an error is returned.
+func (m *RelayForwardDownlinkReq) ValidateFields(paths ...string) error {
+ if m == nil {
+ return nil
+ }
- case "adr_param_setup_req":
- w, ok := m.Payload.(*MACCommand_AdrParamSetupReq)
- if !ok || w == nil {
- continue
- }
+ if len(paths) == 0 {
+ paths = RelayForwardDownlinkReqFieldPathsNested
+ }
- if v, ok := interface{}(m.GetAdrParamSetupReq()).(interface{ ValidateFields(...string) error }); ok {
- if err := v.ValidateFields(subs...); err != nil {
- return MACCommandValidationError{
- field: "adr_param_setup_req",
- reason: "embedded message failed validation",
- cause: err,
- }
- }
- }
+ for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
+ _ = subs
+ switch name {
+ case "raw_payload":
+ // no validation rules for RawPayload
+ default:
+ return RelayForwardDownlinkReqValidationError{
+ field: name,
+ reason: "invalid field path",
+ }
+ }
+ }
+ return nil
+}
- case "device_time_ans":
- w, ok := m.Payload.(*MACCommand_DeviceTimeAns_)
- if !ok || w == nil {
- continue
- }
+// RelayForwardDownlinkReqValidationError is the validation error returned by
+// RelayForwardDownlinkReq.ValidateFields if the designated constraints aren't met.
+type RelayForwardDownlinkReqValidationError struct {
+ field string
+ reason string
+ cause error
+ key bool
+}
- if v, ok := interface{}(m.GetDeviceTimeAns()).(interface{ ValidateFields(...string) error }); ok {
- if err := v.ValidateFields(subs...); err != nil {
- return MACCommandValidationError{
- field: "device_time_ans",
- reason: "embedded message failed validation",
- cause: err,
- }
- }
- }
+// Field function returns field value.
+func (e RelayForwardDownlinkReqValidationError) Field() string { return e.field }
- case "force_rejoin_req":
- w, ok := m.Payload.(*MACCommand_ForceRejoinReq_)
- if !ok || w == nil {
- continue
- }
+// Reason function returns reason value.
+func (e RelayForwardDownlinkReqValidationError) Reason() string { return e.reason }
- if v, ok := interface{}(m.GetForceRejoinReq()).(interface{ ValidateFields(...string) error }); ok {
- if err := v.ValidateFields(subs...); err != nil {
- return MACCommandValidationError{
- field: "force_rejoin_req",
- reason: "embedded message failed validation",
- cause: err,
- }
- }
- }
+// Cause function returns cause value.
+func (e RelayForwardDownlinkReqValidationError) Cause() error { return e.cause }
- case "rejoin_param_setup_req":
- w, ok := m.Payload.(*MACCommand_RejoinParamSetupReq_)
- if !ok || w == nil {
- continue
- }
+// Key function returns key value.
+func (e RelayForwardDownlinkReqValidationError) Key() bool { return e.key }
- if v, ok := interface{}(m.GetRejoinParamSetupReq()).(interface{ ValidateFields(...string) error }); ok {
- if err := v.ValidateFields(subs...); err != nil {
- return MACCommandValidationError{
- field: "rejoin_param_setup_req",
- reason: "embedded message failed validation",
- cause: err,
- }
- }
- }
+// ErrorName returns error name.
+func (e RelayForwardDownlinkReqValidationError) ErrorName() string {
+ return "RelayForwardDownlinkReqValidationError"
+}
- case "rejoin_param_setup_ans":
- w, ok := m.Payload.(*MACCommand_RejoinParamSetupAns_)
- if !ok || w == nil {
- continue
- }
+// Error satisfies the builtin error interface
+func (e RelayForwardDownlinkReqValidationError) Error() string {
+ cause := ""
+ if e.cause != nil {
+ cause = fmt.Sprintf(" | caused by: %v", e.cause)
+ }
- if v, ok := interface{}(m.GetRejoinParamSetupAns()).(interface{ ValidateFields(...string) error }); ok {
- if err := v.ValidateFields(subs...); err != nil {
- return MACCommandValidationError{
- field: "rejoin_param_setup_ans",
- reason: "embedded message failed validation",
- cause: err,
- }
- }
- }
+ key := ""
+ if e.key {
+ key = "key for "
+ }
- case "ping_slot_info_req":
- w, ok := m.Payload.(*MACCommand_PingSlotInfoReq_)
- if !ok || w == nil {
- continue
- }
+ return fmt.Sprintf(
+ "invalid %sRelayForwardDownlinkReq.%s: %s%s",
+ key,
+ e.field,
+ e.reason,
+ cause)
+}
+
+var _ error = RelayForwardDownlinkReqValidationError{}
+
+var _ interface {
+ Field() string
+ Reason() string
+ Key() bool
+ Cause() error
+ ErrorName() string
+} = RelayForwardDownlinkReqValidationError{}
+
+// ValidateFields checks the field values on RelayUplinkToken with the rules
+// defined in the proto definition for this message. If any rules are
+// violated, an error is returned.
+func (m *RelayUplinkToken) ValidateFields(paths ...string) error {
+ if m == nil {
+ return nil
+ }
+
+ if len(paths) == 0 {
+ paths = RelayUplinkTokenFieldPathsNested
+ }
+
+ for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
+ _ = subs
+ switch name {
+ case "ids":
- if v, ok := interface{}(m.GetPingSlotInfoReq()).(interface{ ValidateFields(...string) error }); ok {
- if err := v.ValidateFields(subs...); err != nil {
- return MACCommandValidationError{
- field: "ping_slot_info_req",
- reason: "embedded message failed validation",
- cause: err,
- }
- }
- }
+ if m.GetIds() == nil {
+ return RelayUplinkTokenValidationError{
+ field: "ids",
+ reason: "value is required",
+ }
+ }
- case "ping_slot_channel_req":
- w, ok := m.Payload.(*MACCommand_PingSlotChannelReq_)
- if !ok || w == nil {
- continue
+ if v, ok := interface{}(m.GetIds()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return RelayUplinkTokenValidationError{
+ field: "ids",
+ reason: "embedded message failed validation",
+ cause: err,
}
+ }
+ }
- if v, ok := interface{}(m.GetPingSlotChannelReq()).(interface{ ValidateFields(...string) error }); ok {
- if err := v.ValidateFields(subs...); err != nil {
- return MACCommandValidationError{
- field: "ping_slot_channel_req",
- reason: "embedded message failed validation",
- cause: err,
- }
- }
- }
+ case "session_key_id":
+ // no validation rules for SessionKeyId
+ case "full_f_cnt":
+ // no validation rules for FullFCnt
+ default:
+ return RelayUplinkTokenValidationError{
+ field: name,
+ reason: "invalid field path",
+ }
+ }
+ }
+ return nil
+}
- case "ping_slot_channel_ans":
- w, ok := m.Payload.(*MACCommand_PingSlotChannelAns_)
- if !ok || w == nil {
- continue
- }
+// RelayUplinkTokenValidationError is the validation error returned by
+// RelayUplinkToken.ValidateFields if the designated constraints aren't met.
+type RelayUplinkTokenValidationError struct {
+ field string
+ reason string
+ cause error
+ key bool
+}
- if v, ok := interface{}(m.GetPingSlotChannelAns()).(interface{ ValidateFields(...string) error }); ok {
- if err := v.ValidateFields(subs...); err != nil {
- return MACCommandValidationError{
- field: "ping_slot_channel_ans",
- reason: "embedded message failed validation",
- cause: err,
- }
- }
- }
+// Field function returns field value.
+func (e RelayUplinkTokenValidationError) Field() string { return e.field }
- case "beacon_timing_ans":
- w, ok := m.Payload.(*MACCommand_BeaconTimingAns_)
- if !ok || w == nil {
- continue
- }
+// Reason function returns reason value.
+func (e RelayUplinkTokenValidationError) Reason() string { return e.reason }
- if v, ok := interface{}(m.GetBeaconTimingAns()).(interface{ ValidateFields(...string) error }); ok {
- if err := v.ValidateFields(subs...); err != nil {
- return MACCommandValidationError{
- field: "beacon_timing_ans",
- reason: "embedded message failed validation",
- cause: err,
- }
- }
- }
+// Cause function returns cause value.
+func (e RelayUplinkTokenValidationError) Cause() error { return e.cause }
- case "beacon_freq_req":
- w, ok := m.Payload.(*MACCommand_BeaconFreqReq_)
- if !ok || w == nil {
- continue
- }
+// Key function returns key value.
+func (e RelayUplinkTokenValidationError) Key() bool { return e.key }
- if v, ok := interface{}(m.GetBeaconFreqReq()).(interface{ ValidateFields(...string) error }); ok {
- if err := v.ValidateFields(subs...); err != nil {
- return MACCommandValidationError{
- field: "beacon_freq_req",
- reason: "embedded message failed validation",
- cause: err,
- }
- }
- }
+// ErrorName returns error name.
+func (e RelayUplinkTokenValidationError) ErrorName() string { return "RelayUplinkTokenValidationError" }
- case "beacon_freq_ans":
- w, ok := m.Payload.(*MACCommand_BeaconFreqAns_)
- if !ok || w == nil {
- continue
- }
+// Error satisfies the builtin error interface
+func (e RelayUplinkTokenValidationError) Error() string {
+ cause := ""
+ if e.cause != nil {
+ cause = fmt.Sprintf(" | caused by: %v", e.cause)
+ }
- if v, ok := interface{}(m.GetBeaconFreqAns()).(interface{ ValidateFields(...string) error }); ok {
- if err := v.ValidateFields(subs...); err != nil {
- return MACCommandValidationError{
- field: "beacon_freq_ans",
- reason: "embedded message failed validation",
- cause: err,
- }
- }
- }
+ key := ""
+ if e.key {
+ key = "key for "
+ }
- case "device_mode_ind":
- w, ok := m.Payload.(*MACCommand_DeviceModeInd_)
- if !ok || w == nil {
- continue
- }
+ return fmt.Sprintf(
+ "invalid %sRelayUplinkToken.%s: %s%s",
+ key,
+ e.field,
+ e.reason,
+ cause)
+}
- if v, ok := interface{}(m.GetDeviceModeInd()).(interface{ ValidateFields(...string) error }); ok {
- if err := v.ValidateFields(subs...); err != nil {
- return MACCommandValidationError{
- field: "device_mode_ind",
- reason: "embedded message failed validation",
- cause: err,
- }
- }
- }
+var _ error = RelayUplinkTokenValidationError{}
- case "device_mode_conf":
- w, ok := m.Payload.(*MACCommand_DeviceModeConf_)
- if !ok || w == nil {
- continue
- }
+var _ interface {
+ Field() string
+ Reason() string
+ Key() bool
+ Cause() error
+ ErrorName() string
+} = RelayUplinkTokenValidationError{}
- if v, ok := interface{}(m.GetDeviceModeConf()).(interface{ ValidateFields(...string) error }); ok {
- if err := v.ValidateFields(subs...); err != nil {
- return MACCommandValidationError{
- field: "device_mode_conf",
- reason: "embedded message failed validation",
- cause: err,
- }
- }
- }
+// ValidateFields checks the field values on TxSettings_Downlink with the rules
+// defined in the proto definition for this message. If any rules are
+// violated, an error is returned.
+func (m *TxSettings_Downlink) ValidateFields(paths ...string) error {
+ if m == nil {
+ return nil
+ }
- }
- }
+ if len(paths) == 0 {
+ paths = TxSettings_DownlinkFieldPathsNested
+ }
+
+ for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
+ _ = subs
+ switch name {
+ case "antenna_index":
+ // no validation rules for AntennaIndex
+ case "tx_power":
+ // no validation rules for TxPower
+ case "invert_polarization":
+ // no validation rules for InvertPolarization
default:
- return MACCommandValidationError{
+ return TxSettings_DownlinkValidationError{
field: name,
reason: "invalid field path",
}
@@ -2959,9 +5072,9 @@ func (m *MACCommand) ValidateFields(paths ...string) error {
return nil
}
-// MACCommandValidationError is the validation error returned by
-// MACCommand.ValidateFields if the designated constraints aren't met.
-type MACCommandValidationError struct {
+// TxSettings_DownlinkValidationError is the validation error returned by
+// TxSettings_Downlink.ValidateFields if the designated constraints aren't met.
+type TxSettings_DownlinkValidationError struct {
field string
reason string
cause error
@@ -2969,22 +5082,24 @@ type MACCommandValidationError struct {
}
// Field function returns field value.
-func (e MACCommandValidationError) Field() string { return e.field }
+func (e TxSettings_DownlinkValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e MACCommandValidationError) Reason() string { return e.reason }
+func (e TxSettings_DownlinkValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e MACCommandValidationError) Cause() error { return e.cause }
+func (e TxSettings_DownlinkValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e MACCommandValidationError) Key() bool { return e.key }
+func (e TxSettings_DownlinkValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e MACCommandValidationError) ErrorName() string { return "MACCommandValidationError" }
+func (e TxSettings_DownlinkValidationError) ErrorName() string {
+ return "TxSettings_DownlinkValidationError"
+}
// Error satisfies the builtin error interface
-func (e MACCommandValidationError) Error() string {
+func (e TxSettings_DownlinkValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -2996,14 +5111,14 @@ func (e MACCommandValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sMACCommand.%s: %s%s",
+ "invalid %sTxSettings_Downlink.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = MACCommandValidationError{}
+var _ error = TxSettings_DownlinkValidationError{}
var _ interface {
Field() string
@@ -3011,46 +5126,41 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = MACCommandValidationError{}
-
-var _MACCommand_Cid_NotInLookup = map[MACCommandIdentifier]struct{}{
- 0: {},
-}
+} = TxSettings_DownlinkValidationError{}
-// ValidateFields checks the field values on MACCommands with the rules defined
-// in the proto definition for this message. If any rules are violated, an
-// error is returned.
-func (m *MACCommands) ValidateFields(paths ...string) error {
+// ValidateFields checks the field values on MACCommand_ResetInd with the rules
+// defined in the proto definition for this message. If any rules are
+// violated, an error is returned.
+func (m *MACCommand_ResetInd) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = MACCommandsFieldPathsNested
+ paths = MACCommand_ResetIndFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "commands":
-
- for idx, item := range m.GetCommands() {
- _, _ = idx, item
+ case "minor_version":
- if v, ok := interface{}(item).(interface{ ValidateFields(...string) error }); ok {
- if err := v.ValidateFields(subs...); err != nil {
- return MACCommandsValidationError{
- field: fmt.Sprintf("commands[%v]", idx),
- reason: "embedded message failed validation",
- cause: err,
- }
- }
+ if _, ok := _MACCommand_ResetInd_MinorVersion_InLookup[m.GetMinorVersion()]; !ok {
+ return MACCommand_ResetIndValidationError{
+ field: "minor_version",
+ reason: "value must be in list [1]",
}
+ }
+ if _, ok := Minor_name[int32(m.GetMinorVersion())]; !ok {
+ return MACCommand_ResetIndValidationError{
+ field: "minor_version",
+ reason: "value must be one of the defined enum values",
+ }
}
default:
- return MACCommandsValidationError{
+ return MACCommand_ResetIndValidationError{
field: name,
reason: "invalid field path",
}
@@ -3059,9 +5169,9 @@ func (m *MACCommands) ValidateFields(paths ...string) error {
return nil
}
-// MACCommandsValidationError is the validation error returned by
-// MACCommands.ValidateFields if the designated constraints aren't met.
-type MACCommandsValidationError struct {
+// MACCommand_ResetIndValidationError is the validation error returned by
+// MACCommand_ResetInd.ValidateFields if the designated constraints aren't met.
+type MACCommand_ResetIndValidationError struct {
field string
reason string
cause error
@@ -3069,22 +5179,24 @@ type MACCommandsValidationError struct {
}
// Field function returns field value.
-func (e MACCommandsValidationError) Field() string { return e.field }
+func (e MACCommand_ResetIndValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e MACCommandsValidationError) Reason() string { return e.reason }
+func (e MACCommand_ResetIndValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e MACCommandsValidationError) Cause() error { return e.cause }
+func (e MACCommand_ResetIndValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e MACCommandsValidationError) Key() bool { return e.key }
+func (e MACCommand_ResetIndValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e MACCommandsValidationError) ErrorName() string { return "MACCommandsValidationError" }
+func (e MACCommand_ResetIndValidationError) ErrorName() string {
+ return "MACCommand_ResetIndValidationError"
+}
// Error satisfies the builtin error interface
-func (e MACCommandsValidationError) Error() string {
+func (e MACCommand_ResetIndValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -3096,14 +5208,14 @@ func (e MACCommandsValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sMACCommands.%s: %s%s",
+ "invalid %sMACCommand_ResetInd.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = MACCommandsValidationError{}
+var _ error = MACCommand_ResetIndValidationError{}
var _ interface {
Field() string
@@ -3111,34 +5223,45 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = MACCommandsValidationError{}
+} = MACCommand_ResetIndValidationError{}
-// ValidateFields checks the field values on FrequencyValue with the rules
-// defined in the proto definition for this message. If any rules are
+var _MACCommand_ResetInd_MinorVersion_InLookup = map[Minor]struct{}{
+ 1: {},
+}
+
+// ValidateFields checks the field values on MACCommand_ResetConf with the
+// rules defined in the proto definition for this message. If any rules are
// violated, an error is returned.
-func (m *FrequencyValue) ValidateFields(paths ...string) error {
+func (m *MACCommand_ResetConf) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = FrequencyValueFieldPathsNested
+ paths = MACCommand_ResetConfFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "value":
+ case "minor_version":
- if m.GetValue() < 100000 {
- return FrequencyValueValidationError{
- field: "value",
- reason: "value must be greater than or equal to 100000",
+ if _, ok := _MACCommand_ResetConf_MinorVersion_InLookup[m.GetMinorVersion()]; !ok {
+ return MACCommand_ResetConfValidationError{
+ field: "minor_version",
+ reason: "value must be in list [1]",
+ }
+ }
+
+ if _, ok := Minor_name[int32(m.GetMinorVersion())]; !ok {
+ return MACCommand_ResetConfValidationError{
+ field: "minor_version",
+ reason: "value must be one of the defined enum values",
}
}
default:
- return FrequencyValueValidationError{
+ return MACCommand_ResetConfValidationError{
field: name,
reason: "invalid field path",
}
@@ -3147,9 +5270,9 @@ func (m *FrequencyValue) ValidateFields(paths ...string) error {
return nil
}
-// FrequencyValueValidationError is the validation error returned by
-// FrequencyValue.ValidateFields if the designated constraints aren't met.
-type FrequencyValueValidationError struct {
+// MACCommand_ResetConfValidationError is the validation error returned by
+// MACCommand_ResetConf.ValidateFields if the designated constraints aren't met.
+type MACCommand_ResetConfValidationError struct {
field string
reason string
cause error
@@ -3157,22 +5280,24 @@ type FrequencyValueValidationError struct {
}
// Field function returns field value.
-func (e FrequencyValueValidationError) Field() string { return e.field }
+func (e MACCommand_ResetConfValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e FrequencyValueValidationError) Reason() string { return e.reason }
+func (e MACCommand_ResetConfValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e FrequencyValueValidationError) Cause() error { return e.cause }
+func (e MACCommand_ResetConfValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e FrequencyValueValidationError) Key() bool { return e.key }
+func (e MACCommand_ResetConfValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e FrequencyValueValidationError) ErrorName() string { return "FrequencyValueValidationError" }
+func (e MACCommand_ResetConfValidationError) ErrorName() string {
+ return "MACCommand_ResetConfValidationError"
+}
// Error satisfies the builtin error interface
-func (e FrequencyValueValidationError) Error() string {
+func (e MACCommand_ResetConfValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -3184,14 +5309,14 @@ func (e FrequencyValueValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sFrequencyValue.%s: %s%s",
+ "invalid %sMACCommand_ResetConf.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = FrequencyValueValidationError{}
+var _ error = MACCommand_ResetConfValidationError{}
var _ interface {
Field() string
@@ -3199,34 +5324,47 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = FrequencyValueValidationError{}
+} = MACCommand_ResetConfValidationError{}
-// ValidateFields checks the field values on ZeroableFrequencyValue with the
+var _MACCommand_ResetConf_MinorVersion_InLookup = map[Minor]struct{}{
+ 1: {},
+}
+
+// ValidateFields checks the field values on MACCommand_LinkCheckAns with the
// rules defined in the proto definition for this message. If any rules are
// violated, an error is returned.
-func (m *ZeroableFrequencyValue) ValidateFields(paths ...string) error {
+func (m *MACCommand_LinkCheckAns) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = ZeroableFrequencyValueFieldPathsNested
+ paths = MACCommand_LinkCheckAnsFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "value":
+ case "margin":
- if val := m.GetValue(); val > 0 && val < 100000 {
- return ZeroableFrequencyValueValidationError{
- field: "value",
- reason: "value must be outside range (0, 100000)",
+ if m.GetMargin() > 254 {
+ return MACCommand_LinkCheckAnsValidationError{
+ field: "margin",
+ reason: "value must be less than or equal to 254",
+ }
+ }
+
+ case "gateway_count":
+
+ if m.GetGatewayCount() > 255 {
+ return MACCommand_LinkCheckAnsValidationError{
+ field: "gateway_count",
+ reason: "value must be less than or equal to 255",
}
}
default:
- return ZeroableFrequencyValueValidationError{
+ return MACCommand_LinkCheckAnsValidationError{
field: name,
reason: "invalid field path",
}
@@ -3235,9 +5373,9 @@ func (m *ZeroableFrequencyValue) ValidateFields(paths ...string) error {
return nil
}
-// ZeroableFrequencyValueValidationError is the validation error returned by
-// ZeroableFrequencyValue.ValidateFields if the designated constraints aren't met.
-type ZeroableFrequencyValueValidationError struct {
+// MACCommand_LinkCheckAnsValidationError is the validation error returned by
+// MACCommand_LinkCheckAns.ValidateFields if the designated constraints aren't met.
+type MACCommand_LinkCheckAnsValidationError struct {
field string
reason string
cause error
@@ -3245,24 +5383,24 @@ type ZeroableFrequencyValueValidationError struct {
}
// Field function returns field value.
-func (e ZeroableFrequencyValueValidationError) Field() string { return e.field }
+func (e MACCommand_LinkCheckAnsValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e ZeroableFrequencyValueValidationError) Reason() string { return e.reason }
+func (e MACCommand_LinkCheckAnsValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e ZeroableFrequencyValueValidationError) Cause() error { return e.cause }
+func (e MACCommand_LinkCheckAnsValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e ZeroableFrequencyValueValidationError) Key() bool { return e.key }
+func (e MACCommand_LinkCheckAnsValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e ZeroableFrequencyValueValidationError) ErrorName() string {
- return "ZeroableFrequencyValueValidationError"
+func (e MACCommand_LinkCheckAnsValidationError) ErrorName() string {
+ return "MACCommand_LinkCheckAnsValidationError"
}
// Error satisfies the builtin error interface
-func (e ZeroableFrequencyValueValidationError) Error() string {
+func (e MACCommand_LinkCheckAnsValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -3274,14 +5412,14 @@ func (e ZeroableFrequencyValueValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sZeroableFrequencyValue.%s: %s%s",
+ "invalid %sMACCommand_LinkCheckAns.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = ZeroableFrequencyValueValidationError{}
+var _ error = MACCommand_LinkCheckAnsValidationError{}
var _ interface {
Field() string
@@ -3289,34 +5427,70 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = ZeroableFrequencyValueValidationError{}
+} = MACCommand_LinkCheckAnsValidationError{}
-// ValidateFields checks the field values on DataRateOffsetValue with the rules
-// defined in the proto definition for this message. If any rules are
+// ValidateFields checks the field values on MACCommand_LinkADRReq with the
+// rules defined in the proto definition for this message. If any rules are
// violated, an error is returned.
-func (m *DataRateOffsetValue) ValidateFields(paths ...string) error {
+func (m *MACCommand_LinkADRReq) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = DataRateOffsetValueFieldPathsNested
+ paths = MACCommand_LinkADRReqFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "value":
+ case "data_rate_index":
- if _, ok := DataRateOffset_name[int32(m.GetValue())]; !ok {
- return DataRateOffsetValueValidationError{
- field: "value",
+ if _, ok := DataRateIndex_name[int32(m.GetDataRateIndex())]; !ok {
+ return MACCommand_LinkADRReqValidationError{
+ field: "data_rate_index",
reason: "value must be one of the defined enum values",
}
}
+ case "tx_power_index":
+
+ if m.GetTxPowerIndex() > 15 {
+ return MACCommand_LinkADRReqValidationError{
+ field: "tx_power_index",
+ reason: "value must be less than or equal to 15",
+ }
+ }
+
+ case "channel_mask":
+
+ if len(m.GetChannelMask()) > 16 {
+ return MACCommand_LinkADRReqValidationError{
+ field: "channel_mask",
+ reason: "value must contain no more than 16 item(s)",
+ }
+ }
+
+ case "channel_mask_control":
+
+ if m.GetChannelMaskControl() > 7 {
+ return MACCommand_LinkADRReqValidationError{
+ field: "channel_mask_control",
+ reason: "value must be less than or equal to 7",
+ }
+ }
+
+ case "nb_trans":
+
+ if m.GetNbTrans() > 15 {
+ return MACCommand_LinkADRReqValidationError{
+ field: "nb_trans",
+ reason: "value must be less than or equal to 15",
+ }
+ }
+
default:
- return DataRateOffsetValueValidationError{
+ return MACCommand_LinkADRReqValidationError{
field: name,
reason: "invalid field path",
}
@@ -3325,9 +5499,9 @@ func (m *DataRateOffsetValue) ValidateFields(paths ...string) error {
return nil
}
-// DataRateOffsetValueValidationError is the validation error returned by
-// DataRateOffsetValue.ValidateFields if the designated constraints aren't met.
-type DataRateOffsetValueValidationError struct {
+// MACCommand_LinkADRReqValidationError is the validation error returned by
+// MACCommand_LinkADRReq.ValidateFields if the designated constraints aren't met.
+type MACCommand_LinkADRReqValidationError struct {
field string
reason string
cause error
@@ -3335,24 +5509,24 @@ type DataRateOffsetValueValidationError struct {
}
// Field function returns field value.
-func (e DataRateOffsetValueValidationError) Field() string { return e.field }
+func (e MACCommand_LinkADRReqValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e DataRateOffsetValueValidationError) Reason() string { return e.reason }
+func (e MACCommand_LinkADRReqValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e DataRateOffsetValueValidationError) Cause() error { return e.cause }
+func (e MACCommand_LinkADRReqValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e DataRateOffsetValueValidationError) Key() bool { return e.key }
+func (e MACCommand_LinkADRReqValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e DataRateOffsetValueValidationError) ErrorName() string {
- return "DataRateOffsetValueValidationError"
+func (e MACCommand_LinkADRReqValidationError) ErrorName() string {
+ return "MACCommand_LinkADRReqValidationError"
}
// Error satisfies the builtin error interface
-func (e DataRateOffsetValueValidationError) Error() string {
+func (e MACCommand_LinkADRReqValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -3364,14 +5538,14 @@ func (e DataRateOffsetValueValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sDataRateOffsetValue.%s: %s%s",
+ "invalid %sMACCommand_LinkADRReq.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = DataRateOffsetValueValidationError{}
+var _ error = MACCommand_LinkADRReqValidationError{}
var _ interface {
Field() string
@@ -3379,34 +5553,31 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = DataRateOffsetValueValidationError{}
+} = MACCommand_LinkADRReqValidationError{}
-// ValidateFields checks the field values on DataRateIndexValue with the rules
-// defined in the proto definition for this message. If any rules are
+// ValidateFields checks the field values on MACCommand_LinkADRAns with the
+// rules defined in the proto definition for this message. If any rules are
// violated, an error is returned.
-func (m *DataRateIndexValue) ValidateFields(paths ...string) error {
+func (m *MACCommand_LinkADRAns) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = DataRateIndexValueFieldPathsNested
+ paths = MACCommand_LinkADRAnsFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "value":
-
- if _, ok := DataRateIndex_name[int32(m.GetValue())]; !ok {
- return DataRateIndexValueValidationError{
- field: "value",
- reason: "value must be one of the defined enum values",
- }
- }
-
+ case "channel_mask_ack":
+ // no validation rules for ChannelMaskAck
+ case "data_rate_index_ack":
+ // no validation rules for DataRateIndexAck
+ case "tx_power_index_ack":
+ // no validation rules for TxPowerIndexAck
default:
- return DataRateIndexValueValidationError{
+ return MACCommand_LinkADRAnsValidationError{
field: name,
reason: "invalid field path",
}
@@ -3415,9 +5586,9 @@ func (m *DataRateIndexValue) ValidateFields(paths ...string) error {
return nil
}
-// DataRateIndexValueValidationError is the validation error returned by
-// DataRateIndexValue.ValidateFields if the designated constraints aren't met.
-type DataRateIndexValueValidationError struct {
+// MACCommand_LinkADRAnsValidationError is the validation error returned by
+// MACCommand_LinkADRAns.ValidateFields if the designated constraints aren't met.
+type MACCommand_LinkADRAnsValidationError struct {
field string
reason string
cause error
@@ -3425,24 +5596,24 @@ type DataRateIndexValueValidationError struct {
}
// Field function returns field value.
-func (e DataRateIndexValueValidationError) Field() string { return e.field }
+func (e MACCommand_LinkADRAnsValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e DataRateIndexValueValidationError) Reason() string { return e.reason }
+func (e MACCommand_LinkADRAnsValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e DataRateIndexValueValidationError) Cause() error { return e.cause }
+func (e MACCommand_LinkADRAnsValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e DataRateIndexValueValidationError) Key() bool { return e.key }
+func (e MACCommand_LinkADRAnsValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e DataRateIndexValueValidationError) ErrorName() string {
- return "DataRateIndexValueValidationError"
+func (e MACCommand_LinkADRAnsValidationError) ErrorName() string {
+ return "MACCommand_LinkADRAnsValidationError"
}
// Error satisfies the builtin error interface
-func (e DataRateIndexValueValidationError) Error() string {
+func (e MACCommand_LinkADRAnsValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -3454,14 +5625,14 @@ func (e DataRateIndexValueValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sDataRateIndexValue.%s: %s%s",
+ "invalid %sMACCommand_LinkADRAns.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = DataRateIndexValueValidationError{}
+var _ error = MACCommand_LinkADRAnsValidationError{}
var _ interface {
Field() string
@@ -3469,34 +5640,34 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = DataRateIndexValueValidationError{}
+} = MACCommand_LinkADRAnsValidationError{}
-// ValidateFields checks the field values on PingSlotPeriodValue with the rules
-// defined in the proto definition for this message. If any rules are
+// ValidateFields checks the field values on MACCommand_DutyCycleReq with the
+// rules defined in the proto definition for this message. If any rules are
// violated, an error is returned.
-func (m *PingSlotPeriodValue) ValidateFields(paths ...string) error {
+func (m *MACCommand_DutyCycleReq) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = PingSlotPeriodValueFieldPathsNested
+ paths = MACCommand_DutyCycleReqFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "value":
+ case "max_duty_cycle":
- if _, ok := PingSlotPeriod_name[int32(m.GetValue())]; !ok {
- return PingSlotPeriodValueValidationError{
- field: "value",
+ if _, ok := AggregatedDutyCycle_name[int32(m.GetMaxDutyCycle())]; !ok {
+ return MACCommand_DutyCycleReqValidationError{
+ field: "max_duty_cycle",
reason: "value must be one of the defined enum values",
}
}
default:
- return PingSlotPeriodValueValidationError{
+ return MACCommand_DutyCycleReqValidationError{
field: name,
reason: "invalid field path",
}
@@ -3505,9 +5676,9 @@ func (m *PingSlotPeriodValue) ValidateFields(paths ...string) error {
return nil
}
-// PingSlotPeriodValueValidationError is the validation error returned by
-// PingSlotPeriodValue.ValidateFields if the designated constraints aren't met.
-type PingSlotPeriodValueValidationError struct {
+// MACCommand_DutyCycleReqValidationError is the validation error returned by
+// MACCommand_DutyCycleReq.ValidateFields if the designated constraints aren't met.
+type MACCommand_DutyCycleReqValidationError struct {
field string
reason string
cause error
@@ -3515,24 +5686,24 @@ type PingSlotPeriodValueValidationError struct {
}
// Field function returns field value.
-func (e PingSlotPeriodValueValidationError) Field() string { return e.field }
+func (e MACCommand_DutyCycleReqValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e PingSlotPeriodValueValidationError) Reason() string { return e.reason }
+func (e MACCommand_DutyCycleReqValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e PingSlotPeriodValueValidationError) Cause() error { return e.cause }
+func (e MACCommand_DutyCycleReqValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e PingSlotPeriodValueValidationError) Key() bool { return e.key }
+func (e MACCommand_DutyCycleReqValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e PingSlotPeriodValueValidationError) ErrorName() string {
- return "PingSlotPeriodValueValidationError"
+func (e MACCommand_DutyCycleReqValidationError) ErrorName() string {
+ return "MACCommand_DutyCycleReqValidationError"
}
// Error satisfies the builtin error interface
-func (e PingSlotPeriodValueValidationError) Error() string {
+func (e MACCommand_DutyCycleReqValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -3544,14 +5715,14 @@ func (e PingSlotPeriodValueValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sPingSlotPeriodValue.%s: %s%s",
+ "invalid %sMACCommand_DutyCycleReq.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = PingSlotPeriodValueValidationError{}
+var _ error = MACCommand_DutyCycleReqValidationError{}
var _ interface {
Field() string
@@ -3559,34 +5730,52 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = PingSlotPeriodValueValidationError{}
+} = MACCommand_DutyCycleReqValidationError{}
-// ValidateFields checks the field values on AggregatedDutyCycleValue with the
-// rules defined in the proto definition for this message. If any rules are
-// violated, an error is returned.
-func (m *AggregatedDutyCycleValue) ValidateFields(paths ...string) error {
+// ValidateFields checks the field values on MACCommand_RxParamSetupReq with
+// the rules defined in the proto definition for this message. If any rules
+// are violated, an error is returned.
+func (m *MACCommand_RxParamSetupReq) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = AggregatedDutyCycleValueFieldPathsNested
+ paths = MACCommand_RxParamSetupReqFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "value":
+ case "rx2_data_rate_index":
- if _, ok := AggregatedDutyCycle_name[int32(m.GetValue())]; !ok {
- return AggregatedDutyCycleValueValidationError{
- field: "value",
+ if _, ok := DataRateIndex_name[int32(m.GetRx2DataRateIndex())]; !ok {
+ return MACCommand_RxParamSetupReqValidationError{
+ field: "rx2_data_rate_index",
+ reason: "value must be one of the defined enum values",
+ }
+ }
+
+ case "rx1_data_rate_offset":
+
+ if _, ok := DataRateOffset_name[int32(m.GetRx1DataRateOffset())]; !ok {
+ return MACCommand_RxParamSetupReqValidationError{
+ field: "rx1_data_rate_offset",
reason: "value must be one of the defined enum values",
}
}
+ case "rx2_frequency":
+
+ if m.GetRx2Frequency() < 100000 {
+ return MACCommand_RxParamSetupReqValidationError{
+ field: "rx2_frequency",
+ reason: "value must be greater than or equal to 100000",
+ }
+ }
+
default:
- return AggregatedDutyCycleValueValidationError{
+ return MACCommand_RxParamSetupReqValidationError{
field: name,
reason: "invalid field path",
}
@@ -3595,10 +5784,10 @@ func (m *AggregatedDutyCycleValue) ValidateFields(paths ...string) error {
return nil
}
-// AggregatedDutyCycleValueValidationError is the validation error returned by
-// AggregatedDutyCycleValue.ValidateFields if the designated constraints
+// MACCommand_RxParamSetupReqValidationError is the validation error returned
+// by MACCommand_RxParamSetupReq.ValidateFields if the designated constraints
// aren't met.
-type AggregatedDutyCycleValueValidationError struct {
+type MACCommand_RxParamSetupReqValidationError struct {
field string
reason string
cause error
@@ -3606,24 +5795,24 @@ type AggregatedDutyCycleValueValidationError struct {
}
// Field function returns field value.
-func (e AggregatedDutyCycleValueValidationError) Field() string { return e.field }
+func (e MACCommand_RxParamSetupReqValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e AggregatedDutyCycleValueValidationError) Reason() string { return e.reason }
+func (e MACCommand_RxParamSetupReqValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e AggregatedDutyCycleValueValidationError) Cause() error { return e.cause }
+func (e MACCommand_RxParamSetupReqValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e AggregatedDutyCycleValueValidationError) Key() bool { return e.key }
+func (e MACCommand_RxParamSetupReqValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e AggregatedDutyCycleValueValidationError) ErrorName() string {
- return "AggregatedDutyCycleValueValidationError"
+func (e MACCommand_RxParamSetupReqValidationError) ErrorName() string {
+ return "MACCommand_RxParamSetupReqValidationError"
}
// Error satisfies the builtin error interface
-func (e AggregatedDutyCycleValueValidationError) Error() string {
+func (e MACCommand_RxParamSetupReqValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -3635,14 +5824,14 @@ func (e AggregatedDutyCycleValueValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sAggregatedDutyCycleValue.%s: %s%s",
+ "invalid %sMACCommand_RxParamSetupReq.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = AggregatedDutyCycleValueValidationError{}
+var _ error = MACCommand_RxParamSetupReqValidationError{}
var _ interface {
Field() string
@@ -3650,34 +5839,31 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = AggregatedDutyCycleValueValidationError{}
+} = MACCommand_RxParamSetupReqValidationError{}
-// ValidateFields checks the field values on RxDelayValue with the rules
-// defined in the proto definition for this message. If any rules are
-// violated, an error is returned.
-func (m *RxDelayValue) ValidateFields(paths ...string) error {
+// ValidateFields checks the field values on MACCommand_RxParamSetupAns with
+// the rules defined in the proto definition for this message. If any rules
+// are violated, an error is returned.
+func (m *MACCommand_RxParamSetupAns) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = RxDelayValueFieldPathsNested
+ paths = MACCommand_RxParamSetupAnsFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "value":
-
- if _, ok := RxDelay_name[int32(m.GetValue())]; !ok {
- return RxDelayValueValidationError{
- field: "value",
- reason: "value must be one of the defined enum values",
- }
- }
-
+ case "rx2_data_rate_index_ack":
+ // no validation rules for Rx2DataRateIndexAck
+ case "rx1_data_rate_offset_ack":
+ // no validation rules for Rx1DataRateOffsetAck
+ case "rx2_frequency_ack":
+ // no validation rules for Rx2FrequencyAck
default:
- return RxDelayValueValidationError{
+ return MACCommand_RxParamSetupAnsValidationError{
field: name,
reason: "invalid field path",
}
@@ -3686,9 +5872,10 @@ func (m *RxDelayValue) ValidateFields(paths ...string) error {
return nil
}
-// RxDelayValueValidationError is the validation error returned by
-// RxDelayValue.ValidateFields if the designated constraints aren't met.
-type RxDelayValueValidationError struct {
+// MACCommand_RxParamSetupAnsValidationError is the validation error returned
+// by MACCommand_RxParamSetupAns.ValidateFields if the designated constraints
+// aren't met.
+type MACCommand_RxParamSetupAnsValidationError struct {
field string
reason string
cause error
@@ -3696,22 +5883,24 @@ type RxDelayValueValidationError struct {
}
// Field function returns field value.
-func (e RxDelayValueValidationError) Field() string { return e.field }
+func (e MACCommand_RxParamSetupAnsValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e RxDelayValueValidationError) Reason() string { return e.reason }
+func (e MACCommand_RxParamSetupAnsValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e RxDelayValueValidationError) Cause() error { return e.cause }
+func (e MACCommand_RxParamSetupAnsValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e RxDelayValueValidationError) Key() bool { return e.key }
+func (e MACCommand_RxParamSetupAnsValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e RxDelayValueValidationError) ErrorName() string { return "RxDelayValueValidationError" }
+func (e MACCommand_RxParamSetupAnsValidationError) ErrorName() string {
+ return "MACCommand_RxParamSetupAnsValidationError"
+}
// Error satisfies the builtin error interface
-func (e RxDelayValueValidationError) Error() string {
+func (e MACCommand_RxParamSetupAnsValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -3723,14 +5912,14 @@ func (e RxDelayValueValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sRxDelayValue.%s: %s%s",
+ "invalid %sMACCommand_RxParamSetupAns.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = RxDelayValueValidationError{}
+var _ error = MACCommand_RxParamSetupAnsValidationError{}
var _ interface {
Field() string
@@ -3738,34 +5927,43 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = RxDelayValueValidationError{}
+} = MACCommand_RxParamSetupAnsValidationError{}
-// ValidateFields checks the field values on ADRAckLimitExponentValue with the
+// ValidateFields checks the field values on MACCommand_DevStatusAns with the
// rules defined in the proto definition for this message. If any rules are
// violated, an error is returned.
-func (m *ADRAckLimitExponentValue) ValidateFields(paths ...string) error {
+func (m *MACCommand_DevStatusAns) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = ADRAckLimitExponentValueFieldPathsNested
+ paths = MACCommand_DevStatusAnsFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "value":
+ case "battery":
- if _, ok := ADRAckLimitExponent_name[int32(m.GetValue())]; !ok {
- return ADRAckLimitExponentValueValidationError{
- field: "value",
- reason: "value must be one of the defined enum values",
+ if m.GetBattery() > 255 {
+ return MACCommand_DevStatusAnsValidationError{
+ field: "battery",
+ reason: "value must be less than or equal to 255",
+ }
+ }
+
+ case "margin":
+
+ if val := m.GetMargin(); val < -32 || val > 31 {
+ return MACCommand_DevStatusAnsValidationError{
+ field: "margin",
+ reason: "value must be inside range [-32, 31]",
}
}
default:
- return ADRAckLimitExponentValueValidationError{
+ return MACCommand_DevStatusAnsValidationError{
field: name,
reason: "invalid field path",
}
@@ -3774,10 +5972,9 @@ func (m *ADRAckLimitExponentValue) ValidateFields(paths ...string) error {
return nil
}
-// ADRAckLimitExponentValueValidationError is the validation error returned by
-// ADRAckLimitExponentValue.ValidateFields if the designated constraints
-// aren't met.
-type ADRAckLimitExponentValueValidationError struct {
+// MACCommand_DevStatusAnsValidationError is the validation error returned by
+// MACCommand_DevStatusAns.ValidateFields if the designated constraints aren't met.
+type MACCommand_DevStatusAnsValidationError struct {
field string
reason string
cause error
@@ -3785,24 +5982,24 @@ type ADRAckLimitExponentValueValidationError struct {
}
// Field function returns field value.
-func (e ADRAckLimitExponentValueValidationError) Field() string { return e.field }
+func (e MACCommand_DevStatusAnsValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e ADRAckLimitExponentValueValidationError) Reason() string { return e.reason }
+func (e MACCommand_DevStatusAnsValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e ADRAckLimitExponentValueValidationError) Cause() error { return e.cause }
+func (e MACCommand_DevStatusAnsValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e ADRAckLimitExponentValueValidationError) Key() bool { return e.key }
+func (e MACCommand_DevStatusAnsValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e ADRAckLimitExponentValueValidationError) ErrorName() string {
- return "ADRAckLimitExponentValueValidationError"
+func (e MACCommand_DevStatusAnsValidationError) ErrorName() string {
+ return "MACCommand_DevStatusAnsValidationError"
}
// Error satisfies the builtin error interface
-func (e ADRAckLimitExponentValueValidationError) Error() string {
+func (e MACCommand_DevStatusAnsValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -3814,14 +6011,14 @@ func (e ADRAckLimitExponentValueValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sADRAckLimitExponentValue.%s: %s%s",
+ "invalid %sMACCommand_DevStatusAns.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = ADRAckLimitExponentValueValidationError{}
+var _ error = MACCommand_DevStatusAnsValidationError{}
var _ interface {
Field() string
@@ -3829,34 +6026,61 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = ADRAckLimitExponentValueValidationError{}
+} = MACCommand_DevStatusAnsValidationError{}
-// ValidateFields checks the field values on ADRAckDelayExponentValue with the
+// ValidateFields checks the field values on MACCommand_NewChannelReq with the
// rules defined in the proto definition for this message. If any rules are
// violated, an error is returned.
-func (m *ADRAckDelayExponentValue) ValidateFields(paths ...string) error {
+func (m *MACCommand_NewChannelReq) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = ADRAckDelayExponentValueFieldPathsNested
+ paths = MACCommand_NewChannelReqFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "value":
+ case "channel_index":
+
+ if m.GetChannelIndex() > 255 {
+ return MACCommand_NewChannelReqValidationError{
+ field: "channel_index",
+ reason: "value must be less than or equal to 255",
+ }
+ }
+
+ case "frequency":
+
+ if val := m.GetFrequency(); val > 0 && val < 100000 {
+ return MACCommand_NewChannelReqValidationError{
+ field: "frequency",
+ reason: "value must be outside range (0, 100000)",
+ }
+ }
+
+ case "min_data_rate_index":
+
+ if _, ok := DataRateIndex_name[int32(m.GetMinDataRateIndex())]; !ok {
+ return MACCommand_NewChannelReqValidationError{
+ field: "min_data_rate_index",
+ reason: "value must be one of the defined enum values",
+ }
+ }
- if _, ok := ADRAckDelayExponent_name[int32(m.GetValue())]; !ok {
- return ADRAckDelayExponentValueValidationError{
- field: "value",
+ case "max_data_rate_index":
+
+ if _, ok := DataRateIndex_name[int32(m.GetMaxDataRateIndex())]; !ok {
+ return MACCommand_NewChannelReqValidationError{
+ field: "max_data_rate_index",
reason: "value must be one of the defined enum values",
}
}
default:
- return ADRAckDelayExponentValueValidationError{
+ return MACCommand_NewChannelReqValidationError{
field: name,
reason: "invalid field path",
}
@@ -3865,10 +6089,10 @@ func (m *ADRAckDelayExponentValue) ValidateFields(paths ...string) error {
return nil
}
-// ADRAckDelayExponentValueValidationError is the validation error returned by
-// ADRAckDelayExponentValue.ValidateFields if the designated constraints
+// MACCommand_NewChannelReqValidationError is the validation error returned by
+// MACCommand_NewChannelReq.ValidateFields if the designated constraints
// aren't met.
-type ADRAckDelayExponentValueValidationError struct {
+type MACCommand_NewChannelReqValidationError struct {
field string
reason string
cause error
@@ -3876,24 +6100,24 @@ type ADRAckDelayExponentValueValidationError struct {
}
// Field function returns field value.
-func (e ADRAckDelayExponentValueValidationError) Field() string { return e.field }
+func (e MACCommand_NewChannelReqValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e ADRAckDelayExponentValueValidationError) Reason() string { return e.reason }
+func (e MACCommand_NewChannelReqValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e ADRAckDelayExponentValueValidationError) Cause() error { return e.cause }
+func (e MACCommand_NewChannelReqValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e ADRAckDelayExponentValueValidationError) Key() bool { return e.key }
+func (e MACCommand_NewChannelReqValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e ADRAckDelayExponentValueValidationError) ErrorName() string {
- return "ADRAckDelayExponentValueValidationError"
+func (e MACCommand_NewChannelReqValidationError) ErrorName() string {
+ return "MACCommand_NewChannelReqValidationError"
}
// Error satisfies the builtin error interface
-func (e ADRAckDelayExponentValueValidationError) Error() string {
+func (e MACCommand_NewChannelReqValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -3905,14 +6129,14 @@ func (e ADRAckDelayExponentValueValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sADRAckDelayExponentValue.%s: %s%s",
+ "invalid %sMACCommand_NewChannelReq.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = ADRAckDelayExponentValueValidationError{}
+var _ error = MACCommand_NewChannelReqValidationError{}
var _ interface {
Field() string
@@ -3920,34 +6144,29 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = ADRAckDelayExponentValueValidationError{}
+} = MACCommand_NewChannelReqValidationError{}
-// ValidateFields checks the field values on DeviceEIRPValue with the rules
-// defined in the proto definition for this message. If any rules are
+// ValidateFields checks the field values on MACCommand_NewChannelAns with the
+// rules defined in the proto definition for this message. If any rules are
// violated, an error is returned.
-func (m *DeviceEIRPValue) ValidateFields(paths ...string) error {
+func (m *MACCommand_NewChannelAns) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = DeviceEIRPValueFieldPathsNested
+ paths = MACCommand_NewChannelAnsFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "value":
-
- if _, ok := DeviceEIRP_name[int32(m.GetValue())]; !ok {
- return DeviceEIRPValueValidationError{
- field: "value",
- reason: "value must be one of the defined enum values",
- }
- }
-
+ case "frequency_ack":
+ // no validation rules for FrequencyAck
+ case "data_rate_ack":
+ // no validation rules for DataRateAck
default:
- return DeviceEIRPValueValidationError{
+ return MACCommand_NewChannelAnsValidationError{
field: name,
reason: "invalid field path",
}
@@ -3956,9 +6175,10 @@ func (m *DeviceEIRPValue) ValidateFields(paths ...string) error {
return nil
}
-// DeviceEIRPValueValidationError is the validation error returned by
-// DeviceEIRPValue.ValidateFields if the designated constraints aren't met.
-type DeviceEIRPValueValidationError struct {
+// MACCommand_NewChannelAnsValidationError is the validation error returned by
+// MACCommand_NewChannelAns.ValidateFields if the designated constraints
+// aren't met.
+type MACCommand_NewChannelAnsValidationError struct {
field string
reason string
cause error
@@ -3966,22 +6186,24 @@ type DeviceEIRPValueValidationError struct {
}
// Field function returns field value.
-func (e DeviceEIRPValueValidationError) Field() string { return e.field }
+func (e MACCommand_NewChannelAnsValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e DeviceEIRPValueValidationError) Reason() string { return e.reason }
+func (e MACCommand_NewChannelAnsValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e DeviceEIRPValueValidationError) Cause() error { return e.cause }
+func (e MACCommand_NewChannelAnsValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e DeviceEIRPValueValidationError) Key() bool { return e.key }
+func (e MACCommand_NewChannelAnsValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e DeviceEIRPValueValidationError) ErrorName() string { return "DeviceEIRPValueValidationError" }
+func (e MACCommand_NewChannelAnsValidationError) ErrorName() string {
+ return "MACCommand_NewChannelAnsValidationError"
+}
// Error satisfies the builtin error interface
-func (e DeviceEIRPValueValidationError) Error() string {
+func (e MACCommand_NewChannelAnsValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -3993,14 +6215,14 @@ func (e DeviceEIRPValueValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sDeviceEIRPValue.%s: %s%s",
+ "invalid %sMACCommand_NewChannelAns.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = DeviceEIRPValueValidationError{}
+var _ error = MACCommand_NewChannelAnsValidationError{}
var _ interface {
Field() string
@@ -4008,31 +6230,43 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = DeviceEIRPValueValidationError{}
+} = MACCommand_NewChannelAnsValidationError{}
-// ValidateFields checks the field values on TxSettings_Downlink with the rules
-// defined in the proto definition for this message. If any rules are
+// ValidateFields checks the field values on MACCommand_DLChannelReq with the
+// rules defined in the proto definition for this message. If any rules are
// violated, an error is returned.
-func (m *TxSettings_Downlink) ValidateFields(paths ...string) error {
+func (m *MACCommand_DLChannelReq) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = TxSettings_DownlinkFieldPathsNested
+ paths = MACCommand_DLChannelReqFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "antenna_index":
- // no validation rules for AntennaIndex
- case "tx_power":
- // no validation rules for TxPower
- case "invert_polarization":
- // no validation rules for InvertPolarization
+ case "channel_index":
+
+ if m.GetChannelIndex() > 255 {
+ return MACCommand_DLChannelReqValidationError{
+ field: "channel_index",
+ reason: "value must be less than or equal to 255",
+ }
+ }
+
+ case "frequency":
+
+ if m.GetFrequency() < 100000 {
+ return MACCommand_DLChannelReqValidationError{
+ field: "frequency",
+ reason: "value must be greater than or equal to 100000",
+ }
+ }
+
default:
- return TxSettings_DownlinkValidationError{
+ return MACCommand_DLChannelReqValidationError{
field: name,
reason: "invalid field path",
}
@@ -4041,9 +6275,9 @@ func (m *TxSettings_Downlink) ValidateFields(paths ...string) error {
return nil
}
-// TxSettings_DownlinkValidationError is the validation error returned by
-// TxSettings_Downlink.ValidateFields if the designated constraints aren't met.
-type TxSettings_DownlinkValidationError struct {
+// MACCommand_DLChannelReqValidationError is the validation error returned by
+// MACCommand_DLChannelReq.ValidateFields if the designated constraints aren't met.
+type MACCommand_DLChannelReqValidationError struct {
field string
reason string
cause error
@@ -4051,24 +6285,24 @@ type TxSettings_DownlinkValidationError struct {
}
// Field function returns field value.
-func (e TxSettings_DownlinkValidationError) Field() string { return e.field }
+func (e MACCommand_DLChannelReqValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e TxSettings_DownlinkValidationError) Reason() string { return e.reason }
+func (e MACCommand_DLChannelReqValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e TxSettings_DownlinkValidationError) Cause() error { return e.cause }
+func (e MACCommand_DLChannelReqValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e TxSettings_DownlinkValidationError) Key() bool { return e.key }
+func (e MACCommand_DLChannelReqValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e TxSettings_DownlinkValidationError) ErrorName() string {
- return "TxSettings_DownlinkValidationError"
+func (e MACCommand_DLChannelReqValidationError) ErrorName() string {
+ return "MACCommand_DLChannelReqValidationError"
}
// Error satisfies the builtin error interface
-func (e TxSettings_DownlinkValidationError) Error() string {
+func (e MACCommand_DLChannelReqValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -4080,14 +6314,14 @@ func (e TxSettings_DownlinkValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sTxSettings_Downlink.%s: %s%s",
+ "invalid %sMACCommand_DLChannelReq.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = TxSettings_DownlinkValidationError{}
+var _ error = MACCommand_DLChannelReqValidationError{}
var _ interface {
Field() string
@@ -4095,41 +6329,29 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = TxSettings_DownlinkValidationError{}
+} = MACCommand_DLChannelReqValidationError{}
-// ValidateFields checks the field values on MACCommand_ResetInd with the rules
-// defined in the proto definition for this message. If any rules are
+// ValidateFields checks the field values on MACCommand_DLChannelAns with the
+// rules defined in the proto definition for this message. If any rules are
// violated, an error is returned.
-func (m *MACCommand_ResetInd) ValidateFields(paths ...string) error {
+func (m *MACCommand_DLChannelAns) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = MACCommand_ResetIndFieldPathsNested
+ paths = MACCommand_DLChannelAnsFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "minor_version":
-
- if _, ok := _MACCommand_ResetInd_MinorVersion_InLookup[m.GetMinorVersion()]; !ok {
- return MACCommand_ResetIndValidationError{
- field: "minor_version",
- reason: "value must be in list [1]",
- }
- }
-
- if _, ok := Minor_name[int32(m.GetMinorVersion())]; !ok {
- return MACCommand_ResetIndValidationError{
- field: "minor_version",
- reason: "value must be one of the defined enum values",
- }
- }
-
+ case "channel_index_ack":
+ // no validation rules for ChannelIndexAck
+ case "frequency_ack":
+ // no validation rules for FrequencyAck
default:
- return MACCommand_ResetIndValidationError{
+ return MACCommand_DLChannelAnsValidationError{
field: name,
reason: "invalid field path",
}
@@ -4138,9 +6360,9 @@ func (m *MACCommand_ResetInd) ValidateFields(paths ...string) error {
return nil
}
-// MACCommand_ResetIndValidationError is the validation error returned by
-// MACCommand_ResetInd.ValidateFields if the designated constraints aren't met.
-type MACCommand_ResetIndValidationError struct {
+// MACCommand_DLChannelAnsValidationError is the validation error returned by
+// MACCommand_DLChannelAns.ValidateFields if the designated constraints aren't met.
+type MACCommand_DLChannelAnsValidationError struct {
field string
reason string
cause error
@@ -4148,24 +6370,24 @@ type MACCommand_ResetIndValidationError struct {
}
// Field function returns field value.
-func (e MACCommand_ResetIndValidationError) Field() string { return e.field }
+func (e MACCommand_DLChannelAnsValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e MACCommand_ResetIndValidationError) Reason() string { return e.reason }
+func (e MACCommand_DLChannelAnsValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e MACCommand_ResetIndValidationError) Cause() error { return e.cause }
+func (e MACCommand_DLChannelAnsValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e MACCommand_ResetIndValidationError) Key() bool { return e.key }
+func (e MACCommand_DLChannelAnsValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e MACCommand_ResetIndValidationError) ErrorName() string {
- return "MACCommand_ResetIndValidationError"
+func (e MACCommand_DLChannelAnsValidationError) ErrorName() string {
+ return "MACCommand_DLChannelAnsValidationError"
}
// Error satisfies the builtin error interface
-func (e MACCommand_ResetIndValidationError) Error() string {
+func (e MACCommand_DLChannelAnsValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -4177,14 +6399,14 @@ func (e MACCommand_ResetIndValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sMACCommand_ResetInd.%s: %s%s",
+ "invalid %sMACCommand_DLChannelAns.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = MACCommand_ResetIndValidationError{}
+var _ error = MACCommand_DLChannelAnsValidationError{}
var _ interface {
Field() string
@@ -4192,45 +6414,34 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = MACCommand_ResetIndValidationError{}
-
-var _MACCommand_ResetInd_MinorVersion_InLookup = map[Minor]struct{}{
- 1: {},
-}
+} = MACCommand_DLChannelAnsValidationError{}
-// ValidateFields checks the field values on MACCommand_ResetConf with the
-// rules defined in the proto definition for this message. If any rules are
-// violated, an error is returned.
-func (m *MACCommand_ResetConf) ValidateFields(paths ...string) error {
+// ValidateFields checks the field values on MACCommand_RxTimingSetupReq with
+// the rules defined in the proto definition for this message. If any rules
+// are violated, an error is returned.
+func (m *MACCommand_RxTimingSetupReq) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = MACCommand_ResetConfFieldPathsNested
+ paths = MACCommand_RxTimingSetupReqFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "minor_version":
-
- if _, ok := _MACCommand_ResetConf_MinorVersion_InLookup[m.GetMinorVersion()]; !ok {
- return MACCommand_ResetConfValidationError{
- field: "minor_version",
- reason: "value must be in list [1]",
- }
- }
+ case "delay":
- if _, ok := Minor_name[int32(m.GetMinorVersion())]; !ok {
- return MACCommand_ResetConfValidationError{
- field: "minor_version",
+ if _, ok := RxDelay_name[int32(m.GetDelay())]; !ok {
+ return MACCommand_RxTimingSetupReqValidationError{
+ field: "delay",
reason: "value must be one of the defined enum values",
}
}
default:
- return MACCommand_ResetConfValidationError{
+ return MACCommand_RxTimingSetupReqValidationError{
field: name,
reason: "invalid field path",
}
@@ -4239,9 +6450,10 @@ func (m *MACCommand_ResetConf) ValidateFields(paths ...string) error {
return nil
}
-// MACCommand_ResetConfValidationError is the validation error returned by
-// MACCommand_ResetConf.ValidateFields if the designated constraints aren't met.
-type MACCommand_ResetConfValidationError struct {
+// MACCommand_RxTimingSetupReqValidationError is the validation error returned
+// by MACCommand_RxTimingSetupReq.ValidateFields if the designated constraints
+// aren't met.
+type MACCommand_RxTimingSetupReqValidationError struct {
field string
reason string
cause error
@@ -4249,24 +6461,24 @@ type MACCommand_ResetConfValidationError struct {
}
// Field function returns field value.
-func (e MACCommand_ResetConfValidationError) Field() string { return e.field }
+func (e MACCommand_RxTimingSetupReqValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e MACCommand_ResetConfValidationError) Reason() string { return e.reason }
+func (e MACCommand_RxTimingSetupReqValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e MACCommand_ResetConfValidationError) Cause() error { return e.cause }
+func (e MACCommand_RxTimingSetupReqValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e MACCommand_ResetConfValidationError) Key() bool { return e.key }
+func (e MACCommand_RxTimingSetupReqValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e MACCommand_ResetConfValidationError) ErrorName() string {
- return "MACCommand_ResetConfValidationError"
+func (e MACCommand_RxTimingSetupReqValidationError) ErrorName() string {
+ return "MACCommand_RxTimingSetupReqValidationError"
}
// Error satisfies the builtin error interface
-func (e MACCommand_ResetConfValidationError) Error() string {
+func (e MACCommand_RxTimingSetupReqValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -4278,14 +6490,14 @@ func (e MACCommand_ResetConfValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sMACCommand_ResetConf.%s: %s%s",
+ "invalid %sMACCommand_RxTimingSetupReq.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = MACCommand_ResetConfValidationError{}
+var _ error = MACCommand_RxTimingSetupReqValidationError{}
var _ interface {
Field() string
@@ -4293,47 +6505,38 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = MACCommand_ResetConfValidationError{}
-
-var _MACCommand_ResetConf_MinorVersion_InLookup = map[Minor]struct{}{
- 1: {},
-}
+} = MACCommand_RxTimingSetupReqValidationError{}
-// ValidateFields checks the field values on MACCommand_LinkCheckAns with the
-// rules defined in the proto definition for this message. If any rules are
-// violated, an error is returned.
-func (m *MACCommand_LinkCheckAns) ValidateFields(paths ...string) error {
+// ValidateFields checks the field values on MACCommand_TxParamSetupReq with
+// the rules defined in the proto definition for this message. If any rules
+// are violated, an error is returned.
+func (m *MACCommand_TxParamSetupReq) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = MACCommand_LinkCheckAnsFieldPathsNested
+ paths = MACCommand_TxParamSetupReqFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "margin":
-
- if m.GetMargin() > 254 {
- return MACCommand_LinkCheckAnsValidationError{
- field: "margin",
- reason: "value must be less than or equal to 254",
- }
- }
-
- case "gateway_count":
+ case "max_eirp_index":
- if m.GetGatewayCount() > 255 {
- return MACCommand_LinkCheckAnsValidationError{
- field: "gateway_count",
- reason: "value must be less than or equal to 255",
+ if _, ok := DeviceEIRP_name[int32(m.GetMaxEirpIndex())]; !ok {
+ return MACCommand_TxParamSetupReqValidationError{
+ field: "max_eirp_index",
+ reason: "value must be one of the defined enum values",
}
}
+ case "uplink_dwell_time":
+ // no validation rules for UplinkDwellTime
+ case "downlink_dwell_time":
+ // no validation rules for DownlinkDwellTime
default:
- return MACCommand_LinkCheckAnsValidationError{
+ return MACCommand_TxParamSetupReqValidationError{
field: name,
reason: "invalid field path",
}
@@ -4342,9 +6545,10 @@ func (m *MACCommand_LinkCheckAns) ValidateFields(paths ...string) error {
return nil
}
-// MACCommand_LinkCheckAnsValidationError is the validation error returned by
-// MACCommand_LinkCheckAns.ValidateFields if the designated constraints aren't met.
-type MACCommand_LinkCheckAnsValidationError struct {
+// MACCommand_TxParamSetupReqValidationError is the validation error returned
+// by MACCommand_TxParamSetupReq.ValidateFields if the designated constraints
+// aren't met.
+type MACCommand_TxParamSetupReqValidationError struct {
field string
reason string
cause error
@@ -4352,24 +6556,24 @@ type MACCommand_LinkCheckAnsValidationError struct {
}
// Field function returns field value.
-func (e MACCommand_LinkCheckAnsValidationError) Field() string { return e.field }
+func (e MACCommand_TxParamSetupReqValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e MACCommand_LinkCheckAnsValidationError) Reason() string { return e.reason }
+func (e MACCommand_TxParamSetupReqValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e MACCommand_LinkCheckAnsValidationError) Cause() error { return e.cause }
+func (e MACCommand_TxParamSetupReqValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e MACCommand_LinkCheckAnsValidationError) Key() bool { return e.key }
+func (e MACCommand_TxParamSetupReqValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e MACCommand_LinkCheckAnsValidationError) ErrorName() string {
- return "MACCommand_LinkCheckAnsValidationError"
+func (e MACCommand_TxParamSetupReqValidationError) ErrorName() string {
+ return "MACCommand_TxParamSetupReqValidationError"
}
// Error satisfies the builtin error interface
-func (e MACCommand_LinkCheckAnsValidationError) Error() string {
+func (e MACCommand_TxParamSetupReqValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -4381,14 +6585,14 @@ func (e MACCommand_LinkCheckAnsValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sMACCommand_LinkCheckAns.%s: %s%s",
+ "invalid %sMACCommand_TxParamSetupReq.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = MACCommand_LinkCheckAnsValidationError{}
+var _ error = MACCommand_TxParamSetupReqValidationError{}
var _ interface {
Field() string
@@ -4396,70 +6600,34 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = MACCommand_LinkCheckAnsValidationError{}
+} = MACCommand_TxParamSetupReqValidationError{}
-// ValidateFields checks the field values on MACCommand_LinkADRReq with the
-// rules defined in the proto definition for this message. If any rules are
+// ValidateFields checks the field values on MACCommand_RekeyInd with the rules
+// defined in the proto definition for this message. If any rules are
// violated, an error is returned.
-func (m *MACCommand_LinkADRReq) ValidateFields(paths ...string) error {
+func (m *MACCommand_RekeyInd) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = MACCommand_LinkADRReqFieldPathsNested
+ paths = MACCommand_RekeyIndFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "data_rate_index":
+ case "minor_version":
- if _, ok := DataRateIndex_name[int32(m.GetDataRateIndex())]; !ok {
- return MACCommand_LinkADRReqValidationError{
- field: "data_rate_index",
+ if _, ok := Minor_name[int32(m.GetMinorVersion())]; !ok {
+ return MACCommand_RekeyIndValidationError{
+ field: "minor_version",
reason: "value must be one of the defined enum values",
}
}
- case "tx_power_index":
-
- if m.GetTxPowerIndex() > 15 {
- return MACCommand_LinkADRReqValidationError{
- field: "tx_power_index",
- reason: "value must be less than or equal to 15",
- }
- }
-
- case "channel_mask":
-
- if len(m.GetChannelMask()) > 16 {
- return MACCommand_LinkADRReqValidationError{
- field: "channel_mask",
- reason: "value must contain no more than 16 item(s)",
- }
- }
-
- case "channel_mask_control":
-
- if m.GetChannelMaskControl() > 7 {
- return MACCommand_LinkADRReqValidationError{
- field: "channel_mask_control",
- reason: "value must be less than or equal to 7",
- }
- }
-
- case "nb_trans":
-
- if m.GetNbTrans() > 15 {
- return MACCommand_LinkADRReqValidationError{
- field: "nb_trans",
- reason: "value must be less than or equal to 15",
- }
- }
-
default:
- return MACCommand_LinkADRReqValidationError{
+ return MACCommand_RekeyIndValidationError{
field: name,
reason: "invalid field path",
}
@@ -4468,9 +6636,9 @@ func (m *MACCommand_LinkADRReq) ValidateFields(paths ...string) error {
return nil
}
-// MACCommand_LinkADRReqValidationError is the validation error returned by
-// MACCommand_LinkADRReq.ValidateFields if the designated constraints aren't met.
-type MACCommand_LinkADRReqValidationError struct {
+// MACCommand_RekeyIndValidationError is the validation error returned by
+// MACCommand_RekeyInd.ValidateFields if the designated constraints aren't met.
+type MACCommand_RekeyIndValidationError struct {
field string
reason string
cause error
@@ -4478,24 +6646,24 @@ type MACCommand_LinkADRReqValidationError struct {
}
// Field function returns field value.
-func (e MACCommand_LinkADRReqValidationError) Field() string { return e.field }
+func (e MACCommand_RekeyIndValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e MACCommand_LinkADRReqValidationError) Reason() string { return e.reason }
+func (e MACCommand_RekeyIndValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e MACCommand_LinkADRReqValidationError) Cause() error { return e.cause }
+func (e MACCommand_RekeyIndValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e MACCommand_LinkADRReqValidationError) Key() bool { return e.key }
+func (e MACCommand_RekeyIndValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e MACCommand_LinkADRReqValidationError) ErrorName() string {
- return "MACCommand_LinkADRReqValidationError"
+func (e MACCommand_RekeyIndValidationError) ErrorName() string {
+ return "MACCommand_RekeyIndValidationError"
}
// Error satisfies the builtin error interface
-func (e MACCommand_LinkADRReqValidationError) Error() string {
+func (e MACCommand_RekeyIndValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -4507,14 +6675,14 @@ func (e MACCommand_LinkADRReqValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sMACCommand_LinkADRReq.%s: %s%s",
+ "invalid %sMACCommand_RekeyInd.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = MACCommand_LinkADRReqValidationError{}
+var _ error = MACCommand_RekeyIndValidationError{}
var _ interface {
Field() string
@@ -4522,31 +6690,34 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = MACCommand_LinkADRReqValidationError{}
+} = MACCommand_RekeyIndValidationError{}
-// ValidateFields checks the field values on MACCommand_LinkADRAns with the
+// ValidateFields checks the field values on MACCommand_RekeyConf with the
// rules defined in the proto definition for this message. If any rules are
// violated, an error is returned.
-func (m *MACCommand_LinkADRAns) ValidateFields(paths ...string) error {
+func (m *MACCommand_RekeyConf) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = MACCommand_LinkADRAnsFieldPathsNested
+ paths = MACCommand_RekeyConfFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "channel_mask_ack":
- // no validation rules for ChannelMaskAck
- case "data_rate_index_ack":
- // no validation rules for DataRateIndexAck
- case "tx_power_index_ack":
- // no validation rules for TxPowerIndexAck
+ case "minor_version":
+
+ if _, ok := Minor_name[int32(m.GetMinorVersion())]; !ok {
+ return MACCommand_RekeyConfValidationError{
+ field: "minor_version",
+ reason: "value must be one of the defined enum values",
+ }
+ }
+
default:
- return MACCommand_LinkADRAnsValidationError{
+ return MACCommand_RekeyConfValidationError{
field: name,
reason: "invalid field path",
}
@@ -4555,9 +6726,9 @@ func (m *MACCommand_LinkADRAns) ValidateFields(paths ...string) error {
return nil
}
-// MACCommand_LinkADRAnsValidationError is the validation error returned by
-// MACCommand_LinkADRAns.ValidateFields if the designated constraints aren't met.
-type MACCommand_LinkADRAnsValidationError struct {
+// MACCommand_RekeyConfValidationError is the validation error returned by
+// MACCommand_RekeyConf.ValidateFields if the designated constraints aren't met.
+type MACCommand_RekeyConfValidationError struct {
field string
reason string
cause error
@@ -4565,24 +6736,24 @@ type MACCommand_LinkADRAnsValidationError struct {
}
// Field function returns field value.
-func (e MACCommand_LinkADRAnsValidationError) Field() string { return e.field }
+func (e MACCommand_RekeyConfValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e MACCommand_LinkADRAnsValidationError) Reason() string { return e.reason }
+func (e MACCommand_RekeyConfValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e MACCommand_LinkADRAnsValidationError) Cause() error { return e.cause }
+func (e MACCommand_RekeyConfValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e MACCommand_LinkADRAnsValidationError) Key() bool { return e.key }
+func (e MACCommand_RekeyConfValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e MACCommand_LinkADRAnsValidationError) ErrorName() string {
- return "MACCommand_LinkADRAnsValidationError"
+func (e MACCommand_RekeyConfValidationError) ErrorName() string {
+ return "MACCommand_RekeyConfValidationError"
}
// Error satisfies the builtin error interface
-func (e MACCommand_LinkADRAnsValidationError) Error() string {
+func (e MACCommand_RekeyConfValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -4594,14 +6765,14 @@ func (e MACCommand_LinkADRAnsValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sMACCommand_LinkADRAns.%s: %s%s",
+ "invalid %sMACCommand_RekeyConf.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = MACCommand_LinkADRAnsValidationError{}
+var _ error = MACCommand_RekeyConfValidationError{}
var _ interface {
Field() string
@@ -4609,34 +6780,43 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = MACCommand_LinkADRAnsValidationError{}
+} = MACCommand_RekeyConfValidationError{}
-// ValidateFields checks the field values on MACCommand_DutyCycleReq with the
-// rules defined in the proto definition for this message. If any rules are
-// violated, an error is returned.
-func (m *MACCommand_DutyCycleReq) ValidateFields(paths ...string) error {
+// ValidateFields checks the field values on MACCommand_ADRParamSetupReq with
+// the rules defined in the proto definition for this message. If any rules
+// are violated, an error is returned.
+func (m *MACCommand_ADRParamSetupReq) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = MACCommand_DutyCycleReqFieldPathsNested
+ paths = MACCommand_ADRParamSetupReqFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "max_duty_cycle":
+ case "adr_ack_limit_exponent":
- if _, ok := AggregatedDutyCycle_name[int32(m.GetMaxDutyCycle())]; !ok {
- return MACCommand_DutyCycleReqValidationError{
- field: "max_duty_cycle",
+ if _, ok := ADRAckLimitExponent_name[int32(m.GetAdrAckLimitExponent())]; !ok {
+ return MACCommand_ADRParamSetupReqValidationError{
+ field: "adr_ack_limit_exponent",
+ reason: "value must be one of the defined enum values",
+ }
+ }
+
+ case "adr_ack_delay_exponent":
+
+ if _, ok := ADRAckDelayExponent_name[int32(m.GetAdrAckDelayExponent())]; !ok {
+ return MACCommand_ADRParamSetupReqValidationError{
+ field: "adr_ack_delay_exponent",
reason: "value must be one of the defined enum values",
}
}
default:
- return MACCommand_DutyCycleReqValidationError{
+ return MACCommand_ADRParamSetupReqValidationError{
field: name,
reason: "invalid field path",
}
@@ -4645,9 +6825,10 @@ func (m *MACCommand_DutyCycleReq) ValidateFields(paths ...string) error {
return nil
}
-// MACCommand_DutyCycleReqValidationError is the validation error returned by
-// MACCommand_DutyCycleReq.ValidateFields if the designated constraints aren't met.
-type MACCommand_DutyCycleReqValidationError struct {
+// MACCommand_ADRParamSetupReqValidationError is the validation error returned
+// by MACCommand_ADRParamSetupReq.ValidateFields if the designated constraints
+// aren't met.
+type MACCommand_ADRParamSetupReqValidationError struct {
field string
reason string
cause error
@@ -4655,24 +6836,24 @@ type MACCommand_DutyCycleReqValidationError struct {
}
// Field function returns field value.
-func (e MACCommand_DutyCycleReqValidationError) Field() string { return e.field }
+func (e MACCommand_ADRParamSetupReqValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e MACCommand_DutyCycleReqValidationError) Reason() string { return e.reason }
+func (e MACCommand_ADRParamSetupReqValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e MACCommand_DutyCycleReqValidationError) Cause() error { return e.cause }
+func (e MACCommand_ADRParamSetupReqValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e MACCommand_DutyCycleReqValidationError) Key() bool { return e.key }
+func (e MACCommand_ADRParamSetupReqValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e MACCommand_DutyCycleReqValidationError) ErrorName() string {
- return "MACCommand_DutyCycleReqValidationError"
+func (e MACCommand_ADRParamSetupReqValidationError) ErrorName() string {
+ return "MACCommand_ADRParamSetupReqValidationError"
}
// Error satisfies the builtin error interface
-func (e MACCommand_DutyCycleReqValidationError) Error() string {
+func (e MACCommand_ADRParamSetupReqValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -4684,14 +6865,14 @@ func (e MACCommand_DutyCycleReqValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sMACCommand_DutyCycleReq.%s: %s%s",
+ "invalid %sMACCommand_ADRParamSetupReq.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = MACCommand_DutyCycleReqValidationError{}
+var _ error = MACCommand_ADRParamSetupReqValidationError{}
var _ interface {
Field() string
@@ -4699,52 +6880,34 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = MACCommand_DutyCycleReqValidationError{}
+} = MACCommand_ADRParamSetupReqValidationError{}
-// ValidateFields checks the field values on MACCommand_RxParamSetupReq with
-// the rules defined in the proto definition for this message. If any rules
-// are violated, an error is returned.
-func (m *MACCommand_RxParamSetupReq) ValidateFields(paths ...string) error {
+// ValidateFields checks the field values on MACCommand_DeviceTimeAns with the
+// rules defined in the proto definition for this message. If any rules are
+// violated, an error is returned.
+func (m *MACCommand_DeviceTimeAns) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = MACCommand_RxParamSetupReqFieldPathsNested
+ paths = MACCommand_DeviceTimeAnsFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "rx2_data_rate_index":
-
- if _, ok := DataRateIndex_name[int32(m.GetRx2DataRateIndex())]; !ok {
- return MACCommand_RxParamSetupReqValidationError{
- field: "rx2_data_rate_index",
- reason: "value must be one of the defined enum values",
- }
- }
-
- case "rx1_data_rate_offset":
-
- if _, ok := DataRateOffset_name[int32(m.GetRx1DataRateOffset())]; !ok {
- return MACCommand_RxParamSetupReqValidationError{
- field: "rx1_data_rate_offset",
- reason: "value must be one of the defined enum values",
- }
- }
-
- case "rx2_frequency":
+ case "time":
- if m.GetRx2Frequency() < 100000 {
- return MACCommand_RxParamSetupReqValidationError{
- field: "rx2_frequency",
- reason: "value must be greater than or equal to 100000",
+ if m.GetTime() == nil {
+ return MACCommand_DeviceTimeAnsValidationError{
+ field: "time",
+ reason: "value is required",
}
}
default:
- return MACCommand_RxParamSetupReqValidationError{
+ return MACCommand_DeviceTimeAnsValidationError{
field: name,
reason: "invalid field path",
}
@@ -4753,10 +6916,10 @@ func (m *MACCommand_RxParamSetupReq) ValidateFields(paths ...string) error {
return nil
}
-// MACCommand_RxParamSetupReqValidationError is the validation error returned
-// by MACCommand_RxParamSetupReq.ValidateFields if the designated constraints
+// MACCommand_DeviceTimeAnsValidationError is the validation error returned by
+// MACCommand_DeviceTimeAns.ValidateFields if the designated constraints
// aren't met.
-type MACCommand_RxParamSetupReqValidationError struct {
+type MACCommand_DeviceTimeAnsValidationError struct {
field string
reason string
cause error
@@ -4764,24 +6927,24 @@ type MACCommand_RxParamSetupReqValidationError struct {
}
// Field function returns field value.
-func (e MACCommand_RxParamSetupReqValidationError) Field() string { return e.field }
+func (e MACCommand_DeviceTimeAnsValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e MACCommand_RxParamSetupReqValidationError) Reason() string { return e.reason }
+func (e MACCommand_DeviceTimeAnsValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e MACCommand_RxParamSetupReqValidationError) Cause() error { return e.cause }
+func (e MACCommand_DeviceTimeAnsValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e MACCommand_RxParamSetupReqValidationError) Key() bool { return e.key }
+func (e MACCommand_DeviceTimeAnsValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e MACCommand_RxParamSetupReqValidationError) ErrorName() string {
- return "MACCommand_RxParamSetupReqValidationError"
+func (e MACCommand_DeviceTimeAnsValidationError) ErrorName() string {
+ return "MACCommand_DeviceTimeAnsValidationError"
}
// Error satisfies the builtin error interface
-func (e MACCommand_RxParamSetupReqValidationError) Error() string {
+func (e MACCommand_DeviceTimeAnsValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -4793,14 +6956,14 @@ func (e MACCommand_RxParamSetupReqValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sMACCommand_RxParamSetupReq.%s: %s%s",
+ "invalid %sMACCommand_DeviceTimeAns.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = MACCommand_RxParamSetupReqValidationError{}
+var _ error = MACCommand_DeviceTimeAnsValidationError{}
var _ interface {
Field() string
@@ -4808,31 +6971,61 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = MACCommand_RxParamSetupReqValidationError{}
+} = MACCommand_DeviceTimeAnsValidationError{}
-// ValidateFields checks the field values on MACCommand_RxParamSetupAns with
-// the rules defined in the proto definition for this message. If any rules
-// are violated, an error is returned.
-func (m *MACCommand_RxParamSetupAns) ValidateFields(paths ...string) error {
+// ValidateFields checks the field values on MACCommand_ForceRejoinReq with the
+// rules defined in the proto definition for this message. If any rules are
+// violated, an error is returned.
+func (m *MACCommand_ForceRejoinReq) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = MACCommand_RxParamSetupAnsFieldPathsNested
+ paths = MACCommand_ForceRejoinReqFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "rx2_data_rate_index_ack":
- // no validation rules for Rx2DataRateIndexAck
- case "rx1_data_rate_offset_ack":
- // no validation rules for Rx1DataRateOffsetAck
- case "rx2_frequency_ack":
- // no validation rules for Rx2FrequencyAck
+ case "rejoin_type":
+
+ if _, ok := RejoinRequestType_name[int32(m.GetRejoinType())]; !ok {
+ return MACCommand_ForceRejoinReqValidationError{
+ field: "rejoin_type",
+ reason: "value must be one of the defined enum values",
+ }
+ }
+
+ case "data_rate_index":
+
+ if _, ok := DataRateIndex_name[int32(m.GetDataRateIndex())]; !ok {
+ return MACCommand_ForceRejoinReqValidationError{
+ field: "data_rate_index",
+ reason: "value must be one of the defined enum values",
+ }
+ }
+
+ case "max_retries":
+
+ if m.GetMaxRetries() > 7 {
+ return MACCommand_ForceRejoinReqValidationError{
+ field: "max_retries",
+ reason: "value must be less than or equal to 7",
+ }
+ }
+
+ case "period_exponent":
+
+ if _, ok := RejoinPeriodExponent_name[int32(m.GetPeriodExponent())]; !ok {
+ return MACCommand_ForceRejoinReqValidationError{
+ field: "period_exponent",
+ reason: "value must be one of the defined enum values",
+ }
+ }
+
default:
- return MACCommand_RxParamSetupAnsValidationError{
+ return MACCommand_ForceRejoinReqValidationError{
field: name,
reason: "invalid field path",
}
@@ -4841,10 +7034,10 @@ func (m *MACCommand_RxParamSetupAns) ValidateFields(paths ...string) error {
return nil
}
-// MACCommand_RxParamSetupAnsValidationError is the validation error returned
-// by MACCommand_RxParamSetupAns.ValidateFields if the designated constraints
+// MACCommand_ForceRejoinReqValidationError is the validation error returned by
+// MACCommand_ForceRejoinReq.ValidateFields if the designated constraints
// aren't met.
-type MACCommand_RxParamSetupAnsValidationError struct {
+type MACCommand_ForceRejoinReqValidationError struct {
field string
reason string
cause error
@@ -4852,24 +7045,24 @@ type MACCommand_RxParamSetupAnsValidationError struct {
}
// Field function returns field value.
-func (e MACCommand_RxParamSetupAnsValidationError) Field() string { return e.field }
+func (e MACCommand_ForceRejoinReqValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e MACCommand_RxParamSetupAnsValidationError) Reason() string { return e.reason }
+func (e MACCommand_ForceRejoinReqValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e MACCommand_RxParamSetupAnsValidationError) Cause() error { return e.cause }
+func (e MACCommand_ForceRejoinReqValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e MACCommand_RxParamSetupAnsValidationError) Key() bool { return e.key }
+func (e MACCommand_ForceRejoinReqValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e MACCommand_RxParamSetupAnsValidationError) ErrorName() string {
- return "MACCommand_RxParamSetupAnsValidationError"
+func (e MACCommand_ForceRejoinReqValidationError) ErrorName() string {
+ return "MACCommand_ForceRejoinReqValidationError"
}
// Error satisfies the builtin error interface
-func (e MACCommand_RxParamSetupAnsValidationError) Error() string {
+func (e MACCommand_ForceRejoinReqValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -4881,14 +7074,14 @@ func (e MACCommand_RxParamSetupAnsValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sMACCommand_RxParamSetupAns.%s: %s%s",
+ "invalid %sMACCommand_ForceRejoinReq.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = MACCommand_RxParamSetupAnsValidationError{}
+var _ error = MACCommand_ForceRejoinReqValidationError{}
var _ interface {
Field() string
@@ -4896,43 +7089,43 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = MACCommand_RxParamSetupAnsValidationError{}
+} = MACCommand_ForceRejoinReqValidationError{}
-// ValidateFields checks the field values on MACCommand_DevStatusAns with the
-// rules defined in the proto definition for this message. If any rules are
-// violated, an error is returned.
-func (m *MACCommand_DevStatusAns) ValidateFields(paths ...string) error {
+// ValidateFields checks the field values on MACCommand_RejoinParamSetupReq
+// with the rules defined in the proto definition for this message. If any
+// rules are violated, an error is returned.
+func (m *MACCommand_RejoinParamSetupReq) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = MACCommand_DevStatusAnsFieldPathsNested
+ paths = MACCommand_RejoinParamSetupReqFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "battery":
+ case "max_count_exponent":
- if m.GetBattery() > 255 {
- return MACCommand_DevStatusAnsValidationError{
- field: "battery",
- reason: "value must be less than or equal to 255",
+ if _, ok := RejoinCountExponent_name[int32(m.GetMaxCountExponent())]; !ok {
+ return MACCommand_RejoinParamSetupReqValidationError{
+ field: "max_count_exponent",
+ reason: "value must be one of the defined enum values",
}
}
- case "margin":
+ case "max_time_exponent":
- if val := m.GetMargin(); val < -32 || val > 31 {
- return MACCommand_DevStatusAnsValidationError{
- field: "margin",
- reason: "value must be inside range [-32, 31]",
+ if _, ok := RejoinTimeExponent_name[int32(m.GetMaxTimeExponent())]; !ok {
+ return MACCommand_RejoinParamSetupReqValidationError{
+ field: "max_time_exponent",
+ reason: "value must be one of the defined enum values",
}
}
default:
- return MACCommand_DevStatusAnsValidationError{
+ return MACCommand_RejoinParamSetupReqValidationError{
field: name,
reason: "invalid field path",
}
@@ -4941,9 +7134,10 @@ func (m *MACCommand_DevStatusAns) ValidateFields(paths ...string) error {
return nil
}
-// MACCommand_DevStatusAnsValidationError is the validation error returned by
-// MACCommand_DevStatusAns.ValidateFields if the designated constraints aren't met.
-type MACCommand_DevStatusAnsValidationError struct {
+// MACCommand_RejoinParamSetupReqValidationError is the validation error
+// returned by MACCommand_RejoinParamSetupReq.ValidateFields if the designated
+// constraints aren't met.
+type MACCommand_RejoinParamSetupReqValidationError struct {
field string
reason string
cause error
@@ -4951,24 +7145,24 @@ type MACCommand_DevStatusAnsValidationError struct {
}
// Field function returns field value.
-func (e MACCommand_DevStatusAnsValidationError) Field() string { return e.field }
+func (e MACCommand_RejoinParamSetupReqValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e MACCommand_DevStatusAnsValidationError) Reason() string { return e.reason }
+func (e MACCommand_RejoinParamSetupReqValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e MACCommand_DevStatusAnsValidationError) Cause() error { return e.cause }
+func (e MACCommand_RejoinParamSetupReqValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e MACCommand_DevStatusAnsValidationError) Key() bool { return e.key }
+func (e MACCommand_RejoinParamSetupReqValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e MACCommand_DevStatusAnsValidationError) ErrorName() string {
- return "MACCommand_DevStatusAnsValidationError"
+func (e MACCommand_RejoinParamSetupReqValidationError) ErrorName() string {
+ return "MACCommand_RejoinParamSetupReqValidationError"
}
// Error satisfies the builtin error interface
-func (e MACCommand_DevStatusAnsValidationError) Error() string {
+func (e MACCommand_RejoinParamSetupReqValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -4980,14 +7174,14 @@ func (e MACCommand_DevStatusAnsValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sMACCommand_DevStatusAns.%s: %s%s",
+ "invalid %sMACCommand_RejoinParamSetupReq.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = MACCommand_DevStatusAnsValidationError{}
+var _ error = MACCommand_RejoinParamSetupReqValidationError{}
var _ interface {
Field() string
@@ -4995,61 +7189,27 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = MACCommand_DevStatusAnsValidationError{}
+} = MACCommand_RejoinParamSetupReqValidationError{}
-// ValidateFields checks the field values on MACCommand_NewChannelReq with the
-// rules defined in the proto definition for this message. If any rules are
-// violated, an error is returned.
-func (m *MACCommand_NewChannelReq) ValidateFields(paths ...string) error {
+// ValidateFields checks the field values on MACCommand_RejoinParamSetupAns
+// with the rules defined in the proto definition for this message. If any
+// rules are violated, an error is returned.
+func (m *MACCommand_RejoinParamSetupAns) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
- if len(paths) == 0 {
- paths = MACCommand_NewChannelReqFieldPathsNested
- }
-
- for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
- _ = subs
- switch name {
- case "channel_index":
-
- if m.GetChannelIndex() > 255 {
- return MACCommand_NewChannelReqValidationError{
- field: "channel_index",
- reason: "value must be less than or equal to 255",
- }
- }
-
- case "frequency":
-
- if val := m.GetFrequency(); val > 0 && val < 100000 {
- return MACCommand_NewChannelReqValidationError{
- field: "frequency",
- reason: "value must be outside range (0, 100000)",
- }
- }
-
- case "min_data_rate_index":
-
- if _, ok := DataRateIndex_name[int32(m.GetMinDataRateIndex())]; !ok {
- return MACCommand_NewChannelReqValidationError{
- field: "min_data_rate_index",
- reason: "value must be one of the defined enum values",
- }
- }
-
- case "max_data_rate_index":
-
- if _, ok := DataRateIndex_name[int32(m.GetMaxDataRateIndex())]; !ok {
- return MACCommand_NewChannelReqValidationError{
- field: "max_data_rate_index",
- reason: "value must be one of the defined enum values",
- }
- }
+ if len(paths) == 0 {
+ paths = MACCommand_RejoinParamSetupAnsFieldPathsNested
+ }
+ for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
+ _ = subs
+ switch name {
+ case "max_time_exponent_ack":
+ // no validation rules for MaxTimeExponentAck
default:
- return MACCommand_NewChannelReqValidationError{
+ return MACCommand_RejoinParamSetupAnsValidationError{
field: name,
reason: "invalid field path",
}
@@ -5058,10 +7218,10 @@ func (m *MACCommand_NewChannelReq) ValidateFields(paths ...string) error {
return nil
}
-// MACCommand_NewChannelReqValidationError is the validation error returned by
-// MACCommand_NewChannelReq.ValidateFields if the designated constraints
-// aren't met.
-type MACCommand_NewChannelReqValidationError struct {
+// MACCommand_RejoinParamSetupAnsValidationError is the validation error
+// returned by MACCommand_RejoinParamSetupAns.ValidateFields if the designated
+// constraints aren't met.
+type MACCommand_RejoinParamSetupAnsValidationError struct {
field string
reason string
cause error
@@ -5069,24 +7229,24 @@ type MACCommand_NewChannelReqValidationError struct {
}
// Field function returns field value.
-func (e MACCommand_NewChannelReqValidationError) Field() string { return e.field }
+func (e MACCommand_RejoinParamSetupAnsValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e MACCommand_NewChannelReqValidationError) Reason() string { return e.reason }
+func (e MACCommand_RejoinParamSetupAnsValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e MACCommand_NewChannelReqValidationError) Cause() error { return e.cause }
+func (e MACCommand_RejoinParamSetupAnsValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e MACCommand_NewChannelReqValidationError) Key() bool { return e.key }
+func (e MACCommand_RejoinParamSetupAnsValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e MACCommand_NewChannelReqValidationError) ErrorName() string {
- return "MACCommand_NewChannelReqValidationError"
+func (e MACCommand_RejoinParamSetupAnsValidationError) ErrorName() string {
+ return "MACCommand_RejoinParamSetupAnsValidationError"
}
// Error satisfies the builtin error interface
-func (e MACCommand_NewChannelReqValidationError) Error() string {
+func (e MACCommand_RejoinParamSetupAnsValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -5098,14 +7258,14 @@ func (e MACCommand_NewChannelReqValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sMACCommand_NewChannelReq.%s: %s%s",
+ "invalid %sMACCommand_RejoinParamSetupAns.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = MACCommand_NewChannelReqValidationError{}
+var _ error = MACCommand_RejoinParamSetupAnsValidationError{}
var _ interface {
Field() string
@@ -5113,29 +7273,34 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = MACCommand_NewChannelReqValidationError{}
+} = MACCommand_RejoinParamSetupAnsValidationError{}
-// ValidateFields checks the field values on MACCommand_NewChannelAns with the
-// rules defined in the proto definition for this message. If any rules are
-// violated, an error is returned.
-func (m *MACCommand_NewChannelAns) ValidateFields(paths ...string) error {
+// ValidateFields checks the field values on MACCommand_PingSlotInfoReq with
+// the rules defined in the proto definition for this message. If any rules
+// are violated, an error is returned.
+func (m *MACCommand_PingSlotInfoReq) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = MACCommand_NewChannelAnsFieldPathsNested
+ paths = MACCommand_PingSlotInfoReqFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "frequency_ack":
- // no validation rules for FrequencyAck
- case "data_rate_ack":
- // no validation rules for DataRateAck
+ case "period":
+
+ if _, ok := PingSlotPeriod_name[int32(m.GetPeriod())]; !ok {
+ return MACCommand_PingSlotInfoReqValidationError{
+ field: "period",
+ reason: "value must be one of the defined enum values",
+ }
+ }
+
default:
- return MACCommand_NewChannelAnsValidationError{
+ return MACCommand_PingSlotInfoReqValidationError{
field: name,
reason: "invalid field path",
}
@@ -5144,10 +7309,10 @@ func (m *MACCommand_NewChannelAns) ValidateFields(paths ...string) error {
return nil
}
-// MACCommand_NewChannelAnsValidationError is the validation error returned by
-// MACCommand_NewChannelAns.ValidateFields if the designated constraints
+// MACCommand_PingSlotInfoReqValidationError is the validation error returned
+// by MACCommand_PingSlotInfoReq.ValidateFields if the designated constraints
// aren't met.
-type MACCommand_NewChannelAnsValidationError struct {
+type MACCommand_PingSlotInfoReqValidationError struct {
field string
reason string
cause error
@@ -5155,24 +7320,24 @@ type MACCommand_NewChannelAnsValidationError struct {
}
// Field function returns field value.
-func (e MACCommand_NewChannelAnsValidationError) Field() string { return e.field }
+func (e MACCommand_PingSlotInfoReqValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e MACCommand_NewChannelAnsValidationError) Reason() string { return e.reason }
+func (e MACCommand_PingSlotInfoReqValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e MACCommand_NewChannelAnsValidationError) Cause() error { return e.cause }
+func (e MACCommand_PingSlotInfoReqValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e MACCommand_NewChannelAnsValidationError) Key() bool { return e.key }
+func (e MACCommand_PingSlotInfoReqValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e MACCommand_NewChannelAnsValidationError) ErrorName() string {
- return "MACCommand_NewChannelAnsValidationError"
+func (e MACCommand_PingSlotInfoReqValidationError) ErrorName() string {
+ return "MACCommand_PingSlotInfoReqValidationError"
}
// Error satisfies the builtin error interface
-func (e MACCommand_NewChannelAnsValidationError) Error() string {
+func (e MACCommand_PingSlotInfoReqValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -5184,14 +7349,14 @@ func (e MACCommand_NewChannelAnsValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sMACCommand_NewChannelAns.%s: %s%s",
+ "invalid %sMACCommand_PingSlotInfoReq.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = MACCommand_NewChannelAnsValidationError{}
+var _ error = MACCommand_PingSlotInfoReqValidationError{}
var _ interface {
Field() string
@@ -5199,43 +7364,43 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = MACCommand_NewChannelAnsValidationError{}
+} = MACCommand_PingSlotInfoReqValidationError{}
-// ValidateFields checks the field values on MACCommand_DLChannelReq with the
-// rules defined in the proto definition for this message. If any rules are
-// violated, an error is returned.
-func (m *MACCommand_DLChannelReq) ValidateFields(paths ...string) error {
+// ValidateFields checks the field values on MACCommand_PingSlotChannelReq with
+// the rules defined in the proto definition for this message. If any rules
+// are violated, an error is returned.
+func (m *MACCommand_PingSlotChannelReq) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = MACCommand_DLChannelReqFieldPathsNested
+ paths = MACCommand_PingSlotChannelReqFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "channel_index":
+ case "frequency":
- if m.GetChannelIndex() > 255 {
- return MACCommand_DLChannelReqValidationError{
- field: "channel_index",
- reason: "value must be less than or equal to 255",
+ if val := m.GetFrequency(); val > 0 && val < 100000 {
+ return MACCommand_PingSlotChannelReqValidationError{
+ field: "frequency",
+ reason: "value must be outside range (0, 100000)",
}
}
- case "frequency":
+ case "data_rate_index":
- if m.GetFrequency() < 100000 {
- return MACCommand_DLChannelReqValidationError{
- field: "frequency",
- reason: "value must be greater than or equal to 100000",
+ if _, ok := DataRateIndex_name[int32(m.GetDataRateIndex())]; !ok {
+ return MACCommand_PingSlotChannelReqValidationError{
+ field: "data_rate_index",
+ reason: "value must be one of the defined enum values",
}
}
default:
- return MACCommand_DLChannelReqValidationError{
+ return MACCommand_PingSlotChannelReqValidationError{
field: name,
reason: "invalid field path",
}
@@ -5244,9 +7409,10 @@ func (m *MACCommand_DLChannelReq) ValidateFields(paths ...string) error {
return nil
}
-// MACCommand_DLChannelReqValidationError is the validation error returned by
-// MACCommand_DLChannelReq.ValidateFields if the designated constraints aren't met.
-type MACCommand_DLChannelReqValidationError struct {
+// MACCommand_PingSlotChannelReqValidationError is the validation error
+// returned by MACCommand_PingSlotChannelReq.ValidateFields if the designated
+// constraints aren't met.
+type MACCommand_PingSlotChannelReqValidationError struct {
field string
reason string
cause error
@@ -5254,24 +7420,24 @@ type MACCommand_DLChannelReqValidationError struct {
}
// Field function returns field value.
-func (e MACCommand_DLChannelReqValidationError) Field() string { return e.field }
+func (e MACCommand_PingSlotChannelReqValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e MACCommand_DLChannelReqValidationError) Reason() string { return e.reason }
+func (e MACCommand_PingSlotChannelReqValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e MACCommand_DLChannelReqValidationError) Cause() error { return e.cause }
+func (e MACCommand_PingSlotChannelReqValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e MACCommand_DLChannelReqValidationError) Key() bool { return e.key }
+func (e MACCommand_PingSlotChannelReqValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e MACCommand_DLChannelReqValidationError) ErrorName() string {
- return "MACCommand_DLChannelReqValidationError"
+func (e MACCommand_PingSlotChannelReqValidationError) ErrorName() string {
+ return "MACCommand_PingSlotChannelReqValidationError"
}
// Error satisfies the builtin error interface
-func (e MACCommand_DLChannelReqValidationError) Error() string {
+func (e MACCommand_PingSlotChannelReqValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -5283,14 +7449,14 @@ func (e MACCommand_DLChannelReqValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sMACCommand_DLChannelReq.%s: %s%s",
+ "invalid %sMACCommand_PingSlotChannelReq.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = MACCommand_DLChannelReqValidationError{}
+var _ error = MACCommand_PingSlotChannelReqValidationError{}
var _ interface {
Field() string
@@ -5298,29 +7464,29 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = MACCommand_DLChannelReqValidationError{}
+} = MACCommand_PingSlotChannelReqValidationError{}
-// ValidateFields checks the field values on MACCommand_DLChannelAns with the
-// rules defined in the proto definition for this message. If any rules are
-// violated, an error is returned.
-func (m *MACCommand_DLChannelAns) ValidateFields(paths ...string) error {
+// ValidateFields checks the field values on MACCommand_PingSlotChannelAns with
+// the rules defined in the proto definition for this message. If any rules
+// are violated, an error is returned.
+func (m *MACCommand_PingSlotChannelAns) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = MACCommand_DLChannelAnsFieldPathsNested
+ paths = MACCommand_PingSlotChannelAnsFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "channel_index_ack":
- // no validation rules for ChannelIndexAck
case "frequency_ack":
// no validation rules for FrequencyAck
+ case "data_rate_index_ack":
+ // no validation rules for DataRateIndexAck
default:
- return MACCommand_DLChannelAnsValidationError{
+ return MACCommand_PingSlotChannelAnsValidationError{
field: name,
reason: "invalid field path",
}
@@ -5329,9 +7495,10 @@ func (m *MACCommand_DLChannelAns) ValidateFields(paths ...string) error {
return nil
}
-// MACCommand_DLChannelAnsValidationError is the validation error returned by
-// MACCommand_DLChannelAns.ValidateFields if the designated constraints aren't met.
-type MACCommand_DLChannelAnsValidationError struct {
+// MACCommand_PingSlotChannelAnsValidationError is the validation error
+// returned by MACCommand_PingSlotChannelAns.ValidateFields if the designated
+// constraints aren't met.
+type MACCommand_PingSlotChannelAnsValidationError struct {
field string
reason string
cause error
@@ -5339,24 +7506,24 @@ type MACCommand_DLChannelAnsValidationError struct {
}
// Field function returns field value.
-func (e MACCommand_DLChannelAnsValidationError) Field() string { return e.field }
+func (e MACCommand_PingSlotChannelAnsValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e MACCommand_DLChannelAnsValidationError) Reason() string { return e.reason }
+func (e MACCommand_PingSlotChannelAnsValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e MACCommand_DLChannelAnsValidationError) Cause() error { return e.cause }
+func (e MACCommand_PingSlotChannelAnsValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e MACCommand_DLChannelAnsValidationError) Key() bool { return e.key }
+func (e MACCommand_PingSlotChannelAnsValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e MACCommand_DLChannelAnsValidationError) ErrorName() string {
- return "MACCommand_DLChannelAnsValidationError"
+func (e MACCommand_PingSlotChannelAnsValidationError) ErrorName() string {
+ return "MACCommand_PingSlotChannelAnsValidationError"
}
// Error satisfies the builtin error interface
-func (e MACCommand_DLChannelAnsValidationError) Error() string {
+func (e MACCommand_PingSlotChannelAnsValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -5368,14 +7535,14 @@ func (e MACCommand_DLChannelAnsValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sMACCommand_DLChannelAns.%s: %s%s",
+ "invalid %sMACCommand_PingSlotChannelAns.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = MACCommand_DLChannelAnsValidationError{}
+var _ error = MACCommand_PingSlotChannelAnsValidationError{}
var _ interface {
Field() string
@@ -5383,18 +7550,18 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = MACCommand_DLChannelAnsValidationError{}
+} = MACCommand_PingSlotChannelAnsValidationError{}
-// ValidateFields checks the field values on MACCommand_RxTimingSetupReq with
+// ValidateFields checks the field values on MACCommand_BeaconTimingAns with
// the rules defined in the proto definition for this message. If any rules
// are violated, an error is returned.
-func (m *MACCommand_RxTimingSetupReq) ValidateFields(paths ...string) error {
+func (m *MACCommand_BeaconTimingAns) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = MACCommand_RxTimingSetupReqFieldPathsNested
+ paths = MACCommand_BeaconTimingAnsFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
@@ -5402,15 +7569,24 @@ func (m *MACCommand_RxTimingSetupReq) ValidateFields(paths ...string) error {
switch name {
case "delay":
- if _, ok := RxDelay_name[int32(m.GetDelay())]; !ok {
- return MACCommand_RxTimingSetupReqValidationError{
+ if m.GetDelay() > 65535 {
+ return MACCommand_BeaconTimingAnsValidationError{
field: "delay",
- reason: "value must be one of the defined enum values",
+ reason: "value must be less than or equal to 65535",
+ }
+ }
+
+ case "channel_index":
+
+ if m.GetChannelIndex() > 255 {
+ return MACCommand_BeaconTimingAnsValidationError{
+ field: "channel_index",
+ reason: "value must be less than or equal to 255",
}
}
default:
- return MACCommand_RxTimingSetupReqValidationError{
+ return MACCommand_BeaconTimingAnsValidationError{
field: name,
reason: "invalid field path",
}
@@ -5419,10 +7595,10 @@ func (m *MACCommand_RxTimingSetupReq) ValidateFields(paths ...string) error {
return nil
}
-// MACCommand_RxTimingSetupReqValidationError is the validation error returned
-// by MACCommand_RxTimingSetupReq.ValidateFields if the designated constraints
+// MACCommand_BeaconTimingAnsValidationError is the validation error returned
+// by MACCommand_BeaconTimingAns.ValidateFields if the designated constraints
// aren't met.
-type MACCommand_RxTimingSetupReqValidationError struct {
+type MACCommand_BeaconTimingAnsValidationError struct {
field string
reason string
cause error
@@ -5430,24 +7606,24 @@ type MACCommand_RxTimingSetupReqValidationError struct {
}
// Field function returns field value.
-func (e MACCommand_RxTimingSetupReqValidationError) Field() string { return e.field }
+func (e MACCommand_BeaconTimingAnsValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e MACCommand_RxTimingSetupReqValidationError) Reason() string { return e.reason }
+func (e MACCommand_BeaconTimingAnsValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e MACCommand_RxTimingSetupReqValidationError) Cause() error { return e.cause }
+func (e MACCommand_BeaconTimingAnsValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e MACCommand_RxTimingSetupReqValidationError) Key() bool { return e.key }
+func (e MACCommand_BeaconTimingAnsValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e MACCommand_RxTimingSetupReqValidationError) ErrorName() string {
- return "MACCommand_RxTimingSetupReqValidationError"
+func (e MACCommand_BeaconTimingAnsValidationError) ErrorName() string {
+ return "MACCommand_BeaconTimingAnsValidationError"
}
// Error satisfies the builtin error interface
-func (e MACCommand_RxTimingSetupReqValidationError) Error() string {
+func (e MACCommand_BeaconTimingAnsValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -5459,14 +7635,14 @@ func (e MACCommand_RxTimingSetupReqValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sMACCommand_RxTimingSetupReq.%s: %s%s",
+ "invalid %sMACCommand_BeaconTimingAns.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = MACCommand_RxTimingSetupReqValidationError{}
+var _ error = MACCommand_BeaconTimingAnsValidationError{}
var _ interface {
Field() string
@@ -5474,38 +7650,34 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = MACCommand_RxTimingSetupReqValidationError{}
+} = MACCommand_BeaconTimingAnsValidationError{}
-// ValidateFields checks the field values on MACCommand_TxParamSetupReq with
-// the rules defined in the proto definition for this message. If any rules
-// are violated, an error is returned.
-func (m *MACCommand_TxParamSetupReq) ValidateFields(paths ...string) error {
+// ValidateFields checks the field values on MACCommand_BeaconFreqReq with the
+// rules defined in the proto definition for this message. If any rules are
+// violated, an error is returned.
+func (m *MACCommand_BeaconFreqReq) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = MACCommand_TxParamSetupReqFieldPathsNested
+ paths = MACCommand_BeaconFreqReqFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "max_eirp_index":
+ case "frequency":
- if _, ok := DeviceEIRP_name[int32(m.GetMaxEirpIndex())]; !ok {
- return MACCommand_TxParamSetupReqValidationError{
- field: "max_eirp_index",
- reason: "value must be one of the defined enum values",
+ if val := m.GetFrequency(); val > 0 && val < 100000 {
+ return MACCommand_BeaconFreqReqValidationError{
+ field: "frequency",
+ reason: "value must be outside range (0, 100000)",
}
}
- case "uplink_dwell_time":
- // no validation rules for UplinkDwellTime
- case "downlink_dwell_time":
- // no validation rules for DownlinkDwellTime
default:
- return MACCommand_TxParamSetupReqValidationError{
+ return MACCommand_BeaconFreqReqValidationError{
field: name,
reason: "invalid field path",
}
@@ -5514,10 +7686,10 @@ func (m *MACCommand_TxParamSetupReq) ValidateFields(paths ...string) error {
return nil
}
-// MACCommand_TxParamSetupReqValidationError is the validation error returned
-// by MACCommand_TxParamSetupReq.ValidateFields if the designated constraints
+// MACCommand_BeaconFreqReqValidationError is the validation error returned by
+// MACCommand_BeaconFreqReq.ValidateFields if the designated constraints
// aren't met.
-type MACCommand_TxParamSetupReqValidationError struct {
+type MACCommand_BeaconFreqReqValidationError struct {
field string
reason string
cause error
@@ -5525,24 +7697,24 @@ type MACCommand_TxParamSetupReqValidationError struct {
}
// Field function returns field value.
-func (e MACCommand_TxParamSetupReqValidationError) Field() string { return e.field }
+func (e MACCommand_BeaconFreqReqValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e MACCommand_TxParamSetupReqValidationError) Reason() string { return e.reason }
+func (e MACCommand_BeaconFreqReqValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e MACCommand_TxParamSetupReqValidationError) Cause() error { return e.cause }
+func (e MACCommand_BeaconFreqReqValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e MACCommand_TxParamSetupReqValidationError) Key() bool { return e.key }
+func (e MACCommand_BeaconFreqReqValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e MACCommand_TxParamSetupReqValidationError) ErrorName() string {
- return "MACCommand_TxParamSetupReqValidationError"
+func (e MACCommand_BeaconFreqReqValidationError) ErrorName() string {
+ return "MACCommand_BeaconFreqReqValidationError"
}
// Error satisfies the builtin error interface
-func (e MACCommand_TxParamSetupReqValidationError) Error() string {
+func (e MACCommand_BeaconFreqReqValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -5554,14 +7726,14 @@ func (e MACCommand_TxParamSetupReqValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sMACCommand_TxParamSetupReq.%s: %s%s",
+ "invalid %sMACCommand_BeaconFreqReq.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = MACCommand_TxParamSetupReqValidationError{}
+var _ error = MACCommand_BeaconFreqReqValidationError{}
var _ interface {
Field() string
@@ -5569,34 +7741,27 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = MACCommand_TxParamSetupReqValidationError{}
+} = MACCommand_BeaconFreqReqValidationError{}
-// ValidateFields checks the field values on MACCommand_RekeyInd with the rules
-// defined in the proto definition for this message. If any rules are
+// ValidateFields checks the field values on MACCommand_BeaconFreqAns with the
+// rules defined in the proto definition for this message. If any rules are
// violated, an error is returned.
-func (m *MACCommand_RekeyInd) ValidateFields(paths ...string) error {
+func (m *MACCommand_BeaconFreqAns) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = MACCommand_RekeyIndFieldPathsNested
+ paths = MACCommand_BeaconFreqAnsFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "minor_version":
-
- if _, ok := Minor_name[int32(m.GetMinorVersion())]; !ok {
- return MACCommand_RekeyIndValidationError{
- field: "minor_version",
- reason: "value must be one of the defined enum values",
- }
- }
-
+ case "frequency_ack":
+ // no validation rules for FrequencyAck
default:
- return MACCommand_RekeyIndValidationError{
+ return MACCommand_BeaconFreqAnsValidationError{
field: name,
reason: "invalid field path",
}
@@ -5605,9 +7770,10 @@ func (m *MACCommand_RekeyInd) ValidateFields(paths ...string) error {
return nil
}
-// MACCommand_RekeyIndValidationError is the validation error returned by
-// MACCommand_RekeyInd.ValidateFields if the designated constraints aren't met.
-type MACCommand_RekeyIndValidationError struct {
+// MACCommand_BeaconFreqAnsValidationError is the validation error returned by
+// MACCommand_BeaconFreqAns.ValidateFields if the designated constraints
+// aren't met.
+type MACCommand_BeaconFreqAnsValidationError struct {
field string
reason string
cause error
@@ -5615,24 +7781,24 @@ type MACCommand_RekeyIndValidationError struct {
}
// Field function returns field value.
-func (e MACCommand_RekeyIndValidationError) Field() string { return e.field }
+func (e MACCommand_BeaconFreqAnsValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e MACCommand_RekeyIndValidationError) Reason() string { return e.reason }
+func (e MACCommand_BeaconFreqAnsValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e MACCommand_RekeyIndValidationError) Cause() error { return e.cause }
+func (e MACCommand_BeaconFreqAnsValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e MACCommand_RekeyIndValidationError) Key() bool { return e.key }
+func (e MACCommand_BeaconFreqAnsValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e MACCommand_RekeyIndValidationError) ErrorName() string {
- return "MACCommand_RekeyIndValidationError"
+func (e MACCommand_BeaconFreqAnsValidationError) ErrorName() string {
+ return "MACCommand_BeaconFreqAnsValidationError"
}
// Error satisfies the builtin error interface
-func (e MACCommand_RekeyIndValidationError) Error() string {
+func (e MACCommand_BeaconFreqAnsValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -5644,14 +7810,14 @@ func (e MACCommand_RekeyIndValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sMACCommand_RekeyInd.%s: %s%s",
+ "invalid %sMACCommand_BeaconFreqAns.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = MACCommand_RekeyIndValidationError{}
+var _ error = MACCommand_BeaconFreqAnsValidationError{}
var _ interface {
Field() string
@@ -5659,34 +7825,34 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = MACCommand_RekeyIndValidationError{}
+} = MACCommand_BeaconFreqAnsValidationError{}
-// ValidateFields checks the field values on MACCommand_RekeyConf with the
+// ValidateFields checks the field values on MACCommand_DeviceModeInd with the
// rules defined in the proto definition for this message. If any rules are
// violated, an error is returned.
-func (m *MACCommand_RekeyConf) ValidateFields(paths ...string) error {
+func (m *MACCommand_DeviceModeInd) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = MACCommand_RekeyConfFieldPathsNested
+ paths = MACCommand_DeviceModeIndFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "minor_version":
+ case "class":
- if _, ok := Minor_name[int32(m.GetMinorVersion())]; !ok {
- return MACCommand_RekeyConfValidationError{
- field: "minor_version",
+ if _, ok := Class_name[int32(m.GetClass())]; !ok {
+ return MACCommand_DeviceModeIndValidationError{
+ field: "class",
reason: "value must be one of the defined enum values",
}
}
default:
- return MACCommand_RekeyConfValidationError{
+ return MACCommand_DeviceModeIndValidationError{
field: name,
reason: "invalid field path",
}
@@ -5695,9 +7861,10 @@ func (m *MACCommand_RekeyConf) ValidateFields(paths ...string) error {
return nil
}
-// MACCommand_RekeyConfValidationError is the validation error returned by
-// MACCommand_RekeyConf.ValidateFields if the designated constraints aren't met.
-type MACCommand_RekeyConfValidationError struct {
+// MACCommand_DeviceModeIndValidationError is the validation error returned by
+// MACCommand_DeviceModeInd.ValidateFields if the designated constraints
+// aren't met.
+type MACCommand_DeviceModeIndValidationError struct {
field string
reason string
cause error
@@ -5705,24 +7872,24 @@ type MACCommand_RekeyConfValidationError struct {
}
// Field function returns field value.
-func (e MACCommand_RekeyConfValidationError) Field() string { return e.field }
+func (e MACCommand_DeviceModeIndValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e MACCommand_RekeyConfValidationError) Reason() string { return e.reason }
+func (e MACCommand_DeviceModeIndValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e MACCommand_RekeyConfValidationError) Cause() error { return e.cause }
+func (e MACCommand_DeviceModeIndValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e MACCommand_RekeyConfValidationError) Key() bool { return e.key }
+func (e MACCommand_DeviceModeIndValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e MACCommand_RekeyConfValidationError) ErrorName() string {
- return "MACCommand_RekeyConfValidationError"
+func (e MACCommand_DeviceModeIndValidationError) ErrorName() string {
+ return "MACCommand_DeviceModeIndValidationError"
}
// Error satisfies the builtin error interface
-func (e MACCommand_RekeyConfValidationError) Error() string {
+func (e MACCommand_DeviceModeIndValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -5734,14 +7901,14 @@ func (e MACCommand_RekeyConfValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sMACCommand_RekeyConf.%s: %s%s",
+ "invalid %sMACCommand_DeviceModeInd.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = MACCommand_RekeyConfValidationError{}
+var _ error = MACCommand_DeviceModeIndValidationError{}
var _ interface {
Field() string
@@ -5749,43 +7916,34 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = MACCommand_RekeyConfValidationError{}
+} = MACCommand_DeviceModeIndValidationError{}
-// ValidateFields checks the field values on MACCommand_ADRParamSetupReq with
-// the rules defined in the proto definition for this message. If any rules
-// are violated, an error is returned.
-func (m *MACCommand_ADRParamSetupReq) ValidateFields(paths ...string) error {
+// ValidateFields checks the field values on MACCommand_DeviceModeConf with the
+// rules defined in the proto definition for this message. If any rules are
+// violated, an error is returned.
+func (m *MACCommand_DeviceModeConf) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = MACCommand_ADRParamSetupReqFieldPathsNested
+ paths = MACCommand_DeviceModeConfFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "adr_ack_limit_exponent":
-
- if _, ok := ADRAckLimitExponent_name[int32(m.GetAdrAckLimitExponent())]; !ok {
- return MACCommand_ADRParamSetupReqValidationError{
- field: "adr_ack_limit_exponent",
- reason: "value must be one of the defined enum values",
- }
- }
-
- case "adr_ack_delay_exponent":
+ case "class":
- if _, ok := ADRAckDelayExponent_name[int32(m.GetAdrAckDelayExponent())]; !ok {
- return MACCommand_ADRParamSetupReqValidationError{
- field: "adr_ack_delay_exponent",
+ if _, ok := Class_name[int32(m.GetClass())]; !ok {
+ return MACCommand_DeviceModeConfValidationError{
+ field: "class",
reason: "value must be one of the defined enum values",
}
}
default:
- return MACCommand_ADRParamSetupReqValidationError{
+ return MACCommand_DeviceModeConfValidationError{
field: name,
reason: "invalid field path",
}
@@ -5794,10 +7952,10 @@ func (m *MACCommand_ADRParamSetupReq) ValidateFields(paths ...string) error {
return nil
}
-// MACCommand_ADRParamSetupReqValidationError is the validation error returned
-// by MACCommand_ADRParamSetupReq.ValidateFields if the designated constraints
+// MACCommand_DeviceModeConfValidationError is the validation error returned by
+// MACCommand_DeviceModeConf.ValidateFields if the designated constraints
// aren't met.
-type MACCommand_ADRParamSetupReqValidationError struct {
+type MACCommand_DeviceModeConfValidationError struct {
field string
reason string
cause error
@@ -5805,24 +7963,24 @@ type MACCommand_ADRParamSetupReqValidationError struct {
}
// Field function returns field value.
-func (e MACCommand_ADRParamSetupReqValidationError) Field() string { return e.field }
+func (e MACCommand_DeviceModeConfValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e MACCommand_ADRParamSetupReqValidationError) Reason() string { return e.reason }
+func (e MACCommand_DeviceModeConfValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e MACCommand_ADRParamSetupReqValidationError) Cause() error { return e.cause }
+func (e MACCommand_DeviceModeConfValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e MACCommand_ADRParamSetupReqValidationError) Key() bool { return e.key }
+func (e MACCommand_DeviceModeConfValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e MACCommand_ADRParamSetupReqValidationError) ErrorName() string {
- return "MACCommand_ADRParamSetupReqValidationError"
+func (e MACCommand_DeviceModeConfValidationError) ErrorName() string {
+ return "MACCommand_DeviceModeConfValidationError"
}
// Error satisfies the builtin error interface
-func (e MACCommand_ADRParamSetupReqValidationError) Error() string {
+func (e MACCommand_DeviceModeConfValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -5834,14 +7992,14 @@ func (e MACCommand_ADRParamSetupReqValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sMACCommand_ADRParamSetupReq.%s: %s%s",
+ "invalid %sMACCommand_DeviceModeConf.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = MACCommand_ADRParamSetupReqValidationError{}
+var _ error = MACCommand_DeviceModeConfValidationError{}
var _ interface {
Field() string
@@ -5849,34 +8007,37 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = MACCommand_ADRParamSetupReqValidationError{}
+} = MACCommand_DeviceModeConfValidationError{}
-// ValidateFields checks the field values on MACCommand_DeviceTimeAns with the
+// ValidateFields checks the field values on MACCommand_RelayConfReq with the
// rules defined in the proto definition for this message. If any rules are
// violated, an error is returned.
-func (m *MACCommand_DeviceTimeAns) ValidateFields(paths ...string) error {
+func (m *MACCommand_RelayConfReq) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = MACCommand_DeviceTimeAnsFieldPathsNested
+ paths = MACCommand_RelayConfReqFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "time":
+ case "configuration":
- if m.GetTime() == nil {
- return MACCommand_DeviceTimeAnsValidationError{
- field: "time",
- reason: "value is required",
+ if v, ok := interface{}(m.GetConfiguration()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommand_RelayConfReqValidationError{
+ field: "configuration",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
}
}
default:
- return MACCommand_DeviceTimeAnsValidationError{
+ return MACCommand_RelayConfReqValidationError{
field: name,
reason: "invalid field path",
}
@@ -5885,10 +8046,9 @@ func (m *MACCommand_DeviceTimeAns) ValidateFields(paths ...string) error {
return nil
}
-// MACCommand_DeviceTimeAnsValidationError is the validation error returned by
-// MACCommand_DeviceTimeAns.ValidateFields if the designated constraints
-// aren't met.
-type MACCommand_DeviceTimeAnsValidationError struct {
+// MACCommand_RelayConfReqValidationError is the validation error returned by
+// MACCommand_RelayConfReq.ValidateFields if the designated constraints aren't met.
+type MACCommand_RelayConfReqValidationError struct {
field string
reason string
cause error
@@ -5896,24 +8056,24 @@ type MACCommand_DeviceTimeAnsValidationError struct {
}
// Field function returns field value.
-func (e MACCommand_DeviceTimeAnsValidationError) Field() string { return e.field }
+func (e MACCommand_RelayConfReqValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e MACCommand_DeviceTimeAnsValidationError) Reason() string { return e.reason }
+func (e MACCommand_RelayConfReqValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e MACCommand_DeviceTimeAnsValidationError) Cause() error { return e.cause }
+func (e MACCommand_RelayConfReqValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e MACCommand_DeviceTimeAnsValidationError) Key() bool { return e.key }
+func (e MACCommand_RelayConfReqValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e MACCommand_DeviceTimeAnsValidationError) ErrorName() string {
- return "MACCommand_DeviceTimeAnsValidationError"
+func (e MACCommand_RelayConfReqValidationError) ErrorName() string {
+ return "MACCommand_RelayConfReqValidationError"
}
// Error satisfies the builtin error interface
-func (e MACCommand_DeviceTimeAnsValidationError) Error() string {
+func (e MACCommand_RelayConfReqValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -5925,14 +8085,14 @@ func (e MACCommand_DeviceTimeAnsValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sMACCommand_DeviceTimeAns.%s: %s%s",
+ "invalid %sMACCommand_RelayConfReq.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = MACCommand_DeviceTimeAnsValidationError{}
+var _ error = MACCommand_RelayConfReqValidationError{}
var _ interface {
Field() string
@@ -5940,73 +8100,48 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = MACCommand_DeviceTimeAnsValidationError{}
+} = MACCommand_RelayConfReqValidationError{}
-// ValidateFields checks the field values on MACCommand_ForceRejoinReq with the
+// ValidateFields checks the field values on MACCommand_RelayConfAns with the
// rules defined in the proto definition for this message. If any rules are
// violated, an error is returned.
-func (m *MACCommand_ForceRejoinReq) ValidateFields(paths ...string) error {
+func (m *MACCommand_RelayConfAns) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = MACCommand_ForceRejoinReqFieldPathsNested
+ paths = MACCommand_RelayConfAnsFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "rejoin_type":
-
- if _, ok := RejoinRequestType_name[int32(m.GetRejoinType())]; !ok {
- return MACCommand_ForceRejoinReqValidationError{
- field: "rejoin_type",
- reason: "value must be one of the defined enum values",
- }
- }
-
- case "data_rate_index":
-
- if _, ok := DataRateIndex_name[int32(m.GetDataRateIndex())]; !ok {
- return MACCommand_ForceRejoinReqValidationError{
- field: "data_rate_index",
- reason: "value must be one of the defined enum values",
- }
- }
-
- case "max_retries":
-
- if m.GetMaxRetries() > 7 {
- return MACCommand_ForceRejoinReqValidationError{
- field: "max_retries",
- reason: "value must be less than or equal to 7",
- }
- }
-
- case "period_exponent":
-
- if _, ok := RejoinPeriodExponent_name[int32(m.GetPeriodExponent())]; !ok {
- return MACCommand_ForceRejoinReqValidationError{
- field: "period_exponent",
- reason: "value must be one of the defined enum values",
- }
- }
-
+ case "second_channel_frequency_ack":
+ // no validation rules for SecondChannelFrequencyAck
+ case "second_channel_ack_offset_ack":
+ // no validation rules for SecondChannelAckOffsetAck
+ case "second_channel_data_rate_index_ack":
+ // no validation rules for SecondChannelDataRateIndexAck
+ case "second_channel_index_ack":
+ // no validation rules for SecondChannelIndexAck
+ case "default_channel_index_ack":
+ // no validation rules for DefaultChannelIndexAck
+ case "cad_periodicity_ack":
+ // no validation rules for CadPeriodicityAck
default:
- return MACCommand_ForceRejoinReqValidationError{
+ return MACCommand_RelayConfAnsValidationError{
field: name,
reason: "invalid field path",
}
}
}
- return nil
-}
-
-// MACCommand_ForceRejoinReqValidationError is the validation error returned by
-// MACCommand_ForceRejoinReq.ValidateFields if the designated constraints
-// aren't met.
-type MACCommand_ForceRejoinReqValidationError struct {
+ return nil
+}
+
+// MACCommand_RelayConfAnsValidationError is the validation error returned by
+// MACCommand_RelayConfAns.ValidateFields if the designated constraints aren't met.
+type MACCommand_RelayConfAnsValidationError struct {
field string
reason string
cause error
@@ -6014,24 +8149,24 @@ type MACCommand_ForceRejoinReqValidationError struct {
}
// Field function returns field value.
-func (e MACCommand_ForceRejoinReqValidationError) Field() string { return e.field }
+func (e MACCommand_RelayConfAnsValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e MACCommand_ForceRejoinReqValidationError) Reason() string { return e.reason }
+func (e MACCommand_RelayConfAnsValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e MACCommand_ForceRejoinReqValidationError) Cause() error { return e.cause }
+func (e MACCommand_RelayConfAnsValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e MACCommand_ForceRejoinReqValidationError) Key() bool { return e.key }
+func (e MACCommand_RelayConfAnsValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e MACCommand_ForceRejoinReqValidationError) ErrorName() string {
- return "MACCommand_ForceRejoinReqValidationError"
+func (e MACCommand_RelayConfAnsValidationError) ErrorName() string {
+ return "MACCommand_RelayConfAnsValidationError"
}
// Error satisfies the builtin error interface
-func (e MACCommand_ForceRejoinReqValidationError) Error() string {
+func (e MACCommand_RelayConfAnsValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -6043,14 +8178,14 @@ func (e MACCommand_ForceRejoinReqValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sMACCommand_ForceRejoinReq.%s: %s%s",
+ "invalid %sMACCommand_RelayConfAns.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = MACCommand_ForceRejoinReqValidationError{}
+var _ error = MACCommand_RelayConfAnsValidationError{}
var _ interface {
Field() string
@@ -6058,43 +8193,37 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = MACCommand_ForceRejoinReqValidationError{}
+} = MACCommand_RelayConfAnsValidationError{}
-// ValidateFields checks the field values on MACCommand_RejoinParamSetupReq
+// ValidateFields checks the field values on MACCommand_RelayEndDeviceConfReq
// with the rules defined in the proto definition for this message. If any
// rules are violated, an error is returned.
-func (m *MACCommand_RejoinParamSetupReq) ValidateFields(paths ...string) error {
+func (m *MACCommand_RelayEndDeviceConfReq) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = MACCommand_RejoinParamSetupReqFieldPathsNested
+ paths = MACCommand_RelayEndDeviceConfReqFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "max_count_exponent":
-
- if _, ok := RejoinCountExponent_name[int32(m.GetMaxCountExponent())]; !ok {
- return MACCommand_RejoinParamSetupReqValidationError{
- field: "max_count_exponent",
- reason: "value must be one of the defined enum values",
- }
- }
+ case "configuration":
- case "max_time_exponent":
-
- if _, ok := RejoinTimeExponent_name[int32(m.GetMaxTimeExponent())]; !ok {
- return MACCommand_RejoinParamSetupReqValidationError{
- field: "max_time_exponent",
- reason: "value must be one of the defined enum values",
+ if v, ok := interface{}(m.GetConfiguration()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommand_RelayEndDeviceConfReqValidationError{
+ field: "configuration",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
}
}
default:
- return MACCommand_RejoinParamSetupReqValidationError{
+ return MACCommand_RelayEndDeviceConfReqValidationError{
field: name,
reason: "invalid field path",
}
@@ -6103,10 +8232,10 @@ func (m *MACCommand_RejoinParamSetupReq) ValidateFields(paths ...string) error {
return nil
}
-// MACCommand_RejoinParamSetupReqValidationError is the validation error
-// returned by MACCommand_RejoinParamSetupReq.ValidateFields if the designated
-// constraints aren't met.
-type MACCommand_RejoinParamSetupReqValidationError struct {
+// MACCommand_RelayEndDeviceConfReqValidationError is the validation error
+// returned by MACCommand_RelayEndDeviceConfReq.ValidateFields if the
+// designated constraints aren't met.
+type MACCommand_RelayEndDeviceConfReqValidationError struct {
field string
reason string
cause error
@@ -6114,24 +8243,24 @@ type MACCommand_RejoinParamSetupReqValidationError struct {
}
// Field function returns field value.
-func (e MACCommand_RejoinParamSetupReqValidationError) Field() string { return e.field }
+func (e MACCommand_RelayEndDeviceConfReqValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e MACCommand_RejoinParamSetupReqValidationError) Reason() string { return e.reason }
+func (e MACCommand_RelayEndDeviceConfReqValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e MACCommand_RejoinParamSetupReqValidationError) Cause() error { return e.cause }
+func (e MACCommand_RelayEndDeviceConfReqValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e MACCommand_RejoinParamSetupReqValidationError) Key() bool { return e.key }
+func (e MACCommand_RelayEndDeviceConfReqValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e MACCommand_RejoinParamSetupReqValidationError) ErrorName() string {
- return "MACCommand_RejoinParamSetupReqValidationError"
+func (e MACCommand_RelayEndDeviceConfReqValidationError) ErrorName() string {
+ return "MACCommand_RelayEndDeviceConfReqValidationError"
}
// Error satisfies the builtin error interface
-func (e MACCommand_RejoinParamSetupReqValidationError) Error() string {
+func (e MACCommand_RelayEndDeviceConfReqValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -6143,14 +8272,14 @@ func (e MACCommand_RejoinParamSetupReqValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sMACCommand_RejoinParamSetupReq.%s: %s%s",
+ "invalid %sMACCommand_RelayEndDeviceConfReq.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = MACCommand_RejoinParamSetupReqValidationError{}
+var _ error = MACCommand_RelayEndDeviceConfReqValidationError{}
var _ interface {
Field() string
@@ -6158,27 +8287,33 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = MACCommand_RejoinParamSetupReqValidationError{}
+} = MACCommand_RelayEndDeviceConfReqValidationError{}
-// ValidateFields checks the field values on MACCommand_RejoinParamSetupAns
+// ValidateFields checks the field values on MACCommand_RelayEndDeviceConfAns
// with the rules defined in the proto definition for this message. If any
// rules are violated, an error is returned.
-func (m *MACCommand_RejoinParamSetupAns) ValidateFields(paths ...string) error {
+func (m *MACCommand_RelayEndDeviceConfAns) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = MACCommand_RejoinParamSetupAnsFieldPathsNested
+ paths = MACCommand_RelayEndDeviceConfAnsFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "max_time_exponent_ack":
- // no validation rules for MaxTimeExponentAck
+ case "second_channel_frequency_ack":
+ // no validation rules for SecondChannelFrequencyAck
+ case "second_channel_data_rate_index_ack":
+ // no validation rules for SecondChannelDataRateIndexAck
+ case "second_channel_index_ack":
+ // no validation rules for SecondChannelIndexAck
+ case "backoff_ack":
+ // no validation rules for BackoffAck
default:
- return MACCommand_RejoinParamSetupAnsValidationError{
+ return MACCommand_RelayEndDeviceConfAnsValidationError{
field: name,
reason: "invalid field path",
}
@@ -6187,10 +8322,10 @@ func (m *MACCommand_RejoinParamSetupAns) ValidateFields(paths ...string) error {
return nil
}
-// MACCommand_RejoinParamSetupAnsValidationError is the validation error
-// returned by MACCommand_RejoinParamSetupAns.ValidateFields if the designated
-// constraints aren't met.
-type MACCommand_RejoinParamSetupAnsValidationError struct {
+// MACCommand_RelayEndDeviceConfAnsValidationError is the validation error
+// returned by MACCommand_RelayEndDeviceConfAns.ValidateFields if the
+// designated constraints aren't met.
+type MACCommand_RelayEndDeviceConfAnsValidationError struct {
field string
reason string
cause error
@@ -6198,24 +8333,24 @@ type MACCommand_RejoinParamSetupAnsValidationError struct {
}
// Field function returns field value.
-func (e MACCommand_RejoinParamSetupAnsValidationError) Field() string { return e.field }
+func (e MACCommand_RelayEndDeviceConfAnsValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e MACCommand_RejoinParamSetupAnsValidationError) Reason() string { return e.reason }
+func (e MACCommand_RelayEndDeviceConfAnsValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e MACCommand_RejoinParamSetupAnsValidationError) Cause() error { return e.cause }
+func (e MACCommand_RelayEndDeviceConfAnsValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e MACCommand_RejoinParamSetupAnsValidationError) Key() bool { return e.key }
+func (e MACCommand_RelayEndDeviceConfAnsValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e MACCommand_RejoinParamSetupAnsValidationError) ErrorName() string {
- return "MACCommand_RejoinParamSetupAnsValidationError"
+func (e MACCommand_RelayEndDeviceConfAnsValidationError) ErrorName() string {
+ return "MACCommand_RelayEndDeviceConfAnsValidationError"
}
// Error satisfies the builtin error interface
-func (e MACCommand_RejoinParamSetupAnsValidationError) Error() string {
+func (e MACCommand_RelayEndDeviceConfAnsValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -6227,14 +8362,14 @@ func (e MACCommand_RejoinParamSetupAnsValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sMACCommand_RejoinParamSetupAns.%s: %s%s",
+ "invalid %sMACCommand_RelayEndDeviceConfAns.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = MACCommand_RejoinParamSetupAnsValidationError{}
+var _ error = MACCommand_RelayEndDeviceConfAnsValidationError{}
var _ interface {
Field() string
@@ -6242,34 +8377,92 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = MACCommand_RejoinParamSetupAnsValidationError{}
+} = MACCommand_RelayEndDeviceConfAnsValidationError{}
-// ValidateFields checks the field values on MACCommand_PingSlotInfoReq with
-// the rules defined in the proto definition for this message. If any rules
-// are violated, an error is returned.
-func (m *MACCommand_PingSlotInfoReq) ValidateFields(paths ...string) error {
+// ValidateFields checks the field values on
+// MACCommand_RelayUpdateUplinkListReq with the rules defined in the proto
+// definition for this message. If any rules are violated, an error is returned.
+func (m *MACCommand_RelayUpdateUplinkListReq) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = MACCommand_PingSlotInfoReqFieldPathsNested
+ paths = MACCommand_RelayUpdateUplinkListReqFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "period":
+ case "rule_index":
- if _, ok := PingSlotPeriod_name[int32(m.GetPeriod())]; !ok {
- return MACCommand_PingSlotInfoReqValidationError{
- field: "period",
- reason: "value must be one of the defined enum values",
+ if m.GetRuleIndex() > 15 {
+ return MACCommand_RelayUpdateUplinkListReqValidationError{
+ field: "rule_index",
+ reason: "value must be less than or equal to 15",
+ }
+ }
+
+ case "forward_limits":
+
+ if v, ok := interface{}(m.GetForwardLimits()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommand_RelayUpdateUplinkListReqValidationError{
+ field: "forward_limits",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "dev_addr":
+
+ if len(m.GetDevAddr()) > 0 {
+
+ if len(m.GetDevAddr()) != 4 {
+ return MACCommand_RelayUpdateUplinkListReqValidationError{
+ field: "dev_addr",
+ reason: "value length must be 4 bytes",
+ }
+ }
+
+ }
+
+ case "w_f_cnt":
+ // no validation rules for WFCnt
+ case "root_wor_s_key":
+
+ if len(m.GetRootWorSKey()) > 0 {
+
+ if len(m.GetRootWorSKey()) != 16 {
+ return MACCommand_RelayUpdateUplinkListReqValidationError{
+ field: "root_wor_s_key",
+ reason: "value length must be 16 bytes",
+ }
+ }
+
+ }
+
+ case "device_id":
+
+ if utf8.RuneCountInString(m.GetDeviceId()) > 36 {
+ return MACCommand_RelayUpdateUplinkListReqValidationError{
+ field: "device_id",
+ reason: "value length must be at most 36 runes",
+ }
+ }
+
+ if !_MACCommand_RelayUpdateUplinkListReq_DeviceId_Pattern.MatchString(m.GetDeviceId()) {
+ return MACCommand_RelayUpdateUplinkListReqValidationError{
+ field: "device_id",
+ reason: "value does not match regex pattern \"^[a-z0-9](?:[-]?[a-z0-9]){2,}$\"",
}
}
+ case "session_key_id":
+ // no validation rules for SessionKeyId
default:
- return MACCommand_PingSlotInfoReqValidationError{
+ return MACCommand_RelayUpdateUplinkListReqValidationError{
field: name,
reason: "invalid field path",
}
@@ -6278,10 +8471,10 @@ func (m *MACCommand_PingSlotInfoReq) ValidateFields(paths ...string) error {
return nil
}
-// MACCommand_PingSlotInfoReqValidationError is the validation error returned
-// by MACCommand_PingSlotInfoReq.ValidateFields if the designated constraints
-// aren't met.
-type MACCommand_PingSlotInfoReqValidationError struct {
+// MACCommand_RelayUpdateUplinkListReqValidationError is the validation error
+// returned by MACCommand_RelayUpdateUplinkListReq.ValidateFields if the
+// designated constraints aren't met.
+type MACCommand_RelayUpdateUplinkListReqValidationError struct {
field string
reason string
cause error
@@ -6289,24 +8482,24 @@ type MACCommand_PingSlotInfoReqValidationError struct {
}
// Field function returns field value.
-func (e MACCommand_PingSlotInfoReqValidationError) Field() string { return e.field }
+func (e MACCommand_RelayUpdateUplinkListReqValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e MACCommand_PingSlotInfoReqValidationError) Reason() string { return e.reason }
+func (e MACCommand_RelayUpdateUplinkListReqValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e MACCommand_PingSlotInfoReqValidationError) Cause() error { return e.cause }
+func (e MACCommand_RelayUpdateUplinkListReqValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e MACCommand_PingSlotInfoReqValidationError) Key() bool { return e.key }
+func (e MACCommand_RelayUpdateUplinkListReqValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e MACCommand_PingSlotInfoReqValidationError) ErrorName() string {
- return "MACCommand_PingSlotInfoReqValidationError"
+func (e MACCommand_RelayUpdateUplinkListReqValidationError) ErrorName() string {
+ return "MACCommand_RelayUpdateUplinkListReqValidationError"
}
// Error satisfies the builtin error interface
-func (e MACCommand_PingSlotInfoReqValidationError) Error() string {
+func (e MACCommand_RelayUpdateUplinkListReqValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -6318,14 +8511,14 @@ func (e MACCommand_PingSlotInfoReqValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sMACCommand_PingSlotInfoReq.%s: %s%s",
+ "invalid %sMACCommand_RelayUpdateUplinkListReq.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = MACCommand_PingSlotInfoReqValidationError{}
+var _ error = MACCommand_RelayUpdateUplinkListReqValidationError{}
var _ interface {
Field() string
@@ -6333,43 +8526,105 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = MACCommand_PingSlotInfoReqValidationError{}
+} = MACCommand_RelayUpdateUplinkListReqValidationError{}
-// ValidateFields checks the field values on MACCommand_PingSlotChannelReq with
-// the rules defined in the proto definition for this message. If any rules
-// are violated, an error is returned.
-func (m *MACCommand_PingSlotChannelReq) ValidateFields(paths ...string) error {
+var _MACCommand_RelayUpdateUplinkListReq_DeviceId_Pattern = regexp.MustCompile("^[a-z0-9](?:[-]?[a-z0-9]){2,}$")
+
+// ValidateFields checks the field values on
+// MACCommand_RelayUpdateUplinkListAns with the rules defined in the proto
+// definition for this message. If any rules are violated, an error is returned.
+func (m *MACCommand_RelayUpdateUplinkListAns) ValidateFields(paths ...string) error {
+ if len(paths) > 0 {
+ return fmt.Errorf("message MACCommand_RelayUpdateUplinkListAns has no fields, but paths %s were specified", paths)
+ }
+ return nil
+}
+
+// MACCommand_RelayUpdateUplinkListAnsValidationError is the validation error
+// returned by MACCommand_RelayUpdateUplinkListAns.ValidateFields if the
+// designated constraints aren't met.
+type MACCommand_RelayUpdateUplinkListAnsValidationError struct {
+ field string
+ reason string
+ cause error
+ key bool
+}
+
+// Field function returns field value.
+func (e MACCommand_RelayUpdateUplinkListAnsValidationError) Field() string { return e.field }
+
+// Reason function returns reason value.
+func (e MACCommand_RelayUpdateUplinkListAnsValidationError) Reason() string { return e.reason }
+
+// Cause function returns cause value.
+func (e MACCommand_RelayUpdateUplinkListAnsValidationError) Cause() error { return e.cause }
+
+// Key function returns key value.
+func (e MACCommand_RelayUpdateUplinkListAnsValidationError) Key() bool { return e.key }
+
+// ErrorName returns error name.
+func (e MACCommand_RelayUpdateUplinkListAnsValidationError) ErrorName() string {
+ return "MACCommand_RelayUpdateUplinkListAnsValidationError"
+}
+
+// Error satisfies the builtin error interface
+func (e MACCommand_RelayUpdateUplinkListAnsValidationError) Error() string {
+ cause := ""
+ if e.cause != nil {
+ cause = fmt.Sprintf(" | caused by: %v", e.cause)
+ }
+
+ key := ""
+ if e.key {
+ key = "key for "
+ }
+
+ return fmt.Sprintf(
+ "invalid %sMACCommand_RelayUpdateUplinkListAns.%s: %s%s",
+ key,
+ e.field,
+ e.reason,
+ cause)
+}
+
+var _ error = MACCommand_RelayUpdateUplinkListAnsValidationError{}
+
+var _ interface {
+ Field() string
+ Reason() string
+ Key() bool
+ Cause() error
+ ErrorName() string
+} = MACCommand_RelayUpdateUplinkListAnsValidationError{}
+
+// ValidateFields checks the field values on MACCommand_RelayCtrlUplinkListReq
+// with the rules defined in the proto definition for this message. If any
+// rules are violated, an error is returned.
+func (m *MACCommand_RelayCtrlUplinkListReq) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = MACCommand_PingSlotChannelReqFieldPathsNested
+ paths = MACCommand_RelayCtrlUplinkListReqFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "frequency":
-
- if val := m.GetFrequency(); val > 0 && val < 100000 {
- return MACCommand_PingSlotChannelReqValidationError{
- field: "frequency",
- reason: "value must be outside range (0, 100000)",
- }
- }
+ case "rule_index":
- case "data_rate_index":
-
- if _, ok := DataRateIndex_name[int32(m.GetDataRateIndex())]; !ok {
- return MACCommand_PingSlotChannelReqValidationError{
- field: "data_rate_index",
- reason: "value must be one of the defined enum values",
+ if m.GetRuleIndex() > 15 {
+ return MACCommand_RelayCtrlUplinkListReqValidationError{
+ field: "rule_index",
+ reason: "value must be less than or equal to 15",
}
}
+ case "action":
+ // no validation rules for Action
default:
- return MACCommand_PingSlotChannelReqValidationError{
+ return MACCommand_RelayCtrlUplinkListReqValidationError{
field: name,
reason: "invalid field path",
}
@@ -6378,10 +8633,10 @@ func (m *MACCommand_PingSlotChannelReq) ValidateFields(paths ...string) error {
return nil
}
-// MACCommand_PingSlotChannelReqValidationError is the validation error
-// returned by MACCommand_PingSlotChannelReq.ValidateFields if the designated
-// constraints aren't met.
-type MACCommand_PingSlotChannelReqValidationError struct {
+// MACCommand_RelayCtrlUplinkListReqValidationError is the validation error
+// returned by MACCommand_RelayCtrlUplinkListReq.ValidateFields if the
+// designated constraints aren't met.
+type MACCommand_RelayCtrlUplinkListReqValidationError struct {
field string
reason string
cause error
@@ -6389,24 +8644,24 @@ type MACCommand_PingSlotChannelReqValidationError struct {
}
// Field function returns field value.
-func (e MACCommand_PingSlotChannelReqValidationError) Field() string { return e.field }
+func (e MACCommand_RelayCtrlUplinkListReqValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e MACCommand_PingSlotChannelReqValidationError) Reason() string { return e.reason }
+func (e MACCommand_RelayCtrlUplinkListReqValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e MACCommand_PingSlotChannelReqValidationError) Cause() error { return e.cause }
+func (e MACCommand_RelayCtrlUplinkListReqValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e MACCommand_PingSlotChannelReqValidationError) Key() bool { return e.key }
+func (e MACCommand_RelayCtrlUplinkListReqValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e MACCommand_PingSlotChannelReqValidationError) ErrorName() string {
- return "MACCommand_PingSlotChannelReqValidationError"
+func (e MACCommand_RelayCtrlUplinkListReqValidationError) ErrorName() string {
+ return "MACCommand_RelayCtrlUplinkListReqValidationError"
}
// Error satisfies the builtin error interface
-func (e MACCommand_PingSlotChannelReqValidationError) Error() string {
+func (e MACCommand_RelayCtrlUplinkListReqValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -6418,14 +8673,14 @@ func (e MACCommand_PingSlotChannelReqValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sMACCommand_PingSlotChannelReq.%s: %s%s",
+ "invalid %sMACCommand_RelayCtrlUplinkListReq.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = MACCommand_PingSlotChannelReqValidationError{}
+var _ error = MACCommand_RelayCtrlUplinkListReqValidationError{}
var _ interface {
Field() string
@@ -6433,29 +8688,29 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = MACCommand_PingSlotChannelReqValidationError{}
+} = MACCommand_RelayCtrlUplinkListReqValidationError{}
-// ValidateFields checks the field values on MACCommand_PingSlotChannelAns with
-// the rules defined in the proto definition for this message. If any rules
-// are violated, an error is returned.
-func (m *MACCommand_PingSlotChannelAns) ValidateFields(paths ...string) error {
+// ValidateFields checks the field values on MACCommand_RelayCtrlUplinkListAns
+// with the rules defined in the proto definition for this message. If any
+// rules are violated, an error is returned.
+func (m *MACCommand_RelayCtrlUplinkListAns) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = MACCommand_PingSlotChannelAnsFieldPathsNested
+ paths = MACCommand_RelayCtrlUplinkListAnsFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "frequency_ack":
- // no validation rules for FrequencyAck
- case "data_rate_index_ack":
- // no validation rules for DataRateIndexAck
+ case "rule_index_ack":
+ // no validation rules for RuleIndexAck
+ case "w_f_cnt":
+ // no validation rules for WFCnt
default:
- return MACCommand_PingSlotChannelAnsValidationError{
+ return MACCommand_RelayCtrlUplinkListAnsValidationError{
field: name,
reason: "invalid field path",
}
@@ -6464,10 +8719,10 @@ func (m *MACCommand_PingSlotChannelAns) ValidateFields(paths ...string) error {
return nil
}
-// MACCommand_PingSlotChannelAnsValidationError is the validation error
-// returned by MACCommand_PingSlotChannelAns.ValidateFields if the designated
-// constraints aren't met.
-type MACCommand_PingSlotChannelAnsValidationError struct {
+// MACCommand_RelayCtrlUplinkListAnsValidationError is the validation error
+// returned by MACCommand_RelayCtrlUplinkListAns.ValidateFields if the
+// designated constraints aren't met.
+type MACCommand_RelayCtrlUplinkListAnsValidationError struct {
field string
reason string
cause error
@@ -6475,24 +8730,24 @@ type MACCommand_PingSlotChannelAnsValidationError struct {
}
// Field function returns field value.
-func (e MACCommand_PingSlotChannelAnsValidationError) Field() string { return e.field }
+func (e MACCommand_RelayCtrlUplinkListAnsValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e MACCommand_PingSlotChannelAnsValidationError) Reason() string { return e.reason }
+func (e MACCommand_RelayCtrlUplinkListAnsValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e MACCommand_PingSlotChannelAnsValidationError) Cause() error { return e.cause }
+func (e MACCommand_RelayCtrlUplinkListAnsValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e MACCommand_PingSlotChannelAnsValidationError) Key() bool { return e.key }
+func (e MACCommand_RelayCtrlUplinkListAnsValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e MACCommand_PingSlotChannelAnsValidationError) ErrorName() string {
- return "MACCommand_PingSlotChannelAnsValidationError"
+func (e MACCommand_RelayCtrlUplinkListAnsValidationError) ErrorName() string {
+ return "MACCommand_RelayCtrlUplinkListAnsValidationError"
}
// Error satisfies the builtin error interface
-func (e MACCommand_PingSlotChannelAnsValidationError) Error() string {
+func (e MACCommand_RelayCtrlUplinkListAnsValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -6504,14 +8759,14 @@ func (e MACCommand_PingSlotChannelAnsValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sMACCommand_PingSlotChannelAns.%s: %s%s",
+ "invalid %sMACCommand_RelayCtrlUplinkListAns.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = MACCommand_PingSlotChannelAnsValidationError{}
+var _ error = MACCommand_RelayCtrlUplinkListAnsValidationError{}
var _ interface {
Field() string
@@ -6519,43 +8774,75 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = MACCommand_PingSlotChannelAnsValidationError{}
+} = MACCommand_RelayCtrlUplinkListAnsValidationError{}
-// ValidateFields checks the field values on MACCommand_BeaconTimingAns with
-// the rules defined in the proto definition for this message. If any rules
-// are violated, an error is returned.
-func (m *MACCommand_BeaconTimingAns) ValidateFields(paths ...string) error {
+// ValidateFields checks the field values on
+// MACCommand_RelayConfigureFwdLimitReq with the rules defined in the proto
+// definition for this message. If any rules are violated, an error is returned.
+func (m *MACCommand_RelayConfigureFwdLimitReq) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = MACCommand_BeaconTimingAnsFieldPathsNested
+ paths = MACCommand_RelayConfigureFwdLimitReqFieldPathsNested
}
- for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
- _ = subs
- switch name {
- case "delay":
+ for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
+ _ = subs
+ switch name {
+ case "reset_limit_counter":
+ // no validation rules for ResetLimitCounter
+ case "join_request_limits":
+
+ if v, ok := interface{}(m.GetJoinRequestLimits()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommand_RelayConfigureFwdLimitReqValidationError{
+ field: "join_request_limits",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "notify_limits":
- if m.GetDelay() > 65535 {
- return MACCommand_BeaconTimingAnsValidationError{
- field: "delay",
- reason: "value must be less than or equal to 65535",
+ if v, ok := interface{}(m.GetNotifyLimits()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommand_RelayConfigureFwdLimitReqValidationError{
+ field: "notify_limits",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
}
}
- case "channel_index":
+ case "global_uplink_limits":
- if m.GetChannelIndex() > 255 {
- return MACCommand_BeaconTimingAnsValidationError{
- field: "channel_index",
- reason: "value must be less than or equal to 255",
+ if v, ok := interface{}(m.GetGlobalUplinkLimits()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommand_RelayConfigureFwdLimitReqValidationError{
+ field: "global_uplink_limits",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "overall_limits":
+
+ if v, ok := interface{}(m.GetOverallLimits()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommand_RelayConfigureFwdLimitReqValidationError{
+ field: "overall_limits",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
}
}
default:
- return MACCommand_BeaconTimingAnsValidationError{
+ return MACCommand_RelayConfigureFwdLimitReqValidationError{
field: name,
reason: "invalid field path",
}
@@ -6564,10 +8851,10 @@ func (m *MACCommand_BeaconTimingAns) ValidateFields(paths ...string) error {
return nil
}
-// MACCommand_BeaconTimingAnsValidationError is the validation error returned
-// by MACCommand_BeaconTimingAns.ValidateFields if the designated constraints
-// aren't met.
-type MACCommand_BeaconTimingAnsValidationError struct {
+// MACCommand_RelayConfigureFwdLimitReqValidationError is the validation error
+// returned by MACCommand_RelayConfigureFwdLimitReq.ValidateFields if the
+// designated constraints aren't met.
+type MACCommand_RelayConfigureFwdLimitReqValidationError struct {
field string
reason string
cause error
@@ -6575,24 +8862,24 @@ type MACCommand_BeaconTimingAnsValidationError struct {
}
// Field function returns field value.
-func (e MACCommand_BeaconTimingAnsValidationError) Field() string { return e.field }
+func (e MACCommand_RelayConfigureFwdLimitReqValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e MACCommand_BeaconTimingAnsValidationError) Reason() string { return e.reason }
+func (e MACCommand_RelayConfigureFwdLimitReqValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e MACCommand_BeaconTimingAnsValidationError) Cause() error { return e.cause }
+func (e MACCommand_RelayConfigureFwdLimitReqValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e MACCommand_BeaconTimingAnsValidationError) Key() bool { return e.key }
+func (e MACCommand_RelayConfigureFwdLimitReqValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e MACCommand_BeaconTimingAnsValidationError) ErrorName() string {
- return "MACCommand_BeaconTimingAnsValidationError"
+func (e MACCommand_RelayConfigureFwdLimitReqValidationError) ErrorName() string {
+ return "MACCommand_RelayConfigureFwdLimitReqValidationError"
}
// Error satisfies the builtin error interface
-func (e MACCommand_BeaconTimingAnsValidationError) Error() string {
+func (e MACCommand_RelayConfigureFwdLimitReqValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -6604,14 +8891,14 @@ func (e MACCommand_BeaconTimingAnsValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sMACCommand_BeaconTimingAns.%s: %s%s",
+ "invalid %sMACCommand_RelayConfigureFwdLimitReq.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = MACCommand_BeaconTimingAnsValidationError{}
+var _ error = MACCommand_RelayConfigureFwdLimitReqValidationError{}
var _ interface {
Field() string
@@ -6619,46 +8906,22 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = MACCommand_BeaconTimingAnsValidationError{}
-
-// ValidateFields checks the field values on MACCommand_BeaconFreqReq with the
-// rules defined in the proto definition for this message. If any rules are
-// violated, an error is returned.
-func (m *MACCommand_BeaconFreqReq) ValidateFields(paths ...string) error {
- if m == nil {
- return nil
- }
-
- if len(paths) == 0 {
- paths = MACCommand_BeaconFreqReqFieldPathsNested
- }
-
- for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
- _ = subs
- switch name {
- case "frequency":
-
- if val := m.GetFrequency(); val > 0 && val < 100000 {
- return MACCommand_BeaconFreqReqValidationError{
- field: "frequency",
- reason: "value must be outside range (0, 100000)",
- }
- }
+} = MACCommand_RelayConfigureFwdLimitReqValidationError{}
- default:
- return MACCommand_BeaconFreqReqValidationError{
- field: name,
- reason: "invalid field path",
- }
- }
+// ValidateFields checks the field values on
+// MACCommand_RelayConfigureFwdLimitAns with the rules defined in the proto
+// definition for this message. If any rules are violated, an error is returned.
+func (m *MACCommand_RelayConfigureFwdLimitAns) ValidateFields(paths ...string) error {
+ if len(paths) > 0 {
+ return fmt.Errorf("message MACCommand_RelayConfigureFwdLimitAns has no fields, but paths %s were specified", paths)
}
return nil
}
-// MACCommand_BeaconFreqReqValidationError is the validation error returned by
-// MACCommand_BeaconFreqReq.ValidateFields if the designated constraints
-// aren't met.
-type MACCommand_BeaconFreqReqValidationError struct {
+// MACCommand_RelayConfigureFwdLimitAnsValidationError is the validation error
+// returned by MACCommand_RelayConfigureFwdLimitAns.ValidateFields if the
+// designated constraints aren't met.
+type MACCommand_RelayConfigureFwdLimitAnsValidationError struct {
field string
reason string
cause error
@@ -6666,24 +8929,24 @@ type MACCommand_BeaconFreqReqValidationError struct {
}
// Field function returns field value.
-func (e MACCommand_BeaconFreqReqValidationError) Field() string { return e.field }
+func (e MACCommand_RelayConfigureFwdLimitAnsValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e MACCommand_BeaconFreqReqValidationError) Reason() string { return e.reason }
+func (e MACCommand_RelayConfigureFwdLimitAnsValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e MACCommand_BeaconFreqReqValidationError) Cause() error { return e.cause }
+func (e MACCommand_RelayConfigureFwdLimitAnsValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e MACCommand_BeaconFreqReqValidationError) Key() bool { return e.key }
+func (e MACCommand_RelayConfigureFwdLimitAnsValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e MACCommand_BeaconFreqReqValidationError) ErrorName() string {
- return "MACCommand_BeaconFreqReqValidationError"
+func (e MACCommand_RelayConfigureFwdLimitAnsValidationError) ErrorName() string {
+ return "MACCommand_RelayConfigureFwdLimitAnsValidationError"
}
// Error satisfies the builtin error interface
-func (e MACCommand_BeaconFreqReqValidationError) Error() string {
+func (e MACCommand_RelayConfigureFwdLimitAnsValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -6695,14 +8958,14 @@ func (e MACCommand_BeaconFreqReqValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sMACCommand_BeaconFreqReq.%s: %s%s",
+ "invalid %sMACCommand_RelayConfigureFwdLimitAns.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = MACCommand_BeaconFreqReqValidationError{}
+var _ error = MACCommand_RelayConfigureFwdLimitAnsValidationError{}
var _ interface {
Field() string
@@ -6710,27 +8973,56 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = MACCommand_BeaconFreqReqValidationError{}
+} = MACCommand_RelayConfigureFwdLimitAnsValidationError{}
-// ValidateFields checks the field values on MACCommand_BeaconFreqAns with the
-// rules defined in the proto definition for this message. If any rules are
-// violated, an error is returned.
-func (m *MACCommand_BeaconFreqAns) ValidateFields(paths ...string) error {
+// ValidateFields checks the field values on
+// MACCommand_RelayNotifyNewEndDeviceReq with the rules defined in the proto
+// definition for this message. If any rules are violated, an error is returned.
+func (m *MACCommand_RelayNotifyNewEndDeviceReq) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = MACCommand_BeaconFreqAnsFieldPathsNested
+ paths = MACCommand_RelayNotifyNewEndDeviceReqFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "frequency_ack":
- // no validation rules for FrequencyAck
+ case "dev_addr":
+
+ if len(m.GetDevAddr()) > 0 {
+
+ if len(m.GetDevAddr()) != 4 {
+ return MACCommand_RelayNotifyNewEndDeviceReqValidationError{
+ field: "dev_addr",
+ reason: "value length must be 4 bytes",
+ }
+ }
+
+ }
+
+ case "snr":
+
+ if val := m.GetSnr(); val < -20 || val > 11 {
+ return MACCommand_RelayNotifyNewEndDeviceReqValidationError{
+ field: "snr",
+ reason: "value must be inside range [-20, 11]",
+ }
+ }
+
+ case "rssi":
+
+ if val := m.GetRssi(); val < -142 || val > -15 {
+ return MACCommand_RelayNotifyNewEndDeviceReqValidationError{
+ field: "rssi",
+ reason: "value must be inside range [-142, -15]",
+ }
+ }
+
default:
- return MACCommand_BeaconFreqAnsValidationError{
+ return MACCommand_RelayNotifyNewEndDeviceReqValidationError{
field: name,
reason: "invalid field path",
}
@@ -6739,10 +9031,10 @@ func (m *MACCommand_BeaconFreqAns) ValidateFields(paths ...string) error {
return nil
}
-// MACCommand_BeaconFreqAnsValidationError is the validation error returned by
-// MACCommand_BeaconFreqAns.ValidateFields if the designated constraints
-// aren't met.
-type MACCommand_BeaconFreqAnsValidationError struct {
+// MACCommand_RelayNotifyNewEndDeviceReqValidationError is the validation error
+// returned by MACCommand_RelayNotifyNewEndDeviceReq.ValidateFields if the
+// designated constraints aren't met.
+type MACCommand_RelayNotifyNewEndDeviceReqValidationError struct {
field string
reason string
cause error
@@ -6750,24 +9042,24 @@ type MACCommand_BeaconFreqAnsValidationError struct {
}
// Field function returns field value.
-func (e MACCommand_BeaconFreqAnsValidationError) Field() string { return e.field }
+func (e MACCommand_RelayNotifyNewEndDeviceReqValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e MACCommand_BeaconFreqAnsValidationError) Reason() string { return e.reason }
+func (e MACCommand_RelayNotifyNewEndDeviceReqValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e MACCommand_BeaconFreqAnsValidationError) Cause() error { return e.cause }
+func (e MACCommand_RelayNotifyNewEndDeviceReqValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e MACCommand_BeaconFreqAnsValidationError) Key() bool { return e.key }
+func (e MACCommand_RelayNotifyNewEndDeviceReqValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e MACCommand_BeaconFreqAnsValidationError) ErrorName() string {
- return "MACCommand_BeaconFreqAnsValidationError"
+func (e MACCommand_RelayNotifyNewEndDeviceReqValidationError) ErrorName() string {
+ return "MACCommand_RelayNotifyNewEndDeviceReqValidationError"
}
// Error satisfies the builtin error interface
-func (e MACCommand_BeaconFreqAnsValidationError) Error() string {
+func (e MACCommand_RelayNotifyNewEndDeviceReqValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -6779,14 +9071,14 @@ func (e MACCommand_BeaconFreqAnsValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sMACCommand_BeaconFreqAns.%s: %s%s",
+ "invalid %sMACCommand_RelayNotifyNewEndDeviceReq.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = MACCommand_BeaconFreqAnsValidationError{}
+var _ error = MACCommand_RelayNotifyNewEndDeviceReqValidationError{}
var _ interface {
Field() string
@@ -6794,34 +9086,55 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = MACCommand_BeaconFreqAnsValidationError{}
+} = MACCommand_RelayNotifyNewEndDeviceReqValidationError{}
-// ValidateFields checks the field values on MACCommand_DeviceModeInd with the
-// rules defined in the proto definition for this message. If any rules are
-// violated, an error is returned.
-func (m *MACCommand_DeviceModeInd) ValidateFields(paths ...string) error {
+// ValidateFields checks the field values on
+// MACCommand_RelayConfReq_Configuration with the rules defined in the proto
+// definition for this message. If any rules are violated, an error is returned.
+func (m *MACCommand_RelayConfReq_Configuration) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = MACCommand_DeviceModeIndFieldPathsNested
+ paths = MACCommand_RelayConfReq_ConfigurationFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "class":
+ case "second_channel":
- if _, ok := Class_name[int32(m.GetClass())]; !ok {
- return MACCommand_DeviceModeIndValidationError{
- field: "class",
+ if v, ok := interface{}(m.GetSecondChannel()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommand_RelayConfReq_ConfigurationValidationError{
+ field: "second_channel",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "default_channel_index":
+
+ if m.GetDefaultChannelIndex() > 255 {
+ return MACCommand_RelayConfReq_ConfigurationValidationError{
+ field: "default_channel_index",
+ reason: "value must be less than or equal to 255",
+ }
+ }
+
+ case "cad_periodicity":
+
+ if _, ok := RelayCADPeriodicity_name[int32(m.GetCadPeriodicity())]; !ok {
+ return MACCommand_RelayConfReq_ConfigurationValidationError{
+ field: "cad_periodicity",
reason: "value must be one of the defined enum values",
}
}
default:
- return MACCommand_DeviceModeIndValidationError{
+ return MACCommand_RelayConfReq_ConfigurationValidationError{
field: name,
reason: "invalid field path",
}
@@ -6830,10 +9143,10 @@ func (m *MACCommand_DeviceModeInd) ValidateFields(paths ...string) error {
return nil
}
-// MACCommand_DeviceModeIndValidationError is the validation error returned by
-// MACCommand_DeviceModeInd.ValidateFields if the designated constraints
-// aren't met.
-type MACCommand_DeviceModeIndValidationError struct {
+// MACCommand_RelayConfReq_ConfigurationValidationError is the validation error
+// returned by MACCommand_RelayConfReq_Configuration.ValidateFields if the
+// designated constraints aren't met.
+type MACCommand_RelayConfReq_ConfigurationValidationError struct {
field string
reason string
cause error
@@ -6841,24 +9154,24 @@ type MACCommand_DeviceModeIndValidationError struct {
}
// Field function returns field value.
-func (e MACCommand_DeviceModeIndValidationError) Field() string { return e.field }
+func (e MACCommand_RelayConfReq_ConfigurationValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e MACCommand_DeviceModeIndValidationError) Reason() string { return e.reason }
+func (e MACCommand_RelayConfReq_ConfigurationValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
-func (e MACCommand_DeviceModeIndValidationError) Cause() error { return e.cause }
+func (e MACCommand_RelayConfReq_ConfigurationValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e MACCommand_DeviceModeIndValidationError) Key() bool { return e.key }
+func (e MACCommand_RelayConfReq_ConfigurationValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e MACCommand_DeviceModeIndValidationError) ErrorName() string {
- return "MACCommand_DeviceModeIndValidationError"
+func (e MACCommand_RelayConfReq_ConfigurationValidationError) ErrorName() string {
+ return "MACCommand_RelayConfReq_ConfigurationValidationError"
}
// Error satisfies the builtin error interface
-func (e MACCommand_DeviceModeIndValidationError) Error() string {
+func (e MACCommand_RelayConfReq_ConfigurationValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -6870,14 +9183,14 @@ func (e MACCommand_DeviceModeIndValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sMACCommand_DeviceModeInd.%s: %s%s",
+ "invalid %sMACCommand_RelayConfReq_Configuration.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = MACCommand_DeviceModeIndValidationError{}
+var _ error = MACCommand_RelayConfReq_ConfigurationValidationError{}
var _ interface {
Field() string
@@ -6885,34 +9198,128 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = MACCommand_DeviceModeIndValidationError{}
+} = MACCommand_RelayConfReq_ConfigurationValidationError{}
-// ValidateFields checks the field values on MACCommand_DeviceModeConf with the
-// rules defined in the proto definition for this message. If any rules are
-// violated, an error is returned.
-func (m *MACCommand_DeviceModeConf) ValidateFields(paths ...string) error {
+// ValidateFields checks the field values on
+// MACCommand_RelayEndDeviceConfReq_Configuration with the rules defined in
+// the proto definition for this message. If any rules are violated, an error
+// is returned.
+func (m *MACCommand_RelayEndDeviceConfReq_Configuration) ValidateFields(paths ...string) error {
if m == nil {
return nil
}
if len(paths) == 0 {
- paths = MACCommand_DeviceModeConfFieldPathsNested
+ paths = MACCommand_RelayEndDeviceConfReq_ConfigurationFieldPathsNested
}
for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
_ = subs
switch name {
- case "class":
+ case "backoff":
- if _, ok := Class_name[int32(m.GetClass())]; !ok {
- return MACCommand_DeviceModeConfValidationError{
- field: "class",
- reason: "value must be one of the defined enum values",
+ if m.GetBackoff() > 63 {
+ return MACCommand_RelayEndDeviceConfReq_ConfigurationValidationError{
+ field: "backoff",
+ reason: "value must be less than or equal to 63",
+ }
+ }
+
+ case "second_channel":
+
+ if v, ok := interface{}(m.GetSecondChannel()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommand_RelayEndDeviceConfReq_ConfigurationValidationError{
+ field: "second_channel",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "serving_device_id":
+
+ if utf8.RuneCountInString(m.GetServingDeviceId()) > 36 {
+ return MACCommand_RelayEndDeviceConfReq_ConfigurationValidationError{
+ field: "serving_device_id",
+ reason: "value length must be at most 36 runes",
+ }
+ }
+
+ if !_MACCommand_RelayEndDeviceConfReq_Configuration_ServingDeviceId_Pattern.MatchString(m.GetServingDeviceId()) {
+ return MACCommand_RelayEndDeviceConfReq_ConfigurationValidationError{
+ field: "serving_device_id",
+ reason: "value does not match regex pattern \"^[a-z0-9](?:[-]?[a-z0-9]){2,}$\"",
+ }
+ }
+
+ case "mode":
+ if m.Mode == nil {
+ return MACCommand_RelayEndDeviceConfReq_ConfigurationValidationError{
+ field: "mode",
+ reason: "value is required",
+ }
+ }
+ if len(subs) == 0 {
+ subs = []string{
+ "always", "dynamic", "end_device_controlled",
}
}
+ for name, subs := range _processPaths(subs) {
+ _ = subs
+ switch name {
+ case "always":
+ w, ok := m.Mode.(*MACCommand_RelayEndDeviceConfReq_Configuration_Always)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetAlways()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommand_RelayEndDeviceConfReq_ConfigurationValidationError{
+ field: "always",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "dynamic":
+ w, ok := m.Mode.(*MACCommand_RelayEndDeviceConfReq_Configuration_Dynamic)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetDynamic()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommand_RelayEndDeviceConfReq_ConfigurationValidationError{
+ field: "dynamic",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
+ case "end_device_controlled":
+ w, ok := m.Mode.(*MACCommand_RelayEndDeviceConfReq_Configuration_EndDeviceControlled)
+ if !ok || w == nil {
+ continue
+ }
+
+ if v, ok := interface{}(m.GetEndDeviceControlled()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return MACCommand_RelayEndDeviceConfReq_ConfigurationValidationError{
+ field: "end_device_controlled",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+ }
+ }
default:
- return MACCommand_DeviceModeConfValidationError{
+ return MACCommand_RelayEndDeviceConfReq_ConfigurationValidationError{
field: name,
reason: "invalid field path",
}
@@ -6921,10 +9328,11 @@ func (m *MACCommand_DeviceModeConf) ValidateFields(paths ...string) error {
return nil
}
-// MACCommand_DeviceModeConfValidationError is the validation error returned by
-// MACCommand_DeviceModeConf.ValidateFields if the designated constraints
-// aren't met.
-type MACCommand_DeviceModeConfValidationError struct {
+// MACCommand_RelayEndDeviceConfReq_ConfigurationValidationError is the
+// validation error returned by
+// MACCommand_RelayEndDeviceConfReq_Configuration.ValidateFields if the
+// designated constraints aren't met.
+type MACCommand_RelayEndDeviceConfReq_ConfigurationValidationError struct {
field string
reason string
cause error
@@ -6932,24 +9340,26 @@ type MACCommand_DeviceModeConfValidationError struct {
}
// Field function returns field value.
-func (e MACCommand_DeviceModeConfValidationError) Field() string { return e.field }
+func (e MACCommand_RelayEndDeviceConfReq_ConfigurationValidationError) Field() string { return e.field }
// Reason function returns reason value.
-func (e MACCommand_DeviceModeConfValidationError) Reason() string { return e.reason }
+func (e MACCommand_RelayEndDeviceConfReq_ConfigurationValidationError) Reason() string {
+ return e.reason
+}
// Cause function returns cause value.
-func (e MACCommand_DeviceModeConfValidationError) Cause() error { return e.cause }
+func (e MACCommand_RelayEndDeviceConfReq_ConfigurationValidationError) Cause() error { return e.cause }
// Key function returns key value.
-func (e MACCommand_DeviceModeConfValidationError) Key() bool { return e.key }
+func (e MACCommand_RelayEndDeviceConfReq_ConfigurationValidationError) Key() bool { return e.key }
// ErrorName returns error name.
-func (e MACCommand_DeviceModeConfValidationError) ErrorName() string {
- return "MACCommand_DeviceModeConfValidationError"
+func (e MACCommand_RelayEndDeviceConfReq_ConfigurationValidationError) ErrorName() string {
+ return "MACCommand_RelayEndDeviceConfReq_ConfigurationValidationError"
}
// Error satisfies the builtin error interface
-func (e MACCommand_DeviceModeConfValidationError) Error() string {
+func (e MACCommand_RelayEndDeviceConfReq_ConfigurationValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
@@ -6961,14 +9371,14 @@ func (e MACCommand_DeviceModeConfValidationError) Error() string {
}
return fmt.Sprintf(
- "invalid %sMACCommand_DeviceModeConf.%s: %s%s",
+ "invalid %sMACCommand_RelayEndDeviceConfReq_Configuration.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
-var _ error = MACCommand_DeviceModeConfValidationError{}
+var _ error = MACCommand_RelayEndDeviceConfReq_ConfigurationValidationError{}
var _ interface {
Field() string
@@ -6976,4 +9386,6 @@ var _ interface {
Key() bool
Cause() error
ErrorName() string
-} = MACCommand_DeviceModeConfValidationError{}
+} = MACCommand_RelayEndDeviceConfReq_ConfigurationValidationError{}
+
+var _MACCommand_RelayEndDeviceConfReq_Configuration_ServingDeviceId_Pattern = regexp.MustCompile("^[a-z0-9](?:[-]?[a-z0-9]){2,}$")
diff --git a/pkg/ttnpb/lorawan_flags.pb.go b/pkg/ttnpb/lorawan_flags.pb.go
index c46fef0ce9..ab460b1687 100644
--- a/pkg/ttnpb/lorawan_flags.pb.go
+++ b/pkg/ttnpb/lorawan_flags.pb.go
@@ -8,6 +8,7 @@ package ttnpb
import (
flagsplugin "github.com/TheThingsIndustries/protoc-gen-go-flags/flagsplugin"
+ golang "github.com/TheThingsIndustries/protoc-gen-go-flags/golang"
pflag "github.com/spf13/pflag"
customflags "go.thethings.network/lorawan-stack/v3/cmd/ttn-lw-cli/customflags"
)
@@ -509,6 +510,36 @@ func PathsFromSelectFlagsForLoRaDataRate(flags *pflag.FlagSet, prefix string) (p
return paths, nil
}
+// AddSetFlagsForLoRaDataRate adds flags to select fields in LoRaDataRate.
+func AddSetFlagsForLoRaDataRate(flags *pflag.FlagSet, prefix string, hidden bool) {
+ flags.AddFlag(flagsplugin.NewUint32Flag(flagsplugin.Prefix("bandwidth", prefix), "", flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewUint32Flag(flagsplugin.Prefix("spreading-factor", prefix), "", flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewStringFlag(flagsplugin.Prefix("coding-rate", prefix), "", flagsplugin.WithHidden(hidden)))
+}
+
+// SetFromFlags sets the LoRaDataRate message from flags.
+func (m *LoRaDataRate) SetFromFlags(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ if val, changed, err := flagsplugin.GetUint32(flags, flagsplugin.Prefix("bandwidth", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.Bandwidth = val
+ paths = append(paths, flagsplugin.Prefix("bandwidth", prefix))
+ }
+ if val, changed, err := flagsplugin.GetUint32(flags, flagsplugin.Prefix("spreading_factor", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.SpreadingFactor = val
+ paths = append(paths, flagsplugin.Prefix("spreading_factor", prefix))
+ }
+ if val, changed, err := flagsplugin.GetString(flags, flagsplugin.Prefix("coding_rate", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.CodingRate = val
+ paths = append(paths, flagsplugin.Prefix("coding_rate", prefix))
+ }
+ return paths, nil
+}
+
// AddSelectFlagsForFSKDataRate adds flags to select fields in FSKDataRate.
func AddSelectFlagsForFSKDataRate(flags *pflag.FlagSet, prefix string, hidden bool) {
flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("bit-rate", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("bit-rate", prefix), false), flagsplugin.WithHidden(hidden)))
@@ -524,6 +555,22 @@ func PathsFromSelectFlagsForFSKDataRate(flags *pflag.FlagSet, prefix string) (pa
return paths, nil
}
+// AddSetFlagsForFSKDataRate adds flags to select fields in FSKDataRate.
+func AddSetFlagsForFSKDataRate(flags *pflag.FlagSet, prefix string, hidden bool) {
+ flags.AddFlag(flagsplugin.NewUint32Flag(flagsplugin.Prefix("bit-rate", prefix), "", flagsplugin.WithHidden(hidden)))
+}
+
+// SetFromFlags sets the FSKDataRate message from flags.
+func (m *FSKDataRate) SetFromFlags(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ if val, changed, err := flagsplugin.GetUint32(flags, flagsplugin.Prefix("bit_rate", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.BitRate = val
+ paths = append(paths, flagsplugin.Prefix("bit_rate", prefix))
+ }
+ return paths, nil
+}
+
// AddSelectFlagsForLRFHSSDataRate adds flags to select fields in LRFHSSDataRate.
func AddSelectFlagsForLRFHSSDataRate(flags *pflag.FlagSet, prefix string, hidden bool) {
flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("modulation-type", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("modulation-type", prefix), false), flagsplugin.WithHidden(hidden)))
@@ -551,6 +598,36 @@ func PathsFromSelectFlagsForLRFHSSDataRate(flags *pflag.FlagSet, prefix string)
return paths, nil
}
+// AddSetFlagsForLRFHSSDataRate adds flags to select fields in LRFHSSDataRate.
+func AddSetFlagsForLRFHSSDataRate(flags *pflag.FlagSet, prefix string, hidden bool) {
+ flags.AddFlag(flagsplugin.NewUint32Flag(flagsplugin.Prefix("modulation-type", prefix), "", flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewUint32Flag(flagsplugin.Prefix("operating-channel-width", prefix), "", flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewStringFlag(flagsplugin.Prefix("coding-rate", prefix), "", flagsplugin.WithHidden(hidden)))
+}
+
+// SetFromFlags sets the LRFHSSDataRate message from flags.
+func (m *LRFHSSDataRate) SetFromFlags(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ if val, changed, err := flagsplugin.GetUint32(flags, flagsplugin.Prefix("modulation_type", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.ModulationType = val
+ paths = append(paths, flagsplugin.Prefix("modulation_type", prefix))
+ }
+ if val, changed, err := flagsplugin.GetUint32(flags, flagsplugin.Prefix("operating_channel_width", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.OperatingChannelWidth = val
+ paths = append(paths, flagsplugin.Prefix("operating_channel_width", prefix))
+ }
+ if val, changed, err := flagsplugin.GetString(flags, flagsplugin.Prefix("coding_rate", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.CodingRate = val
+ paths = append(paths, flagsplugin.Prefix("coding_rate", prefix))
+ }
+ return paths, nil
+}
+
// AddSelectFlagsForDataRate adds flags to select fields in DataRate.
func AddSelectFlagsForDataRate(flags *pflag.FlagSet, prefix string, hidden bool) {
flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("modulation.lora", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("modulation.lora", prefix), true), flagsplugin.WithHidden(hidden)))
@@ -596,6 +673,54 @@ func PathsFromSelectFlagsForDataRate(flags *pflag.FlagSet, prefix string) (paths
return paths, nil
}
+// AddSetFlagsForDataRate adds flags to select fields in DataRate.
+func AddSetFlagsForDataRate(flags *pflag.FlagSet, prefix string, hidden bool) {
+ AddSetFlagsForLoRaDataRate(flags, flagsplugin.Prefix("modulation.lora", prefix), hidden)
+ AddSetFlagsForFSKDataRate(flags, flagsplugin.Prefix("modulation.fsk", prefix), hidden)
+ AddSetFlagsForLRFHSSDataRate(flags, flagsplugin.Prefix("modulation.lrfhss", prefix), hidden)
+}
+
+// SetFromFlags sets the DataRate message from flags.
+func (m *DataRate) SetFromFlags(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ if changed := flagsplugin.IsAnyPrefixSet(flags, flagsplugin.Prefix("modulation.lora", prefix)); changed {
+ ov := &DataRate_Lora{}
+ if ov.Lora == nil {
+ ov.Lora = &LoRaDataRate{}
+ }
+ if setPaths, err := ov.Lora.SetFromFlags(flags, flagsplugin.Prefix("modulation.lora", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, setPaths...)
+ }
+ m.Modulation = ov
+ }
+ if changed := flagsplugin.IsAnyPrefixSet(flags, flagsplugin.Prefix("modulation.fsk", prefix)); changed {
+ ov := &DataRate_Fsk{}
+ if ov.Fsk == nil {
+ ov.Fsk = &FSKDataRate{}
+ }
+ if setPaths, err := ov.Fsk.SetFromFlags(flags, flagsplugin.Prefix("modulation.fsk", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, setPaths...)
+ }
+ m.Modulation = ov
+ }
+ if changed := flagsplugin.IsAnyPrefixSet(flags, flagsplugin.Prefix("modulation.lrfhss", prefix)); changed {
+ ov := &DataRate_Lrfhss{}
+ if ov.Lrfhss == nil {
+ ov.Lrfhss = &LRFHSSDataRate{}
+ }
+ if setPaths, err := ov.Lrfhss.SetFromFlags(flags, flagsplugin.Prefix("modulation.lrfhss", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, setPaths...)
+ }
+ m.Modulation = ov
+ }
+ return paths, nil
+}
+
// AddSelectFlagsForTxSettings_Downlink adds flags to select fields in TxSettings_Downlink.
func AddSelectFlagsForTxSettings_Downlink(flags *pflag.FlagSet, prefix string, hidden bool) {
flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("antenna-index", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("antenna-index", prefix), false), flagsplugin.WithHidden(hidden)))
@@ -623,6 +748,36 @@ func PathsFromSelectFlagsForTxSettings_Downlink(flags *pflag.FlagSet, prefix str
return paths, nil
}
+// AddSetFlagsForTxSettings_Downlink adds flags to select fields in TxSettings_Downlink.
+func AddSetFlagsForTxSettings_Downlink(flags *pflag.FlagSet, prefix string, hidden bool) {
+ flags.AddFlag(flagsplugin.NewUint32Flag(flagsplugin.Prefix("antenna-index", prefix), "", flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewFloat32Flag(flagsplugin.Prefix("tx-power", prefix), "", flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("invert-polarization", prefix), "", flagsplugin.WithHidden(hidden)))
+}
+
+// SetFromFlags sets the TxSettings_Downlink message from flags.
+func (m *TxSettings_Downlink) SetFromFlags(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ if val, changed, err := flagsplugin.GetUint32(flags, flagsplugin.Prefix("antenna_index", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.AntennaIndex = val
+ paths = append(paths, flagsplugin.Prefix("antenna_index", prefix))
+ }
+ if val, changed, err := flagsplugin.GetFloat32(flags, flagsplugin.Prefix("tx_power", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.TxPower = val
+ paths = append(paths, flagsplugin.Prefix("tx_power", prefix))
+ }
+ if val, changed, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("invert_polarization", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.InvertPolarization = val
+ paths = append(paths, flagsplugin.Prefix("invert_polarization", prefix))
+ }
+ return paths, nil
+}
+
// AddSelectFlagsForTxSettings adds flags to select fields in TxSettings.
func AddSelectFlagsForTxSettings(flags *pflag.FlagSet, prefix string, hidden bool) {
flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("data-rate", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("data-rate", prefix), true), flagsplugin.WithHidden(hidden)))
@@ -686,6 +841,480 @@ func PathsFromSelectFlagsForTxSettings(flags *pflag.FlagSet, prefix string) (pat
return paths, nil
}
+// AddSetFlagsForTxSettings adds flags to select fields in TxSettings.
+func AddSetFlagsForTxSettings(flags *pflag.FlagSet, prefix string, hidden bool) {
+ AddSetFlagsForDataRate(flags, flagsplugin.Prefix("data-rate", prefix), hidden)
+ flags.AddFlag(flagsplugin.NewUint64Flag(flagsplugin.Prefix("frequency", prefix), "", flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("enable-crc", prefix), "", flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewUint32Flag(flagsplugin.Prefix("timestamp", prefix), "", flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewTimestampFlag(flagsplugin.Prefix("time", prefix), "", flagsplugin.WithHidden(hidden)))
+ AddSetFlagsForTxSettings_Downlink(flags, flagsplugin.Prefix("downlink", prefix), hidden)
+ flags.AddFlag(flagsplugin.NewInt64Flag(flagsplugin.Prefix("concentrator-timestamp", prefix), "", flagsplugin.WithHidden(hidden)))
+}
+
+// SetFromFlags sets the TxSettings message from flags.
+func (m *TxSettings) SetFromFlags(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ if changed := flagsplugin.IsAnyPrefixSet(flags, flagsplugin.Prefix("data_rate", prefix)); changed {
+ if m.DataRate == nil {
+ m.DataRate = &DataRate{}
+ }
+ if setPaths, err := m.DataRate.SetFromFlags(flags, flagsplugin.Prefix("data_rate", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, setPaths...)
+ }
+ }
+ if val, changed, err := flagsplugin.GetUint64(flags, flagsplugin.Prefix("frequency", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.Frequency = val
+ paths = append(paths, flagsplugin.Prefix("frequency", prefix))
+ }
+ if val, changed, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("enable_crc", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.EnableCrc = val
+ paths = append(paths, flagsplugin.Prefix("enable_crc", prefix))
+ }
+ if val, changed, err := flagsplugin.GetUint32(flags, flagsplugin.Prefix("timestamp", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.Timestamp = val
+ paths = append(paths, flagsplugin.Prefix("timestamp", prefix))
+ }
+ if val, changed, err := flagsplugin.GetTimestamp(flags, flagsplugin.Prefix("time", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.Time = golang.SetTimestamp(val)
+ paths = append(paths, flagsplugin.Prefix("time", prefix))
+ }
+ if changed := flagsplugin.IsAnyPrefixSet(flags, flagsplugin.Prefix("downlink", prefix)); changed {
+ if m.Downlink == nil {
+ m.Downlink = &TxSettings_Downlink{}
+ }
+ if setPaths, err := m.Downlink.SetFromFlags(flags, flagsplugin.Prefix("downlink", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, setPaths...)
+ }
+ }
+ if val, changed, err := flagsplugin.GetInt64(flags, flagsplugin.Prefix("concentrator_timestamp", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.ConcentratorTimestamp = val
+ paths = append(paths, flagsplugin.Prefix("concentrator_timestamp", prefix))
+ }
+ return paths, nil
+}
+
+// AddSelectFlagsForRelaySecondChannel adds flags to select fields in RelaySecondChannel.
+func AddSelectFlagsForRelaySecondChannel(flags *pflag.FlagSet, prefix string, hidden bool) {
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("ack-offset", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("ack-offset", prefix), false), flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("data-rate-index", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("data-rate-index", prefix), false), flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("frequency", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("frequency", prefix), false), flagsplugin.WithHidden(hidden)))
+}
+
+// SelectFromFlags outputs the fieldmask paths forRelaySecondChannel message from select flags.
+func PathsFromSelectFlagsForRelaySecondChannel(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("ack_offset", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("ack_offset", prefix))
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("data_rate_index", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("data_rate_index", prefix))
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("frequency", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("frequency", prefix))
+ }
+ return paths, nil
+}
+
+// AddSetFlagsForRelaySecondChannel adds flags to select fields in RelaySecondChannel.
+func AddSetFlagsForRelaySecondChannel(flags *pflag.FlagSet, prefix string, hidden bool) {
+ flags.AddFlag(flagsplugin.NewStringFlag(flagsplugin.Prefix("ack-offset", prefix), flagsplugin.EnumValueDesc(RelaySecondChAckOffset_value), flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewStringFlag(flagsplugin.Prefix("data-rate-index", prefix), flagsplugin.EnumValueDesc(DataRateIndex_value, DataRateIndex_customvalue), flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewUint64Flag(flagsplugin.Prefix("frequency", prefix), "", flagsplugin.WithHidden(hidden)))
+}
+
+// SetFromFlags sets the RelaySecondChannel message from flags.
+func (m *RelaySecondChannel) SetFromFlags(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ if val, changed, err := flagsplugin.GetString(flags, flagsplugin.Prefix("ack_offset", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ enumValue, err := flagsplugin.SetEnumString(val, RelaySecondChAckOffset_value)
+ if err != nil {
+ return nil, err
+ }
+ m.AckOffset = RelaySecondChAckOffset(enumValue)
+ paths = append(paths, flagsplugin.Prefix("ack_offset", prefix))
+ }
+ if val, changed, err := flagsplugin.GetString(flags, flagsplugin.Prefix("data_rate_index", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ enumValue, err := flagsplugin.SetEnumString(val, DataRateIndex_value, DataRateIndex_customvalue)
+ if err != nil {
+ return nil, err
+ }
+ m.DataRateIndex = DataRateIndex(enumValue)
+ paths = append(paths, flagsplugin.Prefix("data_rate_index", prefix))
+ }
+ if val, changed, err := flagsplugin.GetUint64(flags, flagsplugin.Prefix("frequency", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.Frequency = val
+ paths = append(paths, flagsplugin.Prefix("frequency", prefix))
+ }
+ return paths, nil
+}
+
+// AddSelectFlagsForRelayUplinkForwardLimits adds flags to select fields in RelayUplinkForwardLimits.
+func AddSelectFlagsForRelayUplinkForwardLimits(flags *pflag.FlagSet, prefix string, hidden bool) {
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("bucket-size", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("bucket-size", prefix), false), flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("reload-rate", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("reload-rate", prefix), false), flagsplugin.WithHidden(hidden)))
+}
+
+// SelectFromFlags outputs the fieldmask paths forRelayUplinkForwardLimits message from select flags.
+func PathsFromSelectFlagsForRelayUplinkForwardLimits(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("bucket_size", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("bucket_size", prefix))
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("reload_rate", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("reload_rate", prefix))
+ }
+ return paths, nil
+}
+
+// AddSetFlagsForRelayUplinkForwardLimits adds flags to select fields in RelayUplinkForwardLimits.
+func AddSetFlagsForRelayUplinkForwardLimits(flags *pflag.FlagSet, prefix string, hidden bool) {
+ flags.AddFlag(flagsplugin.NewStringFlag(flagsplugin.Prefix("bucket-size", prefix), flagsplugin.EnumValueDesc(RelayLimitBucketSize_value), flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewUint32Flag(flagsplugin.Prefix("reload-rate", prefix), "", flagsplugin.WithHidden(hidden)))
+}
+
+// SetFromFlags sets the RelayUplinkForwardLimits message from flags.
+func (m *RelayUplinkForwardLimits) SetFromFlags(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ if val, changed, err := flagsplugin.GetString(flags, flagsplugin.Prefix("bucket_size", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ enumValue, err := flagsplugin.SetEnumString(val, RelayLimitBucketSize_value)
+ if err != nil {
+ return nil, err
+ }
+ m.BucketSize = RelayLimitBucketSize(enumValue)
+ paths = append(paths, flagsplugin.Prefix("bucket_size", prefix))
+ }
+ if val, changed, err := flagsplugin.GetUint32(flags, flagsplugin.Prefix("reload_rate", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.ReloadRate = val
+ paths = append(paths, flagsplugin.Prefix("reload_rate", prefix))
+ }
+ return paths, nil
+}
+
+// AddSelectFlagsForRelayForwardLimits adds flags to select fields in RelayForwardLimits.
+func AddSelectFlagsForRelayForwardLimits(flags *pflag.FlagSet, prefix string, hidden bool) {
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("bucket-size", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("bucket-size", prefix), false), flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("reload-rate", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("reload-rate", prefix), false), flagsplugin.WithHidden(hidden)))
+}
+
+// SelectFromFlags outputs the fieldmask paths forRelayForwardLimits message from select flags.
+func PathsFromSelectFlagsForRelayForwardLimits(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("bucket_size", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("bucket_size", prefix))
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("reload_rate", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("reload_rate", prefix))
+ }
+ return paths, nil
+}
+
+// AddSetFlagsForRelayForwardLimits adds flags to select fields in RelayForwardLimits.
+func AddSetFlagsForRelayForwardLimits(flags *pflag.FlagSet, prefix string, hidden bool) {
+ flags.AddFlag(flagsplugin.NewStringFlag(flagsplugin.Prefix("bucket-size", prefix), flagsplugin.EnumValueDesc(RelayLimitBucketSize_value), flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewUint32Flag(flagsplugin.Prefix("reload-rate", prefix), "", flagsplugin.WithHidden(hidden)))
+}
+
+// SetFromFlags sets the RelayForwardLimits message from flags.
+func (m *RelayForwardLimits) SetFromFlags(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ if val, changed, err := flagsplugin.GetString(flags, flagsplugin.Prefix("bucket_size", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ enumValue, err := flagsplugin.SetEnumString(val, RelayLimitBucketSize_value)
+ if err != nil {
+ return nil, err
+ }
+ m.BucketSize = RelayLimitBucketSize(enumValue)
+ paths = append(paths, flagsplugin.Prefix("bucket_size", prefix))
+ }
+ if val, changed, err := flagsplugin.GetUint32(flags, flagsplugin.Prefix("reload_rate", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.ReloadRate = val
+ paths = append(paths, flagsplugin.Prefix("reload_rate", prefix))
+ }
+ return paths, nil
+}
+
+// AddSelectFlagsForRelayEndDeviceAlwaysMode adds flags to select fields in RelayEndDeviceAlwaysMode.
+func AddSelectFlagsForRelayEndDeviceAlwaysMode(flags *pflag.FlagSet, prefix string, hidden bool) {
+}
+
+// SelectFromFlags outputs the fieldmask paths forRelayEndDeviceAlwaysMode message from select flags.
+func PathsFromSelectFlagsForRelayEndDeviceAlwaysMode(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ return paths, nil
+}
+
+// AddSetFlagsForRelayEndDeviceAlwaysMode adds flags to select fields in RelayEndDeviceAlwaysMode.
+func AddSetFlagsForRelayEndDeviceAlwaysMode(flags *pflag.FlagSet, prefix string, hidden bool) {
+}
+
+// SetFromFlags sets the RelayEndDeviceAlwaysMode message from flags.
+func (m *RelayEndDeviceAlwaysMode) SetFromFlags(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ return paths, nil
+}
+
+// AddSelectFlagsForRelayEndDeviceDynamicMode adds flags to select fields in RelayEndDeviceDynamicMode.
+func AddSelectFlagsForRelayEndDeviceDynamicMode(flags *pflag.FlagSet, prefix string, hidden bool) {
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("smart-enable-level", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("smart-enable-level", prefix), false), flagsplugin.WithHidden(hidden)))
+}
+
+// SelectFromFlags outputs the fieldmask paths forRelayEndDeviceDynamicMode message from select flags.
+func PathsFromSelectFlagsForRelayEndDeviceDynamicMode(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("smart_enable_level", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("smart_enable_level", prefix))
+ }
+ return paths, nil
+}
+
+// AddSetFlagsForRelayEndDeviceDynamicMode adds flags to select fields in RelayEndDeviceDynamicMode.
+func AddSetFlagsForRelayEndDeviceDynamicMode(flags *pflag.FlagSet, prefix string, hidden bool) {
+ flags.AddFlag(flagsplugin.NewStringFlag(flagsplugin.Prefix("smart-enable-level", prefix), flagsplugin.EnumValueDesc(RelaySmartEnableLevel_value), flagsplugin.WithHidden(hidden)))
+}
+
+// SetFromFlags sets the RelayEndDeviceDynamicMode message from flags.
+func (m *RelayEndDeviceDynamicMode) SetFromFlags(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ if val, changed, err := flagsplugin.GetString(flags, flagsplugin.Prefix("smart_enable_level", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ enumValue, err := flagsplugin.SetEnumString(val, RelaySmartEnableLevel_value)
+ if err != nil {
+ return nil, err
+ }
+ m.SmartEnableLevel = RelaySmartEnableLevel(enumValue)
+ paths = append(paths, flagsplugin.Prefix("smart_enable_level", prefix))
+ }
+ return paths, nil
+}
+
+// AddSelectFlagsForRelayEndDeviceControlledMode adds flags to select fields in RelayEndDeviceControlledMode.
+func AddSelectFlagsForRelayEndDeviceControlledMode(flags *pflag.FlagSet, prefix string, hidden bool) {
+}
+
+// SelectFromFlags outputs the fieldmask paths forRelayEndDeviceControlledMode message from select flags.
+func PathsFromSelectFlagsForRelayEndDeviceControlledMode(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ return paths, nil
+}
+
+// AddSetFlagsForRelayEndDeviceControlledMode adds flags to select fields in RelayEndDeviceControlledMode.
+func AddSetFlagsForRelayEndDeviceControlledMode(flags *pflag.FlagSet, prefix string, hidden bool) {
+}
+
+// SetFromFlags sets the RelayEndDeviceControlledMode message from flags.
+func (m *RelayEndDeviceControlledMode) SetFromFlags(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ return paths, nil
+}
+
+// AddSelectFlagsForMACCommand_RelayUpdateUplinkListReq adds flags to select fields in MACCommand_RelayUpdateUplinkListReq.
+func AddSelectFlagsForMACCommand_RelayUpdateUplinkListReq(flags *pflag.FlagSet, prefix string, hidden bool) {
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("rule-index", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("rule-index", prefix), false), flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("forward-limits", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("forward-limits", prefix), true), flagsplugin.WithHidden(hidden)))
+ AddSelectFlagsForRelayUplinkForwardLimits(flags, flagsplugin.Prefix("forward-limits", prefix), hidden)
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("dev-addr", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("dev-addr", prefix), false), flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("w-f-cnt", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("w-f-cnt", prefix), false), flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("root-wor-s-key", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("root-wor-s-key", prefix), false), flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("device-id", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("device-id", prefix), false), flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("session-key-id", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("session-key-id", prefix), false), flagsplugin.WithHidden(hidden)))
+}
+
+// SelectFromFlags outputs the fieldmask paths forMACCommand_RelayUpdateUplinkListReq message from select flags.
+func PathsFromSelectFlagsForMACCommand_RelayUpdateUplinkListReq(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("rule_index", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("rule_index", prefix))
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("forward_limits", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("forward_limits", prefix))
+ }
+ if selectPaths, err := PathsFromSelectFlagsForRelayUplinkForwardLimits(flags, flagsplugin.Prefix("forward_limits", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, selectPaths...)
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("dev_addr", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("dev_addr", prefix))
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("w_f_cnt", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("w_f_cnt", prefix))
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("root_wor_s_key", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("root_wor_s_key", prefix))
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("device_id", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("device_id", prefix))
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("session_key_id", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("session_key_id", prefix))
+ }
+ return paths, nil
+}
+
+// AddSetFlagsForMACCommand_RelayUpdateUplinkListReq adds flags to select fields in MACCommand_RelayUpdateUplinkListReq.
+func AddSetFlagsForMACCommand_RelayUpdateUplinkListReq(flags *pflag.FlagSet, prefix string, hidden bool) {
+ flags.AddFlag(flagsplugin.NewUint32Flag(flagsplugin.Prefix("rule-index", prefix), "", flagsplugin.WithHidden(hidden)))
+ AddSetFlagsForRelayUplinkForwardLimits(flags, flagsplugin.Prefix("forward-limits", prefix), hidden)
+ flags.AddFlag(customflags.New4BytesFlag(flagsplugin.Prefix("dev-addr", prefix), "", flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewUint32Flag(flagsplugin.Prefix("w-f-cnt", prefix), "", flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(customflags.New16BytesFlag(flagsplugin.Prefix("root-wor-s-key", prefix), "", flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewStringFlag(flagsplugin.Prefix("device-id", prefix), "", flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewBytesFlag(flagsplugin.Prefix("session-key-id", prefix), "", flagsplugin.WithHidden(hidden)))
+}
+
+// SetFromFlags sets the MACCommand_RelayUpdateUplinkListReq message from flags.
+func (m *MACCommand_RelayUpdateUplinkListReq) SetFromFlags(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ if val, changed, err := flagsplugin.GetUint32(flags, flagsplugin.Prefix("rule_index", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.RuleIndex = val
+ paths = append(paths, flagsplugin.Prefix("rule_index", prefix))
+ }
+ if changed := flagsplugin.IsAnyPrefixSet(flags, flagsplugin.Prefix("forward_limits", prefix)); changed {
+ if m.ForwardLimits == nil {
+ m.ForwardLimits = &RelayUplinkForwardLimits{}
+ }
+ if setPaths, err := m.ForwardLimits.SetFromFlags(flags, flagsplugin.Prefix("forward_limits", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, setPaths...)
+ }
+ }
+ if val, changed, err := customflags.GetExactBytes(flags, flagsplugin.Prefix("dev_addr", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.DevAddr = val
+ paths = append(paths, flagsplugin.Prefix("dev_addr", prefix))
+ }
+ if val, changed, err := flagsplugin.GetUint32(flags, flagsplugin.Prefix("w_f_cnt", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.WFCnt = val
+ paths = append(paths, flagsplugin.Prefix("w_f_cnt", prefix))
+ }
+ if val, changed, err := customflags.GetExactBytes(flags, flagsplugin.Prefix("root_wor_s_key", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.RootWorSKey = val
+ paths = append(paths, flagsplugin.Prefix("root_wor_s_key", prefix))
+ }
+ if val, changed, err := flagsplugin.GetString(flags, flagsplugin.Prefix("device_id", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.DeviceId = val
+ paths = append(paths, flagsplugin.Prefix("device_id", prefix))
+ }
+ if val, changed, err := flagsplugin.GetBytes(flags, flagsplugin.Prefix("session_key_id", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.SessionKeyId = val
+ paths = append(paths, flagsplugin.Prefix("session_key_id", prefix))
+ }
+ return paths, nil
+}
+
+// AddSelectFlagsForMACCommand_RelayNotifyNewEndDeviceReq adds flags to select fields in MACCommand_RelayNotifyNewEndDeviceReq.
+func AddSelectFlagsForMACCommand_RelayNotifyNewEndDeviceReq(flags *pflag.FlagSet, prefix string, hidden bool) {
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("dev-addr", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("dev-addr", prefix), false), flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("snr", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("snr", prefix), false), flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("rssi", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("rssi", prefix), false), flagsplugin.WithHidden(hidden)))
+}
+
+// SelectFromFlags outputs the fieldmask paths forMACCommand_RelayNotifyNewEndDeviceReq message from select flags.
+func PathsFromSelectFlagsForMACCommand_RelayNotifyNewEndDeviceReq(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("dev_addr", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("dev_addr", prefix))
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("snr", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("snr", prefix))
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("rssi", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("rssi", prefix))
+ }
+ return paths, nil
+}
+
+// AddSetFlagsForMACCommand_RelayNotifyNewEndDeviceReq adds flags to select fields in MACCommand_RelayNotifyNewEndDeviceReq.
+func AddSetFlagsForMACCommand_RelayNotifyNewEndDeviceReq(flags *pflag.FlagSet, prefix string, hidden bool) {
+ flags.AddFlag(customflags.New4BytesFlag(flagsplugin.Prefix("dev-addr", prefix), "", flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewInt32Flag(flagsplugin.Prefix("snr", prefix), "", flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewInt32Flag(flagsplugin.Prefix("rssi", prefix), "", flagsplugin.WithHidden(hidden)))
+}
+
+// SetFromFlags sets the MACCommand_RelayNotifyNewEndDeviceReq message from flags.
+func (m *MACCommand_RelayNotifyNewEndDeviceReq) SetFromFlags(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ if val, changed, err := customflags.GetExactBytes(flags, flagsplugin.Prefix("dev_addr", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.DevAddr = val
+ paths = append(paths, flagsplugin.Prefix("dev_addr", prefix))
+ }
+ if val, changed, err := flagsplugin.GetInt32(flags, flagsplugin.Prefix("snr", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.Snr = val
+ paths = append(paths, flagsplugin.Prefix("snr", prefix))
+ }
+ if val, changed, err := flagsplugin.GetInt32(flags, flagsplugin.Prefix("rssi", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.Rssi = val
+ paths = append(paths, flagsplugin.Prefix("rssi", prefix))
+ }
+ return paths, nil
+}
+
// AddSelectFlagsForFrequencyValue adds flags to select fields in FrequencyValue.
func AddSelectFlagsForFrequencyValue(flags *pflag.FlagSet, prefix string, hidden bool) {
flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("value", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("value", prefix), false), flagsplugin.WithHidden(hidden)))
@@ -1027,3 +1656,144 @@ func (m *DeviceEIRPValue) SetFromFlags(flags *pflag.FlagSet, prefix string) (pat
}
return paths, nil
}
+
+// AddSelectFlagsForRelayForwardUplinkReq adds flags to select fields in RelayForwardUplinkReq.
+func AddSelectFlagsForRelayForwardUplinkReq(flags *pflag.FlagSet, prefix string, hidden bool) {
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("data-rate", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("data-rate", prefix), true), flagsplugin.WithHidden(hidden)))
+ AddSelectFlagsForDataRate(flags, flagsplugin.Prefix("data-rate", prefix), hidden)
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("snr", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("snr", prefix), false), flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("rssi", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("rssi", prefix), false), flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("wor-channel", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("wor-channel", prefix), false), flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("frequency", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("frequency", prefix), false), flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("raw-payload", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("raw-payload", prefix), false), flagsplugin.WithHidden(hidden)))
+}
+
+// SelectFromFlags outputs the fieldmask paths forRelayForwardUplinkReq message from select flags.
+func PathsFromSelectFlagsForRelayForwardUplinkReq(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("data_rate", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("data_rate", prefix))
+ }
+ if selectPaths, err := PathsFromSelectFlagsForDataRate(flags, flagsplugin.Prefix("data_rate", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, selectPaths...)
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("snr", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("snr", prefix))
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("rssi", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("rssi", prefix))
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("wor_channel", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("wor_channel", prefix))
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("frequency", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("frequency", prefix))
+ }
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("raw_payload", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("raw_payload", prefix))
+ }
+ return paths, nil
+}
+
+// AddSetFlagsForRelayForwardUplinkReq adds flags to select fields in RelayForwardUplinkReq.
+func AddSetFlagsForRelayForwardUplinkReq(flags *pflag.FlagSet, prefix string, hidden bool) {
+ AddSetFlagsForDataRate(flags, flagsplugin.Prefix("data-rate", prefix), hidden)
+ flags.AddFlag(flagsplugin.NewInt32Flag(flagsplugin.Prefix("snr", prefix), "", flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewInt32Flag(flagsplugin.Prefix("rssi", prefix), "", flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewStringFlag(flagsplugin.Prefix("wor-channel", prefix), flagsplugin.EnumValueDesc(RelayWORChannel_value), flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewUint64Flag(flagsplugin.Prefix("frequency", prefix), "", flagsplugin.WithHidden(hidden)))
+ flags.AddFlag(flagsplugin.NewBytesFlag(flagsplugin.Prefix("raw-payload", prefix), "", flagsplugin.WithHidden(hidden)))
+}
+
+// SetFromFlags sets the RelayForwardUplinkReq message from flags.
+func (m *RelayForwardUplinkReq) SetFromFlags(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ if changed := flagsplugin.IsAnyPrefixSet(flags, flagsplugin.Prefix("data_rate", prefix)); changed {
+ if m.DataRate == nil {
+ m.DataRate = &DataRate{}
+ }
+ if setPaths, err := m.DataRate.SetFromFlags(flags, flagsplugin.Prefix("data_rate", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, setPaths...)
+ }
+ }
+ if val, changed, err := flagsplugin.GetInt32(flags, flagsplugin.Prefix("snr", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.Snr = val
+ paths = append(paths, flagsplugin.Prefix("snr", prefix))
+ }
+ if val, changed, err := flagsplugin.GetInt32(flags, flagsplugin.Prefix("rssi", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.Rssi = val
+ paths = append(paths, flagsplugin.Prefix("rssi", prefix))
+ }
+ if val, changed, err := flagsplugin.GetString(flags, flagsplugin.Prefix("wor_channel", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ enumValue, err := flagsplugin.SetEnumString(val, RelayWORChannel_value)
+ if err != nil {
+ return nil, err
+ }
+ m.WorChannel = RelayWORChannel(enumValue)
+ paths = append(paths, flagsplugin.Prefix("wor_channel", prefix))
+ }
+ if val, changed, err := flagsplugin.GetUint64(flags, flagsplugin.Prefix("frequency", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.Frequency = val
+ paths = append(paths, flagsplugin.Prefix("frequency", prefix))
+ }
+ if val, changed, err := flagsplugin.GetBytes(flags, flagsplugin.Prefix("raw_payload", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.RawPayload = val
+ paths = append(paths, flagsplugin.Prefix("raw_payload", prefix))
+ }
+ return paths, nil
+}
+
+// AddSelectFlagsForRelayForwardDownlinkReq adds flags to select fields in RelayForwardDownlinkReq.
+func AddSelectFlagsForRelayForwardDownlinkReq(flags *pflag.FlagSet, prefix string, hidden bool) {
+ flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("raw-payload", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("raw-payload", prefix), false), flagsplugin.WithHidden(hidden)))
+}
+
+// SelectFromFlags outputs the fieldmask paths forRelayForwardDownlinkReq message from select flags.
+func PathsFromSelectFlagsForRelayForwardDownlinkReq(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("raw_payload", prefix)); err != nil {
+ return nil, err
+ } else if selected && val {
+ paths = append(paths, flagsplugin.Prefix("raw_payload", prefix))
+ }
+ return paths, nil
+}
+
+// AddSetFlagsForRelayForwardDownlinkReq adds flags to select fields in RelayForwardDownlinkReq.
+func AddSetFlagsForRelayForwardDownlinkReq(flags *pflag.FlagSet, prefix string, hidden bool) {
+ flags.AddFlag(flagsplugin.NewBytesFlag(flagsplugin.Prefix("raw-payload", prefix), "", flagsplugin.WithHidden(hidden)))
+}
+
+// SetFromFlags sets the RelayForwardDownlinkReq message from flags.
+func (m *RelayForwardDownlinkReq) SetFromFlags(flags *pflag.FlagSet, prefix string) (paths []string, err error) {
+ if val, changed, err := flagsplugin.GetBytes(flags, flagsplugin.Prefix("raw_payload", prefix)); err != nil {
+ return nil, err
+ } else if changed {
+ m.RawPayload = val
+ paths = append(paths, flagsplugin.Prefix("raw_payload", prefix))
+ }
+ return paths, nil
+}
diff --git a/pkg/ttnpb/lorawan_json.pb.go b/pkg/ttnpb/lorawan_json.pb.go
index 62825a6d37..0423befb41 100644
--- a/pkg/ttnpb/lorawan_json.pb.go
+++ b/pkg/ttnpb/lorawan_json.pb.go
@@ -558,27 +558,34 @@ func (x MACCommandIdentifier) MarshalJSON() ([]byte, error) {
// MACCommandIdentifier_customvalue contains custom string values that extend MACCommandIdentifier_value.
var MACCommandIdentifier_customvalue = map[string]int32{
- "RFU_0": 0,
- "RESET": 1,
- "LINK_CHECK": 2,
- "LINK_ADR": 3,
- "DUTY_CYCLE": 4,
- "RX_PARAM_SETUP": 5,
- "DEV_STATUS": 6,
- "NEW_CHANNEL": 7,
- "RX_TIMING_SETUP": 8,
- "TX_PARAM_SETUP": 9,
- "DL_CHANNEL": 10,
- "REKEY": 11,
- "ADR_PARAM_SETUP": 12,
- "DEVICE_TIME": 13,
- "FORCE_REJOIN": 14,
- "REJOIN_PARAM_SETUP": 15,
- "PING_SLOT_INFO": 16,
- "PING_SLOT_CHANNEL": 17,
- "BEACON_TIMING": 18,
- "BEACON_FREQ": 19,
- "DEVICE_MODE": 32,
+ "RFU_0": 0,
+ "RESET": 1,
+ "LINK_CHECK": 2,
+ "LINK_ADR": 3,
+ "DUTY_CYCLE": 4,
+ "RX_PARAM_SETUP": 5,
+ "DEV_STATUS": 6,
+ "NEW_CHANNEL": 7,
+ "RX_TIMING_SETUP": 8,
+ "TX_PARAM_SETUP": 9,
+ "DL_CHANNEL": 10,
+ "REKEY": 11,
+ "ADR_PARAM_SETUP": 12,
+ "DEVICE_TIME": 13,
+ "FORCE_REJOIN": 14,
+ "REJOIN_PARAM_SETUP": 15,
+ "PING_SLOT_INFO": 16,
+ "PING_SLOT_CHANNEL": 17,
+ "BEACON_TIMING": 18,
+ "BEACON_FREQ": 19,
+ "DEVICE_MODE": 32,
+ "RELAY_CONF": 64,
+ "RELAY_END_DEVICE_CONF": 65,
+ "RELAY_FILTER_LIST": 66,
+ "RELAY_UPDATE_UPLINK_LIST": 67,
+ "RELAY_CTRL_UPLINK_LIST": 68,
+ "RELAY_CONFIGURE_FWD_LIMIT": 69,
+ "RELAY_NOTIFY_NEW_END_DEVICE": 70,
}
// UnmarshalProtoJSON unmarshals the MACCommandIdentifier from JSON.
@@ -606,6 +613,342 @@ func (x *MACCommandIdentifier) UnmarshalJSON(b []byte) error {
return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
}
+// MarshalProtoJSON marshals the RelayCADPeriodicity to JSON.
+func (x RelayCADPeriodicity) MarshalProtoJSON(s *jsonplugin.MarshalState) {
+ s.WriteEnumString(int32(x), RelayCADPeriodicity_name)
+}
+
+// MarshalText marshals the RelayCADPeriodicity to text.
+func (x RelayCADPeriodicity) MarshalText() ([]byte, error) {
+ return []byte(jsonplugin.GetEnumString(int32(x), RelayCADPeriodicity_name)), nil
+}
+
+// MarshalJSON marshals the RelayCADPeriodicity to JSON.
+func (x RelayCADPeriodicity) MarshalJSON() ([]byte, error) {
+ return jsonplugin.DefaultMarshalerConfig.Marshal(x)
+}
+
+// RelayCADPeriodicity_customvalue contains custom string values that extend RelayCADPeriodicity_value.
+var RelayCADPeriodicity_customvalue = map[string]int32{
+ "1_SECOND": 0,
+ "500_MILLISECONDS": 1,
+ "250_MILLISECONDS": 2,
+ "100_MILLISECONDS": 3,
+ "50_MILLISECONDS": 4,
+ "20_MILLISECONDS": 5,
+}
+
+// UnmarshalProtoJSON unmarshals the RelayCADPeriodicity from JSON.
+func (x *RelayCADPeriodicity) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+ v := s.ReadEnum(RelayCADPeriodicity_value, RelayCADPeriodicity_customvalue)
+ if err := s.Err(); err != nil {
+ s.SetErrorf("could not read RelayCADPeriodicity enum: %v", err)
+ return
+ }
+ *x = RelayCADPeriodicity(v)
+}
+
+// UnmarshalText unmarshals the RelayCADPeriodicity from text.
+func (x *RelayCADPeriodicity) UnmarshalText(b []byte) error {
+ i, err := jsonplugin.ParseEnumString(string(b), RelayCADPeriodicity_customvalue, RelayCADPeriodicity_value)
+ if err != nil {
+ return err
+ }
+ *x = RelayCADPeriodicity(i)
+ return nil
+}
+
+// UnmarshalJSON unmarshals the RelayCADPeriodicity from JSON.
+func (x *RelayCADPeriodicity) UnmarshalJSON(b []byte) error {
+ return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
+}
+
+// MarshalProtoJSON marshals the RelaySecondChAckOffset to JSON.
+func (x RelaySecondChAckOffset) MarshalProtoJSON(s *jsonplugin.MarshalState) {
+ s.WriteEnumString(int32(x), RelaySecondChAckOffset_name)
+}
+
+// MarshalText marshals the RelaySecondChAckOffset to text.
+func (x RelaySecondChAckOffset) MarshalText() ([]byte, error) {
+ return []byte(jsonplugin.GetEnumString(int32(x), RelaySecondChAckOffset_name)), nil
+}
+
+// MarshalJSON marshals the RelaySecondChAckOffset to JSON.
+func (x RelaySecondChAckOffset) MarshalJSON() ([]byte, error) {
+ return jsonplugin.DefaultMarshalerConfig.Marshal(x)
+}
+
+// RelaySecondChAckOffset_customvalue contains custom string values that extend RelaySecondChAckOffset_value.
+var RelaySecondChAckOffset_customvalue = map[string]int32{
+ "0": 0,
+ "200": 1,
+ "400": 2,
+ "800": 3,
+ "1600": 4,
+ "3200": 5,
+}
+
+// UnmarshalProtoJSON unmarshals the RelaySecondChAckOffset from JSON.
+func (x *RelaySecondChAckOffset) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+ v := s.ReadEnum(RelaySecondChAckOffset_value, RelaySecondChAckOffset_customvalue)
+ if err := s.Err(); err != nil {
+ s.SetErrorf("could not read RelaySecondChAckOffset enum: %v", err)
+ return
+ }
+ *x = RelaySecondChAckOffset(v)
+}
+
+// UnmarshalText unmarshals the RelaySecondChAckOffset from text.
+func (x *RelaySecondChAckOffset) UnmarshalText(b []byte) error {
+ i, err := jsonplugin.ParseEnumString(string(b), RelaySecondChAckOffset_customvalue, RelaySecondChAckOffset_value)
+ if err != nil {
+ return err
+ }
+ *x = RelaySecondChAckOffset(i)
+ return nil
+}
+
+// UnmarshalJSON unmarshals the RelaySecondChAckOffset from JSON.
+func (x *RelaySecondChAckOffset) UnmarshalJSON(b []byte) error {
+ return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
+}
+
+// MarshalProtoJSON marshals the RelayLimitBucketSize to JSON.
+func (x RelayLimitBucketSize) MarshalProtoJSON(s *jsonplugin.MarshalState) {
+ s.WriteEnumString(int32(x), RelayLimitBucketSize_name)
+}
+
+// MarshalText marshals the RelayLimitBucketSize to text.
+func (x RelayLimitBucketSize) MarshalText() ([]byte, error) {
+ return []byte(jsonplugin.GetEnumString(int32(x), RelayLimitBucketSize_name)), nil
+}
+
+// MarshalJSON marshals the RelayLimitBucketSize to JSON.
+func (x RelayLimitBucketSize) MarshalJSON() ([]byte, error) {
+ return jsonplugin.DefaultMarshalerConfig.Marshal(x)
+}
+
+// RelayLimitBucketSize_customvalue contains custom string values that extend RelayLimitBucketSize_value.
+var RelayLimitBucketSize_customvalue = map[string]int32{
+ "1": 0,
+ "2": 1,
+ "4": 2,
+ "12": 3,
+}
+
+// UnmarshalProtoJSON unmarshals the RelayLimitBucketSize from JSON.
+func (x *RelayLimitBucketSize) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+ v := s.ReadEnum(RelayLimitBucketSize_value, RelayLimitBucketSize_customvalue)
+ if err := s.Err(); err != nil {
+ s.SetErrorf("could not read RelayLimitBucketSize enum: %v", err)
+ return
+ }
+ *x = RelayLimitBucketSize(v)
+}
+
+// UnmarshalText unmarshals the RelayLimitBucketSize from text.
+func (x *RelayLimitBucketSize) UnmarshalText(b []byte) error {
+ i, err := jsonplugin.ParseEnumString(string(b), RelayLimitBucketSize_customvalue, RelayLimitBucketSize_value)
+ if err != nil {
+ return err
+ }
+ *x = RelayLimitBucketSize(i)
+ return nil
+}
+
+// UnmarshalJSON unmarshals the RelayLimitBucketSize from JSON.
+func (x *RelayLimitBucketSize) UnmarshalJSON(b []byte) error {
+ return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
+}
+
+// MarshalProtoJSON marshals the RelaySmartEnableLevel to JSON.
+func (x RelaySmartEnableLevel) MarshalProtoJSON(s *jsonplugin.MarshalState) {
+ s.WriteEnumString(int32(x), RelaySmartEnableLevel_name)
+}
+
+// MarshalText marshals the RelaySmartEnableLevel to text.
+func (x RelaySmartEnableLevel) MarshalText() ([]byte, error) {
+ return []byte(jsonplugin.GetEnumString(int32(x), RelaySmartEnableLevel_name)), nil
+}
+
+// MarshalJSON marshals the RelaySmartEnableLevel to JSON.
+func (x RelaySmartEnableLevel) MarshalJSON() ([]byte, error) {
+ return jsonplugin.DefaultMarshalerConfig.Marshal(x)
+}
+
+// RelaySmartEnableLevel_customvalue contains custom string values that extend RelaySmartEnableLevel_value.
+var RelaySmartEnableLevel_customvalue = map[string]int32{
+ "8": 0,
+ "16": 1,
+ "32": 2,
+ "64": 3,
+}
+
+// UnmarshalProtoJSON unmarshals the RelaySmartEnableLevel from JSON.
+func (x *RelaySmartEnableLevel) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+ v := s.ReadEnum(RelaySmartEnableLevel_value, RelaySmartEnableLevel_customvalue)
+ if err := s.Err(); err != nil {
+ s.SetErrorf("could not read RelaySmartEnableLevel enum: %v", err)
+ return
+ }
+ *x = RelaySmartEnableLevel(v)
+}
+
+// UnmarshalText unmarshals the RelaySmartEnableLevel from text.
+func (x *RelaySmartEnableLevel) UnmarshalText(b []byte) error {
+ i, err := jsonplugin.ParseEnumString(string(b), RelaySmartEnableLevel_customvalue, RelaySmartEnableLevel_value)
+ if err != nil {
+ return err
+ }
+ *x = RelaySmartEnableLevel(i)
+ return nil
+}
+
+// UnmarshalJSON unmarshals the RelaySmartEnableLevel from JSON.
+func (x *RelaySmartEnableLevel) UnmarshalJSON(b []byte) error {
+ return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
+}
+
+// MarshalProtoJSON marshals the RelayWORChannel to JSON.
+func (x RelayWORChannel) MarshalProtoJSON(s *jsonplugin.MarshalState) {
+ s.WriteEnumString(int32(x), RelayWORChannel_name)
+}
+
+// MarshalText marshals the RelayWORChannel to text.
+func (x RelayWORChannel) MarshalText() ([]byte, error) {
+ return []byte(jsonplugin.GetEnumString(int32(x), RelayWORChannel_name)), nil
+}
+
+// MarshalJSON marshals the RelayWORChannel to JSON.
+func (x RelayWORChannel) MarshalJSON() ([]byte, error) {
+ return jsonplugin.DefaultMarshalerConfig.Marshal(x)
+}
+
+// RelayWORChannel_customvalue contains custom string values that extend RelayWORChannel_value.
+var RelayWORChannel_customvalue = map[string]int32{
+ "DEFAULT": 0,
+ "SECONDARY": 1,
+}
+
+// UnmarshalProtoJSON unmarshals the RelayWORChannel from JSON.
+func (x *RelayWORChannel) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+ v := s.ReadEnum(RelayWORChannel_value, RelayWORChannel_customvalue)
+ if err := s.Err(); err != nil {
+ s.SetErrorf("could not read RelayWORChannel enum: %v", err)
+ return
+ }
+ *x = RelayWORChannel(v)
+}
+
+// UnmarshalText unmarshals the RelayWORChannel from text.
+func (x *RelayWORChannel) UnmarshalText(b []byte) error {
+ i, err := jsonplugin.ParseEnumString(string(b), RelayWORChannel_customvalue, RelayWORChannel_value)
+ if err != nil {
+ return err
+ }
+ *x = RelayWORChannel(i)
+ return nil
+}
+
+// UnmarshalJSON unmarshals the RelayWORChannel from JSON.
+func (x *RelayWORChannel) UnmarshalJSON(b []byte) error {
+ return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
+}
+
+// MarshalProtoJSON marshals the RelayResetLimitCounter to JSON.
+func (x RelayResetLimitCounter) MarshalProtoJSON(s *jsonplugin.MarshalState) {
+ s.WriteEnumString(int32(x), RelayResetLimitCounter_name)
+}
+
+// MarshalText marshals the RelayResetLimitCounter to text.
+func (x RelayResetLimitCounter) MarshalText() ([]byte, error) {
+ return []byte(jsonplugin.GetEnumString(int32(x), RelayResetLimitCounter_name)), nil
+}
+
+// MarshalJSON marshals the RelayResetLimitCounter to JSON.
+func (x RelayResetLimitCounter) MarshalJSON() ([]byte, error) {
+ return jsonplugin.DefaultMarshalerConfig.Marshal(x)
+}
+
+// RelayResetLimitCounter_customvalue contains custom string values that extend RelayResetLimitCounter_value.
+var RelayResetLimitCounter_customvalue = map[string]int32{
+ "ZERO": 0,
+ "RELOAD_RATE": 1,
+ "MAX_VALUE": 2,
+ "NO_RESET": 3,
+}
+
+// UnmarshalProtoJSON unmarshals the RelayResetLimitCounter from JSON.
+func (x *RelayResetLimitCounter) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+ v := s.ReadEnum(RelayResetLimitCounter_value, RelayResetLimitCounter_customvalue)
+ if err := s.Err(); err != nil {
+ s.SetErrorf("could not read RelayResetLimitCounter enum: %v", err)
+ return
+ }
+ *x = RelayResetLimitCounter(v)
+}
+
+// UnmarshalText unmarshals the RelayResetLimitCounter from text.
+func (x *RelayResetLimitCounter) UnmarshalText(b []byte) error {
+ i, err := jsonplugin.ParseEnumString(string(b), RelayResetLimitCounter_customvalue, RelayResetLimitCounter_value)
+ if err != nil {
+ return err
+ }
+ *x = RelayResetLimitCounter(i)
+ return nil
+}
+
+// UnmarshalJSON unmarshals the RelayResetLimitCounter from JSON.
+func (x *RelayResetLimitCounter) UnmarshalJSON(b []byte) error {
+ return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
+}
+
+// MarshalProtoJSON marshals the RelayCtrlUplinkListAction to JSON.
+func (x RelayCtrlUplinkListAction) MarshalProtoJSON(s *jsonplugin.MarshalState) {
+ s.WriteEnumString(int32(x), RelayCtrlUplinkListAction_name)
+}
+
+// MarshalText marshals the RelayCtrlUplinkListAction to text.
+func (x RelayCtrlUplinkListAction) MarshalText() ([]byte, error) {
+ return []byte(jsonplugin.GetEnumString(int32(x), RelayCtrlUplinkListAction_name)), nil
+}
+
+// MarshalJSON marshals the RelayCtrlUplinkListAction to JSON.
+func (x RelayCtrlUplinkListAction) MarshalJSON() ([]byte, error) {
+ return jsonplugin.DefaultMarshalerConfig.Marshal(x)
+}
+
+// RelayCtrlUplinkListAction_customvalue contains custom string values that extend RelayCtrlUplinkListAction_value.
+var RelayCtrlUplinkListAction_customvalue = map[string]int32{
+ "READ_W_F_CNT": 0,
+ "REMOVE_TRUSTED_END_DEVICE": 1,
+}
+
+// UnmarshalProtoJSON unmarshals the RelayCtrlUplinkListAction from JSON.
+func (x *RelayCtrlUplinkListAction) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+ v := s.ReadEnum(RelayCtrlUplinkListAction_value, RelayCtrlUplinkListAction_customvalue)
+ if err := s.Err(); err != nil {
+ s.SetErrorf("could not read RelayCtrlUplinkListAction enum: %v", err)
+ return
+ }
+ *x = RelayCtrlUplinkListAction(v)
+}
+
+// UnmarshalText unmarshals the RelayCtrlUplinkListAction from text.
+func (x *RelayCtrlUplinkListAction) UnmarshalText(b []byte) error {
+ i, err := jsonplugin.ParseEnumString(string(b), RelayCtrlUplinkListAction_customvalue, RelayCtrlUplinkListAction_value)
+ if err != nil {
+ return err
+ }
+ *x = RelayCtrlUplinkListAction(i)
+ return nil
+}
+
+// UnmarshalJSON unmarshals the RelayCtrlUplinkListAction from JSON.
+func (x *RelayCtrlUplinkListAction) UnmarshalJSON(b []byte) error {
+ return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
+}
+
// MarshalProtoJSON marshals the AggregatedDutyCycle to JSON.
func (x AggregatedDutyCycle) MarshalProtoJSON(s *jsonplugin.MarshalState) {
s.WriteEnumString(int32(x), AggregatedDutyCycle_name)
@@ -2329,29 +2672,39 @@ func (x *TxRequest) UnmarshalJSON(b []byte) error {
return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
}
-// MarshalProtoJSON marshals the MACCommand_ResetInd message to JSON.
-func (x *MACCommand_ResetInd) MarshalProtoJSON(s *jsonplugin.MarshalState) {
+// MarshalProtoJSON marshals the RelaySecondChannel message to JSON.
+func (x *RelaySecondChannel) MarshalProtoJSON(s *jsonplugin.MarshalState) {
if x == nil {
s.WriteNil()
return
}
s.WriteObjectStart()
var wroteField bool
- if x.MinorVersion != 0 || s.HasField("minor_version") {
+ if x.AckOffset != 0 || s.HasField("ack_offset") {
s.WriteMoreIf(&wroteField)
- s.WriteObjectField("minor_version")
- x.MinorVersion.MarshalProtoJSON(s)
+ s.WriteObjectField("ack_offset")
+ x.AckOffset.MarshalProtoJSON(s)
+ }
+ if x.DataRateIndex != 0 || s.HasField("data_rate_index") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("data_rate_index")
+ x.DataRateIndex.MarshalProtoJSON(s)
+ }
+ if x.Frequency != 0 || s.HasField("frequency") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("frequency")
+ s.WriteUint64(x.Frequency)
}
s.WriteObjectEnd()
}
-// MarshalJSON marshals the MACCommand_ResetInd to JSON.
-func (x *MACCommand_ResetInd) MarshalJSON() ([]byte, error) {
+// MarshalJSON marshals the RelaySecondChannel to JSON.
+func (x *RelaySecondChannel) MarshalJSON() ([]byte, error) {
return jsonplugin.DefaultMarshalerConfig.Marshal(x)
}
-// UnmarshalProtoJSON unmarshals the MACCommand_ResetInd message from JSON.
-func (x *MACCommand_ResetInd) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+// UnmarshalProtoJSON unmarshals the RelaySecondChannel message from JSON.
+func (x *RelaySecondChannel) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
if s.ReadNil() {
return
}
@@ -2359,41 +2712,52 @@ func (x *MACCommand_ResetInd) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
switch key {
default:
s.ReadAny() // ignore unknown field
- case "minor_version", "minorVersion":
- s.AddField("minor_version")
- x.MinorVersion.UnmarshalProtoJSON(s)
+ case "ack_offset", "ackOffset":
+ s.AddField("ack_offset")
+ x.AckOffset.UnmarshalProtoJSON(s)
+ case "data_rate_index", "dataRateIndex":
+ s.AddField("data_rate_index")
+ x.DataRateIndex.UnmarshalProtoJSON(s)
+ case "frequency":
+ s.AddField("frequency")
+ x.Frequency = s.ReadUint64()
}
})
}
-// UnmarshalJSON unmarshals the MACCommand_ResetInd from JSON.
-func (x *MACCommand_ResetInd) UnmarshalJSON(b []byte) error {
+// UnmarshalJSON unmarshals the RelaySecondChannel from JSON.
+func (x *RelaySecondChannel) UnmarshalJSON(b []byte) error {
return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
}
-// MarshalProtoJSON marshals the MACCommand_ResetConf message to JSON.
-func (x *MACCommand_ResetConf) MarshalProtoJSON(s *jsonplugin.MarshalState) {
+// MarshalProtoJSON marshals the RelayUplinkForwardLimits message to JSON.
+func (x *RelayUplinkForwardLimits) MarshalProtoJSON(s *jsonplugin.MarshalState) {
if x == nil {
s.WriteNil()
return
}
s.WriteObjectStart()
var wroteField bool
- if x.MinorVersion != 0 || s.HasField("minor_version") {
+ if x.BucketSize != 0 || s.HasField("bucket_size") {
s.WriteMoreIf(&wroteField)
- s.WriteObjectField("minor_version")
- x.MinorVersion.MarshalProtoJSON(s)
+ s.WriteObjectField("bucket_size")
+ x.BucketSize.MarshalProtoJSON(s)
+ }
+ if x.ReloadRate != 0 || s.HasField("reload_rate") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("reload_rate")
+ s.WriteUint32(x.ReloadRate)
}
s.WriteObjectEnd()
}
-// MarshalJSON marshals the MACCommand_ResetConf to JSON.
-func (x *MACCommand_ResetConf) MarshalJSON() ([]byte, error) {
+// MarshalJSON marshals the RelayUplinkForwardLimits to JSON.
+func (x *RelayUplinkForwardLimits) MarshalJSON() ([]byte, error) {
return jsonplugin.DefaultMarshalerConfig.Marshal(x)
}
-// UnmarshalProtoJSON unmarshals the MACCommand_ResetConf message from JSON.
-func (x *MACCommand_ResetConf) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+// UnmarshalProtoJSON unmarshals the RelayUplinkForwardLimits message from JSON.
+func (x *RelayUplinkForwardLimits) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
if s.ReadNil() {
return
}
@@ -2401,61 +2765,49 @@ func (x *MACCommand_ResetConf) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState)
switch key {
default:
s.ReadAny() // ignore unknown field
- case "minor_version", "minorVersion":
- s.AddField("minor_version")
- x.MinorVersion.UnmarshalProtoJSON(s)
+ case "bucket_size", "bucketSize":
+ s.AddField("bucket_size")
+ x.BucketSize.UnmarshalProtoJSON(s)
+ case "reload_rate", "reloadRate":
+ s.AddField("reload_rate")
+ x.ReloadRate = s.ReadUint32()
}
})
}
-// UnmarshalJSON unmarshals the MACCommand_ResetConf from JSON.
-func (x *MACCommand_ResetConf) UnmarshalJSON(b []byte) error {
+// UnmarshalJSON unmarshals the RelayUplinkForwardLimits from JSON.
+func (x *RelayUplinkForwardLimits) UnmarshalJSON(b []byte) error {
return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
}
-// MarshalProtoJSON marshals the MACCommand_LinkADRReq message to JSON.
-func (x *MACCommand_LinkADRReq) MarshalProtoJSON(s *jsonplugin.MarshalState) {
+// MarshalProtoJSON marshals the RelayForwardLimits message to JSON.
+func (x *RelayForwardLimits) MarshalProtoJSON(s *jsonplugin.MarshalState) {
if x == nil {
s.WriteNil()
return
}
s.WriteObjectStart()
var wroteField bool
- if x.DataRateIndex != 0 || s.HasField("data_rate_index") {
- s.WriteMoreIf(&wroteField)
- s.WriteObjectField("data_rate_index")
- x.DataRateIndex.MarshalProtoJSON(s)
- }
- if x.TxPowerIndex != 0 || s.HasField("tx_power_index") {
- s.WriteMoreIf(&wroteField)
- s.WriteObjectField("tx_power_index")
- s.WriteUint32(x.TxPowerIndex)
- }
- if len(x.ChannelMask) > 0 || s.HasField("channel_mask") {
- s.WriteMoreIf(&wroteField)
- s.WriteObjectField("channel_mask")
- s.WriteBoolArray(x.ChannelMask)
- }
- if x.ChannelMaskControl != 0 || s.HasField("channel_mask_control") {
+ if x.BucketSize != 0 || s.HasField("bucket_size") {
s.WriteMoreIf(&wroteField)
- s.WriteObjectField("channel_mask_control")
- s.WriteUint32(x.ChannelMaskControl)
+ s.WriteObjectField("bucket_size")
+ x.BucketSize.MarshalProtoJSON(s)
}
- if x.NbTrans != 0 || s.HasField("nb_trans") {
+ if x.ReloadRate != 0 || s.HasField("reload_rate") {
s.WriteMoreIf(&wroteField)
- s.WriteObjectField("nb_trans")
- s.WriteUint32(x.NbTrans)
+ s.WriteObjectField("reload_rate")
+ s.WriteUint32(x.ReloadRate)
}
s.WriteObjectEnd()
}
-// MarshalJSON marshals the MACCommand_LinkADRReq to JSON.
-func (x *MACCommand_LinkADRReq) MarshalJSON() ([]byte, error) {
+// MarshalJSON marshals the RelayForwardLimits to JSON.
+func (x *RelayForwardLimits) MarshalJSON() ([]byte, error) {
return jsonplugin.DefaultMarshalerConfig.Marshal(x)
}
-// UnmarshalProtoJSON unmarshals the MACCommand_LinkADRReq message from JSON.
-func (x *MACCommand_LinkADRReq) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+// UnmarshalProtoJSON unmarshals the RelayForwardLimits message from JSON.
+func (x *RelayForwardLimits) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
if s.ReadNil() {
return
}
@@ -2463,31 +2815,222 @@ func (x *MACCommand_LinkADRReq) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState)
switch key {
default:
s.ReadAny() // ignore unknown field
- case "data_rate_index", "dataRateIndex":
- s.AddField("data_rate_index")
- x.DataRateIndex.UnmarshalProtoJSON(s)
- case "tx_power_index", "txPowerIndex":
- s.AddField("tx_power_index")
- x.TxPowerIndex = s.ReadUint32()
- case "channel_mask", "channelMask":
- s.AddField("channel_mask")
- if s.ReadNil() {
- x.ChannelMask = nil
- return
- }
- x.ChannelMask = s.ReadBoolArray()
- case "channel_mask_control", "channelMaskControl":
- s.AddField("channel_mask_control")
- x.ChannelMaskControl = s.ReadUint32()
- case "nb_trans", "nbTrans":
- s.AddField("nb_trans")
- x.NbTrans = s.ReadUint32()
+ case "bucket_size", "bucketSize":
+ s.AddField("bucket_size")
+ x.BucketSize.UnmarshalProtoJSON(s)
+ case "reload_rate", "reloadRate":
+ s.AddField("reload_rate")
+ x.ReloadRate = s.ReadUint32()
}
})
}
-// UnmarshalJSON unmarshals the MACCommand_LinkADRReq from JSON.
-func (x *MACCommand_LinkADRReq) UnmarshalJSON(b []byte) error {
+// UnmarshalJSON unmarshals the RelayForwardLimits from JSON.
+func (x *RelayForwardLimits) UnmarshalJSON(b []byte) error {
+ return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
+}
+
+// MarshalProtoJSON marshals the RelayEndDeviceDynamicMode message to JSON.
+func (x *RelayEndDeviceDynamicMode) MarshalProtoJSON(s *jsonplugin.MarshalState) {
+ if x == nil {
+ s.WriteNil()
+ return
+ }
+ s.WriteObjectStart()
+ var wroteField bool
+ if x.SmartEnableLevel != 0 || s.HasField("smart_enable_level") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("smart_enable_level")
+ x.SmartEnableLevel.MarshalProtoJSON(s)
+ }
+ s.WriteObjectEnd()
+}
+
+// MarshalJSON marshals the RelayEndDeviceDynamicMode to JSON.
+func (x *RelayEndDeviceDynamicMode) MarshalJSON() ([]byte, error) {
+ return jsonplugin.DefaultMarshalerConfig.Marshal(x)
+}
+
+// UnmarshalProtoJSON unmarshals the RelayEndDeviceDynamicMode message from JSON.
+func (x *RelayEndDeviceDynamicMode) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+ if s.ReadNil() {
+ return
+ }
+ s.ReadObject(func(key string) {
+ switch key {
+ default:
+ s.ReadAny() // ignore unknown field
+ case "smart_enable_level", "smartEnableLevel":
+ s.AddField("smart_enable_level")
+ x.SmartEnableLevel.UnmarshalProtoJSON(s)
+ }
+ })
+}
+
+// UnmarshalJSON unmarshals the RelayEndDeviceDynamicMode from JSON.
+func (x *RelayEndDeviceDynamicMode) UnmarshalJSON(b []byte) error {
+ return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
+}
+
+// MarshalProtoJSON marshals the MACCommand_ResetInd message to JSON.
+func (x *MACCommand_ResetInd) MarshalProtoJSON(s *jsonplugin.MarshalState) {
+ if x == nil {
+ s.WriteNil()
+ return
+ }
+ s.WriteObjectStart()
+ var wroteField bool
+ if x.MinorVersion != 0 || s.HasField("minor_version") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("minor_version")
+ x.MinorVersion.MarshalProtoJSON(s)
+ }
+ s.WriteObjectEnd()
+}
+
+// MarshalJSON marshals the MACCommand_ResetInd to JSON.
+func (x *MACCommand_ResetInd) MarshalJSON() ([]byte, error) {
+ return jsonplugin.DefaultMarshalerConfig.Marshal(x)
+}
+
+// UnmarshalProtoJSON unmarshals the MACCommand_ResetInd message from JSON.
+func (x *MACCommand_ResetInd) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+ if s.ReadNil() {
+ return
+ }
+ s.ReadObject(func(key string) {
+ switch key {
+ default:
+ s.ReadAny() // ignore unknown field
+ case "minor_version", "minorVersion":
+ s.AddField("minor_version")
+ x.MinorVersion.UnmarshalProtoJSON(s)
+ }
+ })
+}
+
+// UnmarshalJSON unmarshals the MACCommand_ResetInd from JSON.
+func (x *MACCommand_ResetInd) UnmarshalJSON(b []byte) error {
+ return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
+}
+
+// MarshalProtoJSON marshals the MACCommand_ResetConf message to JSON.
+func (x *MACCommand_ResetConf) MarshalProtoJSON(s *jsonplugin.MarshalState) {
+ if x == nil {
+ s.WriteNil()
+ return
+ }
+ s.WriteObjectStart()
+ var wroteField bool
+ if x.MinorVersion != 0 || s.HasField("minor_version") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("minor_version")
+ x.MinorVersion.MarshalProtoJSON(s)
+ }
+ s.WriteObjectEnd()
+}
+
+// MarshalJSON marshals the MACCommand_ResetConf to JSON.
+func (x *MACCommand_ResetConf) MarshalJSON() ([]byte, error) {
+ return jsonplugin.DefaultMarshalerConfig.Marshal(x)
+}
+
+// UnmarshalProtoJSON unmarshals the MACCommand_ResetConf message from JSON.
+func (x *MACCommand_ResetConf) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+ if s.ReadNil() {
+ return
+ }
+ s.ReadObject(func(key string) {
+ switch key {
+ default:
+ s.ReadAny() // ignore unknown field
+ case "minor_version", "minorVersion":
+ s.AddField("minor_version")
+ x.MinorVersion.UnmarshalProtoJSON(s)
+ }
+ })
+}
+
+// UnmarshalJSON unmarshals the MACCommand_ResetConf from JSON.
+func (x *MACCommand_ResetConf) UnmarshalJSON(b []byte) error {
+ return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
+}
+
+// MarshalProtoJSON marshals the MACCommand_LinkADRReq message to JSON.
+func (x *MACCommand_LinkADRReq) MarshalProtoJSON(s *jsonplugin.MarshalState) {
+ if x == nil {
+ s.WriteNil()
+ return
+ }
+ s.WriteObjectStart()
+ var wroteField bool
+ if x.DataRateIndex != 0 || s.HasField("data_rate_index") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("data_rate_index")
+ x.DataRateIndex.MarshalProtoJSON(s)
+ }
+ if x.TxPowerIndex != 0 || s.HasField("tx_power_index") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("tx_power_index")
+ s.WriteUint32(x.TxPowerIndex)
+ }
+ if len(x.ChannelMask) > 0 || s.HasField("channel_mask") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("channel_mask")
+ s.WriteBoolArray(x.ChannelMask)
+ }
+ if x.ChannelMaskControl != 0 || s.HasField("channel_mask_control") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("channel_mask_control")
+ s.WriteUint32(x.ChannelMaskControl)
+ }
+ if x.NbTrans != 0 || s.HasField("nb_trans") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("nb_trans")
+ s.WriteUint32(x.NbTrans)
+ }
+ s.WriteObjectEnd()
+}
+
+// MarshalJSON marshals the MACCommand_LinkADRReq to JSON.
+func (x *MACCommand_LinkADRReq) MarshalJSON() ([]byte, error) {
+ return jsonplugin.DefaultMarshalerConfig.Marshal(x)
+}
+
+// UnmarshalProtoJSON unmarshals the MACCommand_LinkADRReq message from JSON.
+func (x *MACCommand_LinkADRReq) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+ if s.ReadNil() {
+ return
+ }
+ s.ReadObject(func(key string) {
+ switch key {
+ default:
+ s.ReadAny() // ignore unknown field
+ case "data_rate_index", "dataRateIndex":
+ s.AddField("data_rate_index")
+ x.DataRateIndex.UnmarshalProtoJSON(s)
+ case "tx_power_index", "txPowerIndex":
+ s.AddField("tx_power_index")
+ x.TxPowerIndex = s.ReadUint32()
+ case "channel_mask", "channelMask":
+ s.AddField("channel_mask")
+ if s.ReadNil() {
+ x.ChannelMask = nil
+ return
+ }
+ x.ChannelMask = s.ReadBoolArray()
+ case "channel_mask_control", "channelMaskControl":
+ s.AddField("channel_mask_control")
+ x.ChannelMaskControl = s.ReadUint32()
+ case "nb_trans", "nbTrans":
+ s.AddField("nb_trans")
+ x.NbTrans = s.ReadUint32()
+ }
+ })
+}
+
+// UnmarshalJSON unmarshals the MACCommand_LinkADRReq from JSON.
+func (x *MACCommand_LinkADRReq) UnmarshalJSON(b []byte) error {
return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
}
@@ -3017,19 +3560,492 @@ func (x *MACCommand_PingSlotInfoReq) MarshalProtoJSON(s *jsonplugin.MarshalState
var wroteField bool
if x.Period != 0 || s.HasField("period") {
s.WriteMoreIf(&wroteField)
- s.WriteObjectField("period")
- x.Period.MarshalProtoJSON(s)
+ s.WriteObjectField("period")
+ x.Period.MarshalProtoJSON(s)
+ }
+ s.WriteObjectEnd()
+}
+
+// MarshalJSON marshals the MACCommand_PingSlotInfoReq to JSON.
+func (x *MACCommand_PingSlotInfoReq) MarshalJSON() ([]byte, error) {
+ return jsonplugin.DefaultMarshalerConfig.Marshal(x)
+}
+
+// UnmarshalProtoJSON unmarshals the MACCommand_PingSlotInfoReq message from JSON.
+func (x *MACCommand_PingSlotInfoReq) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+ if s.ReadNil() {
+ return
+ }
+ s.ReadObject(func(key string) {
+ switch key {
+ default:
+ s.ReadAny() // ignore unknown field
+ case "period":
+ s.AddField("period")
+ x.Period.UnmarshalProtoJSON(s)
+ }
+ })
+}
+
+// UnmarshalJSON unmarshals the MACCommand_PingSlotInfoReq from JSON.
+func (x *MACCommand_PingSlotInfoReq) UnmarshalJSON(b []byte) error {
+ return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
+}
+
+// MarshalProtoJSON marshals the MACCommand_PingSlotChannelReq message to JSON.
+func (x *MACCommand_PingSlotChannelReq) MarshalProtoJSON(s *jsonplugin.MarshalState) {
+ if x == nil {
+ s.WriteNil()
+ return
+ }
+ s.WriteObjectStart()
+ var wroteField bool
+ if x.Frequency != 0 || s.HasField("frequency") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("frequency")
+ s.WriteUint64(x.Frequency)
+ }
+ if x.DataRateIndex != 0 || s.HasField("data_rate_index") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("data_rate_index")
+ x.DataRateIndex.MarshalProtoJSON(s)
+ }
+ s.WriteObjectEnd()
+}
+
+// MarshalJSON marshals the MACCommand_PingSlotChannelReq to JSON.
+func (x *MACCommand_PingSlotChannelReq) MarshalJSON() ([]byte, error) {
+ return jsonplugin.DefaultMarshalerConfig.Marshal(x)
+}
+
+// UnmarshalProtoJSON unmarshals the MACCommand_PingSlotChannelReq message from JSON.
+func (x *MACCommand_PingSlotChannelReq) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+ if s.ReadNil() {
+ return
+ }
+ s.ReadObject(func(key string) {
+ switch key {
+ default:
+ s.ReadAny() // ignore unknown field
+ case "frequency":
+ s.AddField("frequency")
+ x.Frequency = s.ReadUint64()
+ case "data_rate_index", "dataRateIndex":
+ s.AddField("data_rate_index")
+ x.DataRateIndex.UnmarshalProtoJSON(s)
+ }
+ })
+}
+
+// UnmarshalJSON unmarshals the MACCommand_PingSlotChannelReq from JSON.
+func (x *MACCommand_PingSlotChannelReq) UnmarshalJSON(b []byte) error {
+ return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
+}
+
+// MarshalProtoJSON marshals the MACCommand_DeviceModeInd message to JSON.
+func (x *MACCommand_DeviceModeInd) MarshalProtoJSON(s *jsonplugin.MarshalState) {
+ if x == nil {
+ s.WriteNil()
+ return
+ }
+ s.WriteObjectStart()
+ var wroteField bool
+ if x.Class != 0 || s.HasField("class") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("class")
+ x.Class.MarshalProtoJSON(s)
+ }
+ s.WriteObjectEnd()
+}
+
+// MarshalJSON marshals the MACCommand_DeviceModeInd to JSON.
+func (x *MACCommand_DeviceModeInd) MarshalJSON() ([]byte, error) {
+ return jsonplugin.DefaultMarshalerConfig.Marshal(x)
+}
+
+// UnmarshalProtoJSON unmarshals the MACCommand_DeviceModeInd message from JSON.
+func (x *MACCommand_DeviceModeInd) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+ if s.ReadNil() {
+ return
+ }
+ s.ReadObject(func(key string) {
+ switch key {
+ default:
+ s.ReadAny() // ignore unknown field
+ case "class":
+ s.AddField("class")
+ x.Class.UnmarshalProtoJSON(s)
+ }
+ })
+}
+
+// UnmarshalJSON unmarshals the MACCommand_DeviceModeInd from JSON.
+func (x *MACCommand_DeviceModeInd) UnmarshalJSON(b []byte) error {
+ return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
+}
+
+// MarshalProtoJSON marshals the MACCommand_DeviceModeConf message to JSON.
+func (x *MACCommand_DeviceModeConf) MarshalProtoJSON(s *jsonplugin.MarshalState) {
+ if x == nil {
+ s.WriteNil()
+ return
+ }
+ s.WriteObjectStart()
+ var wroteField bool
+ if x.Class != 0 || s.HasField("class") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("class")
+ x.Class.MarshalProtoJSON(s)
+ }
+ s.WriteObjectEnd()
+}
+
+// MarshalJSON marshals the MACCommand_DeviceModeConf to JSON.
+func (x *MACCommand_DeviceModeConf) MarshalJSON() ([]byte, error) {
+ return jsonplugin.DefaultMarshalerConfig.Marshal(x)
+}
+
+// UnmarshalProtoJSON unmarshals the MACCommand_DeviceModeConf message from JSON.
+func (x *MACCommand_DeviceModeConf) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+ if s.ReadNil() {
+ return
+ }
+ s.ReadObject(func(key string) {
+ switch key {
+ default:
+ s.ReadAny() // ignore unknown field
+ case "class":
+ s.AddField("class")
+ x.Class.UnmarshalProtoJSON(s)
+ }
+ })
+}
+
+// UnmarshalJSON unmarshals the MACCommand_DeviceModeConf from JSON.
+func (x *MACCommand_DeviceModeConf) UnmarshalJSON(b []byte) error {
+ return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
+}
+
+// MarshalProtoJSON marshals the MACCommand_RelayConfReq_Configuration message to JSON.
+func (x *MACCommand_RelayConfReq_Configuration) MarshalProtoJSON(s *jsonplugin.MarshalState) {
+ if x == nil {
+ s.WriteNil()
+ return
+ }
+ s.WriteObjectStart()
+ var wroteField bool
+ if x.SecondChannel != nil || s.HasField("second_channel") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("second_channel")
+ x.SecondChannel.MarshalProtoJSON(s.WithField("second_channel"))
+ }
+ if x.DefaultChannelIndex != 0 || s.HasField("default_channel_index") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("default_channel_index")
+ s.WriteUint32(x.DefaultChannelIndex)
+ }
+ if x.CadPeriodicity != 0 || s.HasField("cad_periodicity") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("cad_periodicity")
+ x.CadPeriodicity.MarshalProtoJSON(s)
+ }
+ s.WriteObjectEnd()
+}
+
+// MarshalJSON marshals the MACCommand_RelayConfReq_Configuration to JSON.
+func (x *MACCommand_RelayConfReq_Configuration) MarshalJSON() ([]byte, error) {
+ return jsonplugin.DefaultMarshalerConfig.Marshal(x)
+}
+
+// UnmarshalProtoJSON unmarshals the MACCommand_RelayConfReq_Configuration message from JSON.
+func (x *MACCommand_RelayConfReq_Configuration) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+ if s.ReadNil() {
+ return
+ }
+ s.ReadObject(func(key string) {
+ switch key {
+ default:
+ s.ReadAny() // ignore unknown field
+ case "second_channel", "secondChannel":
+ if s.ReadNil() {
+ x.SecondChannel = nil
+ return
+ }
+ x.SecondChannel = &RelaySecondChannel{}
+ x.SecondChannel.UnmarshalProtoJSON(s.WithField("second_channel", true))
+ case "default_channel_index", "defaultChannelIndex":
+ s.AddField("default_channel_index")
+ x.DefaultChannelIndex = s.ReadUint32()
+ case "cad_periodicity", "cadPeriodicity":
+ s.AddField("cad_periodicity")
+ x.CadPeriodicity.UnmarshalProtoJSON(s)
+ }
+ })
+}
+
+// UnmarshalJSON unmarshals the MACCommand_RelayConfReq_Configuration from JSON.
+func (x *MACCommand_RelayConfReq_Configuration) UnmarshalJSON(b []byte) error {
+ return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
+}
+
+// MarshalProtoJSON marshals the MACCommand_RelayConfReq message to JSON.
+func (x *MACCommand_RelayConfReq) MarshalProtoJSON(s *jsonplugin.MarshalState) {
+ if x == nil {
+ s.WriteNil()
+ return
+ }
+ s.WriteObjectStart()
+ var wroteField bool
+ if x.Configuration != nil || s.HasField("configuration") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("configuration")
+ x.Configuration.MarshalProtoJSON(s.WithField("configuration"))
+ }
+ s.WriteObjectEnd()
+}
+
+// MarshalJSON marshals the MACCommand_RelayConfReq to JSON.
+func (x *MACCommand_RelayConfReq) MarshalJSON() ([]byte, error) {
+ return jsonplugin.DefaultMarshalerConfig.Marshal(x)
+}
+
+// UnmarshalProtoJSON unmarshals the MACCommand_RelayConfReq message from JSON.
+func (x *MACCommand_RelayConfReq) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+ if s.ReadNil() {
+ return
+ }
+ s.ReadObject(func(key string) {
+ switch key {
+ default:
+ s.ReadAny() // ignore unknown field
+ case "configuration":
+ if s.ReadNil() {
+ x.Configuration = nil
+ return
+ }
+ x.Configuration = &MACCommand_RelayConfReq_Configuration{}
+ x.Configuration.UnmarshalProtoJSON(s.WithField("configuration", true))
+ }
+ })
+}
+
+// UnmarshalJSON unmarshals the MACCommand_RelayConfReq from JSON.
+func (x *MACCommand_RelayConfReq) UnmarshalJSON(b []byte) error {
+ return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
+}
+
+// MarshalProtoJSON marshals the MACCommand_RelayEndDeviceConfReq_Configuration message to JSON.
+func (x *MACCommand_RelayEndDeviceConfReq_Configuration) MarshalProtoJSON(s *jsonplugin.MarshalState) {
+ if x == nil {
+ s.WriteNil()
+ return
+ }
+ s.WriteObjectStart()
+ var wroteField bool
+ if x.Mode != nil {
+ switch ov := x.Mode.(type) {
+ case *MACCommand_RelayEndDeviceConfReq_Configuration_Always:
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("always")
+ // NOTE: RelayEndDeviceAlwaysMode does not seem to implement MarshalProtoJSON.
+ golang.MarshalMessage(s, ov.Always)
+ case *MACCommand_RelayEndDeviceConfReq_Configuration_Dynamic:
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("dynamic")
+ ov.Dynamic.MarshalProtoJSON(s.WithField("dynamic"))
+ case *MACCommand_RelayEndDeviceConfReq_Configuration_EndDeviceControlled:
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("end_device_controlled")
+ // NOTE: RelayEndDeviceControlledMode does not seem to implement MarshalProtoJSON.
+ golang.MarshalMessage(s, ov.EndDeviceControlled)
+ }
+ }
+ if x.Backoff != 0 || s.HasField("backoff") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("backoff")
+ s.WriteUint32(x.Backoff)
+ }
+ if x.SecondChannel != nil || s.HasField("second_channel") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("second_channel")
+ x.SecondChannel.MarshalProtoJSON(s.WithField("second_channel"))
+ }
+ if x.ServingDeviceId != "" || s.HasField("serving_device_id") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("serving_device_id")
+ s.WriteString(x.ServingDeviceId)
+ }
+ s.WriteObjectEnd()
+}
+
+// MarshalJSON marshals the MACCommand_RelayEndDeviceConfReq_Configuration to JSON.
+func (x *MACCommand_RelayEndDeviceConfReq_Configuration) MarshalJSON() ([]byte, error) {
+ return jsonplugin.DefaultMarshalerConfig.Marshal(x)
+}
+
+// UnmarshalProtoJSON unmarshals the MACCommand_RelayEndDeviceConfReq_Configuration message from JSON.
+func (x *MACCommand_RelayEndDeviceConfReq_Configuration) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+ if s.ReadNil() {
+ return
+ }
+ s.ReadObject(func(key string) {
+ switch key {
+ default:
+ s.ReadAny() // ignore unknown field
+ case "always":
+ s.AddField("always")
+ ov := &MACCommand_RelayEndDeviceConfReq_Configuration_Always{}
+ x.Mode = ov
+ if s.ReadNil() {
+ ov.Always = nil
+ return
+ }
+ // NOTE: RelayEndDeviceAlwaysMode does not seem to implement UnmarshalProtoJSON.
+ var v RelayEndDeviceAlwaysMode
+ golang.UnmarshalMessage(s, &v)
+ ov.Always = &v
+ case "dynamic":
+ ov := &MACCommand_RelayEndDeviceConfReq_Configuration_Dynamic{}
+ x.Mode = ov
+ if s.ReadNil() {
+ ov.Dynamic = nil
+ return
+ }
+ ov.Dynamic = &RelayEndDeviceDynamicMode{}
+ ov.Dynamic.UnmarshalProtoJSON(s.WithField("dynamic", true))
+ case "end_device_controlled", "endDeviceControlled":
+ s.AddField("end_device_controlled")
+ ov := &MACCommand_RelayEndDeviceConfReq_Configuration_EndDeviceControlled{}
+ x.Mode = ov
+ if s.ReadNil() {
+ ov.EndDeviceControlled = nil
+ return
+ }
+ // NOTE: RelayEndDeviceControlledMode does not seem to implement UnmarshalProtoJSON.
+ var v RelayEndDeviceControlledMode
+ golang.UnmarshalMessage(s, &v)
+ ov.EndDeviceControlled = &v
+ case "backoff":
+ s.AddField("backoff")
+ x.Backoff = s.ReadUint32()
+ case "second_channel", "secondChannel":
+ if s.ReadNil() {
+ x.SecondChannel = nil
+ return
+ }
+ x.SecondChannel = &RelaySecondChannel{}
+ x.SecondChannel.UnmarshalProtoJSON(s.WithField("second_channel", true))
+ case "serving_device_id", "servingDeviceId":
+ s.AddField("serving_device_id")
+ x.ServingDeviceId = s.ReadString()
+ }
+ })
+}
+
+// UnmarshalJSON unmarshals the MACCommand_RelayEndDeviceConfReq_Configuration from JSON.
+func (x *MACCommand_RelayEndDeviceConfReq_Configuration) UnmarshalJSON(b []byte) error {
+ return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
+}
+
+// MarshalProtoJSON marshals the MACCommand_RelayEndDeviceConfReq message to JSON.
+func (x *MACCommand_RelayEndDeviceConfReq) MarshalProtoJSON(s *jsonplugin.MarshalState) {
+ if x == nil {
+ s.WriteNil()
+ return
+ }
+ s.WriteObjectStart()
+ var wroteField bool
+ if x.Configuration != nil || s.HasField("configuration") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("configuration")
+ x.Configuration.MarshalProtoJSON(s.WithField("configuration"))
+ }
+ s.WriteObjectEnd()
+}
+
+// MarshalJSON marshals the MACCommand_RelayEndDeviceConfReq to JSON.
+func (x *MACCommand_RelayEndDeviceConfReq) MarshalJSON() ([]byte, error) {
+ return jsonplugin.DefaultMarshalerConfig.Marshal(x)
+}
+
+// UnmarshalProtoJSON unmarshals the MACCommand_RelayEndDeviceConfReq message from JSON.
+func (x *MACCommand_RelayEndDeviceConfReq) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+ if s.ReadNil() {
+ return
+ }
+ s.ReadObject(func(key string) {
+ switch key {
+ default:
+ s.ReadAny() // ignore unknown field
+ case "configuration":
+ if s.ReadNil() {
+ x.Configuration = nil
+ return
+ }
+ x.Configuration = &MACCommand_RelayEndDeviceConfReq_Configuration{}
+ x.Configuration.UnmarshalProtoJSON(s.WithField("configuration", true))
+ }
+ })
+}
+
+// UnmarshalJSON unmarshals the MACCommand_RelayEndDeviceConfReq from JSON.
+func (x *MACCommand_RelayEndDeviceConfReq) UnmarshalJSON(b []byte) error {
+ return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
+}
+
+// MarshalProtoJSON marshals the MACCommand_RelayUpdateUplinkListReq message to JSON.
+func (x *MACCommand_RelayUpdateUplinkListReq) MarshalProtoJSON(s *jsonplugin.MarshalState) {
+ if x == nil {
+ s.WriteNil()
+ return
+ }
+ s.WriteObjectStart()
+ var wroteField bool
+ if x.RuleIndex != 0 || s.HasField("rule_index") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("rule_index")
+ s.WriteUint32(x.RuleIndex)
+ }
+ if x.ForwardLimits != nil || s.HasField("forward_limits") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("forward_limits")
+ x.ForwardLimits.MarshalProtoJSON(s.WithField("forward_limits"))
+ }
+ if len(x.DevAddr) > 0 || s.HasField("dev_addr") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("dev_addr")
+ types.MarshalHEXBytes(s.WithField("dev_addr"), x.DevAddr)
+ }
+ if x.WFCnt != 0 || s.HasField("w_f_cnt") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("w_f_cnt")
+ s.WriteUint32(x.WFCnt)
+ }
+ if len(x.RootWorSKey) > 0 || s.HasField("root_wor_s_key") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("root_wor_s_key")
+ types.MarshalHEXBytes(s.WithField("root_wor_s_key"), x.RootWorSKey)
+ }
+ if x.DeviceId != "" || s.HasField("device_id") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("device_id")
+ s.WriteString(x.DeviceId)
+ }
+ if len(x.SessionKeyId) > 0 || s.HasField("session_key_id") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("session_key_id")
+ s.WriteBytes(x.SessionKeyId)
}
s.WriteObjectEnd()
}
-// MarshalJSON marshals the MACCommand_PingSlotInfoReq to JSON.
-func (x *MACCommand_PingSlotInfoReq) MarshalJSON() ([]byte, error) {
+// MarshalJSON marshals the MACCommand_RelayUpdateUplinkListReq to JSON.
+func (x *MACCommand_RelayUpdateUplinkListReq) MarshalJSON() ([]byte, error) {
return jsonplugin.DefaultMarshalerConfig.Marshal(x)
}
-// UnmarshalProtoJSON unmarshals the MACCommand_PingSlotInfoReq message from JSON.
-func (x *MACCommand_PingSlotInfoReq) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+// UnmarshalProtoJSON unmarshals the MACCommand_RelayUpdateUplinkListReq message from JSON.
+func (x *MACCommand_RelayUpdateUplinkListReq) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
if s.ReadNil() {
return
}
@@ -3037,46 +4053,68 @@ func (x *MACCommand_PingSlotInfoReq) UnmarshalProtoJSON(s *jsonplugin.UnmarshalS
switch key {
default:
s.ReadAny() // ignore unknown field
- case "period":
- s.AddField("period")
- x.Period.UnmarshalProtoJSON(s)
+ case "rule_index", "ruleIndex":
+ s.AddField("rule_index")
+ x.RuleIndex = s.ReadUint32()
+ case "forward_limits", "forwardLimits":
+ if s.ReadNil() {
+ x.ForwardLimits = nil
+ return
+ }
+ x.ForwardLimits = &RelayUplinkForwardLimits{}
+ x.ForwardLimits.UnmarshalProtoJSON(s.WithField("forward_limits", true))
+ case "dev_addr", "devAddr":
+ s.AddField("dev_addr")
+ x.DevAddr = types.Unmarshal4Bytes(s.WithField("dev_addr", false))
+ case "w_f_cnt", "wFCnt":
+ s.AddField("w_f_cnt")
+ x.WFCnt = s.ReadUint32()
+ case "root_wor_s_key", "rootWorSKey":
+ s.AddField("root_wor_s_key")
+ x.RootWorSKey = types.Unmarshal16Bytes(s.WithField("root_wor_s_key", false))
+ case "device_id", "deviceId":
+ s.AddField("device_id")
+ x.DeviceId = s.ReadString()
+ case "session_key_id", "sessionKeyId":
+ s.AddField("session_key_id")
+ x.SessionKeyId = s.ReadBytes()
}
})
}
-// UnmarshalJSON unmarshals the MACCommand_PingSlotInfoReq from JSON.
-func (x *MACCommand_PingSlotInfoReq) UnmarshalJSON(b []byte) error {
+// UnmarshalJSON unmarshals the MACCommand_RelayUpdateUplinkListReq from JSON.
+func (x *MACCommand_RelayUpdateUplinkListReq) UnmarshalJSON(b []byte) error {
return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
}
-// MarshalProtoJSON marshals the MACCommand_PingSlotChannelReq message to JSON.
-func (x *MACCommand_PingSlotChannelReq) MarshalProtoJSON(s *jsonplugin.MarshalState) {
+// MarshalProtoJSON marshals the MACCommand_RelayCtrlUplinkListReq message to JSON.
+func (x *MACCommand_RelayCtrlUplinkListReq) MarshalProtoJSON(s *jsonplugin.MarshalState) {
if x == nil {
s.WriteNil()
return
}
s.WriteObjectStart()
var wroteField bool
- if x.Frequency != 0 || s.HasField("frequency") {
+ if x.RuleIndex != 0 || s.HasField("rule_index") {
s.WriteMoreIf(&wroteField)
- s.WriteObjectField("frequency")
- s.WriteUint64(x.Frequency)
+ s.WriteObjectField("rule_index")
+ s.WriteUint32(x.RuleIndex)
}
- if x.DataRateIndex != 0 || s.HasField("data_rate_index") {
+ if x.Action != 0 || s.HasField("action") {
s.WriteMoreIf(&wroteField)
- s.WriteObjectField("data_rate_index")
- x.DataRateIndex.MarshalProtoJSON(s)
+ s.WriteObjectField("action")
+ x.Action.MarshalProtoJSON(s)
}
s.WriteObjectEnd()
}
-// MarshalJSON marshals the MACCommand_PingSlotChannelReq to JSON.
-func (x *MACCommand_PingSlotChannelReq) MarshalJSON() ([]byte, error) {
+// MarshalJSON marshals the MACCommand_RelayCtrlUplinkListReq to JSON.
+func (x *MACCommand_RelayCtrlUplinkListReq) MarshalJSON() ([]byte, error) {
return jsonplugin.DefaultMarshalerConfig.Marshal(x)
}
-// UnmarshalProtoJSON unmarshals the MACCommand_PingSlotChannelReq message from JSON.
-func (x *MACCommand_PingSlotChannelReq) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+// UnmarshalProtoJSON unmarshals the MACCommand_RelayCtrlUplinkListReq message from JSON.
+func (x *MACCommand_RelayCtrlUplinkListReq) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
if s.ReadNil() {
return
}
@@ -3084,44 +4122,64 @@ func (x *MACCommand_PingSlotChannelReq) UnmarshalProtoJSON(s *jsonplugin.Unmarsh
switch key {
default:
s.ReadAny() // ignore unknown field
- case "frequency":
- s.AddField("frequency")
- x.Frequency = s.ReadUint64()
- case "data_rate_index", "dataRateIndex":
- s.AddField("data_rate_index")
- x.DataRateIndex.UnmarshalProtoJSON(s)
+ case "rule_index", "ruleIndex":
+ s.AddField("rule_index")
+ x.RuleIndex = s.ReadUint32()
+ case "action":
+ s.AddField("action")
+ x.Action.UnmarshalProtoJSON(s)
}
})
}
-// UnmarshalJSON unmarshals the MACCommand_PingSlotChannelReq from JSON.
-func (x *MACCommand_PingSlotChannelReq) UnmarshalJSON(b []byte) error {
+// UnmarshalJSON unmarshals the MACCommand_RelayCtrlUplinkListReq from JSON.
+func (x *MACCommand_RelayCtrlUplinkListReq) UnmarshalJSON(b []byte) error {
return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
}
-// MarshalProtoJSON marshals the MACCommand_DeviceModeInd message to JSON.
-func (x *MACCommand_DeviceModeInd) MarshalProtoJSON(s *jsonplugin.MarshalState) {
+// MarshalProtoJSON marshals the MACCommand_RelayConfigureFwdLimitReq message to JSON.
+func (x *MACCommand_RelayConfigureFwdLimitReq) MarshalProtoJSON(s *jsonplugin.MarshalState) {
if x == nil {
s.WriteNil()
return
}
s.WriteObjectStart()
var wroteField bool
- if x.Class != 0 || s.HasField("class") {
+ if x.ResetLimitCounter != 0 || s.HasField("reset_limit_counter") {
s.WriteMoreIf(&wroteField)
- s.WriteObjectField("class")
- x.Class.MarshalProtoJSON(s)
+ s.WriteObjectField("reset_limit_counter")
+ x.ResetLimitCounter.MarshalProtoJSON(s)
+ }
+ if x.JoinRequestLimits != nil || s.HasField("join_request_limits") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("join_request_limits")
+ x.JoinRequestLimits.MarshalProtoJSON(s.WithField("join_request_limits"))
+ }
+ if x.NotifyLimits != nil || s.HasField("notify_limits") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("notify_limits")
+ x.NotifyLimits.MarshalProtoJSON(s.WithField("notify_limits"))
+ }
+ if x.GlobalUplinkLimits != nil || s.HasField("global_uplink_limits") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("global_uplink_limits")
+ x.GlobalUplinkLimits.MarshalProtoJSON(s.WithField("global_uplink_limits"))
+ }
+ if x.OverallLimits != nil || s.HasField("overall_limits") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("overall_limits")
+ x.OverallLimits.MarshalProtoJSON(s.WithField("overall_limits"))
}
s.WriteObjectEnd()
}
-// MarshalJSON marshals the MACCommand_DeviceModeInd to JSON.
-func (x *MACCommand_DeviceModeInd) MarshalJSON() ([]byte, error) {
+// MarshalJSON marshals the MACCommand_RelayConfigureFwdLimitReq to JSON.
+func (x *MACCommand_RelayConfigureFwdLimitReq) MarshalJSON() ([]byte, error) {
return jsonplugin.DefaultMarshalerConfig.Marshal(x)
}
-// UnmarshalProtoJSON unmarshals the MACCommand_DeviceModeInd message from JSON.
-func (x *MACCommand_DeviceModeInd) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+// UnmarshalProtoJSON unmarshals the MACCommand_RelayConfigureFwdLimitReq message from JSON.
+func (x *MACCommand_RelayConfigureFwdLimitReq) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
if s.ReadNil() {
return
}
@@ -3129,41 +4187,79 @@ func (x *MACCommand_DeviceModeInd) UnmarshalProtoJSON(s *jsonplugin.UnmarshalSta
switch key {
default:
s.ReadAny() // ignore unknown field
- case "class":
- s.AddField("class")
- x.Class.UnmarshalProtoJSON(s)
+ case "reset_limit_counter", "resetLimitCounter":
+ s.AddField("reset_limit_counter")
+ x.ResetLimitCounter.UnmarshalProtoJSON(s)
+ case "join_request_limits", "joinRequestLimits":
+ if s.ReadNil() {
+ x.JoinRequestLimits = nil
+ return
+ }
+ x.JoinRequestLimits = &RelayForwardLimits{}
+ x.JoinRequestLimits.UnmarshalProtoJSON(s.WithField("join_request_limits", true))
+ case "notify_limits", "notifyLimits":
+ if s.ReadNil() {
+ x.NotifyLimits = nil
+ return
+ }
+ x.NotifyLimits = &RelayForwardLimits{}
+ x.NotifyLimits.UnmarshalProtoJSON(s.WithField("notify_limits", true))
+ case "global_uplink_limits", "globalUplinkLimits":
+ if s.ReadNil() {
+ x.GlobalUplinkLimits = nil
+ return
+ }
+ x.GlobalUplinkLimits = &RelayForwardLimits{}
+ x.GlobalUplinkLimits.UnmarshalProtoJSON(s.WithField("global_uplink_limits", true))
+ case "overall_limits", "overallLimits":
+ if s.ReadNil() {
+ x.OverallLimits = nil
+ return
+ }
+ x.OverallLimits = &RelayForwardLimits{}
+ x.OverallLimits.UnmarshalProtoJSON(s.WithField("overall_limits", true))
}
})
}
-// UnmarshalJSON unmarshals the MACCommand_DeviceModeInd from JSON.
-func (x *MACCommand_DeviceModeInd) UnmarshalJSON(b []byte) error {
+// UnmarshalJSON unmarshals the MACCommand_RelayConfigureFwdLimitReq from JSON.
+func (x *MACCommand_RelayConfigureFwdLimitReq) UnmarshalJSON(b []byte) error {
return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
}
-// MarshalProtoJSON marshals the MACCommand_DeviceModeConf message to JSON.
-func (x *MACCommand_DeviceModeConf) MarshalProtoJSON(s *jsonplugin.MarshalState) {
+// MarshalProtoJSON marshals the MACCommand_RelayNotifyNewEndDeviceReq message to JSON.
+func (x *MACCommand_RelayNotifyNewEndDeviceReq) MarshalProtoJSON(s *jsonplugin.MarshalState) {
if x == nil {
s.WriteNil()
return
}
s.WriteObjectStart()
var wroteField bool
- if x.Class != 0 || s.HasField("class") {
+ if len(x.DevAddr) > 0 || s.HasField("dev_addr") {
s.WriteMoreIf(&wroteField)
- s.WriteObjectField("class")
- x.Class.MarshalProtoJSON(s)
+ s.WriteObjectField("dev_addr")
+ types.MarshalHEXBytes(s.WithField("dev_addr"), x.DevAddr)
+ }
+ if x.Snr != 0 || s.HasField("snr") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("snr")
+ s.WriteInt32(x.Snr)
+ }
+ if x.Rssi != 0 || s.HasField("rssi") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("rssi")
+ s.WriteInt32(x.Rssi)
}
s.WriteObjectEnd()
}
-// MarshalJSON marshals the MACCommand_DeviceModeConf to JSON.
-func (x *MACCommand_DeviceModeConf) MarshalJSON() ([]byte, error) {
+// MarshalJSON marshals the MACCommand_RelayNotifyNewEndDeviceReq to JSON.
+func (x *MACCommand_RelayNotifyNewEndDeviceReq) MarshalJSON() ([]byte, error) {
return jsonplugin.DefaultMarshalerConfig.Marshal(x)
}
-// UnmarshalProtoJSON unmarshals the MACCommand_DeviceModeConf message from JSON.
-func (x *MACCommand_DeviceModeConf) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+// UnmarshalProtoJSON unmarshals the MACCommand_RelayNotifyNewEndDeviceReq message from JSON.
+func (x *MACCommand_RelayNotifyNewEndDeviceReq) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
if s.ReadNil() {
return
}
@@ -3171,15 +4267,21 @@ func (x *MACCommand_DeviceModeConf) UnmarshalProtoJSON(s *jsonplugin.UnmarshalSt
switch key {
default:
s.ReadAny() // ignore unknown field
- case "class":
- s.AddField("class")
- x.Class.UnmarshalProtoJSON(s)
+ case "dev_addr", "devAddr":
+ s.AddField("dev_addr")
+ x.DevAddr = types.Unmarshal4Bytes(s.WithField("dev_addr", false))
+ case "snr":
+ s.AddField("snr")
+ x.Snr = s.ReadInt32()
+ case "rssi":
+ s.AddField("rssi")
+ x.Rssi = s.ReadInt32()
}
})
}
-// UnmarshalJSON unmarshals the MACCommand_DeviceModeConf from JSON.
-func (x *MACCommand_DeviceModeConf) UnmarshalJSON(b []byte) error {
+// UnmarshalJSON unmarshals the MACCommand_RelayNotifyNewEndDeviceReq from JSON.
+func (x *MACCommand_RelayNotifyNewEndDeviceReq) UnmarshalJSON(b []byte) error {
return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
}
@@ -3335,6 +4437,55 @@ func (x *MACCommand) MarshalProtoJSON(s *jsonplugin.MarshalState) {
s.WriteMoreIf(&wroteField)
s.WriteObjectField("device_mode_conf")
ov.DeviceModeConf.MarshalProtoJSON(s.WithField("device_mode_conf"))
+ case *MACCommand_RelayConfReq_:
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("relay_conf_req")
+ ov.RelayConfReq.MarshalProtoJSON(s.WithField("relay_conf_req"))
+ case *MACCommand_RelayConfAns_:
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("relay_conf_ans")
+ // NOTE: MACCommand_RelayConfAns does not seem to implement MarshalProtoJSON.
+ golang.MarshalMessage(s, ov.RelayConfAns)
+ case *MACCommand_RelayEndDeviceConfReq_:
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("relay_end_device_conf_req")
+ ov.RelayEndDeviceConfReq.MarshalProtoJSON(s.WithField("relay_end_device_conf_req"))
+ case *MACCommand_RelayEndDeviceConfAns_:
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("relay_end_device_conf_ans")
+ // NOTE: MACCommand_RelayEndDeviceConfAns does not seem to implement MarshalProtoJSON.
+ golang.MarshalMessage(s, ov.RelayEndDeviceConfAns)
+ case *MACCommand_RelayUpdateUplinkListReq_:
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("relay_update_uplink_list_req")
+ ov.RelayUpdateUplinkListReq.MarshalProtoJSON(s.WithField("relay_update_uplink_list_req"))
+ case *MACCommand_RelayUpdateUplinkListAns_:
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("relay_update_uplink_list_ans")
+ // NOTE: MACCommand_RelayUpdateUplinkListAns does not seem to implement MarshalProtoJSON.
+ golang.MarshalMessage(s, ov.RelayUpdateUplinkListAns)
+ case *MACCommand_RelayCtrlUplinkListReq_:
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("relay_ctrl_uplink_list_req")
+ ov.RelayCtrlUplinkListReq.MarshalProtoJSON(s.WithField("relay_ctrl_uplink_list_req"))
+ case *MACCommand_RelayCtrlUplinkListAns_:
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("relay_ctrl_uplink_list_ans")
+ // NOTE: MACCommand_RelayCtrlUplinkListAns does not seem to implement MarshalProtoJSON.
+ golang.MarshalMessage(s, ov.RelayCtrlUplinkListAns)
+ case *MACCommand_RelayConfigureFwdLimitReq_:
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("relay_configure_fwd_limit_req")
+ ov.RelayConfigureFwdLimitReq.MarshalProtoJSON(s.WithField("relay_configure_fwd_limit_req"))
+ case *MACCommand_RelayConfigureFwdLimitAns_:
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("relay_configure_fwd_limit_ans")
+ // NOTE: MACCommand_RelayConfigureFwdLimitAns does not seem to implement MarshalProtoJSON.
+ golang.MarshalMessage(s, ov.RelayConfigureFwdLimitAns)
+ case *MACCommand_RelayNotifyNewEndDeviceReq_:
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("relay_notify_new_end_device_req")
+ ov.RelayNotifyNewEndDeviceReq.MarshalProtoJSON(s.WithField("relay_notify_new_end_device_req"))
}
}
s.WriteObjectEnd()
@@ -3671,6 +4822,120 @@ func (x *MACCommand) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
}
ov.DeviceModeConf = &MACCommand_DeviceModeConf{}
ov.DeviceModeConf.UnmarshalProtoJSON(s.WithField("device_mode_conf", true))
+ case "relay_conf_req", "relayConfReq":
+ ov := &MACCommand_RelayConfReq_{}
+ x.Payload = ov
+ if s.ReadNil() {
+ ov.RelayConfReq = nil
+ return
+ }
+ ov.RelayConfReq = &MACCommand_RelayConfReq{}
+ ov.RelayConfReq.UnmarshalProtoJSON(s.WithField("relay_conf_req", true))
+ case "relay_conf_ans", "relayConfAns":
+ s.AddField("relay_conf_ans")
+ ov := &MACCommand_RelayConfAns_{}
+ x.Payload = ov
+ if s.ReadNil() {
+ ov.RelayConfAns = nil
+ return
+ }
+ // NOTE: MACCommand_RelayConfAns does not seem to implement UnmarshalProtoJSON.
+ var v MACCommand_RelayConfAns
+ golang.UnmarshalMessage(s, &v)
+ ov.RelayConfAns = &v
+ case "relay_end_device_conf_req", "relayEndDeviceConfReq":
+ ov := &MACCommand_RelayEndDeviceConfReq_{}
+ x.Payload = ov
+ if s.ReadNil() {
+ ov.RelayEndDeviceConfReq = nil
+ return
+ }
+ ov.RelayEndDeviceConfReq = &MACCommand_RelayEndDeviceConfReq{}
+ ov.RelayEndDeviceConfReq.UnmarshalProtoJSON(s.WithField("relay_end_device_conf_req", true))
+ case "relay_end_device_conf_ans", "relayEndDeviceConfAns":
+ s.AddField("relay_end_device_conf_ans")
+ ov := &MACCommand_RelayEndDeviceConfAns_{}
+ x.Payload = ov
+ if s.ReadNil() {
+ ov.RelayEndDeviceConfAns = nil
+ return
+ }
+ // NOTE: MACCommand_RelayEndDeviceConfAns does not seem to implement UnmarshalProtoJSON.
+ var v MACCommand_RelayEndDeviceConfAns
+ golang.UnmarshalMessage(s, &v)
+ ov.RelayEndDeviceConfAns = &v
+ case "relay_update_uplink_list_req", "relayUpdateUplinkListReq":
+ ov := &MACCommand_RelayUpdateUplinkListReq_{}
+ x.Payload = ov
+ if s.ReadNil() {
+ ov.RelayUpdateUplinkListReq = nil
+ return
+ }
+ ov.RelayUpdateUplinkListReq = &MACCommand_RelayUpdateUplinkListReq{}
+ ov.RelayUpdateUplinkListReq.UnmarshalProtoJSON(s.WithField("relay_update_uplink_list_req", true))
+ case "relay_update_uplink_list_ans", "relayUpdateUplinkListAns":
+ s.AddField("relay_update_uplink_list_ans")
+ ov := &MACCommand_RelayUpdateUplinkListAns_{}
+ x.Payload = ov
+ if s.ReadNil() {
+ ov.RelayUpdateUplinkListAns = nil
+ return
+ }
+ // NOTE: MACCommand_RelayUpdateUplinkListAns does not seem to implement UnmarshalProtoJSON.
+ var v MACCommand_RelayUpdateUplinkListAns
+ golang.UnmarshalMessage(s, &v)
+ ov.RelayUpdateUplinkListAns = &v
+ case "relay_ctrl_uplink_list_req", "relayCtrlUplinkListReq":
+ ov := &MACCommand_RelayCtrlUplinkListReq_{}
+ x.Payload = ov
+ if s.ReadNil() {
+ ov.RelayCtrlUplinkListReq = nil
+ return
+ }
+ ov.RelayCtrlUplinkListReq = &MACCommand_RelayCtrlUplinkListReq{}
+ ov.RelayCtrlUplinkListReq.UnmarshalProtoJSON(s.WithField("relay_ctrl_uplink_list_req", true))
+ case "relay_ctrl_uplink_list_ans", "relayCtrlUplinkListAns":
+ s.AddField("relay_ctrl_uplink_list_ans")
+ ov := &MACCommand_RelayCtrlUplinkListAns_{}
+ x.Payload = ov
+ if s.ReadNil() {
+ ov.RelayCtrlUplinkListAns = nil
+ return
+ }
+ // NOTE: MACCommand_RelayCtrlUplinkListAns does not seem to implement UnmarshalProtoJSON.
+ var v MACCommand_RelayCtrlUplinkListAns
+ golang.UnmarshalMessage(s, &v)
+ ov.RelayCtrlUplinkListAns = &v
+ case "relay_configure_fwd_limit_req", "relayConfigureFwdLimitReq":
+ ov := &MACCommand_RelayConfigureFwdLimitReq_{}
+ x.Payload = ov
+ if s.ReadNil() {
+ ov.RelayConfigureFwdLimitReq = nil
+ return
+ }
+ ov.RelayConfigureFwdLimitReq = &MACCommand_RelayConfigureFwdLimitReq{}
+ ov.RelayConfigureFwdLimitReq.UnmarshalProtoJSON(s.WithField("relay_configure_fwd_limit_req", true))
+ case "relay_configure_fwd_limit_ans", "relayConfigureFwdLimitAns":
+ s.AddField("relay_configure_fwd_limit_ans")
+ ov := &MACCommand_RelayConfigureFwdLimitAns_{}
+ x.Payload = ov
+ if s.ReadNil() {
+ ov.RelayConfigureFwdLimitAns = nil
+ return
+ }
+ // NOTE: MACCommand_RelayConfigureFwdLimitAns does not seem to implement UnmarshalProtoJSON.
+ var v MACCommand_RelayConfigureFwdLimitAns
+ golang.UnmarshalMessage(s, &v)
+ ov.RelayConfigureFwdLimitAns = &v
+ case "relay_notify_new_end_device_req", "relayNotifyNewEndDeviceReq":
+ ov := &MACCommand_RelayNotifyNewEndDeviceReq_{}
+ x.Payload = ov
+ if s.ReadNil() {
+ ov.RelayNotifyNewEndDeviceReq = nil
+ return
+ }
+ ov.RelayNotifyNewEndDeviceReq = &MACCommand_RelayNotifyNewEndDeviceReq{}
+ ov.RelayNotifyNewEndDeviceReq.UnmarshalProtoJSON(s.WithField("relay_notify_new_end_device_req", true))
}
})
}
@@ -4032,3 +5297,155 @@ func (x *DeviceEIRPValue) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
func (x *DeviceEIRPValue) UnmarshalJSON(b []byte) error {
return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
}
+
+// MarshalProtoJSON marshals the RelayForwardUplinkReq message to JSON.
+func (x *RelayForwardUplinkReq) MarshalProtoJSON(s *jsonplugin.MarshalState) {
+ if x == nil {
+ s.WriteNil()
+ return
+ }
+ s.WriteObjectStart()
+ var wroteField bool
+ if x.DataRate != nil || s.HasField("data_rate") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("data_rate")
+ // NOTE: DataRate does not seem to implement MarshalProtoJSON.
+ golang.MarshalMessage(s, x.DataRate)
+ }
+ if x.Snr != 0 || s.HasField("snr") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("snr")
+ s.WriteInt32(x.Snr)
+ }
+ if x.Rssi != 0 || s.HasField("rssi") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("rssi")
+ s.WriteInt32(x.Rssi)
+ }
+ if x.WorChannel != 0 || s.HasField("wor_channel") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("wor_channel")
+ x.WorChannel.MarshalProtoJSON(s)
+ }
+ if x.Frequency != 0 || s.HasField("frequency") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("frequency")
+ s.WriteUint64(x.Frequency)
+ }
+ if len(x.RawPayload) > 0 || s.HasField("raw_payload") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("raw_payload")
+ s.WriteBytes(x.RawPayload)
+ }
+ s.WriteObjectEnd()
+}
+
+// MarshalJSON marshals the RelayForwardUplinkReq to JSON.
+func (x *RelayForwardUplinkReq) MarshalJSON() ([]byte, error) {
+ return jsonplugin.DefaultMarshalerConfig.Marshal(x)
+}
+
+// UnmarshalProtoJSON unmarshals the RelayForwardUplinkReq message from JSON.
+func (x *RelayForwardUplinkReq) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+ if s.ReadNil() {
+ return
+ }
+ s.ReadObject(func(key string) {
+ switch key {
+ default:
+ s.ReadAny() // ignore unknown field
+ case "data_rate", "dataRate":
+ s.AddField("data_rate")
+ if s.ReadNil() {
+ x.DataRate = nil
+ return
+ }
+ // NOTE: DataRate does not seem to implement UnmarshalProtoJSON.
+ var v DataRate
+ golang.UnmarshalMessage(s, &v)
+ x.DataRate = &v
+ case "snr":
+ s.AddField("snr")
+ x.Snr = s.ReadInt32()
+ case "rssi":
+ s.AddField("rssi")
+ x.Rssi = s.ReadInt32()
+ case "wor_channel", "worChannel":
+ s.AddField("wor_channel")
+ x.WorChannel.UnmarshalProtoJSON(s)
+ case "frequency":
+ s.AddField("frequency")
+ x.Frequency = s.ReadUint64()
+ case "raw_payload", "rawPayload":
+ s.AddField("raw_payload")
+ x.RawPayload = s.ReadBytes()
+ }
+ })
+}
+
+// UnmarshalJSON unmarshals the RelayForwardUplinkReq from JSON.
+func (x *RelayForwardUplinkReq) UnmarshalJSON(b []byte) error {
+ return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
+}
+
+// MarshalProtoJSON marshals the RelayUplinkToken message to JSON.
+func (x *RelayUplinkToken) MarshalProtoJSON(s *jsonplugin.MarshalState) {
+ if x == nil {
+ s.WriteNil()
+ return
+ }
+ s.WriteObjectStart()
+ var wroteField bool
+ if x.Ids != nil || s.HasField("ids") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("ids")
+ x.Ids.MarshalProtoJSON(s.WithField("ids"))
+ }
+ if len(x.SessionKeyId) > 0 || s.HasField("session_key_id") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("session_key_id")
+ s.WriteBytes(x.SessionKeyId)
+ }
+ if x.FullFCnt != 0 || s.HasField("full_f_cnt") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("full_f_cnt")
+ s.WriteUint32(x.FullFCnt)
+ }
+ s.WriteObjectEnd()
+}
+
+// MarshalJSON marshals the RelayUplinkToken to JSON.
+func (x *RelayUplinkToken) MarshalJSON() ([]byte, error) {
+ return jsonplugin.DefaultMarshalerConfig.Marshal(x)
+}
+
+// UnmarshalProtoJSON unmarshals the RelayUplinkToken message from JSON.
+func (x *RelayUplinkToken) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+ if s.ReadNil() {
+ return
+ }
+ s.ReadObject(func(key string) {
+ switch key {
+ default:
+ s.ReadAny() // ignore unknown field
+ case "ids":
+ if s.ReadNil() {
+ x.Ids = nil
+ return
+ }
+ x.Ids = &EndDeviceIdentifiers{}
+ x.Ids.UnmarshalProtoJSON(s.WithField("ids", true))
+ case "session_key_id", "sessionKeyId":
+ s.AddField("session_key_id")
+ x.SessionKeyId = s.ReadBytes()
+ case "full_f_cnt", "fullFCnt":
+ s.AddField("full_f_cnt")
+ x.FullFCnt = s.ReadUint32()
+ }
+ })
+}
+
+// UnmarshalJSON unmarshals the RelayUplinkToken from JSON.
+func (x *RelayUplinkToken) UnmarshalJSON(b []byte) error {
+ return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
+}
diff --git a/pkg/ttnpb/lorawan_mac_commands.go b/pkg/ttnpb/lorawan_mac_commands.go
index 407b8d4d9b..38b0167494 100644
--- a/pkg/ttnpb/lorawan_mac_commands.go
+++ b/pkg/ttnpb/lorawan_mac_commands.go
@@ -328,3 +328,141 @@ func (pld *MACCommand_DeviceModeConf) MACCommand() *MACCommand {
},
}
}
+
+// MACCommand returns the RelayConfReq MAC command as a *MACCommand.
+func (pld *MACCommand_RelayConfReq) MACCommand() *MACCommand {
+ return &MACCommand{
+ Cid: MACCommandIdentifier_CID_RELAY_CONF,
+ Payload: &MACCommand_RelayConfReq_{
+ RelayConfReq: pld,
+ },
+ }
+}
+
+// MACCommand returns the RelayConfAns MAC command as a *MACCommand.
+func (pld *MACCommand_RelayConfAns) MACCommand() *MACCommand {
+ return &MACCommand{
+ Cid: MACCommandIdentifier_CID_RELAY_CONF,
+ Payload: &MACCommand_RelayConfAns_{
+ RelayConfAns: pld,
+ },
+ }
+}
+
+// MACCommand returns the EndDeviceConfReq MAC command as a *MACCommand.
+func (pld *MACCommand_RelayEndDeviceConfReq) MACCommand() *MACCommand {
+ return &MACCommand{
+ Cid: MACCommandIdentifier_CID_RELAY_END_DEVICE_CONF,
+ Payload: &MACCommand_RelayEndDeviceConfReq_{
+ RelayEndDeviceConfReq: pld,
+ },
+ }
+}
+
+// MACCommand returns the EndDeviceConfAns MAC command as a *MACCommand.
+func (pld *MACCommand_RelayEndDeviceConfAns) MACCommand() *MACCommand {
+ return &MACCommand{
+ Cid: MACCommandIdentifier_CID_RELAY_END_DEVICE_CONF,
+ Payload: &MACCommand_RelayEndDeviceConfAns_{
+ RelayEndDeviceConfAns: pld,
+ },
+ }
+}
+
+// MACCommand returns the UpdateUplinkListReq MAC command as a *MACCommand.
+func (pld *MACCommand_RelayUpdateUplinkListReq) MACCommand() *MACCommand {
+ return &MACCommand{
+ Cid: MACCommandIdentifier_CID_RELAY_UPDATE_UPLINK_LIST,
+ Payload: &MACCommand_RelayUpdateUplinkListReq_{
+ RelayUpdateUplinkListReq: pld,
+ },
+ }
+}
+
+// MACCommand returns the UpdateUplinkListAns MAC command as a *MACCommand.
+func (pld *MACCommand_RelayUpdateUplinkListAns) MACCommand() *MACCommand {
+ return &MACCommand{
+ Cid: MACCommandIdentifier_CID_RELAY_UPDATE_UPLINK_LIST,
+ Payload: &MACCommand_RelayUpdateUplinkListAns_{
+ RelayUpdateUplinkListAns: pld,
+ },
+ }
+}
+
+// MACCommand returns the RelayCtrlUplinkListReq MAC command as a *MACCommand.
+func (pld *MACCommand_RelayCtrlUplinkListReq) MACCommand() *MACCommand {
+ return &MACCommand{
+ Cid: MACCommandIdentifier_CID_RELAY_CTRL_UPLINK_LIST,
+ Payload: &MACCommand_RelayCtrlUplinkListReq_{
+ RelayCtrlUplinkListReq: pld,
+ },
+ }
+}
+
+// MACCommand returns the RelayCtrlUplinkListAns MAC command as a *MACCommand.
+func (pld *MACCommand_RelayCtrlUplinkListAns) MACCommand() *MACCommand {
+ return &MACCommand{
+ Cid: MACCommandIdentifier_CID_RELAY_CTRL_UPLINK_LIST,
+ Payload: &MACCommand_RelayCtrlUplinkListAns_{
+ RelayCtrlUplinkListAns: pld,
+ },
+ }
+}
+
+// MACCommand returns the ConfigureFwdLimitReq MAC command as a *MACCommand.
+func (pld *MACCommand_RelayConfigureFwdLimitReq) MACCommand() *MACCommand {
+ return &MACCommand{
+ Cid: MACCommandIdentifier_CID_RELAY_CONFIGURE_FWD_LIMIT,
+ Payload: &MACCommand_RelayConfigureFwdLimitReq_{
+ RelayConfigureFwdLimitReq: pld,
+ },
+ }
+}
+
+// MACCommand returns the ConfigureFwdLimitAns MAC command as a *MACCommand.
+func (pld *MACCommand_RelayConfigureFwdLimitAns) MACCommand() *MACCommand {
+ return &MACCommand{
+ Cid: MACCommandIdentifier_CID_RELAY_CONFIGURE_FWD_LIMIT,
+ Payload: &MACCommand_RelayConfigureFwdLimitAns_{
+ RelayConfigureFwdLimitAns: pld,
+ },
+ }
+}
+
+// MACCommand returns the NotifyNewEndDeviceReq MAC command as a *MACCommand.
+func (pld *MACCommand_RelayNotifyNewEndDeviceReq) MACCommand() *MACCommand {
+ return &MACCommand{
+ Cid: MACCommandIdentifier_CID_RELAY_NOTIFY_NEW_END_DEVICE,
+ Payload: &MACCommand_RelayNotifyNewEndDeviceReq_{
+ RelayNotifyNewEndDeviceReq: pld,
+ },
+ }
+}
+
+// sanitizableMACCommandPayload is a MAC command payload that can be sanitized.
+type sanitizableMACCommandPayload interface {
+ // sanitizedMACCommand returns a sanitized copy of the MAC command.
+ sanitizedMACCommand() *MACCommand
+}
+
+// Sanitized returns a sanitized copy of the MAC command.
+func (m *MACCommand) Sanitized() *MACCommand {
+ if v, ok := m.GetPayload().(sanitizableMACCommandPayload); ok {
+ return v.sanitizedMACCommand()
+ }
+ return m
+}
+
+var _ sanitizableMACCommandPayload = (*MACCommand_RelayUpdateUplinkListReq_)(nil)
+
+// Sanitized returns a sanitized copy of the payload.
+func (pld *MACCommand_RelayUpdateUplinkListReq) Sanitized() *MACCommand_RelayUpdateUplinkListReq {
+ pld = Clone(pld)
+ pld.RootWorSKey = nil
+ return pld
+}
+
+// sanitizedMACCommand returns a sanitized copy of the MAC command.
+func (pld *MACCommand_RelayUpdateUplinkListReq_) sanitizedMACCommand() *MACCommand {
+ return pld.RelayUpdateUplinkListReq.Sanitized().MACCommand()
+}
diff --git a/pkg/ttnpb/messages_flags.pb.go b/pkg/ttnpb/messages_flags.pb.go
index e8dfada3f1..38ea4ccdd8 100644
--- a/pkg/ttnpb/messages_flags.pb.go
+++ b/pkg/ttnpb/messages_flags.pb.go
@@ -165,7 +165,7 @@ func AddSetFlagsForApplicationUplink(flags *pflag.FlagSet, prefix string, hidden
// FIXME: Skipping NormalizedPayload because this repeated WKT is currently not supported.
flags.AddFlag(flagsplugin.NewStringSliceFlag(flagsplugin.Prefix("normalized-payload-warnings", prefix), "", flagsplugin.WithHidden(hidden)))
// FIXME: Skipping RxMetadata because repeated messages are currently not supported.
- // FIXME: Skipping Settings because it does not seem to implement AddSetFlags.
+ AddSetFlagsForTxSettings(flags, flagsplugin.Prefix("settings", prefix), hidden)
flags.AddFlag(flagsplugin.NewTimestampFlag(flagsplugin.Prefix("received-at", prefix), "", flagsplugin.WithHidden(hidden)))
AddSetFlagsForKeyEnvelope(flags, flagsplugin.Prefix("app-s-key", prefix), hidden)
flags.AddFlag(flagsplugin.NewUint32Flag(flagsplugin.Prefix("last-a-f-cnt-down", prefix), "", flagsplugin.WithHidden(hidden)))
@@ -173,7 +173,7 @@ func AddSetFlagsForApplicationUplink(flags *pflag.FlagSet, prefix string, hidden
flags.AddFlag(flagsplugin.NewDurationFlag(flagsplugin.Prefix("consumed-airtime", prefix), "", flagsplugin.WithHidden(hidden)))
// FIXME: Skipping Locations because maps with message value types are currently not supported.
AddSetFlagsForEndDeviceVersionIdentifiers(flags, flagsplugin.Prefix("version-ids", prefix), hidden)
- // FIXME: Skipping NetworkIds because it does not seem to implement AddSetFlags.
+ AddSetFlagsForNetworkIdentifiers(flags, flagsplugin.Prefix("network-ids", prefix), hidden)
}
// SetFromFlags sets the ApplicationUplink message from flags.
@@ -217,7 +217,16 @@ func (m *ApplicationUplink) SetFromFlags(flags *pflag.FlagSet, prefix string) (p
paths = append(paths, flagsplugin.Prefix("normalized_payload_warnings", prefix))
}
// FIXME: Skipping RxMetadata because it does not seem to implement AddSetFlags.
- // FIXME: Skipping Settings because it does not seem to implement AddSetFlags.
+ if changed := flagsplugin.IsAnyPrefixSet(flags, flagsplugin.Prefix("settings", prefix)); changed {
+ if m.Settings == nil {
+ m.Settings = &TxSettings{}
+ }
+ if setPaths, err := m.Settings.SetFromFlags(flags, flagsplugin.Prefix("settings", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, setPaths...)
+ }
+ }
if val, changed, err := flagsplugin.GetTimestamp(flags, flagsplugin.Prefix("received_at", prefix)); err != nil {
return nil, err
} else if changed {
@@ -263,7 +272,16 @@ func (m *ApplicationUplink) SetFromFlags(flags *pflag.FlagSet, prefix string) (p
paths = append(paths, setPaths...)
}
}
- // FIXME: Skipping NetworkIds because it does not seem to implement AddSetFlags.
+ if changed := flagsplugin.IsAnyPrefixSet(flags, flagsplugin.Prefix("network_ids", prefix)); changed {
+ if m.NetworkIds == nil {
+ m.NetworkIds = &NetworkIdentifiers{}
+ }
+ if setPaths, err := m.NetworkIds.SetFromFlags(flags, flagsplugin.Prefix("network_ids", prefix)); err != nil {
+ return nil, err
+ } else {
+ paths = append(paths, setPaths...)
+ }
+ }
return paths, nil
}
diff --git a/pkg/ttnpb/metadata.pb.go b/pkg/ttnpb/metadata.pb.go
index 9ae514f75a..a3ec06d512 100644
--- a/pkg/ttnpb/metadata.pb.go
+++ b/pkg/ttnpb/metadata.pb.go
@@ -126,6 +126,7 @@ type RxMetadata struct {
GatewayIds *GatewayIdentifiers `protobuf:"bytes,1,opt,name=gateway_ids,json=gatewayIds,proto3" json:"gateway_ids,omitempty"`
PacketBroker *PacketBrokerMetadata `protobuf:"bytes,18,opt,name=packet_broker,json=packetBroker,proto3" json:"packet_broker,omitempty"`
+ Relay *RelayMetadata `protobuf:"bytes,23,opt,name=relay,proto3" json:"relay,omitempty"`
AntennaIndex uint32 `protobuf:"varint,2,opt,name=antenna_index,json=antennaIndex,proto3" json:"antenna_index,omitempty"`
// Timestamp at the end of the transmission, provided by the gateway. The accuracy is undefined.
Time *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=time,proto3" json:"time,omitempty"`
@@ -218,6 +219,13 @@ func (x *RxMetadata) GetPacketBroker() *PacketBrokerMetadata {
return nil
}
+func (x *RxMetadata) GetRelay() *RelayMetadata {
+ if x != nil {
+ return x.Relay
+ }
+ return nil
+}
+
func (x *RxMetadata) GetAntennaIndex() uint32 {
if x != nil {
return x.AntennaIndex
@@ -663,6 +671,63 @@ func (x *PacketBrokerRouteHop) GetReceiverAgent() string {
return ""
}
+type RelayMetadata struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // End device identifiers of the relay.
+ DeviceId string `protobuf:"bytes,1,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"`
+ // Wake on radio channel.
+ WorChannel RelayWORChannel `protobuf:"varint,2,opt,name=wor_channel,json=worChannel,proto3,enum=ttn.lorawan.v3.RelayWORChannel" json:"wor_channel,omitempty"`
+}
+
+func (x *RelayMetadata) Reset() {
+ *x = RelayMetadata{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_ttn_lorawan_v3_metadata_proto_msgTypes[4]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *RelayMetadata) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RelayMetadata) ProtoMessage() {}
+
+func (x *RelayMetadata) ProtoReflect() protoreflect.Message {
+ mi := &file_ttn_lorawan_v3_metadata_proto_msgTypes[4]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use RelayMetadata.ProtoReflect.Descriptor instead.
+func (*RelayMetadata) Descriptor() ([]byte, []int) {
+ return file_ttn_lorawan_v3_metadata_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *RelayMetadata) GetDeviceId() string {
+ if x != nil {
+ return x.DeviceId
+ }
+ return ""
+}
+
+func (x *RelayMetadata) GetWorChannel() RelayWORChannel {
+ if x != nil {
+ return x.WorChannel
+ }
+ return RelayWORChannel_RELAY_WOR_CHANNEL_DEFAULT
+}
+
var File_ttn_lorawan_v3_metadata_proto protoreflect.FileDescriptor
var file_ttn_lorawan_v3_metadata_proto_rawDesc = []byte{
@@ -686,201 +751,216 @@ var file_ttn_lorawan_v3_metadata_proto_rawDesc = []byte{
0x2f, 0x76, 0x33, 0x2f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a,
0x20, 0x74, 0x74, 0x6e, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2f, 0x76, 0x33, 0x2f,
0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74,
- 0x6f, 0x1a, 0x17, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, 0x6c, 0x69,
- 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x95, 0x09, 0x0a, 0x0a, 0x52,
- 0x78, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x4d, 0x0a, 0x0b, 0x67, 0x61, 0x74,
- 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22,
- 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
- 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65,
- 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x67, 0x61,
- 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x73, 0x12, 0x49, 0x0a, 0x0d, 0x70, 0x61, 0x63, 0x6b,
- 0x65, 0x74, 0x5f, 0x62, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32,
- 0x24, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
- 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x4d, 0x65, 0x74,
- 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x0c, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x42, 0x72, 0x6f,
- 0x6b, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x6e, 0x74, 0x65, 0x6e, 0x6e, 0x61, 0x5f, 0x69,
- 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x61, 0x6e, 0x74, 0x65,
- 0x6e, 0x6e, 0x61, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65,
- 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
- 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65,
- 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x74, 0x69, 0x6d,
- 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x25, 0x0a, 0x0e, 0x66, 0x69, 0x6e, 0x65, 0x5f, 0x74,
- 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d,
- 0x66, 0x69, 0x6e, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x38, 0x0a,
- 0x18, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x66, 0x69, 0x6e, 0x65, 0x5f,
- 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52,
- 0x16, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x46, 0x69, 0x6e, 0x65, 0x54, 0x69,
- 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x44, 0x0a, 0x1f, 0x65, 0x6e, 0x63, 0x72, 0x79,
- 0x70, 0x74, 0x65, 0x64, 0x5f, 0x66, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74,
- 0x61, 0x6d, 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09,
- 0x52, 0x1b, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x46, 0x69, 0x6e, 0x65, 0x54,
- 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x12, 0x0a,
- 0x04, 0x72, 0x73, 0x73, 0x69, 0x18, 0x08, 0x20, 0x01, 0x28, 0x02, 0x52, 0x04, 0x72, 0x73, 0x73,
- 0x69, 0x12, 0x3c, 0x0a, 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x5f, 0x72, 0x73, 0x73, 0x69,
- 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x56, 0x61,
- 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x52, 0x73, 0x73, 0x69, 0x12,
- 0x21, 0x0a, 0x0c, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x72, 0x73, 0x73, 0x69, 0x18,
- 0x09, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0b, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x73,
- 0x73, 0x69, 0x12, 0x36, 0x0a, 0x17, 0x72, 0x73, 0x73, 0x69, 0x5f, 0x73, 0x74, 0x61, 0x6e, 0x64,
- 0x61, 0x72, 0x64, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20,
- 0x01, 0x28, 0x02, 0x52, 0x15, 0x72, 0x73, 0x73, 0x69, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72,
- 0x64, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x6e,
- 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x02, 0x52, 0x03, 0x73, 0x6e, 0x72, 0x12, 0x29, 0x0a, 0x10,
- 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74,
- 0x18, 0x0c, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63,
- 0x79, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x34, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74,
- 0x69, 0x6f, 0x6e, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
- 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74,
- 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x6a, 0x0a,
- 0x18, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x63,
- 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0e, 0x32,
- 0x26, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
- 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x50, 0x61, 0x74, 0x68, 0x43, 0x6f, 0x6e,
- 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10,
- 0x01, 0x52, 0x16, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x50, 0x61, 0x74, 0x68, 0x43,
- 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x75, 0x70, 0x6c,
- 0x69, 0x6e, 0x6b, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0c, 0x52,
- 0x0b, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x2d, 0x0a, 0x0d,
- 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x11, 0x20,
- 0x01, 0x28, 0x0d, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x2a, 0x03, 0x18, 0xff, 0x01, 0x52, 0x0c, 0x63,
- 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x23, 0x0a, 0x0d, 0x68,
- 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x77, 0x69, 0x64, 0x74, 0x68, 0x18, 0x13, 0x20, 0x01,
- 0x28, 0x0d, 0x52, 0x0c, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x57, 0x69, 0x64, 0x74, 0x68,
- 0x12, 0x27, 0x0a, 0x0f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x64, 0x72,
- 0x69, 0x66, 0x74, 0x18, 0x14, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x66, 0x72, 0x65, 0x71, 0x75,
- 0x65, 0x6e, 0x63, 0x79, 0x44, 0x72, 0x69, 0x66, 0x74, 0x12, 0x35, 0x0a, 0x08, 0x67, 0x70, 0x73,
- 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f,
- 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69,
- 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x07, 0x67, 0x70, 0x73, 0x54, 0x69, 0x6d, 0x65,
- 0x12, 0x3b, 0x0a, 0x0b, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18,
- 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
- 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
- 0x70, 0x52, 0x0a, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x41, 0x74, 0x12, 0x33, 0x0a,
- 0x08, 0x61, 0x64, 0x76, 0x61, 0x6e, 0x63, 0x65, 0x64, 0x18, 0x63, 0x20, 0x01, 0x28, 0x0b, 0x32,
- 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
- 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x08, 0x61, 0x64, 0x76, 0x61, 0x6e, 0x63,
- 0x65, 0x64, 0x22, 0x80, 0x02, 0x0a, 0x08, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12,
- 0x33, 0x0a, 0x08, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
- 0x01, 0x42, 0x17, 0xfa, 0x42, 0x14, 0x12, 0x12, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x56,
- 0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x56, 0xc0, 0x52, 0x08, 0x6c, 0x61, 0x74, 0x69,
- 0x74, 0x75, 0x64, 0x65, 0x12, 0x35, 0x0a, 0x09, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64,
- 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x42, 0x17, 0xfa, 0x42, 0x14, 0x12, 0x12, 0x19, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x80, 0x66, 0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x66, 0xc0,
- 0x52, 0x09, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x61,
- 0x6c, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x61,
- 0x6c, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x63, 0x63, 0x75, 0x72,
- 0x61, 0x63, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x61, 0x63, 0x63, 0x75, 0x72,
- 0x61, 0x63, 0x79, 0x12, 0x46, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x05, 0x20,
- 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
- 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x6f, 0x75,
- 0x72, 0x63, 0x65, 0x42, 0x0e, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0xf2, 0xaa, 0x19,
- 0x02, 0x10, 0x00, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3a, 0x08, 0xf2, 0xaa, 0x19,
- 0x04, 0x08, 0x01, 0x10, 0x01, 0x22, 0xae, 0x08, 0x0a, 0x14, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74,
- 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1d,
- 0x0a, 0x0a, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x09, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x64, 0x12, 0xd5, 0x01,
- 0x0a, 0x10, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x6e, 0x65, 0x74, 0x5f,
- 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0xaa, 0x01, 0x92, 0x41, 0x17, 0x4a, 0x08,
- 0x22, 0x30, 0x30, 0x30, 0x30, 0x31, 0x33, 0x22, 0x9a, 0x02, 0x01, 0x07, 0xa2, 0x02, 0x06, 0x73,
- 0x74, 0x72, 0x69, 0x6e, 0x67, 0xfa, 0x42, 0x06, 0x7a, 0x04, 0x68, 0x03, 0x70, 0x01, 0xea, 0xaa,
- 0x19, 0x82, 0x01, 0x0a, 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67,
- 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
- 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74,
- 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x48, 0x45, 0x58, 0x42,
- 0x79, 0x74, 0x65, 0x73, 0x12, 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e,
- 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77,
- 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f,
- 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x55, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x33,
- 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x0e, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72,
- 0x4e, 0x65, 0x74, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x13, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64,
- 0x65, 0x72, 0x5f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x11, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x54, 0x65, 0x6e,
- 0x61, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x14, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64,
- 0x65, 0x72, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x12, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x43, 0x6c,
- 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x12, 0xe9, 0x01, 0x0a, 0x15, 0x66, 0x6f, 0x72, 0x77,
- 0x61, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x65, 0x75,
- 0x69, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x42, 0xb4, 0x01, 0x92, 0x41, 0x21, 0x4a, 0x12, 0x22,
- 0x37, 0x30, 0x42, 0x33, 0x44, 0x35, 0x37, 0x45, 0x44, 0x30, 0x30, 0x30, 0x41, 0x42, 0x43, 0x44,
- 0x22, 0x9a, 0x02, 0x01, 0x07, 0xa2, 0x02, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0xfa, 0x42,
- 0x06, 0x7a, 0x04, 0x68, 0x08, 0x70, 0x01, 0xea, 0xaa, 0x19, 0x82, 0x01, 0x0a, 0x3f, 0x67, 0x6f,
- 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f,
- 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b,
- 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4d, 0x61,
- 0x72, 0x73, 0x68, 0x61, 0x6c, 0x48, 0x45, 0x58, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x3f, 0x67,
- 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77,
- 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63,
- 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x55,
- 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x38, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x13,
- 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
- 0x45, 0x75, 0x69, 0x12, 0x4e, 0x0a, 0x14, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72,
- 0x5f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28,
- 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
- 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52,
- 0x12, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61,
- 0x79, 0x49, 0x64, 0x12, 0xda, 0x01, 0x0a, 0x13, 0x68, 0x6f, 0x6d, 0x65, 0x5f, 0x6e, 0x65, 0x74,
- 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28,
- 0x0c, 0x42, 0xaa, 0x01, 0x92, 0x41, 0x17, 0x4a, 0x08, 0x22, 0x30, 0x30, 0x30, 0x30, 0x31, 0x33,
- 0x22, 0x9a, 0x02, 0x01, 0x07, 0xa2, 0x02, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0xfa, 0x42,
- 0x06, 0x7a, 0x04, 0x68, 0x03, 0x70, 0x01, 0xea, 0xaa, 0x19, 0x82, 0x01, 0x0a, 0x3f, 0x67, 0x6f,
- 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f,
- 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b,
- 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4d, 0x61,
- 0x72, 0x73, 0x68, 0x61, 0x6c, 0x48, 0x45, 0x58, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x3f, 0x67,
- 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77,
- 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63,
- 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x55,
- 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x33, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x10,
- 0x68, 0x6f, 0x6d, 0x65, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x4e, 0x65, 0x74, 0x49, 0x64,
- 0x12, 0x33, 0x0a, 0x16, 0x68, 0x6f, 0x6d, 0x65, 0x5f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
- 0x5f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09,
- 0x52, 0x13, 0x68, 0x6f, 0x6d, 0x65, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x54, 0x65, 0x6e,
- 0x61, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x35, 0x0a, 0x17, 0x68, 0x6f, 0x6d, 0x65, 0x5f, 0x6e, 0x65,
- 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x64,
- 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x68, 0x6f, 0x6d, 0x65, 0x4e, 0x65, 0x74, 0x77,
- 0x6f, 0x72, 0x6b, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x04,
- 0x68, 0x6f, 0x70, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x74, 0x74, 0x6e,
- 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x50, 0x61, 0x63, 0x6b,
- 0x65, 0x74, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x48, 0x6f, 0x70,
- 0x52, 0x04, 0x68, 0x6f, 0x70, 0x73, 0x22, 0xe7, 0x01, 0x0a, 0x14, 0x50, 0x61, 0x63, 0x6b, 0x65,
- 0x74, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x48, 0x6f, 0x70, 0x12,
- 0x3b, 0x0a, 0x0b, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x01,
- 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
- 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
- 0x52, 0x0a, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1f, 0x0a, 0x0b,
- 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x0a, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a,
- 0x0e, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18,
- 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x41, 0x64, 0x64,
- 0x72, 0x65, 0x73, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72,
- 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x63,
- 0x65, 0x69, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x63,
- 0x65, 0x69, 0x76, 0x65, 0x72, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x0d, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74,
- 0x2a, 0x9b, 0x02, 0x0a, 0x0e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x6f, 0x75,
- 0x72, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x55, 0x4e,
- 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x53, 0x4f, 0x55, 0x52, 0x43,
- 0x45, 0x5f, 0x47, 0x50, 0x53, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x4f, 0x55, 0x52, 0x43,
- 0x45, 0x5f, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x52, 0x59, 0x10, 0x03, 0x12, 0x19, 0x0a, 0x15,
- 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x49, 0x50, 0x5f, 0x47, 0x45, 0x4f, 0x4c, 0x4f, 0x43,
- 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x04, 0x12, 0x20, 0x0a, 0x1c, 0x53, 0x4f, 0x55, 0x52, 0x43,
- 0x45, 0x5f, 0x57, 0x49, 0x46, 0x49, 0x5f, 0x52, 0x53, 0x53, 0x49, 0x5f, 0x47, 0x45, 0x4f, 0x4c,
- 0x4f, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x53, 0x4f, 0x55,
- 0x52, 0x43, 0x45, 0x5f, 0x42, 0x54, 0x5f, 0x52, 0x53, 0x53, 0x49, 0x5f, 0x47, 0x45, 0x4f, 0x4c,
- 0x4f, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x06, 0x12, 0x20, 0x0a, 0x1c, 0x53, 0x4f, 0x55,
- 0x52, 0x43, 0x45, 0x5f, 0x4c, 0x4f, 0x52, 0x41, 0x5f, 0x52, 0x53, 0x53, 0x49, 0x5f, 0x47, 0x45,
- 0x4f, 0x4c, 0x4f, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x07, 0x12, 0x20, 0x0a, 0x1c, 0x53,
- 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4c, 0x4f, 0x52, 0x41, 0x5f, 0x54, 0x44, 0x4f, 0x41, 0x5f,
- 0x47, 0x45, 0x4f, 0x4c, 0x4f, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x08, 0x12, 0x1f, 0x0a,
- 0x1b, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x42, 0x49, 0x4e, 0x45, 0x44,
- 0x5f, 0x47, 0x45, 0x4f, 0x4c, 0x4f, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x09, 0x1a, 0x0e,
- 0xea, 0xaa, 0x19, 0x0a, 0x18, 0x01, 0x2a, 0x06, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x42, 0x31,
- 0x5a, 0x2f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e,
+ 0x6f, 0x1a, 0x1c, 0x74, 0x74, 0x6e, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2f, 0x76,
+ 0x33, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a,
+ 0x17, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61,
+ 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xca, 0x09, 0x0a, 0x0a, 0x52, 0x78, 0x4d,
+ 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x4d, 0x0a, 0x0b, 0x67, 0x61, 0x74, 0x65, 0x77,
+ 0x61, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74,
+ 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x47, 0x61,
+ 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73,
+ 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x67, 0x61, 0x74, 0x65,
+ 0x77, 0x61, 0x79, 0x49, 0x64, 0x73, 0x12, 0x49, 0x0a, 0x0d, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74,
+ 0x5f, 0x62, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e,
+ 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x50,
+ 0x61, 0x63, 0x6b, 0x65, 0x74, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64,
+ 0x61, 0x74, 0x61, 0x52, 0x0c, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x42, 0x72, 0x6f, 0x6b, 0x65,
+ 0x72, 0x12, 0x33, 0x0a, 0x05, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
+ 0x33, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52,
+ 0x05, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x6e, 0x74, 0x65, 0x6e, 0x6e,
+ 0x61, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x61,
+ 0x6e, 0x74, 0x65, 0x6e, 0x6e, 0x61, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x2e, 0x0a, 0x04, 0x74,
+ 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
+ 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65,
+ 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74,
+ 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09,
+ 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x25, 0x0a, 0x0e, 0x66, 0x69, 0x6e,
+ 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28,
+ 0x04, 0x52, 0x0d, 0x66, 0x69, 0x6e, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
+ 0x12, 0x38, 0x0a, 0x18, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x66, 0x69,
+ 0x6e, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x06, 0x20, 0x01,
+ 0x28, 0x0c, 0x52, 0x16, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x46, 0x69, 0x6e,
+ 0x65, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x44, 0x0a, 0x1f, 0x65, 0x6e,
+ 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x66, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x69, 0x6d,
+ 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x1b, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x46, 0x69,
+ 0x6e, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4b, 0x65, 0x79, 0x49, 0x64,
+ 0x12, 0x12, 0x0a, 0x04, 0x72, 0x73, 0x73, 0x69, 0x18, 0x08, 0x20, 0x01, 0x28, 0x02, 0x52, 0x04,
+ 0x72, 0x73, 0x73, 0x69, 0x12, 0x3c, 0x0a, 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x5f, 0x72,
+ 0x73, 0x73, 0x69, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
+ 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x6c, 0x6f, 0x61,
+ 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x52, 0x73,
+ 0x73, 0x69, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x72, 0x73,
+ 0x73, 0x69, 0x18, 0x09, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0b, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65,
+ 0x6c, 0x52, 0x73, 0x73, 0x69, 0x12, 0x36, 0x0a, 0x17, 0x72, 0x73, 0x73, 0x69, 0x5f, 0x73, 0x74,
+ 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+ 0x18, 0x0a, 0x20, 0x01, 0x28, 0x02, 0x52, 0x15, 0x72, 0x73, 0x73, 0x69, 0x53, 0x74, 0x61, 0x6e,
+ 0x64, 0x61, 0x72, 0x64, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a,
+ 0x03, 0x73, 0x6e, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x02, 0x52, 0x03, 0x73, 0x6e, 0x72, 0x12,
+ 0x29, 0x0a, 0x10, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x6f, 0x66, 0x66,
+ 0x73, 0x65, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x66, 0x72, 0x65, 0x71, 0x75,
+ 0x65, 0x6e, 0x63, 0x79, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x34, 0x0a, 0x08, 0x6c, 0x6f,
+ 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74,
+ 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x6f,
+ 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+ 0x12, 0x6a, 0x0a, 0x18, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x70, 0x61, 0x74,
+ 0x68, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x18, 0x0e, 0x20, 0x01,
+ 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
+ 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x50, 0x61, 0x74, 0x68,
+ 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82,
+ 0x01, 0x02, 0x10, 0x01, 0x52, 0x16, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x50, 0x61,
+ 0x74, 0x68, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x0c,
+ 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x0f, 0x20, 0x01,
+ 0x28, 0x0c, 0x52, 0x0b, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12,
+ 0x2d, 0x0a, 0x0d, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78,
+ 0x18, 0x11, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x2a, 0x03, 0x18, 0xff, 0x01,
+ 0x52, 0x0c, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x23,
+ 0x0a, 0x0d, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x77, 0x69, 0x64, 0x74, 0x68, 0x18,
+ 0x13, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x57, 0x69,
+ 0x64, 0x74, 0x68, 0x12, 0x27, 0x0a, 0x0f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79,
+ 0x5f, 0x64, 0x72, 0x69, 0x66, 0x74, 0x18, 0x14, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x66, 0x72,
+ 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x44, 0x72, 0x69, 0x66, 0x74, 0x12, 0x35, 0x0a, 0x08,
+ 0x67, 0x70, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a,
+ 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
+ 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x07, 0x67, 0x70, 0x73, 0x54,
+ 0x69, 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x0b, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x5f,
+ 0x61, 0x74, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
+ 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73,
+ 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x41, 0x74,
+ 0x12, 0x33, 0x0a, 0x08, 0x61, 0x64, 0x76, 0x61, 0x6e, 0x63, 0x65, 0x64, 0x18, 0x63, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x08, 0x61, 0x64, 0x76,
+ 0x61, 0x6e, 0x63, 0x65, 0x64, 0x22, 0x80, 0x02, 0x0a, 0x08, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69,
+ 0x6f, 0x6e, 0x12, 0x33, 0x0a, 0x08, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x01, 0x42, 0x17, 0xfa, 0x42, 0x14, 0x12, 0x12, 0x19, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x56, 0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x56, 0xc0, 0x52, 0x08, 0x6c,
+ 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x12, 0x35, 0x0a, 0x09, 0x6c, 0x6f, 0x6e, 0x67, 0x69,
+ 0x74, 0x75, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x42, 0x17, 0xfa, 0x42, 0x14, 0x12,
+ 0x12, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x66, 0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x66, 0xc0, 0x52, 0x09, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x12, 0x1a,
+ 0x0a, 0x08, 0x61, 0x6c, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05,
+ 0x52, 0x08, 0x61, 0x6c, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x63,
+ 0x63, 0x75, 0x72, 0x61, 0x63, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x61, 0x63,
+ 0x63, 0x75, 0x72, 0x61, 0x63, 0x79, 0x12, 0x46, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
+ 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
+ 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+ 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x42, 0x0e, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01,
+ 0xf2, 0xaa, 0x19, 0x02, 0x10, 0x00, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3a, 0x08,
+ 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x22, 0xae, 0x08, 0x0a, 0x14, 0x50, 0x61, 0x63,
+ 0x6b, 0x65, 0x74, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
+ 0x61, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x64,
+ 0x12, 0xd5, 0x01, 0x0a, 0x10, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x6e,
+ 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0xaa, 0x01, 0x92, 0x41,
+ 0x17, 0x4a, 0x08, 0x22, 0x30, 0x30, 0x30, 0x30, 0x31, 0x33, 0x22, 0x9a, 0x02, 0x01, 0x07, 0xa2,
+ 0x02, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0xfa, 0x42, 0x06, 0x7a, 0x04, 0x68, 0x03, 0x70,
+ 0x01, 0xea, 0xaa, 0x19, 0x82, 0x01, 0x0a, 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68,
+ 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72,
+ 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b,
+ 0x67, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x48,
+ 0x45, 0x58, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74,
+ 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f,
+ 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70,
+ 0x6b, 0x67, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x55, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68,
+ 0x61, 0x6c, 0x33, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x0e, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72,
+ 0x64, 0x65, 0x72, 0x4e, 0x65, 0x74, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x13, 0x66, 0x6f, 0x72, 0x77,
+ 0x61, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18,
+ 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72,
+ 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x14, 0x66, 0x6f, 0x72, 0x77,
+ 0x61, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x64,
+ 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65,
+ 0x72, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x12, 0xe9, 0x01, 0x0a, 0x15, 0x66,
+ 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
+ 0x5f, 0x65, 0x75, 0x69, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x42, 0xb4, 0x01, 0x92, 0x41, 0x21,
+ 0x4a, 0x12, 0x22, 0x37, 0x30, 0x42, 0x33, 0x44, 0x35, 0x37, 0x45, 0x44, 0x30, 0x30, 0x30, 0x41,
+ 0x42, 0x43, 0x44, 0x22, 0x9a, 0x02, 0x01, 0x07, 0xa2, 0x02, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e,
+ 0x67, 0xfa, 0x42, 0x06, 0x7a, 0x04, 0x68, 0x08, 0x70, 0x01, 0xea, 0xaa, 0x19, 0x82, 0x01, 0x0a,
+ 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65,
+ 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74,
+ 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73,
+ 0x2e, 0x4d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x48, 0x45, 0x58, 0x42, 0x79, 0x74, 0x65, 0x73,
+ 0x12, 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e,
0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73,
- 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74, 0x6e, 0x70,
- 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+ 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x79, 0x70, 0x65,
+ 0x73, 0x2e, 0x55, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x38, 0x42, 0x79, 0x74, 0x65,
+ 0x73, 0x52, 0x13, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x47, 0x61, 0x74, 0x65,
+ 0x77, 0x61, 0x79, 0x45, 0x75, 0x69, 0x12, 0x4e, 0x0a, 0x14, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72,
+ 0x64, 0x65, 0x72, 0x5f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x0a,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c,
+ 0x75, 0x65, 0x52, 0x12, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x47, 0x61, 0x74,
+ 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x12, 0xda, 0x01, 0x0a, 0x13, 0x68, 0x6f, 0x6d, 0x65, 0x5f,
+ 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x05,
+ 0x20, 0x01, 0x28, 0x0c, 0x42, 0xaa, 0x01, 0x92, 0x41, 0x17, 0x4a, 0x08, 0x22, 0x30, 0x30, 0x30,
+ 0x30, 0x31, 0x33, 0x22, 0x9a, 0x02, 0x01, 0x07, 0xa2, 0x02, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e,
+ 0x67, 0xfa, 0x42, 0x06, 0x7a, 0x04, 0x68, 0x03, 0x70, 0x01, 0xea, 0xaa, 0x19, 0x82, 0x01, 0x0a,
+ 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65,
+ 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74,
+ 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73,
+ 0x2e, 0x4d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x48, 0x45, 0x58, 0x42, 0x79, 0x74, 0x65, 0x73,
+ 0x12, 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e,
+ 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73,
+ 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x79, 0x70, 0x65,
+ 0x73, 0x2e, 0x55, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x33, 0x42, 0x79, 0x74, 0x65,
+ 0x73, 0x52, 0x10, 0x68, 0x6f, 0x6d, 0x65, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x4e, 0x65,
+ 0x74, 0x49, 0x64, 0x12, 0x33, 0x0a, 0x16, 0x68, 0x6f, 0x6d, 0x65, 0x5f, 0x6e, 0x65, 0x74, 0x77,
+ 0x6f, 0x72, 0x6b, 0x5f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x13, 0x68, 0x6f, 0x6d, 0x65, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
+ 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x35, 0x0a, 0x17, 0x68, 0x6f, 0x6d, 0x65,
+ 0x5f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72,
+ 0x5f, 0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x68, 0x6f, 0x6d, 0x65, 0x4e,
+ 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x12,
+ 0x38, 0x0a, 0x04, 0x68, 0x6f, 0x70, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e,
+ 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x50,
+ 0x61, 0x63, 0x6b, 0x65, 0x74, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x52, 0x6f, 0x75, 0x74, 0x65,
+ 0x48, 0x6f, 0x70, 0x52, 0x04, 0x68, 0x6f, 0x70, 0x73, 0x22, 0xe7, 0x01, 0x0a, 0x14, 0x50, 0x61,
+ 0x63, 0x6b, 0x65, 0x74, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x48,
+ 0x6f, 0x70, 0x12, 0x3b, 0x0a, 0x0b, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x5f, 0x61,
+ 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+ 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
+ 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x41, 0x74, 0x12,
+ 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65,
+ 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65,
+ 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72,
+ 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x63, 0x65, 0x69,
+ 0x76, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c,
+ 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e,
+ 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x18, 0x05,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x41, 0x67,
+ 0x65, 0x6e, 0x74, 0x22, 0xa1, 0x01, 0x0a, 0x0d, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x4d, 0x65, 0x74,
+ 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x44, 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f,
+ 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x27, 0xfa, 0x42, 0x24, 0x72, 0x22, 0x18,
+ 0x24, 0x32, 0x1e, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x3f, 0x3a, 0x5b,
+ 0x2d, 0x5d, 0x3f, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x7b, 0x32, 0x2c, 0x7d,
+ 0x24, 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x4a, 0x0a, 0x0b, 0x77,
+ 0x6f, 0x72, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e,
+ 0x32, 0x1f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
+ 0x33, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x57, 0x4f, 0x52, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65,
+ 0x6c, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x77, 0x6f, 0x72,
+ 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x2a, 0x9b, 0x02, 0x0a, 0x0e, 0x4c, 0x6f, 0x63, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x4f,
+ 0x55, 0x52, 0x43, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0e,
+ 0x0a, 0x0a, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x47, 0x50, 0x53, 0x10, 0x01, 0x12, 0x13,
+ 0x0a, 0x0f, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x52,
+ 0x59, 0x10, 0x03, 0x12, 0x19, 0x0a, 0x15, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x49, 0x50,
+ 0x5f, 0x47, 0x45, 0x4f, 0x4c, 0x4f, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x04, 0x12, 0x20,
+ 0x0a, 0x1c, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x57, 0x49, 0x46, 0x49, 0x5f, 0x52, 0x53,
+ 0x53, 0x49, 0x5f, 0x47, 0x45, 0x4f, 0x4c, 0x4f, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x05,
+ 0x12, 0x1e, 0x0a, 0x1a, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x42, 0x54, 0x5f, 0x52, 0x53,
+ 0x53, 0x49, 0x5f, 0x47, 0x45, 0x4f, 0x4c, 0x4f, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x06,
+ 0x12, 0x20, 0x0a, 0x1c, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4c, 0x4f, 0x52, 0x41, 0x5f,
+ 0x52, 0x53, 0x53, 0x49, 0x5f, 0x47, 0x45, 0x4f, 0x4c, 0x4f, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e,
+ 0x10, 0x07, 0x12, 0x20, 0x0a, 0x1c, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x4c, 0x4f, 0x52,
+ 0x41, 0x5f, 0x54, 0x44, 0x4f, 0x41, 0x5f, 0x47, 0x45, 0x4f, 0x4c, 0x4f, 0x43, 0x41, 0x54, 0x49,
+ 0x4f, 0x4e, 0x10, 0x08, 0x12, 0x1f, 0x0a, 0x1b, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x43,
+ 0x4f, 0x4d, 0x42, 0x49, 0x4e, 0x45, 0x44, 0x5f, 0x47, 0x45, 0x4f, 0x4c, 0x4f, 0x43, 0x41, 0x54,
+ 0x49, 0x4f, 0x4e, 0x10, 0x09, 0x1a, 0x0e, 0xea, 0xaa, 0x19, 0x0a, 0x18, 0x01, 0x2a, 0x06, 0x53,
+ 0x4f, 0x55, 0x52, 0x43, 0x45, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74,
+ 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f,
+ 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70,
+ 0x6b, 0x67, 0x2f, 0x74, 0x74, 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -896,39 +976,43 @@ func file_ttn_lorawan_v3_metadata_proto_rawDescGZIP() []byte {
}
var file_ttn_lorawan_v3_metadata_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
-var file_ttn_lorawan_v3_metadata_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
+var file_ttn_lorawan_v3_metadata_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
var file_ttn_lorawan_v3_metadata_proto_goTypes = []interface{}{
(LocationSource)(0), // 0: ttn.lorawan.v3.LocationSource
(*RxMetadata)(nil), // 1: ttn.lorawan.v3.RxMetadata
(*Location)(nil), // 2: ttn.lorawan.v3.Location
(*PacketBrokerMetadata)(nil), // 3: ttn.lorawan.v3.PacketBrokerMetadata
(*PacketBrokerRouteHop)(nil), // 4: ttn.lorawan.v3.PacketBrokerRouteHop
- (*GatewayIdentifiers)(nil), // 5: ttn.lorawan.v3.GatewayIdentifiers
- (*timestamppb.Timestamp)(nil), // 6: google.protobuf.Timestamp
- (*wrapperspb.FloatValue)(nil), // 7: google.protobuf.FloatValue
- (DownlinkPathConstraint)(0), // 8: ttn.lorawan.v3.DownlinkPathConstraint
- (*structpb.Struct)(nil), // 9: google.protobuf.Struct
- (*wrapperspb.StringValue)(nil), // 10: google.protobuf.StringValue
+ (*RelayMetadata)(nil), // 5: ttn.lorawan.v3.RelayMetadata
+ (*GatewayIdentifiers)(nil), // 6: ttn.lorawan.v3.GatewayIdentifiers
+ (*timestamppb.Timestamp)(nil), // 7: google.protobuf.Timestamp
+ (*wrapperspb.FloatValue)(nil), // 8: google.protobuf.FloatValue
+ (DownlinkPathConstraint)(0), // 9: ttn.lorawan.v3.DownlinkPathConstraint
+ (*structpb.Struct)(nil), // 10: google.protobuf.Struct
+ (*wrapperspb.StringValue)(nil), // 11: google.protobuf.StringValue
+ (RelayWORChannel)(0), // 12: ttn.lorawan.v3.RelayWORChannel
}
var file_ttn_lorawan_v3_metadata_proto_depIdxs = []int32{
- 5, // 0: ttn.lorawan.v3.RxMetadata.gateway_ids:type_name -> ttn.lorawan.v3.GatewayIdentifiers
+ 6, // 0: ttn.lorawan.v3.RxMetadata.gateway_ids:type_name -> ttn.lorawan.v3.GatewayIdentifiers
3, // 1: ttn.lorawan.v3.RxMetadata.packet_broker:type_name -> ttn.lorawan.v3.PacketBrokerMetadata
- 6, // 2: ttn.lorawan.v3.RxMetadata.time:type_name -> google.protobuf.Timestamp
- 7, // 3: ttn.lorawan.v3.RxMetadata.signal_rssi:type_name -> google.protobuf.FloatValue
- 2, // 4: ttn.lorawan.v3.RxMetadata.location:type_name -> ttn.lorawan.v3.Location
- 8, // 5: ttn.lorawan.v3.RxMetadata.downlink_path_constraint:type_name -> ttn.lorawan.v3.DownlinkPathConstraint
- 6, // 6: ttn.lorawan.v3.RxMetadata.gps_time:type_name -> google.protobuf.Timestamp
- 6, // 7: ttn.lorawan.v3.RxMetadata.received_at:type_name -> google.protobuf.Timestamp
- 9, // 8: ttn.lorawan.v3.RxMetadata.advanced:type_name -> google.protobuf.Struct
- 0, // 9: ttn.lorawan.v3.Location.source:type_name -> ttn.lorawan.v3.LocationSource
- 10, // 10: ttn.lorawan.v3.PacketBrokerMetadata.forwarder_gateway_id:type_name -> google.protobuf.StringValue
- 4, // 11: ttn.lorawan.v3.PacketBrokerMetadata.hops:type_name -> ttn.lorawan.v3.PacketBrokerRouteHop
- 6, // 12: ttn.lorawan.v3.PacketBrokerRouteHop.received_at:type_name -> google.protobuf.Timestamp
- 13, // [13:13] is the sub-list for method output_type
- 13, // [13:13] is the sub-list for method input_type
- 13, // [13:13] is the sub-list for extension type_name
- 13, // [13:13] is the sub-list for extension extendee
- 0, // [0:13] is the sub-list for field type_name
+ 5, // 2: ttn.lorawan.v3.RxMetadata.relay:type_name -> ttn.lorawan.v3.RelayMetadata
+ 7, // 3: ttn.lorawan.v3.RxMetadata.time:type_name -> google.protobuf.Timestamp
+ 8, // 4: ttn.lorawan.v3.RxMetadata.signal_rssi:type_name -> google.protobuf.FloatValue
+ 2, // 5: ttn.lorawan.v3.RxMetadata.location:type_name -> ttn.lorawan.v3.Location
+ 9, // 6: ttn.lorawan.v3.RxMetadata.downlink_path_constraint:type_name -> ttn.lorawan.v3.DownlinkPathConstraint
+ 7, // 7: ttn.lorawan.v3.RxMetadata.gps_time:type_name -> google.protobuf.Timestamp
+ 7, // 8: ttn.lorawan.v3.RxMetadata.received_at:type_name -> google.protobuf.Timestamp
+ 10, // 9: ttn.lorawan.v3.RxMetadata.advanced:type_name -> google.protobuf.Struct
+ 0, // 10: ttn.lorawan.v3.Location.source:type_name -> ttn.lorawan.v3.LocationSource
+ 11, // 11: ttn.lorawan.v3.PacketBrokerMetadata.forwarder_gateway_id:type_name -> google.protobuf.StringValue
+ 4, // 12: ttn.lorawan.v3.PacketBrokerMetadata.hops:type_name -> ttn.lorawan.v3.PacketBrokerRouteHop
+ 7, // 13: ttn.lorawan.v3.PacketBrokerRouteHop.received_at:type_name -> google.protobuf.Timestamp
+ 12, // 14: ttn.lorawan.v3.RelayMetadata.wor_channel:type_name -> ttn.lorawan.v3.RelayWORChannel
+ 15, // [15:15] is the sub-list for method output_type
+ 15, // [15:15] is the sub-list for method input_type
+ 15, // [15:15] is the sub-list for extension type_name
+ 15, // [15:15] is the sub-list for extension extendee
+ 0, // [0:15] is the sub-list for field type_name
}
func init() { file_ttn_lorawan_v3_metadata_proto_init() }
@@ -938,6 +1022,7 @@ func file_ttn_lorawan_v3_metadata_proto_init() {
}
file_ttn_lorawan_v3_enums_proto_init()
file_ttn_lorawan_v3_identifiers_proto_init()
+ file_ttn_lorawan_v3_lorawan_proto_init()
if !protoimpl.UnsafeEnabled {
file_ttn_lorawan_v3_metadata_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RxMetadata); i {
@@ -987,6 +1072,18 @@ func file_ttn_lorawan_v3_metadata_proto_init() {
return nil
}
}
+ file_ttn_lorawan_v3_metadata_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*RelayMetadata); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
}
type x struct{}
out := protoimpl.TypeBuilder{
@@ -994,7 +1091,7 @@ func file_ttn_lorawan_v3_metadata_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_ttn_lorawan_v3_metadata_proto_rawDesc,
NumEnums: 1,
- NumMessages: 4,
+ NumMessages: 5,
NumExtensions: 0,
NumServices: 0,
},
diff --git a/pkg/ttnpb/metadata.pb.paths.fm.go b/pkg/ttnpb/metadata.pb.paths.fm.go
index 692280d0c8..878d9d1826 100644
--- a/pkg/ttnpb/metadata.pb.paths.fm.go
+++ b/pkg/ttnpb/metadata.pb.paths.fm.go
@@ -36,6 +36,9 @@ var RxMetadataFieldPathsNested = []string{
"packet_broker.hops",
"packet_broker.message_id",
"received_at",
+ "relay",
+ "relay.device_id",
+ "relay.wor_channel",
"rssi",
"rssi_standard_deviation",
"signal_rssi",
@@ -62,6 +65,7 @@ var RxMetadataFieldPathsTopLevel = []string{
"location",
"packet_broker",
"received_at",
+ "relay",
"rssi",
"rssi_standard_deviation",
"signal_rssi",
@@ -125,3 +129,12 @@ var PacketBrokerRouteHopFieldPathsTopLevel = []string{
"sender_address",
"sender_name",
}
+var RelayMetadataFieldPathsNested = []string{
+ "device_id",
+ "wor_channel",
+}
+
+var RelayMetadataFieldPathsTopLevel = []string{
+ "device_id",
+ "wor_channel",
+}
diff --git a/pkg/ttnpb/metadata.pb.setters.fm.go b/pkg/ttnpb/metadata.pb.setters.fm.go
index 5eac69dbb0..b6e711d744 100644
--- a/pkg/ttnpb/metadata.pb.setters.fm.go
+++ b/pkg/ttnpb/metadata.pb.setters.fm.go
@@ -57,6 +57,31 @@ func (dst *RxMetadata) SetFields(src *RxMetadata, paths ...string) error {
dst.PacketBroker = nil
}
}
+ case "relay":
+ if len(subs) > 0 {
+ var newDst, newSrc *RelayMetadata
+ if (src == nil || src.Relay == nil) && dst.Relay == nil {
+ continue
+ }
+ if src != nil {
+ newSrc = src.Relay
+ }
+ if dst.Relay != nil {
+ newDst = dst.Relay
+ } else {
+ newDst = &RelayMetadata{}
+ dst.Relay = newDst
+ }
+ if err := newDst.SetFields(newSrc, subs...); err != nil {
+ return err
+ }
+ } else {
+ if src != nil {
+ dst.Relay = src.Relay
+ } else {
+ dst.Relay = nil
+ }
+ }
case "antenna_index":
if len(subs) > 0 {
return fmt.Errorf("'antenna_index' has no subfields, but %s were specified", subs)
@@ -507,3 +532,33 @@ func (dst *PacketBrokerRouteHop) SetFields(src *PacketBrokerRouteHop, paths ...s
}
return nil
}
+
+func (dst *RelayMetadata) SetFields(src *RelayMetadata, paths ...string) error {
+ for name, subs := range _processPaths(paths) {
+ switch name {
+ case "device_id":
+ if len(subs) > 0 {
+ return fmt.Errorf("'device_id' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.DeviceId = src.DeviceId
+ } else {
+ var zero string
+ dst.DeviceId = zero
+ }
+ case "wor_channel":
+ if len(subs) > 0 {
+ return fmt.Errorf("'wor_channel' has no subfields, but %s were specified", subs)
+ }
+ if src != nil {
+ dst.WorChannel = src.WorChannel
+ } else {
+ dst.WorChannel = 0
+ }
+
+ default:
+ return fmt.Errorf("invalid field: '%s'", name)
+ }
+ }
+ return nil
+}
diff --git a/pkg/ttnpb/metadata.pb.validate.go b/pkg/ttnpb/metadata.pb.validate.go
index 90a88dd264..852bcc101e 100644
--- a/pkg/ttnpb/metadata.pb.validate.go
+++ b/pkg/ttnpb/metadata.pb.validate.go
@@ -78,6 +78,18 @@ func (m *RxMetadata) ValidateFields(paths ...string) error {
}
}
+ case "relay":
+
+ if v, ok := interface{}(m.GetRelay()).(interface{ ValidateFields(...string) error }); ok {
+ if err := v.ValidateFields(subs...); err != nil {
+ return RxMetadataValidationError{
+ field: "relay",
+ reason: "embedded message failed validation",
+ cause: err,
+ }
+ }
+ }
+
case "antenna_index":
// no validation rules for AntennaIndex
case "time":
@@ -627,3 +639,109 @@ var _ interface {
Cause() error
ErrorName() string
} = PacketBrokerRouteHopValidationError{}
+
+// ValidateFields checks the field values on RelayMetadata with the rules
+// defined in the proto definition for this message. If any rules are
+// violated, an error is returned.
+func (m *RelayMetadata) ValidateFields(paths ...string) error {
+ if m == nil {
+ return nil
+ }
+
+ if len(paths) == 0 {
+ paths = RelayMetadataFieldPathsNested
+ }
+
+ for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
+ _ = subs
+ switch name {
+ case "device_id":
+
+ if utf8.RuneCountInString(m.GetDeviceId()) > 36 {
+ return RelayMetadataValidationError{
+ field: "device_id",
+ reason: "value length must be at most 36 runes",
+ }
+ }
+
+ if !_RelayMetadata_DeviceId_Pattern.MatchString(m.GetDeviceId()) {
+ return RelayMetadataValidationError{
+ field: "device_id",
+ reason: "value does not match regex pattern \"^[a-z0-9](?:[-]?[a-z0-9]){2,}$\"",
+ }
+ }
+
+ case "wor_channel":
+
+ if _, ok := RelayWORChannel_name[int32(m.GetWorChannel())]; !ok {
+ return RelayMetadataValidationError{
+ field: "wor_channel",
+ reason: "value must be one of the defined enum values",
+ }
+ }
+
+ default:
+ return RelayMetadataValidationError{
+ field: name,
+ reason: "invalid field path",
+ }
+ }
+ }
+ return nil
+}
+
+// RelayMetadataValidationError is the validation error returned by
+// RelayMetadata.ValidateFields if the designated constraints aren't met.
+type RelayMetadataValidationError struct {
+ field string
+ reason string
+ cause error
+ key bool
+}
+
+// Field function returns field value.
+func (e RelayMetadataValidationError) Field() string { return e.field }
+
+// Reason function returns reason value.
+func (e RelayMetadataValidationError) Reason() string { return e.reason }
+
+// Cause function returns cause value.
+func (e RelayMetadataValidationError) Cause() error { return e.cause }
+
+// Key function returns key value.
+func (e RelayMetadataValidationError) Key() bool { return e.key }
+
+// ErrorName returns error name.
+func (e RelayMetadataValidationError) ErrorName() string { return "RelayMetadataValidationError" }
+
+// Error satisfies the builtin error interface
+func (e RelayMetadataValidationError) Error() string {
+ cause := ""
+ if e.cause != nil {
+ cause = fmt.Sprintf(" | caused by: %v", e.cause)
+ }
+
+ key := ""
+ if e.key {
+ key = "key for "
+ }
+
+ return fmt.Sprintf(
+ "invalid %sRelayMetadata.%s: %s%s",
+ key,
+ e.field,
+ e.reason,
+ cause)
+}
+
+var _ error = RelayMetadataValidationError{}
+
+var _ interface {
+ Field() string
+ Reason() string
+ Key() bool
+ Cause() error
+ ErrorName() string
+} = RelayMetadataValidationError{}
+
+var _RelayMetadata_DeviceId_Pattern = regexp.MustCompile("^[a-z0-9](?:[-]?[a-z0-9]){2,}$")
diff --git a/pkg/ttnpb/metadata_json.pb.go b/pkg/ttnpb/metadata_json.pb.go
index 08f5421ed0..78fb30da13 100644
--- a/pkg/ttnpb/metadata_json.pb.go
+++ b/pkg/ttnpb/metadata_json.pb.go
@@ -84,6 +84,11 @@ func (x *RxMetadata) MarshalProtoJSON(s *jsonplugin.MarshalState) {
s.WriteObjectField("packet_broker")
x.PacketBroker.MarshalProtoJSON(s.WithField("packet_broker"))
}
+ if x.Relay != nil || s.HasField("relay") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("relay")
+ x.Relay.MarshalProtoJSON(s.WithField("relay"))
+ }
if x.AntennaIndex != 0 || s.HasField("antenna_index") {
s.WriteMoreIf(&wroteField)
s.WriteObjectField("antenna_index")
@@ -240,6 +245,13 @@ func (x *RxMetadata) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
}
x.PacketBroker = &PacketBrokerMetadata{}
x.PacketBroker.UnmarshalProtoJSON(s.WithField("packet_broker", true))
+ case "relay":
+ if s.ReadNil() {
+ x.Relay = nil
+ return
+ }
+ x.Relay = &RelayMetadata{}
+ x.Relay.UnmarshalProtoJSON(s.WithField("relay", true))
case "antenna_index", "antennaIndex":
s.AddField("antenna_index")
x.AntennaIndex = s.ReadUint32()
@@ -571,3 +583,53 @@ func (x *PacketBrokerMetadata) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState)
func (x *PacketBrokerMetadata) UnmarshalJSON(b []byte) error {
return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
}
+
+// MarshalProtoJSON marshals the RelayMetadata message to JSON.
+func (x *RelayMetadata) MarshalProtoJSON(s *jsonplugin.MarshalState) {
+ if x == nil {
+ s.WriteNil()
+ return
+ }
+ s.WriteObjectStart()
+ var wroteField bool
+ if x.DeviceId != "" || s.HasField("device_id") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("device_id")
+ s.WriteString(x.DeviceId)
+ }
+ if x.WorChannel != 0 || s.HasField("wor_channel") {
+ s.WriteMoreIf(&wroteField)
+ s.WriteObjectField("wor_channel")
+ x.WorChannel.MarshalProtoJSON(s)
+ }
+ s.WriteObjectEnd()
+}
+
+// MarshalJSON marshals the RelayMetadata to JSON.
+func (x *RelayMetadata) MarshalJSON() ([]byte, error) {
+ return jsonplugin.DefaultMarshalerConfig.Marshal(x)
+}
+
+// UnmarshalProtoJSON unmarshals the RelayMetadata message from JSON.
+func (x *RelayMetadata) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
+ if s.ReadNil() {
+ return
+ }
+ s.ReadObject(func(key string) {
+ switch key {
+ default:
+ s.ReadAny() // ignore unknown field
+ case "device_id", "deviceId":
+ s.AddField("device_id")
+ x.DeviceId = s.ReadString()
+ case "wor_channel", "worChannel":
+ s.AddField("wor_channel")
+ x.WorChannel.UnmarshalProtoJSON(s)
+ }
+ })
+}
+
+// UnmarshalJSON unmarshals the RelayMetadata from JSON.
+func (x *RelayMetadata) UnmarshalJSON(b []byte) error {
+ return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x)
+}
diff --git a/pkg/ttnpb/qrcodegenerator.pb.paths.fm.go b/pkg/ttnpb/qrcodegenerator.pb.paths.fm.go
index ab09f0addd..52103884db 100644
--- a/pkg/ttnpb/qrcodegenerator.pb.paths.fm.go
+++ b/pkg/ttnpb/qrcodegenerator.pb.paths.fm.go
@@ -110,6 +110,42 @@ var GenerateEndDeviceQRCodeRequestFieldPathsNested = []string{
"end_device.mac_settings.desired_ping_slot_data_rate_index.value",
"end_device.mac_settings.desired_ping_slot_frequency",
"end_device.mac_settings.desired_ping_slot_frequency.value",
+ "end_device.mac_settings.desired_relay",
+ "end_device.mac_settings.desired_relay.mode",
+ "end_device.mac_settings.desired_relay.mode.served",
+ "end_device.mac_settings.desired_relay.mode.served.backoff",
+ "end_device.mac_settings.desired_relay.mode.served.mode",
+ "end_device.mac_settings.desired_relay.mode.served.mode.always",
+ "end_device.mac_settings.desired_relay.mode.served.mode.dynamic",
+ "end_device.mac_settings.desired_relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device.mac_settings.desired_relay.mode.served.mode.end_device_controlled",
+ "end_device.mac_settings.desired_relay.mode.served.second_channel",
+ "end_device.mac_settings.desired_relay.mode.served.second_channel.ack_offset",
+ "end_device.mac_settings.desired_relay.mode.served.second_channel.data_rate_index",
+ "end_device.mac_settings.desired_relay.mode.served.second_channel.frequency",
+ "end_device.mac_settings.desired_relay.mode.served.serving_device_id",
+ "end_device.mac_settings.desired_relay.mode.serving",
+ "end_device.mac_settings.desired_relay.mode.serving.cad_periodicity",
+ "end_device.mac_settings.desired_relay.mode.serving.default_channel_index",
+ "end_device.mac_settings.desired_relay.mode.serving.limits",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.join_requests",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.notifications",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.notifications.bucket_size",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.notifications.reload_rate",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.overall",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.overall.bucket_size",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.overall.reload_rate",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.reset_behavior",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.uplink_messages",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device.mac_settings.desired_relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device.mac_settings.desired_relay.mode.serving.second_channel",
+ "end_device.mac_settings.desired_relay.mode.serving.second_channel.ack_offset",
+ "end_device.mac_settings.desired_relay.mode.serving.second_channel.data_rate_index",
+ "end_device.mac_settings.desired_relay.mode.serving.second_channel.frequency",
+ "end_device.mac_settings.desired_relay.mode.serving.uplink_forwarding_rules",
"end_device.mac_settings.desired_rx1_data_rate_offset",
"end_device.mac_settings.desired_rx1_data_rate_offset.value",
"end_device.mac_settings.desired_rx1_delay",
@@ -129,6 +165,42 @@ var GenerateEndDeviceQRCodeRequestFieldPathsNested = []string{
"end_device.mac_settings.ping_slot_frequency.value",
"end_device.mac_settings.ping_slot_periodicity",
"end_device.mac_settings.ping_slot_periodicity.value",
+ "end_device.mac_settings.relay",
+ "end_device.mac_settings.relay.mode",
+ "end_device.mac_settings.relay.mode.served",
+ "end_device.mac_settings.relay.mode.served.backoff",
+ "end_device.mac_settings.relay.mode.served.mode",
+ "end_device.mac_settings.relay.mode.served.mode.always",
+ "end_device.mac_settings.relay.mode.served.mode.dynamic",
+ "end_device.mac_settings.relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device.mac_settings.relay.mode.served.mode.end_device_controlled",
+ "end_device.mac_settings.relay.mode.served.second_channel",
+ "end_device.mac_settings.relay.mode.served.second_channel.ack_offset",
+ "end_device.mac_settings.relay.mode.served.second_channel.data_rate_index",
+ "end_device.mac_settings.relay.mode.served.second_channel.frequency",
+ "end_device.mac_settings.relay.mode.served.serving_device_id",
+ "end_device.mac_settings.relay.mode.serving",
+ "end_device.mac_settings.relay.mode.serving.cad_periodicity",
+ "end_device.mac_settings.relay.mode.serving.default_channel_index",
+ "end_device.mac_settings.relay.mode.serving.limits",
+ "end_device.mac_settings.relay.mode.serving.limits.join_requests",
+ "end_device.mac_settings.relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device.mac_settings.relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device.mac_settings.relay.mode.serving.limits.notifications",
+ "end_device.mac_settings.relay.mode.serving.limits.notifications.bucket_size",
+ "end_device.mac_settings.relay.mode.serving.limits.notifications.reload_rate",
+ "end_device.mac_settings.relay.mode.serving.limits.overall",
+ "end_device.mac_settings.relay.mode.serving.limits.overall.bucket_size",
+ "end_device.mac_settings.relay.mode.serving.limits.overall.reload_rate",
+ "end_device.mac_settings.relay.mode.serving.limits.reset_behavior",
+ "end_device.mac_settings.relay.mode.serving.limits.uplink_messages",
+ "end_device.mac_settings.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device.mac_settings.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device.mac_settings.relay.mode.serving.second_channel",
+ "end_device.mac_settings.relay.mode.serving.second_channel.ack_offset",
+ "end_device.mac_settings.relay.mode.serving.second_channel.data_rate_index",
+ "end_device.mac_settings.relay.mode.serving.second_channel.frequency",
+ "end_device.mac_settings.relay.mode.serving.uplink_forwarding_rules",
"end_device.mac_settings.resets_f_cnt",
"end_device.mac_settings.resets_f_cnt.value",
"end_device.mac_settings.rx1_data_rate_offset",
@@ -172,6 +244,42 @@ var GenerateEndDeviceQRCodeRequestFieldPathsNested = []string{
"end_device.mac_state.current_parameters.ping_slot_frequency",
"end_device.mac_state.current_parameters.rejoin_count_periodicity",
"end_device.mac_state.current_parameters.rejoin_time_periodicity",
+ "end_device.mac_state.current_parameters.relay",
+ "end_device.mac_state.current_parameters.relay.mode",
+ "end_device.mac_state.current_parameters.relay.mode.served",
+ "end_device.mac_state.current_parameters.relay.mode.served.backoff",
+ "end_device.mac_state.current_parameters.relay.mode.served.mode",
+ "end_device.mac_state.current_parameters.relay.mode.served.mode.always",
+ "end_device.mac_state.current_parameters.relay.mode.served.mode.dynamic",
+ "end_device.mac_state.current_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device.mac_state.current_parameters.relay.mode.served.mode.end_device_controlled",
+ "end_device.mac_state.current_parameters.relay.mode.served.second_channel",
+ "end_device.mac_state.current_parameters.relay.mode.served.second_channel.ack_offset",
+ "end_device.mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index",
+ "end_device.mac_state.current_parameters.relay.mode.served.second_channel.frequency",
+ "end_device.mac_state.current_parameters.relay.mode.served.serving_device_id",
+ "end_device.mac_state.current_parameters.relay.mode.serving",
+ "end_device.mac_state.current_parameters.relay.mode.serving.cad_periodicity",
+ "end_device.mac_state.current_parameters.relay.mode.serving.default_channel_index",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.join_requests",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.notifications",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.overall",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.reset_behavior",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.uplink_messages",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device.mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device.mac_state.current_parameters.relay.mode.serving.second_channel",
+ "end_device.mac_state.current_parameters.relay.mode.serving.second_channel.ack_offset",
+ "end_device.mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "end_device.mac_state.current_parameters.relay.mode.serving.second_channel.frequency",
+ "end_device.mac_state.current_parameters.relay.mode.serving.uplink_forwarding_rules",
"end_device.mac_state.current_parameters.rx1_data_rate_offset",
"end_device.mac_state.current_parameters.rx1_delay",
"end_device.mac_state.current_parameters.rx2_data_rate_index",
@@ -200,6 +308,42 @@ var GenerateEndDeviceQRCodeRequestFieldPathsNested = []string{
"end_device.mac_state.desired_parameters.ping_slot_frequency",
"end_device.mac_state.desired_parameters.rejoin_count_periodicity",
"end_device.mac_state.desired_parameters.rejoin_time_periodicity",
+ "end_device.mac_state.desired_parameters.relay",
+ "end_device.mac_state.desired_parameters.relay.mode",
+ "end_device.mac_state.desired_parameters.relay.mode.served",
+ "end_device.mac_state.desired_parameters.relay.mode.served.backoff",
+ "end_device.mac_state.desired_parameters.relay.mode.served.mode",
+ "end_device.mac_state.desired_parameters.relay.mode.served.mode.always",
+ "end_device.mac_state.desired_parameters.relay.mode.served.mode.dynamic",
+ "end_device.mac_state.desired_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device.mac_state.desired_parameters.relay.mode.served.mode.end_device_controlled",
+ "end_device.mac_state.desired_parameters.relay.mode.served.second_channel",
+ "end_device.mac_state.desired_parameters.relay.mode.served.second_channel.ack_offset",
+ "end_device.mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index",
+ "end_device.mac_state.desired_parameters.relay.mode.served.second_channel.frequency",
+ "end_device.mac_state.desired_parameters.relay.mode.served.serving_device_id",
+ "end_device.mac_state.desired_parameters.relay.mode.serving",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.cad_periodicity",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.default_channel_index",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.join_requests",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.notifications",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.overall",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.reset_behavior",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.second_channel",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.second_channel.ack_offset",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.second_channel.frequency",
+ "end_device.mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules",
"end_device.mac_state.desired_parameters.rx1_data_rate_offset",
"end_device.mac_state.desired_parameters.rx1_delay",
"end_device.mac_state.desired_parameters.rx2_data_rate_index",
@@ -239,6 +383,8 @@ var GenerateEndDeviceQRCodeRequestFieldPathsNested = []string{
"end_device.mac_state.pending_join_request.downlink_settings.rx1_dr_offset",
"end_device.mac_state.pending_join_request.downlink_settings.rx2_dr",
"end_device.mac_state.pending_join_request.rx_delay",
+ "end_device.mac_state.pending_relay_downlink",
+ "end_device.mac_state.pending_relay_downlink.raw_payload",
"end_device.mac_state.pending_requests",
"end_device.mac_state.ping_slot_periodicity",
"end_device.mac_state.ping_slot_periodicity.value",
@@ -314,6 +460,42 @@ var GenerateEndDeviceQRCodeRequestFieldPathsNested = []string{
"end_device.pending_mac_state.current_parameters.ping_slot_frequency",
"end_device.pending_mac_state.current_parameters.rejoin_count_periodicity",
"end_device.pending_mac_state.current_parameters.rejoin_time_periodicity",
+ "end_device.pending_mac_state.current_parameters.relay",
+ "end_device.pending_mac_state.current_parameters.relay.mode",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.backoff",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.mode",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.mode.always",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.mode.dynamic",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.mode.end_device_controlled",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.second_channel",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.second_channel.ack_offset",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.second_channel.frequency",
+ "end_device.pending_mac_state.current_parameters.relay.mode.served.serving_device_id",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.cad_periodicity",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.default_channel_index",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.notifications",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.overall",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.reset_behavior",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.second_channel",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.second_channel.ack_offset",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.second_channel.frequency",
+ "end_device.pending_mac_state.current_parameters.relay.mode.serving.uplink_forwarding_rules",
"end_device.pending_mac_state.current_parameters.rx1_data_rate_offset",
"end_device.pending_mac_state.current_parameters.rx1_delay",
"end_device.pending_mac_state.current_parameters.rx2_data_rate_index",
@@ -342,6 +524,42 @@ var GenerateEndDeviceQRCodeRequestFieldPathsNested = []string{
"end_device.pending_mac_state.desired_parameters.ping_slot_frequency",
"end_device.pending_mac_state.desired_parameters.rejoin_count_periodicity",
"end_device.pending_mac_state.desired_parameters.rejoin_time_periodicity",
+ "end_device.pending_mac_state.desired_parameters.relay",
+ "end_device.pending_mac_state.desired_parameters.relay.mode",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.backoff",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.mode",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.mode.always",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.mode.dynamic",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.mode.end_device_controlled",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.second_channel",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.second_channel.ack_offset",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.second_channel.frequency",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.served.serving_device_id",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.cad_periodicity",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.default_channel_index",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.overall",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.reset_behavior",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.second_channel",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.second_channel.ack_offset",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.second_channel.frequency",
+ "end_device.pending_mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules",
"end_device.pending_mac_state.desired_parameters.rx1_data_rate_offset",
"end_device.pending_mac_state.desired_parameters.rx1_delay",
"end_device.pending_mac_state.desired_parameters.rx2_data_rate_index",
@@ -381,6 +599,8 @@ var GenerateEndDeviceQRCodeRequestFieldPathsNested = []string{
"end_device.pending_mac_state.pending_join_request.downlink_settings.rx1_dr_offset",
"end_device.pending_mac_state.pending_join_request.downlink_settings.rx2_dr",
"end_device.pending_mac_state.pending_join_request.rx_delay",
+ "end_device.pending_mac_state.pending_relay_downlink",
+ "end_device.pending_mac_state.pending_relay_downlink.raw_payload",
"end_device.pending_mac_state.pending_requests",
"end_device.pending_mac_state.ping_slot_periodicity",
"end_device.pending_mac_state.ping_slot_periodicity.value",
@@ -629,6 +849,42 @@ var ParseEndDeviceQRCodeResponseFieldPathsNested = []string{
"end_device_template.end_device.mac_settings.desired_ping_slot_data_rate_index.value",
"end_device_template.end_device.mac_settings.desired_ping_slot_frequency",
"end_device_template.end_device.mac_settings.desired_ping_slot_frequency.value",
+ "end_device_template.end_device.mac_settings.desired_relay",
+ "end_device_template.end_device.mac_settings.desired_relay.mode",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.served",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.served.backoff",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.served.mode",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.served.mode.always",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.served.mode.dynamic",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.served.mode.end_device_controlled",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.served.second_channel",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.served.second_channel.ack_offset",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.served.second_channel.data_rate_index",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.served.second_channel.frequency",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.served.serving_device_id",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.serving",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.serving.cad_periodicity",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.serving.default_channel_index",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.serving.limits",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.serving.limits.join_requests",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.serving.limits.notifications",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.serving.limits.notifications.bucket_size",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.serving.limits.notifications.reload_rate",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.serving.limits.overall",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.serving.limits.overall.bucket_size",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.serving.limits.overall.reload_rate",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.serving.limits.reset_behavior",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.serving.limits.uplink_messages",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.serving.second_channel",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.serving.second_channel.ack_offset",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.serving.second_channel.data_rate_index",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.serving.second_channel.frequency",
+ "end_device_template.end_device.mac_settings.desired_relay.mode.serving.uplink_forwarding_rules",
"end_device_template.end_device.mac_settings.desired_rx1_data_rate_offset",
"end_device_template.end_device.mac_settings.desired_rx1_data_rate_offset.value",
"end_device_template.end_device.mac_settings.desired_rx1_delay",
@@ -648,6 +904,42 @@ var ParseEndDeviceQRCodeResponseFieldPathsNested = []string{
"end_device_template.end_device.mac_settings.ping_slot_frequency.value",
"end_device_template.end_device.mac_settings.ping_slot_periodicity",
"end_device_template.end_device.mac_settings.ping_slot_periodicity.value",
+ "end_device_template.end_device.mac_settings.relay",
+ "end_device_template.end_device.mac_settings.relay.mode",
+ "end_device_template.end_device.mac_settings.relay.mode.served",
+ "end_device_template.end_device.mac_settings.relay.mode.served.backoff",
+ "end_device_template.end_device.mac_settings.relay.mode.served.mode",
+ "end_device_template.end_device.mac_settings.relay.mode.served.mode.always",
+ "end_device_template.end_device.mac_settings.relay.mode.served.mode.dynamic",
+ "end_device_template.end_device.mac_settings.relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device_template.end_device.mac_settings.relay.mode.served.mode.end_device_controlled",
+ "end_device_template.end_device.mac_settings.relay.mode.served.second_channel",
+ "end_device_template.end_device.mac_settings.relay.mode.served.second_channel.ack_offset",
+ "end_device_template.end_device.mac_settings.relay.mode.served.second_channel.data_rate_index",
+ "end_device_template.end_device.mac_settings.relay.mode.served.second_channel.frequency",
+ "end_device_template.end_device.mac_settings.relay.mode.served.serving_device_id",
+ "end_device_template.end_device.mac_settings.relay.mode.serving",
+ "end_device_template.end_device.mac_settings.relay.mode.serving.cad_periodicity",
+ "end_device_template.end_device.mac_settings.relay.mode.serving.default_channel_index",
+ "end_device_template.end_device.mac_settings.relay.mode.serving.limits",
+ "end_device_template.end_device.mac_settings.relay.mode.serving.limits.join_requests",
+ "end_device_template.end_device.mac_settings.relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device_template.end_device.mac_settings.relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device_template.end_device.mac_settings.relay.mode.serving.limits.notifications",
+ "end_device_template.end_device.mac_settings.relay.mode.serving.limits.notifications.bucket_size",
+ "end_device_template.end_device.mac_settings.relay.mode.serving.limits.notifications.reload_rate",
+ "end_device_template.end_device.mac_settings.relay.mode.serving.limits.overall",
+ "end_device_template.end_device.mac_settings.relay.mode.serving.limits.overall.bucket_size",
+ "end_device_template.end_device.mac_settings.relay.mode.serving.limits.overall.reload_rate",
+ "end_device_template.end_device.mac_settings.relay.mode.serving.limits.reset_behavior",
+ "end_device_template.end_device.mac_settings.relay.mode.serving.limits.uplink_messages",
+ "end_device_template.end_device.mac_settings.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device_template.end_device.mac_settings.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device_template.end_device.mac_settings.relay.mode.serving.second_channel",
+ "end_device_template.end_device.mac_settings.relay.mode.serving.second_channel.ack_offset",
+ "end_device_template.end_device.mac_settings.relay.mode.serving.second_channel.data_rate_index",
+ "end_device_template.end_device.mac_settings.relay.mode.serving.second_channel.frequency",
+ "end_device_template.end_device.mac_settings.relay.mode.serving.uplink_forwarding_rules",
"end_device_template.end_device.mac_settings.resets_f_cnt",
"end_device_template.end_device.mac_settings.resets_f_cnt.value",
"end_device_template.end_device.mac_settings.rx1_data_rate_offset",
@@ -691,6 +983,42 @@ var ParseEndDeviceQRCodeResponseFieldPathsNested = []string{
"end_device_template.end_device.mac_state.current_parameters.ping_slot_frequency",
"end_device_template.end_device.mac_state.current_parameters.rejoin_count_periodicity",
"end_device_template.end_device.mac_state.current_parameters.rejoin_time_periodicity",
+ "end_device_template.end_device.mac_state.current_parameters.relay",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.served",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.served.backoff",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.served.mode",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.served.mode.always",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.served.mode.dynamic",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.served.mode.end_device_controlled",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.served.second_channel",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.served.second_channel.ack_offset",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.served.second_channel.frequency",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.served.serving_device_id",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.serving",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.serving.cad_periodicity",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.serving.default_channel_index",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.serving.limits",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.serving.limits.join_requests",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.serving.limits.notifications",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.serving.limits.overall",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.serving.limits.reset_behavior",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.serving.limits.uplink_messages",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.serving.second_channel",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.serving.second_channel.ack_offset",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.serving.second_channel.frequency",
+ "end_device_template.end_device.mac_state.current_parameters.relay.mode.serving.uplink_forwarding_rules",
"end_device_template.end_device.mac_state.current_parameters.rx1_data_rate_offset",
"end_device_template.end_device.mac_state.current_parameters.rx1_delay",
"end_device_template.end_device.mac_state.current_parameters.rx2_data_rate_index",
@@ -719,6 +1047,42 @@ var ParseEndDeviceQRCodeResponseFieldPathsNested = []string{
"end_device_template.end_device.mac_state.desired_parameters.ping_slot_frequency",
"end_device_template.end_device.mac_state.desired_parameters.rejoin_count_periodicity",
"end_device_template.end_device.mac_state.desired_parameters.rejoin_time_periodicity",
+ "end_device_template.end_device.mac_state.desired_parameters.relay",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.served",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.served.backoff",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.served.mode",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.served.mode.always",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.served.mode.dynamic",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.served.mode.end_device_controlled",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.served.second_channel",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.served.second_channel.ack_offset",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.served.second_channel.frequency",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.served.serving_device_id",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.serving",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.serving.cad_periodicity",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.serving.default_channel_index",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.serving.limits",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.serving.limits.join_requests",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.serving.limits.notifications",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.serving.limits.overall",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.serving.limits.reset_behavior",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.serving.second_channel",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.serving.second_channel.ack_offset",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.serving.second_channel.frequency",
+ "end_device_template.end_device.mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules",
"end_device_template.end_device.mac_state.desired_parameters.rx1_data_rate_offset",
"end_device_template.end_device.mac_state.desired_parameters.rx1_delay",
"end_device_template.end_device.mac_state.desired_parameters.rx2_data_rate_index",
@@ -758,6 +1122,8 @@ var ParseEndDeviceQRCodeResponseFieldPathsNested = []string{
"end_device_template.end_device.mac_state.pending_join_request.downlink_settings.rx1_dr_offset",
"end_device_template.end_device.mac_state.pending_join_request.downlink_settings.rx2_dr",
"end_device_template.end_device.mac_state.pending_join_request.rx_delay",
+ "end_device_template.end_device.mac_state.pending_relay_downlink",
+ "end_device_template.end_device.mac_state.pending_relay_downlink.raw_payload",
"end_device_template.end_device.mac_state.pending_requests",
"end_device_template.end_device.mac_state.ping_slot_periodicity",
"end_device_template.end_device.mac_state.ping_slot_periodicity.value",
@@ -833,6 +1199,42 @@ var ParseEndDeviceQRCodeResponseFieldPathsNested = []string{
"end_device_template.end_device.pending_mac_state.current_parameters.ping_slot_frequency",
"end_device_template.end_device.pending_mac_state.current_parameters.rejoin_count_periodicity",
"end_device_template.end_device.pending_mac_state.current_parameters.rejoin_time_periodicity",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.served",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.served.backoff",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.served.mode",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.served.mode.always",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.served.mode.dynamic",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.served.mode.end_device_controlled",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.served.second_channel",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.served.second_channel.ack_offset",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.served.second_channel.frequency",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.served.serving_device_id",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.serving",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.serving.cad_periodicity",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.serving.default_channel_index",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.serving.limits",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.notifications",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.overall",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.reset_behavior",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.serving.second_channel",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.serving.second_channel.ack_offset",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.serving.second_channel.frequency",
+ "end_device_template.end_device.pending_mac_state.current_parameters.relay.mode.serving.uplink_forwarding_rules",
"end_device_template.end_device.pending_mac_state.current_parameters.rx1_data_rate_offset",
"end_device_template.end_device.pending_mac_state.current_parameters.rx1_delay",
"end_device_template.end_device.pending_mac_state.current_parameters.rx2_data_rate_index",
@@ -861,6 +1263,42 @@ var ParseEndDeviceQRCodeResponseFieldPathsNested = []string{
"end_device_template.end_device.pending_mac_state.desired_parameters.ping_slot_frequency",
"end_device_template.end_device.pending_mac_state.desired_parameters.rejoin_count_periodicity",
"end_device_template.end_device.pending_mac_state.desired_parameters.rejoin_time_periodicity",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.served",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.served.backoff",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.served.mode",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.served.mode.always",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.served.mode.dynamic",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.served.mode.end_device_controlled",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.served.second_channel",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.served.second_channel.ack_offset",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.served.second_channel.frequency",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.served.serving_device_id",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.serving",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.serving.cad_periodicity",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.serving.default_channel_index",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.overall",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.reset_behavior",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.serving.second_channel",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.serving.second_channel.ack_offset",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.serving.second_channel.frequency",
+ "end_device_template.end_device.pending_mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules",
"end_device_template.end_device.pending_mac_state.desired_parameters.rx1_data_rate_offset",
"end_device_template.end_device.pending_mac_state.desired_parameters.rx1_delay",
"end_device_template.end_device.pending_mac_state.desired_parameters.rx2_data_rate_index",
@@ -900,6 +1338,8 @@ var ParseEndDeviceQRCodeResponseFieldPathsNested = []string{
"end_device_template.end_device.pending_mac_state.pending_join_request.downlink_settings.rx1_dr_offset",
"end_device_template.end_device.pending_mac_state.pending_join_request.downlink_settings.rx2_dr",
"end_device_template.end_device.pending_mac_state.pending_join_request.rx_delay",
+ "end_device_template.end_device.pending_mac_state.pending_relay_downlink",
+ "end_device_template.end_device.pending_mac_state.pending_relay_downlink.raw_payload",
"end_device_template.end_device.pending_mac_state.pending_requests",
"end_device_template.end_device.pending_mac_state.ping_slot_periodicity",
"end_device_template.end_device.pending_mac_state.ping_slot_periodicity.value",
diff --git a/pkg/ttnpb/testdata/ttnpb_encoding_golden.md b/pkg/ttnpb/testdata/ttnpb_encoding_golden.md
index e87dac40fa..4bb15def24 100644
--- a/pkg/ttnpb/testdata/ttnpb_encoding_golden.md
+++ b/pkg/ttnpb/testdata/ttnpb_encoding_golden.md
@@ -201,6 +201,13 @@ Binary | ttnpb.MACCommandIdentifier | CID_PING_SLOT_CHANNEL | [17]
Binary | ttnpb.MACCommandIdentifier | CID_PING_SLOT_INFO | [16]
Binary | ttnpb.MACCommandIdentifier | CID_REJOIN_PARAM_SETUP | [15]
Binary | ttnpb.MACCommandIdentifier | CID_REKEY | [11]
+Binary | ttnpb.MACCommandIdentifier | CID_RELAY_CONF | [64]
+Binary | ttnpb.MACCommandIdentifier | CID_RELAY_CONFIGURE_FWD_LIMIT | [69]
+Binary | ttnpb.MACCommandIdentifier | CID_RELAY_CTRL_UPLINK_LIST | [68]
+Binary | ttnpb.MACCommandIdentifier | CID_RELAY_END_DEVICE_CONF | [65]
+Binary | ttnpb.MACCommandIdentifier | CID_RELAY_FILTER_LIST | [66]
+Binary | ttnpb.MACCommandIdentifier | CID_RELAY_NOTIFY_NEW_END_DEVICE | [70]
+Binary | ttnpb.MACCommandIdentifier | CID_RELAY_UPDATE_UPLINK_LIST | [67]
Binary | ttnpb.MACCommandIdentifier | CID_RESET | [1]
Binary | ttnpb.MACCommandIdentifier | CID_RFU_0 | [0]
Binary | ttnpb.MACCommandIdentifier | CID_RX_PARAM_SETUP | [5]
@@ -570,6 +577,13 @@ JSON | ttnpb.MACCommandIdentifier | CID_PING_SLOT_CHANNEL | "CID_PING_SLOT_CHANN
JSON | ttnpb.MACCommandIdentifier | CID_PING_SLOT_INFO | "CID_PING_SLOT_INFO"
JSON | ttnpb.MACCommandIdentifier | CID_REJOIN_PARAM_SETUP | "CID_REJOIN_PARAM_SETUP"
JSON | ttnpb.MACCommandIdentifier | CID_REKEY | "CID_REKEY"
+JSON | ttnpb.MACCommandIdentifier | CID_RELAY_CONF | "CID_RELAY_CONF"
+JSON | ttnpb.MACCommandIdentifier | CID_RELAY_CONFIGURE_FWD_LIMIT | "CID_RELAY_CONFIGURE_FWD_LIMIT"
+JSON | ttnpb.MACCommandIdentifier | CID_RELAY_CTRL_UPLINK_LIST | "CID_RELAY_CTRL_UPLINK_LIST"
+JSON | ttnpb.MACCommandIdentifier | CID_RELAY_END_DEVICE_CONF | "CID_RELAY_END_DEVICE_CONF"
+JSON | ttnpb.MACCommandIdentifier | CID_RELAY_FILTER_LIST | "CID_RELAY_FILTER_LIST"
+JSON | ttnpb.MACCommandIdentifier | CID_RELAY_NOTIFY_NEW_END_DEVICE | "CID_RELAY_NOTIFY_NEW_END_DEVICE"
+JSON | ttnpb.MACCommandIdentifier | CID_RELAY_UPDATE_UPLINK_LIST | "CID_RELAY_UPDATE_UPLINK_LIST"
JSON | ttnpb.MACCommandIdentifier | CID_RESET | "CID_RESET"
JSON | ttnpb.MACCommandIdentifier | CID_RFU_0 | "CID_RFU_0"
JSON | ttnpb.MACCommandIdentifier | CID_RX_PARAM_SETUP | "CID_RX_PARAM_SETUP"
@@ -1012,6 +1026,13 @@ ProtoJSON | ttnpb.MACCommandIdentifier | CID_PING_SLOT_CHANNEL | "CID_PING_SLOT_
ProtoJSON | ttnpb.MACCommandIdentifier | CID_PING_SLOT_INFO | "CID_PING_SLOT_INFO"
ProtoJSON | ttnpb.MACCommandIdentifier | CID_REJOIN_PARAM_SETUP | "CID_REJOIN_PARAM_SETUP"
ProtoJSON | ttnpb.MACCommandIdentifier | CID_REKEY | "CID_REKEY"
+ProtoJSON | ttnpb.MACCommandIdentifier | CID_RELAY_CONF | "CID_RELAY_CONF"
+ProtoJSON | ttnpb.MACCommandIdentifier | CID_RELAY_CONFIGURE_FWD_LIMIT | "CID_RELAY_CONFIGURE_FWD_LIMIT"
+ProtoJSON | ttnpb.MACCommandIdentifier | CID_RELAY_CTRL_UPLINK_LIST | "CID_RELAY_CTRL_UPLINK_LIST"
+ProtoJSON | ttnpb.MACCommandIdentifier | CID_RELAY_END_DEVICE_CONF | "CID_RELAY_END_DEVICE_CONF"
+ProtoJSON | ttnpb.MACCommandIdentifier | CID_RELAY_FILTER_LIST | "CID_RELAY_FILTER_LIST"
+ProtoJSON | ttnpb.MACCommandIdentifier | CID_RELAY_NOTIFY_NEW_END_DEVICE | "CID_RELAY_NOTIFY_NEW_END_DEVICE"
+ProtoJSON | ttnpb.MACCommandIdentifier | CID_RELAY_UPDATE_UPLINK_LIST | "CID_RELAY_UPDATE_UPLINK_LIST"
ProtoJSON | ttnpb.MACCommandIdentifier | CID_RESET | "CID_RESET"
ProtoJSON | ttnpb.MACCommandIdentifier | CID_RFU_0 | "CID_RFU_0"
ProtoJSON | ttnpb.MACCommandIdentifier | CID_RX_PARAM_SETUP | "CID_RX_PARAM_SETUP"
@@ -1454,6 +1475,13 @@ Text | ttnpb.MACCommandIdentifier | CID_PING_SLOT_CHANNEL | CID_PING_SLOT_CHANNE
Text | ttnpb.MACCommandIdentifier | CID_PING_SLOT_INFO | CID_PING_SLOT_INFO
Text | ttnpb.MACCommandIdentifier | CID_REJOIN_PARAM_SETUP | CID_REJOIN_PARAM_SETUP
Text | ttnpb.MACCommandIdentifier | CID_REKEY | CID_REKEY
+Text | ttnpb.MACCommandIdentifier | CID_RELAY_CONF | CID_RELAY_CONF
+Text | ttnpb.MACCommandIdentifier | CID_RELAY_CONFIGURE_FWD_LIMIT | CID_RELAY_CONFIGURE_FWD_LIMIT
+Text | ttnpb.MACCommandIdentifier | CID_RELAY_CTRL_UPLINK_LIST | CID_RELAY_CTRL_UPLINK_LIST
+Text | ttnpb.MACCommandIdentifier | CID_RELAY_END_DEVICE_CONF | CID_RELAY_END_DEVICE_CONF
+Text | ttnpb.MACCommandIdentifier | CID_RELAY_FILTER_LIST | CID_RELAY_FILTER_LIST
+Text | ttnpb.MACCommandIdentifier | CID_RELAY_NOTIFY_NEW_END_DEVICE | CID_RELAY_NOTIFY_NEW_END_DEVICE
+Text | ttnpb.MACCommandIdentifier | CID_RELAY_UPDATE_UPLINK_LIST | CID_RELAY_UPDATE_UPLINK_LIST
Text | ttnpb.MACCommandIdentifier | CID_RESET | CID_RESET
Text | ttnpb.MACCommandIdentifier | CID_RFU_0 | CID_RFU_0
Text | ttnpb.MACCommandIdentifier | CID_RX_PARAM_SETUP | CID_RX_PARAM_SETUP
diff --git a/pkg/ttnpb/zero_test.go b/pkg/ttnpb/zero_test.go
index efda844672..f4958d041e 100644
--- a/pkg/ttnpb/zero_test.go
+++ b/pkg/ttnpb/zero_test.go
@@ -107,6 +107,20 @@ func TestFieldIsZero(t *testing.T) {
(*SetEndDeviceRequest)(nil): EndDeviceFieldPathsNested,
&UpdateEndDeviceRequest{}: EndDeviceFieldPathsNested,
(*UpdateEndDeviceRequest)(nil): EndDeviceFieldPathsNested,
+ &RelayParameters{}: RelayParametersFieldPathsNested,
+ (*RelayParameters)(nil): RelayParametersFieldPathsNested,
+ &ServedRelayParameters{}: ServedRelayParametersFieldPathsNested,
+ (*ServedRelayParameters)(nil): ServedRelayParametersFieldPathsNested,
+ &ServingRelayParameters{}: ServingRelayParametersFieldPathsNested,
+ (*ServingRelayParameters)(nil): ServingRelayParametersFieldPathsNested,
+ &RelaySecondChannel{}: RelaySecondChannelFieldPathsNested,
+ (*RelaySecondChannel)(nil): RelaySecondChannelFieldPathsNested,
+ &RelayEndDeviceDynamicMode{}: RelayEndDeviceDynamicModeFieldPathsNested,
+ (*RelayEndDeviceDynamicMode)(nil): RelayEndDeviceDynamicModeFieldPathsNested,
+ &RelayForwardLimits{}: RelayForwardLimitsFieldPathsNested,
+ (*RelayForwardLimits)(nil): RelayForwardLimitsFieldPathsNested,
+ &ServingRelayForwardingLimits{}: ServingRelayForwardingLimitsFieldPathsNested,
+ (*ServingRelayForwardingLimits)(nil): ServingRelayForwardingLimitsFieldPathsNested,
} {
for _, p := range paths {
v, p := v, p
diff --git a/pkg/util/test/constructors_generated.go b/pkg/util/test/constructors_generated.go
index 7403d703ac..abb8efc41a 100644
--- a/pkg/util/test/constructors_generated.go
+++ b/pkg/util/test/constructors_generated.go
@@ -483,6 +483,15 @@ func (MACStateOptionNamespace) WithRecentMacCommandIdentifiers(vs ...ttnpb.MACCo
}
}
+// WithPendingRelayDownlink returns a MACStateOption, which returns a copy of ttnpb.MACState with PendingRelayDownlink set to v.
+func (MACStateOptionNamespace) WithPendingRelayDownlink(v *ttnpb.RelayForwardDownlinkReq) MACStateOption {
+ return func(x *ttnpb.MACState) *ttnpb.MACState {
+ copy := ttnpb.Clone(x)
+ copy.PendingRelayDownlink = v
+ return copy
+ }
+}
+
// Compose returns a functional composition of opts as a singular MACStateOption.
func (MACStateOptionNamespace) Compose(opts ...MACStateOption) MACStateOption {
return func(x *ttnpb.MACState) *ttnpb.MACState {
diff --git a/pkg/version/ttn.go b/pkg/version/ttn.go
index 2fa9d9073f..87ae965713 100644
--- a/pkg/version/ttn.go
+++ b/pkg/version/ttn.go
@@ -3,4 +3,4 @@
package version
// TTN Version
-var TTN = "3.27.2-dev"
+var TTN = "3.28.1-dev"
diff --git a/pkg/web/web.go b/pkg/web/web.go
index ad2725d268..a5c1f0c270 100644
--- a/pkg/web/web.go
+++ b/pkg/web/web.go
@@ -27,8 +27,10 @@ import (
"github.com/gorilla/csrf"
"github.com/gorilla/mux"
+ "github.com/klauspost/compress/gzhttp"
"go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux"
"go.thethings.network/lorawan-stack/v3/pkg/errors"
+ "go.thethings.network/lorawan-stack/v3/pkg/experimental"
"go.thethings.network/lorawan-stack/v3/pkg/fillcontext"
"go.thethings.network/lorawan-stack/v3/pkg/log"
"go.thethings.network/lorawan-stack/v3/pkg/random"
@@ -39,6 +41,19 @@ import (
"gopkg.in/yaml.v2"
)
+var responseCompressionFeatureFlag = experimental.DefineFeature("http.server.transport.compression", true)
+
+func compressionMiddleware(ctx context.Context) (func(http.Handler) http.Handler, error) {
+ if !responseCompressionFeatureFlag.GetValue(ctx) {
+ return func(next http.Handler) http.Handler { return next }, nil
+ }
+ m, err := gzhttp.NewWrapper()
+ if err != nil {
+ return nil, err
+ }
+ return func(h http.Handler) http.Handler { return m(h) }, nil
+}
+
// Registerer allows components to register their services to the web server.
type Registerer interface {
RegisterRoutes(s *Server)
@@ -171,7 +186,13 @@ func New(ctx context.Context, opts ...Option) (*Server, error) {
}
var proxyConfiguration webmiddleware.ProxyConfiguration
- proxyConfiguration.ParseAndAddTrusted(options.trustedProxies...)
+ if err := proxyConfiguration.ParseAndAddTrusted(options.trustedProxies...); err != nil {
+ return nil, err
+ }
+ compressor, err := compressionMiddleware(ctx)
+ if err != nil {
+ return nil, err
+ }
root := mux.NewRouter()
root.NotFoundHandler = http.HandlerFunc(webhandlers.NotFound)
root.Use(
@@ -179,6 +200,7 @@ func New(ctx context.Context, opts ...Option) (*Server, error) {
"text/html": webhandlers.Template,
}),
mux.MiddlewareFunc(webmiddleware.Recover()),
+ compressor,
otelmux.Middleware("ttn-lw-stack", otelmux.WithTracerProvider(tracing.FromContext(ctx))),
mux.MiddlewareFunc(webmiddleware.FillContext(options.contextFillers...)),
mux.MiddlewareFunc(webmiddleware.Peer()),
diff --git a/pkg/webui/account/components/oauth-client-form/messages.js b/pkg/webui/account/components/oauth-client-form/messages.js
index 2b204a8fb7..bfbc36f2e7 100644
--- a/pkg/webui/account/components/oauth-client-form/messages.js
+++ b/pkg/webui/account/components/oauth-client-form/messages.js
@@ -21,7 +21,6 @@ export default defineMessages({
clientDescDescription:
'The description is displayed to the user when authorizing the client. Use it to explain the purpose of your client.',
createClient: 'Create OAuth client',
- deleteTitle: 'Are you sure you want to delete this account?',
deleteWarning:
'This will PERMANENTLY DELETE THIS OAUTH CLIENT and LOCK THE OAUTH ID . Make sure you assign new collaborators to such entities if you plan to continue using them.',
purgeWarning:
@@ -41,9 +40,7 @@ export default defineMessages({
'If set, the authorization page will visually indicate endorsement to improve trust',
grants: 'Grant types',
grantsDesc: 'OAuth flows that can be used for the client to get a token',
- grantAuthorizationLabel: 'Authorization code',
grantRefreshTokenLabel: 'Refresh token',
- grantPasswordLabel: 'Password',
deleteClient: 'Delete OAuth client',
urlsPlaceholder: 'https://example.com/oauth/callback',
rightsWarning:
diff --git a/pkg/webui/account/containers/authorizations-table/index.js b/pkg/webui/account/containers/authorizations-table/index.js
index f7ac141a72..6f9fad7007 100644
--- a/pkg/webui/account/containers/authorizations-table/index.js
+++ b/pkg/webui/account/containers/authorizations-table/index.js
@@ -14,7 +14,6 @@
import React from 'react'
import { useSelector } from 'react-redux'
-import { defineMessages } from 'react-intl'
import { createSelector } from 'reselect'
import FetchTable from '@ttn-lw/containers/fetch-table'
@@ -32,11 +31,6 @@ import {
} from '@account/store/selectors/authorizations'
import { selectUserId } from '@account/store/selectors/user'
-const m = defineMessages({
- clientId: 'Client ID',
- tableTitle: 'OAuth client authorizations',
-})
-
const getItemPathPrefix = item => `${item.client_ids.client_id}`
const OAuthClientAuthorizationsTable = () => {
@@ -46,7 +40,7 @@ const OAuthClientAuthorizationsTable = () => {
const baseHeaders = [
{
name: 'client_ids.client_id',
- displayName: m.clientId,
+ displayName: sharedMessages.clientId,
width: 20,
},
{
@@ -84,7 +78,7 @@ const OAuthClientAuthorizationsTable = () => {
getItemsAction={getItems}
baseDataSelector={baseDataSelector}
getItemPathPrefix={getItemPathPrefix}
- tableTitle={ }
+ tableTitle={ }
clickable
/>
)
diff --git a/pkg/webui/account/containers/clients-table/index.js b/pkg/webui/account/containers/clients-table/index.js
index fefbb8dd9f..36d2c5f33c 100644
--- a/pkg/webui/account/containers/clients-table/index.js
+++ b/pkg/webui/account/containers/clients-table/index.js
@@ -44,7 +44,6 @@ const m = defineMessages({
restoreFail: 'There was an error and OAuth client could not be restored',
purgeSuccess: 'OAuth client purged',
purgeFail: 'There was an error and the OAuth client could not be purged',
- addClient: 'Add OAuth client',
})
const OWNED_TAB = 'owned'
@@ -200,7 +199,7 @@ const ClientsTable = () => {
{
@@ -87,7 +84,7 @@ const CollaboratorsTable = props => {
const baseHeaders = [
{
name: 'ids',
- displayName: m.id,
+ displayName: sharedMessages.userOrgId,
render: ids => {
const isUser = 'user_ids' in ids
const collaboratorId = getCollaboratorId({ ids })
@@ -144,7 +141,7 @@ const CollaboratorsTable = props => {
@@ -188,7 +185,7 @@ const CollaboratorsTable = props => {
headers={headers}
rowKeySelector={rowKeySelector}
getItemPathPrefix={getCollaboratorPathPrefix}
- addMessage={m.addCollaborator}
+ addMessage={sharedMessages.addCollaborator}
getItemsAction={getItems}
baseDataSelector={baseDataSelector}
tableTitle={ }
diff --git a/pkg/webui/account/containers/profile-settings-form/index.js b/pkg/webui/account/containers/profile-settings-form/index.js
index f0cfd86a58..c266e8654b 100644
--- a/pkg/webui/account/containers/profile-settings-form/index.js
+++ b/pkg/webui/account/containers/profile-settings-form/index.js
@@ -220,7 +220,7 @@ const ProfileEditForm = () => {
onChange={setProfilePictureSource}
>
-
+
)}
{!disableUploadConfig && profilePictureSource === 'upload' && (
diff --git a/pkg/webui/account/containers/profile-settings-form/messages.js b/pkg/webui/account/containers/profile-settings-form/messages.js
index 3464e17a21..21a8b0e907 100644
--- a/pkg/webui/account/containers/profile-settings-form/messages.js
+++ b/pkg/webui/account/containers/profile-settings-form/messages.js
@@ -20,14 +20,12 @@ export default defineMessages({
successMessage: 'Profile updated',
deleteAccount: 'Delete account',
useGravatar: 'Use Gravatar',
- uploadAnImage: 'Upload an image',
gravatarInfo:
"If available, we're using the Gravatar image associated with your email address. You can upload a different profile picture by selecting the option above.",
gravatarInfoGravatarOnly:
"If available, we're using the Gravatar image associated with your email address. Please follow the instructions on the Gravatar website to change your profile picture.",
primaryEmailAddressDescription: 'Primary email address associated with your account',
deleteAccountError: 'There was an error and your account could not be deleted',
- deleteAccountSuccess: 'Account deleted',
imageRequired:
'Please select a file to use as your profile picture or choose "Gravatar" as source',
imageUpload: 'Image upload',
diff --git a/pkg/webui/account/containers/sessions-table/index.js b/pkg/webui/account/containers/sessions-table/index.js
index b3b0492468..c01cb54513 100644
--- a/pkg/webui/account/containers/sessions-table/index.js
+++ b/pkg/webui/account/containers/sessions-table/index.js
@@ -36,7 +36,6 @@ import { selectUserSessions, selectUserSessionsTotalCount } from '@account/store
const m = defineMessages({
deleteSessionSuccess: 'Session removed successfully',
deleteSessionError: 'There was an error and the session could not be deleted',
- sessionsTableTitle: 'Sessions',
removeButtonMessage: 'Remove this session',
noExpiryDate: 'No expiry date',
endSession: 'Logout to end this session',
@@ -183,7 +182,7 @@ const UserSessionsTable = () => {
headers={makeHeaders}
getItemsAction={getSessions}
baseDataSelector={baseDataSelector}
- tableTitle={ }
+ tableTitle={ }
getItemPathPrefix={getItemPathPrefix}
/>
)
diff --git a/pkg/webui/account/containers/tokens-table/index.js b/pkg/webui/account/containers/tokens-table/index.js
index 328c643d0d..b836616073 100644
--- a/pkg/webui/account/containers/tokens-table/index.js
+++ b/pkg/webui/account/containers/tokens-table/index.js
@@ -45,7 +45,6 @@ import { selectTokens, selectTokensTotalCount } from '@account/store/selectors/a
import { selectUserId } from '@account/store/selectors/user'
const m = defineMessages({
- tableTitle: 'Access tokens',
deleteSuccess: 'Access token invalidated',
deleteFail: 'There was an error and the access token could not be invalidated',
deleteButton: 'Invalidate this access token',
@@ -53,7 +52,6 @@ const m = defineMessages({
deleteAllFail: 'There was an error and the access tokens could not be invalidated',
deleteAllButton: 'Invalidate all access tokens',
expires: 'Expires',
- accessTokens: 'Access tokens',
})
const TokensTable = () => {
@@ -67,7 +65,7 @@ const TokensTable = () => {
'client-authorizations.single.access-tokens',
,
)
@@ -200,7 +198,7 @@ const TokensTable = () => {
baseDataSelector={baseDataSelector}
pageSize={PAGE_SIZES.SMALL}
actionItems={deleteAllButton}
- tableTitle={ }
+ tableTitle={ }
/>
diff --git a/pkg/webui/account/views/app/index.js b/pkg/webui/account/views/app/index.js
index 8f4fd0adaa..284175f326 100644
--- a/pkg/webui/account/views/app/index.js
+++ b/pkg/webui/account/views/app/index.js
@@ -14,7 +14,15 @@
import { useSelector, useDispatch } from 'react-redux'
import React, { useEffect } from 'react'
-import { Routes, Route, BrowserRouter } from 'react-router-dom'
+import {
+ Routes,
+ Route,
+ BrowserRouter,
+ ScrollRestoration,
+ createBrowserRouter,
+ RouterProvider,
+ Outlet,
+} from 'react-router-dom'
import { Helmet } from 'react-helmet'
import { ToastContainer } from '@ttn-lw/components/toast'
@@ -27,7 +35,6 @@ import Header from '@account/containers/header'
import Landing from '@account/views/landing'
import Authorize from '@account/views/authorize'
-import PropTypes from '@ttn-lw/lib/prop-types'
import {
selectApplicationSiteName,
selectApplicationSiteTitle,
@@ -44,8 +51,34 @@ const siteTitle = selectApplicationSiteTitle()
const pageData = selectPageData()
const errorRender = error => } />
+const getScrollRestorationKey = location => {
+ // Preserve scroll position only when necessary.
+ // E.g. we don't want to scroll to top when changing tabs of a table,
+ // but we do want to scroll to top when changing pages.
+ const { pathname, search } = location
+ const params = new URLSearchParams(search)
+ const page = params.get('page')
+
+ return `${pathname}${page ? `?page=${page}` : ''}`
+}
-const AccountApp = ({ history }) => {
+const Layout = () => (
+ <>
+
+
+
+
+
+
+
+
+ >
+)
+
+const AccountRoot = () => {
const user = useSelector(selectUser)
const dispatch = useDispatch()
@@ -72,28 +105,19 @@ const AccountApp = ({ history }) => {
}
return (
- <>
-
-
-
-
-
-
-
-
-
-
-
-
- >
+
+ }>
+
+
+
+
)
}
-AccountApp.propTypes = {
- history: PropTypes.history.isRequired,
-}
+const router = createBrowserRouter([{ path: '*', Component: AccountRoot }], {
+ basename: '/oauth',
+})
+
+const AccountApp = () =>
export default AccountApp
diff --git a/pkg/webui/account/views/code/index.js b/pkg/webui/account/views/code/index.js
index 285f39997a..8f6e8c3e3f 100644
--- a/pkg/webui/account/views/code/index.js
+++ b/pkg/webui/account/views/code/index.js
@@ -24,13 +24,12 @@ import PageTitle from '@ttn-lw/components/page-title'
import Message from '@ttn-lw/lib/components/message'
import { selectApplicationSiteTitle } from '@ttn-lw/lib/selectors/env'
+import sharedMessages from '@ttn-lw/lib/shared-messages'
import style from './code.styl'
const m = defineMessages({
- code: 'Authorization code',
codeDescription: 'Your authorization code is:',
- backToAccount: 'Back to {siteTitle}',
})
const siteTitle = selectApplicationSiteTitle()
@@ -47,7 +46,7 @@ const Code = () => {
-
+
{
diff --git a/pkg/webui/account/views/front-not-found/index.js b/pkg/webui/account/views/front-not-found/index.js
index 9b74065e81..1b8c107afa 100644
--- a/pkg/webui/account/views/front-not-found/index.js
+++ b/pkg/webui/account/views/front-not-found/index.js
@@ -1,4 +1,4 @@
-// Copyright © 2020 The Things Network Foundation, The Things Industries B.V.
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -13,7 +13,6 @@
// limitations under the License.
import React from 'react'
-import { defineMessages } from 'react-intl'
import Button from '@ttn-lw/components/button'
@@ -25,10 +24,7 @@ import style from '@account/views/front/front.styl'
import { selectApplicationSiteName, selectApplicationSiteTitle } from '@ttn-lw/lib/selectors/env'
import errorMessages from '@ttn-lw/lib/errors/error-messages'
import statusCodeMessages from '@ttn-lw/lib/errors/status-code-messages'
-
-const m = defineMessages({
- backToAccount: 'Back to {siteTitle}',
-})
+import sharedMessages from '@ttn-lw/lib/shared-messages'
const siteName = selectApplicationSiteName()
const siteTitle = selectApplicationSiteTitle()
@@ -51,7 +47,7 @@ const FrontNotFound = () => (
diff --git a/pkg/webui/account/views/login/index.js b/pkg/webui/account/views/login/index.js
index fdddbed39d..cfc7d379bb 100644
--- a/pkg/webui/account/views/login/index.js
+++ b/pkg/webui/account/views/login/index.js
@@ -44,8 +44,6 @@ const m = defineMessages({
createAccount: 'Create an account',
forgotPassword: 'Forgot password?',
loginToContinue: 'Please login to continue',
- loginFailed: 'Login failed',
- accountDeleted: 'Account deleted',
})
const appRoot = selectApplicationRootPath()
@@ -114,7 +112,7 @@ const Login = () => {
} else if (!next || (next !== appRoot && !Boolean(error))) {
info = m.loginToContinue
} else if ('account-deleted' in Query.parse(location.search)) {
- info = m.accountDeleted
+ info = sharedMessages.accountDeleted
}
return (
@@ -130,7 +128,7 @@ const Login = () => {
onSubmit={handleSubmit}
initialValues={initialValues}
error={error}
- errorTitle={m.loginFailed}
+ errorTitle={sharedMessages.loginFailed}
info={info}
validationSchema={validationSchema}
horizontal={false}
diff --git a/pkg/webui/account/views/oauth-client-add/index.js b/pkg/webui/account/views/oauth-client-add/index.js
index 33423c5758..1c2cf01027 100644
--- a/pkg/webui/account/views/oauth-client-add/index.js
+++ b/pkg/webui/account/views/oauth-client-add/index.js
@@ -15,7 +15,6 @@
import React from 'react'
import { useSelector } from 'react-redux'
import { Container, Col, Row } from 'react-grid-system'
-import { defineMessages } from 'react-intl'
import PageTitle from '@ttn-lw/components/page-title'
@@ -23,6 +22,8 @@ import RequireRequest from '@ttn-lw/lib/components/require-request'
import ClientAdd from '@account/containers/oauth-client-add'
+import sharedMessages from '@ttn-lw/lib/shared-messages'
+
import { getUserRights } from '@account/store/actions/user'
import {
@@ -32,10 +33,6 @@ import {
selectUserPseudoRights,
} from '@account/store/selectors/user'
-const m = defineMessages({
- addClient: 'Add OAuth client',
-})
-
const OAuthClientAddInner = () => {
const userId = useSelector(selectUserId)
const isAdmin = useSelector(selectUserIsAdmin)
@@ -44,7 +41,7 @@ const OAuthClientAddInner = () => {
return (
-
+
{
>
-
+
diff --git a/pkg/webui/account/views/token-login/index.js b/pkg/webui/account/views/token-login/index.js
index 3a502a8a6e..fab8cb9dbc 100644
--- a/pkg/webui/account/views/token-login/index.js
+++ b/pkg/webui/account/views/token-login/index.js
@@ -37,7 +37,6 @@ import sharedMessages from '@ttn-lw/lib/shared-messages'
const m = defineMessages({
loginToken: 'Login Token',
- loginFailed: 'Login failed',
})
const appRoot = selectApplicationRootPath()
@@ -97,7 +96,7 @@ const TokenLogin = () => {
onSubmit={handleSubmit}
initialValues={initialValues}
error={error}
- errorTitle={m.loginFailed}
+ errorTitle={sharedMessages.loginFailed}
validationSchema={validationSchema}
horizontal={false}
>
diff --git a/pkg/webui/components/breadcrumbs/context.js b/pkg/webui/components/breadcrumbs/context.js
index 6adf8c6770..ba6e6334a2 100644
--- a/pkg/webui/components/breadcrumbs/context.js
+++ b/pkg/webui/components/breadcrumbs/context.js
@@ -1,4 +1,4 @@
-// Copyright © 2019 The Things Network Foundation, The Things Industries B.V.
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,114 +12,44 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import React, { useContext, useEffect } from 'react'
-import bind from 'autobind-decorator'
+import React, { useContext, useEffect, useState } from 'react'
import PropTypes from '@ttn-lw/lib/prop-types'
const BreadcrumbsContext = React.createContext()
const { Provider, Consumer } = BreadcrumbsContext
-class BreadcrumbsProvider extends React.Component {
- static propTypes = {
- children: PropTypes.node.isRequired,
- }
-
- state = {
- breadcrumbs: [],
- }
+const BreadcrumbsProvider = ({ children }) => {
+ const [breadcrumbs, setBreadcrumbs] = useState([])
- @bind
- add(id, breadcrumb) {
- this.setState(prev => {
- const index = prev.breadcrumbs.findIndex(({ id: breadcrumbId }) => breadcrumbId === id)
+ const add = (id, breadcrumb) => {
+ setBreadcrumbs(prev => {
+ const index = prev.findIndex(({ id: breadcrumbId }) => breadcrumbId === id)
if (index === -1) {
- return {
- breadcrumbs: [...prev.breadcrumbs, { id, breadcrumb }].sort((a, b) =>
- a.id < b.id ? -1 : 1,
- ),
- }
+ return [...prev, { id, breadcrumb }].sort((a, b) => (a.id < b.id ? -1 : 1))
}
// Replace breadcrumb with existing id.
- return {
- breadcrumbs: [
- ...prev.breadcrumbs.slice(0, index),
- { id, breadcrumb },
- ...prev.breadcrumbs.slice(index + 1),
- ],
- }
+ return [...prev.slice(0, index), { id, breadcrumb }, ...prev.slice(index + 1)]
})
}
- @bind
- remove(id) {
- this.setState(prev => ({
- breadcrumbs: prev.breadcrumbs.filter(b => b.id !== id),
- }))
+ const remove = id => {
+ setBreadcrumbs(prev => prev.filter(b => b.id !== id))
}
- render() {
- const { children } = this.props
- const value = {
- add: this.add,
- remove: this.remove,
- breadcrumbs: this.state.breadcrumbs.map(b => b.breadcrumb),
- }
-
- return {children}
+ const value = {
+ add,
+ remove,
+ breadcrumbs: breadcrumbs.map(b => b.breadcrumb),
}
-}
-const withBreadcrumb = (id, element) => Component => {
- class BreadcrumbsConsumer extends React.Component {
- static propTypes = {
- add: PropTypes.func.isRequired,
- breadcrumb: PropTypes.oneOfType([PropTypes.func, PropTypes.element]).isRequired,
- remove: PropTypes.func.isRequired,
- }
-
- constructor(props) {
- super(props)
-
- this.add()
- }
-
- add() {
- const { add, breadcrumb } = this.props
-
- add(id, breadcrumb)
- }
-
- remove() {
- const { remove } = this.props
-
- remove(id)
- }
-
- componentWillUnmount() {
- this.remove()
- }
-
- render() {
- const { add, remove, breadcrumb, ...rest } = this.props
-
- return
- }
- }
-
- const BreadcrumbsConsumerContainer = props => (
-
- {({ add, remove }) => (
-
- )}
-
- )
-
- return BreadcrumbsConsumerContainer
+ return {children}
}
-withBreadcrumb.displayName = 'withBreadcrumb'
+BreadcrumbsProvider.propTypes = {
+ children: PropTypes.node.isRequired,
+}
const useBreadcrumbs = (id, element) => {
const context = useContext(BreadcrumbsContext)
@@ -133,10 +63,4 @@ const useBreadcrumbs = (id, element) => {
}, [])
}
-export {
- Consumer as BreadcrumbsConsumer,
- BreadcrumbsProvider,
- withBreadcrumb,
- BreadcrumbsContext,
- useBreadcrumbs,
-}
+export { Consumer as BreadcrumbsConsumer, BreadcrumbsProvider, BreadcrumbsContext, useBreadcrumbs }
diff --git a/pkg/webui/components/checkbox/checkbox.js b/pkg/webui/components/checkbox/checkbox.js
index a83adf674d..488322e92d 100644
--- a/pkg/webui/components/checkbox/checkbox.js
+++ b/pkg/webui/components/checkbox/checkbox.js
@@ -60,7 +60,7 @@ const Checkbox = props => {
event => {
const { checked } = event.target
- if (hasValue && !context) {
+ if (!hasValue && !context) {
setChecked(checked)
}
diff --git a/pkg/webui/components/checkbox/group/index.js b/pkg/webui/components/checkbox/group/index.js
index 1cd09a084f..25b63e36da 100644
--- a/pkg/webui/components/checkbox/group/index.js
+++ b/pkg/webui/components/checkbox/group/index.js
@@ -22,9 +22,25 @@ import style from './group.styl'
export const CheckboxGroupContext = React.createContext()
const CheckboxGroup = props => {
- const { children, className, horizontal, onChange, disabled, onFocus, onBlur, ...rest } = props
- const hasValue = 'value' in rest
- const [value, setValue] = React.useState(hasValue ? rest.value : rest.initialValue || {})
+ const {
+ children,
+ className,
+ horizontal,
+ onChange,
+ disabled,
+ onFocus,
+ onBlur,
+ value: valueProp,
+ ...rest
+ } = props
+ const hasValue = Boolean(valueProp)
+ const [value, setValue] = React.useState(hasValue ? valueProp : rest.initialValue || {})
+
+ React.useEffect(() => {
+ if (valueProp) {
+ setValue(valueProp || {})
+ }
+ }, [valueProp])
const handleCheckboxChange = useCallback(
async event => {
diff --git a/pkg/webui/components/file-input/index.js b/pkg/webui/components/file-input/index.js
index e071ec82c7..9978046666 100644
--- a/pkg/webui/components/file-input/index.js
+++ b/pkg/webui/components/file-input/index.js
@@ -35,7 +35,6 @@ const m = defineMessages({
noFileSelected: 'No file selected',
fileProvided: 'A file has been provided',
tooBig: 'The selected file is too large',
- remove: 'Remove',
})
const defaultDataTransform = content => content.replace(/^.*;base64,/, '')
diff --git a/pkg/webui/components/form/field/index.js b/pkg/webui/components/form/field/index.js
index cef8c33795..46b5764992 100644
--- a/pkg/webui/components/form/field/index.js
+++ b/pkg/webui/components/form/field/index.js
@@ -192,7 +192,7 @@ const FormField = props => {
const hasTooltip = Boolean(tooltipId)
const hasTitle = Boolean(title)
const showError = touched && !isEmpty(errors)
- const showWarning = isEmpty(errors) && Boolean(warning)
+ const showWarning = !showError && Boolean(warning)
const error = showError && errors[0]
const showDescription = !showError && !showWarning && Boolean(description)
const tooltipIcon = hasTooltip ? : null
diff --git a/pkg/webui/components/form/field/stories/shared.js b/pkg/webui/components/form/field/stories/shared.js
index f9f5f71fc7..56c98c0b1c 100644
--- a/pkg/webui/components/form/field/stories/shared.js
+++ b/pkg/webui/components/form/field/stories/shared.js
@@ -1,4 +1,4 @@
-// Copyright © 2021 The Things Network Foundation, The Things Industries B.V.
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,12 +12,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-/* eslint-disable react/prop-types */
-
-import React from 'react'
+import React, { useEffect, useRef } from 'react'
import { action } from '@storybook/addon-actions'
import Yup from '@ttn-lw/lib/yup'
+import PropTypes from '@ttn-lw/lib/prop-types'
import Form from '../..'
@@ -38,28 +37,31 @@ const validationSchema = Yup.object().shape({
error: errorSchema,
})
-class FieldsWrapperExample extends React.Component {
- form = React.createRef()
-
- componentDidMount() {
- if (this.form.current) {
- this.form.current.setFieldError('error', 'Something went wrong.')
- this.form.current.setFieldTouched('error')
+const FieldsWrapperExample = props => {
+ const formRef = useRef(null)
+ const { initialValues, children } = props
+ useEffect(() => {
+ if (formRef.current) {
+ formRef.current.setFieldError('error', 'Something went wrong.')
+ formRef.current.setFieldTouched('error')
}
- }
+ }, [])
+
+ return (
+
+ )
+}
- render() {
- return (
-
- )
- }
+FieldsWrapperExample.propTypes = {
+ children: PropTypes.node.isRequired,
+ initialValues: PropTypes.shape({}).isRequired,
}
export { info, FieldsWrapperExample }
diff --git a/pkg/webui/components/input/byte.js b/pkg/webui/components/input/byte.js
index 3f0a0c2129..0cf440b053 100644
--- a/pkg/webui/components/input/byte.js
+++ b/pkg/webui/components/input/byte.js
@@ -55,139 +55,134 @@ const upper = str => str.toUpperCase()
const clean = str => (typeof str === 'string' ? str.replace(voidChars, '') : str)
-const ByteInput = ({
- onBlur,
- value,
- className,
- min,
- max,
- onChange,
- placeholder,
- showPerChar,
- unbounded,
- ...rest
-}) => {
- const onCopy = useCallback(evt => {
- const input = evt.target
- const selectedValue = input.value.substr(
- input.selectionStart,
- input.selectionEnd - input.selectionStart,
- )
- evt.clipboardData.setData('text/plain', clean(selectedValue))
- evt.preventDefault()
- }, [])
-
- const onPaste = useCallback(
- evt => {
- // Ignore empty pastes.
- if (evt?.clipboardData?.getData('text/plain')?.length === 0) {
- return
- }
- const val = evt.target.value
- const cleanedSelection = clean(
- val.substr(
- evt.target.selectionStart,
- Math.max(1, evt.target.selectionEnd - evt.target.selectionStart),
- ),
+const ByteInput = React.forwardRef(
+ (
+ { onBlur, value, className, min, max, onChange, placeholder, showPerChar, unbounded, ...rest },
+ ref,
+ ) => {
+ const onCopy = useCallback(evt => {
+ const input = evt.target
+ const selectedValue = input.value.substr(
+ input.selectionStart,
+ input.selectionEnd - input.selectionStart,
)
+ evt.clipboardData.setData('text/plain', clean(selectedValue))
+ evt.preventDefault()
+ }, [])
+
+ const onPaste = useCallback(
+ evt => {
+ // Ignore empty pastes.
+ if (evt?.clipboardData?.getData('text/plain')?.length === 0) {
+ return
+ }
+ const val = evt.target.value
+ const cleanedSelection = clean(
+ val.substr(
+ evt.target.selectionStart,
+ Math.max(1, evt.target.selectionEnd - evt.target.selectionStart),
+ ),
+ )
+
+ // To avoid the masked input from cutting off characters when the cursor
+ // is placed in the mask placeholders, the placeholder chars are removed before
+ // the paste is applied, unless the user made a selection to paste into.
+ // This will ensure a consistent pasting experience.
+ if (!unbounded && cleanedSelection === '') {
+ evt.target.value = val.replace(voidChars, '')
+ }
+ },
+ [unbounded],
+ )
- // To avoid the masked input from cutting off characters when the cursor
- // is placed in the mask placeholders, the placeholder chars are removed before
- // the paste is applied, unless the user made a selection to paste into.
- // This will ensure a consistent pasting experience.
- if (!unbounded && cleanedSelection === '') {
- evt.target.value = val.replace(voidChars, '')
- }
- },
- [unbounded],
- )
-
- const onChangeCallback = useCallback(
- evt => {
- const data = evt?.nativeEvent?.data
-
- // Due to the way that react-text-mask works, it is not possible to
- // store the cleaned value, since it would create ambiguity between
- // values like `AA` and `AA `. This causes backspaces to not work
- // if it targets the space character, since the deleted space would
- // be re-added right away. Hence, unbounded inputs need to remove
- // the space paddings manually.
- let newValue = unbounded ? evt.target.value : clean(evt.target.value)
-
- // Make sure values entered at the end of the input (with placeholders)
- // are added as expected. `selectionStart` cannot be used due to
- // inconsistent behavior on Android phones.
- if (
- evt.target.value.endsWith(PLACEHOLDER_CHAR) &&
- data &&
- hex.test(data) &&
- value === newValue
- ) {
- newValue += data
- }
-
- onChange({
- target: {
- name: evt.target.name,
- value: newValue,
- },
- })
- },
- [onChange, value, unbounded],
- )
-
- const onBlurCallback = useCallback(
- evt => {
- onBlur({
- relatedTarget: evt.relatedTarget,
- target: {
- name: evt.target.name,
- value: clean(evt.target.value),
- },
- })
- },
- [onBlur],
- )
-
- const onCut = useCallback(evt => {
- evt.preventDefault()
- // Recreate cut action by deleting and reusing copy handler.
- document.execCommand('copy')
- document.execCommand('delete')
- }, [])
-
- // Instead of calculating the max width dynamically, which leads to various issues
- // with pasting, it's better to use a high max value for unbounded inputs instead.
- const calculatedMax = max || 4096
-
- if (!unbounded && typeof max !== 'number') {
- warn(
- 'Byte input has been setup without `max` prop. Always use a max prop unless using `unbounded`',
+ const onChangeCallback = useCallback(
+ evt => {
+ const data = evt?.nativeEvent?.data
+
+ // Due to the way that react-text-mask works, it is not possible to
+ // store the cleaned value, since it would create ambiguity between
+ // values like `AA` and `AA `. This causes backspaces to not work
+ // if it targets the space character, since the deleted space would
+ // be re-added right away. Hence, unbounded inputs need to remove
+ // the space paddings manually.
+ let newValue = unbounded ? evt.target.value : clean(evt.target.value)
+
+ // Make sure values entered at the end of the input (with placeholders)
+ // are added as expected. `selectionStart` cannot be used due to
+ // inconsistent behavior on Android phones.
+ if (
+ evt.target.value.endsWith(PLACEHOLDER_CHAR) &&
+ data &&
+ hex.test(data) &&
+ value === newValue
+ ) {
+ newValue += data
+ }
+
+ onChange({
+ target: {
+ name: evt.target.name,
+ value: newValue,
+ },
+ })
+ },
+ [onChange, value, unbounded],
)
- }
- return (
-
- )
-}
+ const onBlurCallback = useCallback(
+ evt => {
+ onBlur({
+ relatedTarget: evt.relatedTarget,
+ target: {
+ name: evt.target.name,
+ value: clean(evt.target.value),
+ },
+ })
+ },
+ [onBlur],
+ )
+
+ const onCut = useCallback(evt => {
+ evt.preventDefault()
+ // Recreate cut action by deleting and reusing copy handler.
+ document.execCommand('copy')
+ document.execCommand('delete')
+ }, [])
+
+ // Instead of calculating the max width dynamically, which leads to various issues
+ // with pasting, it's better to use a high max value for unbounded inputs instead.
+ const calculatedMax = max || 4096
+
+ if (!unbounded && typeof max !== 'number') {
+ warn(
+ 'Byte input has been setup without `max` prop. Always use a max prop unless using `unbounded`',
+ )
+ }
+
+ return (
+
+ )
+ },
+)
ByteInput.propTypes = {
className: PropTypes.string,
diff --git a/pkg/webui/components/input/stories/shared.js b/pkg/webui/components/input/stories/shared.js
index 3e4350d296..5cdaf61735 100644
--- a/pkg/webui/components/input/stories/shared.js
+++ b/pkg/webui/components/input/stories/shared.js
@@ -14,33 +14,22 @@
/* eslint-disable react/prop-types, import/prefer-default-export */
-import React from 'react'
-import bind from 'autobind-decorator'
+import React, { useCallback, useState } from 'react'
import Input from '..'
-class Example extends React.Component {
- constructor(props) {
- super(props)
+const Example = props => {
+ const { value: initialValue, type, component: Component, ...rest } = props
- this.state = {
- value: props.value || '',
- }
- }
+ const [value, setValue] = useState(initialValue || '')
- @bind
- onChange(value) {
- this.setState({ value })
- }
+ const handleChangeInput = useCallback(newValue => {
+ setValue(newValue)
+ }, [])
- render() {
- const { type, component: Component, ...props } = this.props
- const { value } = this.state
+ const InputComponent = Component || Input
- const InputComponent = Component ? Component : Input
-
- return
- }
+ return
}
export { Example }
diff --git a/pkg/webui/components/key-value-map/entry.js b/pkg/webui/components/key-value-map/entry.js
index 05e25355df..b509198db9 100644
--- a/pkg/webui/components/key-value-map/entry.js
+++ b/pkg/webui/components/key-value-map/entry.js
@@ -12,12 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import React, { useCallback, useMemo } from 'react'
+import React, { useCallback, useMemo, useState } from 'react'
import { defineMessages } from 'react-intl'
import classnames from 'classnames'
import Button from '@ttn-lw/components/button'
+import sharedMessages from '@ttn-lw/lib/shared-messages'
import PropTypes from '@ttn-lw/lib/prop-types'
import style from './key-value-map.styl'
@@ -30,6 +31,7 @@ const Entry = ({
readOnly,
name,
value,
+ fieldValue,
index,
onRemoveButtonClick,
onChange,
@@ -39,12 +41,19 @@ const Entry = ({
valuePlaceholder,
keyPlaceholder,
additionalInputProps,
+ removeMessage,
+ distinctOptions,
+ atLeastOneEntry,
+ filterByTag,
}) => {
+ const [currentValue, setCurrentValue] = useState(value)
+ const [newOptions, setNewOptions] = useState(undefined)
+ const { options, ...additionalInputPropsRest } = additionalInputProps
const _getKeyInputName = useMemo(() => `${name}[${index}].key`, [index, name])
const _getValueInputName = useMemo(() => `${name}[${index}].value`, [index, name])
- const handleRemoveButtonClicked = useCallback(
+ const handleRemoveButtonClick = useCallback(
event => {
onRemoveButtonClick(index, event)
},
@@ -60,6 +69,7 @@ const Entry = ({
const handleValueChanged = useCallback(
newValue => {
+ setCurrentValue(newValue)
onChange(index, { value: newValue })
},
[index, onChange],
@@ -82,6 +92,25 @@ const Entry = ({
[onBlur, name, value, _getKeyInputName, _getValueInputName],
)
+ const handleOptionComposition = useCallback(() => {
+ let newOptions
+ if (currentValue) {
+ newOptions = options.filter(v => !fieldValue.includes(v.value) || v.value === currentValue)
+ } else {
+ newOptions = options.filter(v => !fieldValue.includes(v.value))
+ }
+
+ let taggedOptions = newOptions
+ if (fieldValue.length >= 2 && filterByTag) {
+ const selectedOption = options.find(v => v.value === fieldValue[0])
+ taggedOptions = newOptions.filter(v => selectedOption.tag === v.tag)
+ }
+
+ setNewOptions(taggedOptions)
+ }, [currentValue, options, fieldValue, filterByTag])
+
+ const showRemoveButton = atLeastOneEntry ? index !== 0 : true
+
return (
{!indexAsKey && (
@@ -107,25 +136,36 @@ const Entry = ({
type="text"
onChange={handleValueChanged}
onBlur={handleBlur}
+ onFocus={distinctOptions && options ? handleOptionComposition : undefined}
value={indexAsKey ? value : value.value}
readOnly={readOnly}
code
- {...additionalInputProps}
- />
-
+ {showRemoveButton && (
+
+ )}
)
}
Entry.propTypes = {
- additionalInputProps: PropTypes.shape({}).isRequired,
+ additionalInputProps: PropTypes.shape({
+ options: PropTypes.array,
+ }).isRequired,
+ atLeastOneEntry: PropTypes.bool,
+ distinctOptions: PropTypes.bool,
+ fieldValue: PropTypes.any,
+ filterByTag: PropTypes.bool,
index: PropTypes.number.isRequired,
indexAsKey: PropTypes.bool.isRequired,
inputElement: PropTypes.elementType.isRequired,
@@ -135,6 +175,7 @@ Entry.propTypes = {
onChange: PropTypes.func.isRequired,
onRemoveButtonClick: PropTypes.func.isRequired,
readOnly: PropTypes.bool,
+ removeMessage: PropTypes.message,
value: PropTypes.oneOfType([
PropTypes.shape({
key: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
@@ -148,6 +189,11 @@ Entry.propTypes = {
Entry.defaultProps = {
value: undefined,
readOnly: false,
+ removeMessage: sharedMessages.remove,
+ distinctOptions: false,
+ fieldValue: undefined,
+ atLeastOneEntry: false,
+ filterByTag: false,
}
export default Entry
diff --git a/pkg/webui/components/key-value-map/index.js b/pkg/webui/components/key-value-map/index.js
index 42900f0730..b908a8f6e9 100644
--- a/pkg/webui/components/key-value-map/index.js
+++ b/pkg/webui/components/key-value-map/index.js
@@ -31,6 +31,7 @@ const m = defineMessages({
const KeyValueMap = ({
addMessage,
+ removeMessage,
additionalInputProps,
className,
disabled,
@@ -43,6 +44,9 @@ const KeyValueMap = ({
onChange,
value,
valuePlaceholder,
+ distinctOptions,
+ atLeastOneEntry,
+ filterByTag,
}) => {
const handleEntryChange = useCallback(
(index, newValues) => {
@@ -76,11 +80,12 @@ const KeyValueMap = ({
{value &&
- value.map((value, index) => (
+ value.map((individualValue, index) => (
))}
@@ -111,8 +120,11 @@ const KeyValueMap = ({
KeyValueMap.propTypes = {
addMessage: PropTypes.message,
additionalInputProps: PropTypes.shape({}),
+ atLeastOneEntry: PropTypes.bool,
className: PropTypes.string,
disabled: PropTypes.bool,
+ distinctOptions: PropTypes.bool,
+ filterByTag: PropTypes.bool,
indexAsKey: PropTypes.bool,
inputElement: PropTypes.elementType,
isReadOnly: PropTypes.func,
@@ -120,6 +132,7 @@ KeyValueMap.propTypes = {
name: PropTypes.string.isRequired,
onBlur: PropTypes.func,
onChange: PropTypes.func,
+ removeMessage: PropTypes.message,
value: PropTypes.arrayOf(
PropTypes.oneOfType([
PropTypes.shape({
@@ -144,6 +157,10 @@ KeyValueMap.defaultProps = {
disabled: false,
isReadOnly: () => null,
inputElement: Input,
+ removeMessage: undefined,
+ distinctOptions: false,
+ atLeastOneEntry: false,
+ filterByTag: false,
}
export default KeyValueMap
diff --git a/pkg/webui/components/modal/modal.styl b/pkg/webui/components/modal/modal.styl
index 845b81c688..703e85eca1 100644
--- a/pkg/webui/components/modal/modal.styl
+++ b/pkg/webui/components/modal/modal.styl
@@ -136,6 +136,7 @@
margin-bottom: $cs.s
flex-direction: row
align-items: stretch
+ gap: 1rem
button:not(:last-child)
margin-right: 0
diff --git a/pkg/webui/components/profile-dropdown/index.js b/pkg/webui/components/profile-dropdown/index.js
index 31149e3437..1c69eee1ea 100644
--- a/pkg/webui/components/profile-dropdown/index.js
+++ b/pkg/webui/components/profile-dropdown/index.js
@@ -1,4 +1,4 @@
-// Copyright © 2019 The Things Network Foundation, The Things Industries B.V.
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,8 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import React from 'react'
-import bind from 'autobind-decorator'
+import React, { useCallback, useRef, useState } from 'react'
import classnames from 'classnames'
import Icon from '@ttn-lw/components/icon'
@@ -24,69 +23,41 @@ import PropTypes from '@ttn-lw/lib/prop-types'
import styles from './profile-dropdown.styl'
-export default class ProfileDropdown extends React.PureComponent {
- state = {
- expanded: false,
- }
+const ProfileDropdown = props => {
+ const [expanded, setExpanded] = useState(false)
+ const node = useRef(null)
+ const { userName, className, children, profilePicture, ...rest } = props
- @bind
- showDropdown() {
- document.addEventListener('mousedown', this.handleClickOutside)
- this.setState({ expanded: true })
- }
-
- @bind
- hideDropdown() {
- document.removeEventListener('mousedown', this.handleClickOutside)
- this.setState({ expanded: false })
- }
-
- @bind
- handleClickOutside(e) {
- if (!this.node.contains(e.target)) {
- this.hideDropdown()
- }
- }
-
- @bind
- toggleDropdown() {
- let { expanded } = this.state
- expanded = !expanded
- if (expanded) {
- this.showDropdown()
- } else {
- this.hideDropdown()
+ const handleClickOutside = useCallback(e => {
+ if (node.current && !node.current.contains(e.target)) {
+ setExpanded(false)
}
- }
-
- @bind
- ref(node) {
- this.node = node
- }
+ }, [])
- render() {
- const { userName, className, children, profilePicture, ...rest } = this.props
+ const toggleDropdown = useCallback(() => {
+ setExpanded(oldExpanded => {
+ const newState = !oldExpanded
+ if (newState) document.addEventListener('mousedown', handleClickOutside)
+ else document.removeEventListener('mousedown', handleClickOutside)
+ return newState
+ })
+ }, [handleClickOutside])
- return (
-
-
-
{userName}
-
- {this.state.expanded &&
{children} }
-
- )
- }
+ return (
+
+
+
{userName}
+
+ {expanded &&
{children} }
+
+ )
}
ProfileDropdown.propTypes = {
@@ -106,3 +77,5 @@ ProfileDropdown.defaultProps = {
className: undefined,
profilePicture: undefined,
}
+
+export default ProfileDropdown
diff --git a/pkg/webui/components/qr-modal-button/index.js b/pkg/webui/components/qr-modal-button/index.js
index ab66035cc1..4771b134e2 100644
--- a/pkg/webui/components/qr-modal-button/index.js
+++ b/pkg/webui/components/qr-modal-button/index.js
@@ -34,7 +34,6 @@ const QrScanDoc = (
)
const m = defineMessages({
- scanEndDevice: 'Scan end device QR code',
scanEndDeviceContinue: 'Please scan the QR code to continue. {qrScanDoc}',
invalidData:
'Invalid QR code data. Please note that only TR005 LoRaWAN® Device Identification QR Code can be scanned. Some devices have unrelated QR codes printed on them that cannot be used.',
@@ -81,7 +80,7 @@ const QRModalButton = props => {
onApprove={onApprove}
message={message}
modalData={{
- title: m.scanEndDevice,
+ title: sharedMessages.scanEndDevice,
children: modalData,
buttonMessage: m.apply,
approveButtonProps: {
diff --git a/pkg/webui/components/qr/input/video/index.js b/pkg/webui/components/qr/input/video/index.js
index f965f9672e..d08e614ce7 100644
--- a/pkg/webui/components/qr/input/video/index.js
+++ b/pkg/webui/components/qr/input/video/index.js
@@ -1,4 +1,4 @@
-// Copyright © 2022 The Things Network Foundation, The Things Industries B.V.
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -28,42 +28,118 @@ const m = defineMessages({
switchCamera: 'Switch camera',
})
-const Video = props => {
+const Camera = props => {
const { onRead, setError, setCapture } = props
- const videoRef = createRef()
- const [stream, setStream] = useState(undefined)
- const [devices, setDevices] = useState([])
const [cameras, setCameras] = useState([])
- const isMobile = window.innerWidth <= 768
+ const [deviceId, setDeviceId] = useState(undefined)
+
+ const [hasFrontCamera, setHasFrontCamera] = useState(false)
+ const [hasBackCamera, setHasBackCamera] = useState(false)
+
+ const handleSwitchCamera = useCallback(() => {
+ // The majority of mobile device will have labeled front and back cameras.
+ const currentCamera = cameras.find(device => device.deviceId === deviceId)
+
+ if (hasFrontCamera && hasBackCamera) {
+ if (currentCamera.label.toLowerCase().includes('back')) {
+ const frontCamera = cameras.find(device => device.label.toLowerCase().includes('front'))
+ setDeviceId(frontCamera.deviceId)
+ }
+
+ if (currentCamera.label.toLowerCase().includes('front')) {
+ const backCamera = cameras.find(device => device.label.toLowerCase().includes('back'))
+ setDeviceId(backCamera.deviceId)
+ }
+ }
+ }, [cameras, deviceId, hasBackCamera, hasFrontCamera])
+
+ const handleCameraCycle = useCallback(() => {
+ // If there are more than one camera then cycle through them, only if there are no camera clearly labeled and back and front
+ if (cameras.length > 1) {
+ const currentIndex = cameras.findIndex(device => device.deviceId === deviceId)
+
+ const nextDevice = currentIndex !== -1 ? cameras[(currentIndex + 1) % cameras.length] : null
+ setDeviceId(nextDevice.deviceId)
+ }
+ }, [cameras, deviceId])
const getDevices = useCallback(async () => {
- if (!devices.length) {
- const enumerateDevices = await navigator.mediaDevices.enumerateDevices()
- setDevices(enumerateDevices)
+ // Depending on your device you may have access to this list on initial load
+ // If you do not have access to this list then you will need to request a stream to get the list
+ const enumerateDevices = await navigator.mediaDevices.enumerateDevices()
+ const videoInputs = enumerateDevices.filter(device => device.kind === 'videoinput')
+
+ if (videoInputs.length !== cameras.length) {
+ setCameras(videoInputs)
}
- }, [devices.length])
-
- const getStream = useCallback(async () => {
- if (devices.length && !stream) {
- const ua = navigator.userAgent.toLowerCase()
- const cameras = devices.filter(device => device.kind === 'videoinput')
- setCameras(cameras)
- let rearCamera = cameras.find(device => device.label.toLowerCase().includes('back'))
- if (!rearCamera) {
- rearCamera = cameras[1] ?? cameras[0]
- }
- const videoMode =
- cameras.length > 1
- ? ua.indexOf('safari') !== -1 && ua.indexOf('chrome') === -1
- ? { facingMode: { exact: 'environment' } }
- : { deviceId: rearCamera.deviceId }
- : { facingMode: 'environment' }
+ }, [cameras])
+
+ const setDeviceIdFromStream = useCallback(userStream => {
+ const videoTracks = userStream.getVideoTracks()
+
+ if (videoTracks.length > 0) {
+ const { deviceId } = videoTracks[0].getSettings()
+ setDeviceId(deviceId)
+ }
+ }, [])
+
+ useEffect(() => {
+ setHasFrontCamera(cameras.some(device => device.label.toLowerCase().includes('front')))
+ setHasBackCamera(cameras.some(device => device.label.toLowerCase().includes('back')))
+ }, [cameras])
+
+ return (
+ <>
+ {hasFrontCamera && hasBackCamera ? (
+
+ ) : (
+ cameras.length > 1 && (
+
+ )
+ )}
+
+
+ >
+ )
+}
+
+Camera.propTypes = {
+ onRead: PropTypes.func.isRequired,
+ setCapture: PropTypes.func.isRequired,
+ setError: PropTypes.func.isRequired,
+}
+const Stream = props => {
+ const { deviceId, getDevices, setDeviceIdFromStream, onRead, setCapture, setError } = props
+ const [stream, setStream] = useState(undefined)
+
+ useEffect(() => {
+ const getStream = async () => {
+ // Initially request the stream with the default camera for facing mode environment
+ // if device id is set then create stream with that device id and display video
try {
- const userStream = await navigator.mediaDevices.getUserMedia({
- video: videoMode ? { ...videoMode } : { facingMode: 'environment' },
- })
- setStream(userStream)
+ if (!deviceId) {
+ const userStream = await navigator.mediaDevices.getUserMedia({
+ video: { facingMode: 'environment' },
+ })
+ // After requesting the stream, get the devices again as we now have permission to see all devices
+ getDevices()
+ // On initial request set the device id from the stream, this should rerender this component
+ setDeviceIdFromStream(userStream)
+ } else {
+ const userStream = await navigator.mediaDevices.getUserMedia({
+ video: { deviceId },
+ })
+ // Only set the stream if the device id is set
+ setStream(userStream)
+ }
} catch (error) {
if (error instanceof DOMException && error.name === 'NotAllowedError') {
setCapture(false)
@@ -73,43 +149,29 @@ const Video = props => {
}
}
}
- }, [devices, setCapture, setError, stream])
-
- const switchStream = useCallback(async () => {
- if (stream === { facingMode: 'environment' }) {
- const userStream = await navigator.mediaDevices.getUserMedia({
- video: { facingMode: 'user' },
- })
- setStream(userStream)
- } else if (stream === { facingMode: 'user' }) {
- const userStream = await navigator.mediaDevices.getUserMedia({
- video: { facingMode: 'environment' },
- })
- setStream(userStream)
- } else if ('deviceId' in stream) {
- const indexOfCurrentDevice = cameras.findIndex(camera => camera.deviceId === stream.deviceId)
- // The first item will be taken from the beginning of the array after the last item.
- const nextIndex = ++indexOfCurrentDevice % cameras.length
- const device =
- cameras.length === 2
- ? cameras.find((_, i) => i !== indexOfCurrentDevice)
- : cameras[nextIndex]
- const userStream = await navigator.mediaDevices.getUserMedia({
- video: { deviceId: device.deviceId },
- })
- setStream(userStream)
- }
- }, [cameras, stream])
- useEffect(() => {
- getDevices()
getStream()
- return () => {
- if (stream) {
- stream.getTracks().map(t => t.stop())
- }
- }
- }, [devices, getDevices, getStream, stream])
+ }, [deviceId, getDevices, setCapture, setDeviceIdFromStream, setError])
+
+ return
+}
+
+Stream.propTypes = {
+ deviceId: PropTypes.string,
+ getDevices: PropTypes.func.isRequired,
+ onRead: PropTypes.func.isRequired,
+ setCapture: PropTypes.func.isRequired,
+ setDeviceIdFromStream: PropTypes.func.isRequired,
+ setError: PropTypes.func.isRequired,
+}
+
+Stream.defaultProps = {
+ deviceId: undefined,
+}
+
+const Video = props => {
+ const { stream, onRead } = props
+ const videoRef = createRef()
const handleVideoFrame = useCallback(
video => {
@@ -128,39 +190,46 @@ const Video = props => {
)
useEffect(() => {
- if (devices.length && stream) {
+ if (stream) {
const video = videoRef.current
video.srcObject = stream
handleVideoFrame(video)
}
- }, [devices, handleVideoFrame, stream, videoRef])
- return devices.length && stream ? (
+ return () => {
+ // On android devices if you do not stop the tracks then the camera will error
+ if (stream) {
+ stream.getTracks().forEach(track => {
+ track.stop()
+ })
+ }
+ }
+ }, [handleVideoFrame, stream, videoRef])
+
+ return (
<>
-
- {cameras.length > 1 && isMobile && (
-
+ {stream ? (
+
+ ) : (
+
+
+
)}
>
- ) : (
-
-
-
)
}
Video.propTypes = {
onRead: PropTypes.func.isRequired,
- setCapture: PropTypes.func.isRequired,
- setError: PropTypes.func.isRequired,
stream: PropTypes.shape({
active: PropTypes.bool,
+ getTracks: PropTypes.func,
}),
}
@@ -168,4 +237,4 @@ Video.defaultProps = {
stream: undefined,
}
-export default Video
+export default Camera
diff --git a/pkg/webui/components/qr/qr.styl b/pkg/webui/components/qr/qr.styl
index 6eb2b3d991..e7cd367766 100644
--- a/pkg/webui/components/qr/qr.styl
+++ b/pkg/webui/components/qr/qr.styl
@@ -20,6 +20,9 @@
align-items: center
justify-content: center
position: relative
+ +media-query($bp.s)
+ background: none
+ align-items: start
.capture
background: $c-backdrop
diff --git a/pkg/webui/components/qr/require-permission.js b/pkg/webui/components/qr/require-permission.js
index 30a83ff502..59e0749992 100644
--- a/pkg/webui/components/qr/require-permission.js
+++ b/pkg/webui/components/qr/require-permission.js
@@ -28,7 +28,6 @@ import style from './qr.styl'
const m = defineMessages({
permissionDeniedError: 'Permission Denied: Please allow access to your camera or upload a photo',
fetchingPermission: 'Please set camera permissions',
- uploadImage: 'Upload an image',
})
const RequirePermission = props => {
diff --git a/pkg/webui/components/tag/group/index.js b/pkg/webui/components/tag/group/index.js
index ff7ab08003..779f488c86 100644
--- a/pkg/webui/components/tag/group/index.js
+++ b/pkg/webui/components/tag/group/index.js
@@ -1,4 +1,4 @@
-// Copyright © 2019 The Things Network Foundation, The Things Industries B.V.
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,9 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import React from 'react'
+import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import classnames from 'classnames'
-import bind from 'autobind-decorator'
import Tooltip from '@ttn-lw/components/tooltip'
@@ -28,97 +27,62 @@ const measureWidth = element => {
if (!element) {
return 0
}
-
- return element.current.clientWidth
+ return element.clientWidth
}
-// The width in pixels for the left tag.
const LEFT_TAG_WIDTH = 40
-// The space between the tags.
const TAG_SPACE_WIDTH = 3
-class TagGroup extends React.Component {
- static propTypes = {
- className: PropTypes.string,
- tagMaxWidth: PropTypes.number.isRequired,
- tags: PropTypes.arrayOf(PropTypes.shape(Tag.PropTypes)).isRequired,
- }
-
- static defaultProps = {
- className: undefined,
- }
-
- constructor(props) {
- super(props)
-
- this.state = {
- left: 0,
- }
+const TagGroup = ({ className, tagMaxWidth, tags }) => {
+ const [left, setLeft] = useState(0)
+ const element = useRef(null)
- this.element = React.createRef()
- }
-
- componentDidMount() {
- window.addEventListener('resize', this.handleWindowResize)
-
- this.handleWindowResize()
- }
-
- componentDidUpdate(prevProps) {
- const props = this.props
-
- // Calculate fit on any props change.
- if (prevProps.tags !== props.tags) {
- this.checkTagsFit()
- }
- }
-
- checkTagsFit() {
- this.handleWindowResize()
- }
-
- componentWillUnmount() {
- window.removeEventListener('resize', this.handleWindowResize)
- }
-
- @bind
- handleWindowResize() {
- const { tags, tagMaxWidth } = this.props
-
- const containerWidth = measureWidth(this.element)
+ const handleWindowResize = useCallback(() => {
+ const containerWidth = measureWidth(element.current)
const totalTagCount = tags.length
const possibleFitCount = Math.floor(containerWidth / tagMaxWidth) || 1
- // Count for the left tag and paddings between tags.
const leftTagWidth = totalTagCount !== possibleFitCount ? LEFT_TAG_WIDTH : 0
const spaceWidth = possibleFitCount > 1 ? possibleFitCount * TAG_SPACE_WIDTH : 0
const finalAvailableWidth = containerWidth - leftTagWidth - spaceWidth
const finalLeft = Math.floor(finalAvailableWidth / tagMaxWidth) || 1
- this.setState({
- left: totalTagCount - finalLeft,
- })
- }
+ setLeft(totalTagCount - finalLeft)
+ }, [tagMaxWidth, tags.length])
- render() {
- const { className, tags } = this.props
- const { left } = this.state
-
- const ts = tags.slice(0, tags.length - left)
- const leftGroup =
{tags.slice(tags.length - left)}
-
- return (
-
- {ts}
- {left > 0 && (
-
-
-
- )}
-
- )
- }
+ useEffect(() => {
+ window.addEventListener('resize', handleWindowResize)
+ handleWindowResize()
+
+ return () => {
+ window.removeEventListener('resize', handleWindowResize)
+ }
+ }, [handleWindowResize, tags])
+
+ const ts = useMemo(() => tags.slice(0, tags.length - left), [left, tags])
+ const leftGroup =
{tags.slice(tags.length - left)}
+
+ return (
+
+ {ts}
+ {left > 0 && (
+
+
+
+ )}
+
+ )
+}
+
+TagGroup.propTypes = {
+ className: PropTypes.string,
+ tagMaxWidth: PropTypes.number.isRequired,
+ tags: PropTypes.arrayOf(PropTypes.shape(Tag.PropTypes)).isRequired,
+}
+
+TagGroup.defaultProps = {
+ className: undefined,
}
export default TagGroup
diff --git a/pkg/webui/console.js b/pkg/webui/console.js
index b68777a2d6..fdba93024f 100644
--- a/pkg/webui/console.js
+++ b/pkg/webui/console.js
@@ -23,7 +23,6 @@ import sentryConfig from '@ttn-lw/constants/sentry'
import { BreadcrumbsProvider } from '@ttn-lw/components/breadcrumbs/context'
import Header from '@ttn-lw/components/header'
-import { EnvProvider } from '@ttn-lw/lib/components/env'
import { ErrorView } from '@ttn-lw/lib/components/error-view'
import { FullViewError } from '@ttn-lw/lib/components/full-view-error'
import Init from '@ttn-lw/lib/components/init'
@@ -33,7 +32,6 @@ import Logo from '@console/containers/logo'
import App from '@console/views/app'
-import env from '@ttn-lw/lib/env'
import { selectApplicationRootPath, selectSentryDsnConfig } from '@ttn-lw/lib/selectors/env'
import createStore from './console/store'
@@ -58,17 +56,15 @@ const errorRender = error => (
DOM.render(
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
,
rootElement,
)
diff --git a/pkg/webui/console/components/default-routing-policy-form/index.js b/pkg/webui/console/components/default-routing-policy-form/index.js
new file mode 100644
index 0000000000..ce33d11b2a
--- /dev/null
+++ b/pkg/webui/console/components/default-routing-policy-form/index.js
@@ -0,0 +1,118 @@
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import React, { useCallback, useState } from 'react'
+import { Col, Row } from 'react-grid-system'
+import { defineMessages } from 'react-intl'
+
+import Form, { useFormContext } from '@ttn-lw/components/form'
+import Checkbox from '@ttn-lw/components/checkbox'
+import Radio from '@ttn-lw/components/radio-button'
+
+import Message from '@ttn-lw/lib/components/message'
+
+import sharedMessages from '@ttn-lw/lib/shared-messages'
+
+import policyMessages from '@console/lib/packet-broker/messages'
+
+const m = defineMessages({
+ doNotUseADefaultPolicy: 'Do not use a default routing policy for this network',
+})
+
+const useDefaultEncode = val => val === 'default'
+const useDefaultDecode = val => (val ? 'default' : 'no-default')
+
+const DefaultRoutingPolicyForm = () => {
+ const { values } = useFormContext()
+ const [useDefault, setUseDefault] = useState(values._use_default_policy || false)
+ const handlePolicySourceChange = useCallback(setUseDefault, [setUseDefault])
+
+ return (
+
+
+
+
+
+
+
+ {useDefault && (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ )}
+
+ )
+}
+
+export default DefaultRoutingPolicyForm
diff --git a/pkg/webui/console/components/device-import-form/index.js b/pkg/webui/console/components/device-import-form/index.js
index bcbb6ca42c..5eb629adc0 100644
--- a/pkg/webui/console/components/device-import-form/index.js
+++ b/pkg/webui/console/components/device-import-form/index.js
@@ -53,7 +53,6 @@ const m = defineMessages({
formatInfo: 'Format information',
selectAFile: 'Please select a template file',
fileInfoPlaceholder: 'Please select a template format',
- claiming: 'Claiming',
setClaimAuthCode: 'Set claim authentication code',
targetedComponents: 'Targeted components',
advancedSectionTitle: 'Advanced end device claiming settings',
@@ -143,7 +142,7 @@ const DeviceBulkCreateFormInner = props => {
{
- const appId = selectSelectedApplicationId(state)
- const devId = selectSelectedDeviceId(state)
- const device = selectSelectedDevice(state)
- const skipPayloadCrypto = selectApplicationLinkSkipPayloadCrypto(state)
-
- return {
- appId,
- devId,
- device,
- downlinkQueue: tts.Applications.Devices.DownlinkQueue,
- skipPayloadCrypto,
- }
-}
-
-export default DownlinkForm => connect(mapStateToProps)(DownlinkForm)
diff --git a/pkg/webui/console/components/downlink-form/downlink-form.js b/pkg/webui/console/components/downlink-form/downlink-form.js
deleted file mode 100644
index e7f196a172..0000000000
--- a/pkg/webui/console/components/downlink-form/downlink-form.js
+++ /dev/null
@@ -1,207 +0,0 @@
-// Copyright © 2020 The Things Network Foundation, The Things Industries B.V.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import React, { useState, useCallback } from 'react'
-import { defineMessages } from 'react-intl'
-
-import Notification from '@ttn-lw/components/notification'
-import SubmitButton from '@ttn-lw/components/submit-button'
-import RadioButton from '@ttn-lw/components/radio-button'
-import Checkbox from '@ttn-lw/components/checkbox'
-import Input from '@ttn-lw/components/input'
-import SubmitBar from '@ttn-lw/components/submit-bar'
-import toast from '@ttn-lw/components/toast'
-import Form from '@ttn-lw/components/form'
-import CodeEditor from '@ttn-lw/components/code-editor'
-
-import IntlHelmet from '@ttn-lw/lib/components/intl-helmet'
-
-import Yup from '@ttn-lw/lib/yup'
-import PropTypes from '@ttn-lw/lib/prop-types'
-import sharedMessages from '@ttn-lw/lib/shared-messages'
-
-import { hexToBase64 } from '@console/lib/bytes'
-
-const m = defineMessages({
- insertMode: 'Insert Mode',
- payloadType: 'Payload type',
- bytes: 'Bytes',
- replace: 'Replace downlink queue',
- push: 'Push to downlink queue (append)',
- confirmedDownlink: 'Confirmed downlink',
- scheduleDownlink: 'Schedule downlink',
- downlinkSuccess: 'Downlink scheduled',
- bytesPayloadDescription: 'The desired payload bytes of the downlink message',
- jsonPayloadDescription: 'The decoded payload of the downlink message',
- invalidSessionWarning:
- 'Downlinks can only be scheduled for end devices with a valid session. Please make sure your end device is properly connected to the network.',
-})
-
-const validationSchema = Yup.object({
- _mode: Yup.string().oneOf(['replace', 'push']).required(sharedMessages.validateRequired),
- _payload_type: Yup.string().oneOf(['bytes', 'json']),
- f_port: Yup.number()
- .min(1, Yup.passValues(sharedMessages.validateNumberGte))
- .max(223, Yup.passValues(sharedMessages.validateNumberLte))
- .required(sharedMessages.validateRequired),
- confirmed: Yup.bool().required(),
- frm_payload: Yup.string().when('_payload_type', {
- is: type => type === 'bytes',
- then: schema =>
- schema.test(
- 'len',
- Yup.passValues(sharedMessages.validateHexLength),
- val => !Boolean(val) || val.length % 3 === 0,
- ),
- otherwise: schema => schema.strip(),
- }),
- decoded_payload: Yup.string().when('_payload_type', {
- is: type => type === 'json',
- then: schema =>
- schema.test('valid-json', sharedMessages.validateJson, json => {
- try {
- JSON.parse(json)
- return true
- } catch (e) {
- return false
- }
- }),
- otherwise: schema => schema.strip(),
- }),
-})
-
-const initialValues = {
- _mode: 'replace',
- _payload_type: 'bytes',
- f_port: 1,
- confirmed: false,
- frm_payload: '',
- decoded_payload: '',
-}
-
-const DownlinkForm = ({ appId, devId, device, downlinkQueue, skipPayloadCrypto }) => {
- const [payloadType, setPayloadType] = React.useState('bytes')
- const [error, setError] = useState('')
-
- const handleSubmit = useCallback(
- async (vals, { setSubmitting, resetForm }) => {
- const { _mode, _payload_type, ...values } = validationSchema.cast(vals)
- try {
- if (_payload_type === 'bytes') {
- values.frm_payload = hexToBase64(values.frm_payload)
- }
-
- if (_payload_type === 'json') {
- values.decoded_payload = JSON.parse(values.decoded_payload)
- }
-
- await downlinkQueue[_mode](appId, devId, [values])
- toast({
- title: sharedMessages.success,
- type: toast.types.SUCCESS,
- message: m.downlinkSuccess,
- })
- setSubmitting(false)
- } catch (err) {
- setError(err)
- resetForm({ values: vals })
- }
- },
- [appId, devId, downlinkQueue],
- )
-
- const validSession = device.session || device.pending_session
- const payloadCryptoSkipped = device.skip_payload_crypto_override ?? skipPayloadCrypto
- const deviceSimulationDisabled = !validSession || payloadCryptoSkipped
-
- return (
- <>
- {payloadCryptoSkipped && (
-
- )}
- {!validSession && }
-
-
-
-
-
-
-
-
-
-
-
- {payloadType === 'bytes' ? (
-
- ) : (
-
- )}
-
-
-
-
-
- >
- )
-}
-
-DownlinkForm.propTypes = {
- appId: PropTypes.string.isRequired,
- devId: PropTypes.string.isRequired,
- device: PropTypes.device.isRequired,
- downlinkQueue: PropTypes.shape({
- list: PropTypes.func.isRequired,
- push: PropTypes.func.isRequired,
- replace: PropTypes.func.isRequired,
- }).isRequired,
- skipPayloadCrypto: PropTypes.bool.isRequired,
-}
-
-export default DownlinkForm
diff --git a/pkg/webui/console/components/downlink-form/index.js b/pkg/webui/console/components/downlink-form/index.js
index de4f69e297..413aba6b65 100644
--- a/pkg/webui/console/components/downlink-form/index.js
+++ b/pkg/webui/console/components/downlink-form/index.js
@@ -12,9 +12,199 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import DownlinkForm from './downlink-form'
-import connect from './connect'
+import React, { useState, useCallback } from 'react'
+import { defineMessages } from 'react-intl'
+import { useSelector } from 'react-redux'
-const ConnectedDownlinkForm = connect(DownlinkForm)
+import tts from '@console/api/tts'
-export { ConnectedDownlinkForm as default, DownlinkForm }
+import Notification from '@ttn-lw/components/notification'
+import SubmitButton from '@ttn-lw/components/submit-button'
+import RadioButton from '@ttn-lw/components/radio-button'
+import Checkbox from '@ttn-lw/components/checkbox'
+import Input from '@ttn-lw/components/input'
+import SubmitBar from '@ttn-lw/components/submit-bar'
+import toast from '@ttn-lw/components/toast'
+import Form from '@ttn-lw/components/form'
+import CodeEditor from '@ttn-lw/components/code-editor'
+
+import IntlHelmet from '@ttn-lw/lib/components/intl-helmet'
+
+import Yup from '@ttn-lw/lib/yup'
+import sharedMessages from '@ttn-lw/lib/shared-messages'
+
+import { hexToBase64 } from '@console/lib/bytes'
+
+import {
+ selectApplicationLinkSkipPayloadCrypto,
+ selectSelectedApplicationId,
+} from '@console/store/selectors/applications'
+import { selectSelectedDevice, selectSelectedDeviceId } from '@console/store/selectors/devices'
+
+const m = defineMessages({
+ insertMode: 'Insert Mode',
+ payloadType: 'Payload type',
+ bytes: 'Bytes',
+ replace: 'Replace downlink queue',
+ push: 'Push to downlink queue (append)',
+ scheduleDownlink: 'Schedule downlink',
+ downlinkSuccess: 'Downlink scheduled',
+ bytesPayloadDescription: 'The desired payload bytes of the downlink message',
+ jsonPayloadDescription: 'The decoded payload of the downlink message',
+ invalidSessionWarning:
+ 'Downlinks can only be scheduled for end devices with a valid session. Please make sure your end device is properly connected to the network.',
+})
+
+const validationSchema = Yup.object({
+ _mode: Yup.string().oneOf(['replace', 'push']).required(sharedMessages.validateRequired),
+ _payload_type: Yup.string().oneOf(['bytes', 'json']),
+ f_port: Yup.number()
+ .min(1, Yup.passValues(sharedMessages.validateNumberGte))
+ .max(223, Yup.passValues(sharedMessages.validateNumberLte))
+ .required(sharedMessages.validateRequired),
+ confirmed: Yup.bool().required(),
+ frm_payload: Yup.string().when('_payload_type', {
+ is: type => type === 'bytes',
+ then: schema =>
+ schema.test(
+ 'len',
+ Yup.passValues(sharedMessages.validateHexLength),
+ val => !Boolean(val) || val.length % 3 === 0,
+ ),
+ otherwise: schema => schema.strip(),
+ }),
+ decoded_payload: Yup.string().when('_payload_type', {
+ is: type => type === 'json',
+ then: schema =>
+ schema.test('valid-json', sharedMessages.validateJson, json => {
+ try {
+ JSON.parse(json)
+ return true
+ } catch (e) {
+ return false
+ }
+ }),
+ otherwise: schema => schema.strip(),
+ }),
+})
+
+const initialValues = {
+ _mode: 'replace',
+ _payload_type: 'bytes',
+ f_port: 1,
+ confirmed: false,
+ frm_payload: '',
+ decoded_payload: '',
+}
+
+const DownlinkForm = () => {
+ const [payloadType, setPayloadType] = React.useState('bytes')
+ const [error, setError] = useState('')
+ const appId = useSelector(selectSelectedApplicationId)
+ const devId = useSelector(selectSelectedDeviceId)
+ const device = useSelector(selectSelectedDevice)
+ const skipPayloadCrypto = useSelector(selectApplicationLinkSkipPayloadCrypto)
+
+ const handleSubmit = useCallback(
+ async (vals, { setSubmitting, resetForm }) => {
+ const { _mode, _payload_type, ...values } = validationSchema.cast(vals)
+ try {
+ if (_payload_type === 'bytes') {
+ values.frm_payload = hexToBase64(values.frm_payload)
+ }
+
+ if (_payload_type === 'json') {
+ values.decoded_payload = JSON.parse(values.decoded_payload)
+ }
+
+ await tts.Applications.Devices.DownlinkQueue[_mode](appId, devId, [values])
+ toast({
+ title: sharedMessages.success,
+ type: toast.types.SUCCESS,
+ message: m.downlinkSuccess,
+ })
+ setSubmitting(false)
+ } catch (err) {
+ setError(err)
+ resetForm({ values: vals })
+ }
+ },
+ [appId, devId],
+ )
+
+ const validSession = device.session || device.pending_session
+ const payloadCryptoSkipped = device.skip_payload_crypto_override ?? skipPayloadCrypto
+ const deviceSimulationDisabled = !validSession || payloadCryptoSkipped
+
+ return (
+ <>
+ {payloadCryptoSkipped && (
+
+ )}
+ {!validSession && }
+
+
+
+
+
+
+
+
+
+
+
+ {payloadType === 'bytes' ? (
+
+ ) : (
+
+ )}
+
+
+
+
+
+ >
+ )
+}
+
+export default DownlinkForm
diff --git a/pkg/webui/console/components/events/error-boundary.js b/pkg/webui/console/components/events/error-boundary.js
index 951bb8d102..df905cb630 100644
--- a/pkg/webui/console/components/events/error-boundary.js
+++ b/pkg/webui/console/components/events/error-boundary.js
@@ -1,4 +1,4 @@
-// Copyright © 2020 The Things Network Foundation, The Things Industries B.V.
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import React from 'react'
+import React, { useCallback, useState } from 'react'
import Icon from '@ttn-lw/components/icon'
@@ -24,32 +24,38 @@ import m from './messages'
import style from './events.styl'
-class EventErrorBoundary extends React.Component {
- state = { hasErrored: false, error: undefined, expanded: false }
+const EventErrorBoundary = ({ children }) => {
+ const [hasErrored, setHasErrored] = useState(false)
- static getDerivedStateFromError() {
- return { hasErrored: true }
- }
-
- render() {
- const { hasErrored } = this.state
- const { children } = this.props
+ const handleError = useCallback(() => {
+ setHasErrored(true)
+ }, [])
- if (hasErrored) {
- return (
-
-
-
-
- )
- }
-
- return children
+ if (hasErrored) {
+ return (
+
+
+
+
+ )
}
+
+ return (
+
+ {React.Children.map(children, child => {
+ if (!child) {
+ return null
+ }
+ return React.cloneElement(child, {
+ onError: handleError,
+ })
+ })}
+
+ )
}
EventErrorBoundary.propTypes = {
- children: PropTypes.node.isRequired,
+ children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]).isRequired,
}
export default EventErrorBoundary
diff --git a/pkg/webui/console/components/events/messages.js b/pkg/webui/console/components/events/messages.js
index 77e54d255a..7e6e8a6827 100644
--- a/pkg/webui/console/components/events/messages.js
+++ b/pkg/webui/console/components/events/messages.js
@@ -15,8 +15,6 @@
import { defineMessages } from 'react-intl'
const messages = defineMessages({
- // Field messages
- payload: 'Payload',
MACPayload: 'MAC payload',
devAddr: 'DevAddr',
fPort: 'FPort',
@@ -37,6 +35,7 @@ const messages = defineMessages({
rx2DataRateIndex: 'Rx2 Data Rate Index',
rx2Frequency: 'Rx2 Frequency',
class: 'Class',
+
// Generic messages
eventDetails: 'Event details',
rawEvent: 'Raw event',
@@ -53,7 +52,6 @@ const messages = defineMessages({
'Old events have been truncated to save memory. The current event limit per stream is {limit}.',
eventUnavailable: 'This event is not available anymore. It was likely truncated to save memory.',
verboseStream: 'Verbose stream',
- confirmedDownlink: 'Confirmed downlink',
confirmedUplink: 'Confirmed uplink',
})
diff --git a/pkg/webui/console/components/gateway-visibility-form/index.js b/pkg/webui/console/components/gateway-visibility-form/index.js
index 724f405f4a..535477a7ac 100644
--- a/pkg/webui/console/components/gateway-visibility-form/index.js
+++ b/pkg/webui/console/components/gateway-visibility-form/index.js
@@ -23,6 +23,7 @@ import SubmitButton from '@ttn-lw/components/submit-button'
import PropTypes from '@ttn-lw/lib/prop-types'
import Yup from '@ttn-lw/lib/yup'
+import sharedMessages from '@ttn-lw/lib/shared-messages'
import gatewayVisibilityMessages from '@console/lib/packet-broker/messages'
@@ -49,7 +50,7 @@ const GatewayVisibilityForm = ({ onSubmit, initialValues, error }) => {
{
{
+ const {
+ formTitle,
validationSchema,
- updatesDisabled: false,
- noLocationSetInfo: m.noLocationSetInfo,
- }
+ children,
+ updatesDisabled,
+ additionalMarkers,
+ initialValues,
+ disabledInfo,
+ noLocationSetInfo,
+ onSubmit,
+ onDelete,
+ entityId,
+ } = props
- constructor(props) {
- super(props)
+ const form = useRef(null)
+ const [latitude, setLatitude] = useState(props.initialValues.latitude)
+ const [longitude, setLongitude] = useState(props.initialValues.longitude)
+ const [zoom, setZoom] = useState(14)
+ const [error, setError] = useState(undefined)
+ const [mapCenter, setMapCenter] = useState(undefined)
+ const [loading, setLoading] = useState(true)
+ const [deleteAll, setDeleteAll] = useState(
+ !hasLocationSet(initialValues) && Object.keys(additionalMarkers).length !== 0,
+ )
- this.form = React.createRef()
-
- this.state = {
- latitude: props.initialValues.latitude,
- longitude: props.initialValues.longitude,
- zoom: 14,
- error: undefined,
- mapCenter: undefined,
- loading: true,
- deleteAll:
- !hasLocationSet(props.initialValues) && Object.keys(props.additionalMarkers).length !== 0,
- }
+ const entryExists = useMemo(() => hasLocationSet(initialValues), [initialValues])
+ const automaticExists = Object.keys(additionalMarkers).length !== 0
+ const anyEntryExists = entryExists || automaticExists
+ const onlyAutomaticExists = !entryExists && anyEntryExists
+ const markers = [...additionalMarkers]
+ if (typeof longitude === 'number' && typeof latitude === 'number') {
+ markers.push({ position: { longitude, latitude } })
}
- @bind
- async componentDidMount() {
- const { initialValues, additionalMarkers } = this.props
- let newState = { mapCenter: defaultLocation, loading: false }
- if (!hasLocationSet(initialValues) && additionalMarkers.length === 0) {
- if ('geolocation' in navigator) {
- newState = await new Promise(resolve => {
- navigator.geolocation.getCurrentPosition(
- position => {
- resolve({
- mapCenter: [
- isNaN(position.coords.latitude) ? defaultLocation[0] : position.coords.latitude,
- isNaN(position.coords.longitude) ? defaultLocation[1] : position.coords.longitude,
- ],
- loading: false,
- })
- },
- () => {
- resolve({ mapCenter: defaultLocation, zoom: 2, loading: false })
- },
- )
- })
- }
+ const getCurrentLocation = useCallback(async () => {
+ let newState = { mapCenter: defaultLocation }
+ if (
+ !hasLocationSet(initialValues) &&
+ additionalMarkers.length === 0 &&
+ 'geolocation' in navigator
+ ) {
+ newState = await new Promise(resolve => {
+ navigator.geolocation.getCurrentPosition(
+ position => {
+ resolve({
+ mapCenter: [
+ isNaN(position.coords.latitude) ? defaultLocation[0] : position.coords.latitude,
+ isNaN(position.coords.longitude) ? defaultLocation[1] : position.coords.longitude,
+ ],
+ })
+ },
+ () => {
+ resolve({ mapCenter: defaultLocation, zoom: 2 })
+ },
+ )
+ })
}
- this.setState(newState)
- }
- @bind
- async handleSubmit(values, { setSubmitting }) {
- const { onSubmit, entityId, validationSchema } = this.props
- this.setState({ error: undefined })
+ return newState
+ }, [additionalMarkers.length, initialValues])
- const castedValues = validationSchema.cast(values)
+ useEffect(() => {
+ getCurrentLocation().then(res => {
+ setMapCenter(res.mapCenter)
+ setZoom(res.zoom ?? 2)
+ setLoading(false)
+ })
+ }, [getCurrentLocation])
- try {
- await onSubmit(castedValues)
- this.setState({ deleteAll: false })
- toast({
- title: entityId,
- message: m.updateSuccess,
- type: toast.types.SUCCESS,
- })
- } catch (error) {
- this.setState({ error })
- setSubmitting(false)
- }
- }
+ const handleSubmit = useCallback(
+ async (values, { setSubmitting }) => {
+ setError(undefined)
- @bind
- handleClick(event) {
- const { updatesDisabled } = this.props
- const { setValues, values } = this.form.current
- const latitude = isNaN(event.latlng.lat) ? defaultLocation[0] : event.latlng.lat
- const longitude = isNaN(event.latlng.lng) ? defaultLocation[1] : event.latlng.lng
+ const castedValues = validationSchema.cast(values)
- if (updatesDisabled) {
- return
- }
+ try {
+ await onSubmit(castedValues)
+ setDeleteAll(false)
+ toast({
+ title: entityId,
+ message: m.updateSuccess,
+ type: toast.types.SUCCESS,
+ })
+ } catch (error) {
+ setError(error)
+ setSubmitting(false)
+ }
+ },
+ [entityId, onSubmit, validationSchema],
+ )
- this.setState({ latitude, longitude })
- setValues({
- ...values,
- latitude,
- longitude,
- altitude: values.altitude ? values.altitude : 0,
- })
- }
+ const handleClick = useCallback(
+ event => {
+ const { setValues, values } = form.current
+ const latitude = isNaN(event.latlng.lat) ? defaultLocation[0] : event.latlng.lat
+ const longitude = isNaN(event.latlng.lng) ? defaultLocation[1] : event.latlng.lng
- @bind
- handleLatitudeChange(event) {
- const { longitude } = this.state
- const latitude = event.currentTarget.value
- if (longitude) {
- this.setState({ latitude, mapCenter: [Number(latitude), Number(longitude)] })
- } else {
- this.setState({ latitude })
- }
- }
+ if (updatesDisabled) {
+ return
+ }
+ setLatitude(latitude)
+ setLongitude(longitude)
+ setValues({
+ ...values,
+ latitude,
+ longitude,
+ altitude: values.altitude ? values.altitude : 0,
+ })
+ },
+ [updatesDisabled],
+ )
- @bind
- handleLongitudeChange(event) {
- const { latitude } = this.state
- const longitude = event.currentTarget.value
- if (latitude) {
- this.setState({ longitude, mapCenter: [Number(latitude), Number(longitude)] })
- } else {
- this.setState({ longitude })
- }
- }
+ const handleLatitudeChange = useCallback(
+ event => {
+ const latitude = event.currentTarget.value
+ setLatitude(latitude)
+ if (longitude) {
+ setMapCenter([Number(latitude), Number(longitude)])
+ }
+ },
+ [longitude],
+ )
+
+ const handleLongitudeChange = useCallback(
+ event => {
+ const longitude = event.currentTarget.value
+ setLongitude(longitude)
+ if (latitude) {
+ setMapCenter([Number(latitude), Number(longitude)])
+ }
+ },
+ [latitude],
+ )
- @bind
- handleDeleteAllCheck(event) {
+ const handleDeleteAllCheck = useCallback(event => {
if (!event || !event.target) {
return
}
- this.setState({ deleteAll: event.target.checked })
- }
-
- @bind
- async handleDelete() {
- const { onDelete, entityId } = this.props
- const { deleteAll } = this.state
+ setDeleteAll(event.target.checked)
+ }, [])
+ const handleDelete = useCallback(async () => {
try {
await onDelete(deleteAll)
- this.form.current.resetForm({ values: emptyLocation })
- this.setState({ latitude: undefined, longitude: undefined })
+ form.current.resetForm({ values: emptyLocation })
+ setLatitude(undefined)
+ setLongitude(undefined)
toast({
title: entityId,
message: m.deleteSuccess,
type: toast.types.SUCCESS,
})
} catch (error) {
- this.setState({ error })
+ setError(error)
}
- }
+ }, [deleteAll, entityId, onDelete])
- render() {
- const {
- formTitle,
- validationSchema,
- children,
- updatesDisabled,
- additionalMarkers,
- initialValues,
- disabledInfo,
- noLocationSetInfo,
- } = this.props
- const { error, latitude, longitude, mapCenter, zoom, loading, deleteAll } = this.state
-
- const entryExists = hasLocationSet(initialValues)
- const automaticExists = Object.keys(additionalMarkers).length !== 0
- const anyEntryExists = entryExists || automaticExists
- const onlyAutomaticExists = !entryExists && anyEntryExists
- const markers = [...additionalMarkers]
- if (typeof longitude === 'number' && typeof latitude === 'number') {
- markers.push({ position: { longitude, latitude } })
- }
- return (
-
-
- {children}
-
- {!entryExists && }
-
-
-
-
- {updatesDisabled && disabledInfo && }
-
-
-
-
-
-
-
+
+ {children}
+
+ {!entryExists && }
+
+
+
+
+ {updatesDisabled && disabledInfo && }
+
+
+
+
+
+
+
+ {entryExists && automaticExists && (
+ <>
+
+
+
+
- {entryExists && automaticExists && (
- <>
-
-
-
-
- >
- )}
-
- ),
- }}
- onApprove={this.handleDelete}
- disabled={updatesDisabled || !anyEntryExists}
- naked
- danger
- />
-
-
-
- )
- }
+ >
+ )}
+
+ ),
+ }}
+ onApprove={handleDelete}
+ disabled={updatesDisabled || !anyEntryExists}
+ naked
+ danger
+ />
+
+
+ )
+}
+
+LocationForm.propTypes = {
+ additionalMarkers: PropTypes.markers,
+ /** Additional fields to be passed as children. */
+ children: PropTypes.node,
+ disabledInfo: PropTypes.message,
+ entityId: PropTypes.string.isRequired,
+ /** The title message shown at the top of the form. */
+ formTitle: PropTypes.message.isRequired,
+ initialValues: PropTypes.entityLocation,
+ noLocationSetInfo: PropTypes.message,
+ /** The handler for the delete function of the form. */
+ onDelete: PropTypes.func.isRequired,
+ /** The handler for the submit function of the form. */
+ onSubmit: PropTypes.func.isRequired,
+ updatesDisabled: PropTypes.bool,
+ validationSchema: PropTypes.shape({
+ cast: PropTypes.func.isRequired,
+ }),
+}
+
+LocationForm.defaultProps = {
+ additionalMarkers: [],
+ children: null,
+ disabledInfo: undefined,
+ initialValues: emptyLocation,
+ validationSchema,
+ updatesDisabled: false,
+ noLocationSetInfo: m.noLocationSetInfo,
}
export { LocationForm as default, hasLocationSet }
diff --git a/pkg/webui/console/components/mac-settings-section/index.js b/pkg/webui/console/components/mac-settings-section/index.js
index a8ab98a6d6..0c0260e4d4 100644
--- a/pkg/webui/console/components/mac-settings-section/index.js
+++ b/pkg/webui/console/components/mac-settings-section/index.js
@@ -40,32 +40,19 @@ import {
const m = defineMessages({
delayValue: '{count, plural, one {{count} second} other {{count} seconds}}',
factoryPresetFreqDescription: 'List of factory-preset frequencies. Note: order is respected.',
- factoryPresetFreqTitle: 'Factory preset frequencies',
- freqAdd: 'Add Frequency',
- frequencyPlaceholder: 'e.g. 869525000 for 869,525 MHz',
advancedMacSettings: 'Advanced MAC settings',
- pingSlotFrequencyTitle: 'Ping slot frequency',
desiredPingSlotFrequencyTitle: 'Desired ping slot frequency',
pingSlotPeriodicityDescription: 'Periodicity of the class B ping slot',
- pingSlotPeriodicityTitle: 'Ping slot periodicity',
- pingSlotPeriodicityValue: '{count, plural, one {every second} other {every {count} seconds}}',
pingSlotDataRateTitle: 'Ping slot data rate index',
desiredPingSlotDataRateTitle: 'Desired ping slot data rate',
resetWarning: 'Resetting is insecure and makes your device susceptible for replay attacks',
- resetsFCnt: 'Resets frame counters',
- rx1DataRateOffsetTitle: 'Rx1 data rate offset',
desiredRx1DataRateOffsetTitle: 'Desired Rx1 data rate offset',
- rx1DelayTitle: 'Rx1 delay',
desiredRx1DelayTitle: 'Desired Rx1 delay',
rx2DataRateIndexTitle: 'Rx2 data rate index',
desiredRx2DataRateIndexTitle: 'Desired Rx2 data rate index',
desiredRx2FrequencyTitle: 'Desired Rx2 frequency',
- rx2FrequencyTitle: 'Rx2 frequency',
updateSuccess: 'The MAC settings updated',
- beaconFrequency: 'Beacon frequency',
desiredBeaconFrequency: 'Desired beacon frequency',
- classBTimeout: 'Class B timeout',
- classCTimeout: 'Class C timeout',
maxDutyCycle: 'Maximum duty cycle',
desiredMaxDutyCycle: 'Desired maximum duty cycle',
adrMargin: 'ADR margin',
@@ -88,7 +75,7 @@ const pingSlotPeriodicityOptions = Array.from({ length: 8 }, (_, index) => {
return {
value: `PING_EVERY_${value}S`,
- label: ,
+ label: ,
}
})
// 0...15
@@ -189,7 +176,7 @@ const MacSettingsSection = props => {
{!isOTAA && (
}
@@ -219,7 +206,7 @@ const MacSettingsSection = props => {
{!isOTAA && (
{
type="number"
min={100000}
step={100}
- title={m.rx2FrequencyTitle}
+ title={sharedMessages.rx2Frequency}
name="mac_settings.rx2_frequency"
component={UnitInput.Hertz}
tooltipId={tooltipIds.RX2_FREQUENCY}
@@ -336,15 +323,15 @@ const MacSettingsSection = props => {
indexAsKey
name="mac_settings.factory_preset_frequencies"
component={KeyValueMap}
- title={m.factoryPresetFreqTitle}
+ title={sharedMessages.factoryPresetFrequencies}
description={m.factoryPresetFreqDescription}
- addMessage={m.freqAdd}
- valuePlaceholder={m.frequencyPlaceholder}
+ addMessage={sharedMessages.freqAdd}
+ valuePlaceholder={sharedMessages.frequencyPlaceholder}
tooltipId={tooltipIds.FACTORY_PRESET_FREQUENCIES}
/>
{isClassC && (
{
{(isClassB || isMulticast) && (
<>
{
fieldWidth="xs"
/>
{
{
type="number"
min={100000}
title={m.desiredBeaconFrequency}
- placeholder={m.frequencyPlaceholder}
+ placeholder={sharedMessages.frequencyPlaceholder}
name="mac_settings.desired_beacon_frequency"
tooltipId={tooltipIds.BEACON_FREQUENCY}
component={UnitInput.Hertz}
@@ -406,8 +393,8 @@ const MacSettingsSection = props => {
type="number"
min={100000}
step={100}
- title={m.pingSlotFrequencyTitle}
- placeholder={m.frequencyPlaceholder}
+ title={sharedMessages.pingSlotFrequency}
+ placeholder={sharedMessages.frequencyPlaceholder}
name="mac_settings.ping_slot_frequency"
tooltipId={tooltipIds.PING_SLOT_FREQUENCY}
component={UnitInput.Hertz}
@@ -420,7 +407,7 @@ const MacSettingsSection = props => {
min={100000}
step={100}
title={m.desiredPingSlotFrequencyTitle}
- placeholder={m.frequencyPlaceholder}
+ placeholder={sharedMessages.frequencyPlaceholder}
name="mac_settings.desired_ping_slot_frequency"
tooltipId={tooltipIds.PING_SLOT_FREQUENCY}
component={UnitInput.Hertz}
diff --git a/pkg/webui/console/components/payload-formatters-form/index.js b/pkg/webui/console/components/payload-formatters-form/index.js
index 05f015f360..ea7ec8d788 100644
--- a/pkg/webui/console/components/payload-formatters-form/index.js
+++ b/pkg/webui/console/components/payload-formatters-form/index.js
@@ -47,7 +47,6 @@ import TestForm from './test-form'
import style from './payload-formatters-form.styl'
const m = defineMessages({
- grpc: 'GRPC service',
repository: 'Use Device Repository formatters',
customJavascipt: 'Custom Javascript formatter',
formatterType: 'Formatter type',
@@ -57,7 +56,6 @@ const m = defineMessages({
grpcFieldDescription: 'The address of the service to connect to',
appFormatter: 'Use application payload formatter',
appFormatterWarning: 'This option will affect both uplink and downlink formatter',
- setupSubTitle: 'Setup',
defaultFormatter:
'Click here to modify the default payload formatter for this application. The payload formatter of this application is currently set to `{defaultFormatter}`',
pasteRepositoryFormatter: 'Paste repository formatter',
@@ -80,7 +78,7 @@ const formatterOptions = [
{ label: m.appFormatter, value: TYPES.DEFAULT },
{ label: m.repository, value: TYPES.REPOSITORY },
{ label: m.customJavascipt, value: TYPES.JAVASCRIPT },
- { label: m.grpc, value: TYPES.GRPC },
+ { label: sharedMessages.grpcService, value: TYPES.GRPC },
{ label: 'CayenneLPP', value: TYPES.CAYENNELPP },
{ label: sharedMessages.none, value: TYPES.NONE },
]
@@ -420,7 +418,7 @@ const PayloadFormattersForm = ({
>
{() => (
<>
-
+
false,
- onDelete: () => null,
- }
-
- constructor(props) {
- super(props)
-
- this.form = React.createRef()
- this.modalResolve = () => null
- this.modalReject = () => null
-
- const { initialPubsubValue, update, mqttDisabled, natsDisabled } = this.props
-
- this.state = {
- error: undefined,
- mqttDisabled,
- provider: blankValues._provider,
- mqttUseCredentials: true,
- natsUseCredentials: true,
- natsDisabled,
- displayOverwriteModal: false,
- existingId: undefined,
+const PubsubForm = props => {
+ const form = useRef(null)
+ const modalResolve = useRef(() => {})
+ const modalReject = useRef(() => {})
+
+ const {
+ initialPubsubValue,
+ update,
+ mqttDisabled,
+ natsDisabled,
+ appId,
+ onSubmit,
+ existCheck,
+ onDelete,
+ } = props
+ const [error, setError] = useState(undefined)
+ const [provider, setProvider] = useState(blankValues._provider)
+ const [mqttSecure, setMqttSecure] = useState(true)
+ const [mqttUseCredentials, setMqttUseCredentials] = useState(true)
+ const [natsUseCredentials, setNatsUseCredentials] = useState(true)
+ const [displayOverwriteModal, setDisplayOverwriteModal] = useState(false)
+ const [existingId, setExistingId] = useState(undefined)
+
+ const initialValues = useMemo(() => {
+ if (update && initialPubsubValue) {
+ return mapPubsubToFormValues(initialPubsubValue)
+ }
+ return {
+ ...blankValues,
+ _provider: provider,
}
+ }, [initialPubsubValue, provider, update])
+ useEffect(() => {
if (natsDisabled && mqttDisabled) {
- this.state.provider = blankValues._provider
+ setProvider(blankValues._provider)
} else {
- this.state.provider = natsDisabled ? providers.MQTT : providers.NATS
+ setProvider(natsDisabled ? providers.MQTT : providers.NATS)
}
if (update && 'nats' in initialPubsubValue) {
const { password, username } = mapNatsFormValues(initialPubsubValue.nats)
- this.state.provider = providers.NATS
- this.state.natsUseCredentials = Boolean(password || username)
+ setProvider(providers.NATS)
+ setNatsUseCredentials(Boolean(password || username))
} else if (update && 'mqtt' in initialPubsubValue) {
- this.state.provider = providers.MQTT
- this.state.mqttSecure = initialPubsubValue.mqtt.use_tls
- this.state.mqttUseCredentials = Boolean(
- initialPubsubValue.mqtt.username || initialPubsubValue.mqtt.password,
+ setProvider(providers.MQTT)
+ setMqttSecure(initialPubsubValue.mqtt.use_tls)
+ setMqttUseCredentials(
+ Boolean(initialPubsubValue.mqtt.username || initialPubsubValue.mqtt.password),
)
}
- }
-
- @bind
- async handleSubmit(values, { resetForm }) {
- const { appId, onSubmit, existCheck, update } = this.props
-
- const castedValues = validationSchema.cast(values)
- const pubsub = mapFormValuesToPubsub(castedValues, appId)
-
- this.setState({ error: '' })
-
- try {
- if (!update) {
- const pubsubId = pubsub.ids.pub_sub_id
- const exists = await existCheck(pubsubId)
- if (exists) {
- this.setState({ displayOverwriteModal: true, existingId: pubsubId })
- await new Promise((resolve, reject) => {
- this.modalResolve = resolve
- this.modalReject = reject
- })
+ }, [initialPubsubValue, mqttDisabled, natsDisabled, update])
+
+ const handleSubmit = useCallback(
+ async (values, { resetForm }) => {
+ const castedValues = validationSchema.cast(values)
+ const pubsub = mapFormValuesToPubsub(castedValues, appId)
+ setError('')
+
+ try {
+ if (!update) {
+ const pubsubId = pubsub.ids.pub_sub_id
+ const exists = await existCheck(pubsubId)
+ if (exists) {
+ setDisplayOverwriteModal(true)
+ setExistingId(pubsubId)
+ await new Promise((resolve, reject) => {
+ modalResolve.current = resolve
+ modalReject.current = reject
+ })
+ }
}
- }
- await onSubmit(pubsub)
+ await onSubmit(pubsub)
- resetForm({ values })
- } catch (error) {
- resetForm({ values })
-
- this.setState({ error })
- }
- }
+ resetForm({ values })
+ } catch (error) {
+ resetForm({ values })
+ setError(error)
+ }
+ },
+ [appId, existCheck, onSubmit, update],
+ )
- @bind
- async handleDelete() {
- const { onDelete } = this.props
+ const handleDelete = useCallback(async () => {
try {
await onDelete()
- this.form.current.resetForm()
+ form.current.resetForm()
} catch (error) {
- this.setState({ error })
+ setError(error)
}
- }
+ }, [onDelete])
- @bind
- handleProviderSelect(event) {
- this.setState({ provider: event.target.value })
- }
+ const handleProviderSelect = useCallback(event => {
+ setProvider(event.target.value)
+ }, [])
- @bind
- handleUseCredentialsChangeNats(event) {
- this.setState({ natsUseCredentials: event.target.checked })
- }
+ const handleUseCredentialsChangeNats = useCallback(event => {
+ setNatsUseCredentials(event.target.checked)
+ }, [])
- @bind
- handleMqttUseTlsChange(event) {
- this.setState({ mqttSecure: event.target.checked })
- }
+ const handleMqttUseTlsChange = useCallback(event => {
+ setMqttSecure(event.target.checked)
+ }, [])
- @bind
- handleUseCredentialsChangeMqtt(event) {
- this.setState({ mqttUseCredentials: event.target.checked })
- }
+ const handleUseCredentialsChangeMqtt = useCallback(event => {
+ setMqttUseCredentials(event.target.checked)
+ }, [])
- @bind
- handleReplaceModalDecision(mayReplace) {
+ const handleReplaceModalDecision = useCallback(mayReplace => {
if (mayReplace) {
- this.modalResolve()
+ modalResolve.current()
} else {
- this.modalReject()
+ modalReject.current()
}
- this.setState({ displayOverwriteModal: false })
- }
+ setDisplayOverwriteModal(false)
+ }, [])
- get natsSection() {
- const { natsUseCredentials } = this.state
- return (
+ const natsSection = useMemo(
+ () => (
<>
@@ -187,7 +173,7 @@ export default class PubsubForm extends Component {
name="nats._use_credentials"
label={m.useCredentials}
component={Checkbox}
- onChange={this.handleUseCredentialsChangeNats}
+ onChange={handleUseCredentialsChangeNats}
/>
>
- )
- }
+ ),
+ [handleUseCredentialsChangeNats, natsUseCredentials],
+ )
- get mqttSection() {
- const { mqttSecure, mqttUseCredentials } = this.state
-
- return (
+ const mqttSection = useMemo(
+ () => (
<>
{mqttSecure && (
<>
@@ -271,14 +256,14 @@ export default class PubsubForm extends Component {
)}
>
- )
- }
+ ),
+ [handleMqttUseTlsChange, handleUseCredentialsChangeMqtt, mqttSecure, mqttUseCredentials],
+ )
- get messageTypesSection() {
- return (
+ const messageTypesSection = useMemo(
+ () => (
<>
@@ -441,93 +427,104 @@ export default class PubsubForm extends Component {
description={sharedMessages.eventDownlinkReplaceDesc}
/>
>
- )
- }
-
- render() {
- const { update, initialPubsubValue, mqttDisabled, natsDisabled } = this.props
- const { error, provider, displayOverwriteModal, existingId } = this.state
- let initialValues = blankValues
- if (update && initialPubsubValue) {
- initialValues = mapPubsubToFormValues(initialPubsubValue)
- }
-
- return (
- <>
- (
-
- {val}
-
- ),
- }}
- component="p"
+ ),
+ [],
+ )
+
+ return (
+ <>
+ (
+
+ {val}
+
+ ),
+ }}
+ component="p"
+ />
+
+
+
+
-
+
+
+ {provider === providers.NATS && natsSection}
+ {provider === providers.MQTT && mqttSection}
+ {messageTypesSection}
+
+
-
-
-
-
-
-
- {provider === providers.NATS && this.natsSection}
- {provider === providers.MQTT && this.mqttSection}
- {this.messageTypesSection}
-
-
- {update && (
-
- )}
-
-
- >
- )
- }
+ )}
+
+
+ >
+ )
}
+PubsubForm.propTypes = {
+ appId: PropTypes.string.isRequired,
+ existCheck: PropTypes.func,
+ initialPubsubValue: PropTypes.pubsub,
+ mqttDisabled: PropTypes.bool.isRequired,
+ natsDisabled: PropTypes.bool.isRequired,
+ onDelete: PropTypes.func,
+ onSubmit: PropTypes.func.isRequired,
+ update: PropTypes.bool.isRequired,
+}
+
+PubsubForm.defaultProps = {
+ initialPubsubValue: undefined,
+ existCheck: () => false,
+ onDelete: () => null,
+}
+
+export default PubsubForm
diff --git a/pkg/webui/console/components/pubsub-form/messages.js b/pkg/webui/console/components/pubsub-form/messages.js
index 0b99afbb3e..81457da324 100644
--- a/pkg/webui/console/components/pubsub-form/messages.js
+++ b/pkg/webui/console/components/pubsub-form/messages.js
@@ -21,9 +21,6 @@ export default defineMessages({
modalWarning:
'Are you sure you want to delete Pub/Sub "{pubsubId}"? Deleting a Pub/Sub cannot be undone.',
headers: 'Headers',
- headersKeyPlaceholder: 'Authorization',
- headersValuePlaceholder: 'Bearer my-auth-token',
- headersAdd: 'Add header entry',
headersValidateRequired: 'All header entry values are required. Please remove empty entries.',
usernamePlaceholder: 'my-username',
passwordPlaceholder: 'my-password',
@@ -33,9 +30,8 @@ export default defineMessages({
mqttConfig: 'MQTT configuration',
mqttClientIdPlaceholder: 'my-client-id',
mqttServerUrlPlaceholder: 'mqtts://example.com',
- serverUrl: 'Server URL',
- clientId: 'Client ID',
subscribeQos: 'Subscribe QoS',
+ providerDescription: 'Changing the Pub/Sub provider has been disabled by an administrator',
publishQos: 'Publish QoS',
tlsCa: 'Root CA certificate',
tlsClientCert: 'Client certificate',
@@ -43,7 +39,6 @@ export default defineMessages({
selectPemFile: 'Select .pem file…',
pemFileProvided: '.pem file has been provided',
useCredentials: 'Use credentials',
- alreadyExistsModalTitle: 'ID already exists',
alreadyExistsModalMessage:
'A Pub/Sub with the ID "{id}" already exists. Do you wish to replace this Pub/Sub?',
replacePubsub: 'Replace Pub/Sub',
diff --git a/pkg/webui/console/components/routing-policy-form/index.js b/pkg/webui/console/components/routing-policy-form/index.js
index 8ad08204e7..b000a2f304 100644
--- a/pkg/webui/console/components/routing-policy-form/index.js
+++ b/pkg/webui/console/components/routing-policy-form/index.js
@@ -37,9 +37,7 @@ import style from './routing-policy-form.styl'
const m = defineMessages({
saveDefaultPolicy: 'Save default policy',
- useDefaultPolicy: 'Use default routing policy for this network',
useSpecificPolicy: 'Use network specific routing policy',
- doNotUseADefaultPolicy: 'Do not use a default routing policy for this network',
doNotUseAPolicy: 'Do not use a routing policy for this network',
})
@@ -53,25 +51,15 @@ const validationSchema = Yup.object({
const policySourceEncode = val => val === 'default'
const policySourceDecode = val => (val ? 'default' : 'specific')
-const useDefaultEncode = val => val === 'default'
-const useDefaultDecode = val => (val ? 'default' : 'no-default')
-const RoutingPolicyForm = ({
- onSubmit,
- initialValues,
- error,
- defaultPolicy,
- networkLevel,
- submitMessage,
-}) => {
+const RoutingPolicyForm = ({ onSubmit, initialValues, error, defaultPolicy, submitMessage }) => {
const handleSubmit = useCallback(values => onSubmit(validationSchema.cast(values)), [onSubmit])
const [useDefault, setUseDefault] = useState(initialValues._use_default_policy || false)
const handlePolicySourceChange = useCallback(setUseDefault, [setUseDefault])
const hasDefaultPolicy = isValidPolicy(defaultPolicy)
- const showDefaultPolicySheet = networkLevel && useDefault && isValidPolicy(defaultPolicy)
- const showPolicyCheckboxes = (useDefault && !networkLevel) || (!useDefault && networkLevel)
-
+ const showDefaultPolicySheet = useDefault && isValidPolicy(defaultPolicy)
+ const showPolicyCheckboxes = !useDefault
return (
+ >
+ )
+}
+
+export default UplinkForm
diff --git a/pkg/webui/console/components/uplink-form/uplink-form.js b/pkg/webui/console/components/uplink-form/uplink-form.js
deleted file mode 100644
index 827bfca706..0000000000
--- a/pkg/webui/console/components/uplink-form/uplink-form.js
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright © 2020 The Things Network Foundation, The Things Industries B.V.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import React from 'react'
-import { defineMessages } from 'react-intl'
-
-import Notification from '@ttn-lw/components/notification'
-import SubmitButton from '@ttn-lw/components/submit-button'
-import Input from '@ttn-lw/components/input'
-import SubmitBar from '@ttn-lw/components/submit-bar'
-import toast from '@ttn-lw/components/toast'
-import Form from '@ttn-lw/components/form'
-
-import IntlHelmet from '@ttn-lw/lib/components/intl-helmet'
-
-import Yup from '@ttn-lw/lib/yup'
-import PropTypes from '@ttn-lw/lib/prop-types'
-import sharedMessages from '@ttn-lw/lib/shared-messages'
-
-import { hexToBase64 } from '@console/lib/bytes'
-
-const m = defineMessages({
- simulateUplink: 'Simulate uplink',
- payloadDescription: 'The desired payload bytes of the uplink message',
- uplinkSuccess: 'Uplink sent',
-})
-
-const validationSchema = Yup.object({
- f_port: Yup.number()
- .min(1, Yup.passValues(sharedMessages.validateNumberGte))
- .max(223, Yup.passValues(sharedMessages.validateNumberLte))
- .required(sharedMessages.validateRequired),
- frm_payload: Yup.string().test(
- 'len',
- Yup.passValues(sharedMessages.validateHexLength),
- payload => !Boolean(payload) || payload.length % 3 === 0,
- ),
-})
-
-const initialValues = { f_port: 1, frm_payload: '' }
-
-const UplinkForm = props => {
- const { simulateUplink, device, skipPayloadCrypto } = props
-
- const [error, setError] = React.useState('')
-
- const handleSubmit = React.useCallback(
- async (values, { setSubmitting, resetForm }) => {
- try {
- await simulateUplink({
- f_port: values.f_port,
- frm_payload: hexToBase64(values.frm_payload),
- // `rx_metadata` and `settings` fields are required by the validation middleware in AS.
- // These fields won't affect the result of simulating an uplink message.
- rx_metadata: [
- { gateway_ids: { gateway_id: 'test' }, rssi: 42, channel_rssi: 42, snr: 4.2 },
- ],
- settings: {
- data_rate: { lora: { bandwidth: 125000, spreading_factor: 7 } },
- frequency: 868000000,
- },
- })
- toast({
- title: sharedMessages.success,
- type: toast.types.SUCCESS,
- message: m.uplinkSuccess,
- })
- setSubmitting(false)
- } catch (error) {
- setError(error)
- resetForm({ values })
- }
- },
- [simulateUplink],
- )
-
- const deviceSimulationDisabled = device.skip_payload_crypto_override ?? skipPayloadCrypto
-
- return (
- <>
- {deviceSimulationDisabled && (
-
- )}
-
-
-
-
-
-
-
-
-
- >
- )
-}
-
-UplinkForm.propTypes = {
- device: PropTypes.device.isRequired,
- simulateUplink: PropTypes.func.isRequired,
- skipPayloadCrypto: PropTypes.bool,
-}
-
-UplinkForm.defaultProps = {
- skipPayloadCrypto: false,
-}
-
-export default UplinkForm
diff --git a/pkg/webui/console/components/webhook-form/index.js b/pkg/webui/console/components/webhook-form/index.js
index 4fa389e191..8960f872c7 100644
--- a/pkg/webui/console/components/webhook-form/index.js
+++ b/pkg/webui/console/components/webhook-form/index.js
@@ -1,4 +1,4 @@
-// Copyright © 2021 The Things Network Foundation, The Things Industries B.V.
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,9 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import React, { Component } from 'react'
+import React, { useCallback, useRef, useState } from 'react'
import { defineMessages, FormattedRelativeTime } from 'react-intl'
-import bind from 'autobind-decorator'
import { uniq } from 'lodash'
import tts from '@console/api/tts'
@@ -70,9 +69,6 @@ const m = defineMessages({
modalWarning:
'Are you sure you want to delete webhook "{webhookId}"? Deleting a webhook cannot be undone.',
additionalHeaders: 'Additional headers',
- headersKeyPlaceholder: 'Authorization',
- headersValuePlaceholder: 'Bearer my-auth-token',
- headersAdd: 'Add header entry',
downlinkAPIKey: 'Downlink API key',
downlinkAPIKeyDesc:
'The API key will be provided to the endpoint using the "X-Downlink-Apikey" header',
@@ -236,120 +232,97 @@ const validationSchema = Yup.object().shape({
.nullable(),
})
-export default class WebhookForm extends Component {
- static propTypes = {
- error: PropTypes.error,
- existCheck: PropTypes.func,
- hasUnhealthyWebhookConfig: PropTypes.bool,
- healthStatusEnabled: PropTypes.bool,
- initialWebhookValue: PropTypes.shape({
- ids: PropTypes.shape({
- webhook_id: PropTypes.string,
- }),
- health_status: PropTypes.shape({
- healthy: PropTypes.shape({}),
- unhealthy: PropTypes.shape({}),
- }),
- headers: PropTypes.shape({
- Authorization: PropTypes.string,
- }),
- }),
- onDelete: PropTypes.func,
- onDeleteFailure: PropTypes.func,
- onDeleteSuccess: PropTypes.func,
- onReactivate: PropTypes.func,
- onReactivateSuccess: PropTypes.func,
- onSubmit: PropTypes.func.isRequired,
- update: PropTypes.bool.isRequired,
- webhookRetryInterval: PropTypes.string,
- webhookTemplate: PropTypes.webhookTemplate,
+const WebhookForm = props => {
+ const {
+ update,
+ initialWebhookValue,
+ webhookTemplate,
+ healthStatusEnabled,
+ webhookRetryInterval,
+ hasUnhealthyWebhookConfig,
+ error: propsError,
+ existCheck,
+ onSubmit,
+ onDelete,
+ onDeleteSuccess,
+ onDeleteFailure,
+ onReactivate,
+ onReactivateSuccess,
+ } = props
+
+ const form = useRef(null)
+ const modalResolve = useRef(() => {})
+ const modalReject = useRef(() => {})
+ const [shouldShowCredentialsInput, setShouldShowCredentialsInput] = useState(
+ Boolean(initialWebhookValue?.headers?.Authorization?.startsWith('Basic ')) &&
+ Boolean(!decodeValues(initialWebhookValue)._headers.find(i => i.decodeError)?.decodeError),
+ )
+ const [showDecodeError, setShowDecodeError] = useState(
+ Boolean(decodeValues(initialWebhookValue)._headers.find(i => i.decodeError)?.decodeError),
+ )
+ const [displayOverwriteModal, setDisplayOverwriteModal] = useState(false)
+ const [existingId, setExistingId] = useState(undefined)
+ const [error, setError] = useState(undefined)
+
+ const retryIntervalValue = webhookRetryInterval?.match(durationRegExp)[0]
+ const retryIntervalUnit = webhookRetryInterval?.match(durationRegExp)[1]
+ const retryIntervalIntlUnit = units[retryIntervalUnit]
+
+ let initialValues = blankValues
+ if (update && initialWebhookValue) {
+ initialValues = decodeValues({ ...blankValues, ...initialWebhookValue })
}
- static defaultProps = {
- initialWebhookValue: undefined,
- onReactivate: () => null,
- onReactivateSuccess: () => null,
- onDeleteFailure: () => null,
- onDeleteSuccess: () => null,
- onDelete: () => null,
- webhookTemplate: undefined,
- healthStatusEnabled: false,
- error: undefined,
- existCheck: () => null,
- webhookRetryInterval: null,
- hasUnhealthyWebhookConfig: false,
- }
+ const hasTemplate = Boolean(webhookTemplate)
- form = React.createRef()
-
- modalResolve = () => null
- modalReject = () => null
-
- constructor(props) {
- super(props)
- const { initialWebhookValue } = this.props
-
- this.state = {
- shouldShowCredentialsInput:
- Boolean(initialWebhookValue?.headers?.Authorization?.startsWith('Basic ')) &&
- Boolean(!decodeValues(initialWebhookValue)._headers.find(i => i.decodeError)?.decodeError),
- showDecodeError: Boolean(
- decodeValues(initialWebhookValue)._headers.find(i => i.decodeError)?.decodeError,
- ),
- displayOverwriteModal: false,
- existingId: undefined,
- error: undefined,
- }
- }
+ const healthStatus = initialWebhookValue?.health_status
+ const mayReactivate = update && hasUnhealthyWebhookConfig && healthStatus?.unhealthy
+ const isPending = update && healthStatusEnabled && !healthStatus
- @bind
- handleReplaceModalDecision(mayReplace) {
+ const handleReplaceModalDecision = useCallback(mayReplace => {
if (mayReplace) {
- this.modalResolve()
+ modalResolve.current()
} else {
- this.modalReject()
- }
- this.setState({ displayOverwriteModal: false })
- }
-
- @bind
- async handleSubmit(values, { setSubmitting, resetForm }) {
- const { onSubmit, existCheck } = this.props
- const castedWebhookValues = validationSchema.cast(values)
- const encodedValues = encodeValues(castedWebhookValues)
- const webhookId = encodedValues.ids.webhook_id
- const exists = await existCheck(webhookId)
- this.setState({
- showDecodeError: Boolean(
- decodeValues(encodedValues)._headers.find(i => i.decodeError)?.decodeError,
- ),
- })
- if (exists) {
- this.setState({ displayOverwriteModal: true, existingId: webhookId })
- await new Promise((resolve, reject) => {
- this.modalResolve = resolve
- this.modalReject = reject
- })
+ modalReject.current()
}
- await onSubmit(castedWebhookValues, encodedValues, { setSubmitting, resetForm })
- }
+ setDisplayOverwriteModal(false)
+ }, [])
+
+ const handleSubmit = useCallback(
+ async (values, { setSubmitting, resetForm }) => {
+ const castedWebhookValues = validationSchema.cast(values)
+ const encodedValues = encodeValues(castedWebhookValues)
+ const webhookId = encodedValues.ids.webhook_id
+ const exists = await existCheck(webhookId)
+ setShowDecodeError(
+ Boolean(decodeValues(encodedValues)._headers.find(i => i.decodeError)?.decodeError),
+ )
- @bind
- async handleDelete() {
- const { onDelete, onDeleteSuccess, onDeleteFailure } = this.props
+ if (exists) {
+ setDisplayOverwriteModal(true)
+ setExistingId(webhookId)
+ await new Promise((resolve, reject) => {
+ modalResolve.current = resolve
+ modalReject.current = reject
+ })
+ }
+ await onSubmit(castedWebhookValues, encodedValues, { setSubmitting, resetForm })
+ },
+ [existCheck, onSubmit],
+ )
+
+ const handleDelete = useCallback(async () => {
try {
await onDelete()
- this.form.current.resetForm()
+ form.current.resetForm()
onDeleteSuccess()
} catch (error) {
- this.setState({ error })
+ setError(error)
onDeleteFailure()
}
- }
+ }, [onDelete, onDeleteFailure, onDeleteSuccess])
- @bind
- async handleReactivate() {
- const { onReactivate, onReactivateSuccess } = this.props
+ const handleReactivate = useCallback(async () => {
const healthStatus = {
health_status: null,
}
@@ -358,342 +331,356 @@ export default class WebhookForm extends Component {
await onReactivate(healthStatus)
onReactivateSuccess()
} catch (error) {
- this.setState({ error })
+ setError(error)
}
- }
+ }, [onReactivate, onReactivateSuccess])
- @bind
- handleRequestAuthenticationChange(event) {
- const currentHeaders = this.form.current.values._headers
+ const handleRequestAuthenticationChange = useCallback(event => {
+ const currentHeaders = form.current.values._headers
if (!event.target.checked) {
- this.form.current.setFieldValue(
+ form.current.setFieldValue(
'_headers',
currentHeaders.filter(i => !i.readOnly),
)
} else {
- this.form.current.setFieldValue('_headers', [
+ form.current.setFieldValue('_headers', [
{ key: 'Authorization', value: 'Basic ...', readOnly: true },
])
}
- this.setState({ shouldShowCredentialsInput: event.target.checked })
- }
-
- @bind
- handleHeadersChange() {
- this.setState({ showDecodeError: !hasNoEmptyEntry })
- }
-
- render() {
- const {
- update,
- initialWebhookValue,
- webhookTemplate,
- healthStatusEnabled,
- webhookRetryInterval,
- hasUnhealthyWebhookConfig,
- error,
- } = this.props
-
- const retryIntervalValue = webhookRetryInterval?.match(durationRegExp)[0]
- const retryIntervalUnit = webhookRetryInterval?.match(durationRegExp)[1]
- const retryIntervalIntlUnit = units[retryIntervalUnit]
-
- let initialValues = blankValues
- if (update && initialWebhookValue) {
- initialValues = decodeValues({ ...blankValues, ...initialWebhookValue })
- }
-
- const hasTemplate = Boolean(webhookTemplate)
-
- const healthStatus = initialWebhookValue?.health_status
- const mayReactivate = update && hasUnhealthyWebhookConfig && healthStatus?.unhealthy
- const isPending = update && healthStatusEnabled && !healthStatus
-
- return (
- <>
- {!hasTemplate && (
- <>
- (
-
- {val}
-
- ),
- }}
- component="p"
+ setShouldShowCredentialsInput(event.target.checked)
+ }, [])
+
+ const handleHeadersChange = useCallback(() => {
+ setShowDecodeError(!hasNoEmptyEntry)
+ }, [])
+
+ return (
+ <>
+ {!hasTemplate && (
+ <>
+ (
+
+ {val}
+
+ ),
+ }}
+ component="p"
+ />
+
+ >
+ )}
+ {mayReactivate && (
+
+ ),
+ }}
+ children={
+
+ }
+ small
+ />
+ )}
+ {isPending && }
+
+ {hasTemplate && }
+
+
+
+
+
+
+
+ {shouldShowCredentialsInput && (
+
+
+
-
- >
+
)}
- {mayReactivate && (
+ {showDecodeError && (
- ),
- }}
- children={
-
+ content={
+ 'Something went wrong and the contents of the Authorization header could not be decoded.'
}
small
+ className="mt-cs-xl"
/>
)}
- {isPending && }
-
- {hasTemplate && }
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- {this.state.shouldShowCredentialsInput && (
-
-
-
-
- )}
- {this.state.showDecodeError && (
-
)}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {update && (
-
- )}
-
-
- >
- )
- }
+
+
+ >
+ )
+}
+
+WebhookForm.propTypes = {
+ error: PropTypes.error,
+ existCheck: PropTypes.func,
+ hasUnhealthyWebhookConfig: PropTypes.bool,
+ healthStatusEnabled: PropTypes.bool,
+ initialWebhookValue: PropTypes.shape({
+ ids: PropTypes.shape({
+ webhook_id: PropTypes.string,
+ }),
+ health_status: PropTypes.shape({
+ healthy: PropTypes.shape({}),
+ unhealthy: PropTypes.shape({}),
+ }),
+ headers: PropTypes.shape({
+ Authorization: PropTypes.string,
+ }),
+ }),
+ onDelete: PropTypes.func,
+ onDeleteFailure: PropTypes.func,
+ onDeleteSuccess: PropTypes.func,
+ onReactivate: PropTypes.func,
+ onReactivateSuccess: PropTypes.func,
+ onSubmit: PropTypes.func.isRequired,
+ update: PropTypes.bool.isRequired,
+ webhookRetryInterval: PropTypes.string,
+ webhookTemplate: PropTypes.webhookTemplate,
+}
+
+WebhookForm.defaultProps = {
+ initialWebhookValue: undefined,
+ onReactivate: () => null,
+ onReactivateSuccess: () => null,
+ onDeleteFailure: () => null,
+ onDeleteSuccess: () => null,
+ onDelete: () => null,
+ webhookTemplate: undefined,
+ healthStatusEnabled: false,
+ error: undefined,
+ existCheck: () => null,
+ webhookRetryInterval: null,
+ hasUnhealthyWebhookConfig: false,
}
+export default WebhookForm
diff --git a/pkg/webui/console/components/webhook-template-form/index.js b/pkg/webui/console/components/webhook-template-form/index.js
index bed01ea334..77125de8f9 100644
--- a/pkg/webui/console/components/webhook-template-form/index.js
+++ b/pkg/webui/console/components/webhook-template-form/index.js
@@ -1,4 +1,4 @@
-// Copyright © 2020 The Things Network Foundation, The Things Industries B.V.
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,9 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import React, { Component } from 'react'
+import React, { useCallback, useMemo, useRef, useState } from 'react'
import { defineMessages } from 'react-intl'
-import bind from 'autobind-decorator'
import Form from '@ttn-lw/components/form'
import Input from '@ttn-lw/components/input'
@@ -34,133 +33,136 @@ const m = defineMessages({
idPlaceholder: 'my-new-{templateId}-webhook',
})
-export default class WebhookTemplateForm extends Component {
- static propTypes = {
- convertTemplateToWebhook: PropTypes.func.isRequired,
- error: PropTypes.string,
- existCheck: PropTypes.func,
- onSubmit: PropTypes.func.isRequired,
- templateId: PropTypes.string.isRequired,
- webhookTemplate: PropTypes.webhookTemplate.isRequired,
- }
-
- static defaultProps = {
- error: undefined,
- existCheck: () => null,
- }
-
- modalResolve = () => null
- modalReject = () => null
-
- state = {
- displayOverwriteModal: false,
- existingId: undefined,
- }
-
- @bind
- handleReplaceModalDecision(mayReplace) {
+const WebhookTemplateForm = props => {
+ const [displayOverwriteModal, setDisplayOverwriteModal] = useState(false)
+ const [existingId, setExistingId] = useState(undefined)
+ const modalResolve = useRef(null)
+ const modalReject = useRef(null)
+
+ const { convertTemplateToWebhook, error, existCheck, onSubmit, templateId, webhookTemplate } =
+ props
+
+ const handleReplaceModalDecision = useCallback(mayReplace => {
+ if (!modalResolve.current || !modalReject.current) return
if (mayReplace) {
- this.modalResolve()
+ modalResolve.current()
} else {
- this.modalReject()
+ modalReject.current()
}
- this.setState({ displayOverwriteModal: false })
- }
-
- @bind
- async handleSubmit(values, { setSubmitting, resetForm }) {
- const { onSubmit, convertTemplateToWebhook, existCheck } = this.props
- const webhook = await convertTemplateToWebhook(values)
- const webhookId = webhook.ids.webhook_id
- const exists = await existCheck(webhookId)
- if (exists) {
- this.setState({ displayOverwriteModal: true, existingId: webhookId })
- await new Promise((resolve, reject) => {
- this.modalResolve = resolve
- this.modalReject = reject
- })
- }
- await onSubmit(values, webhook, { setSubmitting, resetForm })
- }
-
- render() {
- const { templateId, webhookTemplate, error } = this.props
- const { name, fields = [] } = webhookTemplate
-
- const validationSchema = Yup.object({
- ...fields.reduce(
- (acc, field) => ({
- ...acc,
- [field.id]: field.optional
- ? Yup.string()
- : Yup.string().required(sharedMessages.validateRequired),
- }),
- {
- webhook_id: Yup.string()
- .min(3, Yup.passValues(sharedMessages.validateTooShort))
- .max(36, Yup.passValues(sharedMessages.validateTooLong))
- .matches(webhookIdRegexp, Yup.passValues(sharedMessages.validateIdFormat))
- .required(sharedMessages.validateRequired),
- },
- ),
- })
-
- const initialValues = fields.reduce(
- (acc, field) => ({ ...acc, [field.id]: field.default_value || '' }),
+ setDisplayOverwriteModal(false)
+ }, [])
+
+ const handleSubmit = useCallback(
+ async (values, { setSubmitting, resetForm }) => {
+ const webhook = await convertTemplateToWebhook(values)
+ const webhookId = webhook.ids.webhook_id
+ const exists = await existCheck(webhookId)
+ if (exists) {
+ setDisplayOverwriteModal(true)
+ setExistingId(webhookId)
+ await new Promise((resolve, reject) => {
+ modalResolve.current = resolve
+ modalReject.current = reject
+ })
+ }
+ await onSubmit(values, webhook, { setSubmitting, resetForm })
+ },
+ [convertTemplateToWebhook, existCheck, onSubmit],
+ )
+
+ const { name, fields = [] } = webhookTemplate
+
+ const validationSchema = Yup.object({
+ ...fields.reduce(
+ (acc, field) => ({
+ ...acc,
+ [field.id]: field.optional
+ ? Yup.string()
+ : Yup.string().required(sharedMessages.validateRequired),
+ }),
{
- webhook_id: '',
+ webhook_id: Yup.string()
+ .min(3, Yup.passValues(sharedMessages.validateTooShort))
+ .max(36, Yup.passValues(sharedMessages.validateTooLong))
+ .matches(webhookIdRegexp, Yup.passValues(sharedMessages.validateIdFormat))
+ .required(sharedMessages.validateRequired),
},
- )
- return (
-
-
+ fields.reduce((acc, field) => ({ ...acc, [field.id]: field.default_value || '' }), {
+ webhook_id: '',
+ }),
+ [fields],
+ )
+
+ return (
+
+
+
+
+
-
-
+ {fields.map(field => (
- {fields.map(field => (
-
- ))}
-
-
-
-
-
- )
- }
+ ))}
+
+
+
+
+
+ )
+}
+
+WebhookTemplateForm.propTypes = {
+ convertTemplateToWebhook: PropTypes.func.isRequired,
+ error: PropTypes.string,
+ existCheck: PropTypes.func,
+ onSubmit: PropTypes.func.isRequired,
+ templateId: PropTypes.string.isRequired,
+ webhookTemplate: PropTypes.webhookTemplate.isRequired,
+}
+
+WebhookTemplateForm.defaultProps = {
+ error: undefined,
+ existCheck: () => null,
}
+
+export default WebhookTemplateForm
diff --git a/pkg/webui/console/components/webhook-template-info/index.js b/pkg/webui/console/components/webhook-template-info/index.js
index 6189f6c53b..24e2928178 100644
--- a/pkg/webui/console/components/webhook-template-info/index.js
+++ b/pkg/webui/console/components/webhook-template-info/index.js
@@ -25,7 +25,6 @@ import style from './webhook-template-info.styl'
const m = defineMessages({
about: 'About {name}',
- documentation: 'Documentation',
setupWebhook: 'Setup webhook for {name}',
editWebhook: 'Edit webhook for {name}',
})
diff --git a/pkg/webui/console/containers/account-select/index.js b/pkg/webui/console/containers/account-select/index.js
index 1ec9803554..de1dcf94a3 100644
--- a/pkg/webui/console/containers/account-select/index.js
+++ b/pkg/webui/console/containers/account-select/index.js
@@ -13,7 +13,7 @@
// limitations under the License.
import React, { useCallback, useRef } from 'react'
-import { defineMessages, useIntl } from 'react-intl'
+import { useIntl } from 'react-intl'
import { useDispatch, useSelector } from 'react-redux'
import { components } from 'react-select'
@@ -25,6 +25,7 @@ import PropTypes from '@ttn-lw/lib/prop-types'
import attachPromise from '@ttn-lw/lib/store/actions/attach-promise'
import { searchAccounts } from '@ttn-lw/lib/store/actions/search-accounts'
import { selectSearchResultAccountIds } from '@ttn-lw/lib/store/selectors/search-accounts'
+import sharedMessages from '@ttn-lw/lib/shared-messages'
import styles from './account-select.styl'
@@ -44,18 +45,16 @@ SingleValue.propTypes = {
}).isRequired,
}
-const m = defineMessages({
- noOptionsMessage: 'No matching user or organization was found',
- suggestions: 'Suggestions',
-})
-
const Suggest = ({ entity, ...rest }) => {
const dispatch = useDispatch()
const searchResults = useSelector(selectSearchResultAccountIds)
const searchResultsRef = useRef()
searchResultsRef.current = searchResults
const { formatMessage } = useIntl()
- const handleNoOptions = useCallback(() => formatMessage(m.noOptionsMessage), [formatMessage])
+ const noOptionsMessage = useCallback(
+ () => formatMessage(sharedMessages.noMatchingUserFound),
+ [formatMessage],
+ )
const onlyUsers = entity === 'organization'
const handleLoadingOptions = useCallback(
@@ -95,7 +94,7 @@ const Suggest = ({ entity, ...rest }) => {
component={Select.Suggested}
openMenuOnFocus={false}
openMenuOnClick={false}
- noOptionsMessage={handleNoOptions}
+ noOptionsMessage={noOptionsMessage}
loadOptions={handleLoadingOptions}
autoFocus
showOptionIcon
diff --git a/pkg/webui/console/containers/api-keys-table/index.js b/pkg/webui/console/containers/api-keys-table/index.js
index 4101cdffe8..091ff05b0f 100644
--- a/pkg/webui/console/containers/api-keys-table/index.js
+++ b/pkg/webui/console/containers/api-keys-table/index.js
@@ -29,7 +29,6 @@ import sharedMessages from '@ttn-lw/lib/shared-messages'
import style from './api-keys-table.styl'
const m = defineMessages({
- keyId: 'Key ID',
grantedRights: 'Granted Rights',
})
@@ -42,7 +41,7 @@ const ApiKeysTable = props => {
const headers = [
{
name: 'id',
- displayName: m.keyId,
+ displayName: sharedMessages.keyId,
width: 20,
sortKey: 'api_key_id',
render: id => {id} ,
diff --git a/pkg/webui/console/containers/application-events/index.js b/pkg/webui/console/containers/application-events/index.js
index 8cd3854e74..f39f2d0349 100644
--- a/pkg/webui/console/containers/application-events/index.js
+++ b/pkg/webui/console/containers/application-events/index.js
@@ -12,12 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import React from 'react'
-import { connect } from 'react-redux'
+import React, { useCallback, useMemo } from 'react'
+import { useDispatch, useSelector } from 'react-redux'
import Events from '@console/components/events'
-import withFeatureRequirement from '@console/lib/components/with-feature-requirement'
+import Require from '@console/lib/components/require'
import PropTypes from '@ttn-lw/lib/prop-types'
@@ -38,75 +38,68 @@ import {
} from '@console/store/selectors/applications'
const ApplicationEvents = props => {
- const {
- appId,
- events,
- widget,
- paused,
- onClear,
- onPauseToggle,
- truncated,
- onFilterChange,
- filter,
- } = props
-
- if (widget) {
+ const { appId, widget } = props
+
+ const events = useSelector(state => selectApplicationEvents(state, appId))
+ const paused = useSelector(state => selectApplicationEventsPaused(state, appId))
+ const truncated = useSelector(state => selectApplicationEventsTruncated(state, appId))
+ const filter = useSelector(state => selectApplicationEventsFilter(state, appId))
+
+ const dispatch = useDispatch()
+
+ const onClear = useCallback(() => {
+ dispatch(clearApplicationEventsStream(appId))
+ }, [appId, dispatch])
+
+ const onPauseToggle = useCallback(
+ paused => {
+ if (paused) {
+ dispatch(resumeApplicationEventsStream(appId))
+ return
+ }
+ dispatch(pauseApplicationEventsStream(appId))
+ },
+ [appId, dispatch],
+ )
+
+ const onFilterChange = useCallback(
+ filterId => {
+ dispatch(setApplicationEventsFilter(appId, filterId))
+ },
+ [appId, dispatch],
+ )
+
+ const content = useMemo(() => {
+ if (widget) {
+ return (
+
+ )
+ }
+
return (
-
+
)
- }
-
- return (
-
- )
+ }, [appId, events, filter, onClear, onFilterChange, onPauseToggle, paused, truncated, widget])
+
+ return {content}
}
ApplicationEvents.propTypes = {
appId: PropTypes.string.isRequired,
- events: PropTypes.events,
- filter: PropTypes.eventFilter,
- onClear: PropTypes.func.isRequired,
- onFilterChange: PropTypes.func.isRequired,
- onPauseToggle: PropTypes.func.isRequired,
- paused: PropTypes.bool.isRequired,
- truncated: PropTypes.bool.isRequired,
widget: PropTypes.bool,
}
ApplicationEvents.defaultProps = {
widget: false,
- events: [],
- filter: undefined,
}
-export default withFeatureRequirement(mayViewApplicationEvents)(
- connect(
- (state, props) => {
- const { appId } = props
-
- return {
- events: selectApplicationEvents(state, appId),
- paused: selectApplicationEventsPaused(state, appId),
- truncated: selectApplicationEventsTruncated(state, appId),
- filter: selectApplicationEventsFilter(state, appId),
- }
- },
- (dispatch, ownProps) => ({
- onClear: () => dispatch(clearApplicationEventsStream(ownProps.appId)),
- onPauseToggle: paused =>
- paused
- ? dispatch(resumeApplicationEventsStream(ownProps.appId))
- : dispatch(pauseApplicationEventsStream(ownProps.appId)),
- onFilterChange: filterId => dispatch(setApplicationEventsFilter(ownProps.appId, filterId)),
- }),
- )(ApplicationEvents),
-)
+export default ApplicationEvents
diff --git a/pkg/webui/console/containers/applications-form/index.js b/pkg/webui/console/containers/applications-form/index.js
index f0ee31b73c..e74ac93b38 100644
--- a/pkg/webui/console/containers/applications-form/index.js
+++ b/pkg/webui/console/containers/applications-form/index.js
@@ -45,7 +45,6 @@ const m = defineMessages({
'Optional application description; can also be used to save notes about the application',
appDescription:
'Within applications, you can register and manage end devices, aggregate their sensor data and act on it using our many integration options.{break}Learn more in our Applications Guide',
- createApplication: 'Create application',
})
const validationSchema = Yup.object().shape({
@@ -141,7 +140,7 @@ const ApplicationForm = props => {
component={Input}
/>
-
+
)
diff --git a/pkg/webui/console/containers/collaborators-table/index.js b/pkg/webui/console/containers/collaborators-table/index.js
index 4ff2bba690..e606b67bf7 100644
--- a/pkg/webui/console/containers/collaborators-table/index.js
+++ b/pkg/webui/console/containers/collaborators-table/index.js
@@ -13,9 +13,9 @@
// limitations under the License.
import React from 'react'
-import { defineMessages, useIntl } from 'react-intl'
import { createSelector } from 'reselect'
import { useSelector } from 'react-redux'
+import { useIntl } from 'react-intl'
import Tag from '@ttn-lw/components/tag'
import TagGroup from '@ttn-lw/components/tag/group'
@@ -36,10 +36,6 @@ import style from './collaborators-table.styl'
const RIGHT_TAG_MAX_WIDTH = 140
-const m = defineMessages({
- id: 'User / Organization ID',
-})
-
const rowKeySelector = row => row._type
const getCollaboratorPathPrefix = collaborator =>
@@ -54,7 +50,7 @@ const CollaboratorsTable = props => {
const headers = [
{
name: 'ids',
- displayName: m.id,
+ displayName: sharedMessages.userOrgId,
sortable: true,
sortKey: 'id',
width: 30,
diff --git a/pkg/webui/console/containers/dev-eui-component/index.js b/pkg/webui/console/containers/dev-eui-component/index.js
index 7e335d6020..e88df9cbff 100644
--- a/pkg/webui/console/containers/dev-eui-component/index.js
+++ b/pkg/webui/console/containers/dev-eui-component/index.js
@@ -15,6 +15,7 @@
import React, { useState, useCallback } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import classnames from 'classnames'
+import { defineMessages } from 'react-intl'
import Input from '@ttn-lw/components/input'
import Form, { useFormContext } from '@ttn-lw/components/form'
@@ -37,6 +38,10 @@ import {
import style from './dev-eui.styl'
+const m = defineMessages({
+ unknownError: 'Unknown error while generating DevEUI',
+})
+
const DevEUIComponent = props => {
const { name, required, disabled, autoFocus } = props
const { values, setFieldValue, touched } = useFormContext()
@@ -93,7 +98,7 @@ const DevEUIComponent = props => {
} catch (error) {
if (getBackendErrorName(error) === 'global_eui_limit_reached') {
setErrorMessage(sharedMessages.devEUIBlockLimitReached)
- } else setErrorMessage(sharedMessages.unknownError)
+ } else setErrorMessage(m.unknownError)
setDevEUIGenerated(true)
}
}, [handleDevEUIRequest, handleIdPrefill])
diff --git a/pkg/webui/console/containers/device-events/index.js b/pkg/webui/console/containers/device-events/index.js
index c415b47f55..9b93c57c08 100644
--- a/pkg/webui/console/containers/device-events/index.js
+++ b/pkg/webui/console/containers/device-events/index.js
@@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import React from 'react'
-import { connect } from 'react-redux'
+import React, { useCallback } from 'react'
+import { useDispatch, useSelector } from 'react-redux'
import Events from '@console/components/events'
@@ -35,18 +35,40 @@ import {
} from '@console/store/selectors/devices'
const DeviceEvents = props => {
- const {
- appId,
- devId,
- events,
- widget,
- paused,
- onClear,
- onPauseToggle,
- onFilterChange,
- truncated,
- filter,
- } = props
+ const { devIds, widget } = props
+
+ const appId = getApplicationId(devIds)
+ const devId = getDeviceId(devIds)
+ const combinedId = combineDeviceIds(appId, devId)
+
+ const events = useSelector(state => selectDeviceEvents(state, combinedId))
+ const paused = useSelector(state => selectDeviceEventsPaused(state, combinedId))
+ const truncated = useSelector(state => selectDeviceEventsTruncated(state, combinedId))
+ const filter = useSelector(state => selectDeviceEventsFilter(state, combinedId))
+
+ const dispatch = useDispatch()
+
+ const onClear = useCallback(() => {
+ dispatch(clearDeviceEventsStream(devIds))
+ }, [devIds, dispatch])
+
+ const onPauseToggle = useCallback(
+ paused => {
+ if (paused) {
+ dispatch(resumeDeviceEventsStream(devIds))
+ return
+ }
+ dispatch(pauseDeviceEventsStream(devIds))
+ },
+ [devIds, dispatch],
+ )
+
+ const onFilterChange = useCallback(
+ filterId => {
+ dispatch(setDeviceEventsFilter(devIds, filterId))
+ },
+ [devIds, dispatch],
+ )
if (widget) {
return (
@@ -76,57 +98,17 @@ const DeviceEvents = props => {
}
DeviceEvents.propTypes = {
- appId: PropTypes.string.isRequired,
- devId: PropTypes.string.isRequired,
devIds: PropTypes.shape({
device_id: PropTypes.string,
application_ids: PropTypes.shape({
application_id: PropTypes.string,
}),
}).isRequired,
- events: PropTypes.events,
- filter: PropTypes.eventFilter,
- onClear: PropTypes.func.isRequired,
- onFilterChange: PropTypes.func.isRequired,
- onPauseToggle: PropTypes.func.isRequired,
- paused: PropTypes.bool.isRequired,
- truncated: PropTypes.bool.isRequired,
widget: PropTypes.bool,
}
DeviceEvents.defaultProps = {
widget: false,
- events: [],
- filter: undefined,
}
-export default connect(
- (state, props) => {
- const { devIds } = props
-
- const appId = getApplicationId(devIds)
- const devId = getDeviceId(devIds)
- const combinedId = combineDeviceIds(appId, devId)
-
- return {
- devId,
- appId,
- events: selectDeviceEvents(state, combinedId),
- paused: selectDeviceEventsPaused(state, combinedId),
- truncated: selectDeviceEventsTruncated(state, combinedId),
- filter: selectDeviceEventsFilter(state, combinedId),
- }
- },
- (dispatch, ownProps) => {
- const { devIds } = ownProps
-
- return {
- onClear: () => dispatch(clearDeviceEventsStream(devIds)),
- onPauseToggle: paused =>
- paused
- ? dispatch(resumeDeviceEventsStream(devIds))
- : dispatch(pauseDeviceEventsStream(devIds)),
- onFilterChange: filterId => dispatch(setDeviceEventsFilter(devIds, filterId)),
- }
- },
-)(DeviceEvents)
+export default DeviceEvents
diff --git a/pkg/webui/console/containers/device-importer/index.js b/pkg/webui/console/containers/device-importer/index.js
index 85a94377c0..b6b24bad15 100644
--- a/pkg/webui/console/containers/device-importer/index.js
+++ b/pkg/webui/console/containers/device-importer/index.js
@@ -155,7 +155,7 @@ const DeviceImporter = () => {
devices = await new Promise((resolve, reject) => {
const chunks = []
- templateStream.on('chunk', message => {
+ templateStream.on('message', message => {
appendToLog(message)
chunks.push(message)
})
@@ -252,7 +252,7 @@ const DeviceImporter = () => {
createStream.current = tts.Applications.Devices.bulkCreate(appId, devices)
await new Promise(resolve => {
- createStream.current.on('chunk', handleCreationSuccess)
+ createStream.current.on('message', handleCreationSuccess)
createStream.current.on('error', handleCreationError)
createStream.current.on('close', resolve)
diff --git a/pkg/webui/console/containers/device-onboarding-form/index.js b/pkg/webui/console/containers/device-onboarding-form/index.js
index 79f8a1e8e1..98dc5c5d60 100644
--- a/pkg/webui/console/containers/device-onboarding-form/index.js
+++ b/pkg/webui/console/containers/device-onboarding-form/index.js
@@ -26,6 +26,7 @@ import Notification from '@ttn-lw/components/notification'
import attachPromise from '@ttn-lw/lib/store/actions/attach-promise'
import { selectAsEnabled, selectJsEnabled, selectNsEnabled } from '@ttn-lw/lib/selectors/env'
+import sharedMessages from '@ttn-lw/lib/shared-messages'
import { checkFromState } from '@account/lib/feature-checks'
import { mayEditApplicationDeviceKeys } from '@console/lib/feature-checks'
@@ -73,7 +74,7 @@ const DeviceOnboardingFormInner = () => {
-
+
>
)}
diff --git a/pkg/webui/console/containers/device-onboarding-form/messages.js b/pkg/webui/console/containers/device-onboarding-form/messages.js
index c0f45cd1cc..922f343007 100644
--- a/pkg/webui/console/containers/device-onboarding-form/messages.js
+++ b/pkg/webui/console/containers/device-onboarding-form/messages.js
@@ -30,9 +30,9 @@ export default defineMessages({
confirmedClaiming: 'This end device can be claimed',
cannotConfirmEui:
'There was an error and the JoinEUI could not be confirmed. Please try again later.',
+
// Shared messages.
classCapabilities: 'Additional LoRaWAN class capabilities',
- submitTitle: 'Register end device',
afterRegistration: 'After registration',
singleRegistration: 'View registered end device',
multipleRegistration: 'Register another end device of this type',
@@ -40,29 +40,16 @@ export default defineMessages({
deviceIdDescription: 'This value is automatically prefilled using the DevEUI',
onboardingDisabled:
'Device onboarding can only be performed on deployments that have Network Server, Application Server and Join Server activated. Please use the CLI to register devices on individual components.',
- // Manual messages.
- beaconFrequency: 'Beacon frequency',
- rx1DataRateOffsetTitle: 'Rx1 data rate offset',
- rx1DelayTitle: 'Rx1 delay',
- factoryPresetFreqTitle: 'Factory preset frequencies',
- freqAdd: 'Add Frequency',
- frequencyPlaceholder: 'e.g. 869525000 for 869,525 MHz',
- pingSlotPeriodicityTitle: 'Ping slot periodicity',
- pingSlotPeriodicityValue: '{count, plural, one {every second} other {every {count} seconds}}',
pingSlotDataRateTitle: 'Ping slot data rate',
- pingSlotFrequencyTitle: 'Ping slot frequency',
rx2DataRateIndexTitle: 'Rx2 data rate',
- rx2FrequencyTitle: 'Rx2 frequency',
- classBTimeout: 'Class B timeout',
- classCTimeout: 'Class C timeout',
defaultNetworksSettings: "Use network's default MAC settings",
clusterSettings: 'Cluster settings',
networkDefaults: 'Network defaults',
+
// QR code section.
hasEndDeviceQR:
'Does your end device have a LoRaWAN® Device Identification QR Code? Scan it to speed up onboarding.',
deviceGuide: 'Device registration help',
- scanEndDevice: 'Scan end device QR code',
deviceInfo: 'Found QR code data',
resetQRCodeData: 'Reset QR code data',
resetConfirm:
diff --git a/pkg/webui/console/containers/device-onboarding-form/qr-scan-form-section/index.js b/pkg/webui/console/containers/device-onboarding-form/qr-scan-form-section/index.js
index 2029cb40f8..6f14b9b4ac 100644
--- a/pkg/webui/console/containers/device-onboarding-form/qr-scan-form-section/index.js
+++ b/pkg/webui/console/containers/device-onboarding-form/qr-scan-form-section/index.js
@@ -177,7 +177,7 @@ const DeviceQRScanFormSection = () => {
/>
) : (
{freqPlan} frequency plan could not be loaded',
- fpNotFoundError:
- 'The LoRaWAN version {lorawanVersion}
does not support the {freqPlan}
frequency plan. Please choose a different MAC version or frequency plan.',
})
const emptyDefaultMacSettings = {}
@@ -154,7 +150,7 @@ const pingSlotPeriodicityOptions = Array.from({ length: 8 }, (_, index) => {
return {
value: `PING_EVERY_${value}S`,
- label: ,
+ label: ,
}
})
@@ -230,7 +226,7 @@ const AdvancedSettingsSection = () => {
if (isBackend(err) && getBackendErrorName(err) === 'no_band_version') {
toast({
type: toast.types.ERROR,
- message: m.fpNotFoundError,
+ message: sharedMessages.fpNotFoundError,
messageValues: {
lorawanVersion: lorawan_phy_version,
freqPlan: frequency_plan_id,
@@ -240,7 +236,7 @@ const AdvancedSettingsSection = () => {
} else {
toast({
type: toast.types.ERROR,
- message: m.macSettingsError,
+ message: sharedMessages.macSettingsError,
messageValues: {
freqPlan: frequency_plan_id,
code: msg => {msg}
,
@@ -336,7 +332,7 @@ const AdvancedSettingsSection = () => {
{
{
}
/>
{
type="number"
min={100000}
required={!isUndefined(defaultMacSettings.beacon_frequency)}
- title={messages.beaconFrequency}
- placeholder={messages.frequencyPlaceholder}
+ title={sharedMessages.beaconFrequency}
+ placeholder={sharedMessages.frequencyPlaceholder}
name="mac_settings.beacon_frequency"
tooltipId={tooltipIds.BEACON_FREQUENCY}
component={UnitInput.Hertz}
@@ -450,8 +446,8 @@ const AdvancedSettingsSection = () => {
type="number"
min={100000}
required={!isUndefined(defaultMacSettings.ping_slot_frequency)}
- title={messages.pingSlotFrequencyTitle}
- placeholder={messages.frequencyPlaceholder}
+ title={sharedMessages.pingSlotFrequency}
+ placeholder={sharedMessages.frequencyPlaceholder}
name="mac_settings.ping_slot_frequency"
tooltipId={tooltipIds.PING_SLOT_FREQUENCY}
component={UnitInput.Hertz}
@@ -470,7 +466,7 @@ const AdvancedSettingsSection = () => {
{isClassC && (
{
min={100000}
step={100}
required={!isUndefined(defaultMacSettings.rx2_frequency)}
- title={messages.rx2FrequencyTitle}
- placeholder={messages.frequencyPlaceholder}
+ title={sharedMessages.rx2Frequency}
+ placeholder={sharedMessages.frequencyPlaceholder}
name="mac_settings.rx2_frequency"
tooltipId={tooltipIds.RX2_FREQUENCY}
component={UnitInput.Hertz}
@@ -528,9 +524,9 @@ const AdvancedSettingsSection = () => {
indexAsKey
name="mac_settings.factory_preset_frequencies"
component={KeyValueMap}
- title={messages.factoryPresetFreqTitle}
+ title={sharedMessages.factoryPresetFrequencies}
addMessage={messages.freqAdd}
- valuePlaceholder={messages.frequencyPlaceholder}
+ valuePlaceholder={sharedMessages.frequencyPlaceholder}
tooltipId={tooltipIds.FACTORY_PRESET_FREQUENCIES}
encode={factoryPresetFreqEncoder}
decode={factoryPresetFreqDecoder}
diff --git a/pkg/webui/console/containers/device-profile-section/device-card/device-card.js b/pkg/webui/console/containers/device-profile-section/device-card/device-card.js
deleted file mode 100644
index 4f1df2165c..0000000000
--- a/pkg/webui/console/containers/device-profile-section/device-card/device-card.js
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright © 2022 The Things Network Foundation, The Things Industries B.V.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import React from 'react'
-import { defineMessages, useIntl } from 'react-intl'
-
-import devicePlaceholder from '@assets/misc/end-device-placeholder.svg'
-
-import Link from '@ttn-lw/components/link'
-
-import Message from '@ttn-lw/lib/components/message'
-
-import PropTypes from '@ttn-lw/lib/prop-types'
-import sharedMessages from '@ttn-lw/lib/shared-messages'
-
-import { getLorawanVersionLabel, getLorawanPhyVersionLabel } from '@console/lib/device-utils'
-
-import style from './device-card.styl'
-
-const m = defineMessages({
- productWebsite: 'Product website',
- dataSheet: 'Data sheet',
- classA: 'Class A',
- classB: 'Class B',
- classC: 'Class C',
-})
-
-const DeviceCard = props => {
- const { model, template } = props
- const { name, description, product_url, datasheet_url, photos = {} } = model
- const { end_device: device } = template
- const { formatMessage } = useIntl()
-
- const deviceImage = photos.main || devicePlaceholder
- const lwVersionLabel = getLorawanVersionLabel(device)
- const lwPhyVersionLabel = getLorawanPhyVersionLabel(device)
- const modeTitleLabel = device.supports_join
- ? sharedMessages.otaa
- : device.multicast
- ? sharedMessages.multicast
- : sharedMessages.abp
- const deviceClassTitleLabel = device.supports_class_c
- ? m.classC
- : device.supports_class_b
- ? m.classB
- : m.classA
- const hasLinks = Boolean(product_url || datasheet_url)
-
- return (
-
-
-
-
-
{name}
- {Boolean(lwVersionLabel) && (
-
- {lwVersionLabel}
-
- )}
- {Boolean(lwPhyVersionLabel) && (
-
- {lwPhyVersionLabel}
-
- )}
-
-
-
- {description &&
{description}
}
- {hasLinks && (
-
- {product_url && (
-
-
-
- )}
- {product_url && datasheet_url && (
- |
- )}
- {datasheet_url && (
-
-
-
- )}
-
- )}
-
-
- )
-}
-
-DeviceCard.propTypes = {
- model: PropTypes.shape({
- name: PropTypes.string,
- description: PropTypes.string,
- product_url: PropTypes.string,
- datasheet_url: PropTypes.string,
- photos: PropTypes.shape({
- main: PropTypes.string,
- }),
- }),
- template: PropTypes.deviceTemplate.isRequired,
-}
-DeviceCard.defaultProps = {
- model: {
- name: undefined,
- },
-}
-
-export default DeviceCard
diff --git a/pkg/webui/console/containers/device-profile-section/device-card/index.js b/pkg/webui/console/containers/device-profile-section/device-card/index.js
index 5d85032ccb..cd719906eb 100644
--- a/pkg/webui/console/containers/device-profile-section/device-card/index.js
+++ b/pkg/webui/console/containers/device-profile-section/device-card/index.js
@@ -1,4 +1,4 @@
-// Copyright © 2022 The Things Network Foundation, The Things Industries B.V.
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,9 +12,110 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import connect from './connect'
-import DeviceCard from './device-card'
+import React from 'react'
+import { defineMessages, useIntl } from 'react-intl'
+import { useSelector } from 'react-redux'
-const ConnectedDeviceCard = connect(DeviceCard)
+import devicePlaceholder from '@assets/misc/end-device-placeholder.svg'
-export { ConnectedDeviceCard as default, DeviceCard }
+import Link from '@ttn-lw/components/link'
+
+import Message from '@ttn-lw/lib/components/message'
+
+import PropTypes from '@ttn-lw/lib/prop-types'
+import sharedMessages from '@ttn-lw/lib/shared-messages'
+
+import { getLorawanVersionLabel, getLorawanPhyVersionLabel } from '@console/lib/device-utils'
+
+import { selectDeviceModelById } from '@console/store/selectors/device-repository'
+
+import style from './device-card.styl'
+
+const m = defineMessages({
+ productWebsite: 'Product website',
+ dataSheet: 'Data sheet',
+ classA: 'Class A',
+ classB: 'Class B',
+ classC: 'Class C',
+})
+
+const DeviceCard = props => {
+ const { brandId, modelId, template } = props
+ const { end_device: device } = template
+ const { formatMessage } = useIntl()
+ const model = useSelector(state => selectDeviceModelById(state, brandId, modelId))
+ const { name, description, product_url, datasheet_url, photos = {} } = model
+ const deviceImage = photos.main || devicePlaceholder
+ const lwVersionLabel = getLorawanVersionLabel(device)
+ const lwPhyVersionLabel = getLorawanPhyVersionLabel(device)
+ const modeTitleLabel = device.supports_join
+ ? sharedMessages.otaa
+ : device.multicast
+ ? sharedMessages.multicast
+ : sharedMessages.abp
+ const deviceClassTitleLabel = device.supports_class_c
+ ? m.classC
+ : device.supports_class_b
+ ? m.classB
+ : m.classA
+ const hasLinks = Boolean(product_url || datasheet_url)
+
+ return (
+
+
+
+
+
{name}
+ {Boolean(lwVersionLabel) && (
+
+ {lwVersionLabel}
+
+ )}
+ {Boolean(lwPhyVersionLabel) && (
+
+ {lwPhyVersionLabel}
+
+ )}
+
+
+
+ {description &&
{description}
}
+ {hasLinks && (
+
+ {product_url && (
+
+
+
+ )}
+ {product_url && datasheet_url && (
+ |
+ )}
+ {datasheet_url && (
+
+
+
+ )}
+
+ )}
+
+
+ )
+}
+
+DeviceCard.propTypes = {
+ brandId: PropTypes.string.isRequired,
+ modelId: PropTypes.string.isRequired,
+ template: PropTypes.deviceTemplate.isRequired,
+}
+
+export default DeviceCard
diff --git a/pkg/webui/console/containers/device-profile-section/device-selection/brand-select/brand-select.js b/pkg/webui/console/containers/device-profile-section/device-selection/brand-select/brand-select.js
deleted file mode 100644
index 939a575fd2..0000000000
--- a/pkg/webui/console/containers/device-profile-section/device-selection/brand-select/brand-select.js
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright © 2022 The Things Network Foundation, The Things Industries B.V.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import React from 'react'
-import { defineMessages, useIntl } from 'react-intl'
-
-import Field from '@ttn-lw/components/form/field'
-import Select from '@ttn-lw/components/select'
-
-import PropTypes from '@ttn-lw/lib/prop-types'
-import sharedMessages from '@ttn-lw/lib/shared-messages'
-
-import { SELECT_OTHER_OPTION } from '@console/lib/device-utils'
-
-const m = defineMessages({
- title: 'End device brand',
- warning: 'End device models unavailable',
- noOptionsMessage: 'No matching brand found',
-})
-
-const formatOptions = (brands = []) =>
- brands
- .map(brand => ({
- value: brand.brand_id,
- label: brand.name || brand.brand_id,
- profileID: brand.brand_id,
- }))
- .concat([{ value: SELECT_OTHER_OPTION, label: sharedMessages.otherOption }])
-
-const BrandSelect = props => {
- const { appId, name, error, fetching, brands, onChange, ...rest } = props
- const { formatMessage } = useIntl()
-
- const options = React.useMemo(() => formatOptions(brands), [brands])
- const handleNoOptions = React.useCallback(
- () => formatMessage(m.noOptionsMessage),
- [formatMessage],
- )
-
- return (
-
- )
-}
-
-BrandSelect.propTypes = {
- appId: PropTypes.string.isRequired,
- brands: PropTypes.arrayOf(
- PropTypes.shape({
- brand_id: PropTypes.string.isRequired,
- }),
- ),
- error: PropTypes.error,
- fetching: PropTypes.bool,
- name: PropTypes.string.isRequired,
- onChange: PropTypes.func,
-}
-
-BrandSelect.defaultProps = {
- error: undefined,
- fetching: false,
- brands: [],
- onChange: () => null,
-}
-
-export default BrandSelect
diff --git a/pkg/webui/console/containers/device-profile-section/device-selection/brand-select/connect.js b/pkg/webui/console/containers/device-profile-section/device-selection/brand-select/connect.js
deleted file mode 100644
index 7eda01f495..0000000000
--- a/pkg/webui/console/containers/device-profile-section/device-selection/brand-select/connect.js
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright © 2022 The Things Network Foundation, The Things Industries B.V.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import { connect } from 'react-redux'
-
-import {
- selectDeviceBrands,
- selectDeviceBrandsError,
- selectDeviceBrandsFetching,
-} from '@console/store/selectors/device-repository'
-import { selectSelectedApplicationId } from '@console/store/selectors/applications'
-
-const mapStateToProps = state => ({
- appId: selectSelectedApplicationId(state),
- brands: selectDeviceBrands(state),
- error: selectDeviceBrandsError(state),
- fetching: selectDeviceBrandsFetching(state),
-})
-
-const mapDispatchToProps = {}
-
-export default BrandSelect => connect(mapStateToProps, mapDispatchToProps)(BrandSelect)
diff --git a/pkg/webui/console/containers/device-profile-section/device-selection/brand-select/index.js b/pkg/webui/console/containers/device-profile-section/device-selection/brand-select/index.js
index 87b87a17af..1e93ddaa74 100644
--- a/pkg/webui/console/containers/device-profile-section/device-selection/brand-select/index.js
+++ b/pkg/webui/console/containers/device-profile-section/device-selection/brand-select/index.js
@@ -12,9 +12,75 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import connect from './connect'
-import BrandSelect from './brand-select'
+import React from 'react'
+import { defineMessages, useIntl } from 'react-intl'
+import { useSelector } from 'react-redux'
-const ConnectedBrandSelect = connect(BrandSelect)
+import Field from '@ttn-lw/components/form/field'
+import Select from '@ttn-lw/components/select'
-export { ConnectedBrandSelect as default, BrandSelect }
+import PropTypes from '@ttn-lw/lib/prop-types'
+import sharedMessages from '@ttn-lw/lib/shared-messages'
+
+import { SELECT_OTHER_OPTION } from '@console/lib/device-utils'
+
+import {
+ selectDeviceBrands,
+ selectDeviceBrandsError,
+ selectDeviceBrandsFetching,
+} from '@console/store/selectors/device-repository'
+
+const m = defineMessages({
+ title: 'End device brand',
+ noOptionsMessage: 'No matching brand found',
+})
+
+const formatOptions = (brands = []) =>
+ brands
+ .map(brand => ({
+ value: brand.brand_id,
+ label: brand.name || brand.brand_id,
+ profileID: brand.brand_id,
+ }))
+ .concat([{ value: SELECT_OTHER_OPTION, label: sharedMessages.otherOption }])
+
+const BrandSelect = props => {
+ const { name, onChange, ...rest } = props
+ const { formatMessage } = useIntl()
+ const brands = useSelector(selectDeviceBrands)
+ const error = useSelector(selectDeviceBrandsError)
+ const fetching = useSelector(selectDeviceBrandsFetching)
+
+ const options = React.useMemo(() => formatOptions(brands), [brands])
+ const handleNoOptions = React.useCallback(
+ () => formatMessage(m.noOptionsMessage),
+ [formatMessage],
+ )
+
+ return (
+
+ )
+}
+
+BrandSelect.propTypes = {
+ name: PropTypes.string.isRequired,
+ onChange: PropTypes.func,
+}
+
+BrandSelect.defaultProps = {
+ onChange: () => null,
+}
+
+export default BrandSelect
diff --git a/pkg/webui/console/containers/device-profile-section/device-selection/fw-version-select/connect.js b/pkg/webui/console/containers/device-profile-section/device-selection/fw-version-select/connect.js
deleted file mode 100644
index b5cd5c46b0..0000000000
--- a/pkg/webui/console/containers/device-profile-section/device-selection/fw-version-select/connect.js
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright © 2022 The Things Network Foundation, The Things Industries B.V.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import { connect } from 'react-redux'
-
-import { isUnknownHwVersion } from '@console/lib/device-utils'
-
-import { selectDeviceModelFirmwareVersions } from '@console/store/selectors/device-repository'
-
-const mapStateToProps = (state, props) => {
- const { brandId, modelId, hwVersion } = props
-
- const fwVersions = selectDeviceModelFirmwareVersions(state, brandId, modelId).filter(
- ({ supported_hardware_versions = [] }) =>
- (Boolean(hwVersion) && supported_hardware_versions.includes(hwVersion)) ||
- // Include firmware versions when there are no hardware versions configured in device repository
- // for selected end device model.
- isUnknownHwVersion(hwVersion),
- )
-
- return {
- versions: fwVersions,
- }
-}
-
-export default FirmwareVersionSelect => connect(mapStateToProps)(FirmwareVersionSelect)
diff --git a/pkg/webui/console/containers/device-profile-section/device-selection/fw-version-select/fw-version-select.js b/pkg/webui/console/containers/device-profile-section/device-selection/fw-version-select/fw-version-select.js
deleted file mode 100644
index 2f4cf20595..0000000000
--- a/pkg/webui/console/containers/device-profile-section/device-selection/fw-version-select/fw-version-select.js
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright © 2022 The Things Network Foundation, The Things Industries B.V.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import React from 'react'
-import { defineMessages } from 'react-intl'
-
-import Field from '@ttn-lw/components/form/field'
-import Select from '@ttn-lw/components/select'
-import { useFormContext } from '@ttn-lw/components/form'
-
-import PropTypes from '@ttn-lw/lib/prop-types'
-import sharedMessages from '@ttn-lw/lib/shared-messages'
-
-import { SELECT_OTHER_OPTION } from '@console/lib/device-utils'
-
-const m = defineMessages({
- title: 'Firmware Ver.',
-})
-
-const formatOptions = (versions = []) =>
- versions
- .map(version => ({
- value: version.version,
- label: version.version,
- }))
- .concat([{ value: SELECT_OTHER_OPTION, label: sharedMessages.otherOption }])
-
-const FirmwareVersionSelect = props => {
- const { name, versions, onChange, ...rest } = props
- const { setFieldValue } = useFormContext()
-
- const options = React.useMemo(() => formatOptions(versions), [versions])
-
- React.useEffect(() => {
- if (options.length > 0 && options.length <= 2) {
- setFieldValue('version_ids.firmware_version', options[0].value)
- }
- }, [setFieldValue, options])
-
- return (
-
- )
-}
-
-FirmwareVersionSelect.propTypes = {
- name: PropTypes.string.isRequired,
- onChange: PropTypes.func,
- versions: PropTypes.arrayOf(
- PropTypes.shape({
- version: PropTypes.string.isRequired,
- }),
- ),
-}
-
-FirmwareVersionSelect.defaultProps = {
- versions: [],
- onChange: () => null,
-}
-
-export default FirmwareVersionSelect
diff --git a/pkg/webui/console/containers/device-profile-section/device-selection/fw-version-select/index.js b/pkg/webui/console/containers/device-profile-section/device-selection/fw-version-select/index.js
index 5dfd1369ce..4075d42862 100644
--- a/pkg/webui/console/containers/device-profile-section/device-selection/fw-version-select/index.js
+++ b/pkg/webui/console/containers/device-profile-section/device-selection/fw-version-select/index.js
@@ -12,9 +12,70 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import connect from './connect'
-import FirmwareVersionSelect from './fw-version-select'
+import React from 'react'
+import { defineMessages } from 'react-intl'
+import { useSelector } from 'react-redux'
-const ConnectedFirmwareVersionSelect = connect(FirmwareVersionSelect)
+import Field from '@ttn-lw/components/form/field'
+import Select from '@ttn-lw/components/select'
+import { useFormContext } from '@ttn-lw/components/form'
-export { ConnectedFirmwareVersionSelect as default, FirmwareVersionSelect }
+import PropTypes from '@ttn-lw/lib/prop-types'
+import sharedMessages from '@ttn-lw/lib/shared-messages'
+
+import { isUnknownHwVersion, SELECT_OTHER_OPTION } from '@console/lib/device-utils'
+
+import { selectDeviceModelFirmwareVersions } from '@console/store/selectors/device-repository'
+
+const m = defineMessages({
+ title: 'Firmware Ver.',
+})
+
+const formatOptions = (versions = []) =>
+ versions
+ .map(version => ({
+ value: version.version,
+ label: version.version,
+ }))
+ .concat([{ value: SELECT_OTHER_OPTION, label: sharedMessages.otherOption }])
+
+const FirmwareVersionSelect = props => {
+ const { name, onChange, brandId, modelId, hwVersion, ...rest } = props
+ const { setFieldValue, values } = useFormContext()
+
+ const versions = useSelector(state =>
+ selectDeviceModelFirmwareVersions(state, brandId, modelId).filter(
+ ({ supported_hardware_versions = [] }) =>
+ (Boolean(hwVersion) && supported_hardware_versions.includes(hwVersion)) ||
+ // Include firmware versions when there are no hardware versions configured in device repository
+ // for selected end device model.
+ isUnknownHwVersion(hwVersion),
+ ),
+ )
+
+ const options = React.useMemo(() => formatOptions(versions), [versions])
+
+ React.useEffect(() => {
+ if (options.length > 0 && options.length <= 2 && !values.version_ids.firmware_version.length) {
+ setFieldValue('version_ids.firmware_version', options[0].value)
+ }
+ }, [setFieldValue, options, values.version_ids.firmware_version.length])
+
+ return (
+
+ )
+}
+
+FirmwareVersionSelect.propTypes = {
+ brandId: PropTypes.string.isRequired,
+ hwVersion: PropTypes.string.isRequired,
+ modelId: PropTypes.string.isRequired,
+ name: PropTypes.string.isRequired,
+ onChange: PropTypes.func,
+}
+
+FirmwareVersionSelect.defaultProps = {
+ onChange: () => null,
+}
+
+export default FirmwareVersionSelect
diff --git a/pkg/webui/console/containers/device-profile-section/device-selection/hw-version-select/hw-version-select.js b/pkg/webui/console/containers/device-profile-section/device-selection/hw-version-select/hw-version-select.js
deleted file mode 100644
index 940218ae42..0000000000
--- a/pkg/webui/console/containers/device-profile-section/device-selection/hw-version-select/hw-version-select.js
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright © 2022 The Things Network Foundation, The Things Industries B.V.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import React from 'react'
-import { defineMessages } from 'react-intl'
-
-import Field from '@ttn-lw/components/form/field'
-import Select from '@ttn-lw/components/select'
-import { useFormContext } from '@ttn-lw/components/form'
-
-import PropTypes from '@ttn-lw/lib/prop-types'
-import sharedMessages from '@ttn-lw/lib/shared-messages'
-
-import { SELECT_OTHER_OPTION, SELECT_UNKNOWN_HW_OPTION } from '@console/lib/device-utils'
-
-const m = defineMessages({
- title: 'Hardware Ver.',
-})
-
-const formatOptions = (versions = []) =>
- versions
- .map(version => ({
- value: version.version,
- label: version.version,
- }))
- .concat([{ value: SELECT_OTHER_OPTION, label: sharedMessages.otherOption }])
-
-const HardwareVersionSelect = props => {
- const { name, versions, onChange, ...rest } = props
- const { setFieldValue } = useFormContext()
-
- const options = React.useMemo(() => {
- const opts = formatOptions(versions)
- // When only the `Other...` option is available (so end device model has no hw versions defined
- // in the device repository) add another pseudo option that represents absence of hw versions.
- if (opts.length === 1) {
- opts.unshift({ value: SELECT_UNKNOWN_HW_OPTION, label: sharedMessages.unknownHwOption })
- }
-
- return opts
- }, [versions])
-
- React.useEffect(() => {
- if (options.length > 0 && options.length <= 2) {
- setFieldValue('version_ids.hardware_version', options[0].value)
- }
- }, [options, setFieldValue])
-
- return (
-
- )
-}
-
-HardwareVersionSelect.propTypes = {
- name: PropTypes.string.isRequired,
- onChange: PropTypes.func,
- versions: PropTypes.arrayOf(
- PropTypes.shape({
- version: PropTypes.string.isRequired,
- }),
- ),
-}
-
-HardwareVersionSelect.defaultProps = {
- versions: [],
- onChange: () => null,
-}
-
-export default HardwareVersionSelect
diff --git a/pkg/webui/console/containers/device-profile-section/device-selection/hw-version-select/index.js b/pkg/webui/console/containers/device-profile-section/device-selection/hw-version-select/index.js
index 9f14b89010..7f1cfa0470 100644
--- a/pkg/webui/console/containers/device-profile-section/device-selection/hw-version-select/index.js
+++ b/pkg/webui/console/containers/device-profile-section/device-selection/hw-version-select/index.js
@@ -1,4 +1,4 @@
-// Copyright © 2022 The Things Network Foundation, The Things Industries B.V.
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,9 +12,69 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import connect from './connect'
-import HardwareVersionSelect from './hw-version-select'
+import React from 'react'
+import { defineMessages } from 'react-intl'
+import { useSelector } from 'react-redux'
-const ConnectedHardwareVersionSelect = connect(HardwareVersionSelect)
+import Field from '@ttn-lw/components/form/field'
+import Select from '@ttn-lw/components/select'
+import { useFormContext } from '@ttn-lw/components/form'
-export { ConnectedHardwareVersionSelect as default, HardwareVersionSelect }
+import PropTypes from '@ttn-lw/lib/prop-types'
+import sharedMessages from '@ttn-lw/lib/shared-messages'
+
+import { SELECT_OTHER_OPTION, SELECT_UNKNOWN_HW_OPTION } from '@console/lib/device-utils'
+
+import { selectDeviceModelHardwareVersions } from '@console/store/selectors/device-repository'
+
+const m = defineMessages({
+ title: 'Hardware Ver.',
+})
+
+const formatOptions = (versions = []) =>
+ versions
+ .map(version => ({
+ value: version.version,
+ label: version.version,
+ }))
+ .concat([{ value: SELECT_OTHER_OPTION, label: sharedMessages.otherOption }])
+
+const HardwareVersionSelect = props => {
+ const { name, brandId, modelId, onChange, ...rest } = props
+ const { setFieldValue, values } = useFormContext()
+ const versions = useSelector(state => selectDeviceModelHardwareVersions(state, brandId, modelId))
+
+ const options = React.useMemo(() => {
+ const opts = formatOptions(versions)
+ // When only the `Other...` option is available (so end device model has no hw versions defined
+ // in the device repository) add another pseudo option that represents absence of hw versions.
+ if (opts.length === 1) {
+ opts.unshift({ value: SELECT_UNKNOWN_HW_OPTION, label: sharedMessages.unknownHwOption })
+ }
+
+ return opts
+ }, [versions])
+
+ React.useEffect(() => {
+ if (options.length > 0 && options.length <= 2 && !values.version_ids.hardware_version.length) {
+ setFieldValue('version_ids.hardware_version', options[0].value)
+ }
+ }, [options, setFieldValue, values])
+
+ return (
+
+ )
+}
+
+HardwareVersionSelect.propTypes = {
+ brandId: PropTypes.string.isRequired,
+ modelId: PropTypes.string.isRequired,
+ name: PropTypes.string.isRequired,
+ onChange: PropTypes.func,
+}
+
+HardwareVersionSelect.defaultProps = {
+ onChange: () => null,
+}
+
+export default HardwareVersionSelect
diff --git a/pkg/webui/console/containers/device-profile-section/device-selection/model-select/connect.js b/pkg/webui/console/containers/device-profile-section/device-selection/model-select/connect.js
deleted file mode 100644
index 5a5a5bedfa..0000000000
--- a/pkg/webui/console/containers/device-profile-section/device-selection/model-select/connect.js
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright © 2022 The Things Network Foundation, The Things Industries B.V.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import { connect } from 'react-redux'
-
-import { listModels } from '@console/store/actions/device-repository'
-
-import {
- selectDeviceModelsByBrandId,
- selectDeviceModelsError,
- selectDeviceModelsFetching,
-} from '@console/store/selectors/device-repository'
-import { selectSelectedApplicationId } from '@console/store/selectors/applications'
-
-const mapStateToProps = (state, props) => {
- const { brandId } = props
-
- return {
- appId: selectSelectedApplicationId(state),
- models: selectDeviceModelsByBrandId(state, brandId),
- error: selectDeviceModelsError(state),
- fetching: selectDeviceModelsFetching(state),
- }
-}
-
-const mapDispatchToProps = { listModels }
-
-export default ModelSelect => connect(mapStateToProps, mapDispatchToProps)(ModelSelect)
diff --git a/pkg/webui/console/containers/device-profile-section/device-selection/model-select/index.js b/pkg/webui/console/containers/device-profile-section/device-selection/model-select/index.js
index a83ad06022..7c0f6a494b 100644
--- a/pkg/webui/console/containers/device-profile-section/device-selection/model-select/index.js
+++ b/pkg/webui/console/containers/device-profile-section/device-selection/model-select/index.js
@@ -12,9 +12,106 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import connect from './connect'
-import ModelSelect from './model-select'
+import React from 'react'
+import { defineMessages, useIntl } from 'react-intl'
+import { useDispatch, useSelector } from 'react-redux'
-const ConnectedModelSelect = connect(ModelSelect)
+import Field from '@ttn-lw/components/form/field'
+import Select from '@ttn-lw/components/select'
-export { ConnectedModelSelect as default, ModelSelect }
+import PropTypes from '@ttn-lw/lib/prop-types'
+import sharedMessages from '@ttn-lw/lib/shared-messages'
+
+import { SELECT_OTHER_OPTION } from '@console/lib/device-utils'
+
+import { listModels } from '@console/store/actions/device-repository'
+
+import { selectSelectedApplicationId } from '@console/store/selectors/applications'
+import {
+ selectDeviceModelsByBrandId,
+ selectDeviceModelsError,
+ selectDeviceModelsFetching,
+} from '@console/store/selectors/device-repository'
+
+const m = defineMessages({
+ noOptionsMessage: 'No matching model found',
+})
+
+const formatOptions = (models = []) =>
+ models
+ .map(model => ({
+ value: model.model_id,
+ label: model.name,
+ }))
+ .concat([{ value: SELECT_OTHER_OPTION, label: sharedMessages.otherOption }])
+
+const ModelSelect = props => {
+ const { brandId, name, onChange, ...rest } = props
+ const { formatMessage } = useIntl()
+ const dispatch = useDispatch()
+ const appId = useSelector(selectSelectedApplicationId)
+ const models = useSelector(state => selectDeviceModelsByBrandId(state, brandId))
+ const error = useSelector(selectDeviceModelsError)
+ const fetching = useSelector(selectDeviceModelsFetching)
+
+ React.useEffect(() => {
+ dispatch(
+ listModels(appId, brandId, {}, [
+ 'name',
+ 'description',
+ 'firmware_versions',
+ 'hardware_versions',
+ 'key_provisioning',
+ 'photos',
+ 'product_url',
+ 'datasheet_url',
+ ]),
+ )
+ }, [appId, brandId, dispatch])
+
+ const options = React.useMemo(() => formatOptions(models), [models])
+ const handleNoOptions = React.useCallback(
+ () => formatMessage(m.noOptionsMessage),
+ [formatMessage],
+ )
+
+ return (
+
+ )
+}
+
+ModelSelect.propTypes = {
+ appId: PropTypes.string.isRequired,
+ brandId: PropTypes.string.isRequired,
+ error: PropTypes.error,
+ fetching: PropTypes.bool,
+ models: PropTypes.arrayOf(
+ PropTypes.shape({
+ model_id: PropTypes.string.isRequired,
+ name: PropTypes.string.isRequired,
+ }),
+ ),
+ name: PropTypes.string.isRequired,
+ onChange: PropTypes.func,
+}
+
+ModelSelect.defaultProps = {
+ error: undefined,
+ fetching: false,
+ models: [],
+ onChange: () => null,
+}
+
+export default ModelSelect
diff --git a/pkg/webui/console/containers/device-profile-section/device-selection/model-select/model-select.js b/pkg/webui/console/containers/device-profile-section/device-selection/model-select/model-select.js
deleted file mode 100644
index bb72f95b3a..0000000000
--- a/pkg/webui/console/containers/device-profile-section/device-selection/model-select/model-select.js
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright © 2022 The Things Network Foundation, The Things Industries B.V.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import React from 'react'
-import { defineMessages, useIntl } from 'react-intl'
-
-import Field from '@ttn-lw/components/form/field'
-import Select from '@ttn-lw/components/select'
-
-import PropTypes from '@ttn-lw/lib/prop-types'
-import sharedMessages from '@ttn-lw/lib/shared-messages'
-
-import { SELECT_OTHER_OPTION } from '@console/lib/device-utils'
-
-const m = defineMessages({
- title: 'Model',
- warning: 'End device models unavailable',
- noOptionsMessage: 'No matching model found',
-})
-
-const formatOptions = (models = []) =>
- models
- .map(model => ({
- value: model.model_id,
- label: model.name,
- }))
- .concat([{ value: SELECT_OTHER_OPTION, label: sharedMessages.otherOption }])
-
-const ModelSelect = props => {
- const { appId, brandId, name, error, fetching, models, listModels, onChange, ...rest } = props
- const { formatMessage } = useIntl()
-
- React.useEffect(() => {
- listModels(appId, brandId, {}, [
- 'name',
- 'description',
- 'firmware_versions',
- 'hardware_versions',
- 'key_provisioning',
- 'photos',
- 'product_url',
- 'datasheet_url',
- ])
- }, [appId, brandId, listModels])
-
- const options = React.useMemo(() => formatOptions(models), [models])
- const handleNoOptions = React.useCallback(
- () => formatMessage(m.noOptionsMessage),
- [formatMessage],
- )
-
- return (
-
- )
-}
-
-ModelSelect.propTypes = {
- appId: PropTypes.string.isRequired,
- brandId: PropTypes.string.isRequired,
- error: PropTypes.error,
- fetching: PropTypes.bool,
- listModels: PropTypes.func.isRequired,
- models: PropTypes.arrayOf(
- PropTypes.shape({
- model_id: PropTypes.string.isRequired,
- name: PropTypes.string.isRequired,
- }),
- ),
- name: PropTypes.string.isRequired,
- onChange: PropTypes.func,
-}
-
-ModelSelect.defaultProps = {
- error: undefined,
- fetching: false,
- models: [],
- onChange: () => null,
-}
-
-export default ModelSelect
diff --git a/pkg/webui/console/containers/device-title-section/connect.js b/pkg/webui/console/containers/device-title-section/connect.js
deleted file mode 100644
index c1f922fecf..0000000000
--- a/pkg/webui/console/containers/device-title-section/connect.js
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright © 2020 The Things Network Foundation, The Things Industries B.V.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import { connect } from 'react-redux'
-
-import {
- selectDeviceByIds,
- selectDeviceDerivedUplinkFrameCount,
- selectDeviceDerivedDownlinkFrameCount,
- selectDeviceLastSeen,
-} from '@console/store/selectors/devices'
-
-const mapStateToProps = (state, props) => {
- const { devId, appId } = props
-
- return {
- devId,
- appId,
- device: selectDeviceByIds(state, appId, devId),
- uplinkFrameCount: selectDeviceDerivedUplinkFrameCount(state, appId, devId),
- downlinkFrameCount: selectDeviceDerivedDownlinkFrameCount(state, appId, devId),
- lastSeen: selectDeviceLastSeen(state, appId, devId),
- }
-}
-
-export default TitleSection => connect(mapStateToProps)(TitleSection)
diff --git a/pkg/webui/console/containers/device-title-section/device-title-section.js b/pkg/webui/console/containers/device-title-section/device-title-section.js
deleted file mode 100644
index 80e9735676..0000000000
--- a/pkg/webui/console/containers/device-title-section/device-title-section.js
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright © 2020 The Things Network Foundation, The Things Industries B.V.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import React from 'react'
-import { defineMessages } from 'react-intl'
-
-import deviceIcon from '@assets/misc/end-device.svg'
-
-import Status from '@ttn-lw/components/status'
-import Tooltip from '@ttn-lw/components/tooltip'
-import DocTooltip from '@ttn-lw/components/tooltip/doc'
-import Icon from '@ttn-lw/components/icon'
-
-import Message from '@ttn-lw/lib/components/message'
-import DateTime from '@ttn-lw/lib/components/date-time'
-
-import EntityTitleSection from '@console/components/entity-title-section'
-import LastSeen from '@console/components/last-seen'
-
-import PropTypes from '@ttn-lw/lib/prop-types'
-import sharedMessages from '@ttn-lw/lib/shared-messages'
-
-import style from './device-title-section.styl'
-
-const m = defineMessages({
- uplinkDownlinkTooltip:
- 'The number of sent uplinks and received downlinks of this end device since the last frame counter reset.',
- lastSeenAvailableTooltip:
- 'The elapsed time since the network registered the last activity of this end device. This is determined from sent uplinks, confirmed downlinks or (re)join requests.{lineBreak}The last activity was received at {lastActivityInfo}',
- noActivityTooltip:
- 'The network has not registered any activity from this end device yet. This could mean that your end device has not sent any messages yet or only messages that cannot be handled by the network, e.g. due to a mismatch of EUIs or frequencies.',
-})
-
-const { Content } = EntityTitleSection
-
-const DeviceTitleSection = props => {
- const { devId, fetching, device, uplinkFrameCount, downlinkFrameCount, lastSeen, children } =
- props
- const showLastSeen = Boolean(lastSeen)
- const showUplinkCount = typeof uplinkFrameCount === 'number'
- const showDownlinkCount = typeof downlinkFrameCount === 'number'
- const notAvailableElem =
- const lastActivityInfo = lastSeen ? : lastSeen
- const lineBreak =
- const bottomBarLeft = (
- <>
- }>
-
-
-
-
-
- {showLastSeen ? (
-
- }
- >
-
-
-
-
- ) : (
- }
- >
-
-
-
-
- )}
- >
- )
-
- return (
-
-
- {children}
-
- )
-}
-
-DeviceTitleSection.propTypes = {
- children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),
- devId: PropTypes.string.isRequired,
- device: PropTypes.device.isRequired,
- downlinkFrameCount: PropTypes.number,
- fetching: PropTypes.bool,
- lastSeen: PropTypes.string,
- uplinkFrameCount: PropTypes.number,
-}
-
-DeviceTitleSection.defaultProps = {
- uplinkFrameCount: undefined,
- lastSeen: undefined,
- children: null,
- fetching: false,
- downlinkFrameCount: undefined,
-}
-
-export default DeviceTitleSection
diff --git a/pkg/webui/console/containers/device-title-section/index.js b/pkg/webui/console/containers/device-title-section/index.js
index 53e492af34..7588a1c864 100644
--- a/pkg/webui/console/containers/device-title-section/index.js
+++ b/pkg/webui/console/containers/device-title-section/index.js
@@ -12,9 +12,134 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import DeviceTitleSection from './device-title-section'
-import connect from './connect'
+import React from 'react'
+import { defineMessages } from 'react-intl'
+import { useSelector } from 'react-redux'
-const ConnectedDeviceTitleSection = connect(DeviceTitleSection)
+import deviceIcon from '@assets/misc/end-device.svg'
-export { ConnectedDeviceTitleSection as default, DeviceTitleSection }
+import Status from '@ttn-lw/components/status'
+import Tooltip from '@ttn-lw/components/tooltip'
+import DocTooltip from '@ttn-lw/components/tooltip/doc'
+import Icon from '@ttn-lw/components/icon'
+
+import Message from '@ttn-lw/lib/components/message'
+import DateTime from '@ttn-lw/lib/components/date-time'
+
+import EntityTitleSection from '@console/components/entity-title-section'
+import LastSeen from '@console/components/last-seen'
+
+import PropTypes from '@ttn-lw/lib/prop-types'
+import sharedMessages from '@ttn-lw/lib/shared-messages'
+
+import {
+ selectDeviceByIds,
+ selectDeviceDerivedDownlinkFrameCount,
+ selectDeviceDerivedUplinkFrameCount,
+ selectDeviceLastSeen,
+} from '@console/store/selectors/devices'
+
+import style from './device-title-section.styl'
+
+const m = defineMessages({
+ uplinkDownlinkTooltip:
+ 'The number of sent uplinks and received downlinks of this end device since the last frame counter reset.',
+ lastSeenAvailableTooltip:
+ 'The elapsed time since the network registered the last activity of this end device. This is determined from sent uplinks, confirmed downlinks or (re)join requests.{lineBreak}The last activity was received at {lastActivityInfo}',
+ noActivityTooltip:
+ 'The network has not registered any activity from this end device yet. This could mean that your end device has not sent any messages yet or only messages that cannot be handled by the network, e.g. due to a mismatch of EUIs or frequencies.',
+})
+
+const { Content } = EntityTitleSection
+
+const DeviceTitleSection = props => {
+ const { appId, devId, fetching, children } = props
+ const device = useSelector(state => selectDeviceByIds(state, appId, devId))
+ const uplinkFrameCount = useSelector(state =>
+ selectDeviceDerivedUplinkFrameCount(state, appId, devId),
+ )
+ const downlinkFrameCount = useSelector(state =>
+ selectDeviceDerivedDownlinkFrameCount(state, appId, devId),
+ )
+ const lastSeen = useSelector(state => selectDeviceLastSeen(state, appId, devId))
+ const showLastSeen = Boolean(lastSeen)
+ const showUplinkCount = typeof uplinkFrameCount === 'number'
+ const showDownlinkCount = typeof downlinkFrameCount === 'number'
+ const notAvailableElem =
+ const lastActivityInfo = lastSeen ? : lastSeen
+ const lineBreak =
+ const bottomBarLeft = (
+ <>
+ }>
+
+
+
+
+
+ {showLastSeen ? (
+
+ }
+ >
+
+
+
+
+ ) : (
+ }
+ >
+
+
+
+
+ )}
+ >
+ )
+
+ return (
+
+
+ {children}
+
+ )
+}
+
+DeviceTitleSection.propTypes = {
+ appId: PropTypes.string.isRequired,
+ children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),
+ devId: PropTypes.string.isRequired,
+ fetching: PropTypes.bool,
+}
+
+DeviceTitleSection.defaultProps = {
+ children: null,
+ fetching: false,
+}
+
+export default DeviceTitleSection
diff --git a/pkg/webui/console/containers/fetch-select/index.js b/pkg/webui/console/containers/fetch-select/index.js
index ff3ca7e561..5e004727ab 100644
--- a/pkg/webui/console/containers/fetch-select/index.js
+++ b/pkg/webui/console/containers/fetch-select/index.js
@@ -12,9 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import React from 'react'
-import { connect as storeConnect } from 'react-redux'
-import bind from 'autobind-decorator'
+import React, { useCallback, useEffect } from 'react'
+import { useDispatch, useSelector } from 'react-redux'
import Field from '@ttn-lw/components/form/field'
import Select from '@ttn-lw/components/select'
@@ -37,66 +36,60 @@ export default ({
defaultDescription,
additionalOptions = [],
}) => {
- @storeConnect(
- state => ({
- options: [...optionsFormatter(optionsSelector(state)), ...additionalOptions],
- error: errorSelector(state),
- fetching: fetchingSelector(state),
- }),
- { fetchOptions },
- )
- class FetchSelect extends React.PureComponent {
- static propTypes = {
- ...fieldPropTypes,
- ...Select.propTypes,
- defaultWarning: PropTypes.message,
- description: PropTypes.message,
- fetchOptions: PropTypes.func.isRequired,
- menuPlacement: PropTypes.oneOf(['top', 'bottom', 'auto']),
- onChange: PropTypes.func,
- options: PropTypes.arrayOf(
- PropTypes.shape({ value: PropTypes.string, label: PropTypes.message }),
- ),
- title: PropTypes.message,
- warning: PropTypes.message,
- }
+ const FetchSelect = props => {
+ const { warning, onChange, ...rest } = props
+ const options = [...optionsFormatter(useSelector(optionsSelector)), ...additionalOptions]
+ const error = useSelector(errorSelector)
+ const fetching = useSelector(fetchingSelector)
+ const dispatch = useDispatch()
- static defaultProps = {
- description: defaultDescription,
- menuPlacement: 'auto',
- onChange: () => null,
- options: [],
- title: defaultTitle,
- warning: undefined,
- defaultWarning,
- }
+ useEffect(() => {
+ dispatch(fetchOptions())
+ }, [dispatch])
- componentDidMount() {
- const { fetchOptions } = this.props
+ const handleChange = useCallback(
+ value => {
+ const selectedOption = options.find(option => option.value === value)
+ onChange(selectedOption)
+ },
+ [onChange, options],
+ )
- fetchOptions()
- }
-
- @bind
- handleChange(value) {
- const { onChange, options } = this.props
-
- onChange(options.find(e => e.value === value))
- }
+ return (
+
+ )
+ }
- render() {
- const { error, fetching, warning, defaultWarning, ...rest } = this.props
+ FetchSelect.propTypes = {
+ ...fieldPropTypes,
+ ...Select.propTypes,
+ defaultWarning: PropTypes.message,
+ description: PropTypes.message,
+ fetchOptions: PropTypes.func.isRequired,
+ menuPlacement: PropTypes.oneOf(['top', 'bottom', 'auto']),
+ onChange: PropTypes.func,
+ options: PropTypes.arrayOf(
+ PropTypes.shape({ value: PropTypes.string, label: PropTypes.message }),
+ ),
+ title: PropTypes.message,
+ warning: PropTypes.message,
+ }
- return (
-
- )
- }
+ FetchSelect.defaultProps = {
+ description: defaultDescription,
+ menuPlacement: 'auto',
+ onChange: () => null,
+ options: [],
+ title: defaultTitle,
+ warning: undefined,
+ defaultWarning,
}
return FetchSelect
diff --git a/pkg/webui/console/containers/freq-plans-select/gs-frequency-plan-select.js b/pkg/webui/console/containers/freq-plans-select/gs-frequency-plan-select.js
new file mode 100644
index 0000000000..74b8a5f0ae
--- /dev/null
+++ b/pkg/webui/console/containers/freq-plans-select/gs-frequency-plan-select.js
@@ -0,0 +1,78 @@
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import React, { useCallback, useEffect } from 'react'
+import { useDispatch, useSelector } from 'react-redux'
+
+import frequencyPlans from '@console/constants/frequency-plans'
+
+import KeyValueMap from '@ttn-lw/components/key-value-map'
+import Select from '@ttn-lw/components/select'
+import Form, { useFormContext } from '@ttn-lw/components/form'
+
+import sharedMessages from '@ttn-lw/lib/shared-messages'
+import tooltipIds from '@ttn-lw/lib/constants/tooltip-ids'
+
+import { getGsFrequencyPlans } from '@console/store/actions/configuration'
+
+import { selectGsFrequencyPlans } from '@console/store/selectors/configuration'
+
+import { formatOptions, m } from './utils'
+
+const isEmptyFrequencyPlan = value => value?.includes(frequencyPlans.EMPTY_FREQ_PLAN)
+
+const GatewayFrequencyPlansSelect = () => {
+ const { values } = useFormContext()
+ const { frequency_plan_ids } = values
+ const dispatch = useDispatch()
+ const [showFrequencyPlanWarning, setShowFrequencyPlanWarning] = React.useState(
+ isEmptyFrequencyPlan(frequency_plan_ids) || !frequency_plan_ids,
+ )
+
+ useEffect(() => {
+ dispatch(getGsFrequencyPlans())
+ }, [dispatch])
+
+ const freqPlanOptions = [
+ ...formatOptions(useSelector(selectGsFrequencyPlans)),
+ { value: 'no-frequency-plan', label: m.none },
+ ]
+
+ const onFrequencyPlanChange = useCallback(freqPlan => {
+ setShowFrequencyPlanWarning(isEmptyFrequencyPlan(freqPlan))
+ }, [])
+
+ return (
+
+ )
+}
+
+export default GatewayFrequencyPlansSelect
diff --git a/pkg/webui/console/containers/freq-plans-select/index.js b/pkg/webui/console/containers/freq-plans-select/index.js
index 7842e7ff22..c598dfcad0 100644
--- a/pkg/webui/console/containers/freq-plans-select/index.js
+++ b/pkg/webui/console/containers/freq-plans-select/index.js
@@ -12,10 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import { defineMessages } from 'react-intl'
-
import CreateFetchSelect from '@console/containers/fetch-select'
+import sharedMessages from '@ttn-lw/lib/shared-messages'
+
import { getGsFrequencyPlans, getNsFrequencyPlans } from '@console/store/actions/configuration'
import {
@@ -25,13 +25,7 @@ import {
selectFrequencyPlansFetching,
} from '@console/store/selectors/configuration'
-const m = defineMessages({
- title: 'Frequency plan',
- warning: 'Frequency plans unavailable',
- none: 'Do not set a frequency plan',
-})
-
-const formatOptions = plans => plans.map(plan => ({ value: plan.id, label: plan.name }))
+import { formatOptions, m } from './utils'
export const CreateFrequencyPlansSelect = (source, options = {}) =>
CreateFetchSelect({
@@ -40,7 +34,7 @@ export const CreateFrequencyPlansSelect = (source, options = {}) =>
fetchingSelector: selectFrequencyPlansFetching,
errorSelector: selectFrequencyPlansError,
defaultWarning: m.warning,
- defaultTitle: m.title,
+ defaultTitle: sharedMessages.frequencyPlan,
optionsFormatter: formatOptions,
additionalOptions: source === 'gs' ? [{ value: 'no-frequency-plan', label: m.none }] : [],
...options,
diff --git a/pkg/webui/console/containers/freq-plans-select/utils.js b/pkg/webui/console/containers/freq-plans-select/utils.js
new file mode 100644
index 0000000000..0526a8fd1c
--- /dev/null
+++ b/pkg/webui/console/containers/freq-plans-select/utils.js
@@ -0,0 +1,26 @@
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import { defineMessages } from 'react-intl'
+
+export const formatOptions = plans =>
+ plans.map(plan => ({ value: plan.id, label: plan.name, tag: plan.band_id }))
+export const m = defineMessages({
+ warning: 'Frequency plans unavailable',
+ none: 'Do not set a frequency plan',
+ selectFrequencyPlan: 'Select a frequency plan...',
+ addFrequencyPlan: 'Add frequency plan',
+ frequencyPlanDescription:
+ 'Note: most gateways use a single frequency plan. Some 16 and 64 channel gateways however allow setting multiple within the same band.',
+})
diff --git a/pkg/webui/console/containers/gateway-connection/connect.js b/pkg/webui/console/containers/gateway-connection/connect.js
deleted file mode 100644
index 1cd5a148ec..0000000000
--- a/pkg/webui/console/containers/gateway-connection/connect.js
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright © 2019 The Things Network Foundation, The Things Industries B.V.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import { connect } from 'react-redux'
-
-import { selectGsConfig } from '@ttn-lw/lib/selectors/env'
-import getHostFromUrl from '@ttn-lw/lib/host-from-url'
-
-import {
- startGatewayStatistics,
- stopGatewayStatistics,
- updateGatewayStatistics,
-} from '@console/store/actions/gateways'
-
-import {
- selectGatewayStatistics,
- selectGatewayStatisticsError,
- selectGatewayStatisticsIsFetching,
- selectLatestGatewayEvent,
- selectGatewayById,
-} from '@console/store/selectors/gateways'
-import { selectGatewayLastSeen } from '@console/store/selectors/gateway-status'
-
-import withConnectionReactor from './gateway-connection-reactor'
-
-export default GatewayConnection =>
- connect(
- (state, ownProps) => {
- const gateway = selectGatewayById(state, ownProps.gtwId)
- const gsConfig = selectGsConfig()
- const consoleGsAddress = getHostFromUrl(gsConfig.base_url)
- const gatewayServerAddress = getHostFromUrl(gateway.gateway_server_address)
-
- return {
- statistics: selectGatewayStatistics(state, ownProps),
- error: selectGatewayStatisticsError(state, ownProps),
- fetching: selectGatewayStatisticsIsFetching(state, ownProps),
- latestEvent: selectLatestGatewayEvent(state, ownProps.gtwId),
- lastSeen: selectGatewayLastSeen(state),
- isOtherCluster: consoleGsAddress !== gatewayServerAddress,
- }
- },
- (dispatch, ownProps) => ({
- startStatistics: () => dispatch(startGatewayStatistics(ownProps.gtwId)),
- stopStatistics: () => dispatch(stopGatewayStatistics()),
- updateGatewayStatistics: () => dispatch(updateGatewayStatistics(ownProps.gtwId)),
- }),
- )(withConnectionReactor(GatewayConnection))
diff --git a/pkg/webui/console/containers/gateway-connection/gateway-connection-reactor.js b/pkg/webui/console/containers/gateway-connection/gateway-connection-reactor.js
deleted file mode 100644
index a680fa9ede..0000000000
--- a/pkg/webui/console/containers/gateway-connection/gateway-connection-reactor.js
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright © 2019 The Things Network Foundation, The Things Industries B.V.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import React from 'react'
-
-import {
- isGsStatusReceiveEvent,
- isGsDownlinkSendEvent,
- isGsUplinkReceiveEvent,
-} from '@ttn-lw/lib/selectors/event'
-import PropTypes from '@ttn-lw/lib/prop-types'
-
-/**
- * `withConnectionReactor` is a HOC that handles gateway connection statistics
- * updates based on gateway uplink, downlink and connection events.
- *
- * @param {object} Component - React component to be wrapped by the reactor.
- * @returns {object} - A wrapped react component.
- */
-const withConnectionReactor = Component => {
- class ConnectionReactor extends React.PureComponent {
- componentDidUpdate(prevProps) {
- const { latestEvent, updateGatewayStatistics } = this.props
-
- if (Boolean(latestEvent) && latestEvent !== prevProps.latestEvent) {
- const { name } = latestEvent
- const isHeartBeatEvent =
- isGsDownlinkSendEvent(name) ||
- isGsUplinkReceiveEvent(name) ||
- isGsStatusReceiveEvent(name)
-
- if (isHeartBeatEvent) {
- updateGatewayStatistics()
- }
- }
- }
-
- render() {
- const { latestEvent, updateGatewayStatistics, ...rest } = this.props
- return
- }
- }
-
- ConnectionReactor.propTypes = {
- latestEvent: PropTypes.event,
- updateGatewayStatistics: PropTypes.func.isRequired,
- }
-
- ConnectionReactor.defaultProps = {
- latestEvent: undefined,
- }
-
- return ConnectionReactor
-}
-
-export default withConnectionReactor
diff --git a/pkg/webui/console/containers/gateway-connection/gateway-connection.js b/pkg/webui/console/containers/gateway-connection/gateway-connection.js
deleted file mode 100644
index f27334cfd7..0000000000
--- a/pkg/webui/console/containers/gateway-connection/gateway-connection.js
+++ /dev/null
@@ -1,216 +0,0 @@
-// Copyright © 2020 The Things Network Foundation, The Things Industries B.V.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import React from 'react'
-import classnames from 'classnames'
-import { FormattedNumber, defineMessages } from 'react-intl'
-
-import Status from '@ttn-lw/components/status'
-import Icon from '@ttn-lw/components/icon'
-import DocTooltip from '@ttn-lw/components/tooltip/doc'
-import Tooltip from '@ttn-lw/components/tooltip'
-
-import Message from '@ttn-lw/lib/components/message'
-
-import LastSeen from '@console/components/last-seen'
-
-import PropTypes from '@ttn-lw/lib/prop-types'
-import sharedMessages from '@ttn-lw/lib/shared-messages'
-import { isNotFoundError, isTranslated } from '@ttn-lw/lib/errors/utils'
-
-import style from './gateway-connection.styl'
-
-const m = defineMessages({
- lastSeenAvailableTooltip:
- 'The elapsed time since the network registered the last activity of this gateway. This is determined from received uplinks, or sent status messages of this gateway.',
- disconnectedTooltip:
- 'The gateway has currently no TCP connection established with the Gateway Server. For (rare) UDP based gateways, this can also mean that the gateway initiated no pull/push data request within the last 30 seconds.',
- connectedTooltip:
- 'This gateway is connected to the Gateway Server but the network has not registered any activity (sent uplinks or status messages) from it yet.',
- otherClusterTooltip:
- 'This gateway is connected to an external Gateway Server that is not handling messages for this cluster. You will hence not be able to see any activity from this gateway.',
- messageCountTooltip:
- 'The amount of received uplinks and sent downlinks of this gateway since the last (re)connect. Note that some gateway types reconnect frequently causing the counter to be reset.',
-})
-
-class GatewayConnection extends React.PureComponent {
- static propTypes = {
- className: PropTypes.string,
- error: PropTypes.oneOfType([PropTypes.error, PropTypes.shape({ message: PropTypes.message })]),
- fetching: PropTypes.bool,
- isOtherCluster: PropTypes.bool.isRequired,
- lastSeen: PropTypes.oneOfType([
- PropTypes.string,
- PropTypes.number, // Support timestamps.
- PropTypes.instanceOf(Date),
- ]),
- startStatistics: PropTypes.func.isRequired,
- statistics: PropTypes.gatewayStats,
- stopStatistics: PropTypes.func.isRequired,
- }
-
- static defaultProps = {
- className: undefined,
- fetching: false,
- error: null,
- statistics: null,
- lastSeen: undefined,
- }
-
- componentDidMount() {
- const { startStatistics } = this.props
-
- startStatistics()
- }
-
- componentWillUnmount() {
- const { stopStatistics } = this.props
-
- stopStatistics()
- }
-
- get status() {
- const { statistics, error, fetching, lastSeen, isOtherCluster } = this.props
-
- const statsNotFound = Boolean(error) && isNotFoundError(error)
- const isDisconnected = Boolean(statistics) && Boolean(statistics.disconnected_at)
- const isFetching = !Boolean(statistics) && fetching
- const isUnavailable = Boolean(error) && Boolean(error.message) && isTranslated(error.message)
- const hasStatistics = Boolean(statistics)
- const hasLastSeen = Boolean(lastSeen)
-
- let statusIndicator = null
- let message = null
- let tooltipMessage = undefined
- let docPath = '/getting-started/console/troubleshooting'
- let docTitle = sharedMessages.troubleshooting
-
- if (statsNotFound) {
- statusIndicator = 'bad'
- message = sharedMessages.disconnected
- tooltipMessage = m.disconnectedTooltip
- docPath = '/gateways/troubleshooting/#my-gateway-wont-connect-what-do-i-do'
- } else if (isDisconnected) {
- tooltipMessage = m.disconnectedTooltip
- docPath = '/gateways/troubleshooting/#my-gateway-wont-connect-what-do-i-do'
- } else if (isFetching) {
- statusIndicator = 'mediocre'
- message = sharedMessages.connecting
- } else if (isUnavailable) {
- statusIndicator = 'unknown'
- message = error.message
- if (isOtherCluster) {
- tooltipMessage = m.otherClusterTooltip
- docPath = '/gateways/troubleshooting/#my-gateway-shows-a-other-cluster-status-why'
- }
- } else if (hasStatistics) {
- message = sharedMessages.connected
- statusIndicator = 'good'
- if (hasLastSeen) {
- tooltipMessage = m.lastSeenAvailableTooltip
- } else {
- docPath =
- 'gateways/troubleshooting/#my-gateway-is-shown-as-connected-in-the-console-but-i-dont-see-any-events-including-the-gateway-connection-stats-what-do-i-do'
- tooltipMessage = m.connectedTooltip
- }
- docTitle = sharedMessages.moreInformation
- } else {
- message = sharedMessages.unknown
- statusIndicator = 'unknown'
- docPath = '/gateways/troubleshooting'
- }
-
- let node
-
- if (isDisconnected) {
- node = (
-
-
-
- )
- } else if (statusIndicator === 'good' && hasLastSeen) {
- node = (
-
-
-
- )
- } else {
- node = (
-
-
-
- )
- }
-
- if (tooltipMessage) {
- return (
- }
- children={node}
- />
- )
- }
-
- return node
- }
-
- get messages() {
- const { statistics } = this.props
-
- if (!statistics) {
- return null
- }
-
- const uplinks = statistics.uplink_count || '0'
- const downlinks = statistics.downlink_count || '0'
-
- const uplinkCount = parseInt(uplinks) || 0
- const downlinkCount = parseInt(downlinks) || 0
-
- return (
- }>
-
-
-
-
-
-
-
-
-
-
-
- )
- }
-
- render() {
- const { className } = this.props
-
- return (
-
- {this.messages}
- {this.status}
-
- )
- }
-}
-
-export default GatewayConnection
diff --git a/pkg/webui/console/containers/gateway-connection/index.js b/pkg/webui/console/containers/gateway-connection/index.js
index 642d24c74a..4dae7f4962 100644
--- a/pkg/webui/console/containers/gateway-connection/index.js
+++ b/pkg/webui/console/containers/gateway-connection/index.js
@@ -1,4 +1,4 @@
-// Copyright © 2019 The Things Network Foundation, The Things Industries B.V.
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,9 +12,209 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import Connection from './gateway-connection'
-import connect from './connect'
+import React, { useEffect, useMemo } from 'react'
+import classnames from 'classnames'
+import { FormattedNumber, defineMessages } from 'react-intl'
+import { useDispatch, useSelector } from 'react-redux'
-const ConnectedGatewayConnection = connect(Connection)
+import Status from '@ttn-lw/components/status'
+import Icon from '@ttn-lw/components/icon'
+import DocTooltip from '@ttn-lw/components/tooltip/doc'
+import Tooltip from '@ttn-lw/components/tooltip'
-export { ConnectedGatewayConnection as default, Connection }
+import Message from '@ttn-lw/lib/components/message'
+
+import LastSeen from '@console/components/last-seen'
+
+import useConnectionReactor from '@console/containers/gateway-connection/use-connection-reactor'
+
+import PropTypes from '@ttn-lw/lib/prop-types'
+import sharedMessages from '@ttn-lw/lib/shared-messages'
+import { isNotFoundError, isTranslated } from '@ttn-lw/lib/errors/utils'
+import { selectGsConfig } from '@ttn-lw/lib/selectors/env'
+import getHostFromUrl from '@ttn-lw/lib/host-from-url'
+
+import { startGatewayStatistics, stopGatewayStatistics } from '@console/store/actions/gateways'
+
+import {
+ selectGatewayById,
+ selectGatewayStatistics,
+ selectGatewayStatisticsError,
+ selectGatewayStatisticsIsFetching,
+} from '@console/store/selectors/gateways'
+import { selectGatewayLastSeen } from '@console/store/selectors/gateway-status'
+
+import style from './gateway-connection.styl'
+
+const m = defineMessages({
+ lastSeenAvailableTooltip:
+ 'The elapsed time since the network registered the last activity of this gateway. This is determined from received uplinks, or sent status messages of this gateway.',
+ disconnectedTooltip:
+ 'The gateway has currently no TCP connection established with the Gateway Server. For (rare) UDP based gateways, this can also mean that the gateway initiated no pull/push data request within the last 30 seconds.',
+ connectedTooltip:
+ 'This gateway is connected to the Gateway Server but the network has not registered any activity (sent uplinks or status messages) from it yet.',
+ otherClusterTooltip:
+ 'This gateway is connected to an external Gateway Server that is not handling messages for this cluster. You will hence not be able to see any activity from this gateway.',
+ messageCountTooltip:
+ 'The amount of received uplinks and sent downlinks of this gateway since the last (re)connect. Note that some gateway types reconnect frequently causing the counter to be reset.',
+})
+
+const GatewayConnection = props => {
+ const { className, gtwId } = props
+
+ const gateway = useSelector(state => selectGatewayById(state, gtwId))
+ const gsConfig = selectGsConfig()
+ const consoleGsAddress = getHostFromUrl(gsConfig.base_url)
+ const gatewayServerAddress = getHostFromUrl(gateway.gateway_server_address)
+ const statistics = useSelector(selectGatewayStatistics)
+ const error = useSelector(selectGatewayStatisticsError)
+ const fetching = useSelector(selectGatewayStatisticsIsFetching)
+ const lastSeen = useSelector(selectGatewayLastSeen)
+ const isOtherCluster = consoleGsAddress !== gatewayServerAddress
+
+ const dispatch = useDispatch()
+
+ useConnectionReactor(gtwId)
+
+ useEffect(() => {
+ dispatch(startGatewayStatistics(gtwId))
+ return () => {
+ dispatch(stopGatewayStatistics())
+ }
+ }, [dispatch, gtwId])
+
+ const status = useMemo(() => {
+ const statsNotFound = Boolean(error) && isNotFoundError(error)
+ const isDisconnected = Boolean(statistics) && Boolean(statistics.disconnected_at)
+ const isFetching = !Boolean(statistics) && fetching
+ const isUnavailable = Boolean(error) && Boolean(error.message) && isTranslated(error.message)
+ const hasStatistics = Boolean(statistics)
+ const hasLastSeen = Boolean(lastSeen)
+
+ let statusIndicator = null
+ let message = null
+ let tooltipMessage = undefined
+ let docPath = '/getting-started/console/troubleshooting'
+ let docTitle = sharedMessages.troubleshooting
+
+ if (statsNotFound) {
+ statusIndicator = 'bad'
+ message = sharedMessages.disconnected
+ tooltipMessage = m.disconnectedTooltip
+ docPath = '/gateways/troubleshooting/#my-gateway-wont-connect-what-do-i-do'
+ } else if (isDisconnected) {
+ tooltipMessage = m.disconnectedTooltip
+ docPath = '/gateways/troubleshooting/#my-gateway-wont-connect-what-do-i-do'
+ } else if (isFetching) {
+ statusIndicator = 'mediocre'
+ message = sharedMessages.connecting
+ } else if (isUnavailable) {
+ statusIndicator = 'unknown'
+ message = error.message
+ if (isOtherCluster) {
+ tooltipMessage = m.otherClusterTooltip
+ docPath = '/gateways/troubleshooting/#my-gateway-shows-a-other-cluster-status-why'
+ }
+ } else if (hasStatistics) {
+ message = sharedMessages.connected
+ statusIndicator = 'good'
+ if (hasLastSeen) {
+ tooltipMessage = m.lastSeenAvailableTooltip
+ } else {
+ docPath =
+ 'gateways/troubleshooting/#my-gateway-is-shown-as-connected-in-the-console-but-i-dont-see-any-events-including-the-gateway-connection-stats-what-do-i-do'
+ tooltipMessage = m.connectedTooltip
+ }
+ docTitle = sharedMessages.moreInformation
+ } else {
+ message = sharedMessages.unknown
+ statusIndicator = 'unknown'
+ docPath = '/gateways/troubleshooting'
+ }
+
+ let node
+
+ if (isDisconnected) {
+ node = (
+
+
+
+ )
+ } else if (statusIndicator === 'good' && hasLastSeen) {
+ node = (
+
+
+
+ )
+ } else {
+ node = (
+
+
+
+ )
+ }
+
+ if (tooltipMessage) {
+ return (
+ }
+ children={node}
+ />
+ )
+ }
+
+ return node
+ }, [error, fetching, isOtherCluster, lastSeen, statistics])
+
+ const messages = useMemo(() => {
+ if (!statistics) {
+ return null
+ }
+
+ const uplinks = statistics.uplink_count || '0'
+ const downlinks = statistics.downlink_count || '0'
+
+ const uplinkCount = parseInt(uplinks) || 0
+ const downlinkCount = parseInt(downlinks) || 0
+
+ return (
+ }>
+
+
+
+
+
+
+
+
+
+
+
+ )
+ }, [statistics])
+
+ return (
+
+ {messages}
+ {status}
+
+ )
+}
+
+GatewayConnection.propTypes = {
+ className: PropTypes.string,
+ gtwId: PropTypes.string.isRequired,
+}
+
+GatewayConnection.defaultProps = {
+ className: undefined,
+}
+
+export default GatewayConnection
diff --git a/pkg/webui/console/containers/gateway-connection/use-connection-reactor.js b/pkg/webui/console/containers/gateway-connection/use-connection-reactor.js
new file mode 100644
index 0000000000..eb81de7567
--- /dev/null
+++ b/pkg/webui/console/containers/gateway-connection/use-connection-reactor.js
@@ -0,0 +1,46 @@
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import { useEffect, useRef } from 'react'
+import { useDispatch, useSelector } from 'react-redux'
+
+import {
+ isGsDownlinkSendEvent,
+ isGsStatusReceiveEvent,
+ isGsUplinkReceiveEvent,
+} from '@ttn-lw/lib/selectors/event'
+
+import { updateGatewayStatistics } from '@console/store/actions/gateways'
+
+import { selectLatestGatewayEvent } from '@console/store/selectors/gateways'
+
+const useConnectionReactor = gtwId => {
+ const latestEvent = useSelector(state => selectLatestGatewayEvent(state, gtwId))
+ const dispatch = useDispatch()
+ const prevEvent = useRef(null)
+
+ useEffect(() => {
+ if (Boolean(latestEvent) && latestEvent !== prevEvent.current) {
+ const { name } = latestEvent
+ const isHeartBeatEvent =
+ isGsDownlinkSendEvent(name) || isGsUplinkReceiveEvent(name) || isGsStatusReceiveEvent(name)
+
+ if (isHeartBeatEvent) {
+ dispatch(updateGatewayStatistics(gtwId))
+ }
+ prevEvent.current = latestEvent
+ }
+ }, [dispatch, gtwId, latestEvent])
+}
+export default useConnectionReactor
diff --git a/pkg/webui/console/containers/gateway-events/index.js b/pkg/webui/console/containers/gateway-events/index.js
index c9283fb0b6..a876b98e67 100644
--- a/pkg/webui/console/containers/gateway-events/index.js
+++ b/pkg/webui/console/containers/gateway-events/index.js
@@ -12,12 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import React from 'react'
-import { connect } from 'react-redux'
+import React, { useCallback, useMemo } from 'react'
+import { useDispatch, useSelector } from 'react-redux'
import Events from '@console/components/events'
-import withFeatureRequirement from '@console/lib/components/with-feature-requirement'
+import Require from '@console/lib/components/require'
import PropTypes from '@ttn-lw/lib/prop-types'
@@ -38,76 +38,74 @@ import {
} from '@console/store/selectors/gateways'
const GatewayEvents = props => {
- const {
- gtwId,
- events,
- widget,
- paused,
- onPauseToggle,
- onClear,
- onFilterChange,
- truncated,
- filter,
- } = props
-
- if (widget) {
+ const { gtwId, widget } = props
+
+ const events = useSelector(state => selectGatewayEvents(state, gtwId))
+ const paused = useSelector(state => selectGatewayEventsPaused(state, gtwId))
+ const truncated = useSelector(state => selectGatewayEventsTruncated(state, gtwId))
+ const filter = useSelector(state => selectGatewayEventsFilter(state, gtwId))
+
+ const dispatch = useDispatch()
+
+ const onClear = useCallback(() => {
+ dispatch(clearGatewayEventsStream(gtwId))
+ }, [dispatch, gtwId])
+
+ const onPauseToggle = useCallback(
+ paused => {
+ if (paused) {
+ dispatch(resumeGatewayEventsStream(gtwId))
+ return
+ }
+ dispatch(pauseGatewayEventsStream(gtwId))
+ },
+ [dispatch, gtwId],
+ )
+
+ const onFilterChange = useCallback(
+ filterId => {
+ dispatch(setGatewayEventsFilter(gtwId, filterId))
+ },
+ [dispatch, gtwId],
+ )
+
+ const content = useMemo(() => {
+ if (widget) {
+ return (
+
+ )
+ }
+
return (
-
+
)
- }
-
- return (
-
- )
+ }, [events, filter, gtwId, onClear, onFilterChange, onPauseToggle, paused, truncated, widget])
+
+ return {content}
}
GatewayEvents.propTypes = {
- events: PropTypes.events,
- filter: PropTypes.eventFilter,
gtwId: PropTypes.string.isRequired,
- onClear: PropTypes.func.isRequired,
- onFilterChange: PropTypes.func.isRequired,
- onPauseToggle: PropTypes.func.isRequired,
- paused: PropTypes.bool.isRequired,
- truncated: PropTypes.bool.isRequired,
widget: PropTypes.bool,
}
GatewayEvents.defaultProps = {
widget: false,
- events: [],
- filter: undefined,
}
-export default withFeatureRequirement(mayViewGatewayEvents)(
- connect(
- (state, props) => {
- const { gtwId } = props
-
- return {
- events: selectGatewayEvents(state, gtwId),
- paused: selectGatewayEventsPaused(state, gtwId),
- truncated: selectGatewayEventsTruncated(state, gtwId),
- filter: selectGatewayEventsFilter(state, gtwId),
- }
- },
- (dispatch, ownProps) => ({
- onClear: () => dispatch(clearGatewayEventsStream(ownProps.gtwId)),
- onPauseToggle: paused =>
- paused
- ? dispatch(resumeGatewayEventsStream(ownProps.gtwId))
- : dispatch(pauseGatewayEventsStream(ownProps.gtwId)),
- onFilterChange: filterId => dispatch(setGatewayEventsFilter(ownProps.gtwId, filterId)),
- }),
- )(GatewayEvents),
-)
+export default GatewayEvents
diff --git a/pkg/webui/console/containers/gateway-location-form/connect.js b/pkg/webui/console/containers/gateway-location-form/connect.js
deleted file mode 100644
index cf67f307ac..0000000000
--- a/pkg/webui/console/containers/gateway-location-form/connect.js
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright © 2020 The Things Network Foundation, The Things Industries B.V.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import { connect } from 'react-redux'
-
-import attachPromise from '@ttn-lw/lib/store/actions/attach-promise'
-
-import { updateGateway } from '@console/store/actions/gateways'
-
-import { selectSelectedGateway, selectSelectedGatewayId } from '@console/store/selectors/gateways'
-
-const mapStateToProps = state => ({
- gateway: selectSelectedGateway(state),
- gatewayId: selectSelectedGatewayId(state),
-})
-
-const mapDispatchToProps = {
- updateGateway: attachPromise(updateGateway),
-}
-
-export default Component => connect(mapStateToProps, mapDispatchToProps)(Component)
diff --git a/pkg/webui/console/containers/gateway-location-form/gateway-location-form.js b/pkg/webui/console/containers/gateway-location-form/gateway-location-form.js
deleted file mode 100644
index 520ee98241..0000000000
--- a/pkg/webui/console/containers/gateway-location-form/gateway-location-form.js
+++ /dev/null
@@ -1,239 +0,0 @@
-// Copyright © 2020 The Things Network Foundation, The Things Industries B.V.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import React, { useCallback, useState } from 'react'
-import { defineMessages } from 'react-intl'
-
-import Checkbox from '@ttn-lw/components/checkbox'
-import Form from '@ttn-lw/components/form'
-import Radio from '@ttn-lw/components/radio-button'
-
-import LocationForm, { hasLocationSet } from '@console/components/location-form'
-
-import Yup from '@ttn-lw/lib/yup'
-import PropTypes from '@ttn-lw/lib/prop-types'
-import sharedMessages from '@ttn-lw/lib/shared-messages'
-import tooltipIds from '@ttn-lw/lib/constants/tooltip-ids'
-
-import { latitude as latitudeRegexp, longitude as longitudeRegexp } from '@console/lib/regexp'
-
-const m = defineMessages({
- updateLocationFromStatus: 'Update from status messages',
- updateLocationFromStatusDescription:
- 'Update the location of this gateway based on incoming status messages',
- setGatewayLocation: 'Gateway antenna location settings',
- locationSource: 'Location source',
- locationPrivacy: 'Location privacy',
- placement: 'Placement',
- indoor: 'Indoor',
- outdoor: 'Outdoor',
- locationFromStatusMessage: 'Location set automatically from status messages',
- setLocationManually: 'Set location manually',
- noLocationSetInfo: 'This gateway has no location information set',
-})
-
-const validationSchema = Yup.object().shape({
- latitude: Yup.number().when('update_location_from_status', {
- is: false,
- then: schema =>
- schema
- .required(sharedMessages.validateRequired)
- .test('is-valid-latitude', sharedMessages.validateLatitude, value =>
- latitudeRegexp.test(String(value)),
- ),
- otherwise: schema => schema.strip(),
- }),
- longitude: Yup.number().when('update_location_from_status', {
- is: false,
- then: schema =>
- schema
- .required(sharedMessages.validateRequired)
- .test('is-valid-longitude', sharedMessages.validateLongitude, value =>
- longitudeRegexp.test(String(value)),
- ),
- otherwise: schema => schema.strip(),
- }),
- altitude: Yup.number().when('update_location_from_status', {
- is: false,
- then: schema =>
- schema.integer(sharedMessages.validateInt32).required(sharedMessages.validateRequired),
- otherwise: schema => schema.strip(),
- }),
- location_public: Yup.bool(),
- update_location_from_status: Yup.bool(),
- placement: Yup.string().oneOf(['PLACEMENT_UNKNOWN', 'INDOOR', 'OUTDOOR']),
-})
-
-const getRegistryLocation = antennas => {
- let registryLocation
- if (antennas) {
- for (const key of Object.keys(antennas)) {
- if (
- antennas[key].location !== null &&
- typeof antennas[key].location === 'object' &&
- antennas[key].location.source === 'SOURCE_REGISTRY'
- ) {
- registryLocation = { antenna: antennas[key], key }
- break
- } else {
- registryLocation = { antenna: antennas[key], key }
- }
- }
- }
- return registryLocation
-}
-
-const GatewayLocationForm = ({ gateway, gatewayId, updateGateway }) => {
- const registryLocation = getRegistryLocation(gateway.antennas)
- const initialValues = {
- placement:
- registryLocation && registryLocation.antenna.placement
- ? registryLocation.antenna.placement
- : 'PLACEMENT_UNKNOWN',
- location_public: gateway.location_public || false,
- update_location_from_status: gateway.update_location_from_status || false,
- ...(hasLocationSet(registryLocation?.antenna?.location)
- ? registryLocation.antenna.location
- : {
- latitude: undefined,
- longitude: undefined,
- altitude: undefined,
- }),
- }
-
- const handleSubmit = useCallback(
- async values => {
- const { update_location_from_status, location_public, placement, ...location } = values
- const patch = {
- location_public,
- update_location_from_status,
- }
-
- const registryLocation = getRegistryLocation(gateway.antennas)
- if (!values.update_location_from_status) {
- if (registryLocation) {
- // Update old location value.
- patch.antennas = [...gateway.antennas]
- patch.antennas[registryLocation.key].location = {
- ...registryLocation.antenna.location,
- ...location,
- }
- patch.antennas[registryLocation.key].placement = placement
- } else {
- // Create new location value.
- patch.antennas = [
- {
- gain: 0,
- location: {
- ...values,
- accuracy: 0,
- source: 'SOURCE_REGISTRY',
- },
- placement,
- },
- ]
- }
- } else if (registryLocation) {
- patch.antennas = gateway.antennas.map(antenna => {
- const { location, ...rest } = antenna
- return rest
- })
- patch.antennas[registryLocation.key].placement = values.placement
- } else {
- patch.antennas = [{ gain: 0, placement: values.placement }]
- }
-
- return updateGateway(gatewayId, patch)
- },
- [gateway, gatewayId, updateGateway],
- )
-
- const handleDelete = useCallback(
- async deleteAll => {
- const registryLocation = getRegistryLocation(gateway.antennas)
-
- if (deleteAll) {
- return updateGateway(gatewayId, { antennas: [] })
- }
-
- const patch = {
- antennas: [...gateway.antennas],
- }
- patch.antennas.splice(registryLocation.key, 1)
-
- return updateGateway(gatewayId, patch)
- },
- [gateway, gatewayId, updateGateway],
- )
-
- const [updateLocationFromStatus, setUpdateLocationFromStatus] = useState(
- initialValues.update_location_from_status,
- )
-
- const handleUpdateLocationFromStatusChange = useCallback(useAutomaticUpdates => {
- setUpdateLocationFromStatus(useAutomaticUpdates)
- }, [])
-
- return (
-
-
-
-
-
-
-
-
-
-
-
-
- )
-}
-
-GatewayLocationForm.propTypes = {
- gateway: PropTypes.gateway.isRequired,
- gatewayId: PropTypes.string.isRequired,
- updateGateway: PropTypes.func.isRequired,
-}
-
-export default GatewayLocationForm
diff --git a/pkg/webui/console/containers/gateway-location-form/index.js b/pkg/webui/console/containers/gateway-location-form/index.js
index badd87cdf6..b72ab0fcf2 100644
--- a/pkg/webui/console/containers/gateway-location-form/index.js
+++ b/pkg/webui/console/containers/gateway-location-form/index.js
@@ -1,4 +1,4 @@
-// Copyright © 2020 The Things Network Foundation, The Things Industries B.V.
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,7 +12,230 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import GatewayLocationForm from './gateway-location-form'
-import connect from './connect'
+import React, { useCallback, useState } from 'react'
+import { defineMessages } from 'react-intl'
+import { useDispatch, useSelector } from 'react-redux'
-export default connect(GatewayLocationForm)
+import Checkbox from '@ttn-lw/components/checkbox'
+import Form from '@ttn-lw/components/form'
+import Radio from '@ttn-lw/components/radio-button'
+
+import LocationForm, { hasLocationSet } from '@console/components/location-form'
+
+import Yup from '@ttn-lw/lib/yup'
+import sharedMessages from '@ttn-lw/lib/shared-messages'
+import tooltipIds from '@ttn-lw/lib/constants/tooltip-ids'
+import attachPromise from '@ttn-lw/lib/store/actions/attach-promise'
+
+import { latitude as latitudeRegexp, longitude as longitudeRegexp } from '@console/lib/regexp'
+
+import { updateGateway } from '@console/store/actions/gateways'
+
+import { selectSelectedGateway, selectSelectedGatewayId } from '@console/store/selectors/gateways'
+
+const m = defineMessages({
+ updateLocationFromStatus: 'Update from status messages',
+ updateLocationFromStatusDescription:
+ 'Update the location of this gateway based on incoming status messages',
+ setGatewayLocation: 'Gateway antenna location settings',
+ locationSource: 'Location source',
+ locationPrivacy: 'Location privacy',
+ placement: 'Placement',
+ indoor: 'Indoor',
+ outdoor: 'Outdoor',
+ locationFromStatusMessage: 'Location set automatically from status messages',
+ setLocationManually: 'Set location manually',
+ noLocationSetInfo: 'This gateway has no location information set',
+})
+
+const validationSchema = Yup.object().shape({
+ latitude: Yup.number().when('update_location_from_status', {
+ is: false,
+ then: schema =>
+ schema
+ .required(sharedMessages.validateRequired)
+ .test('is-valid-latitude', sharedMessages.validateLatitude, value =>
+ latitudeRegexp.test(String(value)),
+ ),
+ otherwise: schema => schema.strip(),
+ }),
+ longitude: Yup.number().when('update_location_from_status', {
+ is: false,
+ then: schema =>
+ schema
+ .required(sharedMessages.validateRequired)
+ .test('is-valid-longitude', sharedMessages.validateLongitude, value =>
+ longitudeRegexp.test(String(value)),
+ ),
+ otherwise: schema => schema.strip(),
+ }),
+ altitude: Yup.number().when('update_location_from_status', {
+ is: false,
+ then: schema =>
+ schema.integer(sharedMessages.validateInt32).required(sharedMessages.validateRequired),
+ otherwise: schema => schema.strip(),
+ }),
+ location_public: Yup.bool(),
+ update_location_from_status: Yup.bool(),
+ placement: Yup.string().oneOf(['PLACEMENT_UNKNOWN', 'INDOOR', 'OUTDOOR']),
+})
+
+const getRegistryLocation = antennas => {
+ let registryLocation
+ if (antennas) {
+ for (const key of Object.keys(antennas)) {
+ if (
+ antennas[key].location !== null &&
+ typeof antennas[key].location === 'object' &&
+ antennas[key].location.source === 'SOURCE_REGISTRY'
+ ) {
+ registryLocation = { antenna: antennas[key], key }
+ break
+ } else {
+ registryLocation = { antenna: antennas[key], key }
+ }
+ }
+ }
+ return registryLocation
+}
+
+const GatewayLocationForm = () => {
+ const gateway = useSelector(selectSelectedGateway)
+ const gatewayId = useSelector(selectSelectedGatewayId)
+ const dispatch = useDispatch()
+ const registryLocation = getRegistryLocation(gateway.antennas)
+ const initialValues = {
+ placement:
+ registryLocation && registryLocation.antenna.placement
+ ? registryLocation.antenna.placement
+ : 'PLACEMENT_UNKNOWN',
+ location_public: gateway.location_public || false,
+ update_location_from_status: gateway.update_location_from_status || false,
+ ...(hasLocationSet(registryLocation?.antenna?.location)
+ ? registryLocation.antenna.location
+ : {
+ latitude: undefined,
+ longitude: undefined,
+ altitude: undefined,
+ }),
+ }
+
+ const handleSubmit = useCallback(
+ async values => {
+ const { update_location_from_status, location_public, placement, ...location } = values
+ const patch = {
+ location_public,
+ update_location_from_status,
+ }
+
+ const registryLocation = getRegistryLocation(gateway.antennas)
+ if (!values.update_location_from_status) {
+ if (registryLocation) {
+ // Update old location value.
+ patch.antennas = [...gateway.antennas]
+ patch.antennas[registryLocation.key].location = {
+ ...registryLocation.antenna.location,
+ ...location,
+ }
+ patch.antennas[registryLocation.key].placement = placement
+ } else {
+ // Create new location value.
+ patch.antennas = [
+ {
+ gain: 0,
+ location: {
+ ...values,
+ accuracy: 0,
+ source: 'SOURCE_REGISTRY',
+ },
+ placement,
+ },
+ ]
+ }
+ } else if (registryLocation) {
+ patch.antennas = gateway.antennas.map(antenna => {
+ const { location, ...rest } = antenna
+ return rest
+ })
+ patch.antennas[registryLocation.key].placement = values.placement
+ } else {
+ patch.antennas = [{ gain: 0, placement: values.placement }]
+ }
+
+ return dispatch(attachPromise(updateGateway(gatewayId, patch)))
+ },
+ [dispatch, gateway.antennas, gatewayId],
+ )
+
+ const handleDelete = useCallback(
+ async deleteAll => {
+ const registryLocation = getRegistryLocation(gateway.antennas)
+
+ if (deleteAll) {
+ return dispatch(attachPromise(updateGateway(gatewayId, { antennas: [] })))
+ }
+
+ const patch = {
+ antennas: [...gateway.antennas],
+ }
+ patch.antennas.splice(registryLocation.key, 1)
+
+ return dispatch(attachPromise(updateGateway(gatewayId, patch)))
+ },
+ [dispatch, gateway.antennas, gatewayId],
+ )
+
+ const [updateLocationFromStatus, setUpdateLocationFromStatus] = useState(
+ initialValues.update_location_from_status,
+ )
+
+ const handleUpdateLocationFromStatusChange = useCallback(useAutomaticUpdates => {
+ setUpdateLocationFromStatus(useAutomaticUpdates)
+ }, [])
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+export default GatewayLocationForm
diff --git a/pkg/webui/console/containers/gateway-onboarding-form/gateway-provisioning-form/gateway-registration-form-section/index.js b/pkg/webui/console/containers/gateway-onboarding-form/gateway-provisioning-form/gateway-registration-form-section/index.js
index 94550191b9..9793941419 100644
--- a/pkg/webui/console/containers/gateway-onboarding-form/gateway-provisioning-form/gateway-registration-form-section/index.js
+++ b/pkg/webui/console/containers/gateway-onboarding-form/gateway-provisioning-form/gateway-registration-form-section/index.js
@@ -16,8 +16,6 @@ import React from 'react'
import { useFormikContext } from 'formik'
import { defineMessages } from 'react-intl'
-import frequencyPlans from '@console/constants/frequency-plans'
-
import Form from '@ttn-lw/components/form'
import Input from '@ttn-lw/components/input'
import Checkbox from '@ttn-lw/components/checkbox'
@@ -28,7 +26,7 @@ import SubmitButton from '@ttn-lw/components/submit-button'
import Message from '@ttn-lw/lib/components/message'
-import { GsFrequencyPlansSelect as FrequencyPlansSelect } from '@console/containers/freq-plans-select'
+import GsFrequencyPlansSelect from '@console/containers/freq-plans-select/gs-frequency-plan-select'
import { selectGsConfig } from '@ttn-lw/lib/selectors/env'
import sharedMessages from '@ttn-lw/lib/shared-messages'
@@ -41,8 +39,6 @@ const m = defineMessages({
'Select which information can be seen by other network participants, including {packetBrokerURL}',
shareGatewayInfoDescription:
'Choose this option eg. if your gateway is powered by {loraBasicStationURL}',
- generateAPIKeyCups: 'Generate API key for CUPS',
- generateAPIKeyLNS: 'Generate API key for LNS',
})
const PacketBrokerURL = (
@@ -67,7 +63,7 @@ const initialValues = {
},
status_public: true,
location_public: true,
- frequency_plan_id: '',
+ frequency_plan_ids: [''],
name: '',
require_authenticated_connection: false,
gateway_server_address: gsEnabled ? new URL(gsBaseURL).hostname : '',
@@ -95,19 +91,7 @@ const GatewayRegistrationFormSections = () => {
component={Input}
tooltipId={tooltipIds.GATEWAY_NAME}
/>
- {gsEnabled && (
-
- )}
+ {gsEnabled && }
{
{
+ frequencyPlanIds.length > 0 && frequencyPlanIds.some(entry => entry !== '' && entry !== undefined)
+
const validationSchema = Yup.object().shape({
ids: Yup.object().shape({
gateway_id: Yup.string()
@@ -44,11 +53,12 @@ const validationSchema = Yup.object().shape({
require_authenticated_connection: Yup.boolean(),
location_public: Yup.boolean(),
status_public: Yup.boolean(),
- frequency_plan_id: gsEnabled
- ? Yup.string()
- .max(64, Yup.passValues(sharedMessages.validateTooLong))
- .required(sharedMessages.validateRequired)
- : Yup.string(),
+ frequency_plan_ids: gsEnabled
+ ? Yup.array()
+ .of(Yup.string().max(64, Yup.passValues(sharedMessages.validateTooLong)))
+ .max(8, Yup.passValues(sharedMessages.attributesValidateTooMany))
+ .test('has at least one entry', m.validateEntry, hasAtLeastOneEntry)
+ : Yup.array(),
})
export default validationSchema
diff --git a/pkg/webui/console/containers/invite-user-form/index.js b/pkg/webui/console/containers/invite-user-form/index.js
index e0bfadad54..741f07d7f3 100644
--- a/pkg/webui/console/containers/invite-user-form/index.js
+++ b/pkg/webui/console/containers/invite-user-form/index.js
@@ -31,7 +31,6 @@ import attachPromise from '@ttn-lw/lib/store/actions/attach-promise'
import { sendInvite } from '@console/store/actions/users'
const m = defineMessages({
- emailPlaceholder: 'mail@example.com',
invitationsDescription:
'You can invite users to this network by providing an email address. The person will then get an email with instructions on how to join your network.',
})
@@ -80,7 +79,7 @@ const InviteForm = () => {
title={sharedMessages.emailAddress}
component={Input}
name="email"
- placeholder={m.emailPlaceholder}
+ placeholder={sharedMessages.emailPlaceholder}
required
/>
diff --git a/pkg/webui/console/containers/lora-cloud-das-form/index.js b/pkg/webui/console/containers/lora-cloud-das-form/index.js
index 28f2da3108..fc5e5408e0 100644
--- a/pkg/webui/console/containers/lora-cloud-das-form/index.js
+++ b/pkg/webui/console/containers/lora-cloud-das-form/index.js
@@ -49,7 +49,6 @@ const m = defineMessages({
fPortSetDescription:
'Comma separated list of F-Port values (1-223) to be used for LoRa Cloud Modem Services',
modemEncoding: 'LoRa Edge Reference Tracker (Modem-E) encoding',
- setLoRaCloudToken: 'Set LoRa Cloud token',
deleteWarning:
'Are you sure you want to delete the LoRa Cloud Modem and Geolocation Services token? This action cannot be undone.',
fPortSetValidationFormat:
diff --git a/pkg/webui/console/containers/lora-cloud-gls-form/index.js b/pkg/webui/console/containers/lora-cloud-gls-form/index.js
index 0fb72fc002..492852e3b7 100644
--- a/pkg/webui/console/containers/lora-cloud-gls-form/index.js
+++ b/pkg/webui/console/containers/lora-cloud-gls-form/index.js
@@ -45,7 +45,6 @@ import {
const m = defineMessages({
tokenDescription: 'Geolocation access token as configured within LoRa Cloud',
- setLoRaCloudToken: 'Set LoRa Cloud token',
deleteWarning:
'Are you sure you want to delete the LoRaCloud Geolocation token? This action cannot be undone.',
queryType: 'Query type',
diff --git a/pkg/webui/console/containers/organization-events/connect.js b/pkg/webui/console/containers/organization-events/connect.js
deleted file mode 100644
index ec37e084ba..0000000000
--- a/pkg/webui/console/containers/organization-events/connect.js
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright © 2019 The Things Network Foundation, The Things Industries B.V.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import { connect } from 'react-redux'
-
-import {
- clearOrganizationEventsStream,
- pauseOrganizationEventsStream,
- resumeOrganizationEventsStream,
-} from '@console/store/actions/organizations'
-
-import {
- selectOrganizationEvents,
- selectOrganizationEventsPaused,
- selectOrganizationEventsTruncated,
-} from '@console/store/selectors/organizations'
-
-const mapStateToProps = (state, props) => {
- const { orgId } = props
-
- return {
- events: selectOrganizationEvents(state, orgId),
- paused: selectOrganizationEventsPaused(state, orgId),
- truncated: selectOrganizationEventsTruncated(state, orgId),
- }
-}
-
-const mapDispatchToProps = (dispatch, ownProps) => ({
- onClear: () => dispatch(clearOrganizationEventsStream(ownProps.orgId)),
- onPauseToggle: paused =>
- paused
- ? dispatch(resumeOrganizationEventsStream(ownProps.orgId))
- : dispatch(pauseOrganizationEventsStream(ownProps.orgId)),
-})
-
-export default Events => connect(mapStateToProps, mapDispatchToProps)(Events)
diff --git a/pkg/webui/console/containers/organization-events/index.js b/pkg/webui/console/containers/organization-events/index.js
index 98a82898da..a9f830c22e 100644
--- a/pkg/webui/console/containers/organization-events/index.js
+++ b/pkg/webui/console/containers/organization-events/index.js
@@ -12,9 +12,80 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import Events from './organization-events'
-import connect from './connect'
+import React, { useCallback } from 'react'
+import { useDispatch, useSelector } from 'react-redux'
-const ConnectedOrganizationEvents = connect(Events)
+import Events from '@console/components/events'
-export { ConnectedOrganizationEvents as default, Events }
+import PropTypes from '@ttn-lw/lib/prop-types'
+
+import {
+ clearOrganizationEventsStream,
+ pauseOrganizationEventsStream,
+ resumeOrganizationEventsStream,
+} from '@console/store/actions/organizations'
+
+import {
+ selectOrganizationEvents,
+ selectOrganizationEventsPaused,
+ selectOrganizationEventsTruncated,
+} from '@console/store/selectors/organizations'
+
+const OrganizationEvents = props => {
+ const { orgId, widget } = props
+
+ const events = useSelector(state => selectOrganizationEvents(state, orgId))
+ const paused = useSelector(state => selectOrganizationEventsPaused(state, orgId))
+ const truncated = useSelector(state => selectOrganizationEventsTruncated(state, orgId))
+
+ const dispatch = useDispatch()
+
+ const onPauseToggle = useCallback(
+ paused => {
+ if (paused) {
+ dispatch(resumeOrganizationEventsStream(orgId))
+ return
+ }
+ dispatch(pauseOrganizationEventsStream(orgId))
+ },
+ [dispatch, orgId],
+ )
+
+ const onClear = useCallback(() => {
+ dispatch(clearOrganizationEventsStream(orgId))
+ }, [dispatch, orgId])
+
+ if (widget) {
+ return (
+
+ )
+ }
+
+ return (
+
+ )
+}
+
+OrganizationEvents.propTypes = {
+ orgId: PropTypes.string.isRequired,
+ widget: PropTypes.bool,
+}
+
+OrganizationEvents.defaultProps = {
+ widget: false,
+}
+
+export default OrganizationEvents
diff --git a/pkg/webui/console/containers/organization-events/organization-events.js b/pkg/webui/console/containers/organization-events/organization-events.js
deleted file mode 100644
index 25b61e5add..0000000000
--- a/pkg/webui/console/containers/organization-events/organization-events.js
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright © 2019 The Things Network Foundation, The Things Industries B.V.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import React from 'react'
-
-import Events from '@console/components/events'
-
-import PropTypes from '@ttn-lw/lib/prop-types'
-
-const OrganizationEvents = props => {
- const { orgId, events, widget, paused, onPauseToggle, onClear, truncated } = props
-
- if (widget) {
- return (
-
- )
- }
-
- return (
-
- )
-}
-
-OrganizationEvents.propTypes = {
- events: PropTypes.events,
- onClear: PropTypes.func.isRequired,
- onPauseToggle: PropTypes.func.isRequired,
- orgId: PropTypes.string.isRequired,
- paused: PropTypes.bool.isRequired,
- truncated: PropTypes.bool.isRequired,
- widget: PropTypes.bool,
-}
-
-OrganizationEvents.defaultProps = {
- widget: false,
- events: [],
-}
-
-export default OrganizationEvents
diff --git a/pkg/webui/console/containers/owners-select/connect.js b/pkg/webui/console/containers/owners-select/connect.js
deleted file mode 100644
index dcd1f08cd7..0000000000
--- a/pkg/webui/console/containers/owners-select/connect.js
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright © 2019 The Things Network Foundation, The Things Industries B.V.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import { connect } from 'react-redux'
-
-import { getOrganizationsList } from '@console/store/actions/organizations'
-
-import {
- selectOrganizationsFetching,
- selectOrganizationsError,
- selectOrganizations,
-} from '@console/store/selectors/organizations'
-import { selectUser } from '@console/store/selectors/logout'
-
-export default OwnersSelect =>
- connect(
- state => ({
- user: selectUser(state),
- organizations: selectOrganizations(state),
- error: selectOrganizationsError(state),
- fetching: selectOrganizationsFetching(state),
- }),
- { getOrganizationsList },
- )(OwnersSelect)
diff --git a/pkg/webui/console/containers/owners-select/index.js b/pkg/webui/console/containers/owners-select/index.js
index c20c89c993..b9454b96ec 100644
--- a/pkg/webui/console/containers/owners-select/index.js
+++ b/pkg/webui/console/containers/owners-select/index.js
@@ -12,9 +12,87 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import connect from './connect'
-import OwnersSelect from './owners-select'
+import React from 'react'
+import { defineMessages } from 'react-intl'
+import { useSelector } from 'react-redux'
-const ConnectedOwnersSelect = connect(OwnersSelect)
+import Select from '@ttn-lw/components/select'
+import Field from '@ttn-lw/components/form/field'
-export { ConnectedOwnersSelect as default, OwnersSelect }
+import { getOrganizationId, getUserId } from '@ttn-lw/lib/selectors/id'
+import PropTypes from '@ttn-lw/lib/prop-types'
+
+import { selectUser } from '@console/store/selectors/logout'
+import {
+ selectOrganizations,
+ selectOrganizationsError,
+ selectOrganizationsFetching,
+} from '@console/store/selectors/organizations'
+
+const m = defineMessages({
+ title: 'Owner',
+ warning: 'There was an error and the list of organizations could not be displayed',
+})
+
+const OwnersSelect = props => {
+ const { autoFocus, menuPlacement, name, onChange, required } = props
+
+ const user = useSelector(selectUser)
+ const organizations = useSelector(selectOrganizations)
+ const error = useSelector(selectOrganizationsError)
+ const fetching = useSelector(selectOrganizationsFetching)
+
+ const options = React.useMemo(() => {
+ const usrOption = { label: getUserId(user), value: getUserId(user) }
+ const orgsOptions = organizations.map(org => ({
+ label: getOrganizationId(org),
+ value: getOrganizationId(org),
+ }))
+
+ return [usrOption, ...orgsOptions]
+ }, [user, organizations])
+ const handleChange = React.useCallback(
+ value => {
+ onChange(options.find(option => option.value === value))
+ },
+ [onChange, options],
+ )
+
+ // Do not show the input when there are no alternative options.
+ if (options.length === 1) {
+ return null
+ }
+
+ return (
+
+ )
+}
+
+OwnersSelect.propTypes = {
+ autoFocus: PropTypes.bool,
+ menuPlacement: PropTypes.oneOf(['top', 'bottom', 'auto']),
+ name: PropTypes.string.isRequired,
+ onChange: PropTypes.func,
+ required: PropTypes.bool,
+}
+
+OwnersSelect.defaultProps = {
+ autoFocus: false,
+ onChange: () => null,
+ menuPlacement: 'auto',
+ required: false,
+}
+
+export default OwnersSelect
diff --git a/pkg/webui/console/containers/owners-select/owners-select.js b/pkg/webui/console/containers/owners-select/owners-select.js
deleted file mode 100644
index f8ad538978..0000000000
--- a/pkg/webui/console/containers/owners-select/owners-select.js
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright © 2019 The Things Network Foundation, The Things Industries B.V.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import React from 'react'
-import { defineMessages } from 'react-intl'
-
-import Select from '@ttn-lw/components/select'
-import Field from '@ttn-lw/components/form/field'
-
-import { getOrganizationId, getUserId } from '@ttn-lw/lib/selectors/id'
-import PropTypes from '@ttn-lw/lib/prop-types'
-
-const m = defineMessages({
- title: 'Owner',
- warning: 'There was an error and the list of organizations could not be displayed',
-})
-
-const OwnersSelect = props => {
- const {
- autoFocus,
- error,
- fetching,
- menuPlacement,
- name,
- onChange,
- organizations,
- required,
- user,
- } = props
-
- const options = React.useMemo(() => {
- const usrOption = { label: getUserId(user), value: getUserId(user) }
- const orgsOptions = organizations.map(org => ({
- label: getOrganizationId(org),
- value: getOrganizationId(org),
- }))
-
- return [usrOption, ...orgsOptions]
- }, [user, organizations])
- const handleChange = React.useCallback(
- value => {
- onChange(options.find(option => option.value === value))
- },
- [onChange, options],
- )
-
- // Do not show the input when there are no alternative options.
- if (options.length === 1) {
- return null
- }
-
- return (
-
- )
-}
-
-OwnersSelect.propTypes = {
- autoFocus: PropTypes.bool,
- error: PropTypes.error,
- fetching: PropTypes.bool,
- menuPlacement: PropTypes.oneOf(['top', 'bottom', 'auto']),
- name: PropTypes.string.isRequired,
- onChange: PropTypes.func,
- organizations: PropTypes.arrayOf(PropTypes.organization).isRequired,
- required: PropTypes.bool,
- user: PropTypes.user.isRequired,
-}
-
-OwnersSelect.defaultProps = {
- autoFocus: false,
- error: undefined,
- fetching: false,
- onChange: () => null,
- menuPlacement: 'auto',
- required: false,
-}
-
-export default OwnersSelect
diff --git a/pkg/webui/console/containers/pubsub-formats-select/index.js b/pkg/webui/console/containers/pubsub-formats-select/index.js
index 6605ee2968..afee2d2ff6 100644
--- a/pkg/webui/console/containers/pubsub-formats-select/index.js
+++ b/pkg/webui/console/containers/pubsub-formats-select/index.js
@@ -16,6 +16,8 @@ import { defineMessages } from 'react-intl'
import CreateFetchSelect from '@console/containers/fetch-select'
+import sharedMessages from '@ttn-lw/lib/shared-messages'
+
import { getPubsubFormats } from '@console/store/actions/pubsub-formats'
import {
@@ -25,7 +27,6 @@ import {
} from '@console/store/selectors/pubsub-formats'
const m = defineMessages({
- title: 'Pub/Sub format',
warning: 'Pub/Sub formats unavailable',
})
@@ -35,5 +36,5 @@ export default CreateFetchSelect({
errorSelector: selectPubsubFormatsError,
fetchingSelector: selectPubsubFormatsFetching,
defaultWarning: m.warning,
- defaultTitle: m.title,
+ defaultTitle: sharedMessages.pubsubFormat,
})
diff --git a/pkg/webui/console/containers/pubsubs-table/index.js b/pkg/webui/console/containers/pubsubs-table/index.js
index 3e548c07d3..6e555ea663 100644
--- a/pkg/webui/console/containers/pubsubs-table/index.js
+++ b/pkg/webui/console/containers/pubsubs-table/index.js
@@ -30,7 +30,6 @@ import { getPubsubsList } from '@console/store/actions/pubsubs'
import { selectPubsubs, selectPubsubsTotalCount } from '@console/store/selectors/pubsubs'
const m = defineMessages({
- format: 'Format',
host: 'Server host',
})
@@ -74,7 +73,7 @@ const headers = [
},
{
name: 'format',
- displayName: m.format,
+ displayName: sharedMessages.format,
width: 9,
sortable: true,
},
diff --git a/pkg/webui/console/containers/user-data-form/add.js b/pkg/webui/console/containers/user-data-form/add.js
index 46ac8e7fc8..993d5f50f0 100644
--- a/pkg/webui/console/containers/user-data-form/add.js
+++ b/pkg/webui/console/containers/user-data-form/add.js
@@ -16,7 +16,7 @@ import React, { useCallback, useState } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { useNavigate } from 'react-router-dom'
import { Container, Col, Row } from 'react-grid-system'
-import { defineMessages, useIntl } from 'react-intl'
+import { useIntl } from 'react-intl'
import PageTitle from '@ttn-lw/components/page-title'
import Form from '@ttn-lw/components/form'
@@ -44,22 +44,6 @@ const approvalStates = [
'STATE_SUSPENDED',
]
-const m = defineMessages({
- adminLabel: 'Grant this user admin status',
- adminDescription:
- 'Admin status enables overarching rights such as managing other users or modifying entities regardless of collaboration status',
- userDescPlaceholder: 'Description for my new user',
- userDescDescription: 'Optional user description; can also be used to save notes about the user',
- userIdPlaceholder: 'jane-doe',
- userNamePlaceholder: 'Jane Doe',
- emailPlaceholder: 'mail@example.com',
- emailAddressDescription:
- 'Primary email address used for logging in; this address is not publicly visible',
- emailAddressValidation: 'Treat email address as validated',
- emailAddressValidationDescription:
- 'Enable this option if you do not need this user to validate the email address',
-})
-
const baseValidationSchema = Yup.object().shape({
ids: Yup.object().shape({
user_id: Yup.string()
@@ -152,22 +136,22 @@ const UserDataFormAdd = () => {
@@ -181,14 +165,14 @@ const UserDataFormAdd = () => {
PERMANENTLY DELETE THIS ACCOUNT and LOCK THE USER ID AND EMAIL FOR RE-REGISTRATION . Associated entities (e.g. gateways, applications and end devices) owned by this user that do not have any other collaborators will become UNACCESSIBLE and it will NOT BE POSSIBLE TO REGISTER ENTITIES WITH THE SAME ID OR EUI's AGAIN . Make sure you assign new collaborators to such entities if you plan to continue using them.",
purgeWarning:
@@ -180,22 +166,22 @@ const UserDataFormEdit = () => {
@@ -209,14 +195,14 @@ const UserDataFormEdit = () => {
@@ -224,7 +210,7 @@ const UserDataFormEdit = () => {
message={sharedMessages.userDelete}
entityId={initialValues?.ids?.user_id}
entityName={initialValues?.name}
- title={m.deleteTitle}
+ title={sharedMessages.accountDeleteConfirmation}
confirmMessage={m.deleteConfirmMessage}
defaultMessage={m.deleteWarning}
purgeMessage={m.purgeWarning}
diff --git a/pkg/webui/console/containers/webhook-edit/index.js b/pkg/webui/console/containers/webhook-edit/index.js
index f95362ea24..cdfd339e63 100644
--- a/pkg/webui/console/containers/webhook-edit/index.js
+++ b/pkg/webui/console/containers/webhook-edit/index.js
@@ -13,7 +13,6 @@
// limitations under the License.
import React, { useState } from 'react'
-import { defineMessages } from 'react-intl'
import { useDispatch } from 'react-redux'
import { useNavigate } from 'react-router-dom'
@@ -26,16 +25,10 @@ import WebhookForm from '@console/components/webhook-form'
import diff from '@ttn-lw/lib/diff'
import PropTypes from '@ttn-lw/lib/prop-types'
import attachPromise from '@ttn-lw/lib/store/actions/attach-promise'
+import sharedMessages from '@ttn-lw/lib/shared-messages'
import { updateWebhook } from '@console/store/actions/webhooks'
-const m = defineMessages({
- editWebhook: 'Edit webhook',
- updateSuccess: 'Webhook updated',
- deleteSuccess: 'Webhook deleted',
- reactivateSuccess: 'Webhook activated',
-})
-
const WebhookEdit = props => {
const {
selectedWebhook,
@@ -68,7 +61,7 @@ const WebhookEdit = props => {
)
const showSuccessToast = React.useCallback(() => {
toast({
- message: m.updateSuccess,
+ message: sharedMessages.webhookUpdated,
type: toast.types.SUCCESS,
})
}, [])
@@ -94,7 +87,7 @@ const WebhookEdit = props => {
}, [appId, webhookId])
const handleDeleteSuccess = React.useCallback(() => {
toast({
- message: m.deleteSuccess,
+ message: sharedMessages.webhookDeleted,
type: toast.types.SUCCESS,
})
@@ -103,7 +96,7 @@ const WebhookEdit = props => {
const handleReactivateSuccess = React.useCallback(() => {
toast({
- message: m.reactivateSuccess,
+ message: sharedMessages.reactivateSuccess,
type: toast.types.SUCCESS,
})
}, [])
diff --git a/pkg/webui/console/containers/webhook-formats-select/index.js b/pkg/webui/console/containers/webhook-formats-select/index.js
index 1951e6a25c..b4d5619832 100644
--- a/pkg/webui/console/containers/webhook-formats-select/index.js
+++ b/pkg/webui/console/containers/webhook-formats-select/index.js
@@ -16,6 +16,8 @@ import { defineMessages } from 'react-intl'
import CreateFetchSelect from '@console/containers/fetch-select'
+import sharedMessages from '@ttn-lw/lib/shared-messages'
+
import { getWebhookFormats } from '@console/store/actions/webhook-formats'
import {
@@ -25,7 +27,6 @@ import {
} from '@console/store/selectors/webhook-formats'
const m = defineMessages({
- title: 'Webhook format',
warning: 'Webhook formats unavailable',
})
@@ -35,5 +36,5 @@ export default CreateFetchSelect({
errorSelector: selectWebhookFormatsError,
fetchingSelector: selectWebhookFormatsFetching,
defaultWarning: m.warning,
- defaultTitle: m.title,
+ defaultTitle: sharedMessages.webhookFormat,
})
diff --git a/pkg/webui/console/containers/webhooks-table/index.js b/pkg/webui/console/containers/webhooks-table/index.js
index aaf4a8c1dc..bbc5ab711c 100644
--- a/pkg/webui/console/containers/webhooks-table/index.js
+++ b/pkg/webui/console/containers/webhooks-table/index.js
@@ -36,8 +36,6 @@ import style from './webhooks-table.styl'
const m = defineMessages({
templateId: 'Template ID',
- format: 'Format',
- baseUrl: 'Base URL',
healthy: 'Healthy',
pending: 'Pending',
requestsFailing: 'Requests failing',
@@ -68,7 +66,7 @@ const WebhooksTable = () => {
},
{
name: 'base_url',
- displayName: m.baseUrl,
+ displayName: sharedMessages.webhookBaseUrl,
width: 40,
sortable: true,
},
diff --git a/pkg/webui/console/lib/components/with-feature-requirement.js b/pkg/webui/console/lib/components/with-feature-requirement.js
deleted file mode 100644
index a4aad75af5..0000000000
--- a/pkg/webui/console/lib/components/with-feature-requirement.js
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright © 2019 The Things Network Foundation, The Things Industries B.V.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import React from 'react'
-
-import Require from './require'
-
-/**
- * `withFeatureRequirement` is a HOC that checks whether the current has the
- * necessary authorization to view the wrapped component. It can be set up to
- * either redirect to another route, to render something different or to not
- * render anything if the requirement is not met.
- *
- * @param {object} featureCheck - The feature check object containing the right
- * selector as well as the check itself.
- * @param {object} otherwise - A configuration object determining what should be
- * rendered if the requirement was not met. If not set, nothing will be
- * rendered.
- * @returns {Function} - An instance of the `withFeatureRequirement` HOC.
- */
-const withFeatureRequirement = (featureCheck, otherwise) => Component =>
- class WithFeatureRequirement extends React.Component {
- constructor(props) {
- super(props)
-
- if (
- typeof otherwise === 'object' &&
- 'redirect' in otherwise &&
- typeof otherwise.redirect === 'function'
- ) {
- this.otherwise = { ...otherwise, redirect: otherwise.redirect(props) }
- } else {
- this.otherwise = otherwise
- }
- }
-
- render() {
- return (
-
-
-
- )
- }
- }
-
-export default withFeatureRequirement
diff --git a/pkg/webui/console/lib/events/definitions.js b/pkg/webui/console/lib/events/definitions.js
index 702679b1bd..d404fd629e 100644
--- a/pkg/webui/console/lib/events/definitions.js
+++ b/pkg/webui/console/lib/events/definitions.js
@@ -14,59 +14,71 @@
import { defineMessages } from 'react-intl'
+import sharedMessages from '@ttn-lw/lib/shared-messages'
+
import { defineSyntheticEvent } from './utils'
-export const eventMessages = defineMessages({
- 'synthetic.error.unknown:type': 'Unknown error',
- 'synthetic.error.unknown:preview':
- 'An unknown error occurred and one or more events could not be retrieved',
- 'synthetic.error.unknown:details':
- 'The Console encountered an unexpected error while handling the event stream data. It is possible that event data could not be displayed (correctly) as a result. Note that this is an internal error which does not imply any malfunction of your gateways or end devices.',
-
- 'synthetic.error.network_error:type': 'Network error',
- 'synthetic.error.network_error:preview': 'The stream connection was lost due to a network error',
- 'synthetic.error.network_error:details':
- 'The Console was not able to fetch further stream events because the network connection of your host machine was interrupted. This can have various causes, such as your host machine switching Wi-Fi networks or experiencing drops in signal strength. Please check your internet connection and ensure a stable internet connection to avoid stream disconnects. The stream will reconnect automatically once the internet connection has been re-established.',
-
- 'synthetic.status.reconnecting:type': 'Reconnecting',
- 'synthetic.status.reconnecting:preview': 'Attempting to reconnect…',
- 'synthetic.status.reconnecting:details':
- 'The Console will periodically try to reconnect to the event stream if the connection was interrupted.',
-
- 'synthetic.status.reconnected:type': 'Stream reconnected',
- 'synthetic.status.reconnected:preview': 'The stream connection has been re-established',
- 'synthetic.status.reconnected:details':
- 'The Console was able to reconnect to the internet and resumed the event stream. Subsequent event data will be received and displayed. Note that event data which was possibly emitted during the network disruption will not be re-delivered.',
-
- 'synthetic.status.closed:type': 'Stream connection closed',
- 'synthetic.status.closed:preview': 'The connection was closed by the stream provider',
- 'synthetic.status.closed:details':
- 'The Console received a close signal from the stream provider. This usually means that the backend server shut down. This can have various causes, such as scheduled maintenance or malfunction which caused a forced restart. The Console will then reconnect automatically once the stream provider becomes available again.',
-
- 'synthetic.status.cleared:type': 'Events cleared',
- 'synthetic.status.cleared:preview': 'The events list has been cleared',
- 'synthetic.status.cleared:details': 'The list of displayed events has been cleared.',
-
- 'synthetic.status.paused:type': 'Stream paused',
- 'synthetic.status.paused:preview': 'The event stream has been paused',
- 'synthetic.status.paused:details':
- 'The event stream has been paused by the user. Subsequent event data will not be displayed until the stream is resumed.',
-
- 'synthetic.status.resumed:type': 'Stream resumed',
- 'synthetic.status.resumed:preview': 'The event stream has been resumed after being paused',
- 'synthetic.status.resumed:details':
- 'The event stream has been resumed by the user and will receive new subsequent event data. Note that event data which was possibly emitted during the stream pause will not be re-delivered.',
-
- 'synthetic.status.filter_enabled:type': 'Filter enabled',
- 'synthetic.status.filter_enabled:preview': 'An event filter has been enabled',
- 'synthetic.status.filter_enabled:details':
- 'The event stream will now be filtered, meaning that some event types may be suppressed. See the details below for more information about the currently enabled filter.',
-
- 'synthetic.status.filter_disabled:type': 'Filter disabled',
- 'synthetic.status.filter_disabled:preview': 'The previously set event filter has been disabled',
- 'synthetic.status.filter_disabled:details':
- 'The event stream will not be filtered anymore. This means that you will see all events that come out of the event stream for this entity.',
-})
+export const eventMessages = {
+ 'synthetic.error.unknown:type': sharedMessages.unknownError,
+ ...defineMessages({
+ 'synthetic.error.unknown:preview':
+ 'An unknown error occurred and one or more events could not be retrieved',
+
+ 'synthetic.error.unknown:details':
+ 'The Console encountered an unexpected error while handling the event stream data. It is possible that event data could not be displayed (correctly) as a result. Note that this is an internal error which does not imply any malfunction of your gateways or end devices.',
+
+ 'synthetic.error.network_error:type': 'Network error',
+
+ 'synthetic.error.network_error:preview':
+ 'The stream connection was lost due to a network error',
+
+ 'synthetic.error.network_error:details':
+ 'The Console was not able to fetch further stream events because the network connection of your host machine was interrupted. This can have various causes, such as your host machine switching Wi-Fi networks or experiencing drops in signal strength. Please check your internet connection and ensure a stable internet connection to avoid stream disconnects. The stream will reconnect automatically once the internet connection has been re-established.',
+
+ 'synthetic.status.reconnecting:type': 'Reconnecting',
+ 'synthetic.status.reconnecting:preview': 'Attempting to reconnect…',
+
+ 'synthetic.status.reconnecting:details':
+ 'The Console will periodically try to reconnect to the event stream if the connection was interrupted.',
+
+ 'synthetic.status.reconnected:type': 'Stream reconnected',
+ 'synthetic.status.reconnected:preview': 'The stream connection has been re-established',
+ 'synthetic.status.reconnected:details':
+ 'The Console was able to reconnect to the network and resumed the event stream. Subsequent event data will be received and displayed. Note that event data which was possibly emitted during the network disruption will only be re-delivered within the range of the event retention configuration for your network.',
+
+ 'synthetic.status.closed:type': 'Stream connection closed',
+ 'synthetic.status.closed:preview': 'The connection was closed',
+ 'synthetic.status.closed:details':
+ 'The event stream was closed. This can be for various reasons, such as your machine going into standby mode or the internet connection being interrupted. The stream will reconnect automatically once the internet connection has been re-established.',
+
+ 'synthetic.status.cleared:type': 'Events cleared',
+ 'synthetic.status.cleared:preview': 'The events list has been cleared',
+ 'synthetic.status.cleared:details': 'The list of displayed events has been cleared.',
+ 'synthetic.status.paused:type': 'Stream paused',
+ 'synthetic.status.paused:preview': 'The event stream has been paused',
+
+ 'synthetic.status.paused:details':
+ 'The event stream has been paused by the user. Subsequent event data will not be displayed until the stream is resumed.',
+
+ 'synthetic.status.resumed:type': 'Stream resumed',
+ 'synthetic.status.resumed:preview': 'The event stream has been resumed after being paused',
+
+ 'synthetic.status.resumed:details':
+ 'The event stream has been resumed by the user and will receive new subsequent event data. Note that event data which was possibly emitted during the stream pause will not be re-delivered.',
+
+ 'synthetic.status.filter_enabled:type': 'Filter enabled',
+ 'synthetic.status.filter_enabled:preview': 'An event filter has been enabled',
+
+ 'synthetic.status.filter_enabled:details':
+ 'The event stream will now be filtered, meaning that some event types may be suppressed. See the details below for more information about the currently enabled filter.',
+
+ 'synthetic.status.filter_disabled:type': 'Filter disabled',
+ 'synthetic.status.filter_disabled:preview': 'The previously set event filter has been disabled',
+
+ 'synthetic.status.filter_disabled:details':
+ 'The event stream will not be filtered anymore. This means that you will see all events that come out of the event stream for this entity.',
+ }),
+}
export const EVENT_UNKNOWN_ERROR = 'synthetic.error.unknown'
export const EVENT_NETWORK_ERROR = 'synthetic.error.network_error'
diff --git a/pkg/webui/console/lib/packet-broker/messages.js b/pkg/webui/console/lib/packet-broker/messages.js
index b1c3ae9977..764cdb47c6 100644
--- a/pkg/webui/console/lib/packet-broker/messages.js
+++ b/pkg/webui/console/lib/packet-broker/messages.js
@@ -15,66 +15,42 @@
import { defineMessages } from 'react-intl'
export default defineMessages({
- applicationData: 'Application data',
applicationDataAllowDesc: 'Allow downlink messages with FPort between 1 and 255',
applicationDataDesc: 'Forward uplink messages with FPort 1-255',
- joinAccept: 'Join accept',
joinAcceptDesc: 'Allow join accept messages',
joinRequest: 'Join request',
joinRequestDesc: 'Forward join-request messages',
localizationInformation: 'Localization information',
localizationInformationDesc: 'Forward gateway location, RSSI, SNR and fine timestamp',
- macData: 'MAC data',
macDataAllowDesc: 'Allow downlink messages with FPort of 0',
macDataDesc: 'Forward uplink messages with FPort 0',
signalQualityInformation: 'Signal quality information',
signalQualityInformationDesc: 'Forward RSSI and SNR',
-
forwardsJoinRequest: 'Join request messages are forwarded',
doesNotForwardJoinRequest: 'Join request messages are not forwarded',
-
forwardsMacData: 'MAC data is forwarded',
doesNotForwardMacData: 'MAC data is not forwarded',
-
forwardsApplicationData: 'Application data is forwarded',
doesNotForwardApplicationData: 'Application data is not forwarded',
-
forwardsSignalQuality: 'Signal quality information is forwarded',
doesNotForwardSignalQuality: 'Signal quality information is not forwarded',
-
forwardsLocalization: 'Localization information is forwarded',
doesNotForwardLocalization: 'Localization information is not forwarded',
-
allowsJoinAccept: 'Join accept messages are allowed',
doesNotAllowJoinAccept: 'Join accept messages are not allowed',
-
allowsMacData: 'MAC data is allowed',
doesNotAllowMacData: 'MAC data is not allowed',
-
allowsApplicationData: 'Application data is allowed',
doesNotAllowApplicationData: 'Application data is not allowed',
-
uplinkPolicies: 'This top row shows the uplink forwarding policies of this network',
downlinkPolicies: 'This bottom row shows the downlink policies of this network',
-
- gatewayLocationLabel: 'Location',
-
gatewayAntennaPlacementLabel: 'Antenna placement',
gatewayAntennaPlacementDescription: 'Show antenna placement (indoor/outdoor)',
-
gatewayAntennaCountLabel: 'Antenna count',
-
gatewayFineTimestampsLabel: 'Fine timestamps',
gatewayFineTimestampsDescription: 'Whether the gateway produces fine timestamps',
-
- gatewayContactInfoLabel: 'Contact information',
gatewayContactInfoDescription: 'Show means to contact the gateway owner or operator',
-
- gatewayStatusLabel: 'Status',
gatewayStatusDescription: 'Show whether the gateway is online or offline',
-
- gatewayFreqPlanLabel: 'Frequency plan',
-
gatewayPacketRatesLabel: 'Packet rates',
gatewayPacketRatesDescription: 'Receive and transmission packet rates',
})
diff --git a/pkg/webui/console/store/actions/packet-broker.js b/pkg/webui/console/store/actions/packet-broker.js
index fc90e5b136..640826f679 100644
--- a/pkg/webui/console/store/actions/packet-broker.js
+++ b/pkg/webui/console/store/actions/packet-broker.js
@@ -210,6 +210,21 @@ export const [
},
] = createRequestActions(DELETE_HOME_NETWORK_ROUTING_POLICY_BASE, (id, policy) => ({ id, policy }))
+export const DELETE_ALL_HOME_NETWORK_ROUTING_POLICIES_BASE =
+ 'DELETE_ALL_HOME_NETWORK_ROUTING_POLICIES'
+export const [
+ {
+ request: DELETE_ALL_HOME_NETWORK_ROUTING_POLICIES,
+ success: DELETE_ALL_HOME_NETWORK_ROUTING_POLICIES_SUCCESS,
+ failure: DELETE_ALL_HOME_NETWORK_ROUTING_POLICIES_FAILURE,
+ },
+ {
+ request: deleteAllHomeNetworkRoutingPolicies,
+ success: deleteAllHomeNetworkRoutingPoliciesSuccess,
+ failure: deleteAllHomeNetworkRoutingPoliciesFailure,
+ },
+] = createRequestActions(DELETE_ALL_HOME_NETWORK_ROUTING_POLICIES_BASE, ids => ({ ids }))
+
export const GET_HOME_NETWORK_ROUTING_POLICIES_BASE = 'GET_HOME_NETWORK_ROUTING_POLICIES'
export const [
{
diff --git a/pkg/webui/console/store/middleware/logics/events.js b/pkg/webui/console/store/middleware/logics/events.js
index fe61572a04..7d6c0b0b1d 100644
--- a/pkg/webui/console/store/middleware/logics/events.js
+++ b/pkg/webui/console/store/middleware/logics/events.js
@@ -132,19 +132,21 @@ const createEventsConnectLogics = (reducerName, entityName, onEventsStart) => {
try {
channel = await onEventsStart([id], filterRegExp, EVENT_TAIL, after)
+ dispatch(startEventsSuccess(id, { silent }))
- channel.on('start', () => dispatch(startEventsSuccess(id, { silent })))
- channel.on('chunk', message => dispatch(getEventSuccess(id, message)))
+ channel.on('message', message => dispatch(getEventSuccess(id, message)))
channel.on('error', error => dispatch(getEventFailure(id, error)))
- channel.on('close', wasClientRequest =>
- dispatch(closeEvents(id, { silent: wasClientRequest })),
- )
-
- channel.open()
+ channel.on('close', wasClientRequest => {
+ dispatch(closeEvents(id, { silent: wasClientRequest }))
+ channel = null
+ })
} catch (error) {
if (isUnauthenticatedError(error)) {
// The user is no longer authenticated; reinitiate the auth flow
// by refreshing the page.
+ // NOTE: As a result of the WebSocket refactor, the error shape is
+ // now very unspecific and authentication errors like before are
+ // not thrown anymore. This should be addressed eventually.
window.location.reload()
} else {
dispatch(startEventsFailure(id, error))
@@ -174,21 +176,16 @@ const createEventsConnectLogics = (reducerName, entityName, onEventsStart) => {
allow(action)
},
process: ({ action }, dispatch, done) => {
- if (channel) {
- try {
- channel.close()
- } catch (error) {
- if (isNetworkError(error) || isTimeoutError(action.payload)) {
- // Set the connection status to `checking` to trigger connection checks
- // and detect possible offline state.
- dispatch(setStatusChecking())
+ if (action.error) {
+ if (action.error?.message === 'timeout') {
+ // Set the connection status to `checking` to trigger connection checks
+ // and detect possible offline state.
+ dispatch(setStatusChecking())
- // In case of a network error, the connection could not be closed
- // since the network connection is disrupted. We can regard this
- // as equivalent to a closed connection.
- return done()
- }
- throw error
+ // In case of a network error, the connection could not be closed
+ // since the network connection is disrupted. We can regard this
+ // as equivalent to a closed connection.
+ return done()
}
}
done()
@@ -245,6 +242,7 @@ const createEventsConnectLogics = (reducerName, entityName, onEventsStart) => {
type: SET_CONNECTION_STATUS,
process: ({ getState, action }, dispatch, done) => {
const isOnline = action.payload.onlineStatus === ONLINE_STATUS.ONLINE
+ const isOffline = action.payload.onlineStatus === ONLINE_STATUS.OFFLINE
if (isOnline) {
const state = getState()
@@ -268,6 +266,8 @@ const createEventsConnectLogics = (reducerName, entityName, onEventsStart) => {
dispatch(dispatch(startEvents(ids)))
}
}
+ } else if (isOffline) {
+ // If the app went offline, close the event stream.
}
done()
diff --git a/pkg/webui/console/store/middleware/logics/gateways.js b/pkg/webui/console/store/middleware/logics/gateways.js
index 08b2c58c4e..bc6c756499 100644
--- a/pkg/webui/console/store/middleware/logics/gateways.js
+++ b/pkg/webui/console/store/middleware/logics/gateways.js
@@ -118,39 +118,41 @@ const getGatewaysLogic = createRequestLogic({
if (options.withStatus) {
const gsConfig = selectGsConfig()
const consoleGsAddress = getHostFromUrl(gsConfig.base_url)
+ const gatewayIds = entities.map(e => e.ids)
+ let gatewaysStats = null
+ if (gatewayIds.length) {
+ gatewaysStats = await tts.Gateways.getBatchStatistics(gatewayIds)
+ }
- entities = await Promise.all(
- data.gateways.map(gateway => {
- const gatewayServerAddress = getHostFromUrl(gateway.gateway_server_address)
-
- if (!Boolean(gatewayServerAddress)) {
- return Promise.resolve({ ...gateway, status: 'unknown' })
- }
-
- if (gatewayServerAddress !== consoleGsAddress) {
- return Promise.resolve({ ...gateway, status: 'other-cluster' })
- }
-
- const id = getGatewayId(gateway)
- return tts.Gateways.getStatisticsById(id)
- .then(stats => {
- let status = 'unknown'
- if (Boolean(stats) && Boolean(stats.connected_at)) {
- status = 'connected'
- } else if (Boolean(stats) && Boolean(stats.disconnected_at)) {
- status = 'disconnected'
- }
- return { ...gateway, status }
- })
- .catch(err => {
- if (err && err.code === 5) {
- return { ...gateway, status: 'disconnected' }
- }
-
- return { ...gateway, status: 'unknown' }
- })
- }),
- )
+ entities = data.gateways.map(gateway => {
+ const gatewayServerAddress = getHostFromUrl(gateway.gateway_server_address)
+
+ if (!Boolean(gatewayServerAddress)) {
+ return { ...gateway, status: 'unknown' }
+ }
+
+ if (gatewayServerAddress !== consoleGsAddress) {
+ return { ...gateway, status: 'other-cluster' }
+ }
+
+ if (!gatewaysStats?.entries) {
+ return { ...gateway, status: 'disconnected' }
+ }
+
+ const id = getGatewayId(gateway)
+ let status = 'unknown'
+
+ if (Boolean(gatewaysStats.entries[id]) && Boolean(gatewaysStats.entries[id].connected_at)) {
+ status = 'connected'
+ } else if (
+ !Boolean(gatewaysStats.entries[id]) ||
+ Boolean(gatewaysStats.entries[id].disconnected_at)
+ ) {
+ status = 'disconnected'
+ }
+
+ return { ...gateway, status }
+ })
}
return {
diff --git a/pkg/webui/console/store/middleware/logics/packet-broker.js b/pkg/webui/console/store/middleware/logics/packet-broker.js
index 1eeed2ac8f..6017934e48 100644
--- a/pkg/webui/console/store/middleware/logics/packet-broker.js
+++ b/pkg/webui/console/store/middleware/logics/packet-broker.js
@@ -263,7 +263,12 @@ const setPacketBrokerHomeNetworkPolicyLogic = createRequestLogic({
const ids = extractPacketBrokerIdsFromCombinedId(id)
await tts.PacketBrokerAgent.setHomeNetworkRoutingPolicy(ids.net_id, ids.tenant_id, policy)
- return policy
+ const newPolicy = { home_network_id: { net_id: ids.net_id }, ...policy }
+ if ('tenant_id' in ids) {
+ newPolicy.home_network_id.tenant_id = ids.tenant_id
+ }
+
+ return newPolicy
},
})
@@ -289,6 +294,34 @@ const deletePacketBrokerHomeNetworkPolicyLogic = createRequestLogic({
},
})
+const deleteAllPacketBrokerHomeNetworkPoliciesLogic = createRequestLogic({
+ type: packetBroker.DELETE_ALL_HOME_NETWORK_ROUTING_POLICIES,
+ process: async ({ action }) => {
+ const {
+ payload: { ids },
+ } = action
+
+ try {
+ await Promise.all(
+ ids.map(async id => {
+ const ids = extractPacketBrokerIdsFromCombinedId(id)
+ if (typeof ids === 'number') {
+ return tts.PacketBrokerAgent.deleteHomeNetworkRoutingPolicy(ids)
+ }
+
+ return tts.PacketBrokerAgent.deleteHomeNetworkRoutingPolicy(ids.net_id, ids.tenant_id)
+ }),
+ )
+
+ return ids
+ } catch (error) {
+ if (!isNotFoundError(error)) {
+ throw error
+ }
+ }
+ },
+})
+
const getDefaultGatewayVisibilityLogic = createRequestLogic({
type: packetBroker.GET_HOME_NETWORK_DEFAULT_GATEWAY_VISIBILITY,
process: async () => {
@@ -346,6 +379,7 @@ export default [
getPacketBrokerHomeNetworkPoliciesLogic,
setPacketBrokerHomeNetworkPolicyLogic,
deletePacketBrokerHomeNetworkPolicyLogic,
+ deleteAllPacketBrokerHomeNetworkPoliciesLogic,
getDefaultGatewayVisibilityLogic,
setDefaultGatewayVisibilityLogic,
deleteDefaultGatewayVisibilityLogic,
diff --git a/pkg/webui/console/views/admin-packet-broker/admin-packet-broker.js b/pkg/webui/console/views/admin-packet-broker/admin-packet-broker.js
index c5d01fc26b..04d50bcd99 100644
--- a/pkg/webui/console/views/admin-packet-broker/admin-packet-broker.js
+++ b/pkg/webui/console/views/admin-packet-broker/admin-packet-broker.js
@@ -15,48 +15,37 @@
import React, { useCallback, useState } from 'react'
import { Container, Col, Row } from 'react-grid-system'
import { useSelector, useDispatch } from 'react-redux'
-import { Routes, Route } from 'react-router-dom'
+import { Routes, Route, Navigate } from 'react-router-dom'
import classnames from 'classnames'
import PacketBrokerLogo from '@assets/misc/packet-broker.svg'
import Link from '@ttn-lw/components/link'
import PageTitle from '@ttn-lw/components/page-title'
-import Icon from '@ttn-lw/components/icon'
import Switch from '@ttn-lw/components/switch'
import Tabs from '@ttn-lw/components/tabs'
import PortalledModal from '@ttn-lw/components/modal/portalled'
-import Notification from '@ttn-lw/components/notification'
import ErrorNotification from '@ttn-lw/components/error-notification'
+import Notification from '@ttn-lw/components/notification'
import Message from '@ttn-lw/lib/components/message'
-import RequireRequest from '@ttn-lw/lib/components/require-request'
import GenericNotFound from '@ttn-lw/lib/components/full-view-error/not-found'
-import SubViewErrorComponent from '@console/views/sub-view-error'
-
import sharedMessages from '@ttn-lw/lib/shared-messages'
import { isNotEnabledError } from '@console/lib/packet-broker/utils'
-import {
- registerPacketBroker,
- deregisterPacketBroker,
- getHomeNetworkDefaultRoutingPolicy,
- getHomeNetworkDefaultGatewayVisibility,
-} from '@console/store/actions/packet-broker'
+import { registerPacketBroker, deregisterPacketBroker } from '@console/store/actions/packet-broker'
import {
selectRegistered,
selectRegisterEnabled,
selectEnabled,
selectListed,
- selectInfo,
selectInfoError,
} from '@console/store/selectors/packet-broker'
-import DefaultRoutingPolicyView from './default-routing-policy'
-import NetworkRoutingPoliciesView from './network-routing-policies'
+import RoutingConfigurationView from './routing-configuration'
import DefaultGatewayVisibilityView from './default-gateway-visibility'
import m from './messages'
@@ -70,7 +59,6 @@ const PacketBroker = () => {
const enabled = useSelector(selectEnabled)
const [unlistModalVisible, setUnlistModalVisible] = useState(false)
const listed = useSelector(selectListed)
- const info = useSelector(selectInfo)
const infoError = useSelector(selectInfoError)
const dispatch = useDispatch()
const showError = Boolean(infoError) && !isNotEnabledError(infoError)
@@ -81,7 +69,7 @@ const PacketBroker = () => {
} else {
setDeregisterModalVisible(true)
}
- }, [dispatch, registered, setDeregisterModalVisible])
+ }, [dispatch, registered])
const handleDeregisterModalComplete = useCallback(
approved => {
@@ -112,22 +100,19 @@ const PacketBroker = () => {
)
const tabs = [
- { title: m.defaultRoutingPolicy, link: '/admin-panel/packet-broker', name: 'default' },
+ {
+ title: m.routingConfig,
+ link: '/admin-panel/packet-broker/routing-configuration',
+ name: 'default',
+ exact: false,
+ },
{
title: m.defaultGatewayVisibility,
link: '/admin-panel/packet-broker/default-gateway-visibility',
name: 'default-gateway-visibility',
},
- {
- title: sharedMessages.networks,
- link: '/admin-panel/packet-broker/networks',
- name: 'networks',
- exact: false,
- },
]
- const boldMessage = { b: msg => {msg} }
-
return (
@@ -138,29 +123,24 @@ const PacketBroker = () => {
-
+
- Packet Broker documentation
+ Packet Broker
{' | '}
- {' | '}
-
-
-
-
+
+
+
+
{!enabled && }
{showError && }
{enabled && (
-
+
{registerEnabled && (
{
[style.disabled]: !enabled || !registerEnabled,
})}
>
-
+
{
/>
)}
- {registered && (
-
- {info.forwarder_enabled ? (
-
-
-
-
- ) : (
-
-
-
-
- )}
- {info.home_network_enabled ? (
-
-
-
-
- ) : (
-
-
-
-
- )}
-
- )}
{
{registered && (
<>
-
@@ -281,28 +218,15 @@ const PacketBroker = () => {
component="span"
/>
-
-
+
-
-
-
-
-
-
-
-
+
+
+
+ } />
+
+
>
)}
diff --git a/pkg/webui/console/views/admin-packet-broker/default-gateway-visibility.js b/pkg/webui/console/views/admin-packet-broker/default-gateway-visibility.js
index ce1703ca42..1591346e9b 100644
--- a/pkg/webui/console/views/admin-packet-broker/default-gateway-visibility.js
+++ b/pkg/webui/console/views/admin-packet-broker/default-gateway-visibility.js
@@ -19,12 +19,16 @@ import { useSelector, useDispatch } from 'react-redux'
import toast from '@ttn-lw/components/toast'
import Message from '@ttn-lw/lib/components/message'
+import RequireRequest from '@ttn-lw/lib/components/require-request'
import GatewayVisibilityForm from '@console/components/gateway-visibility-form'
import attachPromise from '@ttn-lw/lib/store/actions/attach-promise'
-import { setHomeNetworkDefaultGatewayVisibility } from '@console/store/actions/packet-broker'
+import {
+ getHomeNetworkDefaultGatewayVisibility,
+ setHomeNetworkDefaultGatewayVisibility,
+} from '@console/store/actions/packet-broker'
import { selectHomeNetworkDefaultGatewayVisibility } from '@console/store/selectors/packet-broker'
@@ -55,18 +59,20 @@ const DefaultGatewayVisibilityView = () => {
)
return (
-
-
-
-
+
+
+
+
+
+
)
}
diff --git a/pkg/webui/console/views/admin-packet-broker/default-routing-policy.js b/pkg/webui/console/views/admin-packet-broker/default-routing-policy.js
index 7bfbb9bb44..63e4c4dc72 100644
--- a/pkg/webui/console/views/admin-packet-broker/default-routing-policy.js
+++ b/pkg/webui/console/views/admin-packet-broker/default-routing-policy.js
@@ -12,72 +12,26 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import React, { useCallback, useState } from 'react'
+import React from 'react'
import { Col } from 'react-grid-system'
-import { useSelector, useDispatch } from 'react-redux'
-
-import toast from '@ttn-lw/components/toast'
import Message from '@ttn-lw/lib/components/message'
-import RoutingPolicyForm from '@console/components/routing-policy-form'
-
-import attachPromise from '@ttn-lw/lib/store/actions/attach-promise'
-
-import { isValidPolicy } from '@console/lib/packet-broker/utils'
-
-import {
- setHomeNetworkDefaultRoutingPolicy,
- deleteHomeNetworkDefaultRoutingPolicy,
-} from '@console/store/actions/packet-broker'
-
-import { selectHomeNetworkDefaultRoutingPolicy } from '@console/store/selectors/packet-broker'
+import DefaultRoutingPolicyForm from '@console/components/default-routing-policy-form'
import m from './messages'
import style from './admin-packet-broker.styl'
-const DefaultRoutingPolicyView = () => {
- const dispatch = useDispatch()
- const defaultRoutingPolicy = useSelector(selectHomeNetworkDefaultRoutingPolicy)
- const initialValues = { _use_default_policy: isValidPolicy(defaultRoutingPolicy) }
- initialValues.policy = initialValues._use_default_policy
- ? defaultRoutingPolicy
- : { uplink: {}, downlink: {} }
- const [formError, setFormError] = useState(undefined)
- const handleDefaultRoutingPolicySubmit = useCallback(
- async ({ _use_default_policy, policy }) => {
- try {
- if (_use_default_policy) {
- await dispatch(attachPromise(setHomeNetworkDefaultRoutingPolicy(policy)))
- } else {
- await dispatch(attachPromise(deleteHomeNetworkDefaultRoutingPolicy()))
- }
- toast({
- message: m.defaultRoutingPolicySet,
- type: toast.types.SUCCESS,
- })
- } catch (error) {
- setFormError(error)
- }
- },
- [dispatch, setFormError],
- )
-
- return (
-
-
-
-
- )
-}
+const DefaultRoutingPolicyView = () => (
+
+
+
+
+)
export default DefaultRoutingPolicyView
diff --git a/pkg/webui/console/views/admin-packet-broker/index.js b/pkg/webui/console/views/admin-packet-broker/index.js
index e5054a38b8..825c6a7ac5 100644
--- a/pkg/webui/console/views/admin-packet-broker/index.js
+++ b/pkg/webui/console/views/admin-packet-broker/index.js
@@ -36,7 +36,10 @@ import NetworkRoutingPolicy from './network-routing-policy'
const PacketBrokerRouter = () => {
useBreadcrumbs(
'admin-panel.packet-broker',
- ,
+ ,
)
return (
@@ -44,7 +47,7 @@ const PacketBrokerRouter = () => {
enabled',
- homeNetworkDisabled: 'Home network disabled ',
- forwarderEnabled: 'Forwarder enabled ',
- forwarderDisabled: 'Forwarder disabled ',
- listNetwork: 'List network publicly',
+ listNetwork: 'List my network in Packet Broker publicly',
listNetworkDesc:
- 'Listing your network allows other network administrators to see your network. This allows them to easily configure routing policies with your network.',
+ 'Public listing will make it easier for other network operators to set up routing policies for your network. Hence public listing is generally recommended.',
unlistNetwork: 'Unlist this network',
confirmUnlist: 'Confirm unlist',
unlistModal:
@@ -42,11 +41,9 @@ export default defineMessages({
'This will hide your network. Other network administrators will not be able to see your network to configure routing policies.',
routingPolicyInformation:
'You can use the checkboxes below to control the default forwarding behavior of your network. You can additionally set up individual per-network routing policies via the Networks tab.',
- defaultRoutingPolicySet: 'Default routing policy set',
+ defaultRoutingPolicySet: 'Default routing configuration set',
routingPolicySet: 'Routing policy set',
defaultRoutingPolicy: 'Default routing policy',
- networks: 'Networks',
- networkInformation: 'Network information',
devAddressBlock: 'Device address block',
devAddressBlocks: 'Device address blocks',
lastPolicyChange: 'Last policy change',
diff --git a/pkg/webui/console/views/admin-packet-broker/network-routing-policies.js b/pkg/webui/console/views/admin-packet-broker/network-routing-policies.js
index 2ae67cfebf..d3799fc100 100644
--- a/pkg/webui/console/views/admin-packet-broker/network-routing-policies.js
+++ b/pkg/webui/console/views/admin-packet-broker/network-routing-policies.js
@@ -19,12 +19,15 @@ import Breadcrumb from '@ttn-lw/components/breadcrumbs/breadcrumb'
import PacketBrokerNetworksTable from '@console/containers/packet-broker-networks-table'
-import m from './messages'
+import sharedMessages from '@ttn-lw/lib/shared-messages'
const NetworkRoutingPoliciesView = () => {
useBreadcrumbs(
- 'admin-panel.packet-broker.networks',
- ,
+ 'admin-panel.packet-broker.routing-configuration.networks',
+ ,
)
return
diff --git a/pkg/webui/console/views/admin-packet-broker/network-routing-policy.js b/pkg/webui/console/views/admin-packet-broker/network-routing-policy.js
index c7384648f8..6f74b047ac 100644
--- a/pkg/webui/console/views/admin-packet-broker/network-routing-policy.js
+++ b/pkg/webui/console/views/admin-packet-broker/network-routing-policy.js
@@ -73,11 +73,16 @@ const NetworkRoutingPolicyViewInner = () => {
const defaultRoutingPolicy = useSelector(selectHomeNetworkDefaultRoutingPolicy)
useBreadcrumbs(
- 'admin-panel.packet-broker.networks.single',
+ 'admin-panel.packet-broker.routing-configuration.networks.single',
<>
-
+
>,
@@ -120,7 +125,7 @@ const NetworkRoutingPolicyViewInner = () => {
const homeNetworkData = [
{
- header: m.networkInformation,
+ header: sharedMessages.networkInformation,
items: [
{
key: m.networkId,
@@ -160,7 +165,11 @@ const NetworkRoutingPolicyViewInner = () => {
-
+
←
@@ -228,7 +237,10 @@ const NetworkRoutingPolicyView = () => {
const registered = useSelector(selectRegistered)
return (
-
+
+ isEqual(policy.uplink, fullyPermissiveNetworkPolicy.uplink) &&
+ isEqual(policy.downlink, fullyPermissiveNetworkPolicy.downlink)
+
+const onlyTtn = policies =>
+ Object.keys(policies).length === 1 && Object.keys(policies).includes(`${TTN_NET_ID}/ttn`)
+
+const RoutingConfigurationView = () => {
+ const dispatch = useDispatch()
+ const [activeTab, setActiveTab] = useState('default-routing-policy')
+ const tabs = [
+ {
+ title: m.defaultRoutingPolicy,
+ link: '/admin-panel/packet-broker/routing-configuration',
+ name: 'default',
+ },
+ {
+ title: sharedMessages.networks,
+ link: '/admin-panel/packet-broker/routing-configuration/networks',
+ name: 'networks',
+ exact: false,
+ },
+ ]
+
+ const defaultRoutingPolicy = useSelector(selectHomeNetworkDefaultRoutingPolicy)
+ const routingPolicies = useSelector(selectPacketBrokerHomeNetworkPoliciesStore)
+
+ const initialValues = {
+ _routing_configuration:
+ peerWithEveryNetwork(defaultRoutingPolicy) &&
+ Object.keys(routingPolicies).length === 0 &&
+ isValidPolicy(defaultRoutingPolicy)
+ ? 'all_networks'
+ : onlyTtn(routingPolicies) && !isValidPolicy(defaultRoutingPolicy)
+ ? 'ttn'
+ : 'custom',
+ _use_default_policy: isValidPolicy(defaultRoutingPolicy),
+ }
+ initialValues.policy = isValidPolicy(defaultRoutingPolicy)
+ ? defaultRoutingPolicy
+ : { uplink: {}, downlink: {} }
+
+ const [routingConfig, setRoutingConfig] = useState(undefined)
+ const [formError, setFormError] = useState(undefined)
+
+ const handleDefaultRoutingPolicySubmit = useCallback(
+ async values => {
+ const vals = validationSchema.cast(values)
+ const { _routing_configuration, _use_default_policy, policy } = vals
+ const ids = Object.keys(routingPolicies)
+
+ try {
+ if (_routing_configuration === 'ttn') {
+ await dispatch(attachPromise(deleteHomeNetworkDefaultRoutingPolicy()))
+ await dispatch(attachPromise(deleteAllHomeNetworkRoutingPolicies(ids)))
+ await dispatch(attachPromise(setHomeNetworkRoutingPolicy(`${TTN_NET_ID}/ttn`, policy)))
+ } else if (_routing_configuration === 'all_networks') {
+ await dispatch(attachPromise(deleteAllHomeNetworkRoutingPolicies(ids)))
+ await dispatch(attachPromise(setHomeNetworkDefaultRoutingPolicy(policy)))
+ } else if (_routing_configuration === 'custom' && _use_default_policy) {
+ await dispatch(attachPromise(setHomeNetworkDefaultRoutingPolicy(policy)))
+ } else if (_routing_configuration === 'custom' && !_use_default_policy) {
+ await dispatch(attachPromise(deleteHomeNetworkDefaultRoutingPolicy()))
+ }
+
+ toast({
+ message: m.defaultRoutingPolicySet,
+ type: toast.types.SUCCESS,
+ })
+ } catch (error) {
+ setFormError(error)
+ }
+ },
+ [dispatch, setFormError, routingPolicies],
+ )
+
+ const handleRoutingConfigChange = useCallback(
+ value => {
+ setRoutingConfig(value)
+ },
+ [setRoutingConfig],
+ )
+
+ const handleSetPolicies = useCallback(({ setValues }, { value }) => {
+ if (value !== 'custom') {
+ return setValues(values => ({
+ ...values,
+ _routing_configuration: value,
+ policy: fullyPermissiveNetworkPolicy,
+ }))
+ }
+
+ return setValues(values => ({
+ ...values,
+ _routing_configuration: value,
+ }))
+ }, [])
+
+ const showPolicyCheckboxes = routingConfig
+ ? routingConfig === 'custom'
+ : initialValues._routing_configuration === 'custom'
+
+ return (
+
+
+
+
+
+
+
+ {showPolicyCheckboxes && (
+ <>
+
+
+
+
+
+
+ >
+ )}
+
+
+
+
+
+ )
+}
+
+export default RoutingConfigurationView
diff --git a/pkg/webui/console/views/admin-panel-network-information/index.js b/pkg/webui/console/views/admin-panel-network-information/index.js
index 64ad3e9617..9f01c14f0a 100644
--- a/pkg/webui/console/views/admin-panel-network-information/index.js
+++ b/pkg/webui/console/views/admin-panel-network-information/index.js
@@ -13,7 +13,6 @@
// limitations under the License.
import React from 'react'
-import { defineMessages } from 'react-intl'
import Breadcrumb from '@ttn-lw/components/breadcrumbs/breadcrumb'
import { useBreadcrumbs } from '@ttn-lw/components/breadcrumbs/context'
@@ -24,19 +23,20 @@ import RequireRequest from '@ttn-lw/lib/components/require-request'
import NetworkInformationContainer from '@console/containers/network-information-container'
import DeploymentComponentStatus from '@console/containers/deployment-component-status'
+import sharedMessages from '@ttn-lw/lib/shared-messages'
+
import { getApplicationsList } from '@console/store/actions/applications'
import { getGatewaysList } from '@console/store/actions/gateways'
import { getUsersList } from '@console/store/actions/users'
import { getOrganizationsList } from '@console/store/actions/organizations'
-const m = defineMessages({
- title: 'Network information',
-})
-
const NetworkInformation = () => {
useBreadcrumbs(
'admin-panel.network-information',
- ,
+ ,
)
const requestActions = [
@@ -49,7 +49,7 @@ const NetworkInformation = () => {
return (
<>
-
+
diff --git a/pkg/webui/console/views/admin-panel/index.js b/pkg/webui/console/views/admin-panel/index.js
index 3f87065112..fd2d130793 100644
--- a/pkg/webui/console/views/admin-panel/index.js
+++ b/pkg/webui/console/views/admin-panel/index.js
@@ -30,6 +30,8 @@ import UserManagement from '@console/views/admin-user-management'
import PacketBrokerRouter from '@console/views/admin-packet-broker'
import NetworkInformation from '@console/views/admin-panel-network-information'
+import sharedMessages from '@ttn-lw/lib/shared-messages'
+
import {
checkFromState,
mayConfigurePacketBroker,
@@ -38,25 +40,26 @@ import {
} from '@console/lib/feature-checks'
const m = defineMessages({
- adminPanel: 'Admin panel',
- networkInformation: 'Network information',
userManagement: 'User management',
globalNetworkSettings: 'Global network settings',
peeringSettings: 'Peering settings',
})
const AdminPanel = () => {
- useBreadcrumbs('admin-panel', )
+ useBreadcrumbs(
+ 'admin-panel',
+ ,
+ )
const showUserManagement = useSelector(state => checkFromState(mayManageUsers, state))
const showPacketBroker = useSelector(state => checkFromState(mayConfigurePacketBroker, state))
return (
-
+
} />
+const getScrollRestorationKey = location => {
+ // Preserve scroll position only when necessary.
+ // E.g. we don't want to scroll to top when changing tabs of a table,
+ // but we do want to scroll to top when changing pages.
+ const { pathname, search } = location
+ const params = new URLSearchParams(search)
+ const page = params.get('page')
+
+ return `${pathname}${page ? `?page=${page}` : ''}`
+}
const Layout = () => {
const user = useSelector(selectUser)
@@ -70,7 +86,7 @@ const Layout = () => {
return (
<>
-
+
{
const { appId } = useParams()
@@ -42,7 +37,7 @@ const ApplicationData = () => {
useBreadcrumbs(
'apps.single.data',
- ,
+ ,
)
return (
@@ -50,7 +45,7 @@ const ApplicationData = () => {
featureCheck={mayViewApplicationEvents}
otherwise={{ redirect: `/applications/${appId}` }}
>
-
+
)
diff --git a/pkg/webui/console/views/application-integrations-lora-cloud/index.js b/pkg/webui/console/views/application-integrations-lora-cloud/index.js
index 96500d7a8c..07a4ce3994 100644
--- a/pkg/webui/console/views/application-integrations-lora-cloud/index.js
+++ b/pkg/webui/console/views/application-integrations-lora-cloud/index.js
@@ -1,4 +1,4 @@
-// Copyright © 2020 The Things Network Foundation, The Things Industries B.V.
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -23,7 +23,7 @@ import LoRaCloudImage from '@assets/misc/lora-cloud.png'
import PageTitle from '@ttn-lw/components/page-title'
import Breadcrumb from '@ttn-lw/components/breadcrumbs/breadcrumb'
-import { useBreadcrumbs, withBreadcrumb } from '@ttn-lw/components/breadcrumbs/context'
+import { useBreadcrumbs } from '@ttn-lw/components/breadcrumbs/context'
import Link from '@ttn-lw/components/link'
import Collapse from '@ttn-lw/components/collapse'
@@ -52,7 +52,6 @@ const m = defineMessages({
loraCloudInfoText:
'Lora Cloud provides value added APIs that enable simple solutions for common tasks related to LoRaWAN networks and LoRa-based devices. You can setup our LoRaCloud integrations below.',
officialLoRaCloudDocumentation: 'Official LoRa Cloud documentation',
- setToken: 'Set LoRa Cloud token',
dasDescription:
'With the LoRa Cloud Modem and Geolocation Services protocol, you can manage common device functionality at the application layer for LoRaWAN-enabled devices.',
glsDescription:
@@ -108,11 +107,11 @@ const LoRaCloud = () => {
-
+
-
+
@@ -124,13 +123,4 @@ const LoRaCloud = () => {
)
}
-export default withBreadcrumb('apps.single.integrations.lora-cloud', props => {
- const { appId } = props
-
- return (
-
- )
-})(LoRaCloud)
+export default LoRaCloud
diff --git a/pkg/webui/console/views/application-integrations-webhook-edit/index.js b/pkg/webui/console/views/application-integrations-webhook-edit/index.js
index 5de814e94a..99ce00d393 100644
--- a/pkg/webui/console/views/application-integrations-webhook-edit/index.js
+++ b/pkg/webui/console/views/application-integrations-webhook-edit/index.js
@@ -14,7 +14,6 @@
import React from 'react'
import { Container, Col, Row } from 'react-grid-system'
-import { defineMessages } from 'react-intl'
import { useSelector } from 'react-redux'
import { useParams } from 'react-router-dom'
@@ -39,13 +38,6 @@ import {
selectWebhookHasUnhealthyConfig,
} from '@console/store/selectors/application-server'
-const m = defineMessages({
- editWebhook: 'Edit webhook',
- updateSuccess: 'Webhook updated',
- deleteSuccess: 'Webhook deleted',
- reactivateSuccess: 'Webhook activated',
-})
-
const ApplicationWebhookEditInner = () => {
const { appId, webhookId } = useParams()
const healthStatusEnabled = useSelector(selectWebhooksHealthStatusEnabled)
@@ -64,7 +56,11 @@ const ApplicationWebhookEditInner = () => {
return (
-
+
{
useBreadcrumbs('apps', )
return (
-
-
-
- }
- />
-
-
+
+
+
+
+ }
+ />
+
+
+
)
}
-export default withFeatureRequirement(mayViewApplications, { redirect: '/' })(Applications)
+export default Applications
diff --git a/pkg/webui/console/views/device-general-settings/join-server-form/index.js b/pkg/webui/console/views/device-general-settings/join-server-form/index.js
index 48bdc9eae6..2c5f8a06c8 100644
--- a/pkg/webui/console/views/device-general-settings/join-server-form/index.js
+++ b/pkg/webui/console/views/device-general-settings/join-server-form/index.js
@@ -13,6 +13,7 @@
// limitations under the License.
import React from 'react'
+import { useDispatch } from 'react-redux'
import SubmitButton from '@ttn-lw/components/submit-button'
import SubmitBar from '@ttn-lw/components/submit-bar'
@@ -29,6 +30,7 @@ import tooltipIds from '@ttn-lw/lib/constants/tooltip-ids'
import diff from '@ttn-lw/lib/diff'
import PropTypes from '@ttn-lw/lib/prop-types'
import sharedMessages from '@ttn-lw/lib/shared-messages'
+import attachPromise from '@ttn-lw/lib/store/actions/attach-promise'
import { parseLorawanMacVersion, generate16BytesKey } from '@console/lib/device-utils'
@@ -79,9 +81,12 @@ const JoinServerForm = React.memo(props => {
[device, validationContext],
)
+ const dispatch = useDispatch()
+ const appId = device.ids.application_ids.application_id
+ const devId = device.ids.device_id
const handleUsedDevNoncesReset = React.useCallback(async () => {
try {
- await onUsedDevNoncesReset()
+ await dispatch(attachPromise(onUsedDevNoncesReset(appId, devId)))
toast({
message: messages.resetSuccess,
type: toast.types.SUCCESS,
@@ -92,7 +97,7 @@ const JoinServerForm = React.memo(props => {
type: toast.types.ERROR,
})
}
- }, [onUsedDevNoncesReset])
+ }, [onUsedDevNoncesReset, appId, devId, dispatch])
// Setup and memoize callbacks for changes to `resets_join_nonces` for displaying the field warning.
const handleResetsJoinNoncesChange = React.useCallback(
diff --git a/pkg/webui/console/views/device-general-settings/messages.js b/pkg/webui/console/views/device-general-settings/messages.js
index cff0c8f524..2059e366e0 100644
--- a/pkg/webui/console/views/device-general-settings/messages.js
+++ b/pkg/webui/console/views/device-general-settings/messages.js
@@ -38,10 +38,6 @@ const messages = defineMessages({
'You do not have sufficient rights to view end device keys. Only overwriting is allowed.',
unclaimFailure: 'An error occurred and the end device could not be unclaimed and deleted',
validateSessionKey: '{field} must have non-zero value',
- macSettingsError:
- 'There was an error and the default MAC settings for the {freqPlan}
frequency plan could not be loaded',
- fpNotFoundError:
- 'The LoRaWAN version {lorawanVersion}
does not support the {freqPlan}
frequency plan. Please choose a different MAC version or frequency plan.',
resetUsedDevNonces: 'Reset used DevNonces',
resetUsedDevNoncesModal:
'Are you sure you want to reset the used DevNonces of this end device?{break}{break}Resetting the used DevNonces enables replay attacks using past nonces. Do not use this option unless you have reset the end device NVRAM.',
diff --git a/pkg/webui/console/views/device-general-settings/network-server-form/index.js b/pkg/webui/console/views/device-general-settings/network-server-form/index.js
index 688cb93ffc..9ef64b2298 100644
--- a/pkg/webui/console/views/device-general-settings/network-server-form/index.js
+++ b/pkg/webui/console/views/device-general-settings/network-server-form/index.js
@@ -14,6 +14,7 @@
import React from 'react'
import { defineMessages } from 'react-intl'
+import { useDispatch } from 'react-redux'
import Link from '@ttn-lw/components/link'
import ModalButton from '@ttn-lw/components/button/modal-button'
@@ -40,6 +41,7 @@ import { isBackend, getBackendErrorName } from '@ttn-lw/lib/errors/utils'
import diff from '@ttn-lw/lib/diff'
import sharedMessages from '@ttn-lw/lib/shared-messages'
import PropTypes from '@ttn-lw/lib/prop-types'
+import attachPromise from '@ttn-lw/lib/store/actions/attach-promise'
import {
parseLorawanMacVersion,
@@ -173,7 +175,7 @@ const NetworkServerForm = React.memo(props => {
if (isBackend(err) && getBackendErrorName(err) === 'no_band_version') {
toast({
type: toast.types.ERROR,
- message: messages.fpNotFoundError,
+ message: sharedMessages.fpNotFoundError,
messageValues: {
lorawanVersion,
freqPlan,
@@ -229,9 +231,13 @@ const NetworkServerForm = React.memo(props => {
),
[device, initialActivationMode, isClassB, isClassC, macSettings, validationContext],
)
+
+ const dispatch = useDispatch()
+ const appId = device.ids.application_ids.application_id
+ const devId = device.ids.device_id
const handleMacReset = React.useCallback(async () => {
try {
- await onMacReset()
+ await dispatch(attachPromise(onMacReset(appId, devId)))
toast({
message: m.resetSuccess,
type: toast.types.SUCCESS,
@@ -242,7 +248,7 @@ const NetworkServerForm = React.memo(props => {
type: toast.types.ERROR,
})
}
- }, [onMacReset])
+ }, [onMacReset, dispatch, devId, appId])
const handleSubmit = React.useCallback(
async (values, { resetForm, setSubmitting }) => {
diff --git a/pkg/webui/console/views/device-overview/index.js b/pkg/webui/console/views/device-overview/index.js
index 47a50e5483..5cbc43ecf4 100644
--- a/pkg/webui/console/views/device-overview/index.js
+++ b/pkg/webui/console/views/device-overview/index.js
@@ -57,11 +57,10 @@ const m = defineMessages({
sessionInfo: 'Session information',
pendingSessionInfo: 'Session information (pending)',
latestData: 'Latest data',
- rootKeys: 'Root keys',
keysNotExposed: 'Keys are not exposed',
failedAccessOtherHostDevice:
'The end device you attempted to visit is registered on a different cluster and needs to be accessed using its host Console.',
- macData: 'Download MAC data',
+ downloadMacData: 'Download MAC data',
sensitiveDataWarning:
'The MAC data can contain sensitive information such as session keys that can be used to decrypt messages. Do not share this information publicly .',
noSessionWarning:
@@ -194,7 +193,7 @@ const DeviceInfo = ({ frequencyPlans, device, onExport }) => {
}
} else if (supports_join) {
activationInfoData.items.push({
- key: m.rootKeys,
+ key: sharedMessages.rootKeys,
value: ,
})
}
@@ -266,7 +265,7 @@ const DeviceInfo = ({ frequencyPlans, device, onExport }) => {
},
}}
onApprove={onExport}
- message={m.macData}
+ message={m.downloadMacData}
type="button"
icon="file_download"
/>
@@ -308,14 +307,14 @@ const DeviceOverview = () => {
if (!('mac_state' in result)) {
toast({
- title: m.macData,
+ title: m.downloadMacData,
message: m.macStateError,
type: toast.types.ERROR,
})
}
} catch {
toast({
- title: m.macData,
+ title: m.downloadMacData,
message: m.macStateError,
type: toast.types.ERROR,
})
diff --git a/pkg/webui/console/views/gateway-general-settings/index.js b/pkg/webui/console/views/gateway-general-settings/index.js
index d078194c56..47e5426945 100644
--- a/pkg/webui/console/views/gateway-general-settings/index.js
+++ b/pkg/webui/console/views/gateway-general-settings/index.js
@@ -77,14 +77,21 @@ const GatewayGeneralSettingsInner = () => {
const handleSubmit = useCallback(
async values => {
const formValues = { ...values }
- const { attributes } = formValues
+ const { attributes, frequency_plan_ids } = formValues
if (isEqual(gateway.attributes || {}, attributes)) {
delete formValues.attributes
}
- const changed = diff(gateway, formValues)
- const update = 'attributes' in changed ? { ...changed, attributes } : changed
+ if (isEqual(gateway.frequency_plan_ids || {}, frequency_plan_ids)) {
+ delete formValues.frequency_plan_ids
+ }
+
+ const changed = diff(gateway, formValues, {
+ patchArraysItems: false,
+ patchInFull: ['attributes', 'frequency_plan_ids'],
+ })
+
try {
- await dispatch(updateGateway(gtwId, update))
+ await dispatch(updateGateway(gtwId, changed))
toast({
title: gtwId,
message: m.updateSuccess,
@@ -145,7 +152,7 @@ const GatewayGeneralSettingsInner = () => {
/>
{
}
}
-const isEmptyFrequencyPlan = value => value === frequencyPlans.EMPTY_FREQ_PLAN
+const isEmptyFrequencyPlan = value => value?.includes(frequencyPlans.EMPTY_FREQ_PLAN)
const isNotValidDuration = value => {
const { duration, unit } = decodeDelayValue(value)
@@ -78,18 +78,10 @@ const LorawanSettingsForm = React.memo(props => {
setShouldDisplayWarning(isNotValidDuration(value))
}, [])
- const [showFrequencyPlanWarning, setShowFrequencyPlanWarning] = React.useState(
- isEmptyFrequencyPlan(gateway.frequency_plan_id) || !gateway.frequency_plan_id,
- )
-
- const onFrequencyPlanChange = React.useCallback(freqPlan => {
- setShowFrequencyPlanWarning(isEmptyFrequencyPlan(freqPlan.value))
- }, [])
-
const initialValues = React.useMemo(
() => ({
...validationSchema.cast(gateway),
- frequency_plan_id: gateway.frequency_plan_id || frequencyPlans.EMPTY_FREQ_PLAN,
+ frequency_plan_ids: gateway.frequency_plan_ids || [frequencyPlans.EMPTY_FREQ_PLAN],
}),
[gateway],
)
@@ -97,8 +89,8 @@ const LorawanSettingsForm = React.memo(props => {
const onFormSubmit = React.useCallback(
async (values, { resetForm, setSubmitting }) => {
const castedValues = validationSchema.cast(
- isEmptyFrequencyPlan(values.frequency_plan_id)
- ? { ...values, frequency_plan_id: '' }
+ isEmptyFrequencyPlan(values.frequency_plan_ids)
+ ? { ...values, frequency_plan_ids: [''] }
: values,
)
@@ -122,13 +114,7 @@ const LorawanSettingsForm = React.memo(props => {
error={error}
enableReinitialize
>
-
+
(
-
-
-
-
-
-
-
-
-)
-
-export default withBreadcrumb('gateway.single.data', props => {
- const { gtwId } = props
- return
-})(
- withFeatureRequirement(mayViewOrEditGatewayLocation, {
- redirect: ({ gtwId }) => `/gateways/${gtwId}`,
- })(GatewayLocation),
-)
+const GatewayLocation = () => {
+ const { gtwId } = useParams()
+
+ useBreadcrumbs(
+ 'gateway.single.data',
+ ,
+ )
+
+ return (
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+export default GatewayLocation
diff --git a/pkg/webui/console/views/gateway-overview/index.js b/pkg/webui/console/views/gateway-overview/index.js
index 045280b82f..a56b3abed3 100644
--- a/pkg/webui/console/views/gateway-overview/index.js
+++ b/pkg/webui/console/views/gateway-overview/index.js
@@ -22,7 +22,6 @@ import tts from '@console/api/tts'
import Button from '@ttn-lw/components/button'
import DataSheet from '@ttn-lw/components/data-sheet'
-import Tag from '@ttn-lw/components/tag'
import toast from '@ttn-lw/components/toast'
import Message from '@ttn-lw/lib/components/message'
@@ -62,7 +61,7 @@ const GatewayOverview = () => {
const { gtwId } = useParams()
const mayViewGatewayConf = useSelector(state => checkFromState(mayViewGatewayConfJson, state))
const gateway = useSelector(selectSelectedGateway)
- const { ids, description, created_at, updated_at, frequency_plan_id, gateway_server_address } =
+ const { ids, description, created_at, updated_at, frequency_plan_ids, gateway_server_address } =
gateway
const handleGlobalConfDownload = useCallback(async () => {
@@ -122,7 +121,10 @@ const GatewayOverview = () => {
items: [
{
key: sharedMessages.frequencyPlan,
- value: frequency_plan_id ? : undefined,
+ value:
+ frequency_plan_ids.length !== 0 ? (
+
+ ) : undefined,
},
],
}
@@ -130,16 +132,17 @@ const GatewayOverview = () => {
if (mayViewGatewayConf) {
lorawanInfo.items.push({
key: m.globalConf,
- value: Boolean(frequency_plan_id) ? (
-
- ) : (
-
- ),
+ value:
+ frequency_plan_ids.length !== 0 ? (
+
+ ) : (
+
+ ),
})
}
diff --git a/pkg/webui/console/views/overview/index.js b/pkg/webui/console/views/overview/index.js
index 912a1670fa..91e4a59ab7 100644
--- a/pkg/webui/console/views/overview/index.js
+++ b/pkg/webui/console/views/overview/index.js
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import React, { useMemo, useCallback } from 'react'
+import React, { useMemo, useCallback, useRef } from 'react'
import { Container, Col, Row } from 'react-grid-system'
import { defineMessages } from 'react-intl'
import { useSelector } from 'react-redux'
@@ -76,27 +76,27 @@ const Overview = () => {
const mayCreateGtws = useSelector(state => checkFromState(mayCreateGateways, state))
const supportLink = selectSupportLinkConfig()
const documentationBaseUrl = selectDocumentationUrlConfig()
- const appAnimationRef = React.createRef()
- const gatewayAnimationRef = React.createRef()
+ const appAnimationRef = useRef(null)
+ const gatewayAnimationRef = useRef(null)
useBreadcrumbs('overview', )
const handleAppChooserMouseEnter = useCallback(() => {
- appAnimationRef.current.instance.setDirection(1)
- appAnimationRef.current.instance.goToAndPlay(0)
+ appAnimationRef.current.setDirection(1)
+ appAnimationRef.current.goToAndPlay(0)
}, [appAnimationRef])
const handleAppChooserMouseLeave = useCallback(() => {
- appAnimationRef.current.instance.setDirection(-1)
+ appAnimationRef.current.setDirection(-1)
}, [appAnimationRef])
const handleGatewayChooserMouseEnter = useCallback(() => {
- gatewayAnimationRef.current.instance.setDirection(1)
- gatewayAnimationRef.current.instance.goToAndPlay(0)
+ gatewayAnimationRef.current.setDirection(1)
+ gatewayAnimationRef.current.goToAndPlay(0)
}, [gatewayAnimationRef])
const handleGatewayChooserMouseLeave = useCallback(() => {
- gatewayAnimationRef.current.instance.setDirection(-1)
+ gatewayAnimationRef.current.setDirection(-1)
}, [gatewayAnimationRef])
const chooser = useMemo(() => {
@@ -114,7 +114,7 @@ const Overview = () => {
onMouseLeave={handleAppChooserMouseLeave}
className={style.chooser}
>
-
+
{
onMouseLeave={handleGatewayChooserMouseLeave}
className={style.chooser}
>
-
+
{
name="collaborator"
title={sharedMessages.collaborator}
placeholder={m.collaboratorIdPlaceholder}
+ noOptionsMessage={sharedMessages.noMatchingCollaborators}
required
autoFocus={!update}
disabled={update}
diff --git a/pkg/webui/containers/collaborator-select/index.js b/pkg/webui/containers/collaborator-select/index.js
index 478dead137..ca67cce691 100644
--- a/pkg/webui/containers/collaborator-select/index.js
+++ b/pkg/webui/containers/collaborator-select/index.js
@@ -32,6 +32,7 @@ import { selectSearchResultAccountIds } from '@ttn-lw/lib/store/selectors/search
import PropTypes from '@ttn-lw/lib/prop-types'
import { getCollaboratorsList } from '@ttn-lw/lib/store/actions/collaborators'
import { selectCollaborators } from '@ttn-lw/lib/store/selectors/collaborators'
+import sharedMessages from '@ttn-lw/lib/shared-messages'
import { composeOption } from './util'
@@ -43,7 +44,11 @@ const customMenu = props => {
return (
{showSuggestions && (
-
+
)}
{props.children}
@@ -67,8 +72,6 @@ SingleValue.propTypes = {
}
const m = defineMessages({
- noOptionsMessage: 'No matching user or organization was found',
- suggestions: 'Suggestions',
setYourself: 'Set yourself as {name}',
})
@@ -90,7 +93,10 @@ const Suggest = ({
const [showSuggestions, setShowSuggestions] = useState(collaboratorsList !== 0)
const searchResultsRef = useRef()
searchResultsRef.current = searchResults
- const handleNoOptions = useCallback(() => formatMessage(m.noOptionsMessage), [formatMessage])
+ const noOptionsMessage = useCallback(
+ () => formatMessage(sharedMessages.noMatchingUserFound),
+ [formatMessage],
+ )
const collaboratorOf = {
path: `${entity}_ids.${entity}_id`,
id: entityId,
@@ -149,7 +155,7 @@ const Suggest = ({
name={name}
defaultOptions={initialOptions}
component={Select.Suggested}
- noOptionsMessage={handleNoOptions}
+ noOptionsMessage={noOptionsMessage}
loadOptions={handleLoadingOptions}
showOptionIcon
openMenuOnFocus
diff --git a/pkg/webui/csp.go b/pkg/webui/csp.go
index 30de49f4db..867e3cc1ed 100644
--- a/pkg/webui/csp.go
+++ b/pkg/webui/csp.go
@@ -66,6 +66,12 @@ func (csp ContentSecurityPolicy) Clean() ContentSecurityPolicy {
entry = parsed.Host
}
}
+ if strings.HasPrefix(entry, "ws://") || strings.HasPrefix(entry, "wss://") {
+ if parsed, err := url.Parse(entry); err == nil {
+ parsed.Path, parsed.RawPath = "", ""
+ entry = parsed.String()
+ }
+ }
if _, ok := added[entry]; ok {
continue // Skip already added locations.
}
@@ -112,3 +118,32 @@ func (csp ContentSecurityPolicy) String() string {
result = appendPolicy(result, "frame-ancestors", csp.FrameAncestors)
return strings.Join(result, " ")
}
+
+// RewriteScheme rewrites the scheme of the provided URL if it matches a rewrite rule.
+func RewriteScheme(rewrites map[string]string, baseURL string) []string {
+ u, err := url.Parse(baseURL)
+ if err != nil {
+ return []string{baseURL}
+ }
+ rewrite, ok := rewrites[u.Scheme]
+ if !ok {
+ return []string{baseURL}
+ }
+ u.Scheme = rewrite
+ return append(make([]string, 0, 2), baseURL, u.String())
+}
+
+// RewriteSchemes rewrites the scheme of the provided URLs if they match a rewrite rule.
+func RewriteSchemes(rewrites map[string]string, baseURLs ...string) []string {
+ urls := make([]string, 0, 2*len(baseURLs))
+ for _, baseURL := range baseURLs {
+ urls = append(urls, RewriteScheme(rewrites, baseURL)...)
+ }
+ return urls
+}
+
+// WebsocketSchemeRewrites contains the rewrite rules for websocket schemes.
+var WebsocketSchemeRewrites = map[string]string{
+ "http": "ws",
+ "https": "wss",
+}
diff --git a/pkg/webui/csp_test.go b/pkg/webui/csp_test.go
new file mode 100644
index 0000000000..b3bedb6efe
--- /dev/null
+++ b/pkg/webui/csp_test.go
@@ -0,0 +1,95 @@
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package webui_test
+
+import (
+ "testing"
+
+ "github.com/smarty/assertions"
+ "go.thethings.network/lorawan-stack/v3/pkg/util/test/assertions/should"
+ "go.thethings.network/lorawan-stack/v3/pkg/webui"
+)
+
+func TestRewriteScheme(t *testing.T) {
+ t.Parallel()
+ for _, tc := range []struct {
+ name string
+ baseURL string
+ rewrites map[string]string
+ expected []string
+ }{
+ {
+ name: "no match",
+ baseURL: "https://example.com",
+ rewrites: map[string]string{
+ "http": "ws",
+ },
+ expected: []string{"https://example.com"},
+ },
+ {
+ name: "match",
+ baseURL: "https://example.com",
+ rewrites: map[string]string{
+ "https": "wss",
+ },
+ expected: []string{"https://example.com", "wss://example.com"},
+ },
+ } {
+ tc := tc
+ t.Run(tc.name, func(t *testing.T) {
+ t.Parallel()
+ a := assertions.New(t)
+ actual := webui.RewriteScheme(tc.rewrites, tc.baseURL)
+ a.So(actual, should.Resemble, tc.expected)
+ })
+ }
+}
+
+func TestRewriteSchemes(t *testing.T) {
+ t.Parallel()
+ for _, tc := range []struct {
+ name string
+ baseURLs []string
+ rewrites map[string]string
+ expected []string
+ }{
+ {
+ name: "no match",
+ baseURLs: []string{"https://foo.example.com", "https://bar.example.com"},
+ rewrites: map[string]string{
+ "http": "ws",
+ },
+ expected: []string{"https://foo.example.com", "https://bar.example.com"},
+ },
+ {
+ name: "match",
+ baseURLs: []string{"https://foo.example.com", "https://bar.example.com"},
+ rewrites: map[string]string{
+ "https": "wss",
+ },
+ expected: []string{
+ "https://foo.example.com", "wss://foo.example.com", "https://bar.example.com", "wss://bar.example.com",
+ },
+ },
+ } {
+ tc := tc
+ t.Run(tc.name, func(t *testing.T) {
+ t.Parallel()
+ a := assertions.New(t)
+ actual := webui.RewriteSchemes(tc.rewrites, tc.baseURLs...)
+ a.So(actual, should.Resemble, tc.expected)
+ })
+ }
+}
diff --git a/pkg/webui/lib/components/animation/index.js b/pkg/webui/lib/components/animation/index.js
index a5d2e26984..0f4687854c 100644
--- a/pkg/webui/lib/components/animation/index.js
+++ b/pkg/webui/lib/components/animation/index.js
@@ -1,4 +1,4 @@
-// Copyright © 2019 The Things Network Foundation, The Things Industries B.V.
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,51 +12,42 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import React, { Component } from 'react'
+import React, { useEffect, useRef } from 'react'
import lottie from 'lottie-web'
import PropTypes from '@ttn-lw/lib/prop-types'
-export default class Animation extends Component {
- static propTypes = {
- animationData: PropTypes.shape({}).isRequired,
- lottieConfig: PropTypes.shape({}),
- }
+const Animation = props => {
+ const containerRef = useRef(null)
- static defaultProps = {
- lottieConfig: {},
- }
+ const { animationData, lottieConfig, animationRef, ...rest } = props
- constructor(props) {
- super(props)
-
- this.containerRef = React.createRef()
- this.instance = null
- }
-
- componentDidMount() {
- const { lottieConfig } = this.props
-
- this.instance = lottie.loadAnimation({
- container: this.containerRef.current,
+ useEffect(() => {
+ animationRef.current = lottie.loadAnimation({
+ container: containerRef.current,
renderer: 'svg',
loop: false,
autoplay: false,
- animationData: this.props.animationData,
+ animationData,
...lottieConfig,
})
- }
-
- render() {
- const { lottieConfig, animationData, ...rest } = this.props
-
- return (
-
- )
- }
+
+ return () => {
+ animationRef.current = null
+ }
+ }, [animationData, animationRef, lottieConfig])
+
+ return
}
+
+Animation.propTypes = {
+ animationData: PropTypes.shape({}).isRequired,
+ animationRef: PropTypes.shape({ current: PropTypes.any }).isRequired,
+ lottieConfig: PropTypes.shape({}),
+}
+
+Animation.defaultProps = {
+ lottieConfig: {},
+}
+
+export default Animation
diff --git a/pkg/webui/lib/components/date-time/index.js b/pkg/webui/lib/components/date-time/index.js
index 50b5e77064..0e08549448 100644
--- a/pkg/webui/lib/components/date-time/index.js
+++ b/pkg/webui/lib/components/date-time/index.js
@@ -1,4 +1,4 @@
-// Copyright © 2019 The Things Network Foundation, The Things Industries B.V.
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,77 +12,64 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import React from 'react'
+import React, { useCallback } from 'react'
import { FormattedDate, FormattedTime } from 'react-intl'
-import bind from 'autobind-decorator'
import Message from '@ttn-lw/lib/components/message'
-import { ingestError } from '@ttn-lw/lib/errors/utils'
import PropTypes from '@ttn-lw/lib/prop-types'
import sharedMessages from '@ttn-lw/lib/shared-messages'
import { warn } from '@ttn-lw/lib/log'
import RelativeTime from './relative'
-class DateTime extends React.PureComponent {
- state = { hasError: false }
-
- static getDerivedStateFromError() {
- return { hasError: true }
- }
-
- @bind
- renderUnknown() {
- const { className, firstToLower } = this.props
- return (
-
-
-
- )
- }
-
- componentDidCatch(error, info) {
- const { value } = this.props
- warn(`Error rendering date time with value: "${value}"`, error, info)
- ingestError(error, { ingestedBy: 'DateTimeComponent', value, info })
- }
-
- renderDateTime(formattedDate, formattedTime, dateValue) {
- const { className, children, date, time, noTitle } = this.props
-
- let result = ''
- if (date) {
- result += formattedDate
- }
-
- if (time) {
+const DateTime = props => {
+ const {
+ value,
+ date,
+ time,
+ className,
+ children,
+ dateFormatOptions,
+ timeFormatOptions,
+ firstToLower,
+ noTitle,
+ } = props
+
+ const renderUnknown = (
+
+
+
+ )
+
+ const renderDateTime = useCallback(
+ (formattedDate, formattedTime, dateValue) => {
+ let result = ''
if (date) {
- result += ' '
+ result += formattedDate
}
- result += formattedTime
- }
-
- return (
-
- {children ? children(result) : result}
-
- )
- }
-
- render() {
- const { value, dateFormatOptions, timeFormatOptions } = this.props
- const { hasError } = this.state
-
- if (hasError) {
- return this.renderUnknown()
- }
+ if (time) {
+ if (date) {
+ result += ' '
+ }
+ result += formattedTime
+ }
+ return (
+
+ {children ? children(result) : result}
+
+ )
+ },
+ [children, className, date, noTitle, time],
+ )
+
+ try {
let dateValue = value
if (!(value instanceof Date)) {
dateValue = new Date(value)
@@ -92,11 +79,14 @@ class DateTime extends React.PureComponent {
{date => (
- {time => this.renderDateTime(date, time, dateValue)}
+ {time => renderDateTime(date, time, dateValue)}
)}
)
+ } catch (error) {
+ warn(`Error rendering date time with value: "${value}"`, error)
+ return renderUnknown
}
}
@@ -105,23 +95,14 @@ DateTime.Relative = RelativeTime
DateTime.propTypes = {
children: PropTypes.func,
className: PropTypes.string,
- /** The time to be displayed. */
date: PropTypes.bool,
- /** Whether to show the time. */
dateFormatOptions: PropTypes.shape({}),
- /** Whether to convert the first character of the resulting message to lowercase. */
firstToLower: PropTypes.bool,
- /** Whether to show the title or not. */
noTitle: PropTypes.bool,
- // See https://formatjs.io/docs/react-intl/components/#formatteddate
time: PropTypes.bool,
- // See https://formatjs.io/docs/react-intl/components/#formattedtime
timeFormatOptions: PropTypes.shape({}),
- value: PropTypes.oneOfType([
- PropTypes.string,
- PropTypes.number, // Support timestamps.
- PropTypes.instanceOf(Date),
- ]).isRequired,
+ value: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.instanceOf(Date)])
+ .isRequired,
}
DateTime.defaultProps = {
diff --git a/pkg/webui/lib/components/env.js b/pkg/webui/lib/components/env.js
deleted file mode 100644
index 0263d03953..0000000000
--- a/pkg/webui/lib/components/env.js
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright © 2019 The Things Network Foundation, The Things Industries B.V.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import React from 'react'
-import displayName from 'react-display-name'
-
-import PropTypes from '@ttn-lw/lib/prop-types'
-import { warn } from '@ttn-lw/lib/log'
-
-export const withEnv = Component => {
- const Base =
- Component.prototype instanceof React.Component ? React.Component : React.PureComponent
-
- class WithEnv extends Base {
- static displayName = `WithEnv(${displayName(Component)})`
-
- static contextTypes = {
- env: PropTypes.env,
- }
-
- render() {
- const { env } = this.context
-
- if (!env) {
- warn('No env in context, make sure to use env.Provider')
- }
-
- return
- }
- }
-
- return WithEnv
-}
-
-export class EnvProvider extends React.PureComponent {
- static propTypes = {
- children: PropTypes.node.isRequired,
- env: PropTypes.env.isRequired,
- }
-
- static childContextTypes = {
- env: PropTypes.env.isRequired,
- }
-
- getChildContext() {
- return {
- env: this.props.env,
- }
- }
-
- render() {
- return this.props.children
- }
-}
-
-export default withEnv
diff --git a/pkg/webui/lib/components/full-view-error/error.js b/pkg/webui/lib/components/full-view-error/error.js
index a6d1f6c190..96e0dca16b 100644
--- a/pkg/webui/lib/components/full-view-error/error.js
+++ b/pkg/webui/lib/components/full-view-error/error.js
@@ -99,7 +99,7 @@ const FullViewErrorInner = ({ error, safe, action, unexpected }) => {
errorTitle = statusCodeMessages['404']
errorMessage = errorMessages.genericNotFound
} else if (isOAuthCallback) {
- errorTitle = errorMessages.loginFailed
+ errorTitle = sharedMessages.loginFailed
errorMessage = errorMessages.loginFailedDescription
if (isOAuthClientRefusedError(error) || error.error === 'access_denied') {
errorMessage = errorMessages.loginFailedAbortDescription
diff --git a/pkg/webui/lib/errors/custom-errors.js b/pkg/webui/lib/errors/custom-errors.js
index 85972ce242..659e828d89 100644
--- a/pkg/webui/lib/errors/custom-errors.js
+++ b/pkg/webui/lib/errors/custom-errors.js
@@ -1,4 +1,4 @@
-// Copyright © 2022 The Things Network Foundation, The Things Industries B.V.
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/webui/lib/errors/error-messages.js b/pkg/webui/lib/errors/error-messages.js
index 0b49ee9df4..30c838623c 100644
--- a/pkg/webui/lib/errors/error-messages.js
+++ b/pkg/webui/lib/errors/error-messages.js
@@ -30,7 +30,6 @@ export default defineMessages({
errorOccurred: 'An error occurred and the request could not be completed.',
errorId: 'Error ID: {errorId}
',
correlationId: 'Correlation ID: {correlationId}
',
- loginFailed: 'Login failed',
loginFailedDescription:
'There was an error causing the login to fail. This might be due to server-side misconfiguration or a browser-cookie problem. Please try logging in again.',
loginFailedAbortDescription:
diff --git a/pkg/webui/lib/errors/status-code-messages.js b/pkg/webui/lib/errors/status-code-messages.js
index 10cff24986..78f12cffab 100644
--- a/pkg/webui/lib/errors/status-code-messages.js
+++ b/pkg/webui/lib/errors/status-code-messages.js
@@ -16,20 +16,24 @@
import { defineMessages } from 'react-intl'
+import sharedMessages from '../shared-messages'
+
// eslint-disable-next-line capitalized-comments
// prettier-ignore
-export default defineMessages({
- '4××': 'Client error',
- '400': 'Bad request',
- '401': 'Unauthorized',
- '403': 'Forbidden',
- '404': 'Not found',
- '409': 'Conflict',
- '429': 'Too many requests',
- '499': 'Client closed request',
- '500': 'Internal server error',
- '501': 'Not implemented',
- '503': 'Service unavailable',
- '504': 'Gateway timeout',
- '520': 'Unknown error',
-})
+export default {
+ '520': sharedMessages.unknownError,
+ ...defineMessages({
+ '4××': 'Client error',
+ '400': 'Bad request',
+ '401': 'Unauthorized',
+ '403': 'Forbidden',
+ '404': 'Not found',
+ '409': 'Conflict',
+ '429': 'Too many requests',
+ '499': 'Client closed request',
+ '500': 'Internal server error',
+ '501': 'Not implemented',
+ '503': 'Service unavailable',
+ '504': 'Gateway timeout',
+ })
+}
diff --git a/pkg/webui/lib/field-description-messages.js b/pkg/webui/lib/field-description-messages.js
index 572a7c1904..e4d9390571 100644
--- a/pkg/webui/lib/field-description-messages.js
+++ b/pkg/webui/lib/field-description-messages.js
@@ -17,6 +17,8 @@ import { defineMessages } from 'react-intl'
import GLOSSARY_IDS from '@ttn-lw/lib/constants/glossary-ids'
import TOOLTIP_IDS from '@ttn-lw/lib/constants/tooltip-ids'
+import sharedMessages from './shared-messages'
+
const m = defineMessages({
freqPlanDescription:
'A frequency plan defines data rates that your end device or gateway is setup to use. It is important that gateways and end devices within reach use the same frequency plan to be able to communicate.',
@@ -24,145 +26,100 @@ const m = defineMessages({
'Your end device or gateway manufacturer should provide information about the applicable frequency plan for a particular device. In some cases they are printed on the device itself but they should always be in the hardware manual or data sheet.',
freqPlanAbsence:
'Contact the manufacturer or reseller. Using an incorrect frequency plan will prevent traffic between devices.',
-
devEuiDescription: 'A 64 bit extended unique identifier for your end device.',
devEuiLocation:
'It should be provided to you by the manufacturer, or printed on the end device packaging.',
- devEuiAbsence: 'Contact the manufacturer or your reseller.',
-
joinEuiDescription:
'The JoinEUI (formerly called AppEUI) is a 64 bit extended unique identifier used to identify the Join Server during activation.',
joinEuiLocation:
'It should be provided by the end device manufacturer for pre-provisioned end devices, or by the owner of the Join Server you will use.',
joinEuiAbsence:
'Contact the manufacturer or your reseller. If they can not provide a JoinEUI, and your end device is programmable, it is okay to use all-zeros, but ensure that you use the same JoinEUI in your end device as you enter in The Things Stack.',
-
appKeyDescription:
'An end device specific encryption key used during OTAA to derive the AppSKey (in LoRaWAN 1.1x) or both the NwkSKey and AppSKey in LoRaWAN 1.0x.',
appKeyLocation:
'It is usually pre-provisioned by the end device manufacturer, but can also be created by the user.',
- appKeyAbsence:
- 'Contact the manufacturer or your reseller. If they cannot provide an AppKey, and your end device is programmable, it is okay to generate one.',
-
nwkKeyDescription:
'An end device specific encryption key used to derive the FNwkSIntKey, SNwkSIntKey, NwkSEncKey in LoRaWAN 1.1. When a LoRaWAN 1.1 capable device connects to a LoRaWAN 1.0x Network Server which does not support dual root keys (NwkKey and AppKey), the NwkKey value is used as the AppKey value.',
nwkKeyLocation:
'It is usually pre-provisioned by the end device manufacturer, but some end devices also allow using a user-defined value.',
- nwkKeyAbsence:
- 'Contact the manufacturer or your reseller. If they cannot provide an AppKey, and your end device is programmable, it is okay to generate one.',
-
devIdDescription: 'A unique, human-readable identifier for your end device.',
devIdLocation:
'We prefill this value using the previously entered DevEUI but you can use any other unique value you want. End device IDs can not be reused by multiple end devices within the same application.',
-
joinServerDescription:
"The Join Server's role is to store root keys, generate session keys, and to send those securely to the Network Server and Application Server of choice. The device contains the same root keys, which can be provisioned as part of assembly, distribution or upon installation.",
joinServerLocation:
'Contact your manufacturer or reseller to find out if your end device is pre-provisioned on an external Join Server. If not, you may use the local Join Server, or provision the end device on our Global Join Server so that you can transfer it without lock-in.',
joinServerAbsence:
'If the end device is pre-provisioned, you will need the keys from the manufacturer to activate it.',
-
devAddrDescription:
'A 32 bit non-unique identifier, assigned by the Network Server during end device activation.',
devAddrLocation:
'For Activation-By-Personalization (ABP), you must generate a device address and manually program it into the end device. You can use the generate button next to the input field to generate a device address.',
-
appSKeyDescription:
'After activation, this encryption key is used to secure messages which carry a payload.',
appSKeyLocation:
'For Activation-By-Personalization (ABP), you must generate a key and manually program it into your end device. You can use the generate button next to the input field to generate a key.',
-
nwkSKeyDescription:
'After activation, this encryption key is used to secure messages which do not carry a payload.',
nwkSKeyLocation:
'For OTAA, it is created by the Network Server. If using ABP, you must create one and manually enter it in the end device and The Things Stack.',
-
loraCloudModemEncodingDescription:
'The Application Server will parse streaming fragments using the TLV encoding and resubmit it to the Modem Services as a GNSS or WiFi payload, depending on the tag.',
-
lwVersionDescription:
'The LoRa Alliance LoRaWAN specification your end device conforms to, which defines which Media Access Control (MAC) features it supports.',
lwVersionLocation:
'The LoRaWAN version for your end device should be provided by the manufacturer in a datasheet as LoRaWAN version or LoRaWAN specification',
lwVersionAbsence:
'Contact your manufacturer or reseller, since specifying the wrong version can lead to complex issues when the Network Server provides the end device with unsupported configuration (MAC) commands.',
-
regParameterDescription:
'The Regional Parameters specify frequency, dwell time, and other communication settings for different geographical areas. The Regional Parameters version is the version of the LoRa Alliance specification which your device supports.',
regParameterLocation:
'The Regional Parameters version should be provided by the end device manufacturer in a datasheet.',
regParameterAbsence:
'Contact your manufacturer or reseller to obtain the correct specification. Specifying a wrong version can lead to complex issues when the Network Server provides the end device with unsupported configuration (MAC) commands.',
-
classDescription:
'The LoRaWAN specification defines three end device types. All LoRaWAN end devices must implement Class A, whereas Class B and Class C are extensions to the specification of Class A devices that specify different downlink reception behavior.',
classLocation:
'The class capabilities of your end device should be provided by the manufaturer in a datasheet.',
classAbsence:
'If your end device will not receive downlink messages, you can safely use Class A, which all LoRaWAN certified devices must implement. Otherwise contact your manufacturer or reseller.',
-
rx1DataRateOffsetDescription:
'The Data Rate Offset sets the offset between the uplink data rate and the downlink data rate used to communicate with the End Device during the first reception slot (RX1).',
-
deviceBrandDescription: 'This is the manufacturer of your end device.',
deviceModelDescription: 'The particular model of your end device.',
-
deviceHardwareVersionDescription: 'The hardware version of your device.',
deviceHardwareVersionLocation:
'It should be provided by the manufacturer of your device, or printed on the device packaging.',
- deviceHardwareVersionAbsence:
- 'Contact the manufacturer or reseller of your device. Providing an incorrect hardware version can result in unwanted device behavior.',
-
deviceFirmwareVersionDescription: 'The version of firmware loaded on your device.',
deviceFirmwareVersionLocation:
'The firmware version should be provided by the manufacturer of your device, or printed on the device packaging. It may be possible to upgrade your device firmware to a known version.',
- deviceFirmwareVersionAbsence:
- 'Contact the manufacturer or reseller of your device. Providing an incorrect hardware version can result in unwanted device behavior.',
-
activationModeDescription:
'OTAA is the preferred and most secure way to connect a device. Devices perform a join-procedure with the network. ABP requires hardcoding the device address and security keys. Multicast is a virtual group of ABP devices which allows all devices to receive the same downlinks. Multicast groups do not support uplinks.',
activationModeLocation: 'You decide how to activate your devices. Whenever possible, use OTAA.',
-
deviceNameDescription: 'An optional human readable name to help you identify your device.',
- deviceNameLocation: 'You make it up, so be creative!',
-
deviceDescDescription:
'An optional description, which can also be used to save notes about the end device.',
-
frameCounterWidthDescription:
'Most devices use a 32 bit frame counter to prevent replay attacks. Devices with extremely limited resources are permitted to use 16 bit counters.',
frameCounterWidthLocation: 'It should be provided by the device manufacturer.',
frameCounterWidthAbsence:
'Contact your manufacturer or reseller. Most devices use 32 bit counters. Selecting the wrong value will produce errors once the Up or Down frame counter exceeds 16 bits and rolls over.',
-
rx2DataRateIndexDescription:
'The data rate used for the second reception window used by this end device to receive downlinks.',
- rx2DataRateIndexLocation: 'This should be provided by the device manufacturer.',
- rx2DataRateIndexAbsence: 'Contact your device manufacturer or reseller.',
-
rx2FrequencyDescription:
'The frequency used for the second reception window used by this end device to receive downlinks.',
- rx2FrequencyLocation: 'This should be provided by the device manufacturer.',
- rx2FrequencyAbsence: 'Contact your device manufacturer or reseller.',
-
gatewayIdDescription: 'A unique identifier for your gateway.',
- gatewayIdLocation: 'You make it up, so be creative!',
-
gatewayEuiDescription: 'A 64 bit extended unique identifier for your gateway.',
gatewayEuiLocation:
'It should be provided to you by the manufacturer, or printed on the gateway packaging.',
gatewayEuiAbsence:
'Some gateways do not use EUIs. In that case, you can continue without EUI. If you are unsure, we recommend contacting the manufacturer or reseller.',
-
gatewayNameDescription: 'An optional human readable name to help you identify your gateway.',
- gatewayNameLocation: 'You make it up, so be creative!',
-
gatewayDescDescription:
'An optional description, which can also be used to save notes about the gateway.',
-
requireAuthenticatedConnectionDescription:
'This will only allow a gateway to connect if it uses a TLS enabled Basic Station or MQTT connection. It will not allow connections from UDP packet forwarders.',
-
gatewayStatusDescription:
'Setting your gateway status to public allows status information about the gateway to be shared with other users in the network, and with Packet Broker if enabled by the network operator.',
gatewayGenerateApiKeyCUPS:
@@ -173,118 +130,83 @@ const m = defineMessages({
"If this option is checked, the gateway status can be retrieved by other network participants as well as by peering network participants through Packet Broker (if enabled). This is useful if you would like others to benefit from your gateway's coverage by providing them with useful information to do so.",
gatewayLocationPublicDescription:
"If this option is checked, the gateway location can be retrieved by other network participants as well as by peering network participants through Packet Broker (if enabled). This is useful if you would like others to benefit from your gateway's coverage by providing them with the exact location.",
-
gatewayAttributesDescription:
'Attributes can be used to set arbitrary information about the entity, to be used by scripts, or simply for your own organization.',
-
scheduleDownlinkLateDescription:
'This legacy feature enables buffering of downlink messages on the network server, for gateways with no downlink queue. Scheduling consecutive downlinks on gateways with no queue will cause only the most recent downlink to be stored.',
-
enforceDutyCycleDescription:
'When checked, the Network Server will only schedule messages respecting the duty cycle limitations of the selected frequency plan. Note that you are required by law to respect duty cycle regulations applicable to the physical location of your end device.',
-
scheduleAnytimeDelayDescription:
'Adjust the time that the Network Server schedules class C messages in advance. This is useful for gateways that have a known high latency backhaul, like 3G and satellite.',
-
updateGtwLocationFromStatusDescription:
'Instead of setting the location manually, you can alternatively choose to update the location of this gateway from status messages. This only works for gateways that send their locations within status messages while using an authenticated connection; gateways connected over UDP are not supported. Please refer to the manual of your gateway model to see whether sending location data is supported.',
-
disablePacketBrokerForwardingDescription:
'When checked, uplink messages received from this gateway will not be forwarded to Packet Broker. This option takes effect only after the gateway reconnects.',
rx1DelayDescription:
'The amount of time in seconds after an uplink that the downlink window opens.',
rx1DelayAbsence:
'The default value of 5 seconds will be set by The Things Stack to accommodate for high-latency backhauls and/or Packet Broker.',
-
pingSlotPeriodicityDescription: 'The amount of time between two receive windows (ping slots).',
-
classBTimeoutDescription:
'The amount of time after which the network server will assume a message is lost, if not confirmed. This should be set to a value less than the time between two ping slots (ping slot periodicity).',
-
rx2DataRateDescription:
'The data rate used for the RX2 window. For OTAA devices, this is configured as part of join. For ABP devices, a matching value must be programmed in the device.',
-
networkRxDefaultsDescription:
'The network uses a set of default MAC settings (e.g. Rx delays, data rates and frequencies) for the end device. These are based on the recommendations made for the respective band. In most cases these defaults will be correct for your setup. If you wish to use different settings, you can uncheck this checkbox and use custom values.',
-
skipJoinServerRegistration:
'For testing purposes, you can opt to skip registration of this end device on the Join Server. Do not enable this option if you do not understand the implications, as it will affect join capabilities of the end device.',
-
factoryPresetFreqDescription:
'Factory preset frequencies are hard-coded channel frequencies to provide for the Network Server when the end device uses frequencies that divert from the defaults of the band specification. This is uncommon but can be the case for some special devices.',
factoryPresetFreqLocation:
'If your device uses non-default channel frequencies, this information is likely found in the specification sheet or manual of your end device. Otherwise please contact your manufacturer or reseller.',
factoryPresetFreqAbsence:
'If your device uses non-default channel frequencies and these frequencies are not passed to the Network Server, the messages sent between the network and the end device on such non-default frequencies are likely to drop.',
-
classCTimeoutDescription:
'The class C timeout determines how long the network will wait for a response for downlinks that require confirmation (e.g. confirmed downlink messages or MAC commands). During that period no other downlinks will be sent.',
classCTimeoutLocation:
'This is dependant on your exact use case. It can help to consider the following implications: timeouts that are too long can be prone to blocking communication when replies are not sent immediately. On the other hand, timeouts that are too short might miss the reply when it arrives later.',
classCTimeoutAbsence:
'Leave this field empty to let the network apply a default value that should be applicable for most use cases.',
-
gatewayPlacementDescription:
'Informs whether the gateway antenna is placed inside or outside. This information is used solely for display purposes, e.g. on public gateway maps (if your gateway is set as public) and has no technical or functional effects.',
-
setClaimAuthCodeDescription:
'The claim authentication code is used to transfer ownership of an end device using a process called end device claiming. Checking this checkbox will cause a claim authentication code being generated and set for each imported end device so you can eventually transfer the ownership.',
-
pingSlotDataRateDescription:
'The class B ping slot uses a fixed frequency and data rate. This value configures the data rate to use in class B ping slots.',
-
beaconFrequencyDescription:
'The class B beacon is sent on a fixed frequency. This value changes the frequency to use in class B beacons.',
-
pingSlotFrequencyDescription:
'The class B ping slot uses a fixed frequency and data rate. This value configures the frequency to use in class B ping slots.',
-
resetsFCntDescription:
'Enable this to allow end devices to reset their frame counter (FCnt). This is not LoRaWAN compliant and this is not secure. This is to support ABP end devices that reset their frame counter on a power cycle. Do not use this setting in production.',
-
resetMacDescription:
'Resetting the session context and MAC state will reset the end device to its initial (factory) state. This includes resetting the frame counters and any other persisted MAC setting on the end device. Over The Air Activation (OTAA) end devices will also lose their session context. This means that such devices must rejoin the network to continue operation. Activation-by-personalization (ABP) end devices will only reset the MAC state, while preserving up/downlink queues.',
-
useAdrDescription:
'Controls whether the end device uses adaptive data rate. This will allow the network to adjust the employed data rate based on signal to noise ratio. This adaptively optimizes energy consumption, bandwidth and transmission power.',
-
adrMarginDescription:
'Signal-to-noise ratio (SNR) margin in dB that is taken into account in the Adaptive Data Rate (ADR) algorithm to optimize the data rate of the end device. A higher margin requires the end device to have a better SNR before the Network Server instructs a higher data rate for the end device to use.',
-
adrAckLimitDescription: 'This value changes the limit value defining the ADR back-off algorithm.',
-
adrAckDelayDescription: 'This value changes the delay value defining the ADR back-off algorithm.',
-
maxDutyCycleDescription:
'The maximum aggregated transmit duty cycle of the end device over all sub-bands. The allowed time-on-air is 1/N where N is the given value: 1 is 100%, 1024 is 0.97%, etc. This value is used for traffic shaping. All end devices must respect regional regulations regardless of this value.',
-
statusCountPeriodicityDescription:
'Number of uplink messages after which the end device status is requested. Set to 0 to disable requesting the device status based on the number of uplink messages.',
-
statusTimePeriodicityDescription:
'Interval to request the end device status. Set to 0 to disable requesting the end device status on an interval.',
-
skipPayloadCryptoOverrideDescription:
'Skip payload crypto disables the application layer encryption of LoRaWAN frames. This causes the Application Server to forward the messages without any processing, such as payload formatters, to the integrations. When doing so, the integrations are responsible for decryption and processing of the binary format in order to understand the message. This application-wide setting can be overwritten per end device.',
-
basicAuthDescription:
'To increase access security, you can choose to generate a "basic auth" authorization header to be attached to the webhook requests, if the target server requires doing so. This will authenticate the webhook requests with the defined credentials.',
-
downlinkQueueInvalidated:
'This occurs only when using LoRaWAN 1.0.x because the frame counters for the application downlinks and network downlinks are shared. Network downlinks increment this frame counter, thus rendering the queued downlinks invalid (since you cannot send two messages with the same frame counter). The Application Server will automatically handle this message as long as "Skip Payload Crypto" is not enabled.',
-
filterEventDataDescription:
'By default, the data pushed to your webhook contains a vast variety details and metadata related to the event. To avoid noise and to save bandwidth, you can filter the event data by specific paths, e.g. `up.uplink_message.decoded_payload`. Your webhook will then only receive the event data that passed the filter.',
-
inputMethodDescription:
'To register the device, we need to know the exact LoRaWAN specifications that the device adheres to. To do that, you can select your device in our extensive LoRaWAN Device Repository, which is the best way to ensure proper configuration. If your device is not listed in the repository, you can also provide versions and MAC configurations manually. Please refer to the manual and/or data sheet of your device and contact your manufacturer or reseller if you are unsure about a certain config.',
-
resetsJoinNoncesDescription:
'Allowing join nonces to be reset disables any reuse checks for the device nonces and join nonces. The join requests can be replayed indefinitely when this option is enabled. This behavior is non compliant with the LoRaWAN specifications and must not be used outside of development environments.',
-
resetUsedDevNoncesDescription:
'The device nonces ensure that join requests cannot be replayed by attackers. Resetting the device nonces enables the end device to re-use a previously used nonce. Do not use this option unless you are sure that you would like the nonces to be usable again.',
-
alcsyncDescription:
'The Application Layer Clock Synchronization package is part of the LoRa TS003 specification, it synchronizes the real-time clock of an end-device to the network’s Global Positioning System (GPS) clock with near-second accuracy. It is useful for end-devices that do not have access to another accurate time source.',
})
@@ -299,7 +221,7 @@ const descriptions = Object.freeze({
[TOOLTIP_IDS.DEV_EUI]: {
description: m.devEuiDescription,
location: m.devEuiLocation,
- absence: m.devEuiAbsence,
+ absence: sharedMessages.absenceContactManufacturer,
glossaryId: GLOSSARY_IDS.DEV_EUI,
},
[TOOLTIP_IDS.JOIN_EUI]: {
@@ -311,13 +233,13 @@ const descriptions = Object.freeze({
[TOOLTIP_IDS.APP_KEY]: {
description: m.appKeyDescription,
location: m.appKeyLocation,
- absence: m.appKeyAbsence,
+ absence: sharedMessages.absenceContactManufacturer,
glossaryId: GLOSSARY_IDS.APP_KEY,
},
[TOOLTIP_IDS.NETWORK_KEY]: {
description: m.nwkKeyDescription,
location: m.nwkKeyLocation,
- absence: m.nwkKeyAbsence,
+ absence: sharedMessages.absenceContactManufacturer,
glossaryId: GLOSSARY_IDS.NETWORK_KEY,
},
[TOOLTIP_IDS.DEVICE_ID]: {
@@ -377,12 +299,12 @@ const descriptions = Object.freeze({
[TOOLTIP_IDS.DEVICE_HARDWARE_VERSION]: {
description: m.deviceHardwareVersionDescription,
location: m.deviceHardwareVersionLocation,
- absence: m.deviceHardwareVersionAbsence,
+ absence: sharedMessages.absenceContactManufacturer,
},
[TOOLTIP_IDS.DEVICE_FIRMWARE_VERSION]: {
description: m.deviceFirmwareVersionDescription,
location: m.deviceFirmwareVersionLocation,
- absence: m.deviceFirmwareVersionAbsence,
+ absence: sharedMessages.absenceContactManufacturer,
},
[TOOLTIP_IDS.ACTIVATION_MODE]: {
description: m.activationModeDescription,
@@ -404,15 +326,15 @@ const descriptions = Object.freeze({
[TOOLTIP_IDS.RX2_DATA_RATE_INDEX]: {
description: m.rx2DataRateIndexDescription,
location: m.rx2DataRateIndexLocation,
- absence: m.rx2DataRateIndexAbsence,
+ absence: sharedMessages.absenceContactManufacturer,
},
[TOOLTIP_IDS.RX2_FREQUENCY]: {
description: m.rx2FrequencyDescription,
location: m.rx2FrequencyLocation,
- absence: m.rx2FrequencyAbsence,
+ absence: sharedMessages.absenceContactManufacturer,
},
[TOOLTIP_IDS.GATEWAY_ID]: {
- description: m.gatewayIdDescription,
+ description: sharedMessages.absenceContactManufacturer,
location: m.gatewayIdLocation,
glossaryId: GLOSSARY_IDS.GATEWAY_ID,
},
diff --git a/pkg/webui/lib/payload-formatter-messages.js b/pkg/webui/lib/payload-formatter-messages.js
index 7645f0caa2..641456b070 100644
--- a/pkg/webui/lib/payload-formatter-messages.js
+++ b/pkg/webui/lib/payload-formatter-messages.js
@@ -16,18 +16,18 @@ import { defineMessages } from 'react-intl'
import TYPES from '@console/constants/formatter-types'
+import sharedMessages from './shared-messages'
+
const m = defineMessages({
- grpc: 'GRPC service',
repository: 'Repository',
javascript: 'Javascript',
- none: 'None',
cayennelpp: 'CayenneLPP',
})
export default Object.freeze({
[TYPES.JAVASCRIPT]: m.javascript,
[TYPES.REPOSITORY]: m.repository,
- [TYPES.NONE]: m.none,
+ [TYPES.NONE]: sharedMessages.none,
[TYPES.GRPC]: m.grpc,
[TYPES.CAYENNELPP]: m.cayennelpp,
})
diff --git a/pkg/webui/lib/shared-messages.js b/pkg/webui/lib/shared-messages.js
index d8b0a4767a..b8578d3e27 100644
--- a/pkg/webui/lib/shared-messages.js
+++ b/pkg/webui/lib/shared-messages.js
@@ -1,4 +1,4 @@
-// Copyright © 2021 The Things Network Foundation, The Things Industries B.V.
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -19,6 +19,12 @@ export default defineMessages({
'16Bit': '16 bit',
'32Bit': '32 bit',
abp: 'Activation by personalization (ABP)',
+ absenceBeCreative: 'You make it up, so be creative!',
+ absenceContactManufacturer: 'Contact your device manufacturer or reseller.',
+ absenceProvidedByManufacturer: 'This should be provided by the device manufacturer.',
+ accessTokens: 'Access tokens',
+ accountDeleteConfirmation: 'Are you sure you want to delete this account?',
+ accountDeleted: 'Account deleted',
accuracy: 'Accuracy',
actions: 'Actions',
activationMode: 'Activation mode',
@@ -27,13 +33,17 @@ export default defineMessages({
addAttributes: 'Add attributes',
addCollaborator: 'Add collaborator',
addDeviceBulk: 'End device bulk creation',
+ addHeaderEntry: 'Add header entry',
+ addOAuthClient: 'Add OAuth client',
addPubsub: 'Add Pub/Sub',
+ addWebhook: 'Add webhook',
address: 'Address',
addressPlaceholder: 'host',
- addWebhook: 'Add webhook',
admin: 'Admin',
- adminPanel: 'Admin panel',
adminContact: 'Administrative contact',
+ adminDescription:
+ 'Admin status enables overarching rights such as managing other users or modifying entities regardless of collaboration status',
+ adminPanel: 'Admin panel',
all: 'All',
allAdmin: 'All (Admin)',
altitude: 'Altitude',
@@ -43,17 +53,20 @@ export default defineMessages({
apiKeyCounted: '{count, plural, one {API key} other {API keys}}',
apiKeyNamePlaceholder: 'My new API key',
apiKeys: 'API keys',
+ appData: 'Application data',
appEUI: 'AppEUI',
- appEUIJoinEUI: 'AppEUI/JoinEUI',
appEUIDescription:
'The AppEUI uniquely identifies the owner of the end device. If no AppEUI is provided by the device manufacturer (usually for development), it can be filled with zeros.',
+ appEUIJoinEUI: 'AppEUI/JoinEUI',
appId: 'Application ID',
appKey: 'AppKey',
+ appKeyAbsence:
+ 'Contact the manufacturer or your reseller. If they cannot provide an AppKey, and your end device is programmable, it is okay to generate one.',
+ appSKey: 'AppSKey',
application: 'Application',
- applications: 'Applications',
applicationServerAddress: 'Application Server address',
+ applications: 'Applications',
approve: 'Approve',
- appSKey: 'AppSKey',
asServerID: 'Application Server ID',
asServerIDDescription: 'The AS-ID of the Application Server to use',
asServerKekLabel: 'Application Server KEK label',
@@ -64,16 +77,21 @@ export default defineMessages({
attributeKeyValidateTooLong: 'Attribute keys must have less than 32 characters',
attributeKeyValidateTooShort:
'Attribute keys must have at least 3 characters and contain no special characters',
+ attributeValueValidateTooLong: 'Attribute values must have less than 200 characters',
attributes: 'Attributes',
attributesValidateRequired:
'All attribute entry values are required. Please remove empty entries.',
attributesValidateTooMany: '{field} must be 10 items or fewer',
- attributeValueValidateTooLong: 'Attribute values must have less than 200 characters',
+ authorization: 'Authorization',
+ authorizationCode: 'Authorization code',
authorizations: 'Authorizations',
- automaticUpdates: 'Automatic updates',
autoUpdateDescription: 'Gateway can be updated automatically',
- backToOverview: 'Back to overview',
+ automaticUpdates: 'Automatic updates',
+ backTo: 'Back to {siteTitle}',
backToLogin: 'Back to login',
+ backToOverview: 'Back to overview',
+ beaconFrequency: 'Beacon frequency',
+ bearerMyAuthToken: 'Bearer my-auth-token',
brand: 'Brand',
cancel: 'Cancel',
changeLocation: 'Change location settings',
@@ -81,8 +99,11 @@ export default defineMessages({
channel: 'Channel',
claimAuthCode: 'Claim authentication code',
claiming: 'Claiming',
+ classBTimeout: 'Class B timeout',
+ classCTimeout: 'Class C timeout',
clear: 'Clear',
client: 'Client',
+ clientId: 'Client ID',
collaborator: 'Collaborator',
collaboratorCounted: '{count, plural, one {Collaborator} other {Collaborators}}',
collaboratorDeleteSuccess: 'Collaborator removed',
@@ -90,33 +111,34 @@ export default defineMessages({
collaboratorEditRights: 'Edit rights of {collaboratorId}',
collaboratorId: 'Collaborator ID',
collaboratorIdPlaceholder: 'collaborator-id',
- collaboratorWarningSelf: 'Changing your own rights could result in loss of access',
- collaboratorWarningAdmin:
- 'This user is an administrator that will retain all rights to all entities regardless of collaborator status',
- collaboratorWarningAdminSelf:
- 'As an administrator, you always retain all rights to all entities regardless of collaborator status',
collaboratorModalWarning: 'Are you sure you want to remove {collaboratorId} as a collaborator?',
collaboratorModalWarningSelf:
'Are you sure you want to remove yourself as a collaborator? Access to this entity will be lost until someone else adds you as a collaborator again.',
collaboratorRemove: 'Collaborator remove',
- collaborators: 'Collaborators',
collaboratorUpdateSuccess: 'Collaborator rights updated',
+ collaboratorWarningAdmin:
+ 'This user is an administrator that will retain all rights to all entities regardless of collaborator status',
+ collaboratorWarningAdminSelf:
+ 'As an administrator, you always retain all rights to all entities regardless of collaborator status',
+ collaboratorWarningSelf: 'Changing your own rights could result in loss of access',
+ collaborators: 'Collaborators',
componentAs: 'Application Server',
+ componentDcs: 'Device Claiming Server',
componentEdtc: 'End Device Template Converter',
+ componentGcs: 'Gateway Claiming Server',
componentGs: 'Gateway Server',
componentIs: 'Identity Server',
componentJs: 'Join Server',
componentNs: 'Network Server',
componentQrg: 'QR Code Generator',
- componentDcs: 'Device Claiming Server',
- componentGcs: 'Gateway Claiming Server',
confirm: 'Confirm',
confirmPassword: 'Confirm password',
+ confirmedDownlink: 'Confirmed downlink',
connected: 'Connected',
connecting: 'Connecting',
connectionIssues: 'Connection issues',
- contactInformation: 'Contact information',
contactFieldPlaceholder: 'Type or choose a collaborator',
+ contactInformation: 'Contact information',
convertMacToEui: 'Convert MAC to EUI',
copiedToClipboard: 'Copied to clipboard!',
copyToClipboard: 'Copy to clipboard',
@@ -131,34 +153,36 @@ export default defineMessages({
defineRights: 'Define rights',
delayWarning:
'Delay too short. The lower bound ({minimumValue}ms) will be used by the Gateway Server.',
- deleted: 'Deleted (Admin)',
- deleteModalTitle: 'Are you sure you want to delete {entityName} ?',
+ deleteModalConfirmDeletion: 'Confirm deletion',
+ deleteModalConfirmMessage: 'Please enter {entityId} to confirm the deletion.',
deleteModalDefaultMessage:
'This will PERMANENTLY DELETE THE ENTITY ITSELF AND ALL ASSOCIATED ENTITIES , including collaborator associations. It will also NOT BE POSSIBLE TO REUSE THE ENTITY ID .',
deleteModalPurgeMessage:
'This will PERMANENTLY DELETE THE ENTITY ITSELF AND ALL ASSOCIATED ENTITIES , including collaborator associations.',
- deleteModalConfirmMessage: 'Please enter {entityId} to confirm the deletion.',
- deleteModalConfirmDeletion: 'Confirm deletion',
deleteModalPurgeWarning:
'Releasing the entity IDs will make it possible to register a new entity with the same ID. Note that this irreversible and may lead to other users gaining access to historical data of the entity if they register an entity with the same ID . Please make sure you understand the implications of purging as described here .',
- deleteModalReleaseIdTitle: 'Entity purge (admin only)',
deleteModalReleaseIdLabel: 'Also release entity IDs (purge)',
+ deleteModalReleaseIdTitle: 'Entity purge (admin only)',
+ deleteModalTitle: 'Are you sure you want to delete {entityName} ?',
+ deleted: 'Deleted (Admin)',
description: 'Description',
devAddr: 'Device address',
devDesc: 'End device description',
devEUI: 'DevEUI',
devEUIBlockLimitReached: 'DevEUI generation limit reached',
+ devID: 'End device ID',
+ devName: 'End device name',
+ device: 'End device',
deviceCounted: '{count, plural, one {End device} other {End devices}}',
deviceDescDescription:
'Optional end device description; can also be used to save notes about the end device',
deviceDescPlaceholder: 'Description for my new end device',
+ deviceHardwareVersionAbsence:
+ 'Contact the manufacturer or reseller of your device. Providing an incorrect hardware version can result in unwanted device behavior.',
deviceIdPlaceholder: 'my-new-device',
deviceNamePlaceholder: 'My new end device',
deviceSimulationDisabledWarning: 'Simulation is disabled for devices that skip payload crypto',
- device: 'End device',
devices: 'End devices',
- devID: 'End device ID',
- devName: 'End device name',
disabled: 'Disabled',
disconnected: 'Disconnected',
documentation: 'Documentation',
@@ -168,21 +192,28 @@ export default defineMessages({
downlinkFrameCount: 'Downlink frame count',
downlinkNack: 'Downlink nack',
downlinkPush: 'Downlink push',
- downlinkQueued: 'Downlink queued',
downlinkQueueInvalidated: 'Downlink queue invalidated',
+ downlinkQueued: 'Downlink queued',
downlinkReplace: 'Downlink replace',
downlinkSent: 'Downlink sent',
downlinksScheduled: 'Downlinks (re)scheduled',
edit: 'Edit',
+ editWebhook: 'Edit webhook',
email: 'Email',
emailAddress: 'Email address',
+ emailAddressDescription:
+ 'Primary email address used for logging in; this address is not publicly visible',
+ emailAddressValidation: 'Treat email address as validated',
+ emailAddressValidationDescription:
+ 'Enable this option if you do not need this user to validate the email address',
+ emailPlaceholder: 'mail@example.com',
empty: 'Empty',
enabled: 'Enabled',
+ endDeviceModelsUnavailable: 'End device models unavailable',
+ enforceDutyCycle: 'Enforce duty cycle',
enforceDutyCycleDescription:
'Recommended for all gateways in order to respect spectrum regulations',
- enforceDutyCycle: 'Enforce duty cycle',
entityId: 'Entity ID',
- eventEnabledTypes: 'Enabled event types',
eventDownlinkAckDesc: 'A confirmed downlink is acknowledged by an end device',
eventDownlinkFailedDesc: 'A downlink cannot be sent',
eventDownlinkNackDesc: 'A sent confirmed downlink fails confirmation by the end device',
@@ -191,6 +222,7 @@ export default defineMessages({
eventDownlinkQueuedDesc: 'A downlink is added to the downlink queue',
eventDownlinkReplaceDesc: 'A downlink is used to replace the downlink queue',
eventDownlinkSentDesc: 'A downlink is sent to an end device or multicast group',
+ eventEnabledTypes: 'Enabled event types',
eventJoinAcceptDesc: 'An end device successfully joins the network and starts a session',
eventLocationSolvedDesc: 'An integration succeeded locating the end device',
eventServiceDataDesc: 'An integration emits an event',
@@ -201,10 +233,16 @@ export default defineMessages({
exportJson: 'Export as JSON',
external: 'External',
externalJoinServer: 'External Join Server',
+ fNwkSIntKey: 'FNwkSIntKey',
+ factoryPresetFrequencies: 'Factory preset frequencies',
fetching: 'Fetching data…',
firmwareVersion: 'Firmware version',
- fNwkSIntKey: 'FNwkSIntKey',
+ format: 'Format',
+ fpNotFoundError:
+ 'The LoRaWAN version {lorawanVersion}
does not support the {freqPlan}
frequency plan. Please choose a different MAC version or frequency plan.',
frameCounterWidth: 'Frame counter width',
+ freqAdd: 'Add Frequency',
+ frequencyPlaceholder: 'e.g. 869525000 for 869,525 MHz',
frequencyPlan: 'Frequency plan',
frequencyPlanWarning:
'Without choosing a frequency plan, packets from the gateway will not be correctly processed',
@@ -221,18 +259,20 @@ export default defineMessages({
gatewayLocationPublic: 'Share location within network',
gatewayName: 'Gateway name',
gatewayNamePlaceholder: 'My new gateway',
- gateways: 'Gateways',
gatewayScheduleDownlinkLate: 'Schedule downlink late',
gatewayServerAddress: 'Gateway Server address',
gatewayStatus: 'Gateway status',
gatewayStatusPublic: 'Share status within network',
gatewayUpdateOptions: 'Gateway updates',
- generateAPIKeyCups: 'Generate API key for CUPS',
- generateAPIKeyLNS: 'Generate API key for LNS',
+ gateways: 'Gateways',
general: 'General',
generalInformation: 'General information',
generalSettings: 'General settings',
+ generateAPIKeyCups: 'Generate API key for CUPS',
+ generateAPIKeyLNS: 'Generate API key for LNS',
getSupport: 'Get support',
+ grantAdminStatus: 'Grant this user admin status',
+ grpcService: 'GRPC service',
gsServerAddressDescription: 'The address of the Gateway Server to connect to',
hardware: 'Hardware',
hardwareVersion: 'Hardware version',
@@ -243,12 +283,12 @@ export default defineMessages({
idAlreadyExists: 'ID already exists',
import: 'Import',
importDevices: 'Import end devices',
- integrations: 'Integrations',
- invite: 'Invite',
- joinAccept: 'Join accept',
inputMethod: 'Input method',
insufficientAppKeyRights: 'Insufficient rights to set an AppKey',
insufficientNwkKeyRights: 'Insufficient rights to set a NwkKey',
+ integrations: 'Integrations',
+ invite: 'Invite',
+ joinAccept: 'Join accept',
joinEUI: 'JoinEUI',
joinServerAddress: 'Join Server address',
key: 'key',
@@ -268,20 +308,21 @@ export default defineMessages({
'When set to public, the gateway location may be visible to other users of the network',
locationMarkerDescriptionNonUser:
'This location has been set automatically from incoming (status) messages',
- locationMarkerDescriptionUser:
- 'This location has been set manually (e.g. by using the "Location"-tab)',
locationMarkerDescriptionUntrusted:
'This location was determined via an untrusted status message and may be inaccurate',
+ locationMarkerDescriptionUser:
+ 'This location has been set manually (e.g. by using the "Location"-tab)',
locationSolved: 'Location solved',
+ locationSourceBtRssi: 'Bluetooth RSSI geolocation',
+ locationSourceCombined: 'Combined geolocation',
locationSourceGps: 'GPS-based location',
- locationSourceRegistry: 'Manually set location',
locationSourceIpGeolocation: 'IP-based geolocation',
- locationSourceWifiRssi: 'Wifi RSSI geolocation',
- locationSourceBtRssi: 'Bluetooth RSSI geolocation',
locationSourceLoraRssi: 'LoRa RSSI geolocation',
locationSourceLoraTdoa: 'LoRa TDOA geolocation',
- locationSourceCombined: 'Combined geolocation',
+ locationSourceRegistry: 'Manually set location',
+ locationSourceWifiRssi: 'Wifi RSSI geolocation',
login: 'Login',
+ loginFailed: 'Login failed',
logout: 'Logout',
longitude: 'Longitude',
longitudeDesc: 'The east-west position in degrees, where 0 is the prime meridian (Greenwich)',
@@ -291,10 +332,13 @@ export default defineMessages({
lorawanInformation: 'LoRaWAN information',
lorawanOptions: 'LoRaWAN options',
lorawanPhyVersionDescription: 'The LoRaWAN PHY version of the end device',
+ macData: 'MAC data',
+ macSettingsError:
+ 'There was an error and the default MAC settings for the {freqPlan}
frequency plan could not be loaded',
macVersion: 'LoRaWAN version',
+ messageTypes: 'Message types',
messages: 'messages',
messaging: 'Messaging',
- messageTypes: 'Message types',
milliseconds: 'milliseconds',
minutes: 'minutes',
model: 'Model',
@@ -303,24 +347,25 @@ export default defineMessages({
multicast: 'Define multicast group (ABP & Multicast)',
name: 'Name',
netId: 'Net ID',
- networks: 'Networks',
+ networkInformation: 'Network information',
networkServerAddress: 'Network Server address',
+ networks: 'Networks',
never: 'Never',
next: 'Next',
noActivityYet: 'No activity yet',
- noRecentActivity: 'No recent activity',
noDesc: 'This end device has no description',
noEvents: 'Waiting for events from {entityId} …',
noLocation: 'No location information available',
noMatch: 'No items found',
+ noMatchingUserFound: 'No matching user or organization was found',
+ noRecentActivity: 'No recent activity',
none: 'None',
- normalizedPayloadSoil: 'Soil',
normalizedPayloadAir: 'Air',
+ normalizedPayloadSoil: 'Soil',
normalizedPayloadWind: 'Wind',
notAvailable: 'n/a',
notLinked: 'Not linked',
notSet: 'Not set',
- nsAddress: 'Network Server address',
nsEmptyDefault: 'Leave empty to link to the Network Server in the same cluster',
nsServerKekLabel: 'Network Server KEK label',
nsServerKekLabelDescription:
@@ -329,9 +374,9 @@ export default defineMessages({
nwkSEncKey: 'NwkSEncKey',
nwkSEncKeyDescription: 'Network session encryption key',
nwkSKey: 'NwkSKey',
- oauthClients: 'OAuth clients',
- oauthClientId: 'OAuth client ID',
oauthClientAuthorizations: 'OAuth client authorizations',
+ oauthClientId: 'OAuth client ID',
+ oauthClients: 'OAuth clients',
offline: 'Offline',
ok: 'Ok',
online: 'Online',
@@ -357,6 +402,8 @@ export default defineMessages({
phyVersion: 'Regional Parameters version',
phyVersionDescription:
'The Regional Parameters version (PHY), as provided by the device manufacturer',
+ pingSlotFrequency: 'Ping slot frequency',
+ pingSlotPeriodicity: 'Ping slot periodicity',
port: 'Port',
privacyPolicy: 'Privacy policy',
profileSettings: 'Profile settings',
@@ -371,17 +418,18 @@ export default defineMessages({
refresh: 'Refresh',
registerEndDevice: 'Register end device',
registerGateway: 'Register gateway',
- replaceWebhook: 'Replace webhook',
+ remove: 'Remove',
removeCollaborator: 'Remove collaborator',
- removeCollaboratorSelf: 'Remove yourself as collaborator',
removeCollaboratorLast: 'Cannot remove last collaborator',
+ removeCollaboratorSelf: 'Remove yourself as collaborator',
+ replaceWebhook: 'Replace webhook',
requireAuthenticatedConnection: 'Require authenticated connection',
requireAuthenticatedConnectionDescription:
'Controls whether this gateway may only connect if it uses an authenticated Basic Station or MQTT connection',
reset: 'Reset',
+ resetWarning: 'Reseting is insecure and makes your end device susceptible for replay attacks',
resetsFCnt: 'Resets frame counters',
resetsJoinNonces: 'Resets join nonces',
- resetWarning: 'Reseting is insecure and makes your end device susceptible for replay attacks',
restartStream: 'Restart stream',
restore: 'Restore',
restrictedUser:
@@ -389,41 +437,49 @@ export default defineMessages({
resume: 'Resume',
rights: 'Rights',
rootKeys: 'Root keys',
+ rx1DataRateOffset: 'Rx1 data rate offset',
+ rx1Delay: 'Rx1 delay',
+ rx2Frequency: 'Rx2 frequency',
+ sNwkSIKey: 'SNwkSIntKey',
+ sNwkSIKeyDescription: 'Serving network session integrity key',
saveChanges: 'Save changes',
+ scanEndDevice: 'Scan end device QR code',
scheduleAnyTimeDelay: 'Schedule any time delay',
scheduleAnyTimeDescription:
'Configure gateway delay (minimum: {minimumValue}ms, default: {defaultValue}ms)',
scheduleDownlinkLateDescription: 'Enable server-side buffer of downlink messages',
search: 'Search',
+ secondInterval: '{count, plural, one {every second} other {every {count} seconds}}',
seconds: 'seconds',
secondsAbbreviated: 'sec',
secret: 'Secret',
secure: 'Secure',
sendInvitation: 'Send invitation',
- sessions: 'Sessions',
serverUrl: 'Server URL',
serviceData: 'Service data',
+ sessions: 'Sessions',
+ setLoRaCloudToken: 'Set LoRa Cloud token',
settings: 'Settings',
+ setup: 'Setup',
shareGatewayInfo: 'Share gateway information',
skipCryptoDescription: 'Skip decryption of uplink payloads and encryption of downlink payloads',
skipCryptoPlaceholder: 'Encryption/decryption disabled',
skipCryptoTitle: 'Skip payload encryption and decryption',
- sNwkSIKey: 'SNwkSIntKey',
- sNwkSIKeyDescription: 'Serving network session integrity key',
source: 'Source',
stable: 'Stable',
state: 'State',
- stateDescription: 'State description',
stateApproved: 'Approved',
+ stateDescription: 'State description',
stateFlagged: 'Flagged',
stateRejected: 'Rejected',
stateRequested: 'Requested',
stateSuspended: 'Suspended',
status: 'Status',
statusDescription: 'The status of this gateway may be visible to other users',
- statusUnknown: 'Status unknown',
statusPage: 'Status page',
+ statusUnknown: 'Status unknown',
success: 'Success',
+ suggestions: 'Suggestions',
supportsClassB: 'Supports class B',
supportsClassC: 'Supports class C',
takeMeBack: 'Take me back',
@@ -440,9 +496,10 @@ export default defineMessages({
troubleshooting: 'Troubleshooting',
type: 'Type',
typeToSearch: 'Type to search…',
- unknownHwOption: 'Unknown ver.',
+ unexposed: 'Unexposed',
unknown: 'Unknown',
- unknownError: 'Unknown error while generating DevEUI',
+ unknownError: 'Unknown error',
+ unknownHwOption: 'Unknown ver.',
updateChannelDescription: 'Channel for gateway automatic updates',
updatedAt: 'Last updated at',
uplink: 'Uplink',
@@ -450,26 +507,34 @@ export default defineMessages({
uplinkMessage: 'Uplink message',
uplinkNormalized: 'Normalized uplink',
uplinksReceived: 'Uplinks received',
- unexposed: 'Unexposed',
+ uploadAnImage: 'Upload an image',
used: '{currentValue}/{maxValue} used',
+ useDefaultPolicy: 'Use default routing policy for this network',
user: 'User',
userAdd: 'Add user',
userDelete: 'Delete user',
+ userDescDescription: 'Optional user description; can also be used to save notes about the user',
+ userDescription: 'Description for my new user',
userEdit: 'Edit user',
userId: 'User ID',
+ userIdPlaceholder: 'jane-doe',
userInvitations: 'User invitations',
userManagement: 'User management',
+ userNamePlaceholder: 'Jane Doe',
+ userOrgId: 'User / Organization ID',
username: 'Username',
users: 'Users',
+ validFrom: 'Valid from',
+ validTo: 'Valid to',
validateAddressFormat: '{field} must be in the format "host" or "host:port"',
validateApiKey: 'API keys must follow the format "NNSXS.[…].[…]"',
validateDateInPast: '{field} must be a date in the future',
validateDelayFormat: '{field} must be a positive, whole number',
validateDigit: '{field} must have at least {digit} {digit, plural, one {digit} other {digits}}',
validateEmail: 'An email address must use exactly one "@", one "." and use no special characters',
+ validateFreqDynamic: '{field} must be 0 for dynamic frequencies or greater than 100000Hz',
validateFreqNumeric: 'All frequency values must be positive integers',
validateFreqRequired: 'All frequency values are required. Please remove empty entries.',
- validateFreqDynamic: '{field} must be 0 for dynamic frequencies or greater than 100000Hz',
validateHexLength: '{field} must be a complete hex value',
validateIdFormat: '{field} must contain only lowercase letters, numbers and dashes (-)',
validateInt32: '{field} must be a whole number, negative or positive',
@@ -495,13 +560,14 @@ export default defineMessages({
validateUppercase:
'{field} must have at least {upper} uppercase {upper, plural, one {character} other {characters}}',
validateUrl: 'Must be a valid URL format, contain no spaces or special characters',
- validFrom: 'Valid from',
- validTo: 'Valid to',
value: 'value',
+ webhookActivated: 'Webhook activated',
webhookAlreadyExistsModalMessage:
'A Webhook with the ID "{id}" already exists. Do you wish to replace this webhook?',
webhookBaseUrl: 'Base URL',
+ webhookDeleted: 'Webhook deleted',
webhookFormat: 'Webhook format',
webhookId: 'Webhook ID',
+ webhookUpdated: 'Webhook updated',
webhooks: 'Webhooks',
})
diff --git a/pkg/webui/lib/yup.js b/pkg/webui/lib/yup.js
index 5b442cff4b..2021999b26 100644
--- a/pkg/webui/lib/yup.js
+++ b/pkg/webui/lib/yup.js
@@ -1,4 +1,4 @@
-// Copyright © 2019 The Things Network Foundation, The Things Industries B.V.
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -27,7 +27,6 @@ class NullableStringSchemaType extends StringSchema {
const self = this
- /* eslint-disable prefer-arrow/prefer-arrow-functions */
self.withMutation(() => {
self
.transform(value => {
@@ -37,9 +36,8 @@ class NullableStringSchemaType extends StringSchema {
return null
})
- .nullable(true)
+ .nullable()
})
- /* eslint-enable prefer-arrow/prefer-arrow-functions */
}
}
diff --git a/pkg/webui/locales/en.json b/pkg/webui/locales/en.json
index f3b21b6806..334ecdaf14 100644
--- a/pkg/webui/locales/en.json
+++ b/pkg/webui/locales/en.json
@@ -4,7 +4,6 @@
"account.components.oauth-client-form.messages.clientDescPlaceholder": "Description for my new OAuth client",
"account.components.oauth-client-form.messages.clientDescDescription": "The description is displayed to the user when authorizing the client. Use it to explain the purpose of your client.",
"account.components.oauth-client-form.messages.createClient": "Create OAuth client",
- "account.components.oauth-client-form.messages.deleteTitle": "Are you sure you want to delete this account?",
"account.components.oauth-client-form.messages.deleteWarning": "This will PERMANENTLY DELETE THIS OAUTH CLIENT and LOCK THE OAUTH ID . Make sure you assign new collaborators to such entities if you plan to continue using them.",
"account.components.oauth-client-form.messages.purgeWarning": "This will PERMANENTLY DELETE THIS OAUTH CLIENT . This operation cannot be undone.",
"account.components.oauth-client-form.messages.redirectUrls": "Redirect URLs",
@@ -19,9 +18,7 @@
"account.components.oauth-client-form.messages.endorsedDesc": "If set, the authorization page will visually indicate endorsement to improve trust",
"account.components.oauth-client-form.messages.grants": "Grant types",
"account.components.oauth-client-form.messages.grantsDesc": "OAuth flows that can be used for the client to get a token",
- "account.components.oauth-client-form.messages.grantAuthorizationLabel": "Authorization code",
"account.components.oauth-client-form.messages.grantRefreshTokenLabel": "Refresh token",
- "account.components.oauth-client-form.messages.grantPasswordLabel": "Password",
"account.components.oauth-client-form.messages.deleteClient": "Delete OAuth client",
"account.components.oauth-client-form.messages.urlsPlaceholder": "https://example.com/oauth/callback",
"account.components.oauth-client-form.messages.rightsWarning": "Note that only the minimum set of rights needed to provide the functionality of the application should be requested",
@@ -31,8 +28,6 @@
"account.components.oauth-client-form.messages.stateDescriptionDesc": "You can use this field to save additional information about the state of this OAuth client, e.g. why it has been flagged",
"account.components.oauth-client-form.messages.adminContactDescription": "Administrative contact information for this client. Typically used to indicate who to contact with administrative questions about the client.",
"account.components.oauth-client-form.messages.techContactDescription": "Technical contact information for this client. Typically used to indicate who to contact with technical/security questions about the client.",
- "account.containers.authorizations-table.index.clientId": "Client ID",
- "account.containers.authorizations-table.index.tableTitle": "OAuth client authorizations",
"account.containers.change-password-form.index.currentPassword": "Current password",
"account.containers.change-password-form.index.newPassword": "New password",
"account.containers.change-password-form.index.newPasswordConfirm": "Confirm new password",
@@ -43,12 +38,8 @@
"account.containers.clients-table.index.restoreFail": "There was an error and OAuth client could not be restored",
"account.containers.clients-table.index.purgeSuccess": "OAuth client purged",
"account.containers.clients-table.index.purgeFail": "There was an error and the OAuth client could not be purged",
- "account.containers.clients-table.index.addClient": "Add OAuth client",
- "account.containers.collaborators-table.index.id": "User / Organization ID",
- "account.containers.collaborators-table.index.addCollaborator": "Add collaborator",
"account.containers.collaborators-table.index.deleteCollaboratorError": "There was an error and the collaborator could not be deleted",
"account.containers.collaborators-table.index.deleteOnlyCollaboratorError": "This collaborator could not be deleted because every client needs at least one collaborator with all rights",
- "account.containers.collaborators-table.index.removeButtonMessage": "Remove",
"account.containers.oauth-client-add.index.createSuccess": "Client created",
"account.containers.oauth-client-add.index.createFailure": "There was an error and the client could not be created",
"account.containers.oauth-client-edit.index.deleteSuccess": "OAuth client deleted",
@@ -61,12 +52,10 @@
"account.containers.profile-settings-form.messages.successMessage": "Profile updated",
"account.containers.profile-settings-form.messages.deleteAccount": "Delete account",
"account.containers.profile-settings-form.messages.useGravatar": "Use Gravatar",
- "account.containers.profile-settings-form.messages.uploadAnImage": "Upload an image",
"account.containers.profile-settings-form.messages.gravatarInfo": "If available, we're using the Gravatar image associated with your email address. You can upload a different profile picture by selecting the option above.",
"account.containers.profile-settings-form.messages.gravatarInfoGravatarOnly": "If available, we're using the Gravatar image associated with your email address. Please follow the instructions on the Gravatar website to change your profile picture.",
"account.containers.profile-settings-form.messages.primaryEmailAddressDescription": "Primary email address associated with your account",
"account.containers.profile-settings-form.messages.deleteAccountError": "There was an error and your account could not be deleted",
- "account.containers.profile-settings-form.messages.deleteAccountSuccess": "Account deleted",
"account.containers.profile-settings-form.messages.imageRequired": "Please select a file to use as your profile picture or choose \"Gravatar\" as source",
"account.containers.profile-settings-form.messages.imageUpload": "Image upload",
"account.containers.profile-settings-form.messages.chooseImage": "Choose image…",
@@ -79,12 +68,10 @@
"account.containers.profile-settings-form.messages.deleteConfirmMessage": "Please enter your user ID to confirm the account deletion.",
"account.containers.sessions-table.index.deleteSessionSuccess": "Session removed successfully",
"account.containers.sessions-table.index.deleteSessionError": "There was an error and the session could not be deleted",
- "account.containers.sessions-table.index.sessionsTableTitle": "Sessions",
"account.containers.sessions-table.index.removeButtonMessage": "Remove this session",
"account.containers.sessions-table.index.noExpiryDate": "No expiry date",
"account.containers.sessions-table.index.endSession": "Logout to end this session",
"account.containers.sessions-table.index.currentSession": "(This is the current session)",
- "account.containers.tokens-table.index.tableTitle": "Access tokens",
"account.containers.tokens-table.index.deleteSuccess": "Access token invalidated",
"account.containers.tokens-table.index.deleteFail": "There was an error and the access token could not be invalidated",
"account.containers.tokens-table.index.deleteButton": "Invalidate this access token",
@@ -92,7 +79,6 @@
"account.containers.tokens-table.index.deleteAllFail": "There was an error and the access tokens could not be invalidated",
"account.containers.tokens-table.index.deleteAllButton": "Invalidate all access tokens",
"account.containers.tokens-table.index.expires": "Expires",
- "account.containers.tokens-table.index.accessTokens": "Access tokens",
"account.views.authorize.index.modalTitle": "Request for permission",
"account.views.authorize.index.modalSubtitle": "{clientName} is requesting to be granted the following rights:",
"account.views.authorize.index.loginInfo": "You are logged in as {userId}.",
@@ -100,9 +86,7 @@
"account.views.authorize.index.authorize": "Authorize {clientName}",
"account.views.authorize.index.noDescription": "This client does not provide a description",
"account.views.authorize.index.allRights": "This client is requesting all possible current and future rights . This includes reading, writing and deletion of gateways, end devices and applications, as well as their network traffic.",
- "account.views.code.index.code": "Authorization code",
"account.views.code.index.codeDescription": "Your authorization code is:",
- "account.views.code.index.backToAccount": "Back to {siteTitle}",
"account.views.create-account.index.registrationApproved": "You have successfully registered and can login now",
"account.views.create-account.index.createAccount": "Create account",
"account.views.create-account.index.createANewAccount": "Create a new account",
@@ -112,17 +96,13 @@
"account.views.forgot-password.index.send": "Send",
"account.views.forgot-password.index.resetPassword": "Reset password",
"account.views.forgot-password.index.resetPasswordDescription": "Please enter your User ID to receive an email with reset instructions",
- "account.views.front-not-found.index.backToAccount": "Back to {siteTitle}",
"account.views.login.index.createAccount": "Create an account",
"account.views.login.index.forgotPassword": "Forgot password?",
"account.views.login.index.loginToContinue": "Please login to continue",
- "account.views.login.index.loginFailed": "Login failed",
- "account.views.login.index.accountDeleted": "Account deleted",
"account.views.oauth-authorization-settings.index.deleteButton": "Revoke authorization",
"account.views.oauth-authorization-settings.index.deleteSuccess": "This authorization was successfully revoked",
"account.views.oauth-authorization-settings.index.deleteFailure": "There was an error and this authorization could not be revoked",
"account.views.oauth-authorization-settings.index.deleteMessage": "Are you sure you want to unauthorize this client? The client will not be able to perform any actions on your behalf if the authorization is revoked. You can always choose to authorize the client again if wished.",
- "account.views.oauth-client-add.index.addClient": "Add OAuth client",
"account.views.oauth-client-authorization-overview.index.authorizationSettings": "Authorization settings",
"account.views.oauth-client-authorization-overview.index.accessTokens": "Active access tokens",
"account.views.overview.index.accountAppInfoTitle": "Welcome, {userId}! 👋",
@@ -131,11 +111,9 @@
"account.views.overview.index.goToConsole": "Go to the Console",
"account.views.profile-settings.index.profileEdit": "Edit profile",
"account.views.profile-settings.index.generalSettingsDescription": "Change basic info such as your name, profile picture or email address.",
- "account.views.profile-settings.index.changePasswordTitle": "Change password",
"account.views.profile-settings.index.changePasswordDescription": "Set up a new password for your account.",
"account.views.session-management.index.sessionManagement": "Session management",
"account.views.token-login.index.loginToken": "Login Token",
- "account.views.token-login.index.loginFailed": "Login failed",
"account.views.update-password.index.sessionRevoked": "Your password was changed and all active sessions were revoked",
"account.views.validate.index.backToAccount": "Back to Account",
"account.views.validate.index.contactInfoValidation": "Contact info validation",
@@ -152,7 +130,6 @@
"components.file-input.index.noFileSelected": "No file selected",
"components.file-input.index.fileProvided": "A file has been provided",
"components.file-input.index.tooBig": "The selected file is too large",
- "components.file-input.index.remove": "Remove",
"components.form.field.tooltip.descriptionTitle": "What is this?",
"components.form.field.tooltip.locationTitle": "What should I enter here?",
"components.form.field.tooltip.absenceTitle": "What if I cannot find the correct value?",
@@ -180,7 +157,6 @@
"components.progress-bar.index.estimatedCompletion": "Estimated completion {eta}",
"components.progress-bar.index.progress": "{current, number} of {target, number}",
"components.progress-bar.index.percentage": "{percentage, number, percent} finished",
- "components.qr-modal-button.index.scanEndDevice": "Scan end device QR code",
"components.qr-modal-button.index.scanEndDeviceContinue": "Please scan the QR code to continue. {qrScanDoc}",
"components.qr-modal-button.index.invalidData": "Invalid QR code data. Please note that only TR005 LoRaWAN® Device Identification QR Code can be scanned. Some devices have unrelated QR codes printed on them that cannot be used.",
"components.qr-modal-button.index.apply": "Apply",
@@ -191,7 +167,6 @@
"components.qr.input.video.index.switchCamera": "Switch camera",
"components.qr.require-permission.permissionDeniedError": "Permission Denied: Please allow access to your camera or upload a photo",
"components.qr.require-permission.fetchingPermission": "Please set camera permissions",
- "components.qr.require-permission.uploadImage": "Upload an image",
"components.rights-group.index.selectAll": "Select all",
"components.rights-group.index.outOfOwnScopeRights": "This {entityType} has more rights than you have. These rights can not be modified.",
"components.rights-group.index.outOfOwnScopePseudoRight": "This {entityType} has a wildcard right that you don't have. The {entityType} can therefore only be removed entirely.",
@@ -216,11 +191,11 @@
"console.components.application-general-settings-form.index.useAlcsync": "Use Application Layer Clock Synchronization",
"console.components.application-general-settings-form.index.adminContactDescription": "Administrative contact information for this application. Typically used to indicate who to contact with administrative questions about the application.",
"console.components.application-general-settings-form.index.techContactDescription": "Technical contact information for this application. Typically used to indicate who to contact with technical/security questions about the application.",
+ "console.components.default-routing-policy-form.index.doNotUseADefaultPolicy": "Do not use a default routing policy for this network",
"console.components.device-import-form.index.file": "File",
"console.components.device-import-form.index.formatInfo": "Format information",
"console.components.device-import-form.index.selectAFile": "Please select a template file",
"console.components.device-import-form.index.fileInfoPlaceholder": "Please select a template format",
- "console.components.device-import-form.index.claiming": "Claiming",
"console.components.device-import-form.index.setClaimAuthCode": "Set claim authentication code",
"console.components.device-import-form.index.targetedComponents": "Targeted components",
"console.components.device-import-form.index.advancedSectionTitle": "Advanced end device claiming settings",
@@ -230,18 +205,16 @@
"console.components.device-import-form.index.inputMethodManual": "Enter LoRaWAN versions and frequency plan manually",
"console.components.device-import-form.index.fallbackValues": "Fallback values",
"console.components.device-import-form.index.noFallback": "Do not set any fallback values",
- "console.components.downlink-form.downlink-form.insertMode": "Insert Mode",
- "console.components.downlink-form.downlink-form.payloadType": "Payload type",
- "console.components.downlink-form.downlink-form.bytes": "Bytes",
- "console.components.downlink-form.downlink-form.replace": "Replace downlink queue",
- "console.components.downlink-form.downlink-form.push": "Push to downlink queue (append)",
- "console.components.downlink-form.downlink-form.confirmedDownlink": "Confirmed downlink",
- "console.components.downlink-form.downlink-form.scheduleDownlink": "Schedule downlink",
- "console.components.downlink-form.downlink-form.downlinkSuccess": "Downlink scheduled",
- "console.components.downlink-form.downlink-form.bytesPayloadDescription": "The desired payload bytes of the downlink message",
- "console.components.downlink-form.downlink-form.jsonPayloadDescription": "The decoded payload of the downlink message",
- "console.components.downlink-form.downlink-form.invalidSessionWarning": "Downlinks can only be scheduled for end devices with a valid session. Please make sure your end device is properly connected to the network.",
- "console.components.events.messages.payload": "Payload",
+ "console.components.downlink-form.index.insertMode": "Insert Mode",
+ "console.components.downlink-form.index.payloadType": "Payload type",
+ "console.components.downlink-form.index.bytes": "Bytes",
+ "console.components.downlink-form.index.replace": "Replace downlink queue",
+ "console.components.downlink-form.index.push": "Push to downlink queue (append)",
+ "console.components.downlink-form.index.scheduleDownlink": "Schedule downlink",
+ "console.components.downlink-form.index.downlinkSuccess": "Downlink scheduled",
+ "console.components.downlink-form.index.bytesPayloadDescription": "The desired payload bytes of the downlink message",
+ "console.components.downlink-form.index.jsonPayloadDescription": "The decoded payload of the downlink message",
+ "console.components.downlink-form.index.invalidSessionWarning": "Downlinks can only be scheduled for end devices with a valid session. Please make sure your end device is properly connected to the network.",
"console.components.events.messages.MACPayload": "MAC payload",
"console.components.events.messages.devAddr": "DevAddr",
"console.components.events.messages.fPort": "FPort",
@@ -273,7 +246,6 @@
"console.components.events.messages.eventsTruncated": "Old events have been truncated to save memory. The current event limit per stream is {limit}.",
"console.components.events.messages.eventUnavailable": "This event is not available anymore. It was likely truncated to save memory.",
"console.components.events.messages.verboseStream": "Verbose stream",
- "console.components.events.messages.confirmedDownlink": "Confirmed downlink",
"console.components.events.messages.confirmedUplink": "Confirmed uplink",
"console.components.events.previews.shared.json-payload.index.invalid": "Invalid JSON",
"console.components.gateway-api-keys-modal.index.modalTitle": "Download gateway API keys",
@@ -297,32 +269,19 @@
"console.components.lorawan-version-input.index.phyVersionError": "Failed to fetch regional parameters versions",
"console.components.mac-settings-section.index.delayValue": "{count, plural, one {{count} second} other {{count} seconds}}",
"console.components.mac-settings-section.index.factoryPresetFreqDescription": "List of factory-preset frequencies. Note: order is respected.",
- "console.components.mac-settings-section.index.factoryPresetFreqTitle": "Factory preset frequencies",
- "console.components.mac-settings-section.index.freqAdd": "Add Frequency",
- "console.components.mac-settings-section.index.frequencyPlaceholder": "e.g. 869525000 for 869,525 MHz",
"console.components.mac-settings-section.index.advancedMacSettings": "Advanced MAC settings",
- "console.components.mac-settings-section.index.pingSlotFrequencyTitle": "Ping slot frequency",
"console.components.mac-settings-section.index.desiredPingSlotFrequencyTitle": "Desired ping slot frequency",
"console.components.mac-settings-section.index.pingSlotPeriodicityDescription": "Periodicity of the class B ping slot",
- "console.components.mac-settings-section.index.pingSlotPeriodicityTitle": "Ping slot periodicity",
- "console.components.mac-settings-section.index.pingSlotPeriodicityValue": "{count, plural, one {every second} other {every {count} seconds}}",
"console.components.mac-settings-section.index.pingSlotDataRateTitle": "Ping slot data rate index",
"console.components.mac-settings-section.index.desiredPingSlotDataRateTitle": "Desired ping slot data rate",
"console.components.mac-settings-section.index.resetWarning": "Resetting is insecure and makes your device susceptible for replay attacks",
- "console.components.mac-settings-section.index.resetsFCnt": "Resets frame counters",
- "console.components.mac-settings-section.index.rx1DataRateOffsetTitle": "Rx1 data rate offset",
"console.components.mac-settings-section.index.desiredRx1DataRateOffsetTitle": "Desired Rx1 data rate offset",
- "console.components.mac-settings-section.index.rx1DelayTitle": "Rx1 delay",
"console.components.mac-settings-section.index.desiredRx1DelayTitle": "Desired Rx1 delay",
"console.components.mac-settings-section.index.rx2DataRateIndexTitle": "Rx2 data rate index",
"console.components.mac-settings-section.index.desiredRx2DataRateIndexTitle": "Desired Rx2 data rate index",
"console.components.mac-settings-section.index.desiredRx2FrequencyTitle": "Desired Rx2 frequency",
- "console.components.mac-settings-section.index.rx2FrequencyTitle": "Rx2 frequency",
"console.components.mac-settings-section.index.updateSuccess": "The MAC settings updated",
- "console.components.mac-settings-section.index.beaconFrequency": "Beacon frequency",
"console.components.mac-settings-section.index.desiredBeaconFrequency": "Desired beacon frequency",
- "console.components.mac-settings-section.index.classBTimeout": "Class B timeout",
- "console.components.mac-settings-section.index.classCTimeout": "Class C timeout",
"console.components.mac-settings-section.index.maxDutyCycle": "Maximum duty cycle",
"console.components.mac-settings-section.index.desiredMaxDutyCycle": "Desired maximum duty cycle",
"console.components.mac-settings-section.index.adrMargin": "ADR margin",
@@ -337,7 +296,6 @@
"console.components.mac-settings-section.index.adrAckValue": "{count, plural, one {every message} other {every {count} messages}}",
"console.components.mac-settings-section.index.statusCountPeriodicity": "Status count periodicity",
"console.components.mac-settings-section.index.statusTimePeriodicity": "Status time periodicity",
- "console.components.payload-formatters-form.index.grpc": "GRPC service",
"console.components.payload-formatters-form.index.repository": "Use Device Repository formatters",
"console.components.payload-formatters-form.index.customJavascipt": "Custom Javascript formatter",
"console.components.payload-formatters-form.index.formatterType": "Formatter type",
@@ -347,7 +305,6 @@
"console.components.payload-formatters-form.index.grpcFieldDescription": "The address of the service to connect to",
"console.components.payload-formatters-form.index.appFormatter": "Use application payload formatter",
"console.components.payload-formatters-form.index.appFormatterWarning": "This option will affect both uplink and downlink formatter",
- "console.components.payload-formatters-form.index.setupSubTitle": "Setup",
"console.components.payload-formatters-form.index.defaultFormatter": "Click here to modify the default payload formatter for this application. The payload formatter of this application is currently set to `{defaultFormatter}`",
"console.components.payload-formatters-form.index.pasteRepositoryFormatter": "Paste repository formatter",
"console.components.payload-formatters-form.index.pasteApplicationFormatter": "Paste application formatter",
@@ -375,9 +332,6 @@
"console.components.pubsub-form.messages.deletePubsub": "Delete Pub/Sub",
"console.components.pubsub-form.messages.modalWarning": "Are you sure you want to delete Pub/Sub \"{pubsubId}\"? Deleting a Pub/Sub cannot be undone.",
"console.components.pubsub-form.messages.headers": "Headers",
- "console.components.pubsub-form.messages.headersKeyPlaceholder": "Authorization",
- "console.components.pubsub-form.messages.headersValuePlaceholder": "Bearer my-auth-token",
- "console.components.pubsub-form.messages.headersAdd": "Add header entry",
"console.components.pubsub-form.messages.headersValidateRequired": "All header entry values are required. Please remove empty entries.",
"console.components.pubsub-form.messages.usernamePlaceholder": "my-username",
"console.components.pubsub-form.messages.passwordPlaceholder": "my-password",
@@ -387,9 +341,8 @@
"console.components.pubsub-form.messages.mqttConfig": "MQTT configuration",
"console.components.pubsub-form.messages.mqttClientIdPlaceholder": "my-client-id",
"console.components.pubsub-form.messages.mqttServerUrlPlaceholder": "mqtts://example.com",
- "console.components.pubsub-form.messages.serverUrl": "Server URL",
- "console.components.pubsub-form.messages.clientId": "Client ID",
"console.components.pubsub-form.messages.subscribeQos": "Subscribe QoS",
+ "console.components.pubsub-form.messages.providerDescription": "Changing the Pub/Sub provider has been disabled by an administrator",
"console.components.pubsub-form.messages.publishQos": "Publish QoS",
"console.components.pubsub-form.messages.tlsCa": "Root CA certificate",
"console.components.pubsub-form.messages.tlsClientCert": "Client certificate",
@@ -397,27 +350,21 @@
"console.components.pubsub-form.messages.selectPemFile": "Select .pem file…",
"console.components.pubsub-form.messages.pemFileProvided": ".pem file has been provided",
"console.components.pubsub-form.messages.useCredentials": "Use credentials",
- "console.components.pubsub-form.messages.alreadyExistsModalTitle": "ID already exists",
"console.components.pubsub-form.messages.alreadyExistsModalMessage": "A Pub/Sub with the ID \"{id}\" already exists. Do you wish to replace this Pub/Sub?",
"console.components.pubsub-form.messages.replacePubsub": "Replace Pub/Sub",
"console.components.pubsub-form.messages.useSecureConnection": "Use secure connection",
"console.components.pubsub-form.messages.pubsubsDescription": "The Pub/Sub integration allows the Application Server to publish and subscribe to topics, using The Things Stack built-in MQTT client or NATS client. Learn more in our Pub/Sub guide.",
"console.components.routing-policy-form.index.saveDefaultPolicy": "Save default policy",
- "console.components.routing-policy-form.index.useDefaultPolicy": "Use default routing policy for this network",
"console.components.routing-policy-form.index.useSpecificPolicy": "Use network specific routing policy",
- "console.components.routing-policy-form.index.doNotUseADefaultPolicy": "Do not use a default routing policy for this network",
"console.components.routing-policy-form.index.doNotUseAPolicy": "Do not use a routing policy for this network",
- "console.components.uplink-form.uplink-form.simulateUplink": "Simulate uplink",
- "console.components.uplink-form.uplink-form.payloadDescription": "The desired payload bytes of the uplink message",
- "console.components.uplink-form.uplink-form.uplinkSuccess": "Uplink sent",
+ "console.components.uplink-form.index.simulateUplink": "Simulate uplink",
+ "console.components.uplink-form.index.payloadDescription": "The desired payload bytes of the uplink message",
+ "console.components.uplink-form.index.uplinkSuccess": "Uplink sent",
"console.components.webhook-form.index.idPlaceholder": "my-new-webhook",
"console.components.webhook-form.index.messageInfo": "For each enabled event type an optional path can be defined which will be appended to the base URL",
"console.components.webhook-form.index.deleteWebhook": "Delete Webhook",
"console.components.webhook-form.index.modalWarning": "Are you sure you want to delete webhook \"{webhookId}\"? Deleting a webhook cannot be undone.",
"console.components.webhook-form.index.additionalHeaders": "Additional headers",
- "console.components.webhook-form.index.headersKeyPlaceholder": "Authorization",
- "console.components.webhook-form.index.headersValuePlaceholder": "Bearer my-auth-token",
- "console.components.webhook-form.index.headersAdd": "Add header entry",
"console.components.webhook-form.index.downlinkAPIKey": "Downlink API key",
"console.components.webhook-form.index.downlinkAPIKeyDesc": "The API key will be provided to the endpoint using the \"X-Downlink-Apikey\" header",
"console.components.webhook-form.index.templateInformation": "Template information",
@@ -439,16 +386,12 @@
"console.components.webhook-template-form.index.createTemplate": "Create {template} webhook",
"console.components.webhook-template-form.index.idPlaceholder": "my-new-{templateId}-webhook",
"console.components.webhook-template-info.index.about": "About {name}",
- "console.components.webhook-template-info.index.documentation": "Documentation",
"console.components.webhook-template-info.index.setupWebhook": "Setup webhook for {name}",
"console.components.webhook-template-info.index.editWebhook": "Edit webhook for {name}",
- "console.containers.account-select.index.noOptionsMessage": "No matching user or organization was found",
- "console.containers.account-select.index.suggestions": "Suggestions",
"console.containers.api-key-form.edit.deleteKey": "Delete key",
"console.containers.api-key-form.edit.modalWarning": "Are you sure you want to delete the {keyName} API key? Deleting an API key cannot be undone.",
"console.containers.api-key-form.edit.updateSuccess": "API key updated",
"console.containers.api-key-form.edit.deleteSuccess": "API key deleted",
- "console.containers.api-keys-table.index.keyId": "Key ID",
"console.containers.api-keys-table.index.grantedRights": "Granted Rights",
"console.containers.application-general-settings.index.updateSuccess": "Application updated",
"console.containers.application-general-settings.index.deleteSuccess": "Application deleted",
@@ -466,19 +409,18 @@
"console.containers.applications-form.index.appDescPlaceholder": "Description for my new application",
"console.containers.applications-form.index.appDescDescription": "Optional application description; can also be used to save notes about the application",
"console.containers.applications-form.index.appDescription": "Within applications, you can register and manage end devices, aggregate their sensor data and act on it using our many integration options.{break}Learn more in our Applications Guide",
- "console.containers.applications-form.index.createApplication": "Create application",
"console.containers.applications-table.index.ownedTabTitle": "Owned applications",
"console.containers.applications-table.index.restoreSuccess": "Application restored",
"console.containers.applications-table.index.restoreFail": "There was an error and application could not be restored",
"console.containers.applications-table.index.purgeSuccess": "Application purged",
"console.containers.applications-table.index.purgeFail": "There was an error and the application could not be purged",
"console.containers.applications-table.index.otherClusterTooltip": "This application is registered on a different cluster (`{host}`). To access this application, use the Console of the cluster that this application was registered on.",
- "console.containers.collaborators-table.index.id": "User / Organization ID",
"console.containers.deployment-component-status.index.availableComponents": "Available components",
"console.containers.deployment-component-status.index.versionInfo": "Deployment",
"console.containers.deployment-component-status.index.statusPage": "Go to status page",
"console.containers.deployment-component-status.index.seeChangelog": "See changelog",
"console.containers.dev-addr-input.index.devAddrFetchingFailure": "There was an error and the end device address could not be generated",
+ "console.containers.dev-eui-component.index.unknownError": "Unknown error while generating DevEUI",
"console.containers.device-importer.messages.proceed": "Proceed to end device list",
"console.containers.device-importer.messages.retry": "Retry from scratch",
"console.containers.device-importer.messages.abort": "Abort",
@@ -517,33 +459,19 @@
"console.containers.device-onboarding-form.messages.confirmedClaiming": "This end device can be claimed",
"console.containers.device-onboarding-form.messages.cannotConfirmEui": "There was an error and the JoinEUI could not be confirmed. Please try again later.",
"console.containers.device-onboarding-form.messages.classCapabilities": "Additional LoRaWAN class capabilities",
- "console.containers.device-onboarding-form.messages.submitTitle": "Register end device",
"console.containers.device-onboarding-form.messages.afterRegistration": "After registration",
"console.containers.device-onboarding-form.messages.singleRegistration": "View registered end device",
"console.containers.device-onboarding-form.messages.multipleRegistration": "Register another end device of this type",
"console.containers.device-onboarding-form.messages.createSuccess": "End device registered",
"console.containers.device-onboarding-form.messages.deviceIdDescription": "This value is automatically prefilled using the DevEUI",
"console.containers.device-onboarding-form.messages.onboardingDisabled": "Device onboarding can only be performed on deployments that have Network Server, Application Server and Join Server activated. Please use the CLI to register devices on individual components.",
- "console.containers.device-onboarding-form.messages.beaconFrequency": "Beacon frequency",
- "console.containers.device-onboarding-form.messages.rx1DataRateOffsetTitle": "Rx1 data rate offset",
- "console.containers.device-onboarding-form.messages.rx1DelayTitle": "Rx1 delay",
- "console.containers.device-onboarding-form.messages.factoryPresetFreqTitle": "Factory preset frequencies",
- "console.containers.device-onboarding-form.messages.freqAdd": "Add Frequency",
- "console.containers.device-onboarding-form.messages.frequencyPlaceholder": "e.g. 869525000 for 869,525 MHz",
- "console.containers.device-onboarding-form.messages.pingSlotPeriodicityTitle": "Ping slot periodicity",
- "console.containers.device-onboarding-form.messages.pingSlotPeriodicityValue": "{count, plural, one {every second} other {every {count} seconds}}",
"console.containers.device-onboarding-form.messages.pingSlotDataRateTitle": "Ping slot data rate",
- "console.containers.device-onboarding-form.messages.pingSlotFrequencyTitle": "Ping slot frequency",
"console.containers.device-onboarding-form.messages.rx2DataRateIndexTitle": "Rx2 data rate",
- "console.containers.device-onboarding-form.messages.rx2FrequencyTitle": "Rx2 frequency",
- "console.containers.device-onboarding-form.messages.classBTimeout": "Class B timeout",
- "console.containers.device-onboarding-form.messages.classCTimeout": "Class C timeout",
"console.containers.device-onboarding-form.messages.defaultNetworksSettings": "Use network's default MAC settings",
"console.containers.device-onboarding-form.messages.clusterSettings": "Cluster settings",
"console.containers.device-onboarding-form.messages.networkDefaults": "Network defaults",
"console.containers.device-onboarding-form.messages.hasEndDeviceQR": "Does your end device have a LoRaWAN® Device Identification QR Code? Scan it to speed up onboarding.",
"console.containers.device-onboarding-form.messages.deviceGuide": "Device registration help",
- "console.containers.device-onboarding-form.messages.scanEndDevice": "Scan end device QR code",
"console.containers.device-onboarding-form.messages.deviceInfo": "Found QR code data",
"console.containers.device-onboarding-form.messages.resetQRCodeData": "Reset QR code data",
"console.containers.device-onboarding-form.messages.resetConfirm": "Are you sure you want to discard QR code data? The scanned device will not be registered and the form will be reset.",
@@ -557,65 +485,60 @@
"console.containers.device-onboarding-form.type-form-section.manual-form-section.advanced-settings-section.skipJsRegistration": "Skip registration on Join Server",
"console.containers.device-onboarding-form.type-form-section.manual-form-section.advanced-settings-section.multicastClassCapabilities": "LoRaWAN class for multicast downlinks",
"console.containers.device-onboarding-form.type-form-section.manual-form-section.advanced-settings-section.register": "Register manually",
- "console.containers.device-onboarding-form.type-form-section.manual-form-section.advanced-settings-section.macSettingsError": "There was an error and the default MAC settings for the {freqPlan}
frequency plan could not be loaded",
- "console.containers.device-onboarding-form.type-form-section.manual-form-section.advanced-settings-section.fpNotFoundError": "The LoRaWAN version {lorawanVersion}
does not support the {freqPlan}
frequency plan. Please choose a different MAC version or frequency plan.",
"console.containers.device-onboarding-form.warning-tooltip.desiredDescription": "The network will use a different desired value of {value}
for this property.",
"console.containers.device-onboarding-form.warning-tooltip.sessionDescription": "An ABP device is personalized with a session and MAC settings. These MAC settings are considered the current parameters and must match exactly the settings entered here. The Network Server uses desired parameters to change the MAC state with LoRaWAN MAC commands to the desired state. You can use the General Settings page to update the desired setting after you registered the end device.",
"console.containers.device-payload-formatters.messages.defaultFormatter": "Click here to modify the default payload formatter for this application",
"console.containers.device-payload-formatters.messages.mayNotViewLink": "You are not allowed to view link information of this application. This includes seeing the default payload formatter of this application.",
- "console.containers.device-profile-section.device-card.device-card.productWebsite": "Product website",
- "console.containers.device-profile-section.device-card.device-card.dataSheet": "Data sheet",
- "console.containers.device-profile-section.device-card.device-card.classA": "Class A",
- "console.containers.device-profile-section.device-card.device-card.classB": "Class B",
- "console.containers.device-profile-section.device-card.device-card.classC": "Class C",
+ "console.containers.device-profile-section.device-card.index.productWebsite": "Product website",
+ "console.containers.device-profile-section.device-card.index.dataSheet": "Data sheet",
+ "console.containers.device-profile-section.device-card.index.classA": "Class A",
+ "console.containers.device-profile-section.device-card.index.classB": "Class B",
+ "console.containers.device-profile-section.device-card.index.classC": "Class C",
"console.containers.device-profile-section.device-selection.band-select.index.title": "Profile (Region)",
- "console.containers.device-profile-section.device-selection.brand-select.brand-select.title": "End device brand",
- "console.containers.device-profile-section.device-selection.brand-select.brand-select.warning": "End device models unavailable",
- "console.containers.device-profile-section.device-selection.brand-select.brand-select.noOptionsMessage": "No matching brand found",
- "console.containers.device-profile-section.device-selection.fw-version-select.fw-version-select.title": "Firmware Ver.",
- "console.containers.device-profile-section.device-selection.hw-version-select.hw-version-select.title": "Hardware Ver.",
- "console.containers.device-profile-section.device-selection.model-select.model-select.title": "Model",
- "console.containers.device-profile-section.device-selection.model-select.model-select.warning": "End device models unavailable",
- "console.containers.device-profile-section.device-selection.model-select.model-select.noOptionsMessage": "No matching model found",
+ "console.containers.device-profile-section.device-selection.brand-select.index.title": "End device brand",
+ "console.containers.device-profile-section.device-selection.brand-select.index.noOptionsMessage": "No matching brand found",
+ "console.containers.device-profile-section.device-selection.fw-version-select.index.title": "Firmware Ver.",
+ "console.containers.device-profile-section.device-selection.hw-version-select.index.title": "Hardware Ver.",
+ "console.containers.device-profile-section.device-selection.model-select.index.noOptionsMessage": "No matching model found",
"console.containers.device-profile-section.hints.other-hint.hintTitle": "Your end device will be added soon!",
"console.containers.device-profile-section.hints.other-hint.hintMessage": "We're sorry, but your device is not yet part of The LoRaWAN Device Repository. You can use enter end device specifics manually option above, using the information your end device manufacturer provided e.g. in the product's data sheet. Please also refer to our documentation on Adding Devices .",
"console.containers.device-profile-section.hints.progress-hint.hintMessage": "Cannot find your exact end device? Get help here and try enter end device specifics manually option above.",
"console.containers.device-profile-section.hints.progress-hint.hintNoSupportMessage": "Cannot find your exact end device? Try enter end device specifics manually option above.",
"console.containers.device-template-format-select.index.title": "File format",
"console.containers.device-template-format-select.index.warning": "End device template formats unavailable",
- "console.containers.device-title-section.device-title-section.uplinkDownlinkTooltip": "The number of sent uplinks and received downlinks of this end device since the last frame counter reset.",
- "console.containers.device-title-section.device-title-section.lastSeenAvailableTooltip": "The elapsed time since the network registered the last activity of this end device. This is determined from sent uplinks, confirmed downlinks or (re)join requests.{lineBreak}The last activity was received at {lastActivityInfo}",
- "console.containers.device-title-section.device-title-section.noActivityTooltip": "The network has not registered any activity from this end device yet. This could mean that your end device has not sent any messages yet or only messages that cannot be handled by the network, e.g. due to a mismatch of EUIs or frequencies.",
+ "console.containers.device-title-section.index.uplinkDownlinkTooltip": "The number of sent uplinks and received downlinks of this end device since the last frame counter reset.",
+ "console.containers.device-title-section.index.lastSeenAvailableTooltip": "The elapsed time since the network registered the last activity of this end device. This is determined from sent uplinks, confirmed downlinks or (re)join requests.{lineBreak}The last activity was received at {lastActivityInfo}",
+ "console.containers.device-title-section.index.noActivityTooltip": "The network has not registered any activity from this end device yet. This could mean that your end device has not sent any messages yet or only messages that cannot be handled by the network, e.g. due to a mismatch of EUIs or frequencies.",
"console.containers.devices-table.index.otherClusterTooltip": "This end device is registered on a different cluster (`{host}`). To access this device, use the Console of the cluster that this end device was registered on.",
- "console.containers.freq-plans-select.index.title": "Frequency plan",
- "console.containers.freq-plans-select.index.warning": "Frequency plans unavailable",
- "console.containers.freq-plans-select.index.none": "Do not set a frequency plan",
- "console.containers.gateway-connection.gateway-connection.lastSeenAvailableTooltip": "The elapsed time since the network registered the last activity of this gateway. This is determined from received uplinks, or sent status messages of this gateway.",
- "console.containers.gateway-connection.gateway-connection.disconnectedTooltip": "The gateway has currently no TCP connection established with the Gateway Server. For (rare) UDP based gateways, this can also mean that the gateway initiated no pull/push data request within the last 30 seconds.",
- "console.containers.gateway-connection.gateway-connection.connectedTooltip": "This gateway is connected to the Gateway Server but the network has not registered any activity (sent uplinks or status messages) from it yet.",
- "console.containers.gateway-connection.gateway-connection.otherClusterTooltip": "This gateway is connected to an external Gateway Server that is not handling messages for this cluster. You will hence not be able to see any activity from this gateway.",
- "console.containers.gateway-connection.gateway-connection.messageCountTooltip": "The amount of received uplinks and sent downlinks of this gateway since the last (re)connect. Note that some gateway types reconnect frequently causing the counter to be reset.",
- "console.containers.gateway-location-form.gateway-location-form.updateLocationFromStatus": "Update from status messages",
- "console.containers.gateway-location-form.gateway-location-form.updateLocationFromStatusDescription": "Update the location of this gateway based on incoming status messages",
- "console.containers.gateway-location-form.gateway-location-form.setGatewayLocation": "Gateway antenna location settings",
- "console.containers.gateway-location-form.gateway-location-form.locationSource": "Location source",
- "console.containers.gateway-location-form.gateway-location-form.locationPrivacy": "Location privacy",
- "console.containers.gateway-location-form.gateway-location-form.placement": "Placement",
- "console.containers.gateway-location-form.gateway-location-form.indoor": "Indoor",
- "console.containers.gateway-location-form.gateway-location-form.outdoor": "Outdoor",
- "console.containers.gateway-location-form.gateway-location-form.locationFromStatusMessage": "Location set automatically from status messages",
- "console.containers.gateway-location-form.gateway-location-form.setLocationManually": "Set location manually",
- "console.containers.gateway-location-form.gateway-location-form.noLocationSetInfo": "This gateway has no location information set",
+ "console.containers.freq-plans-select.utils.warning": "Frequency plans unavailable",
+ "console.containers.freq-plans-select.utils.none": "Do not set a frequency plan",
+ "console.containers.freq-plans-select.utils.selectFrequencyPlan": "Select a frequency plan...",
+ "console.containers.freq-plans-select.utils.addFrequencyPlan": "Add frequency plan",
+ "console.containers.freq-plans-select.utils.frequencyPlanDescription": "Note: most gateways use a single frequency plan. Some 16 and 64 channel gateways however allow setting multiple within the same band.",
+ "console.containers.gateway-connection.index.lastSeenAvailableTooltip": "The elapsed time since the network registered the last activity of this gateway. This is determined from received uplinks, or sent status messages of this gateway.",
+ "console.containers.gateway-connection.index.disconnectedTooltip": "The gateway has currently no TCP connection established with the Gateway Server. For (rare) UDP based gateways, this can also mean that the gateway initiated no pull/push data request within the last 30 seconds.",
+ "console.containers.gateway-connection.index.connectedTooltip": "This gateway is connected to the Gateway Server but the network has not registered any activity (sent uplinks or status messages) from it yet.",
+ "console.containers.gateway-connection.index.otherClusterTooltip": "This gateway is connected to an external Gateway Server that is not handling messages for this cluster. You will hence not be able to see any activity from this gateway.",
+ "console.containers.gateway-connection.index.messageCountTooltip": "The amount of received uplinks and sent downlinks of this gateway since the last (re)connect. Note that some gateway types reconnect frequently causing the counter to be reset.",
+ "console.containers.gateway-location-form.index.updateLocationFromStatus": "Update from status messages",
+ "console.containers.gateway-location-form.index.updateLocationFromStatusDescription": "Update the location of this gateway based on incoming status messages",
+ "console.containers.gateway-location-form.index.setGatewayLocation": "Gateway antenna location settings",
+ "console.containers.gateway-location-form.index.locationSource": "Location source",
+ "console.containers.gateway-location-form.index.locationPrivacy": "Location privacy",
+ "console.containers.gateway-location-form.index.placement": "Placement",
+ "console.containers.gateway-location-form.index.indoor": "Indoor",
+ "console.containers.gateway-location-form.index.outdoor": "Outdoor",
+ "console.containers.gateway-location-form.index.locationFromStatusMessage": "Location set automatically from status messages",
+ "console.containers.gateway-location-form.index.setLocationManually": "Set location manually",
+ "console.containers.gateway-location-form.index.noLocationSetInfo": "This gateway has no location information set",
"console.containers.gateway-onboarding-form.gateway-provisioning-form.gateway-registration-form-section.index.requireAuthenticatedConnectionDescription": "Select which information can be seen by other network participants, including {packetBrokerURL}",
"console.containers.gateway-onboarding-form.gateway-provisioning-form.gateway-registration-form-section.index.shareGatewayInfoDescription": "Choose this option eg. if your gateway is powered by {loraBasicStationURL}",
- "console.containers.gateway-onboarding-form.gateway-provisioning-form.gateway-registration-form-section.index.generateAPIKeyCups": "Generate API key for CUPS",
- "console.containers.gateway-onboarding-form.gateway-provisioning-form.gateway-registration-form-section.index.generateAPIKeyLNS": "Generate API key for LNS",
+ "console.containers.gateway-onboarding-form.gateway-provisioning-form.gateway-registration-form-section.validation-schema.validateEntry": "There must be at least one selected frequency plan ID.",
"console.containers.gateways-table.index.ownedTabTitle": "Owned gateways",
"console.containers.gateways-table.index.restoreSuccess": "Gateway restored",
"console.containers.gateways-table.index.restoreFail": "There was an error and the gateway could not be restored",
"console.containers.gateways-table.index.purgeSuccess": "Gateway purged",
"console.containers.gateways-table.index.purgeFail": "There was an error and the gateway could not be purged",
- "console.containers.invite-user-form.index.emailPlaceholder": "mail@example.com",
"console.containers.invite-user-form.index.invitationsDescription": "You can invite users to this network by providing an email address. The person will then get an email with instructions on how to join your network.",
"console.containers.log-back-in-modal.index.modalTitle": "Please sign in again",
"console.containers.log-back-in-modal.index.modalMessage": "You were signed out of the Console. You can press 'Reload' to log back into the Console again.",
@@ -624,11 +547,9 @@
"console.containers.lora-cloud-das-form.index.fPortSetTitle": "FPort Set",
"console.containers.lora-cloud-das-form.index.fPortSetDescription": "Comma separated list of F-Port values (1-223) to be used for LoRa Cloud Modem Services",
"console.containers.lora-cloud-das-form.index.modemEncoding": "LoRa Edge Reference Tracker (Modem-E) encoding",
- "console.containers.lora-cloud-das-form.index.setLoRaCloudToken": "Set LoRa Cloud token",
"console.containers.lora-cloud-das-form.index.deleteWarning": "Are you sure you want to delete the LoRa Cloud Modem and Geolocation Services token? This action cannot be undone.",
"console.containers.lora-cloud-das-form.index.fPortSetValidationFormat": "The FPort must be a number between 1 and 223, or a comma-separated list of numbers between 1 and 223",
"console.containers.lora-cloud-gls-form.index.tokenDescription": "Geolocation access token as configured within LoRa Cloud",
- "console.containers.lora-cloud-gls-form.index.setLoRaCloudToken": "Set LoRa Cloud token",
"console.containers.lora-cloud-gls-form.index.deleteWarning": "Are you sure you want to delete the LoRaCloud Geolocation token? This action cannot be undone.",
"console.containers.lora-cloud-gls-form.index.queryType": "Query type",
"console.containers.lora-cloud-gls-form.index.queryTypeDescription": "What kind of geolocation query should be used",
@@ -659,37 +580,14 @@
"console.containers.organizations-table.index.restoreFail": "There was an error and the organization could not be restored",
"console.containers.organizations-table.index.purgeSuccess": "Organization purged",
"console.containers.organizations-table.index.purgeFail": "There was an error and the organization could not be purged",
- "console.containers.owners-select.owners-select.title": "Owner",
- "console.containers.owners-select.owners-select.warning": "There was an error and the list of organizations could not be displayed",
+ "console.containers.owners-select.index.title": "Owner",
+ "console.containers.owners-select.index.warning": "There was an error and the list of organizations could not be displayed",
"console.containers.packet-broker-networks-table.index.nonDefaultPolicies": "Networks with non-default policies",
"console.containers.packet-broker-networks-table.index.search": "Search by tenant ID or name",
"console.containers.packet-broker-networks-table.index.forwarderPolicy": "Their routing policy towards us",
"console.containers.packet-broker-networks-table.index.homeNetworkPolicy": "Our routing policy for them",
- "console.containers.pubsub-formats-select.index.title": "Pub/Sub format",
"console.containers.pubsub-formats-select.index.warning": "Pub/Sub formats unavailable",
- "console.containers.pubsubs-table.index.format": "Format",
"console.containers.pubsubs-table.index.host": "Server host",
- "console.containers.user-data-form.add.adminLabel": "Grant this user admin status",
- "console.containers.user-data-form.add.adminDescription": "Admin status enables overarching rights such as managing other users or modifying entities regardless of collaboration status",
- "console.containers.user-data-form.add.userDescPlaceholder": "Description for my new user",
- "console.containers.user-data-form.add.userDescDescription": "Optional user description; can also be used to save notes about the user",
- "console.containers.user-data-form.add.userIdPlaceholder": "jane-doe",
- "console.containers.user-data-form.add.userNamePlaceholder": "Jane Doe",
- "console.containers.user-data-form.add.emailPlaceholder": "mail@example.com",
- "console.containers.user-data-form.add.emailAddressDescription": "Primary email address used for logging in; this address is not publicly visible",
- "console.containers.user-data-form.add.emailAddressValidation": "Treat email address as validated",
- "console.containers.user-data-form.add.emailAddressValidationDescription": "Enable this option if you do not need this user to validate the email address",
- "console.containers.user-data-form.edit.adminLabel": "Grant this user admin status",
- "console.containers.user-data-form.edit.adminDescription": "Admin status enables overarching rights such as managing other users or modifying entities regardless of collaboration status",
- "console.containers.user-data-form.edit.userDescPlaceholder": "Description for my new user",
- "console.containers.user-data-form.edit.userDescDescription": "Optional user description; can also be used to save notes about the user",
- "console.containers.user-data-form.edit.userIdPlaceholder": "jane-doe",
- "console.containers.user-data-form.edit.userNamePlaceholder": "Jane Doe",
- "console.containers.user-data-form.edit.emailPlaceholder": "mail@example.com",
- "console.containers.user-data-form.edit.emailAddressDescription": "Primary email address used for logging in; this address is not publicly visible",
- "console.containers.user-data-form.edit.emailAddressValidation": "Treat email address as validated",
- "console.containers.user-data-form.edit.emailAddressValidationDescription": "Enable this option if you do not need this user to validate the email address",
- "console.containers.user-data-form.edit.deleteTitle": "Are you sure you want to delete this account?",
"console.containers.user-data-form.edit.deleteWarning": "This will PERMANENTLY DELETE THIS ACCOUNT and LOCK THE USER ID AND EMAIL FOR RE-REGISTRATION . Associated entities (e.g. gateways, applications and end devices) owned by this user that do not have any other collaborators will become UNACCESSIBLE and it will NOT BE POSSIBLE TO REGISTER ENTITIES WITH THE SAME ID OR EUI's AGAIN . Make sure you assign new collaborators to such entities if you plan to continue using them.",
"console.containers.user-data-form.edit.purgeWarning": "This will PERMANENTLY DELETE THIS ACCOUNT . Associated entities (e.g. gateways, applications and end devices) owned by this user that do not have any other collaborators will become UNACCESSIBLE and it will NOT BE POSSIBLE TO REGISTER ENTITIES WITH THE SAME ID OR EUI's AGAIN . Make sure you assign new collaborators to such entities if you plan to continue using them.",
"console.containers.user-data-form.edit.deleteConfirmMessage": "Please type in this user's user ID to confirm.",
@@ -700,19 +598,11 @@
"console.containers.users-table.index.sentAt": "Sent",
"console.containers.users-table.index.revokeSuccess": "Invite removed successfully",
"console.containers.users-table.index.revokeError": "There was an error and the invite could not be revoked",
- "console.containers.webhook-edit.index.editWebhook": "Edit webhook",
- "console.containers.webhook-edit.index.updateSuccess": "Webhook updated",
- "console.containers.webhook-edit.index.deleteSuccess": "Webhook deleted",
- "console.containers.webhook-edit.index.reactivateSuccess": "Webhook activated",
- "console.containers.webhook-formats-select.index.title": "Webhook format",
"console.containers.webhook-formats-select.index.warning": "Webhook formats unavailable",
"console.containers.webhooks-table.index.templateId": "Template ID",
- "console.containers.webhooks-table.index.format": "Format",
- "console.containers.webhooks-table.index.baseUrl": "Base URL",
"console.containers.webhooks-table.index.healthy": "Healthy",
"console.containers.webhooks-table.index.pending": "Pending",
"console.containers.webhooks-table.index.requestsFailing": "Requests failing",
- "console.lib.events.definitions.synthetic.error.unknown:type": "Unknown error",
"console.lib.events.definitions.synthetic.error.unknown:preview": "An unknown error occurred and one or more events could not be retrieved",
"console.lib.events.definitions.synthetic.error.unknown:details": "The Console encountered an unexpected error while handling the event stream data. It is possible that event data could not be displayed (correctly) as a result. Note that this is an internal error which does not imply any malfunction of your gateways or end devices.",
"console.lib.events.definitions.synthetic.error.network_error:type": "Network error",
@@ -723,10 +613,10 @@
"console.lib.events.definitions.synthetic.status.reconnecting:details": "The Console will periodically try to reconnect to the event stream if the connection was interrupted.",
"console.lib.events.definitions.synthetic.status.reconnected:type": "Stream reconnected",
"console.lib.events.definitions.synthetic.status.reconnected:preview": "The stream connection has been re-established",
- "console.lib.events.definitions.synthetic.status.reconnected:details": "The Console was able to reconnect to the internet and resumed the event stream. Subsequent event data will be received and displayed. Note that event data which was possibly emitted during the network disruption will not be re-delivered.",
+ "console.lib.events.definitions.synthetic.status.reconnected:details": "The Console was able to reconnect to the network and resumed the event stream. Subsequent event data will be received and displayed. Note that event data which was possibly emitted during the network disruption will only be re-delivered within the range of the event retention configuration for your network.",
"console.lib.events.definitions.synthetic.status.closed:type": "Stream connection closed",
- "console.lib.events.definitions.synthetic.status.closed:preview": "The connection was closed by the stream provider",
- "console.lib.events.definitions.synthetic.status.closed:details": "The Console received a close signal from the stream provider. This usually means that the backend server shut down. This can have various causes, such as scheduled maintenance or malfunction which caused a forced restart. The Console will then reconnect automatically once the stream provider becomes available again.",
+ "console.lib.events.definitions.synthetic.status.closed:preview": "The connection was closed",
+ "console.lib.events.definitions.synthetic.status.closed:details": "The event stream was closed. This can be for various reasons, such as your machine going into standby mode or the internet connection being interrupted. The stream will reconnect automatically once the internet connection has been re-established.",
"console.lib.events.definitions.synthetic.status.cleared:type": "Events cleared",
"console.lib.events.definitions.synthetic.status.cleared:preview": "The events list has been cleared",
"console.lib.events.definitions.synthetic.status.cleared:details": "The list of displayed events has been cleared.",
@@ -742,16 +632,13 @@
"console.lib.events.definitions.synthetic.status.filter_disabled:type": "Filter disabled",
"console.lib.events.definitions.synthetic.status.filter_disabled:preview": "The previously set event filter has been disabled",
"console.lib.events.definitions.synthetic.status.filter_disabled:details": "The event stream will not be filtered anymore. This means that you will see all events that come out of the event stream for this entity.",
- "console.lib.packet-broker.messages.applicationData": "Application data",
"console.lib.packet-broker.messages.applicationDataAllowDesc": "Allow downlink messages with FPort between 1 and 255",
"console.lib.packet-broker.messages.applicationDataDesc": "Forward uplink messages with FPort 1-255",
- "console.lib.packet-broker.messages.joinAccept": "Join accept",
"console.lib.packet-broker.messages.joinAcceptDesc": "Allow join accept messages",
"console.lib.packet-broker.messages.joinRequest": "Join request",
"console.lib.packet-broker.messages.joinRequestDesc": "Forward join-request messages",
"console.lib.packet-broker.messages.localizationInformation": "Localization information",
"console.lib.packet-broker.messages.localizationInformationDesc": "Forward gateway location, RSSI, SNR and fine timestamp",
- "console.lib.packet-broker.messages.macData": "MAC data",
"console.lib.packet-broker.messages.macDataAllowDesc": "Allow downlink messages with FPort of 0",
"console.lib.packet-broker.messages.macDataDesc": "Forward uplink messages with FPort 0",
"console.lib.packet-broker.messages.signalQualityInformation": "Signal quality information",
@@ -774,17 +661,13 @@
"console.lib.packet-broker.messages.doesNotAllowApplicationData": "Application data is not allowed",
"console.lib.packet-broker.messages.uplinkPolicies": "This top row shows the uplink forwarding policies of this network",
"console.lib.packet-broker.messages.downlinkPolicies": "This bottom row shows the downlink policies of this network",
- "console.lib.packet-broker.messages.gatewayLocationLabel": "Location",
"console.lib.packet-broker.messages.gatewayAntennaPlacementLabel": "Antenna placement",
"console.lib.packet-broker.messages.gatewayAntennaPlacementDescription": "Show antenna placement (indoor/outdoor)",
"console.lib.packet-broker.messages.gatewayAntennaCountLabel": "Antenna count",
"console.lib.packet-broker.messages.gatewayFineTimestampsLabel": "Fine timestamps",
"console.lib.packet-broker.messages.gatewayFineTimestampsDescription": "Whether the gateway produces fine timestamps",
- "console.lib.packet-broker.messages.gatewayContactInfoLabel": "Contact information",
"console.lib.packet-broker.messages.gatewayContactInfoDescription": "Show means to contact the gateway owner or operator",
- "console.lib.packet-broker.messages.gatewayStatusLabel": "Status",
"console.lib.packet-broker.messages.gatewayStatusDescription": "Show whether the gateway is online or offline",
- "console.lib.packet-broker.messages.gatewayFreqPlanLabel": "Frequency plan",
"console.lib.packet-broker.messages.gatewayPacketRatesLabel": "Packet rates",
"console.lib.packet-broker.messages.gatewayPacketRatesDescription": "Receive and transmission packet rates",
"console.store.middleware.logics.packet-broker.unauthenticatedErrorTitle": "Unable to authorize",
@@ -792,30 +675,26 @@
"console.store.middleware.logics.users.errEmailValidationActionSuccess": "Validation email sent (please also check your spam folder)",
"console.store.middleware.logics.users.errEmailValidationActionFailure": "There was an error and the validation email could not be sent.",
"console.store.middleware.logics.users.errEmailValidationAlreadySent": "A validation email has already been sent recently to your email address. Please also check your spam folder.",
- "console.views.admin-packet-broker.messages.packetBrokerInfoText": "Packet Broker can be used to exchange traffic (peering) with other LoRaWAN networks to share coverage and improve the overall network performance.",
+ "console.views.admin-packet-broker.messages.packetBrokerInfoText": "Packet Broker is a service by The Things Industries to facilitate peering between LoRaWAN networks. This extends network coverage and improves overall network performance and device battery lifetime.",
"console.views.admin-packet-broker.messages.packetBrokerWebsite": "Packet Broker website",
- "console.views.admin-packet-broker.messages.registrationStatus": "Registration status",
- "console.views.admin-packet-broker.messages.registerNetwork": "Register network",
- "console.views.admin-packet-broker.messages.networkVisibility": "Network visibility",
- "console.views.admin-packet-broker.messages.packetBrokerRegistrationDesc": "To enable peering from or to your home network, it is necessary to register your network. This will make your network known to Packet Broker and enable you to configure your network's peering behavior.",
+ "console.views.admin-packet-broker.messages.learnMore": "Learn more",
+ "console.views.admin-packet-broker.messages.whyNetworkPeeringTitle": "Why choose network peering?",
+ "console.views.admin-packet-broker.messages.whyNetworkPeeringText": "Since LoRaWAN uses shared spectrum, gateways receive messages from devices registered on other LoRaWAN networks. Instead of discarding this traffic, these messages can be forwarded via Packet Broker to the home network of these devices. This extends coverage of networks and allows devices to use higher data rates that reduce channel utilization and increase battery life. No sensitive data is exposed as LoRaWAN is end-to-end encrypted and integrity protected.",
+ "console.views.admin-packet-broker.messages.enbaling": "Enable forwarding via the options below or define custom routing policies. In the Networks tab below (visible by selecting the option \"Use custom routing policies\"), you can see which other networks are forwarding data to this network.",
"console.views.admin-packet-broker.messages.packetBrokerDisabledDesc": "The Things Stack is not set up to use Packet Broker. Please refer to the documentation link above for instructions on how to set up The Things Stack for peering with Packet Broker.",
- "console.views.admin-packet-broker.messages.packetBrokerRegistrationDisabledDesc": "The Things Stack is set up to use Packet Broker, but security settings disallow (de)registering your network here. Please contact Packet Broker to manage your registration. Refer to the documentation link above for contact information.",
+ "console.views.admin-packet-broker.messages.enablePacketBroker": "Enable Packet Broker",
+ "console.views.admin-packet-broker.messages.packetBrokerRegistrationDesc": "Enabling will allow other networks to send traffic to you as well as you forwarding traffic to them, based on the exact routing policy.",
+ "console.views.admin-packet-broker.messages.routingConfig": "Routing configuration",
"console.views.admin-packet-broker.messages.network": "Network: {network}",
- "console.views.admin-packet-broker.messages.homeNetworkEnabled": "Home network enabled ",
- "console.views.admin-packet-broker.messages.homeNetworkDisabled": "Home network disabled ",
- "console.views.admin-packet-broker.messages.forwarderEnabled": "Forwarder enabled ",
- "console.views.admin-packet-broker.messages.forwarderDisabled": "Forwarder disabled ",
- "console.views.admin-packet-broker.messages.listNetwork": "List network publicly",
- "console.views.admin-packet-broker.messages.listNetworkDesc": "Listing your network allows other network administrators to see your network. This allows them to easily configure routing policies with your network.",
+ "console.views.admin-packet-broker.messages.listNetwork": "List my network in Packet Broker publicly",
+ "console.views.admin-packet-broker.messages.listNetworkDesc": "Public listing will make it easier for other network operators to set up routing policies for your network. Hence public listing is generally recommended.",
"console.views.admin-packet-broker.messages.unlistNetwork": "Unlist this network",
"console.views.admin-packet-broker.messages.confirmUnlist": "Confirm unlist",
"console.views.admin-packet-broker.messages.Are you sure you want to unlist your network in Packet Broker?{lineBreak}This will hide your network. Other network administrators will not be able to see your network to configure routing policies.": "Are you sure you want to unlist your network in Packet Broker?{lineBreak}This will hide your network. Other network administrators will not be able to see your network to configure routing policies.",
"console.views.admin-packet-broker.messages.routingPolicyInformation": "You can use the checkboxes below to control the default forwarding behavior of your network. You can additionally set up individual per-network routing policies via the Networks tab.",
- "console.views.admin-packet-broker.messages.defaultRoutingPolicySet": "Default routing policy set",
+ "console.views.admin-packet-broker.messages.defaultRoutingPolicySet": "Default routing configuration set",
"console.views.admin-packet-broker.messages.routingPolicySet": "Routing policy set",
"console.views.admin-packet-broker.messages.defaultRoutingPolicy": "Default routing policy",
- "console.views.admin-packet-broker.messages.networks": "Networks",
- "console.views.admin-packet-broker.messages.networkInformation": "Network information",
"console.views.admin-packet-broker.messages.devAddressBlock": "Device address block",
"console.views.admin-packet-broker.messages.devAddressBlocks": "Device address blocks",
"console.views.admin-packet-broker.messages.lastPolicyChange": "Last policy change",
@@ -834,12 +713,9 @@
"console.views.admin-packet-broker.messages.gatewayVisibilityInformation": "You can use the checkboxes to control what information of your gateways will be visible. Note that this information will be visible to the public and not only to registered networks.",
"console.views.admin-packet-broker.messages.defaultGatewayVisibilitySet": "Default gateway visibility set",
"console.views.admin-packet-broker.messages.packetBrokerStatusPage": "Packet Broker Status page",
- "console.views.admin-panel-network-information.index.title": "Network information",
"console.views.application-add.index.appDescription": "Within applications, you can register and manage end devices and their network data. After setting up your device fleet, use one of our many integration options to pass relevant data to your external services.{break}Learn more in our guide on Adding Applications.",
- "console.views.application-data.index.appData": "Application data",
"console.views.application-integrations-lora-cloud.index.loraCloudInfoText": "Lora Cloud provides value added APIs that enable simple solutions for common tasks related to LoRaWAN networks and LoRa-based devices. You can setup our LoRaCloud integrations below.",
"console.views.application-integrations-lora-cloud.index.officialLoRaCloudDocumentation": "Official LoRa Cloud documentation",
- "console.views.application-integrations-lora-cloud.index.setToken": "Set LoRa Cloud token",
"console.views.application-integrations-lora-cloud.index.dasDescription": "With the LoRa Cloud Modem and Geolocation Services protocol, you can manage common device functionality at the application layer for LoRaWAN-enabled devices.",
"console.views.application-integrations-lora-cloud.index.glsDescription": "LoRa Cloud Geolocation is a simple cloud API that can be easily integrated with The Things Stack to enable estimating the location of any LoRa-based device.",
"console.views.application-integrations-mqtt.index.publicAddress": "Public address",
@@ -861,10 +737,6 @@
"console.views.application-integrations-webhook-add-form.index.addCustomWebhook": "Add custom webhook",
"console.views.application-integrations-webhook-add-form.index.addWebhookViaTemplate": "Add webhook for {templateName}",
"console.views.application-integrations-webhook-add-form.index.customWebhook": "Custom webhook",
- "console.views.application-integrations-webhook-edit.index.editWebhook": "Edit webhook",
- "console.views.application-integrations-webhook-edit.index.updateSuccess": "Webhook updated",
- "console.views.application-integrations-webhook-edit.index.deleteSuccess": "Webhook deleted",
- "console.views.application-integrations-webhook-edit.index.reactivateSuccess": "Webhook activated",
"console.views.application-overview.index.failedAccessOtherHostApplication": "The application you attempted to visit is registered on a different cluster and needs to be accessed using its host Console.",
"console.views.device-general-settings.application-server-form.index.skip": "Enforce skipping payload crypto",
"console.views.device-general-settings.application-server-form.index.include": "Enforce payload crypto",
@@ -895,8 +767,6 @@
"console.views.device-general-settings.messages.keysResetWarning": "You do not have sufficient rights to view end device keys. Only overwriting is allowed.",
"console.views.device-general-settings.messages.unclaimFailure": "An error occurred and the end device could not be unclaimed and deleted",
"console.views.device-general-settings.messages.validateSessionKey": "{field} must have non-zero value",
- "console.views.device-general-settings.messages.macSettingsError": "There was an error and the default MAC settings for the {freqPlan}
frequency plan could not be loaded",
- "console.views.device-general-settings.messages.fpNotFoundError": "The LoRaWAN version {lorawanVersion}
does not support the {freqPlan}
frequency plan. Please choose a different MAC version or frequency plan.",
"console.views.device-general-settings.messages.resetUsedDevNonces": "Reset used DevNonces",
"console.views.device-general-settings.messages.resetUsedDevNoncesModal": "Are you sure you want to reset the used DevNonces of this end device?{break}{break}Resetting the used DevNonces enables replay attacks using past nonces. Do not use this option unless you have reset the end device NVRAM.",
"console.views.device-general-settings.messages.resetSuccess": "Used DevNonces reset",
@@ -915,10 +785,9 @@
"console.views.device-overview.index.sessionInfo": "Session information",
"console.views.device-overview.index.pendingSessionInfo": "Session information (pending)",
"console.views.device-overview.index.latestData": "Latest data",
- "console.views.device-overview.index.rootKeys": "Root keys",
"console.views.device-overview.index.keysNotExposed": "Keys are not exposed",
"console.views.device-overview.index.failedAccessOtherHostDevice": "The end device you attempted to visit is registered on a different cluster and needs to be accessed using its host Console.",
- "console.views.device-overview.index.macData": "Download MAC data",
+ "console.views.device-overview.index.downloadMacData": "Download MAC data",
"console.views.device-overview.index.sensitiveDataWarning": "The MAC data can contain sensitive information such as session keys that can be used to decrypt messages. Do not share this information publicly .",
"console.views.device-overview.index.noSessionWarning": "The end device is currently not connected to the network (no active session). The MAC data will hence only contain the current MAC settings.",
"console.views.device-overview.index.macStateError": "There was an error and MAC state could not be included in the MAC data.",
@@ -928,7 +797,6 @@
"console.views.gateway-data.index.gtwData": "Gateway data",
"console.views.gateway-general-settings.messages.basicTitle": "Basic settings",
"console.views.gateway-general-settings.messages.basicDescription": "General settings, gateway updates and metadata",
- "console.views.gateway-general-settings.messages.lorawanTitle": "LoRaWAN options",
"console.views.gateway-general-settings.messages.lorawanDescription": "LoRaWAN network-layer settings",
"console.views.gateway-general-settings.messages.updateSuccess": "Gateway updated",
"console.views.gateway-general-settings.messages.deleteSuccess": "Gateway deleted",
@@ -958,8 +826,6 @@
"console.views.overview.index.componentStatus": "Component status",
"console.views.overview.index.versionInfo": "Version info",
"containers.collaborator-form.index.collaboratorIdPlaceholder": "Type to choose a collaborator",
- "containers.collaborator-select.index.noOptionsMessage": "No matching user or organization was found",
- "containers.collaborator-select.index.suggestions": "Suggestions",
"containers.collaborator-select.index.setYourself": "Set yourself as {name}",
"containers.fetch-table.index.errorMessage": "There was an error and the list of {entity, select, applications {applications} organizations {organizations} keys {API keys} collaborators {collaborators} devices {end devices} gateways {gateways} users {users} webhooks {webhooks} other {entities}} could not be displayed",
"lib.components.date-time.relative.justNow": "just now",
@@ -990,7 +856,6 @@
"lib.errors.error-messages.errorOccurred": "An error occurred and the request could not be completed.",
"lib.errors.error-messages.errorId": "Error ID: {errorId}
",
"lib.errors.error-messages.correlationId": "Correlation ID: {correlationId}
",
- "lib.errors.error-messages.loginFailed": "Login failed",
"lib.errors.error-messages.loginFailedDescription": "There was an error causing the login to fail. This might be due to server-side misconfiguration or a browser-cookie problem. Please try logging in again.",
"lib.errors.error-messages.loginFailedAbortDescription": "The login process was aborted during the authentication with the login provider. You can use the button below to retry logging in.",
"lib.errors.error-messages.connectionFailure": "The servers are currently unavailable. This might be due to a scheduled update or maintenance. Please check the status page (if available) for more information and try again later.",
@@ -1006,22 +871,18 @@
"lib.errors.status-code-messages.501": "Not implemented",
"lib.errors.status-code-messages.503": "Service unavailable",
"lib.errors.status-code-messages.504": "Gateway timeout",
- "lib.errors.status-code-messages.520": "Unknown error",
"lib.field-description-messages.freqPlanDescription": "A frequency plan defines data rates that your end device or gateway is setup to use. It is important that gateways and end devices within reach use the same frequency plan to be able to communicate.",
"lib.field-description-messages.freqPlanLocation": "Your end device or gateway manufacturer should provide information about the applicable frequency plan for a particular device. In some cases they are printed on the device itself but they should always be in the hardware manual or data sheet.",
"lib.field-description-messages.freqPlanAbsence": "Contact the manufacturer or reseller. Using an incorrect frequency plan will prevent traffic between devices.",
"lib.field-description-messages.devEuiDescription": "A 64 bit extended unique identifier for your end device.",
"lib.field-description-messages.devEuiLocation": "It should be provided to you by the manufacturer, or printed on the end device packaging.",
- "lib.field-description-messages.devEuiAbsence": "Contact the manufacturer or your reseller.",
"lib.field-description-messages.joinEuiDescription": "The JoinEUI (formerly called AppEUI) is a 64 bit extended unique identifier used to identify the Join Server during activation.",
"lib.field-description-messages.joinEuiLocation": "It should be provided by the end device manufacturer for pre-provisioned end devices, or by the owner of the Join Server you will use.",
"lib.field-description-messages.joinEuiAbsence": "Contact the manufacturer or your reseller. If they can not provide a JoinEUI, and your end device is programmable, it is okay to use all-zeros, but ensure that you use the same JoinEUI in your end device as you enter in The Things Stack.",
"lib.field-description-messages.appKeyDescription": "An end device specific encryption key used during OTAA to derive the AppSKey (in LoRaWAN 1.1x) or both the NwkSKey and AppSKey in LoRaWAN 1.0x.",
"lib.field-description-messages.appKeyLocation": "It is usually pre-provisioned by the end device manufacturer, but can also be created by the user.",
- "lib.field-description-messages.appKeyAbsence": "Contact the manufacturer or your reseller. If they cannot provide an AppKey, and your end device is programmable, it is okay to generate one.",
"lib.field-description-messages.nwkKeyDescription": "An end device specific encryption key used to derive the FNwkSIntKey, SNwkSIntKey, NwkSEncKey in LoRaWAN 1.1. When a LoRaWAN 1.1 capable device connects to a LoRaWAN 1.0x Network Server which does not support dual root keys (NwkKey and AppKey), the NwkKey value is used as the AppKey value.",
"lib.field-description-messages.nwkKeyLocation": "It is usually pre-provisioned by the end device manufacturer, but some end devices also allow using a user-defined value.",
- "lib.field-description-messages.nwkKeyAbsence": "Contact the manufacturer or your reseller. If they cannot provide an AppKey, and your end device is programmable, it is okay to generate one.",
"lib.field-description-messages.devIdDescription": "A unique, human-readable identifier for your end device.",
"lib.field-description-messages.devIdLocation": "We prefill this value using the previously entered DevEUI but you can use any other unique value you want. End device IDs can not be reused by multiple end devices within the same application.",
"lib.field-description-messages.joinServerDescription": "The Join Server's role is to store root keys, generate session keys, and to send those securely to the Network Server and Application Server of choice. The device contains the same root keys, which can be provisioned as part of assembly, distribution or upon installation.",
@@ -1048,31 +909,22 @@
"lib.field-description-messages.deviceModelDescription": "The particular model of your end device.",
"lib.field-description-messages.deviceHardwareVersionDescription": "The hardware version of your device.",
"lib.field-description-messages.deviceHardwareVersionLocation": "It should be provided by the manufacturer of your device, or printed on the device packaging.",
- "lib.field-description-messages.deviceHardwareVersionAbsence": "Contact the manufacturer or reseller of your device. Providing an incorrect hardware version can result in unwanted device behavior.",
"lib.field-description-messages.deviceFirmwareVersionDescription": "The version of firmware loaded on your device.",
"lib.field-description-messages.deviceFirmwareVersionLocation": "The firmware version should be provided by the manufacturer of your device, or printed on the device packaging. It may be possible to upgrade your device firmware to a known version.",
- "lib.field-description-messages.deviceFirmwareVersionAbsence": "Contact the manufacturer or reseller of your device. Providing an incorrect hardware version can result in unwanted device behavior.",
"lib.field-description-messages.activationModeDescription": "OTAA is the preferred and most secure way to connect a device. Devices perform a join-procedure with the network. ABP requires hardcoding the device address and security keys. Multicast is a virtual group of ABP devices which allows all devices to receive the same downlinks. Multicast groups do not support uplinks.",
"lib.field-description-messages.activationModeLocation": "You decide how to activate your devices. Whenever possible, use OTAA.",
"lib.field-description-messages.deviceNameDescription": "An optional human readable name to help you identify your device.",
- "lib.field-description-messages.deviceNameLocation": "You make it up, so be creative!",
"lib.field-description-messages.deviceDescDescription": "An optional description, which can also be used to save notes about the end device.",
"lib.field-description-messages.frameCounterWidthDescription": "Most devices use a 32 bit frame counter to prevent replay attacks. Devices with extremely limited resources are permitted to use 16 bit counters.",
"lib.field-description-messages.frameCounterWidthLocation": "It should be provided by the device manufacturer.",
"lib.field-description-messages.frameCounterWidthAbsence": "Contact your manufacturer or reseller. Most devices use 32 bit counters. Selecting the wrong value will produce errors once the Up or Down frame counter exceeds 16 bits and rolls over.",
"lib.field-description-messages.rx2DataRateIndexDescription": "The data rate used for the second reception window used by this end device to receive downlinks.",
- "lib.field-description-messages.rx2DataRateIndexLocation": "This should be provided by the device manufacturer.",
- "lib.field-description-messages.rx2DataRateIndexAbsence": "Contact your device manufacturer or reseller.",
"lib.field-description-messages.rx2FrequencyDescription": "The frequency used for the second reception window used by this end device to receive downlinks.",
- "lib.field-description-messages.rx2FrequencyLocation": "This should be provided by the device manufacturer.",
- "lib.field-description-messages.rx2FrequencyAbsence": "Contact your device manufacturer or reseller.",
"lib.field-description-messages.gatewayIdDescription": "A unique identifier for your gateway.",
- "lib.field-description-messages.gatewayIdLocation": "You make it up, so be creative!",
"lib.field-description-messages.gatewayEuiDescription": "A 64 bit extended unique identifier for your gateway.",
"lib.field-description-messages.gatewayEuiLocation": "It should be provided to you by the manufacturer, or printed on the gateway packaging.",
"lib.field-description-messages.gatewayEuiAbsence": "Some gateways do not use EUIs. In that case, you can continue without EUI. If you are unsure, we recommend contacting the manufacturer or reseller.",
"lib.field-description-messages.gatewayNameDescription": "An optional human readable name to help you identify your gateway.",
- "lib.field-description-messages.gatewayNameLocation": "You make it up, so be creative!",
"lib.field-description-messages.gatewayDescDescription": "An optional description, which can also be used to save notes about the gateway.",
"lib.field-description-messages.requireAuthenticatedConnectionDescription": "This will only allow a gateway to connect if it uses a TLS enabled Basic Station or MQTT connection. It will not allow connections from UDP packet forwarders.",
"lib.field-description-messages.gatewayStatusDescription": "Setting your gateway status to public allows status information about the gateway to be shared with other users in the network, and with Packet Broker if enabled by the network operator.",
@@ -1121,14 +973,18 @@
"lib.field-description-messages.resetsJoinNoncesDescription": "Allowing join nonces to be reset disables any reuse checks for the device nonces and join nonces. The join requests can be replayed indefinitely when this option is enabled. This behavior is non compliant with the LoRaWAN specifications and must not be used outside of development environments.",
"lib.field-description-messages.resetUsedDevNoncesDescription": "The device nonces ensure that join requests cannot be replayed by attackers. Resetting the device nonces enables the end device to re-use a previously used nonce. Do not use this option unless you are sure that you would like the nonces to be usable again.",
"lib.field-description-messages.alcsyncDescription": "The Application Layer Clock Synchronization package is part of the LoRa TS003 specification, it synchronizes the real-time clock of an end-device to the network’s Global Positioning System (GPS) clock with near-second accuracy. It is useful for end-devices that do not have access to another accurate time source.",
- "lib.payload-formatter-messages.grpc": "GRPC service",
"lib.payload-formatter-messages.repository": "Repository",
"lib.payload-formatter-messages.javascript": "Javascript",
- "lib.payload-formatter-messages.none": "None",
"lib.payload-formatter-messages.cayennelpp": "CayenneLPP",
"lib.shared-messages.16Bit": "16 bit",
"lib.shared-messages.32Bit": "32 bit",
"lib.shared-messages.abp": "Activation by personalization (ABP)",
+ "lib.shared-messages.absenceBeCreative": "You make it up, so be creative!",
+ "lib.shared-messages.absenceContactManufacturer": "Contact your device manufacturer or reseller.",
+ "lib.shared-messages.absenceProvidedByManufacturer": "This should be provided by the device manufacturer.",
+ "lib.shared-messages.accessTokens": "Access tokens",
+ "lib.shared-messages.accountDeleteConfirmation": "Are you sure you want to delete this account?",
+ "lib.shared-messages.accountDeleted": "Account deleted",
"lib.shared-messages.accuracy": "Accuracy",
"lib.shared-messages.actions": "Actions",
"lib.shared-messages.activationMode": "Activation mode",
@@ -1137,13 +993,16 @@
"lib.shared-messages.addAttributes": "Add attributes",
"lib.shared-messages.addCollaborator": "Add collaborator",
"lib.shared-messages.addDeviceBulk": "End device bulk creation",
+ "lib.shared-messages.addHeaderEntry": "Add header entry",
+ "lib.shared-messages.addOAuthClient": "Add OAuth client",
"lib.shared-messages.addPubsub": "Add Pub/Sub",
+ "lib.shared-messages.addWebhook": "Add webhook",
"lib.shared-messages.address": "Address",
"lib.shared-messages.addressPlaceholder": "host",
- "lib.shared-messages.addWebhook": "Add webhook",
"lib.shared-messages.admin": "Admin",
- "lib.shared-messages.adminPanel": "Admin panel",
"lib.shared-messages.adminContact": "Administrative contact",
+ "lib.shared-messages.adminDescription": "Admin status enables overarching rights such as managing other users or modifying entities regardless of collaboration status",
+ "lib.shared-messages.adminPanel": "Admin panel",
"lib.shared-messages.all": "All",
"lib.shared-messages.allAdmin": "All (Admin)",
"lib.shared-messages.altitude": "Altitude",
@@ -1153,16 +1012,18 @@
"lib.shared-messages.apiKeyCounted": "{count, plural, one {API key} other {API keys}}",
"lib.shared-messages.apiKeyNamePlaceholder": "My new API key",
"lib.shared-messages.apiKeys": "API keys",
+ "lib.shared-messages.appData": "Application data",
"lib.shared-messages.appEUI": "AppEUI",
- "lib.shared-messages.appEUIJoinEUI": "AppEUI/JoinEUI",
"lib.shared-messages.appEUIDescription": "The AppEUI uniquely identifies the owner of the end device. If no AppEUI is provided by the device manufacturer (usually for development), it can be filled with zeros.",
+ "lib.shared-messages.appEUIJoinEUI": "AppEUI/JoinEUI",
"lib.shared-messages.appId": "Application ID",
"lib.shared-messages.appKey": "AppKey",
+ "lib.shared-messages.appKeyAbsence": "Contact the manufacturer or your reseller. If they cannot provide an AppKey, and your end device is programmable, it is okay to generate one.",
+ "lib.shared-messages.appSKey": "AppSKey",
"lib.shared-messages.application": "Application",
- "lib.shared-messages.applications": "Applications",
"lib.shared-messages.applicationServerAddress": "Application Server address",
+ "lib.shared-messages.applications": "Applications",
"lib.shared-messages.approve": "Approve",
- "lib.shared-messages.appSKey": "AppSKey",
"lib.shared-messages.asServerID": "Application Server ID",
"lib.shared-messages.asServerIDDescription": "The AS-ID of the Application Server to use",
"lib.shared-messages.asServerKekLabel": "Application Server KEK label",
@@ -1170,15 +1031,20 @@
"lib.shared-messages.attributeDescription": "Attributes can be used to set arbitrary information about the entity, to be used by scripts, or simply for your own organization",
"lib.shared-messages.attributeKeyValidateTooLong": "Attribute keys must have less than 32 characters",
"lib.shared-messages.attributeKeyValidateTooShort": "Attribute keys must have at least 3 characters and contain no special characters",
+ "lib.shared-messages.attributeValueValidateTooLong": "Attribute values must have less than 200 characters",
"lib.shared-messages.attributes": "Attributes",
"lib.shared-messages.attributesValidateRequired": "All attribute entry values are required. Please remove empty entries.",
"lib.shared-messages.attributesValidateTooMany": "{field} must be 10 items or fewer",
- "lib.shared-messages.attributeValueValidateTooLong": "Attribute values must have less than 200 characters",
+ "lib.shared-messages.authorization": "Authorization",
+ "lib.shared-messages.authorizationCode": "Authorization code",
"lib.shared-messages.authorizations": "Authorizations",
- "lib.shared-messages.automaticUpdates": "Automatic updates",
"lib.shared-messages.autoUpdateDescription": "Gateway can be updated automatically",
- "lib.shared-messages.backToOverview": "Back to overview",
+ "lib.shared-messages.automaticUpdates": "Automatic updates",
+ "lib.shared-messages.backTo": "Back to {siteTitle}",
"lib.shared-messages.backToLogin": "Back to login",
+ "lib.shared-messages.backToOverview": "Back to overview",
+ "lib.shared-messages.beaconFrequency": "Beacon frequency",
+ "lib.shared-messages.bearerMyAuthToken": "Bearer my-auth-token",
"lib.shared-messages.brand": "Brand",
"lib.shared-messages.cancel": "Cancel",
"lib.shared-messages.changeLocation": "Change location settings",
@@ -1186,8 +1052,11 @@
"lib.shared-messages.channel": "Channel",
"lib.shared-messages.claimAuthCode": "Claim authentication code",
"lib.shared-messages.claiming": "Claiming",
+ "lib.shared-messages.classBTimeout": "Class B timeout",
+ "lib.shared-messages.classCTimeout": "Class C timeout",
"lib.shared-messages.clear": "Clear",
"lib.shared-messages.client": "Client",
+ "lib.shared-messages.clientId": "Client ID",
"lib.shared-messages.collaborator": "Collaborator",
"lib.shared-messages.collaboratorCounted": "{count, plural, one {Collaborator} other {Collaborators}}",
"lib.shared-messages.collaboratorDeleteSuccess": "Collaborator removed",
@@ -1195,30 +1064,31 @@
"lib.shared-messages.collaboratorEditRights": "Edit rights of {collaboratorId}",
"lib.shared-messages.collaboratorId": "Collaborator ID",
"lib.shared-messages.collaboratorIdPlaceholder": "collaborator-id",
- "lib.shared-messages.collaboratorWarningSelf": "Changing your own rights could result in loss of access",
- "lib.shared-messages.collaboratorWarningAdmin": "This user is an administrator that will retain all rights to all entities regardless of collaborator status",
- "lib.shared-messages.collaboratorWarningAdminSelf": "As an administrator, you always retain all rights to all entities regardless of collaborator status",
"lib.shared-messages.collaboratorModalWarning": "Are you sure you want to remove {collaboratorId} as a collaborator?",
"lib.shared-messages.collaboratorModalWarningSelf": "Are you sure you want to remove yourself as a collaborator? Access to this entity will be lost until someone else adds you as a collaborator again.",
"lib.shared-messages.collaboratorRemove": "Collaborator remove",
- "lib.shared-messages.collaborators": "Collaborators",
"lib.shared-messages.collaboratorUpdateSuccess": "Collaborator rights updated",
+ "lib.shared-messages.collaboratorWarningAdmin": "This user is an administrator that will retain all rights to all entities regardless of collaborator status",
+ "lib.shared-messages.collaboratorWarningAdminSelf": "As an administrator, you always retain all rights to all entities regardless of collaborator status",
+ "lib.shared-messages.collaboratorWarningSelf": "Changing your own rights could result in loss of access",
+ "lib.shared-messages.collaborators": "Collaborators",
"lib.shared-messages.componentAs": "Application Server",
+ "lib.shared-messages.componentDcs": "Device Claiming Server",
"lib.shared-messages.componentEdtc": "End Device Template Converter",
+ "lib.shared-messages.componentGcs": "Gateway Claiming Server",
"lib.shared-messages.componentGs": "Gateway Server",
"lib.shared-messages.componentIs": "Identity Server",
"lib.shared-messages.componentJs": "Join Server",
"lib.shared-messages.componentNs": "Network Server",
"lib.shared-messages.componentQrg": "QR Code Generator",
- "lib.shared-messages.componentDcs": "Device Claiming Server",
- "lib.shared-messages.componentGcs": "Gateway Claiming Server",
"lib.shared-messages.confirm": "Confirm",
"lib.shared-messages.confirmPassword": "Confirm password",
+ "lib.shared-messages.confirmedDownlink": "Confirmed downlink",
"lib.shared-messages.connected": "Connected",
"lib.shared-messages.connecting": "Connecting",
"lib.shared-messages.connectionIssues": "Connection issues",
- "lib.shared-messages.contactInformation": "Contact information",
"lib.shared-messages.contactFieldPlaceholder": "Type or choose a collaborator",
+ "lib.shared-messages.contactInformation": "Contact information",
"lib.shared-messages.convertMacToEui": "Convert MAC to EUI",
"lib.shared-messages.copiedToClipboard": "Copied to clipboard!",
"lib.shared-messages.copyToClipboard": "Copy to clipboard",
@@ -1232,30 +1102,31 @@
"lib.shared-messages.data": "Data",
"lib.shared-messages.defineRights": "Define rights",
"lib.shared-messages.delayWarning": "Delay too short. The lower bound ({minimumValue}ms) will be used by the Gateway Server.",
- "lib.shared-messages.deleted": "Deleted (Admin)",
- "lib.shared-messages.deleteModalTitle": "Are you sure you want to delete {entityName} ?",
+ "lib.shared-messages.deleteModalConfirmDeletion": "Confirm deletion",
+ "lib.shared-messages.deleteModalConfirmMessage": "Please enter {entityId} to confirm the deletion.",
"lib.shared-messages.deleteModalDefaultMessage": "This will PERMANENTLY DELETE THE ENTITY ITSELF AND ALL ASSOCIATED ENTITIES , including collaborator associations. It will also NOT BE POSSIBLE TO REUSE THE ENTITY ID .",
"lib.shared-messages.deleteModalPurgeMessage": "This will PERMANENTLY DELETE THE ENTITY ITSELF AND ALL ASSOCIATED ENTITIES , including collaborator associations.",
- "lib.shared-messages.deleteModalConfirmMessage": "Please enter {entityId} to confirm the deletion.",
- "lib.shared-messages.deleteModalConfirmDeletion": "Confirm deletion",
"lib.shared-messages.deleteModalPurgeWarning": "Releasing the entity IDs will make it possible to register a new entity with the same ID. Note that this irreversible and may lead to other users gaining access to historical data of the entity if they register an entity with the same ID . Please make sure you understand the implications of purging as described here .",
- "lib.shared-messages.deleteModalReleaseIdTitle": "Entity purge (admin only)",
"lib.shared-messages.deleteModalReleaseIdLabel": "Also release entity IDs (purge)",
+ "lib.shared-messages.deleteModalReleaseIdTitle": "Entity purge (admin only)",
+ "lib.shared-messages.deleteModalTitle": "Are you sure you want to delete {entityName} ?",
+ "lib.shared-messages.deleted": "Deleted (Admin)",
"lib.shared-messages.description": "Description",
"lib.shared-messages.devAddr": "Device address",
"lib.shared-messages.devDesc": "End device description",
"lib.shared-messages.devEUI": "DevEUI",
"lib.shared-messages.devEUIBlockLimitReached": "DevEUI generation limit reached",
+ "lib.shared-messages.devID": "End device ID",
+ "lib.shared-messages.devName": "End device name",
+ "lib.shared-messages.device": "End device",
"lib.shared-messages.deviceCounted": "{count, plural, one {End device} other {End devices}}",
"lib.shared-messages.deviceDescDescription": "Optional end device description; can also be used to save notes about the end device",
"lib.shared-messages.deviceDescPlaceholder": "Description for my new end device",
+ "lib.shared-messages.deviceHardwareVersionAbsence": "Contact the manufacturer or reseller of your device. Providing an incorrect hardware version can result in unwanted device behavior.",
"lib.shared-messages.deviceIdPlaceholder": "my-new-device",
"lib.shared-messages.deviceNamePlaceholder": "My new end device",
"lib.shared-messages.deviceSimulationDisabledWarning": "Simulation is disabled for devices that skip payload crypto",
- "lib.shared-messages.device": "End device",
"lib.shared-messages.devices": "End devices",
- "lib.shared-messages.devID": "End device ID",
- "lib.shared-messages.devName": "End device name",
"lib.shared-messages.disabled": "Disabled",
"lib.shared-messages.disconnected": "Disconnected",
"lib.shared-messages.documentation": "Documentation",
@@ -1265,20 +1136,25 @@
"lib.shared-messages.downlinkFrameCount": "Downlink frame count",
"lib.shared-messages.downlinkNack": "Downlink nack",
"lib.shared-messages.downlinkPush": "Downlink push",
- "lib.shared-messages.downlinkQueued": "Downlink queued",
"lib.shared-messages.downlinkQueueInvalidated": "Downlink queue invalidated",
+ "lib.shared-messages.downlinkQueued": "Downlink queued",
"lib.shared-messages.downlinkReplace": "Downlink replace",
"lib.shared-messages.downlinkSent": "Downlink sent",
"lib.shared-messages.downlinksScheduled": "Downlinks (re)scheduled",
"lib.shared-messages.edit": "Edit",
+ "lib.shared-messages.editWebhook": "Edit webhook",
"lib.shared-messages.email": "Email",
"lib.shared-messages.emailAddress": "Email address",
+ "lib.shared-messages.emailAddressDescription": "Primary email address used for logging in; this address is not publicly visible",
+ "lib.shared-messages.emailAddressValidation": "Treat email address as validated",
+ "lib.shared-messages.emailAddressValidationDescription": "Enable this option if you do not need this user to validate the email address",
+ "lib.shared-messages.emailPlaceholder": "mail@example.com",
"lib.shared-messages.empty": "Empty",
"lib.shared-messages.enabled": "Enabled",
- "lib.shared-messages.enforceDutyCycleDescription": "Recommended for all gateways in order to respect spectrum regulations",
+ "lib.shared-messages.endDeviceModelsUnavailable": "End device models unavailable",
"lib.shared-messages.enforceDutyCycle": "Enforce duty cycle",
+ "lib.shared-messages.enforceDutyCycleDescription": "Recommended for all gateways in order to respect spectrum regulations",
"lib.shared-messages.entityId": "Entity ID",
- "lib.shared-messages.eventEnabledTypes": "Enabled event types",
"lib.shared-messages.eventDownlinkAckDesc": "A confirmed downlink is acknowledged by an end device",
"lib.shared-messages.eventDownlinkFailedDesc": "A downlink cannot be sent",
"lib.shared-messages.eventDownlinkNackDesc": "A sent confirmed downlink fails confirmation by the end device",
@@ -1287,6 +1163,7 @@
"lib.shared-messages.eventDownlinkQueuedDesc": "A downlink is added to the downlink queue",
"lib.shared-messages.eventDownlinkReplaceDesc": "A downlink is used to replace the downlink queue",
"lib.shared-messages.eventDownlinkSentDesc": "A downlink is sent to an end device or multicast group",
+ "lib.shared-messages.eventEnabledTypes": "Enabled event types",
"lib.shared-messages.eventJoinAcceptDesc": "An end device successfully joins the network and starts a session",
"lib.shared-messages.eventLocationSolvedDesc": "An integration succeeded locating the end device",
"lib.shared-messages.eventServiceDataDesc": "An integration emits an event",
@@ -1297,10 +1174,15 @@
"lib.shared-messages.exportJson": "Export as JSON",
"lib.shared-messages.external": "External",
"lib.shared-messages.externalJoinServer": "External Join Server",
+ "lib.shared-messages.fNwkSIntKey": "FNwkSIntKey",
+ "lib.shared-messages.factoryPresetFrequencies": "Factory preset frequencies",
"lib.shared-messages.fetching": "Fetching data…",
"lib.shared-messages.firmwareVersion": "Firmware version",
- "lib.shared-messages.fNwkSIntKey": "FNwkSIntKey",
+ "lib.shared-messages.format": "Format",
+ "lib.shared-messages.fpNotFoundError": "The LoRaWAN version {lorawanVersion}
does not support the {freqPlan}
frequency plan. Please choose a different MAC version or frequency plan.",
"lib.shared-messages.frameCounterWidth": "Frame counter width",
+ "lib.shared-messages.freqAdd": "Add Frequency",
+ "lib.shared-messages.frequencyPlaceholder": "e.g. 869525000 for 869,525 MHz",
"lib.shared-messages.frequencyPlan": "Frequency plan",
"lib.shared-messages.frequencyPlanWarning": "Without choosing a frequency plan, packets from the gateway will not be correctly processed",
"lib.shared-messages.furtherResources": "Further resources",
@@ -1315,18 +1197,20 @@
"lib.shared-messages.gatewayLocationPublic": "Share location within network",
"lib.shared-messages.gatewayName": "Gateway name",
"lib.shared-messages.gatewayNamePlaceholder": "My new gateway",
- "lib.shared-messages.gateways": "Gateways",
"lib.shared-messages.gatewayScheduleDownlinkLate": "Schedule downlink late",
"lib.shared-messages.gatewayServerAddress": "Gateway Server address",
"lib.shared-messages.gatewayStatus": "Gateway status",
"lib.shared-messages.gatewayStatusPublic": "Share status within network",
"lib.shared-messages.gatewayUpdateOptions": "Gateway updates",
- "lib.shared-messages.generateAPIKeyCups": "Generate API key for CUPS",
- "lib.shared-messages.generateAPIKeyLNS": "Generate API key for LNS",
+ "lib.shared-messages.gateways": "Gateways",
"lib.shared-messages.general": "General",
"lib.shared-messages.generalInformation": "General information",
"lib.shared-messages.generalSettings": "General settings",
+ "lib.shared-messages.generateAPIKeyCups": "Generate API key for CUPS",
+ "lib.shared-messages.generateAPIKeyLNS": "Generate API key for LNS",
"lib.shared-messages.getSupport": "Get support",
+ "lib.shared-messages.grantAdminStatus": "Grant this user admin status",
+ "lib.shared-messages.grpcService": "GRPC service",
"lib.shared-messages.gsServerAddressDescription": "The address of the Gateway Server to connect to",
"lib.shared-messages.hardware": "Hardware",
"lib.shared-messages.hardwareVersion": "Hardware version",
@@ -1337,12 +1221,12 @@
"lib.shared-messages.idAlreadyExists": "ID already exists",
"lib.shared-messages.import": "Import",
"lib.shared-messages.importDevices": "Import end devices",
- "lib.shared-messages.integrations": "Integrations",
- "lib.shared-messages.invite": "Invite",
- "lib.shared-messages.joinAccept": "Join accept",
"lib.shared-messages.inputMethod": "Input method",
"lib.shared-messages.insufficientAppKeyRights": "Insufficient rights to set an AppKey",
"lib.shared-messages.insufficientNwkKeyRights": "Insufficient rights to set a NwkKey",
+ "lib.shared-messages.integrations": "Integrations",
+ "lib.shared-messages.invite": "Invite",
+ "lib.shared-messages.joinAccept": "Join accept",
"lib.shared-messages.joinEUI": "JoinEUI",
"lib.shared-messages.joinServerAddress": "Join Server address",
"lib.shared-messages.key": "key",
@@ -1359,18 +1243,19 @@
"lib.shared-messages.location": "Location",
"lib.shared-messages.locationDescription": "When set to public, the gateway location may be visible to other users of the network",
"lib.shared-messages.locationMarkerDescriptionNonUser": "This location has been set automatically from incoming (status) messages",
- "lib.shared-messages.locationMarkerDescriptionUser": "This location has been set manually (e.g. by using the \"Location\"-tab)",
"lib.shared-messages.locationMarkerDescriptionUntrusted": "This location was determined via an untrusted status message and may be inaccurate",
+ "lib.shared-messages.locationMarkerDescriptionUser": "This location has been set manually (e.g. by using the \"Location\"-tab)",
"lib.shared-messages.locationSolved": "Location solved",
+ "lib.shared-messages.locationSourceBtRssi": "Bluetooth RSSI geolocation",
+ "lib.shared-messages.locationSourceCombined": "Combined geolocation",
"lib.shared-messages.locationSourceGps": "GPS-based location",
- "lib.shared-messages.locationSourceRegistry": "Manually set location",
"lib.shared-messages.locationSourceIpGeolocation": "IP-based geolocation",
- "lib.shared-messages.locationSourceWifiRssi": "Wifi RSSI geolocation",
- "lib.shared-messages.locationSourceBtRssi": "Bluetooth RSSI geolocation",
"lib.shared-messages.locationSourceLoraRssi": "LoRa RSSI geolocation",
"lib.shared-messages.locationSourceLoraTdoa": "LoRa TDOA geolocation",
- "lib.shared-messages.locationSourceCombined": "Combined geolocation",
+ "lib.shared-messages.locationSourceRegistry": "Manually set location",
+ "lib.shared-messages.locationSourceWifiRssi": "Wifi RSSI geolocation",
"lib.shared-messages.login": "Login",
+ "lib.shared-messages.loginFailed": "Login failed",
"lib.shared-messages.logout": "Logout",
"lib.shared-messages.longitude": "Longitude",
"lib.shared-messages.longitudeDesc": "The east-west position in degrees, where 0 is the prime meridian (Greenwich)",
@@ -1380,10 +1265,12 @@
"lib.shared-messages.lorawanInformation": "LoRaWAN information",
"lib.shared-messages.lorawanOptions": "LoRaWAN options",
"lib.shared-messages.lorawanPhyVersionDescription": "The LoRaWAN PHY version of the end device",
+ "lib.shared-messages.macData": "MAC data",
+ "lib.shared-messages.macSettingsError": "There was an error and the default MAC settings for the {freqPlan}
frequency plan could not be loaded",
"lib.shared-messages.macVersion": "LoRaWAN version",
+ "lib.shared-messages.messageTypes": "Message types",
"lib.shared-messages.messages": "messages",
"lib.shared-messages.messaging": "Messaging",
- "lib.shared-messages.messageTypes": "Message types",
"lib.shared-messages.milliseconds": "milliseconds",
"lib.shared-messages.minutes": "minutes",
"lib.shared-messages.model": "Model",
@@ -1392,24 +1279,25 @@
"lib.shared-messages.multicast": "Define multicast group (ABP & Multicast)",
"lib.shared-messages.name": "Name",
"lib.shared-messages.netId": "Net ID",
- "lib.shared-messages.networks": "Networks",
+ "lib.shared-messages.networkInformation": "Network information",
"lib.shared-messages.networkServerAddress": "Network Server address",
+ "lib.shared-messages.networks": "Networks",
"lib.shared-messages.never": "Never",
"lib.shared-messages.next": "Next",
"lib.shared-messages.noActivityYet": "No activity yet",
- "lib.shared-messages.noRecentActivity": "No recent activity",
"lib.shared-messages.noDesc": "This end device has no description",
"lib.shared-messages.noEvents": "Waiting for events from {entityId} …",
"lib.shared-messages.noLocation": "No location information available",
"lib.shared-messages.noMatch": "No items found",
+ "lib.shared-messages.noMatchingUserFound": "No matching user or organization was found",
+ "lib.shared-messages.noRecentActivity": "No recent activity",
"lib.shared-messages.none": "None",
- "lib.shared-messages.normalizedPayloadSoil": "Soil",
"lib.shared-messages.normalizedPayloadAir": "Air",
+ "lib.shared-messages.normalizedPayloadSoil": "Soil",
"lib.shared-messages.normalizedPayloadWind": "Wind",
"lib.shared-messages.notAvailable": "n/a",
"lib.shared-messages.notLinked": "Not linked",
"lib.shared-messages.notSet": "Not set",
- "lib.shared-messages.nsAddress": "Network Server address",
"lib.shared-messages.nsEmptyDefault": "Leave empty to link to the Network Server in the same cluster",
"lib.shared-messages.nsServerKekLabel": "Network Server KEK label",
"lib.shared-messages.nsServerKekLabelDescription": "The KEK label of the Network Server to use for wrapping the network session key",
@@ -1417,9 +1305,9 @@
"lib.shared-messages.nwkSEncKey": "NwkSEncKey",
"lib.shared-messages.nwkSEncKeyDescription": "Network session encryption key",
"lib.shared-messages.nwkSKey": "NwkSKey",
- "lib.shared-messages.oauthClients": "OAuth clients",
- "lib.shared-messages.oauthClientId": "OAuth client ID",
"lib.shared-messages.oauthClientAuthorizations": "OAuth client authorizations",
+ "lib.shared-messages.oauthClientId": "OAuth client ID",
+ "lib.shared-messages.oauthClients": "OAuth clients",
"lib.shared-messages.offline": "Offline",
"lib.shared-messages.ok": "Ok",
"lib.shared-messages.online": "Online",
@@ -1444,6 +1332,8 @@
"lib.shared-messages.personalApiKeys": "Personal API keys",
"lib.shared-messages.phyVersion": "Regional Parameters version",
"lib.shared-messages.phyVersionDescription": "The Regional Parameters version (PHY), as provided by the device manufacturer",
+ "lib.shared-messages.pingSlotFrequency": "Ping slot frequency",
+ "lib.shared-messages.pingSlotPeriodicity": "Ping slot periodicity",
"lib.shared-messages.port": "Port",
"lib.shared-messages.privacyPolicy": "Privacy policy",
"lib.shared-messages.profileSettings": "Profile settings",
@@ -1458,56 +1348,65 @@
"lib.shared-messages.refresh": "Refresh",
"lib.shared-messages.registerEndDevice": "Register end device",
"lib.shared-messages.registerGateway": "Register gateway",
- "lib.shared-messages.replaceWebhook": "Replace webhook",
+ "lib.shared-messages.remove": "Remove",
"lib.shared-messages.removeCollaborator": "Remove collaborator",
- "lib.shared-messages.removeCollaboratorSelf": "Remove yourself as collaborator",
"lib.shared-messages.removeCollaboratorLast": "Cannot remove last collaborator",
+ "lib.shared-messages.removeCollaboratorSelf": "Remove yourself as collaborator",
+ "lib.shared-messages.replaceWebhook": "Replace webhook",
"lib.shared-messages.requireAuthenticatedConnection": "Require authenticated connection",
"lib.shared-messages.requireAuthenticatedConnectionDescription": "Controls whether this gateway may only connect if it uses an authenticated Basic Station or MQTT connection",
"lib.shared-messages.reset": "Reset",
+ "lib.shared-messages.resetWarning": "Reseting is insecure and makes your end device susceptible for replay attacks",
"lib.shared-messages.resetsFCnt": "Resets frame counters",
"lib.shared-messages.resetsJoinNonces": "Resets join nonces",
- "lib.shared-messages.resetWarning": "Reseting is insecure and makes your end device susceptible for replay attacks",
"lib.shared-messages.restartStream": "Restart stream",
"lib.shared-messages.restore": "Restore",
"lib.shared-messages.restrictedUser": "You can only set yourself as a contact. If you would like another collaborator set as contact, please contact this collaborator to self-assign as contact.",
"lib.shared-messages.resume": "Resume",
"lib.shared-messages.rights": "Rights",
"lib.shared-messages.rootKeys": "Root keys",
+ "lib.shared-messages.rx1DataRateOffset": "Rx1 data rate offset",
+ "lib.shared-messages.rx1Delay": "Rx1 delay",
+ "lib.shared-messages.rx2Frequency": "Rx2 frequency",
+ "lib.shared-messages.sNwkSIKey": "SNwkSIntKey",
+ "lib.shared-messages.sNwkSIKeyDescription": "Serving network session integrity key",
"lib.shared-messages.saveChanges": "Save changes",
+ "lib.shared-messages.scanEndDevice": "Scan end device QR code",
"lib.shared-messages.scheduleAnyTimeDelay": "Schedule any time delay",
"lib.shared-messages.scheduleAnyTimeDescription": "Configure gateway delay (minimum: {minimumValue}ms, default: {defaultValue}ms)",
"lib.shared-messages.scheduleDownlinkLateDescription": "Enable server-side buffer of downlink messages",
"lib.shared-messages.search": "Search",
+ "lib.shared-messages.secondInterval": "{count, plural, one {every second} other {every {count} seconds}}",
"lib.shared-messages.seconds": "seconds",
"lib.shared-messages.secondsAbbreviated": "sec",
"lib.shared-messages.secret": "Secret",
"lib.shared-messages.secure": "Secure",
"lib.shared-messages.sendInvitation": "Send invitation",
- "lib.shared-messages.sessions": "Sessions",
"lib.shared-messages.serverUrl": "Server URL",
"lib.shared-messages.serviceData": "Service data",
+ "lib.shared-messages.sessions": "Sessions",
+ "lib.shared-messages.setLoRaCloudToken": "Set LoRa Cloud token",
"lib.shared-messages.settings": "Settings",
+ "lib.shared-messages.setup": "Setup",
"lib.shared-messages.shareGatewayInfo": "Share gateway information",
"lib.shared-messages.skipCryptoDescription": "Skip decryption of uplink payloads and encryption of downlink payloads",
"lib.shared-messages.skipCryptoPlaceholder": "Encryption/decryption disabled",
"lib.shared-messages.skipCryptoTitle": "Skip payload encryption and decryption",
- "lib.shared-messages.sNwkSIKey": "SNwkSIntKey",
- "lib.shared-messages.sNwkSIKeyDescription": "Serving network session integrity key",
"lib.shared-messages.source": "Source",
"lib.shared-messages.stable": "Stable",
"lib.shared-messages.state": "State",
- "lib.shared-messages.stateDescription": "State description",
"lib.shared-messages.stateApproved": "Approved",
+ "lib.shared-messages.stateDescription": "State description",
"lib.shared-messages.stateFlagged": "Flagged",
"lib.shared-messages.stateRejected": "Rejected",
"lib.shared-messages.stateRequested": "Requested",
"lib.shared-messages.stateSuspended": "Suspended",
"lib.shared-messages.status": "Status",
"lib.shared-messages.statusDescription": "The status of this gateway may be visible to other users",
- "lib.shared-messages.statusUnknown": "Status unknown",
"lib.shared-messages.statusPage": "Status page",
+ "lib.shared-messages.statusUnknown": "Status unknown",
"lib.shared-messages.success": "Success",
+ "lib.shared-messages.suggestions": "Suggestions",
"lib.shared-messages.supportsClassB": "Supports class B",
"lib.shared-messages.supportsClassC": "Supports class C",
"lib.shared-messages.takeMeBack": "Take me back",
@@ -1524,9 +1423,10 @@
"lib.shared-messages.troubleshooting": "Troubleshooting",
"lib.shared-messages.type": "Type",
"lib.shared-messages.typeToSearch": "Type to search…",
- "lib.shared-messages.unknownHwOption": "Unknown ver.",
+ "lib.shared-messages.unexposed": "Unexposed",
"lib.shared-messages.unknown": "Unknown",
- "lib.shared-messages.unknownError": "Unknown error while generating DevEUI",
+ "lib.shared-messages.unknownError": "Unknown error",
+ "lib.shared-messages.unknownHwOption": "Unknown ver.",
"lib.shared-messages.updateChannelDescription": "Channel for gateway automatic updates",
"lib.shared-messages.updatedAt": "Last updated at",
"lib.shared-messages.uplink": "Uplink",
@@ -1534,26 +1434,34 @@
"lib.shared-messages.uplinkMessage": "Uplink message",
"lib.shared-messages.uplinkNormalized": "Normalized uplink",
"lib.shared-messages.uplinksReceived": "Uplinks received",
- "lib.shared-messages.unexposed": "Unexposed",
+ "lib.shared-messages.uploadAnImage": "Upload an image",
"lib.shared-messages.used": "{currentValue}/{maxValue} used",
+ "lib.shared-messages.useDefaultPolicy": "Use default routing policy for this network",
"lib.shared-messages.user": "User",
"lib.shared-messages.userAdd": "Add user",
"lib.shared-messages.userDelete": "Delete user",
+ "lib.shared-messages.userDescDescription": "Optional user description; can also be used to save notes about the user",
+ "lib.shared-messages.userDescription": "Description for my new user",
"lib.shared-messages.userEdit": "Edit user",
"lib.shared-messages.userId": "User ID",
+ "lib.shared-messages.userIdPlaceholder": "jane-doe",
"lib.shared-messages.userInvitations": "User invitations",
"lib.shared-messages.userManagement": "User management",
+ "lib.shared-messages.userNamePlaceholder": "Jane Doe",
+ "lib.shared-messages.userOrgId": "User / Organization ID",
"lib.shared-messages.username": "Username",
"lib.shared-messages.users": "Users",
+ "lib.shared-messages.validFrom": "Valid from",
+ "lib.shared-messages.validTo": "Valid to",
"lib.shared-messages.validateAddressFormat": "{field} must be in the format \"host\" or \"host:port\"",
"lib.shared-messages.validateApiKey": "API keys must follow the format \"NNSXS.[…].[…]\"",
"lib.shared-messages.validateDateInPast": "{field} must be a date in the future",
"lib.shared-messages.validateDelayFormat": "{field} must be a positive, whole number",
"lib.shared-messages.validateDigit": "{field} must have at least {digit} {digit, plural, one {digit} other {digits}}",
"lib.shared-messages.validateEmail": "An email address must use exactly one \"@\", one \".\" and use no special characters",
+ "lib.shared-messages.validateFreqDynamic": "{field} must be 0 for dynamic frequencies or greater than 100000Hz",
"lib.shared-messages.validateFreqNumeric": "All frequency values must be positive integers",
"lib.shared-messages.validateFreqRequired": "All frequency values are required. Please remove empty entries.",
- "lib.shared-messages.validateFreqDynamic": "{field} must be 0 for dynamic frequencies or greater than 100000Hz",
"lib.shared-messages.validateHexLength": "{field} must be a complete hex value",
"lib.shared-messages.validateIdFormat": "{field} must contain only lowercase letters, numbers and dashes (-)",
"lib.shared-messages.validateInt32": "{field} must be a whole number, negative or positive",
@@ -1575,12 +1483,13 @@
"lib.shared-messages.validateTooShort": "{field} must have at least {min} characters",
"lib.shared-messages.validateUppercase": "{field} must have at least {upper} uppercase {upper, plural, one {character} other {characters}}",
"lib.shared-messages.validateUrl": "Must be a valid URL format, contain no spaces or special characters",
- "lib.shared-messages.validFrom": "Valid from",
- "lib.shared-messages.validTo": "Valid to",
"lib.shared-messages.value": "value",
+ "lib.shared-messages.webhookActivated": "Webhook activated",
"lib.shared-messages.webhookAlreadyExistsModalMessage": "A Webhook with the ID \"{id}\" already exists. Do you wish to replace this webhook?",
"lib.shared-messages.webhookBaseUrl": "Base URL",
+ "lib.shared-messages.webhookDeleted": "Webhook deleted",
"lib.shared-messages.webhookFormat": "Webhook format",
"lib.shared-messages.webhookId": "Webhook ID",
+ "lib.shared-messages.webhookUpdated": "Webhook updated",
"lib.shared-messages.webhooks": "Webhooks"
}
diff --git a/pkg/webui/locales/ja.json b/pkg/webui/locales/ja.json
index f1e081c996..2f9f10b27d 100644
--- a/pkg/webui/locales/ja.json
+++ b/pkg/webui/locales/ja.json
@@ -4,7 +4,6 @@
"account.components.oauth-client-form.messages.clientDescPlaceholder": "新しいOAuthクライアントに関する説明",
"account.components.oauth-client-form.messages.clientDescDescription": "説明文は、クライアントをオーソライズする際にユーザーに表示されます。クライアントの目的を説明するために使用してください",
"account.components.oauth-client-form.messages.createClient": "OAuthクライアント作成",
- "account.components.oauth-client-form.messages.deleteTitle": "本当にこのアカウントを削除していいのですか?",
"account.components.oauth-client-form.messages.deleteWarning": "これにより、このOAUTH CLIENTは、永久に削除され、OAUTH IDはロックされます。 このようなエンティティを継続して使用する場合は、必ず新しいコラボレーターを割り当ててください",
"account.components.oauth-client-form.messages.purgeWarning": "このOAUTH CLIENTを永久に削除します。この操作は元に戻せません",
"account.components.oauth-client-form.messages.redirectUrls": "リダイレクトURL",
@@ -19,9 +18,7 @@
"account.components.oauth-client-form.messages.endorsedDesc": "設定されている場合、信頼性を向上させるために、承認ページでエンドースメントを視覚的に表示します",
"account.components.oauth-client-form.messages.grants": "助成金の種類",
"account.components.oauth-client-form.messages.grantsDesc": "クライアントがトークンを取得するために使用できるOAuthフロー",
- "account.components.oauth-client-form.messages.grantAuthorizationLabel": "認証コード",
"account.components.oauth-client-form.messages.grantRefreshTokenLabel": "トークンをリフレッシュする",
- "account.components.oauth-client-form.messages.grantPasswordLabel": "パスワード",
"account.components.oauth-client-form.messages.deleteClient": "OAuthクライアントを削除",
"account.components.oauth-client-form.messages.urlsPlaceholder": "https://example.com/oauth/callback",
"account.components.oauth-client-form.messages.rightsWarning": "アプリケーションの機能を提供するために必要な最小限の権利のセットのみを要求する必要があることに留意してください",
@@ -31,8 +28,6 @@
"account.components.oauth-client-form.messages.stateDescriptionDesc": "このフィールドを使用して、このOAuthクライアントの状態に関する追加情報(フラグが立った理由など)を保存することができます",
"account.components.oauth-client-form.messages.adminContactDescription": "このクライアントの管理者の連絡先情報。通常、クライアントに関する管理上の問い合わせ先を示すために使用されます。",
"account.components.oauth-client-form.messages.techContactDescription": "このクライアントの技術的な連絡先情報。通常、クライアントに関する技術/セキュリティの質問の連絡先を示すために使用されます。",
- "account.containers.authorizations-table.index.clientId": "顧客ID",
- "account.containers.authorizations-table.index.tableTitle": "OAuthクライアント認証",
"account.containers.change-password-form.index.currentPassword": "現在のパスワード",
"account.containers.change-password-form.index.newPassword": "新規パスワード",
"account.containers.change-password-form.index.newPasswordConfirm": "新規パスワード確認",
@@ -43,12 +38,8 @@
"account.containers.clients-table.index.restoreFail": "エラーが発生し、OAuthクライアントを復元できませんでした",
"account.containers.clients-table.index.purgeSuccess": "OAuthクライアントのパージ",
"account.containers.clients-table.index.purgeFail": "エラーが発生し、OAuthクライアントをパージすることができませんでした",
- "account.containers.clients-table.index.addClient": "OAuthクライアント追加",
- "account.containers.collaborators-table.index.id": "ユーザー/組織ID",
- "account.containers.collaborators-table.index.addCollaborator": "コラボレーターを追加",
"account.containers.collaborators-table.index.deleteCollaboratorError": "エラーが発生したため、コラボレーターを削除できませんでした",
"account.containers.collaborators-table.index.deleteOnlyCollaboratorError": "すべてのクライアントは、すべての権限を持つ少なくとも1人のコラボレーターを必要とするため、このコラボレーターを削除できませんでした",
- "account.containers.collaborators-table.index.removeButtonMessage": "削除",
"account.containers.oauth-client-add.index.createSuccess": "クライアント作成",
"account.containers.oauth-client-add.index.createFailure": "エラーが発生したため、クライアントを作成できませんでした",
"account.containers.oauth-client-edit.index.deleteSuccess": "OAuthクライアント削除",
@@ -61,12 +52,10 @@
"account.containers.profile-settings-form.messages.successMessage": "プロフィール更新",
"account.containers.profile-settings-form.messages.deleteAccount": "アカウント削除",
"account.containers.profile-settings-form.messages.useGravatar": "Gravatarを使用",
- "account.containers.profile-settings-form.messages.uploadAnImage": "画像アップロード",
"account.containers.profile-settings-form.messages.gravatarInfo": "利用可能な場合、メールアドレスに関連付けられた Gravatar画像を使用しています。上記のオプションを選択して別のプロフィール画像をアップロードすることができます。",
"account.containers.profile-settings-form.messages.gravatarInfoGravatarOnly": "利用可能な場合は、メールアドレスに関連付けられた Gravatarの画像を使用しています。プロフィール画像を変更するには、Gravatarのウェブサイトの指示に従ってください。",
"account.containers.profile-settings-form.messages.primaryEmailAddressDescription": "アカウントに関連付けられている主要な電子メールアドレス",
"account.containers.profile-settings-form.messages.deleteAccountError": "エラーが発生した為、アカウントを削除できませんでした。",
- "account.containers.profile-settings-form.messages.deleteAccountSuccess": "アカウント削除",
"account.containers.profile-settings-form.messages.imageRequired": "プロフィール写真として使用するファイルを選択するか、ソースとして「Gravatar」を選択してください。",
"account.containers.profile-settings-form.messages.imageUpload": "画像アップロード",
"account.containers.profile-settings-form.messages.chooseImage": "画像を選択してください…",
@@ -79,12 +68,10 @@
"account.containers.profile-settings-form.messages.deleteConfirmMessage": "アカウント削除を確認するため、ユーザーIDを入力してください",
"account.containers.sessions-table.index.deleteSessionSuccess": "セッションが正常に削除されました",
"account.containers.sessions-table.index.deleteSessionError": "エラーが発生し、セッションを削除できませんでした",
- "account.containers.sessions-table.index.sessionsTableTitle": "セッション",
"account.containers.sessions-table.index.removeButtonMessage": "このセッションを削除します",
"account.containers.sessions-table.index.noExpiryDate": "有効期限なし",
"account.containers.sessions-table.index.endSession": "このセッションを終了するには、ログアウトします",
"account.containers.sessions-table.index.currentSession": "(これは現在のセッションです)",
- "account.containers.tokens-table.index.tableTitle": "アクセストークン",
"account.containers.tokens-table.index.deleteSuccess": "アクセストークン無効化",
"account.containers.tokens-table.index.deleteFail": "エラーが発生し、アクセストークンを無効化することができませんでした",
"account.containers.tokens-table.index.deleteButton": "このアクセストークンを無効化します",
@@ -92,7 +79,6 @@
"account.containers.tokens-table.index.deleteAllFail": "エラーが発生し、アクセストークンを無効化することができませんでした",
"account.containers.tokens-table.index.deleteAllButton": "すべてのアクセストークンを無効化",
"account.containers.tokens-table.index.expires": "期限切れ",
- "account.containers.tokens-table.index.accessTokens": "アクセストークン",
"account.views.authorize.index.modalTitle": "許可申請",
"account.views.authorize.index.modalSubtitle": "{clientName}は、以下の権利の付与を要求しています。",
"account.views.authorize.index.loginInfo": "{userId}でログインしています。",
@@ -100,9 +86,7 @@
"account.views.authorize.index.authorize": "認可済 {clientName}",
"account.views.authorize.index.noDescription": "このクライアントは説明を提供していません。",
"account.views.authorize.index.allRights": "このクライアントは、現在および将来の可能なすべての権利 を要求しています。これには、ゲートウェイ、エンドデバイス、アプリケーション、およびそれらのネットワークトラフィックの読み取り、書き込み、削除が含まれます。",
- "account.views.code.index.code": "認証コード",
"account.views.code.index.codeDescription": "あなたの認証コードは:",
- "account.views.code.index.backToAccount": "{siteTitle}に戻る",
"account.views.create-account.index.registrationApproved": "正常に登録され、ログインできます。",
"account.views.create-account.index.createAccount": "アカウント作成",
"account.views.create-account.index.createANewAccount": "新規アカウント作成",
@@ -112,17 +96,13 @@
"account.views.forgot-password.index.send": "送信",
"account.views.forgot-password.index.resetPassword": "パスワードリセット",
"account.views.forgot-password.index.resetPasswordDescription": "ユーザーIDを入力して、リセット方法を記載したメールを受信してください。",
- "account.views.front-not-found.index.backToAccount": "{siteTitle}に戻る",
"account.views.login.index.createAccount": "アカウント作成",
"account.views.login.index.forgotPassword": "パスワードをお忘れですか?",
"account.views.login.index.loginToContinue": "続けるにはログインしてください。",
- "account.views.login.index.loginFailed": "ログインに失敗しました。",
- "account.views.login.index.accountDeleted": "アカウント削除",
"account.views.oauth-authorization-settings.index.deleteButton": "認可の取り消し",
"account.views.oauth-authorization-settings.index.deleteSuccess": "この認証は正常に取り消されました",
"account.views.oauth-authorization-settings.index.deleteFailure": "エラーが発生したため、この権限を取り消すことができませんでした",
"account.views.oauth-authorization-settings.index.deleteMessage": "本当にこのクライアントを認証解除していいのですか?認証が解除されると、クライアントはお客様に代わってアクションを実行することができなくなります。希望すれば、いつでもクライアントを再度承認することができます",
- "account.views.oauth-client-add.index.addClient": "OAuthクライアントを追加",
"account.views.oauth-client-authorization-overview.index.authorizationSettings": "認証の設定",
"account.views.oauth-client-authorization-overview.index.accessTokens": "アクティブ・アクセストークン",
"account.views.overview.index.accountAppInfoTitle": "いらっしゃいませ、{userId}です!👋",
@@ -131,11 +111,9 @@
"account.views.overview.index.goToConsole": "コンソールに移動します",
"account.views.profile-settings.index.profileEdit": "プロフィール編集",
"account.views.profile-settings.index.generalSettingsDescription": "お名前、プロフィール写真、メールアドレスなどの基本情報を変更します",
- "account.views.profile-settings.index.changePasswordTitle": "パスワード変更",
"account.views.profile-settings.index.changePasswordDescription": "あなたのアカウントの新規パスワードを設定します",
"account.views.session-management.index.sessionManagement": "セッション管理",
"account.views.token-login.index.loginToken": "ログイン・トークン",
- "account.views.token-login.index.loginFailed": "ログインに失敗しました",
"account.views.update-password.index.sessionRevoked": "パスワードが変更され、すべてのアクティブなセッションが取り消されました",
"account.views.validate.index.backToAccount": "アカウントに戻る",
"account.views.validate.index.contactInfoValidation": "連絡先情報の検証",
@@ -152,7 +130,6 @@
"components.file-input.index.noFileSelected": "選択されたファイルはありません",
"components.file-input.index.fileProvided": "ファイルが提供されました",
"components.file-input.index.tooBig": "選択したファイルが大きすぎます",
- "components.file-input.index.remove": "削除",
"components.form.field.tooltip.descriptionTitle": "これは何でしょう?",
"components.form.field.tooltip.locationTitle": "ここには何を入力すればよいのでしょうか?",
"components.form.field.tooltip.absenceTitle": "正しい値が見つからない場合はどうすればよいですか?",
@@ -180,7 +157,6 @@
"components.progress-bar.index.estimatedCompletion": "完成予想図{eta}",
"components.progress-bar.index.progress": "{current}を{target}",
"components.progress-bar.index.percentage": "{percentage}% 終了",
- "components.qr-modal-button.index.scanEndDevice": "エンドデバイスのQRコードを読み込む",
"components.qr-modal-button.index.scanEndDeviceContinue": "続けるにはQRコードを読み取ってください{qrScanDoc}",
"components.qr-modal-button.index.invalidData": "無効なQRコードデータです。TR005 LoRaWAN® 機器識別QRコードのみ読み取ることができますので、ご注意ください。端末によっては、関係のないQRコードが印刷されている場合があり、使用できません",
"components.qr-modal-button.index.apply": "適用",
@@ -191,7 +167,6 @@
"components.qr.input.video.index.switchCamera": "カメラを切り替える",
"components.qr.require-permission.permissionDeniedError": "パーミッションが拒否されました: カメラへのアクセスを許可するか、写真をアップロードしてください",
"components.qr.require-permission.fetchingPermission": "カメラのアクセス許可を設定してください",
- "components.qr.require-permission.uploadImage": "画像をアップロード",
"components.rights-group.index.selectAll": "全て選択",
"components.rights-group.index.outOfOwnScopeRights": "この{entityType}は、あなたが持っているよりも多くの権利を持っています。これらの権利を変更することはできません",
"components.rights-group.index.outOfOwnScopePseudoRight": "この{entityType}は、あなたが持っていないワイルドカードの権利を持っています。したがって、{entityType}は完全に削除することしかできません",
@@ -216,11 +191,11 @@
"console.components.application-general-settings-form.index.useAlcsync": "LoRaアプリケーションレイヤー・クロックシンクロパッケージの使用",
"console.components.application-general-settings-form.index.adminContactDescription": "このアプリケーションの管理者の連絡先情報。通常、アプリケーションに関する管理上の問い合わせ先を示すために使用されます。",
"console.components.application-general-settings-form.index.techContactDescription": "このアプリケーションの技術的な連絡先情報。通常、アプリケーションに関する技術/セキュリティの質問の連絡先を示すために使用されます。",
+ "console.components.default-routing-policy-form.index.doNotUseADefaultPolicy": "",
"console.components.device-import-form.index.file": "ファイル",
"console.components.device-import-form.index.formatInfo": "フォーマット情報",
"console.components.device-import-form.index.selectAFile": "テンプレートファイルを選択してください",
"console.components.device-import-form.index.fileInfoPlaceholder": "テンプレート形式を選択してください",
- "console.components.device-import-form.index.claiming": "クレーム",
"console.components.device-import-form.index.setClaimAuthCode": "クレーム認証コードの設定",
"console.components.device-import-form.index.targetedComponents": "対象となるコンポーネント",
"console.components.device-import-form.index.advancedSectionTitle": "エンドデバイスのクレームの詳細設定",
@@ -230,18 +205,16 @@
"console.components.device-import-form.index.inputMethodManual": "LoRaWANのバージョンと周波数プランを手動で入力します",
"console.components.device-import-form.index.fallbackValues": "フォールバック値",
"console.components.device-import-form.index.noFallback": "フォールバック値は設定しない",
- "console.components.downlink-form.downlink-form.insertMode": "挿入モード",
- "console.components.downlink-form.downlink-form.payloadType": "ペイロード・タイプ",
- "console.components.downlink-form.downlink-form.bytes": "バイト",
- "console.components.downlink-form.downlink-form.replace": "ダウンリンクキューの交換",
- "console.components.downlink-form.downlink-form.push": "ダウンリンクキューへのプッシュ(付け加え)",
- "console.components.downlink-form.downlink-form.confirmedDownlink": "ダウンリンク確認済み",
- "console.components.downlink-form.downlink-form.scheduleDownlink": "スケジュール ダウンリンク",
- "console.components.downlink-form.downlink-form.downlinkSuccess": "ダウンリンク予定",
- "console.components.downlink-form.downlink-form.bytesPayloadDescription": "ダウンリンクメッセージの希望ペイロードバイト数",
- "console.components.downlink-form.downlink-form.jsonPayloadDescription": "ダウンリンクメッセージのデコードされたペイロード",
- "console.components.downlink-form.downlink-form.invalidSessionWarning": "ダウンリンクは、有効なセッションを持つエンドデバイスに対してのみスケジュールすることができます。エンドデバイスがネットワークに正しく接続されていることを確認してください",
- "console.components.events.messages.payload": "ペイロード",
+ "console.components.downlink-form.index.insertMode": "挿入モード",
+ "console.components.downlink-form.index.payloadType": "ペイロード・タイプ",
+ "console.components.downlink-form.index.bytes": "バイト",
+ "console.components.downlink-form.index.replace": "ダウンリンクキューの交換",
+ "console.components.downlink-form.index.push": "ダウンリンクキューへのプッシュ(付け加え)",
+ "console.components.downlink-form.index.scheduleDownlink": "スケジュール ダウンリンク",
+ "console.components.downlink-form.index.downlinkSuccess": "ダウンリンク予定",
+ "console.components.downlink-form.index.bytesPayloadDescription": "ダウンリンクメッセージの希望ペイロードバイト数",
+ "console.components.downlink-form.index.jsonPayloadDescription": "ダウンリンクメッセージのデコードされたペイロード",
+ "console.components.downlink-form.index.invalidSessionWarning": "ダウンリンクは、有効なセッションを持つエンドデバイスに対してのみスケジュールすることができます。エンドデバイスがネットワークに正しく接続されていることを確認してください",
"console.components.events.messages.MACPayload": "MAC ペイロード",
"console.components.events.messages.devAddr": "DevAddr",
"console.components.events.messages.fPort": "FPort",
@@ -273,15 +246,14 @@
"console.components.events.messages.eventsTruncated": "古いイベントはメモリを節約するために切り捨てられています。ストリームごとの現在のイベント制限は{limit}です",
"console.components.events.messages.eventUnavailable": "このイベントはもう利用できません。メモリを節約するために切り捨てられたのでしょう",
"console.components.events.messages.verboseStream": "冗長ストリーム",
- "console.components.events.messages.confirmedDownlink": "ダウンリンク確認済み",
"console.components.events.messages.confirmedUplink": "アップリンク確認済み",
- "console.components.events.previews.shared.json-payload.index.invalid": "無効なJSON",
+ "console.components.events.previews.shared.json-payload.index.invalid": "",
"console.components.gateway-api-keys-modal.index.modalTitle": "ダウンロードゲートウェイAPIキー",
"console.components.gateway-api-keys-modal.index.buttonMessage": "キーをダウンロードしました",
"console.components.gateway-api-keys-modal.index.description": "注意:このウィンドウを閉じると、これらのAPIキーはダウンロードできなくなります。必ずダウンロードして保存してください!",
"console.components.gateway-api-keys-modal.index.downloadLns": "LNSキーをダウンロード",
"console.components.gateway-api-keys-modal.index.downloadCups": "CUPSキーをダウンロード",
- "console.components.gateway-visibility-form.index.saveDefaultGatewayVisibility": "デフォルトゲートウェイの可視性を保存",
+ "console.components.gateway-visibility-form.index.saveDefaultGatewayVisibility": "",
"console.components.location-form.index.deleteAllLocations": "すべての位置情報を削除",
"console.components.location-form.index.deleteFailure": "エラーが発生し、その場所を削除できませんでした",
"console.components.location-form.index.deleteLocation": "場所入力を削除",
@@ -297,32 +269,19 @@
"console.components.lorawan-version-input.index.phyVersionError": "地域パラメーターバージョンの取得に失敗しました",
"console.components.mac-settings-section.index.delayValue": "{count, plural, one {{count} 秒} other {{count} 秒}}",
"console.components.mac-settings-section.index.factoryPresetFreqDescription": "工場出荷時に設定されている周波数のリスト。注意:順序は尊重されます",
- "console.components.mac-settings-section.index.factoryPresetFreqTitle": "工場出荷時のプリセット周波数",
- "console.components.mac-settings-section.index.freqAdd": "周波数の追加",
- "console.components.mac-settings-section.index.frequencyPlaceholder": "例:869525000 for 869,525 MHz",
"console.components.mac-settings-section.index.advancedMacSettings": "MACの高度な設定",
- "console.components.mac-settings-section.index.pingSlotFrequencyTitle": "Pingスロット周波数",
"console.components.mac-settings-section.index.desiredPingSlotFrequencyTitle": "希望するpingスロット周波数",
"console.components.mac-settings-section.index.pingSlotPeriodicityDescription": "クラスBのpingスロットの周期性",
- "console.components.mac-settings-section.index.pingSlotPeriodicityTitle": "Pingスロットの周期性",
- "console.components.mac-settings-section.index.pingSlotPeriodicityValue": "{count, plural, one {一秒ごと} other {{count}秒ごと}}",
"console.components.mac-settings-section.index.pingSlotDataRateTitle": "Pingスロットのデータレートインデックス",
"console.components.mac-settings-section.index.desiredPingSlotDataRateTitle": "希望するpingスロットのデータレート",
"console.components.mac-settings-section.index.resetWarning": "リセットは安全ではなく、デバイスがリプレイ攻撃の影響を受けやすくなります",
- "console.components.mac-settings-section.index.resetsFCnt": "フレームカウンタのリセット",
- "console.components.mac-settings-section.index.rx1DataRateOffsetTitle": "Rx1データレート・オフセット",
"console.components.mac-settings-section.index.desiredRx1DataRateOffsetTitle": "希望するRx1データレートのオフセット値",
- "console.components.mac-settings-section.index.rx1DelayTitle": "RX1 遅延",
"console.components.mac-settings-section.index.desiredRx1DelayTitle": "希望するRx1遅延",
"console.components.mac-settings-section.index.rx2DataRateIndexTitle": "RX2データレートインデックス",
"console.components.mac-settings-section.index.desiredRx2DataRateIndexTitle": "希望するRx2データレート・インデックス",
"console.components.mac-settings-section.index.desiredRx2FrequencyTitle": "希望するRx2の周波数",
- "console.components.mac-settings-section.index.rx2FrequencyTitle": "RX2 周波数",
"console.components.mac-settings-section.index.updateSuccess": "MAC設定が更新されました",
- "console.components.mac-settings-section.index.beaconFrequency": "ビーコン周波数",
"console.components.mac-settings-section.index.desiredBeaconFrequency": "希望するビーコン周波数",
- "console.components.mac-settings-section.index.classBTimeout": "クラスBタイムアウト",
- "console.components.mac-settings-section.index.classCTimeout": "クラスCタイムアウト",
"console.components.mac-settings-section.index.maxDutyCycle": "最大デューティーサイクル",
"console.components.mac-settings-section.index.desiredMaxDutyCycle": "希望する最大デューティサイクル",
"console.components.mac-settings-section.index.adrMargin": "ADRマージン",
@@ -337,7 +296,6 @@
"console.components.mac-settings-section.index.adrAckValue": "{count, plural, one {every message} other {every {count} messages}}",
"console.components.mac-settings-section.index.statusCountPeriodicity": "ステータスカウントの周期性",
"console.components.mac-settings-section.index.statusTimePeriodicity": "ステータス時間の周期性",
- "console.components.payload-formatters-form.index.grpc": "GRPCサービス",
"console.components.payload-formatters-form.index.repository": "デバイスリポジトリのフォーマッタを使用",
"console.components.payload-formatters-form.index.customJavascipt": "カスタムJavascriptフォーマッター",
"console.components.payload-formatters-form.index.formatterType": "フォーマッタータイプ",
@@ -347,7 +305,6 @@
"console.components.payload-formatters-form.index.grpcFieldDescription": "接続先サービスのアドレス",
"console.components.payload-formatters-form.index.appFormatter": "アプリケーションペイロードフォーマッタを使用",
"console.components.payload-formatters-form.index.appFormatterWarning": "このオプションは、アップリンクとダウンリンクの両方のフォーマッタをアプリケーションリンクのデフォルトに設定します",
- "console.components.payload-formatters-form.index.setupSubTitle": "セットアップ",
"console.components.payload-formatters-form.index.defaultFormatter": " ここ をクリックすると、このアプリケーションのデフォルトのペイロードフォーマッタを変更することができます。このアプリケーションのペイロードフォーマッタは現在 `{defaultFormatter}` に設定されています",
"console.components.payload-formatters-form.index.pasteRepositoryFormatter": "リポジトリフォーマッター貼り付け",
"console.components.payload-formatters-form.index.pasteApplicationFormatter": "アプリケーションフォーマッター貼り付け",
@@ -375,9 +332,6 @@
"console.components.pubsub-form.messages.deletePubsub": "Pub/Subの削除",
"console.components.pubsub-form.messages.modalWarning": "Pub/Sub \"{pubsubId}\" を削除してもよろしいですか?Pub/Subの削除は元に戻すことができません",
"console.components.pubsub-form.messages.headers": "ヘッダー",
- "console.components.pubsub-form.messages.headersKeyPlaceholder": "認可",
- "console.components.pubsub-form.messages.headersValuePlaceholder": "担当 my-auth-token",
- "console.components.pubsub-form.messages.headersAdd": "ヘッダエントリの追加",
"console.components.pubsub-form.messages.headersValidateRequired": "すべてのヘッダーのエントリ値が必須です。空のエントリは削除してください",
"console.components.pubsub-form.messages.usernamePlaceholder": "my-username",
"console.components.pubsub-form.messages.passwordPlaceholder": "my-username",
@@ -387,9 +341,8 @@
"console.components.pubsub-form.messages.mqttConfig": "MQTT 構成",
"console.components.pubsub-form.messages.mqttClientIdPlaceholder": "my-client-id",
"console.components.pubsub-form.messages.mqttServerUrlPlaceholder": "mqtts://example.com",
- "console.components.pubsub-form.messages.serverUrl": "サーバーURL",
- "console.components.pubsub-form.messages.clientId": "クライアントID",
"console.components.pubsub-form.messages.subscribeQos": "QoSを購読",
+ "console.components.pubsub-form.messages.providerDescription": "Pub/Subプロバイダーの変更が管理者により無効化",
"console.components.pubsub-form.messages.publishQos": "QoSを発行",
"console.components.pubsub-form.messages.tlsCa": "ルート認証局証明書",
"console.components.pubsub-form.messages.tlsClientCert": "クライアント証明書",
@@ -397,27 +350,21 @@
"console.components.pubsub-form.messages.selectPemFile": ".pemファイルを選択してください…",
"console.components.pubsub-form.messages.pemFileProvided": ".pemファイルが提供されました",
"console.components.pubsub-form.messages.useCredentials": "証明書を使用",
- "console.components.pubsub-form.messages.alreadyExistsModalTitle": "IDはすでに存在します。",
"console.components.pubsub-form.messages.alreadyExistsModalMessage": "ID \"{id}\" を持つ Pub/Sub が既に存在します。このPub/Subを置き換えしますか?",
"console.components.pubsub-form.messages.replacePubsub": "Pub/Subを置き換え",
"console.components.pubsub-form.messages.useSecureConnection": "安全な接続を使用",
"console.components.pubsub-form.messages.pubsubsDescription": "Pub/Sub統合により、The Things Stack内蔵のMQTTクライアントまたはNATSクライアントを使用して、アプリケーションサーバーがトピックを公開および購読することができます。詳しくは、<リンク>Pub/Subガイドリンク>をご覧ください",
- "console.components.routing-policy-form.index.saveDefaultPolicy": "デフォルトポリシーの保存",
- "console.components.routing-policy-form.index.useDefaultPolicy": "このネットワークでデフォルトのルーティングポリシーを使用",
+ "console.components.routing-policy-form.index.saveDefaultPolicy": "",
"console.components.routing-policy-form.index.useSpecificPolicy": "ネットワーク固有のルーティングポリシーを使用",
- "console.components.routing-policy-form.index.doNotUseADefaultPolicy": "このネットワークでは、デフォルトのルーティングポリシーを使用しないでください",
"console.components.routing-policy-form.index.doNotUseAPolicy": "このネットワークには、ルーティングポリシーを使用しないでください",
- "console.components.uplink-form.uplink-form.simulateUplink": "アップリンクのシミュレーション",
- "console.components.uplink-form.uplink-form.payloadDescription": "アップリンクメッセージの希望するペイロードバイト数",
- "console.components.uplink-form.uplink-form.uplinkSuccess": "アップリンク送信済",
+ "console.components.uplink-form.index.simulateUplink": "アップリンクのシミュレーション",
+ "console.components.uplink-form.index.payloadDescription": "アップリンクメッセージの希望するペイロードバイト数",
+ "console.components.uplink-form.index.uplinkSuccess": "アップリンク送信済",
"console.components.webhook-form.index.idPlaceholder": "my-new-webhook",
"console.components.webhook-form.index.messageInfo": "有効なメッセージタイプごとに、オプションのパスをベースURLに合わせて定義することができます",
"console.components.webhook-form.index.deleteWebhook": "Webhookの削除",
"console.components.webhook-form.index.modalWarning": "webhook \"{webhookId}\"を削除してもよろしいですか?webhookの削除は元に戻すことができません",
"console.components.webhook-form.index.additionalHeaders": "追加ヘッダー",
- "console.components.webhook-form.index.headersKeyPlaceholder": "認可",
- "console.components.webhook-form.index.headersValuePlaceholder": "担当 my-auth-token",
- "console.components.webhook-form.index.headersAdd": "ヘッダエントリの追加",
"console.components.webhook-form.index.downlinkAPIKey": "ダウンリンクAPIキー",
"console.components.webhook-form.index.downlinkAPIKeyDesc": "API キーは、\"X-Downlink-APIikey\" ヘッダーを使用してエンドポイントに提供されます",
"console.components.webhook-form.index.templateInformation": "テンプレート情報",
@@ -439,16 +386,12 @@
"console.components.webhook-template-form.index.createTemplate": "{template} Webhook作成",
"console.components.webhook-template-form.index.idPlaceholder": "my-new-{templateId}-webhook",
"console.components.webhook-template-info.index.about": "{name}について",
- "console.components.webhook-template-info.index.documentation": "ドキュメント",
"console.components.webhook-template-info.index.setupWebhook": "{name} のWebhookを設定する",
"console.components.webhook-template-info.index.editWebhook": "{name} のWebhookを編集",
- "console.containers.account-select.index.noOptionsMessage": "一致するユーザーまたは組織が見つかりませんでした",
- "console.containers.account-select.index.suggestions": "提案",
"console.containers.api-key-form.edit.deleteKey": "削除キー",
"console.containers.api-key-form.edit.modalWarning": "APIキー{keyName}を削除してもよろしいですか?APIキーの削除は元に戻すことができません",
"console.containers.api-key-form.edit.updateSuccess": "APIキーの更新",
"console.containers.api-key-form.edit.deleteSuccess": "APIキーの削除",
- "console.containers.api-keys-table.index.keyId": "キーID",
"console.containers.api-keys-table.index.grantedRights": "許諾された権利",
"console.containers.application-general-settings.index.updateSuccess": "アプリケーションを更新",
"console.containers.application-general-settings.index.deleteSuccess": "アプリケーションを削除",
@@ -466,19 +409,18 @@
"console.containers.applications-form.index.appDescPlaceholder": "私の新しいアプリケーションの説明",
"console.containers.applications-form.index.appDescDescription": "アプリケーションの説明(任意)。アプリケーションに関するメモを保存するためにも使用できます",
"console.containers.applications-form.index.appDescription": "アプリケーション内では、エンドデバイスの登録と管理、センサーデータの収集、および多くの統合オプションを使用してそれに対応することができます。<リンク>アプリケーションガイドリンク>で詳細をご覧ください",
- "console.containers.applications-form.index.createApplication": "アプリケーションの作成",
"console.containers.applications-table.index.ownedTabTitle": "所有するアプリケーション",
"console.containers.applications-table.index.restoreSuccess": "アプリケーションの復元",
"console.containers.applications-table.index.restoreFail": "エラーが発生し、アプリケーションを復元することができませんでした",
"console.containers.applications-table.index.purgeSuccess": "アプリケーションパージ済み",
"console.containers.applications-table.index.purgeFail": "エラーが発生したため、アプリケーションをパージすることができませんでした",
"console.containers.applications-table.index.otherClusterTooltip": "このアプリケーションは、別のクラスタ(`{host}`)に登録されています。このアプリケーションにアクセスするには、このアプリケーションが登録されているクラスタのコンソールを使用します",
- "console.containers.collaborators-table.index.id": "ユーザー/ 組織ID",
"console.containers.deployment-component-status.index.availableComponents": "利用可能なコンポーネント",
"console.containers.deployment-component-status.index.versionInfo": "デプロイメント",
"console.containers.deployment-component-status.index.statusPage": "ステータスページに移動します",
"console.containers.deployment-component-status.index.seeChangelog": "変更履歴を見る",
- "console.containers.dev-addr-input.index.devAddrFetchingFailure": "エラーが発生し、エンドデバイスのアドレスを生成できませんでした",
+ "console.containers.dev-addr-input.index.devAddrFetchingFailure": "",
+ "console.containers.dev-eui-component.index.unknownError": "",
"console.containers.device-importer.messages.proceed": "エンドデバイスリストへ進む",
"console.containers.device-importer.messages.retry": "ゼロからやり直す",
"console.containers.device-importer.messages.abort": "中止する",
@@ -517,105 +459,86 @@
"console.containers.device-onboarding-form.messages.confirmedClaiming": "このエンドデバイスはクレームが可能です",
"console.containers.device-onboarding-form.messages.cannotConfirmEui": "エラーが発生し、JoinEUIを確認することができませんでした。後ほど再度お試しください",
"console.containers.device-onboarding-form.messages.classCapabilities": "LoRaWANクラスの機能追加",
- "console.containers.device-onboarding-form.messages.submitTitle": "エンドデバイスの登録",
"console.containers.device-onboarding-form.messages.afterRegistration": "登録完了後",
"console.containers.device-onboarding-form.messages.singleRegistration": "登録されたエンドデバイスを表示",
"console.containers.device-onboarding-form.messages.multipleRegistration": "このタイプのエンドデバイスをもう1台登録",
"console.containers.device-onboarding-form.messages.createSuccess": "エンドデバイス登録済み",
"console.containers.device-onboarding-form.messages.deviceIdDescription": "この値は、DevEUIを使用して自動的にプリフィルドされます",
"console.containers.device-onboarding-form.messages.onboardingDisabled": "デバイスのオンボーディングは、Network Server、Application Server、Join Serverが有効になっているデプロイメントでのみ実行可能です。個々のコンポーネントにデバイスを登録するには、CLIを使用してください",
- "console.containers.device-onboarding-form.messages.beaconFrequency": "ビーコン周波数",
- "console.containers.device-onboarding-form.messages.rx1DataRateOffsetTitle": "Rx1 データレートオフセット",
- "console.containers.device-onboarding-form.messages.rx1DelayTitle": "Rx1 遅延",
- "console.containers.device-onboarding-form.messages.factoryPresetFreqTitle": "工場出荷時のプリセット周波数",
- "console.containers.device-onboarding-form.messages.freqAdd": "周波数を追加",
- "console.containers.device-onboarding-form.messages.frequencyPlaceholder": "例:869,525MHzの場合は869525000",
- "console.containers.device-onboarding-form.messages.pingSlotPeriodicityTitle": "Pingスロットの周期性",
- "console.containers.device-onboarding-form.messages.pingSlotPeriodicityValue": "{count, plural, one {every second} other {every {count} seconds}}",
"console.containers.device-onboarding-form.messages.pingSlotDataRateTitle": "Pingスロットのデータレート",
- "console.containers.device-onboarding-form.messages.pingSlotFrequencyTitle": "Pingスロットの周波数",
"console.containers.device-onboarding-form.messages.rx2DataRateIndexTitle": "Rx2 データレート",
- "console.containers.device-onboarding-form.messages.rx2FrequencyTitle": "Rx2 周波数",
- "console.containers.device-onboarding-form.messages.classBTimeout": "クラスBタイムアウト",
- "console.containers.device-onboarding-form.messages.classCTimeout": "クラスCタイムアウト",
"console.containers.device-onboarding-form.messages.defaultNetworksSettings": "ネットワークのデフォルトMAC設定を使用",
"console.containers.device-onboarding-form.messages.clusterSettings": "クラスター設定",
"console.containers.device-onboarding-form.messages.networkDefaults": "ネットワークのデフォルト",
"console.containers.device-onboarding-form.messages.hasEndDeviceQR": "あなたのエンドデバイスにLoRaWAN®デバイス識別QRコードはありますか?それをスキャンすることで、オンボーディングをスピードアップすることができます",
"console.containers.device-onboarding-form.messages.deviceGuide": "デバイス登録のヘルプ",
- "console.containers.device-onboarding-form.messages.scanEndDevice": "エンドデバイスのQRコードを読み込む",
"console.containers.device-onboarding-form.messages.deviceInfo": "QRコードデータを発見",
"console.containers.device-onboarding-form.messages.resetQRCodeData": "QRコードデータをリセット",
"console.containers.device-onboarding-form.messages.resetConfirm": "本当にQRコードデータを破棄していいのですか?スキャンした端末は登録されず、フォームがリセットされま",
"console.containers.device-onboarding-form.messages.scanSuccess": "QRコードの読み取りが成功しました",
- "console.containers.device-onboarding-form.provisioning-form-section.claiming-form-section.validation-schema.validateCode": "クレーム認証コードは数字と文字のみで構成されている必要があります",
- "console.containers.device-onboarding-form.type-form-section.manual-form-section.advanced-settings-section.advancedSectionTitle": "高度なアクティベーション、LoRaWANクラス、クラスタの設定を表示します",
- "console.containers.device-onboarding-form.type-form-section.manual-form-section.advanced-settings-section.classA": "なし(クラスAのみ)",
- "console.containers.device-onboarding-form.type-form-section.manual-form-section.advanced-settings-section.classB": "クラスB(ビーコン)",
- "console.containers.device-onboarding-form.type-form-section.manual-form-section.advanced-settings-section.classC": "クラスC(連続使用)",
- "console.containers.device-onboarding-form.type-form-section.manual-form-section.advanced-settings-section.classBandC": "クラスBとクラスC",
- "console.containers.device-onboarding-form.type-form-section.manual-form-section.advanced-settings-section.skipJsRegistration": "ジョインサーバーでの登録をスキップ",
- "console.containers.device-onboarding-form.type-form-section.manual-form-section.advanced-settings-section.multicastClassCapabilities": "マルチキャスト・ダウンリンク用LoRaWANクラス",
- "console.containers.device-onboarding-form.type-form-section.manual-form-section.advanced-settings-section.register": "手動で登録",
- "console.containers.device-onboarding-form.type-form-section.manual-form-section.advanced-settings-section.macSettingsError": "エラーが発生し、{freqPlan}
周波数プランのデフォルトMAC設定を読み込めませんでした",
- "console.containers.device-onboarding-form.type-form-section.manual-form-section.advanced-settings-section.fpNotFoundError": "The LoRaWAN version {lorawanVersion}
does not support the {freqPlan}
frequency plan.他のMACバージョンや周波数プランを選んでください",
+ "console.containers.device-onboarding-form.provisioning-form-section.claiming-form-section.validation-schema.validateCode": "",
+ "console.containers.device-onboarding-form.type-form-section.manual-form-section.advanced-settings-section.advancedSectionTitle": "",
+ "console.containers.device-onboarding-form.type-form-section.manual-form-section.advanced-settings-section.classA": "",
+ "console.containers.device-onboarding-form.type-form-section.manual-form-section.advanced-settings-section.classB": "",
+ "console.containers.device-onboarding-form.type-form-section.manual-form-section.advanced-settings-section.classC": "",
+ "console.containers.device-onboarding-form.type-form-section.manual-form-section.advanced-settings-section.classBandC": "",
+ "console.containers.device-onboarding-form.type-form-section.manual-form-section.advanced-settings-section.skipJsRegistration": "",
+ "console.containers.device-onboarding-form.type-form-section.manual-form-section.advanced-settings-section.multicastClassCapabilities": "",
+ "console.containers.device-onboarding-form.type-form-section.manual-form-section.advanced-settings-section.register": "",
"console.containers.device-onboarding-form.warning-tooltip.desiredDescription": "The network will use a different desired value of {value}
for this property.",
"console.containers.device-onboarding-form.warning-tooltip.sessionDescription": "ABP 装置は、セッションと MAC 設定でパーソナライズされます。これらのMAC設定は現在のパラメータとみなされ、ここで入力された設定と正確に一致しなければなりません。ネットワークサーバーは、LoRaWAN MACコマンドでMAC状態を希望する状態に変更するために希望するパラメータを使用します。エンドデバイスを登録した後に、一般設定ページを使用して希望する設定を更新することができます",
"console.containers.device-payload-formatters.messages.defaultFormatter": " こちら をクリックすると、このアプリケーションのデフォルトのペイロードフォーマッターを変更できます",
"console.containers.device-payload-formatters.messages.mayNotViewLink": "このアプリケーションのリンク情報を表示することは許可されていません。これには、このアプリケーションのデフォルトのペイロードフォーマッタを見ることも含まれます",
- "console.containers.device-profile-section.device-card.device-card.productWebsite": "製品ウェブサイト",
- "console.containers.device-profile-section.device-card.device-card.dataSheet": "データシート",
- "console.containers.device-profile-section.device-card.device-card.classA": "クラスA",
- "console.containers.device-profile-section.device-card.device-card.classB": "クラスB",
- "console.containers.device-profile-section.device-card.device-card.classC": "クラスC",
+ "console.containers.device-profile-section.device-card.index.productWebsite": "",
+ "console.containers.device-profile-section.device-card.index.dataSheet": "",
+ "console.containers.device-profile-section.device-card.index.classA": "",
+ "console.containers.device-profile-section.device-card.index.classB": "",
+ "console.containers.device-profile-section.device-card.index.classC": "",
"console.containers.device-profile-section.device-selection.band-select.index.title": "プロフィール(リージョン)",
- "console.containers.device-profile-section.device-selection.brand-select.brand-select.title": "エンドデバイスのブランド",
- "console.containers.device-profile-section.device-selection.brand-select.brand-select.warning": "エンドデバイスモデルが使用できません",
- "console.containers.device-profile-section.device-selection.brand-select.brand-select.noOptionsMessage": "該当するブランドはありません",
- "console.containers.device-profile-section.device-selection.fw-version-select.fw-version-select.title": "ファームウェアのバージョン",
- "console.containers.device-profile-section.device-selection.hw-version-select.hw-version-select.title": "ハードウェアのバージョン",
- "console.containers.device-profile-section.device-selection.model-select.model-select.title": "機種",
- "console.containers.device-profile-section.device-selection.model-select.model-select.warning": "エンドデバイスモデルが使用できません",
- "console.containers.device-profile-section.device-selection.model-select.model-select.noOptionsMessage": "該当する機種がありません",
+ "console.containers.device-profile-section.device-selection.brand-select.index.title": "",
+ "console.containers.device-profile-section.device-selection.brand-select.index.noOptionsMessage": "",
+ "console.containers.device-profile-section.device-selection.fw-version-select.index.title": "",
+ "console.containers.device-profile-section.device-selection.hw-version-select.index.title": "",
+ "console.containers.device-profile-section.device-selection.model-select.index.noOptionsMessage": "",
"console.containers.device-profile-section.hints.other-hint.hintTitle": "お客様のエンドデバイスはすぐに追加されます!",
"console.containers.device-profile-section.hints.other-hint.hintMessage": "申し訳ありませんが、あなたのデバイスはまだLoRaWANデバイスリポジトリの一部ではありません。エンドデバイスの製造元が提供する情報(製品のデータシートなど)を使用して、上記のenter end device specifics manuallyオプションを使用することができます。また、デバイスの追加に関するドキュメントも参照してください",
- "console.containers.device-profile-section.hints.progress-hint.hintMessage": "あなたの正確なエンドデバイスを見つけることができませんか? ここで助けを得て、上のオプションでエンドデバイスの仕様を手動で入力してみてください。",
- "console.containers.device-profile-section.hints.progress-hint.hintNoSupportMessage": "あなたの正確なエンドデバイスを見つけることができませんか? 上のオプションでエンドデバイスの仕様を手動で入力してみてください",
+ "console.containers.device-profile-section.hints.progress-hint.hintMessage": "",
+ "console.containers.device-profile-section.hints.progress-hint.hintNoSupportMessage": "",
"console.containers.device-template-format-select.index.title": "ファイルフォーマット",
"console.containers.device-template-format-select.index.warning": "エンドデバイスのテンプレートフォーマットが利用できません",
- "console.containers.device-title-section.device-title-section.uplinkDownlinkTooltip": "前回のフレームカウンタリセット以降、このエンドデバイスの送信アップリンクと受信ダウンリンクの数です",
- "console.containers.device-title-section.device-title-section.lastSeenAvailableTooltip": "ネットワークがこのエンドデバイスの最後のアクティビティを登録してから経過した時間です。これは、送信されたアップリンク、確認されたダウンリンク、または(再)参加要求から判断されます。{lineBreak}最後のアクティビティは{lastActivityInfo}で受信します",
- "console.containers.device-title-section.device-title-section.noActivityTooltip": "ネットワークは、このエンドデバイスからのアクティビティをまだ登録していません。これは、エンドデバイスがまだメッセージを送信していないか、EUIや周波数の不一致など、ネットワークで処理できないメッセージしか送信していないことを意味する可能性があります",
+ "console.containers.device-title-section.index.uplinkDownlinkTooltip": "前回のフレームカウンタリセット以降、このエンドデバイスの送信アップリンクと受信ダウンリンクの数です",
+ "console.containers.device-title-section.index.lastSeenAvailableTooltip": "ネットワークがこのエンドデバイスの最後のアクティビティを登録してから経過した時間です。これは、送信されたアップリンク、確認されたダウンリンク、または(再)参加要求から判断されます。{lineBreak}最後のアクティビティは{lastActivityInfo}で受信します",
+ "console.containers.device-title-section.index.noActivityTooltip": "ネットワークは、このエンドデバイスからのアクティビティをまだ登録していません。これは、エンドデバイスがまだメッセージを送信していないか、EUIや周波数の不一致など、ネットワークで処理できないメッセージしか送信していないことを意味する可能性があります",
"console.containers.devices-table.index.otherClusterTooltip": "このエンドデバイスは、別のクラスタ(`{host}`)に登録されています。このデバイスにアクセスするには、このエンドデバイスが登録されているクラスタのコンソールを使用します",
- "console.containers.freq-plans-select.index.title": "周波数プラン",
- "console.containers.freq-plans-select.index.warning": "周波数プランはご利用いただけません",
- "console.containers.freq-plans-select.index.none": "周波数プランを設定しないでください",
- "console.containers.gateway-connection.gateway-connection.lastSeenAvailableTooltip": "ネットワークがこのゲートウェイの最後のアクティビティを登録してから経過した時間です。これは、このゲートウェイの受信したアップリンク、または送信したステータスメッセージから決定されます",
- "console.containers.gateway-connection.gateway-connection.disconnectedTooltip": "ゲートウェイは現在、ゲートウェイサーバーとの TCP 接続を確立していません。まれに)UDPベースのゲートウェイの場合、これはゲートウェイが過去30秒以内にpull/pushデータ要求を開始しなかったことを意味することもあります",
- "console.containers.gateway-connection.gateway-connection.connectedTooltip": "このゲートウェイはゲートウェイサーバーに接続されていますが、ネットワークはまだゲートウェイからのアクティビティ(アップリンクやステータスメッセージの送信)を登録していません",
- "console.containers.gateway-connection.gateway-connection.otherClusterTooltip": "このゲートウェイは、このクラスタのメッセージを処理しない外部のゲートウェイサーバーに接続されています。そのため、このゲートウェイからのアクティビティを見ることはできません",
- "console.containers.gateway-connection.gateway-connection.messageCountTooltip": "最後の(再)接続以降、このゲートウェイの受信アップリンクと送信ダウンリンクの量です。ゲートウェイの種類によっては、頻繁に再接続するため、カウンタがリセットされることに注意してください",
- "console.containers.gateway-location-form.gateway-location-form.updateLocationFromStatus": "ステータスメッセージから更新",
- "console.containers.gateway-location-form.gateway-location-form.updateLocationFromStatusDescription": "受信ステータスメッセージに基づいて、このゲートウェイの位置を更新します",
- "console.containers.gateway-location-form.gateway-location-form.setGatewayLocation": "ゲートウェイアンテナ位置の設定",
- "console.containers.gateway-location-form.gateway-location-form.locationSource": "位置情報ソース",
- "console.containers.gateway-location-form.gateway-location-form.locationPrivacy": "位置情報プライバシー",
- "console.containers.gateway-location-form.gateway-location-form.placement": "配置",
- "console.containers.gateway-location-form.gateway-location-form.indoor": "屋内",
- "console.containers.gateway-location-form.gateway-location-form.outdoor": "屋外",
- "console.containers.gateway-location-form.gateway-location-form.locationFromStatusMessage": "ステータスメッセージから自動的に位置情報を設定",
- "console.containers.gateway-location-form.gateway-location-form.setLocationManually": "位置情報を手動で設定",
- "console.containers.gateway-location-form.gateway-location-form.noLocationSetInfo": "このゲートウェイには位置情報が設定されていません",
+ "console.containers.freq-plans-select.utils.warning": "",
+ "console.containers.freq-plans-select.utils.none": "",
+ "console.containers.freq-plans-select.utils.selectFrequencyPlan": "",
+ "console.containers.freq-plans-select.utils.addFrequencyPlan": "",
+ "console.containers.freq-plans-select.utils.frequencyPlanDescription": "",
+ "console.containers.gateway-connection.index.lastSeenAvailableTooltip": "ネットワークがこのゲートウェイの最後のアクティビティを登録してから経過した時間です。これは、このゲートウェイの受信したアップリンク、または送信したステータスメッセージから決定されます",
+ "console.containers.gateway-connection.index.disconnectedTooltip": "ゲートウェイは現在、ゲートウェイサーバーとの TCP 接続を確立していません。まれに)UDPベースのゲートウェイの場合、これはゲートウェイが過去30秒以内にpull/pushデータ要求を開始しなかったことを意味することもあります",
+ "console.containers.gateway-connection.index.connectedTooltip": "このゲートウェイはゲートウェイサーバーに接続されていますが、ネットワークはまだゲートウェイからのアクティビティ(アップリンクやステータスメッセージの送信)を登録していません",
+ "console.containers.gateway-connection.index.otherClusterTooltip": "このゲートウェイは、このクラスタのメッセージを処理しない外部のゲートウェイサーバーに接続されています。そのため、このゲートウェイからのアクティビティを見ることはできません",
+ "console.containers.gateway-connection.index.messageCountTooltip": "最後の(再)接続以降、このゲートウェイの受信アップリンクと送信ダウンリンクの量です。ゲートウェイの種類によっては、頻繁に再接続するため、カウンタがリセットされることに注意してください",
+ "console.containers.gateway-location-form.index.updateLocationFromStatus": "",
+ "console.containers.gateway-location-form.index.updateLocationFromStatusDescription": "",
+ "console.containers.gateway-location-form.index.setGatewayLocation": "",
+ "console.containers.gateway-location-form.index.locationSource": "",
+ "console.containers.gateway-location-form.index.locationPrivacy": "",
+ "console.containers.gateway-location-form.index.placement": "",
+ "console.containers.gateway-location-form.index.indoor": "",
+ "console.containers.gateway-location-form.index.outdoor": "",
+ "console.containers.gateway-location-form.index.locationFromStatusMessage": "",
+ "console.containers.gateway-location-form.index.setLocationManually": "",
+ "console.containers.gateway-location-form.index.noLocationSetInfo": "",
"console.containers.gateway-onboarding-form.gateway-provisioning-form.gateway-registration-form-section.index.requireAuthenticatedConnectionDescription": "{packetBrokerURL}など、他のネットワーク参加者が見ることができる情報を選択します",
"console.containers.gateway-onboarding-form.gateway-provisioning-form.gateway-registration-form-section.index.shareGatewayInfoDescription": "ゲートウェイが{loraBasicStationURL}で駆動している場合など、このオプションを選択します",
- "console.containers.gateway-onboarding-form.gateway-provisioning-form.gateway-registration-form-section.index.generateAPIKeyCups": "CUPS用APIキー生成",
- "console.containers.gateway-onboarding-form.gateway-provisioning-form.gateway-registration-form-section.index.generateAPIKeyLNS": "LNS用APIキー生成",
+ "console.containers.gateway-onboarding-form.gateway-provisioning-form.gateway-registration-form-section.validation-schema.validateEntry": "",
"console.containers.gateways-table.index.ownedTabTitle": "所有するゲートウェイ",
"console.containers.gateways-table.index.restoreSuccess": "ゲートウェイが復旧",
"console.containers.gateways-table.index.restoreFail": "エラーが発生し、ゲートウェイを復元することができませんでした",
"console.containers.gateways-table.index.purgeSuccess": "ゲートウェイをパージ",
"console.containers.gateways-table.index.purgeFail": "エラーが発生したため、ゲートウェイをパージすることができませんでした",
- "console.containers.invite-user-form.index.emailPlaceholder": "mail@example.com",
"console.containers.invite-user-form.index.invitationsDescription": "電子メールアドレスを提供することで、このネットワークにユーザーを招待することができます。その後、その人には、あなたのネットワークに参加するための方法が書かれたメールが届きます",
"console.containers.log-back-in-modal.index.modalTitle": "もう一度サインインしてください",
"console.containers.log-back-in-modal.index.modalMessage": "コンソールからサインアウトされました。リロードを押して、コンソールに再度ログインすることができます",
@@ -624,11 +547,9 @@
"console.containers.lora-cloud-das-form.index.fPortSetTitle": "FPortセット",
"console.containers.lora-cloud-das-form.index.fPortSetDescription": "LoRa Cloud Modemサービスで使用するF-Port値(1-223)のカンマ区切りリスト",
"console.containers.lora-cloud-das-form.index.modemEncoding": "LoRa Edge参照トラッカー(Modem-E)エンコーディング",
- "console.containers.lora-cloud-das-form.index.setLoRaCloudToken": "LoRa Cloudトークンを設定する",
"console.containers.lora-cloud-das-form.index.deleteWarning": "本当にLoRa Cloud ModemおよびGeolocationサービストークンを削除しますか?この操作は元に戻すことができません。",
"console.containers.lora-cloud-das-form.index.fPortSetValidationFormat": "FPortは1から223の間の数値、または1から223の間の数値のカンマ区切りリストでなければなりません",
"console.containers.lora-cloud-gls-form.index.tokenDescription": "LoRa Cloud内で設定されたGeolocationアクセストークン",
- "console.containers.lora-cloud-gls-form.index.setLoRaCloudToken": "LoRa Cloudトークンの設定",
"console.containers.lora-cloud-gls-form.index.deleteWarning": "LoRaCloud Geolocationトークンを本当に削除しますか?この操作は元に戻せません",
"console.containers.lora-cloud-gls-form.index.queryType": "クエリータイプ",
"console.containers.lora-cloud-gls-form.index.queryTypeDescription": "どのようなジオロケーションクエリーを使用すべきですか",
@@ -642,77 +563,46 @@
"console.containers.move-away-modal.move-away-modal.modalMessage": "本当にこのままでよいのですか?あなたの現在の変更はまだ保存されていません",
"console.containers.network-information-container.index.openSourceInfo": "現在、The Things Stack Open Sourceを使用しています。The Things Stack Cloudを使用することで、さらなる機能を利用できます。",
"console.containers.network-information-container.index.plansButton": "The Things Stack Cloudを始めましょう",
- "console.containers.network-information-container.registry-totals.applicationsUsed": "使用アプリケーション",
- "console.containers.network-information-container.registry-totals.gatewaysUsed": "使用ゲートウェイ",
- "console.containers.network-information-container.registry-totals.registeredUsers": "登録ユーザー",
- "console.containers.network-information-container.registry-totals.endDevicesAdded": "エンドデバイスの追加",
- "console.containers.organization-form.form.orgDescPlaceholder": "新しい組織の説明",
- "console.containers.organization-form.form.orgDescDescription": "組織の説明(任意)。組織に関するメモを保存するためにも使用できます",
- "console.containers.organization-form.form.orgIdPlaceholder": "my-new-organization",
- "console.containers.organization-form.form.orgNamePlaceholder": "私の新組織",
- "console.containers.organization-form.form.adminContactDescription": "この組織の管理者連絡先情報。通常、組織に関する管理的な質問をするべき連絡先を示すために使用されます。",
- "console.containers.organization-form.form.techContactDescription": "この組織の技術連絡先情報。通常、組織に関する技術/セキュリティの質問をするべき連絡先を示すために使用されます。",
- "console.containers.organization-form.update.deleteOrg": "組織を削除",
- "console.containers.organization-form.update.updateSuccess": "組織が更新されました",
- "console.containers.organization-form.update.deleteSuccess": "削除された組織",
+ "console.containers.network-information-container.registry-totals.applicationsUsed": "",
+ "console.containers.network-information-container.registry-totals.gatewaysUsed": "",
+ "console.containers.network-information-container.registry-totals.registeredUsers": "",
+ "console.containers.network-information-container.registry-totals.endDevicesAdded": "",
+ "console.containers.organization-form.form.orgDescPlaceholder": "",
+ "console.containers.organization-form.form.orgDescDescription": "",
+ "console.containers.organization-form.form.orgIdPlaceholder": "",
+ "console.containers.organization-form.form.orgNamePlaceholder": "",
+ "console.containers.organization-form.form.adminContactDescription": "",
+ "console.containers.organization-form.form.techContactDescription": "",
+ "console.containers.organization-form.update.deleteOrg": "",
+ "console.containers.organization-form.update.updateSuccess": "",
+ "console.containers.organization-form.update.deleteSuccess": "",
"console.containers.organizations-table.index.restoreSuccess": "復元された組織",
"console.containers.organizations-table.index.restoreFail": "エラーが発生し、組織を復元することができませんでした",
"console.containers.organizations-table.index.purgeSuccess": "パージされた組織",
"console.containers.organizations-table.index.purgeFail": "エラーが発生したため、組織をパージすることができませんでした",
- "console.containers.owners-select.owners-select.title": "所有者",
- "console.containers.owners-select.owners-select.warning": "エラーが発生し、組織の一覧を表示できませんでした",
+ "console.containers.owners-select.index.title": "",
+ "console.containers.owners-select.index.warning": "",
"console.containers.packet-broker-networks-table.index.nonDefaultPolicies": "デフォルトでないポリシーを持つネットワーク",
"console.containers.packet-broker-networks-table.index.search": "テナントID、テナント名で検索",
"console.containers.packet-broker-networks-table.index.forwarderPolicy": "私たちに対する彼らのルーティングポリシー",
"console.containers.packet-broker-networks-table.index.homeNetworkPolicy": "それらに対する当社のルーティングポリシー",
- "console.containers.pubsub-formats-select.index.title": "Pub/Subフォーマット",
"console.containers.pubsub-formats-select.index.warning": "Pub/Subフォーマットが無効です",
- "console.containers.pubsubs-table.index.format": "フォーマット",
"console.containers.pubsubs-table.index.host": "サーバーホスト",
- "console.containers.user-data-form.add.adminLabel": "このユーザーに管理者権限を付与します",
- "console.containers.user-data-form.add.adminDescription": "管理者ステータスは、コラボレーションステータスに関係なく、他のユーザーの管理やエンティティの変更など、包括的な権利を可能にします",
- "console.containers.user-data-form.add.userDescPlaceholder": "新しいユーザーの説明",
- "console.containers.user-data-form.add.userDescDescription": "オプションのユーザー説明; ユーザーに関するメモを保存するために使用することもできます",
- "console.containers.user-data-form.add.userIdPlaceholder": "jane-doe",
- "console.containers.user-data-form.add.userNamePlaceholder": "Jane Doe",
- "console.containers.user-data-form.add.emailPlaceholder": "mail@example.com",
- "console.containers.user-data-form.add.emailAddressDescription": "ログインに使用されるプライマリメールアドレス;このアドレスは公開されません。",
- "console.containers.user-data-form.add.emailAddressValidation": "メールアドレスを認証済みとしてみなします",
- "console.containers.user-data-form.add.emailAddressValidationDescription": "このユーザーがメールアドレスの検証を行う必要がない場合は、このオプションを有効にします",
- "console.containers.user-data-form.edit.adminLabel": "このユーザーに管理者ステータスを付与",
- "console.containers.user-data-form.edit.adminDescription": "管理者ステータスは、他のユーザーの管理や、コラボレーションステータスに関係なくエンティティを変更するなどの包括的な権限を有効にします",
- "console.containers.user-data-form.edit.userDescPlaceholder": "私の新しいユーザーの説明",
- "console.containers.user-data-form.edit.userDescDescription": "オプションのユーザー説明; ユーザーに関するメモを保存するためにも使用できます",
- "console.containers.user-data-form.edit.userIdPlaceholder": "jane-doe",
- "console.containers.user-data-form.edit.userNamePlaceholder": "ジェーン・ドウ",
- "console.containers.user-data-form.edit.emailPlaceholder": "mail@example.com",
- "console.containers.user-data-form.edit.emailAddressDescription": "ログインに使用される主要なメールアドレス; このアドレスは公には表示されません",
- "console.containers.user-data-form.edit.emailAddressValidation": "メールアドレスを検証済みとして扱う",
- "console.containers.user-data-form.edit.emailAddressValidationDescription": "このユーザーにメールアドレスの検証を必要としない場合は、このオプションを有効にします",
- "console.containers.user-data-form.edit.deleteTitle": "本当にこのアカウントを削除しますか?",
- "console.containers.user-data-form.edit.deleteWarning": "これにより、このアカウントは永久に削除され、再登録のためにユーザーIDおよび電子メールがロックされます。このユーザーが所有し、他の協力者がいない関連エンティティ(ゲートウェイ、アプリケーション、エンドデバイスなど)は接続不能となり、同じIDまたはEUIを持つエンティティを再び登録することはできなくなります。このようなエンティティを継続して使用する場合は、必ず新しいコラボレーターを割り当ててください",
- "console.containers.user-data-form.edit.purgeWarning": "これにより、このアカウントは永久に削除されます。このユーザーが所有し、他の協力者がいない関連エンティティ(ゲートウェイ、アプリケーション、エンドデバイスなど)は接続不能となり、同じIDまたはEUIを持つエンティティを再び登録することはできなくなります。このようなエンティティの使用を継続する場合は、必ず新しい共同作業者を割り当ててください",
- "console.containers.user-data-form.edit.deleteConfirmMessage": "確認のため、このユーザーのユーザーIDを入力してください",
- "console.containers.user-data-form.edit.updateSuccess": "ユーザーが更新しました",
- "console.containers.user-data-form.edit.deleteSuccess": "ユーザー削除",
+ "console.containers.user-data-form.edit.deleteWarning": "",
+ "console.containers.user-data-form.edit.purgeWarning": "",
+ "console.containers.user-data-form.edit.deleteConfirmMessage": "",
+ "console.containers.user-data-form.edit.updateSuccess": "",
+ "console.containers.user-data-form.edit.deleteSuccess": "",
"console.containers.users-table.index.invite": "ユーザーを招待",
"console.containers.users-table.index.revokeInvitation": "この招待を取り消し",
"console.containers.users-table.index.sentAt": "送信済み",
"console.containers.users-table.index.revokeSuccess": "招待状は正常に削除されました",
"console.containers.users-table.index.revokeError": "エラーが発生したため、招待を取り消すことができませんでした",
- "console.containers.webhook-edit.index.editWebhook": "Webhookを編集",
- "console.containers.webhook-edit.index.updateSuccess": "Webhookを更新",
- "console.containers.webhook-edit.index.deleteSuccess": "Webhookを削除",
- "console.containers.webhook-edit.index.reactivateSuccess": "Webhookの起動",
- "console.containers.webhook-formats-select.index.title": "Webhookフォーマット",
"console.containers.webhook-formats-select.index.warning": "Webhookフォーマットが無効です",
"console.containers.webhooks-table.index.templateId": "テンプレートID",
- "console.containers.webhooks-table.index.format": "フォーマット",
- "console.containers.webhooks-table.index.baseUrl": "ベースURL",
"console.containers.webhooks-table.index.healthy": "ヘルシー",
"console.containers.webhooks-table.index.pending": "保留中",
"console.containers.webhooks-table.index.requestsFailing": "リクエスト失敗",
- "console.lib.events.definitions.synthetic.error.unknown:type": "不明なエラー",
"console.lib.events.definitions.synthetic.error.unknown:preview": "未知のエラーが発生し、1つ以上のイベントを取得できませんでした",
"console.lib.events.definitions.synthetic.error.unknown:details": "コンソールでイベントストリームデータを処理中に予期しないエラーが発生しました。その結果、イベントデータが(正しく)表示されなかった可能性があります。これは内部エラーであり、ゲートウェイやエンドデバイスの故障を意味するものではありません。",
"console.lib.events.definitions.synthetic.error.network_error:type": "ネットワークエラー",
@@ -742,16 +632,13 @@
"console.lib.events.definitions.synthetic.status.filter_disabled:type": "フィルター無効",
"console.lib.events.definitions.synthetic.status.filter_disabled:preview": "以前に設定したイベントフィルターが無効になりました",
"console.lib.events.definitions.synthetic.status.filter_disabled:details": "イベントストリームがフィルタリングされなくなります。つまり、このエンティティのイベントストリームから出るすべてのイベントが表示されることになります",
- "console.lib.packet-broker.messages.applicationData": "アプリケーションデータ",
"console.lib.packet-broker.messages.applicationDataAllowDesc": "FPortが1~255のダウンリンクメッセージを許可します",
"console.lib.packet-broker.messages.applicationDataDesc": "FPort1-255でアップリンクメッセージを転送します",
- "console.lib.packet-broker.messages.joinAccept": "ジョインアクセプト",
"console.lib.packet-broker.messages.joinAcceptDesc": "ジョインアクセプトメッセージを許可",
"console.lib.packet-broker.messages.joinRequest": "ジョイン",
"console.lib.packet-broker.messages.joinRequestDesc": "ジョインリクエストメッセージの転送",
"console.lib.packet-broker.messages.localizationInformation": "ローカライズ情報",
"console.lib.packet-broker.messages.localizationInformationDesc": "フォワードゲートウェイの位置、RSSI、SNR、ファインタイムスタンプ",
- "console.lib.packet-broker.messages.macData": "MACデータ",
"console.lib.packet-broker.messages.macDataAllowDesc": "FPortが0であるダウンリンクメッセージを許可します",
"console.lib.packet-broker.messages.macDataDesc": "FPort 0 でアップリンクメッセージを転送します",
"console.lib.packet-broker.messages.signalQualityInformation": "信号品質に関する情報",
@@ -774,72 +661,61 @@
"console.lib.packet-broker.messages.doesNotAllowApplicationData": "アプリケーションデータの使用不可",
"console.lib.packet-broker.messages.uplinkPolicies": "この最上段には、このネットワークのアップリンク転送ポリシーが表示されています",
"console.lib.packet-broker.messages.downlinkPolicies": "この下段には、このネットワークのダウンリンクのポリシーが示されています",
- "console.lib.packet-broker.messages.gatewayLocationLabel": "場所",
"console.lib.packet-broker.messages.gatewayAntennaPlacementLabel": "アンテナの配置",
"console.lib.packet-broker.messages.gatewayAntennaPlacementDescription": "アンテナ配置を表示(屋内/屋外)",
"console.lib.packet-broker.messages.gatewayAntennaCountLabel": "アンテナ数",
"console.lib.packet-broker.messages.gatewayFineTimestampsLabel": "細かいタイムスタンプ",
"console.lib.packet-broker.messages.gatewayFineTimestampsDescription": "ゲートウェイが細かいタイムスタンプを生成するかどうか",
- "console.lib.packet-broker.messages.gatewayContactInfoLabel": "連絡先",
"console.lib.packet-broker.messages.gatewayContactInfoDescription": "ゲートウェイの所有者または運営者に連絡する手段を示します",
- "console.lib.packet-broker.messages.gatewayStatusLabel": "ステータス",
"console.lib.packet-broker.messages.gatewayStatusDescription": "ゲートウェイがオンラインかオフラインかを表示します",
- "console.lib.packet-broker.messages.gatewayFreqPlanLabel": "周波数プラン",
"console.lib.packet-broker.messages.gatewayPacketRatesLabel": "パケットレート",
"console.lib.packet-broker.messages.gatewayPacketRatesDescription": "受信・送信パケットレート",
- "console.store.middleware.logics.packet-broker.unauthenticatedErrorTitle": "オーソライズできません",
- "console.store.middleware.logics.packet-broker.unauthenticatedErrorMessage": "コンソールは、Packet Brokerエージェントへのリクエストを認証することができません。The Things StackのPacket Broker機能が正しく設定されていることを確認してください。上記のドキュメントを参照することで、より詳細なガイダンスが得られます",
- "console.store.middleware.logics.users.errEmailValidationActionSuccess": "確認メールが送信されました(迷惑メールフォルダも確認してください)",
- "console.store.middleware.logics.users.errEmailValidationActionFailure": "エラーが発生し、確認メールを送信できませんでした。",
- "console.store.middleware.logics.users.errEmailValidationAlreadySent": "最近、あなたのメールアドレスに確認メールが送信されました。迷惑メールフォルダも確認してください。",
- "console.views.admin-packet-broker.messages.packetBrokerInfoText": "Packet Brokerは、他のLoRaWANネットワークとトラフィックを交換(ピアリング)することで、カバレッジを共有し、ネットワーク全体のパフォーマンスを向上させるために使用することができます",
- "console.views.admin-packet-broker.messages.packetBrokerWebsite": "Packer Brokerのサイト",
- "console.views.admin-packet-broker.messages.registrationStatus": "登録状況",
- "console.views.admin-packet-broker.messages.registerNetwork": "ネットワーク登録",
- "console.views.admin-packet-broker.messages.networkVisibility": "ネットワークの可視化",
- "console.views.admin-packet-broker.messages.packetBrokerRegistrationDesc": "ご自宅のネットワークから、またはご自宅のネットワークへのピアリングを可能にするには、ご自宅のネットワークを登録する必要があります。これにより、お客様のネットワークがPacket Brokerに認識され、お客様のネットワークのピアリング動作を設定することができます",
- "console.views.admin-packet-broker.messages.packetBrokerDisabledDesc": "The Things Stackは、Packet Brokerを使用するための設定はされていません。Packet BrokerとピアリングするためのThe Things Stackのセットアップ方法については、上記のドキュメントリンクを参照してください",
- "console.views.admin-packet-broker.messages.packetBrokerRegistrationDisabledDesc": "The Things Stackは、Packet Brokerを使用するように設定されていますが、セキュリティの設定により、ここでネットワークを登録することはできません(解除)。登録の管理は、Packet Brokerにお問い合わせください。連絡先については、上記のドキュメントリンクを参照してください",
- "console.views.admin-packet-broker.messages.network": "ネットワーク: {network}",
- "console.views.admin-packet-broker.messages.homeNetworkEnabled": "ホームネットワーク有効 ",
- "console.views.admin-packet-broker.messages.homeNetworkDisabled": "ホームネットワーク無効 ",
- "console.views.admin-packet-broker.messages.forwarderEnabled": "フォワ―ダ―ネットワーク 有効 ",
- "console.views.admin-packet-broker.messages.forwarderDisabled": "フォワ―ダ―ネットワーク 無効 ",
- "console.views.admin-packet-broker.messages.listNetwork": "ネットワーク公開で一覧表示",
- "console.views.admin-packet-broker.messages.listNetworkDesc": "ネットワークをリストアップすることで、他のネットワーク管理者があなたのネットワークを見ることができます。これにより、他のネットワーク管理者は、あなたのネットワークでルーティングポリシーを簡単に設定することができます",
- "console.views.admin-packet-broker.messages.unlistNetwork": "このネットワークをアンリスト化",
- "console.views.admin-packet-broker.messages.confirmUnlist": "アンリストを確認",
- "console.views.admin-packet-broker.messages.Are you sure you want to unlist your network in Packet Broker?{lineBreak}This will hide your network. Other network administrators will not be able to see your network to configure routing policies.": "PacketBrokerに登録されていないネットワークは、本当に登録されていないのでしょうか?他のネットワーク管理者は、ルーティングポリシーを設定するためにあなたのネットワークを見ることができなくなります",
- "console.views.admin-packet-broker.messages.routingPolicyInformation": "以下のチェックボックスを使用して、ネットワークのデフォルトの転送動作を制御することができます。さらに、[ネットワーク]タブでネットワークごとのルーティングポリシーを個別に設定することもできます",
- "console.views.admin-packet-broker.messages.defaultRoutingPolicySet": "デフォルトのルーティングポリシー設定",
- "console.views.admin-packet-broker.messages.routingPolicySet": "ルーティングポリシーセット",
- "console.views.admin-packet-broker.messages.defaultRoutingPolicy": "既定のルーティングポリシー",
- "console.views.admin-packet-broker.messages.networks": "ネットワーク",
- "console.views.admin-packet-broker.messages.networkInformation": "ネットワーク情報",
- "console.views.admin-packet-broker.messages.devAddressBlock": "デバイスアドレスブロック",
- "console.views.admin-packet-broker.messages.devAddressBlocks": "デバイスアドレスブロック",
- "console.views.admin-packet-broker.messages.lastPolicyChange": "最後の方針変更",
- "console.views.admin-packet-broker.messages.networkId": "ネットワークID",
- "console.views.admin-packet-broker.messages.routingPolicyFromThisNetwork": "このネットワークの当社に対するルーティングポリシー",
- "console.views.admin-packet-broker.messages.routingPolicyToThisNetwork": "このネットワークに対するルーティングポリシーを設定します",
- "console.views.admin-packet-broker.messages.saveRoutingPolicy": "ルーティングポリシーの保存",
- "console.views.admin-packet-broker.messages.noPolicySet": "ポリシーはまだ決まっていません",
- "console.views.admin-packet-broker.messages.prefixes": "プレフィクス",
- "console.views.admin-packet-broker.messages.homeNetworkClusterId": "ホームネットワーククラスターID",
- "console.views.admin-packet-broker.messages.backToAllNetworks": "すべてのネットワークへ戻る",
- "console.views.admin-packet-broker.messages.deregisterNetwork": "このネットワークの登録解除",
- "console.views.admin-packet-broker.messages.confirmDeregister": "登録解除の確認",
- "console.views.admin-packet-broker.messages.Are you sure you want to deregister your network from Packet Broker?{lineBreak}This will permanently delete<.b> all routing policies and may stop traffic from flowing.{lineBreak}Traffic may still be forwarded to your network based on default routing policies configured by forwarders.": "Packet Brokerからネットワークの登録を解除してよろしいですか? {lineBreak}すべてのルーティングポリシーが永久に削除されるため、トラフィックが流れなくなる可能性があります。{lineBreak}フォワーダが設定したデフォルトのルーティングポリシーに基づき、トラフィックがネットワークに転送される可能性はあります",
- "console.views.admin-packet-broker.messages.defaultGatewayVisibility": "デフォルトゲートウェイの可視化",
- "console.views.admin-packet-broker.messages.gatewayVisibilityInformation": "チェックボックスを使用して、ゲートウェイの情報を表示するように制御することができます。この情報は、登録されたネットワークだけでなく、一般にも公開されることに注意してください",
- "console.views.admin-packet-broker.messages.defaultGatewayVisibilitySet": "デフォルトゲートウェイの可視化設定",
- "console.views.admin-packet-broker.messages.packetBrokerStatusPage": "Packet Broker ステータスページ",
- "console.views.admin-panel-network-information.index.title": "ネットワーク情報",
+ "console.store.middleware.logics.packet-broker.unauthenticatedErrorTitle": "",
+ "console.store.middleware.logics.packet-broker.unauthenticatedErrorMessage": "",
+ "console.store.middleware.logics.users.errEmailValidationActionSuccess": "",
+ "console.store.middleware.logics.users.errEmailValidationActionFailure": "",
+ "console.store.middleware.logics.users.errEmailValidationAlreadySent": "",
+ "console.views.admin-packet-broker.messages.packetBrokerInfoText": "",
+ "console.views.admin-packet-broker.messages.packetBrokerWebsite": "",
+ "console.views.admin-packet-broker.messages.learnMore": "",
+ "console.views.admin-packet-broker.messages.whyNetworkPeeringTitle": "",
+ "console.views.admin-packet-broker.messages.whyNetworkPeeringText": "",
+ "console.views.admin-packet-broker.messages.enbaling": "",
+ "console.views.admin-packet-broker.messages.packetBrokerDisabledDesc": "",
+ "console.views.admin-packet-broker.messages.enablePacketBroker": "",
+ "console.views.admin-packet-broker.messages.packetBrokerRegistrationDesc": "",
+ "console.views.admin-packet-broker.messages.routingConfig": "",
+ "console.views.admin-packet-broker.messages.network": "",
+ "console.views.admin-packet-broker.messages.listNetwork": "",
+ "console.views.admin-packet-broker.messages.listNetworkDesc": "",
+ "console.views.admin-packet-broker.messages.unlistNetwork": "",
+ "console.views.admin-packet-broker.messages.confirmUnlist": "",
+ "console.views.admin-packet-broker.messages.Are you sure you want to unlist your network in Packet Broker?{lineBreak}This will hide your network. Other network administrators will not be able to see your network to configure routing policies.": "",
+ "console.views.admin-packet-broker.messages.routingPolicyInformation": "",
+ "console.views.admin-packet-broker.messages.defaultRoutingPolicySet": "",
+ "console.views.admin-packet-broker.messages.routingPolicySet": "",
+ "console.views.admin-packet-broker.messages.defaultRoutingPolicy": "",
+ "console.views.admin-packet-broker.messages.devAddressBlock": "",
+ "console.views.admin-packet-broker.messages.devAddressBlocks": "",
+ "console.views.admin-packet-broker.messages.lastPolicyChange": "",
+ "console.views.admin-packet-broker.messages.networkId": "",
+ "console.views.admin-packet-broker.messages.routingPolicyFromThisNetwork": "",
+ "console.views.admin-packet-broker.messages.routingPolicyToThisNetwork": "",
+ "console.views.admin-packet-broker.messages.saveRoutingPolicy": "",
+ "console.views.admin-packet-broker.messages.noPolicySet": "",
+ "console.views.admin-packet-broker.messages.prefixes": "",
+ "console.views.admin-packet-broker.messages.homeNetworkClusterId": "",
+ "console.views.admin-packet-broker.messages.backToAllNetworks": "",
+ "console.views.admin-packet-broker.messages.deregisterNetwork": "",
+ "console.views.admin-packet-broker.messages.confirmDeregister": "",
+ "console.views.admin-packet-broker.messages.Are you sure you want to deregister your network from Packet Broker?{lineBreak}This will permanently delete<.b> all routing policies and may stop traffic from flowing.{lineBreak}Traffic may still be forwarded to your network based on default routing policies configured by forwarders.": "",
+ "console.views.admin-packet-broker.messages.defaultGatewayVisibility": "",
+ "console.views.admin-packet-broker.messages.gatewayVisibilityInformation": "",
+ "console.views.admin-packet-broker.messages.defaultGatewayVisibilitySet": "",
+ "console.views.admin-packet-broker.messages.packetBrokerStatusPage": "",
"console.views.application-add.index.appDescription": "アプリケーション内では、エンドデバイスとそのネットワークデータを登録、管理することができます。デバイス群を設定した後、多くの統合オプションの1つを使用して、関連データを外部サービスに渡します。 Adding Applications に関するガイドで詳しく説明しています",
- "console.views.application-data.index.appData": "アプリケーションデータ",
"console.views.application-integrations-lora-cloud.index.loraCloudInfoText": "LoRaWANネットワークやLoRaベースのデバイスに関連する一般的なタスクのシンプルなソリューションを可能にする付加価値の高いAPIをローラクラウドが提供します。以下からLoRaCloudのインテグレーションを設定することができます",
"console.views.application-integrations-lora-cloud.index.officialLoRaCloudDocumentation": "オフィシャル LoRa Cloud ドキュメンテーション",
- "console.views.application-integrations-lora-cloud.index.setToken": "LoRa Cloud トークンの設定",
"console.views.application-integrations-lora-cloud.index.dasDescription": "LoRa Cloud Modem and Geolocation Servicesプロトコルを使用すると、LoRaWAN対応デバイスのアプリケーション層で共通のデバイス機能を管理することができます",
"console.views.application-integrations-lora-cloud.index.glsDescription": "LoRa Cloud Geolocationは、The Things Stackと簡単に統合でき、あらゆるLoRaベースのデバイスの位置を推定することができるシンプルなクラウドAPIです",
"console.views.application-integrations-mqtt.index.publicAddress": "パブリックアドレス",
@@ -861,51 +737,45 @@
"console.views.application-integrations-webhook-add-form.index.addCustomWebhook": "カスタム Webhookを追加",
"console.views.application-integrations-webhook-add-form.index.addWebhookViaTemplate": "{templateName} Webhookを追加します",
"console.views.application-integrations-webhook-add-form.index.customWebhook": "カスタム Webhook",
- "console.views.application-integrations-webhook-edit.index.editWebhook": "ウェブフックを編集する",
- "console.views.application-integrations-webhook-edit.index.updateSuccess": "ウェブフックが更新されました",
- "console.views.application-integrations-webhook-edit.index.deleteSuccess": "ウェブフックが削除されました",
- "console.views.application-integrations-webhook-edit.index.reactivateSuccess": "ウェブフックが有効化されました",
"console.views.application-overview.index.failedAccessOtherHostApplication": "アクセスしようとしたアプリケーションは、別のクラスタに登録されており、そのホストコンソールを使用してアクセスする必要があります",
"console.views.device-general-settings.application-server-form.index.skip": "ペイロード暗号のスキップの強制",
"console.views.device-general-settings.application-server-form.index.include": "ペイロード暗号の強制",
"console.views.device-general-settings.application-server-form.index.default": "アプリケーションのデフォルトを使用",
"console.views.device-general-settings.application-server-form.index.skipCryptoTitle": "ペイロード暗号の上書き",
- "console.views.device-general-settings.identity-server-form.index.unclaimAndDeleteDevice": "エンドデバイスのアンクレームと削除",
- "console.views.device-general-settings.identity-server-form.index.deleteDevice": "エンドデバイスの削除",
- "console.views.device-general-settings.identity-server-form.index.deleteWarning": "{deviceId} \"を削除してよろしいでしょうか?この操作は元に戻すことができず、終了したデバイスIDを再利用することはできません",
- "console.views.device-general-settings.messages.isTitle": "ベーシック",
- "console.views.device-general-settings.messages.isDescription": "説明、クラスタ情報、メタデータ",
- "console.views.device-general-settings.messages.isDescriptionMissing": "アイデンティティサーバーは利用できません",
- "console.views.device-general-settings.messages.asTitle": "アプリケーションレイヤー",
- "console.views.device-general-settings.messages.asDescription": "アプリケーションレイヤーの動作とセッション",
- "console.views.device-general-settings.messages.asDescriptionMissing": "アプリケーションサーバーは利用できません",
- "console.views.device-general-settings.messages.asDescriptionOTAA": "参加したOTAAエンドデバイスのキーのみがアプリケーションサーバに保存されます",
- "console.views.device-general-settings.messages.jsTitle": "Join設定",
- "console.views.device-general-settings.messages.jsDescription": "エンドデバイスのアクティベーションのためのルートキーとネットワーク設定",
- "console.views.device-general-settings.messages.jsDescriptionMissing": "Joinサーバーは利用できません",
- "console.views.device-general-settings.messages.jsDescriptionOTAA": "ABP/マルチキャストのエンドデバイスはJoinサーバーに保存されません",
- "console.views.device-general-settings.messages.nsTitle": "ネットワークレイヤー",
- "console.views.device-general-settings.messages.nsDescription": "LoRaWANネットワーク層の設定、動作、セッション",
- "console.views.device-general-settings.messages.nsDescriptionMissing": "ネットワークサーバーは利用できません",
- "console.views.device-general-settings.messages.deleteSuccess": "エンドデバイス削除",
- "console.views.device-general-settings.messages.deleteFailure": "エラーが発生し、エンドデバイスを削除できませんでした",
- "console.views.device-general-settings.messages.activationModeUnknown": "ネットワークサーバーが利用できないため、アクティベーションモードが不明です",
- "console.views.device-general-settings.messages.notInCluster": "このクラスタに登録されていません",
- "console.views.device-general-settings.messages.updateSuccess": "エンドデバイスの更新",
- "console.views.device-general-settings.messages.keysResetWarning": "エンドデバイスのキーの閲覧は禁止されていますが、上書きは許可されています",
- "console.views.device-general-settings.messages.unclaimFailure": "エラーが発生し、エンドデバイスをアンクレイムして削除することができませんでした",
- "console.views.device-general-settings.messages.validateSessionKey": "{field}は0以外の値でなければなりません",
- "console.views.device-general-settings.messages.macSettingsError": "エラーが発生し、{freqPlan}
周波数プランのデフォルトMAC設定を読み込めませんでした",
- "console.views.device-general-settings.messages.fpNotFoundError": "The LoRaWAN version {lorawanVersion}
does not support the {freqPlan}
frequency plan. 他のMACバージョンや周波数プランを選択してください",
- "console.views.device-general-settings.messages.resetUsedDevNonces": "使用したDevNoncesをリセット",
- "console.views.device-general-settings.messages.resetUsedDevNoncesModal": "{break}{break}使用済みDevNoncesをリセットすると、過去のNoncesを使用したリプレイアタックが可能になります。エンドデバイスのNVRAMをリセットしていない限り、このオプションは使用しないでください",
- "console.views.device-general-settings.messages.resetSuccess": "中古DevNoncesリセット",
- "console.views.device-general-settings.messages.resetFailure": "エラーが発生し、使用中のDevNoncesをリセットすることができませんでした",
- "console.views.device-general-settings.network-server-form.index.resetTitle": "セッションおよびMAC状態のリセット",
- "console.views.device-general-settings.network-server-form.index.resetButtonTitle": "セッションとMACの状態をリセット",
- "console.views.device-general-settings.network-server-form.index.resetSuccess": "エンドデバイスのリセット",
- "console.views.device-general-settings.network-server-form.index.resetFailure": "エラーが発生し、エンドデバイスのセッションとMACの状態をリセットすることができませんでした",
- "console.views.device-general-settings.network-server-form.index.modalMessage": "このエンドデバイスのセッションコンテキストとMACの状態をリセットしていいですか? これにより、以下のような影響があります:For OTAA -activated end devices all session and MAC data is wiped and the end device MUST rejoin For ABP -activated end devices, session keys, device address and downlink queue are preserved, while the MAC state is reset ",
+ "console.views.device-general-settings.identity-server-form.index.unclaimAndDeleteDevice": "",
+ "console.views.device-general-settings.identity-server-form.index.deleteDevice": "",
+ "console.views.device-general-settings.identity-server-form.index.deleteWarning": "",
+ "console.views.device-general-settings.messages.isTitle": "",
+ "console.views.device-general-settings.messages.isDescription": "",
+ "console.views.device-general-settings.messages.isDescriptionMissing": "",
+ "console.views.device-general-settings.messages.asTitle": "",
+ "console.views.device-general-settings.messages.asDescription": "",
+ "console.views.device-general-settings.messages.asDescriptionMissing": "",
+ "console.views.device-general-settings.messages.asDescriptionOTAA": "",
+ "console.views.device-general-settings.messages.jsTitle": "",
+ "console.views.device-general-settings.messages.jsDescription": "",
+ "console.views.device-general-settings.messages.jsDescriptionMissing": "",
+ "console.views.device-general-settings.messages.jsDescriptionOTAA": "",
+ "console.views.device-general-settings.messages.nsTitle": "",
+ "console.views.device-general-settings.messages.nsDescription": "",
+ "console.views.device-general-settings.messages.nsDescriptionMissing": "",
+ "console.views.device-general-settings.messages.deleteSuccess": "",
+ "console.views.device-general-settings.messages.deleteFailure": "",
+ "console.views.device-general-settings.messages.activationModeUnknown": "",
+ "console.views.device-general-settings.messages.notInCluster": "",
+ "console.views.device-general-settings.messages.updateSuccess": "",
+ "console.views.device-general-settings.messages.keysResetWarning": "",
+ "console.views.device-general-settings.messages.unclaimFailure": "",
+ "console.views.device-general-settings.messages.validateSessionKey": "",
+ "console.views.device-general-settings.messages.resetUsedDevNonces": "",
+ "console.views.device-general-settings.messages.resetUsedDevNoncesModal": "",
+ "console.views.device-general-settings.messages.resetSuccess": "",
+ "console.views.device-general-settings.messages.resetFailure": "",
+ "console.views.device-general-settings.network-server-form.index.resetTitle": "",
+ "console.views.device-general-settings.network-server-form.index.resetButtonTitle": "",
+ "console.views.device-general-settings.network-server-form.index.resetSuccess": "",
+ "console.views.device-general-settings.network-server-form.index.resetFailure": "",
+ "console.views.device-general-settings.network-server-form.index.modalMessage": "",
"console.views.device-import.index.noTemplatesTitle": "エンドデバイスのテンプレートは見つかりませんでした",
"console.views.device-import.index.noTemplates": "現在、エンドデバイステンプレートは設定されていません。デバイス一括インポート機能を利用するために、エンドデバイステンプレートを設定してください。詳細については、ドキュメントを参照してください",
"console.views.device-location.index.locationInfoTitle": "エンドデバイスの位置設定の把握",
@@ -915,10 +785,9 @@
"console.views.device-overview.index.sessionInfo": "セッション情報",
"console.views.device-overview.index.pendingSessionInfo": "セッション情報(保留)",
"console.views.device-overview.index.latestData": "最新データ",
- "console.views.device-overview.index.rootKeys": "ルートキー",
"console.views.device-overview.index.keysNotExposed": "キーは露出していません",
"console.views.device-overview.index.failedAccessOtherHostDevice": "アクセスしようとしたエンドデバイスは別のクラスタに登録されているため、そのホストコンソールを使用してアクセスする必要があります",
- "console.views.device-overview.index.macData": "MACデータ",
+ "console.views.device-overview.index.downloadMacData": "",
"console.views.device-overview.index.sensitiveDataWarning": "MACデータには、メッセージの復号化に使用できるセッションキーなどの機密情報が含まれていることがあります。この情報を一般に公開しないでください!",
"console.views.device-overview.index.noSessionWarning": "エンドデバイスは現在ネットワークに接続されていない(アクティブセッションがない)。そのため、MACデータには、現在のMAC設定のみが含まれます",
"console.views.device-overview.index.macStateError": "エラーが発生し、MAC状態をMACデータに含めることができませんでした",
@@ -926,18 +795,17 @@
"console.views.device-overview.index.noSession": "このデバイスは、まだネットワークに参加していません",
"console.views.gateway-add.index.gtwOnboardingDescription": "ゲートウェイを登録して、近くのエンドデバイスとネットワーク間のデータトラフィックを可能にします。{break}(ブレイク 詳しくは、 Adding Gateways のガイドをご覧ください",
"console.views.gateway-data.index.gtwData": "ゲートウェイデータ",
- "console.views.gateway-general-settings.messages.basicTitle": "基本設定",
- "console.views.gateway-general-settings.messages.basicDescription": "一般的な設定、ゲートウェイの更新、メタデータ",
- "console.views.gateway-general-settings.messages.lorawanTitle": "LoRaWANオプション",
- "console.views.gateway-general-settings.messages.lorawanDescription": "LoRaWANネットワークレイヤー設定",
- "console.views.gateway-general-settings.messages.updateSuccess": "ゲートウェイ更新",
- "console.views.gateway-general-settings.messages.deleteSuccess": "ゲートウェイ削除",
- "console.views.gateway-general-settings.messages.deleteFailure": "ゲートウェイ削除エラー",
- "console.views.gateway-general-settings.messages.deleteGateway": "ゲートウェイの削除",
- "console.views.gateway-general-settings.messages.modalWarning": "{gtwName}を削除してよろしいでしょうか?このアクションは元に戻すことができず、ゲートウェイIDを再利用することができなくなります",
- "console.views.gateway-general-settings.messages.disablePacketBrokerForwarding": "このゲートウェイから受信したアップリンクメッセージをPacket Brokerに転送しないようにします",
- "console.views.gateway-general-settings.messages.adminContactDescription": "このゲートウェイの管理連絡先情報。通常、ゲートウェイに関する管理的な質問をする人を指すために使用されます。",
- "console.views.gateway-general-settings.messages.techContactDescription": "このゲートウェイの技術連絡先情報。通常、ゲートウェイに関する技術的/セキュリティ的な質問をする人を指すために使用されます。",
+ "console.views.gateway-general-settings.messages.basicTitle": "",
+ "console.views.gateway-general-settings.messages.basicDescription": "",
+ "console.views.gateway-general-settings.messages.lorawanDescription": "",
+ "console.views.gateway-general-settings.messages.updateSuccess": "",
+ "console.views.gateway-general-settings.messages.deleteSuccess": "",
+ "console.views.gateway-general-settings.messages.deleteFailure": "",
+ "console.views.gateway-general-settings.messages.deleteGateway": "",
+ "console.views.gateway-general-settings.messages.modalWarning": "",
+ "console.views.gateway-general-settings.messages.disablePacketBrokerForwarding": "",
+ "console.views.gateway-general-settings.messages.adminContactDescription": "",
+ "console.views.gateway-general-settings.messages.techContactDescription": "",
"console.views.gateway-overview.index.downloadGlobalConf": "global_conf.json のダウンロード",
"console.views.gateway-overview.index.globalConf": "グローバル設定",
"console.views.gateway-overview.index.globalConfFailed": "global_conf.json のダウンロードに失敗しました",
@@ -945,24 +813,22 @@
"console.views.gateway-overview.index.globalConfUnavailable": "周波数プランのないゲートウェイでは利用できません",
"console.views.organization-add.index.orgDescription": "組織は、複数のユーザーをグループ化し、そのユーザーに対して集合的な権利を割り当てるために使用されます。組織は、アプリケーションやゲートウェイのコラボレーターとして設定することができます。これにより、ユーザーのグループに対して、エンティティに対する権利の付与や取り消しを簡単に行うことができます。詳しくは、 Organization Managementのガイドをご覧ください",
"console.views.organization-data.index.orgData": "組織のデータ",
- "console.views.overview.help-link.needHelp": "ヘルプが必要ですか?私たちの{documentationLink}または{supportLink}をご覧ください",
- "console.views.overview.help-link.needHelpShort": "ヘルプが必要ですか?私たちの{link}を参照してください",
- "console.views.overview.index.createApplication": "アプリケーションの作成",
- "console.views.overview.index.createGateway": "ゲートウェイの登録",
- "console.views.overview.index.gotoApplications": "アプリケーションへ移動",
- "console.views.overview.index.gotoGateways": "ゲートウェイへ移動",
- "console.views.overview.index.welcome": "コンソールへようこそ!",
- "console.views.overview.index.welcomeBack": "おかえりなさい、{userName}! 👋",
- "console.views.overview.index.getStarted": "アプリケーションを作成したり、ゲートウェイを登録することで、すぐに始めることができます",
- "console.views.overview.index.continueWorking": "アプリケーションやゲートウェイへの誘導を行います",
- "console.views.overview.index.componentStatus": "コンポーネントの状況",
- "console.views.overview.index.versionInfo": "バージョン情報",
+ "console.views.overview.help-link.needHelp": "",
+ "console.views.overview.help-link.needHelpShort": "",
+ "console.views.overview.index.createApplication": "",
+ "console.views.overview.index.createGateway": "",
+ "console.views.overview.index.gotoApplications": "",
+ "console.views.overview.index.gotoGateways": "",
+ "console.views.overview.index.welcome": "",
+ "console.views.overview.index.welcomeBack": "",
+ "console.views.overview.index.getStarted": "",
+ "console.views.overview.index.continueWorking": "",
+ "console.views.overview.index.componentStatus": "",
+ "console.views.overview.index.versionInfo": "",
"containers.collaborator-form.index.collaboratorIdPlaceholder": "コラボレーターを選択するために入力してください",
- "containers.collaborator-select.index.noOptionsMessage": "一致するユーザーまたは組織が見つかりませんでした",
- "containers.collaborator-select.index.suggestions": "提案",
"containers.collaborator-select.index.setYourself": "自分自身を{name}として設定する",
"containers.fetch-table.index.errorMessage": "エラーが発生し、{entity, select, applications {applications} organizations {organizations} keys {API keys} collaborators {collaborators} devices {end devices} gateways {gateways} users {users} webhooks {webhooks} other {entities}}のリストを表示できませんでした。",
- "lib.components.date-time.relative.justNow": "ただ今",
+ "lib.components.date-time.relative.justNow": "",
"lib.components.init.initializing": "初期化中...",
"lib.components.with-auth.errTooFewRights": "あなたのアカウントは、コンソールを使用するための十分な権利を持っていません",
"lib.components.with-auth.errTooFewRightsTitle": "不十分な権利",
@@ -990,7 +856,6 @@
"lib.errors.error-messages.errorOccurred": "エラーが発生し、リクエストを完了することができませんでした",
"lib.errors.error-messages.errorId": "エラーID: {errorId}
",
"lib.errors.error-messages.correlationId": "相関関係ID: {correlationId}
",
- "lib.errors.error-messages.loginFailed": "ログインに失敗しました",
"lib.errors.error-messages.loginFailedDescription": "ログインに失敗するようなエラーが発生しました。これは、サーバー側の設定ミスやブラウザのCookieの問題によるものかもしれません。再度ログインをお試しください",
"lib.errors.error-messages.loginFailedAbortDescription": "ログインプロバイダとの認証中に、ログイン処理が中断されました。以下のボタンからログインを再試行することができます",
"lib.errors.error-messages.connectionFailure": "現在、サーバーが使用できない状態になっています。これは、定期的なアップデートやメンテナンスのためかもしれません。詳細については、ステータスページ(利用可能な場合)を確認し、後でもう一度試してみてください",
@@ -1006,22 +871,18 @@
"lib.errors.status-code-messages.501": "未実装",
"lib.errors.status-code-messages.503": "サービス利用不可",
"lib.errors.status-code-messages.504": "ゲートウェイのタイムアウト",
- "lib.errors.status-code-messages.520": "不明なエラー",
"lib.field-description-messages.freqPlanDescription": "周波数プランは、エンドデバイスやゲートウェイが使用するように設定されたデータレートを定義します。ゲートウェイとエンドデバイスが通信できるようにするためには、同じ周波数プランを使用することが重要です",
"lib.field-description-messages.freqPlanLocation": "エンドデバイスやゲートウェイのメーカーは、特定のデバイスに適用される周波数プランに関する情報を提供するはずです。場合によっては、デバイス自体に印刷されていることもありますが、常にハードウェアマニュアルまたはデータシートに記載されているはずです",
"lib.field-description-messages.freqPlanAbsence": "メーカーまたは再販業者にお問い合わせください。不正な周波数プランを使用すると、機器間のトラフィックが妨げられます",
"lib.field-description-messages.devEuiDescription": "エンドデバイスの64ビット拡張一意識別子です",
"lib.field-description-messages.devEuiLocation": "メーカーから提供されるか、エンドデバイスのパッケージに印刷されているはずです",
- "lib.field-description-messages.devEuiAbsence": "メーカーまたは販売店にお問い合わせください",
"lib.field-description-messages.joinEuiDescription": "JoinEUI(以前はAppEUIと呼ばれていた)は、アクティベーション時にJoin Serverを識別するために使用される64ビット拡張一意識別子です",
"lib.field-description-messages.joinEuiLocation": "あらかじめ用意されているエンドデバイスの場合はエンドデバイスの製造元から、使用するJoin Serverの所有者から提供されるはずです",
"lib.field-description-messages.joinEuiAbsence": "メーカーまたは再販業者に連絡してください。JoinEUIを提供できず、エンド・デバイスがプログラム可能な場合は、オール・ゼロを使用しても問題ありませんが、The Things Stackで入力するのと同じJoinEUIをエンド・デバイスで使用することを確認します",
"lib.field-description-messages.appKeyDescription": "OTAA中に使用され、AppSKey(LoRaWAN 1.1xの場合)またはLoRaWAN 1.0xのNwkSKeyとAppSKeyの両方を導出するエンドデバイス固有の暗号化キーです",
"lib.field-description-messages.appKeyLocation": "通常はエンドデバイスのメーカーがあらかじめ用意しているものですが、ユーザーが作成することも可能です",
- "lib.field-description-messages.appKeyAbsence": "メーカーまたは再販業者に連絡してください。AppKeyを提供できず、エンドデバイスがプログラム可能であれば、AppKeyを生成しても問題ありません",
"lib.field-description-messages.nwkKeyDescription": "LoRaWAN 1.1 の FNwkSIntKey、SNwkSIntKey、NwkSEncKey の導出に使用するエンドデバイス固有の暗号化キーです。LoRaWAN 1.1 対応デバイスが、デュアルルート鍵(NwkKey と AppKey)をサポートしない LoRaWAN 1.0x ネットワークサーバに接続する場合、NwkKey 値は AppKey 値として使用されます",
"lib.field-description-messages.nwkKeyLocation": "通常、エンドデバイスのメーカーがあらかじめ用意しているものですが、エンドデバイスによっては、ユーザー定義の値を使用することも可能です",
- "lib.field-description-messages.nwkKeyAbsence": "メーカーまたは再販業者に連絡してください。AppKeyを提供できず、エンドデバイスがプログラム可能であれば、AppKeyを生成しても問題ありません",
"lib.field-description-messages.devIdDescription": "エンドデバイスのための、人間が読めるユニークな識別子です",
"lib.field-description-messages.devIdLocation": "この値は、以前に入力されたDevEUIを使用してプレフィルしますが、他のユニークな値を使用することができます。エンドデバイスIDは、同じアプリケーション内の複数のエンドデバイスで再利用することはできません",
"lib.field-description-messages.joinServerDescription": "Join Serverの役割は、ルートキーの保存、セッションキーの生成、およびそれらを選択したネットワークサーバーとアプリケーションサーバーに安全に送信することである。デバイスには同じルート鍵が含まれており、組み立て、配布、インストール時にプロビジョニングすることができます",
@@ -1048,31 +909,22 @@
"lib.field-description-messages.deviceModelDescription": "お使いの端末の特定のモデル",
"lib.field-description-messages.deviceHardwareVersionDescription": "お使いの端末のハードウェアのバージョンです",
"lib.field-description-messages.deviceHardwareVersionLocation": "機器の製造元から提供されるか、機器のパッケージに印刷されているはずです",
- "lib.field-description-messages.deviceHardwareVersionAbsence": "お使いのデバイスの製造元または再販業者にお問い合わせください。不正なハードウェアのバージョンを提供すると、デバイスの不要な動作につながることがあります",
"lib.field-description-messages.deviceFirmwareVersionDescription": "端末に搭載されているファームウェアのバージョンです",
"lib.field-description-messages.deviceFirmwareVersionLocation": "ファームウェアのバージョンは、機器の製造元から提供されるか、機器のパッケージに印刷されているはずです。ファームウェアを既知のバージョンにアップグレードすることが可能な場合があります",
- "lib.field-description-messages.deviceFirmwareVersionAbsence": "お使いのデバイスの製造元または再販業者にお問い合わせください。不正なハードウェアのバージョンを提供すると、デバイスの不要な動作につながることがあります",
"lib.field-description-messages.activationModeDescription": "OTAAは、デバイスを接続するための好ましい、最も安全な方法である。デバイスはネットワークとの結合手続きを行う。ABPでは、デバイスのアドレスとセキュリティキーをハードコードする必要があります。マルチキャストはABPデバイスの仮想グループであり、すべてのデバイスが同じダウンリンクを受信できるようにします。マルチキャストグループはアップリンクに対応していません",
"lib.field-description-messages.activationModeLocation": "デバイスの起動方法を決めるのはあなたです。可能な限り、OTAAを使用してください",
"lib.field-description-messages.deviceNameDescription": "デバイスを識別するのに役立つ、人間が読める名前(オプション)です",
- "lib.field-description-messages.deviceNameLocation": "作るんだから、工夫してください!",
"lib.field-description-messages.deviceDescDescription": "オプションで、エンドデバイスに関するメモを保存するために使用することもできます",
"lib.field-description-messages.frameCounterWidthDescription": "ほとんどのデバイスは、リプレイ攻撃を防ぐために32ビットのフレームカウンタを使用します。リソースが極端に限られている機器では、16ビットカウンタの使用が許可されています",
"lib.field-description-messages.frameCounterWidthLocation": "デバイスメーカーから提供されるはずです",
"lib.field-description-messages.frameCounterWidthAbsence": "メーカーまたは再販業者にお問い合わせください。ほとんどのデバイスは32ビットカウンターを使用しています。間違った値を選択すると、UpまたはDownフレームカウンタが16ビットを超えてロールオーバーした時点でエラーとなります",
"lib.field-description-messages.rx2DataRateIndexDescription": "このエンドデバイスがダウンリンクを受信するために使用する第2の受信ウィンドウに使用されるデータレート",
- "lib.field-description-messages.rx2DataRateIndexLocation": "これはデバイスメーカーから提供されるべきものです",
- "lib.field-description-messages.rx2DataRateIndexAbsence": "お使いの機器のメーカーまたは販売店にお問い合わせください",
"lib.field-description-messages.rx2FrequencyDescription": "このエンドデバイスがダウンリンクを受信するために使用する第2の受信ウィンドウに使用する周波数",
- "lib.field-description-messages.rx2FrequencyLocation": "これはデバイスメーカーから提供されるべきものです",
- "lib.field-description-messages.rx2FrequencyAbsence": "お使いの機器のメーカーまたは販売店にお問い合わせください",
"lib.field-description-messages.gatewayIdDescription": "ゲートウェイのユニークな識別子",
- "lib.field-description-messages.gatewayIdLocation": "作るんだから、工夫してくださいよ!",
"lib.field-description-messages.gatewayEuiDescription": "ゲートウェイの64ビット拡張ユニーク識別子",
"lib.field-description-messages.gatewayEuiLocation": "メーカーから提供されるか、ゲートウェイのパッケージに印刷されているはずです",
"lib.field-description-messages.gatewayEuiAbsence": "EUIを使用しないゲートウェイもあります。その場合、EUIを使用せずに継続することができます。不明な場合は、メーカーやリセラーに問い合わせることをお勧めします",
"lib.field-description-messages.gatewayNameDescription": "ゲートウェイを識別するのに役立つ、人間が読める名前(オプション)です。ゲートウェイIDの代わりに、この名前を使用してゲートウェイを参照することになります",
- "lib.field-description-messages.gatewayNameLocation": "このゲートウェイを識別するのに役立つもの。ゲートウェイIDで十分な場合は、このオプションを空にしてください",
"lib.field-description-messages.gatewayDescDescription": "ゲートウェイに関するメモを保存するために使用することもできる、オプションの説明です",
"lib.field-description-messages.requireAuthenticatedConnectionDescription": "ゲートウェイがTLS対応のBasic StationまたはMQTT接続を使用している場合にのみ、接続を許可します。UDPパケットフォワーダーからの接続は許可しません",
"lib.field-description-messages.gatewayStatusDescription": "ゲートウェイのステータスをパブリックに設定すると、ゲートウェイのステータス情報をネットワーク内の他のユーザーや、ネットワークオペレータが有効な場合はPacket Brokerと共有することができます",
@@ -1121,14 +973,18 @@
"lib.field-description-messages.resetsJoinNoncesDescription": "join noncesのリセットを許可すると、デバイスnoncesとjoin noncesの再利用チェックが無効になります。このオプションを有効にすると、参加リクエストを無限に再生することができます。この動作はLoRaWANの仕様に準拠していないため、開発環境以外では使用しないでください。",
"lib.field-description-messages.resetUsedDevNoncesDescription": "デバイスのnoncesは、攻撃者によってjoin要求が再生されないことを保証します。デバイスノンスをリセットすると、エンドデバイスは以前に使用したノンスを再利用することができます。このオプションは、noncesを再び使用できるようにすることが確実でない限り、使用しないでください",
"lib.field-description-messages.alcsyncDescription": "アプリケーション層クロック同期パッケージは、LoRa TS003仕様の一部であり、エンドデバイスのリアルタイムクロックをネットワークの全地球測位システム(GPS)クロックに秒に近い精度で同期させます。これは、他の正確な時間ソースにアクセスできないエンドデバイスに便利です",
- "lib.payload-formatter-messages.grpc": "GRPCサービス",
"lib.payload-formatter-messages.repository": "レポジトリー",
"lib.payload-formatter-messages.javascript": "Javascript",
- "lib.payload-formatter-messages.none": "なし",
"lib.payload-formatter-messages.cayennelpp": "CayenneLPP",
"lib.shared-messages.16Bit": "16 bit",
"lib.shared-messages.32Bit": "32 bit",
"lib.shared-messages.abp": "Activation by personalization (ABP)",
+ "lib.shared-messages.absenceBeCreative": "",
+ "lib.shared-messages.absenceContactManufacturer": "",
+ "lib.shared-messages.absenceProvidedByManufacturer": "",
+ "lib.shared-messages.accessTokens": "アクティブ・アクセストークン",
+ "lib.shared-messages.accountDeleteConfirmation": "",
+ "lib.shared-messages.accountDeleted": "",
"lib.shared-messages.accuracy": "精度",
"lib.shared-messages.actions": "アクション",
"lib.shared-messages.activationMode": "アクティベーションモード",
@@ -1137,13 +993,16 @@
"lib.shared-messages.addAttributes": "属性の追加",
"lib.shared-messages.addCollaborator": "コラボレータ―の追加",
"lib.shared-messages.addDeviceBulk": "エンドデバイス一括作成",
+ "lib.shared-messages.addHeaderEntry": "",
+ "lib.shared-messages.addOAuthClient": "",
"lib.shared-messages.addPubsub": "Pub/Subの追加",
+ "lib.shared-messages.addWebhook": "webhookの追加",
"lib.shared-messages.address": "住所",
"lib.shared-messages.addressPlaceholder": "ホスト",
- "lib.shared-messages.addWebhook": "webhookの追加",
"lib.shared-messages.admin": "管理者",
- "lib.shared-messages.adminPanel": "管理パネル",
"lib.shared-messages.adminContact": "管理連絡先",
+ "lib.shared-messages.adminDescription": "",
+ "lib.shared-messages.adminPanel": "管理パネル",
"lib.shared-messages.all": "すべて",
"lib.shared-messages.allAdmin": "すべて(管理者)",
"lib.shared-messages.altitude": "高度",
@@ -1153,16 +1012,18 @@
"lib.shared-messages.apiKeyCounted": "{count, plural, one {APIキー} other {APIキース}}",
"lib.shared-messages.apiKeyNamePlaceholder": "私の新しいAPIキー",
"lib.shared-messages.apiKeys": "APIキー",
+ "lib.shared-messages.appData": "",
"lib.shared-messages.appEUI": "AppEUI",
- "lib.shared-messages.appEUIJoinEUI": "AppEUI/JoinEUI",
"lib.shared-messages.appEUIDescription": "AppEUI はエンドデバイスの所有者を一意に識別します。デバイスメーカー(通常は開発用)がAppEUIを提供していない場合は、ゼロで埋めることができます",
+ "lib.shared-messages.appEUIJoinEUI": "AppEUI/JoinEUI",
"lib.shared-messages.appId": "アプリケーションID",
"lib.shared-messages.appKey": "AppKey",
+ "lib.shared-messages.appKeyAbsence": "",
+ "lib.shared-messages.appSKey": "AppSKey",
"lib.shared-messages.application": "アプリケーション",
- "lib.shared-messages.applications": "アプリケーション",
"lib.shared-messages.applicationServerAddress": "アプリケーションサーバのアドレス",
+ "lib.shared-messages.applications": "アプリケーション",
"lib.shared-messages.approve": "承認",
- "lib.shared-messages.appSKey": "AppSKey",
"lib.shared-messages.asServerID": "アプリケーションサーバID",
"lib.shared-messages.asServerIDDescription": "使用するアプリケーションサーバのAS-ID",
"lib.shared-messages.asServerKekLabel": "アプリケーションサーバKEKラベル",
@@ -1170,15 +1031,20 @@
"lib.shared-messages.attributeDescription": "属性は、エンティティに関する任意の情報を設定するために使用することができます",
"lib.shared-messages.attributeKeyValidateTooLong": "属性キーは32文字以下でなければなりません",
"lib.shared-messages.attributeKeyValidateTooShort": "属性キーは最低3文字でなければならず、特別な文字は含まれません",
+ "lib.shared-messages.attributeValueValidateTooLong": "属性値の文字数は200文字以下でなければなりません",
"lib.shared-messages.attributes": "属性",
"lib.shared-messages.attributesValidateRequired": "すべての属性の入力値が必須です。空のエントリは削除してください",
"lib.shared-messages.attributesValidateTooMany": "{field} は10項目以下でなければなりません",
- "lib.shared-messages.attributeValueValidateTooLong": "属性値の文字数は200文字以下でなければなりません",
+ "lib.shared-messages.authorization": "オーソライズ",
+ "lib.shared-messages.authorizationCode": "オーソライズコード",
"lib.shared-messages.authorizations": "オーソライズ",
- "lib.shared-messages.automaticUpdates": "自動更新",
"lib.shared-messages.autoUpdateDescription": "ゲートウェイは自動更新可能",
- "lib.shared-messages.backToOverview": "概要に戻る",
+ "lib.shared-messages.automaticUpdates": "自動更新",
+ "lib.shared-messages.backTo": "",
"lib.shared-messages.backToLogin": "ログインに戻る",
+ "lib.shared-messages.backToOverview": "概要に戻る",
+ "lib.shared-messages.beaconFrequency": "ビーコン周波数",
+ "lib.shared-messages.bearerMyAuthToken": "私の認証トークン",
"lib.shared-messages.brand": "ブランド",
"lib.shared-messages.cancel": "キャンセル",
"lib.shared-messages.changeLocation": "場所の設定を変更",
@@ -1186,8 +1052,11 @@
"lib.shared-messages.channel": "チャンネル",
"lib.shared-messages.claimAuthCode": "認証コード要求",
"lib.shared-messages.claiming": "クレーム",
+ "lib.shared-messages.classBTimeout": "クラスBタイムアウト",
+ "lib.shared-messages.classCTimeout": "クラスCタイムアウト",
"lib.shared-messages.clear": "クリア",
"lib.shared-messages.client": "クライアント",
+ "lib.shared-messages.clientId": "",
"lib.shared-messages.collaborator": "コラボレーター",
"lib.shared-messages.collaboratorCounted": "{count, plural, one {コラボレーター} other {コラボレータース}}",
"lib.shared-messages.collaboratorDeleteSuccess": "コラボレーターの削除",
@@ -1195,30 +1064,31 @@
"lib.shared-messages.collaboratorEditRights": "{collaboratorId}の編集権限",
"lib.shared-messages.collaboratorId": "コラボレーターID",
"lib.shared-messages.collaboratorIdPlaceholder": "collaborator-id",
- "lib.shared-messages.collaboratorWarningSelf": "自分の権利を変更すると、アクセスできなくなる可能性があります",
- "lib.shared-messages.collaboratorWarningAdmin": "このユーザーは、コラボレーターのステータスに関係なく、すべてのエンティティに対するすべての権利を保持する管理者です",
- "lib.shared-messages.collaboratorWarningAdminSelf": "管理者であるあなたは、コラボレーターのステータスに関係なく、常にすべてのエンティティのすべての権利を保持することができます",
"lib.shared-messages.collaboratorModalWarning": "コラボレータとして{collaboratorId}を削除してもよろしいでしょうか?",
"lib.shared-messages.collaboratorModalWarningSelf": "本当にコラボレーターを削除しますか?このエンティティへのアクセスは、他の誰かがあなたを再びコラボレーターとして追加するまで失われます",
"lib.shared-messages.collaboratorRemove": "コラボレーターの削除",
- "lib.shared-messages.collaborators": "コラボレータ―",
"lib.shared-messages.collaboratorUpdateSuccess": "コラボレーターの権利が更新されました",
+ "lib.shared-messages.collaboratorWarningAdmin": "このユーザーは、コラボレーターのステータスに関係なく、すべてのエンティティに対するすべての権利を保持する管理者です",
+ "lib.shared-messages.collaboratorWarningAdminSelf": "管理者であるあなたは、コラボレーターのステータスに関係なく、常にすべてのエンティティのすべての権利を保持することができます",
+ "lib.shared-messages.collaboratorWarningSelf": "自分の権利を変更すると、アクセスできなくなる可能性があります",
+ "lib.shared-messages.collaborators": "コラボレータ―",
"lib.shared-messages.componentAs": "アプリケーションサーバー",
+ "lib.shared-messages.componentDcs": "デバイスクレームサーバー",
"lib.shared-messages.componentEdtc": "エンドデバイステンプレートコンバータ",
+ "lib.shared-messages.componentGcs": "ゲートウェイクレームサーバー",
"lib.shared-messages.componentGs": "ゲートウェイサーバー",
"lib.shared-messages.componentIs": "アイデンティティサーバー",
"lib.shared-messages.componentJs": "Joinサーバー",
"lib.shared-messages.componentNs": "ネットワークサーバー",
"lib.shared-messages.componentQrg": "QRコードジェネレータ",
- "lib.shared-messages.componentDcs": "デバイスクレームサーバー",
- "lib.shared-messages.componentGcs": "ゲートウェイクレームサーバー",
"lib.shared-messages.confirm": "確認",
"lib.shared-messages.confirmPassword": "パスワードの確認",
+ "lib.shared-messages.confirmedDownlink": "確認済みダウンリンク",
"lib.shared-messages.connected": "接続済",
"lib.shared-messages.connecting": "接続中",
"lib.shared-messages.connectionIssues": "接続の問題",
- "lib.shared-messages.contactInformation": "連絡先",
"lib.shared-messages.contactFieldPlaceholder": "コラボレーターを入力または選択",
+ "lib.shared-messages.contactInformation": "連絡先",
"lib.shared-messages.convertMacToEui": "MACをEUIに変換",
"lib.shared-messages.copiedToClipboard": "クリップボードにコピーされます!",
"lib.shared-messages.copyToClipboard": "クリップボードにコピー",
@@ -1232,30 +1102,31 @@
"lib.shared-messages.data": "データ",
"lib.shared-messages.defineRights": "権利の定義",
"lib.shared-messages.delayWarning": "遅延が短すぎます。ゲートウェイサーバーは下限値 ({minimumValue}ms) を使用します",
- "lib.shared-messages.deleted": "削除しました(管理者)",
- "lib.shared-messages.deleteModalTitle": "本当に{entityName} を削除しますか?",
+ "lib.shared-messages.deleteModalConfirmDeletion": "削除の確認",
+ "lib.shared-messages.deleteModalConfirmMessage": "削除を確認するため、{entityId} を入力してください",
"lib.shared-messages.deleteModalDefaultMessage": "これにより、ENTITY自身と、共同研究者の関連付けを含むすべての関連するENTITYが永久に削除されます。また、ENTITY IDを再利用することもできなくなります",
"lib.shared-messages.deleteModalPurgeMessage": "これにより、そのエンティティ自身と、共同作業者の関連付けを含むすべての関連付けが永久に削除されます",
- "lib.shared-messages.deleteModalConfirmMessage": "削除を確認するため、{entityId} を入力してください",
- "lib.shared-messages.deleteModalConfirmDeletion": "削除の確認",
"lib.shared-messages.deleteModalPurgeWarning": "エンティティIDを公開すると、同じIDで新しいエンティティを登録することができるようになります。ただし、これは不可逆的であり、同じIDのエンティティを登録した場合、他のユーザーがそのエンティティの履歴データにアクセスできるようになる可能性があります。こちら に記載されているパージの意味合いをよく理解してください。",
- "lib.shared-messages.deleteModalReleaseIdTitle": "エンティティのパージ(管理者のみ)",
"lib.shared-messages.deleteModalReleaseIdLabel": "エンティティIDの解放(パージ)",
+ "lib.shared-messages.deleteModalReleaseIdTitle": "エンティティのパージ(管理者のみ)",
+ "lib.shared-messages.deleteModalTitle": "本当に{entityName} を削除しますか?",
+ "lib.shared-messages.deleted": "削除しました(管理者)",
"lib.shared-messages.description": "説明",
"lib.shared-messages.devAddr": "デバイスアドレス",
"lib.shared-messages.devDesc": "エンドデバイスの説明",
"lib.shared-messages.devEUI": "DevEUI",
"lib.shared-messages.devEUIBlockLimitReached": "DevEUI生成が限界到達",
+ "lib.shared-messages.devID": "エンドデバイスID",
+ "lib.shared-messages.devName": "エンドデバイス名",
+ "lib.shared-messages.device": "エンドデバイス",
"lib.shared-messages.deviceCounted": "{count, plural, one {エンドデバイス} other {エンドデバイスス}}",
"lib.shared-messages.deviceDescDescription": "エンドデバイスについてのメモを保存するために使用することもできます",
"lib.shared-messages.deviceDescPlaceholder": "私の新しいエンドデバイスの説明",
+ "lib.shared-messages.deviceHardwareVersionAbsence": "",
"lib.shared-messages.deviceIdPlaceholder": "my-new-device",
"lib.shared-messages.deviceNamePlaceholder": "私の新しいエンドデバイス",
"lib.shared-messages.deviceSimulationDisabledWarning": "ペイロード暗号をスキップする機器では、シミュレーションは無効になります",
- "lib.shared-messages.device": "エンドデバイス",
"lib.shared-messages.devices": "エンドデバイス",
- "lib.shared-messages.devID": "エンドデバイスID",
- "lib.shared-messages.devName": "エンドデバイス名",
"lib.shared-messages.disabled": "無効化",
"lib.shared-messages.disconnected": "切断されます",
"lib.shared-messages.documentation": "ドキュメンテーション",
@@ -1265,20 +1136,25 @@
"lib.shared-messages.downlinkFrameCount": "ダウンリンクのフレームカウント",
"lib.shared-messages.downlinkNack": "裸のダウンリンク",
"lib.shared-messages.downlinkPush": "ダウンリンクプッシュ",
- "lib.shared-messages.downlinkQueued": "ダウンリンクキュー",
"lib.shared-messages.downlinkQueueInvalidated": "ダウンリンクキューが無効",
+ "lib.shared-messages.downlinkQueued": "ダウンリンクキュー",
"lib.shared-messages.downlinkReplace": "ダウンリンク交換",
"lib.shared-messages.downlinkSent": "ダウンリンク送信",
"lib.shared-messages.downlinksScheduled": "ダウンリンク(再)予定",
"lib.shared-messages.edit": "編集",
+ "lib.shared-messages.editWebhook": "Webhookの編集",
"lib.shared-messages.email": "Email",
"lib.shared-messages.emailAddress": "Emailアドレス",
+ "lib.shared-messages.emailAddressDescription": "",
+ "lib.shared-messages.emailAddressValidation": "",
+ "lib.shared-messages.emailAddressValidationDescription": "",
+ "lib.shared-messages.emailPlaceholder": "",
"lib.shared-messages.empty": "空の状態",
"lib.shared-messages.enabled": "有効化",
- "lib.shared-messages.enforceDutyCycleDescription": "スペクトラム規制を尊重するため、すべてのゲートウェイに推奨されています",
+ "lib.shared-messages.endDeviceModelsUnavailable": "エンドデバイスモデルが利用できません",
"lib.shared-messages.enforceDutyCycle": "デューティサイクルの強制",
+ "lib.shared-messages.enforceDutyCycleDescription": "スペクトラム規制を尊重するため、すべてのゲートウェイに推奨されています",
"lib.shared-messages.entityId": "エンティティID",
- "lib.shared-messages.eventEnabledTypes": "有効なイベントタイプ",
"lib.shared-messages.eventDownlinkAckDesc": "確認されたダウンリンクは、エンドデバイスによって確認されます",
"lib.shared-messages.eventDownlinkFailedDesc": "ダウンリンクは送信できません",
"lib.shared-messages.eventDownlinkNackDesc": "送信された確認済みダウンリンクが、エンドデバイスの確認に失敗した場合",
@@ -1287,6 +1163,7 @@
"lib.shared-messages.eventDownlinkQueuedDesc": "ダウンリンクがダウンリンクキューに追加されます",
"lib.shared-messages.eventDownlinkReplaceDesc": "ダウンリンクは、ダウンリンクのキューを置き換えるために使用されます",
"lib.shared-messages.eventDownlinkSentDesc": "エンドデバイスまたはマルチキャストグループにダウンリンクが送信されます",
+ "lib.shared-messages.eventEnabledTypes": "有効なイベントタイプ",
"lib.shared-messages.eventJoinAcceptDesc": "エンドデバイスがネットワークに正常に参加し、セッションを開始した場合",
"lib.shared-messages.eventLocationSolvedDesc": "エンドデバイスの位置を特定することに成功したインテグレーション",
"lib.shared-messages.eventServiceDataDesc": "インテグレーションがイベントを発信します",
@@ -1297,10 +1174,15 @@
"lib.shared-messages.exportJson": "JSONとしてエクスポート",
"lib.shared-messages.external": "外部",
"lib.shared-messages.externalJoinServer": "外部Joinサーバー",
+ "lib.shared-messages.fNwkSIntKey": "",
+ "lib.shared-messages.factoryPresetFrequencies": "",
"lib.shared-messages.fetching": "データの取得...",
"lib.shared-messages.firmwareVersion": "ファームウェアバージョン",
- "lib.shared-messages.fNwkSIntKey": "FNwkSIntKey",
+ "lib.shared-messages.format": "フォーマット",
+ "lib.shared-messages.fpNotFoundError": "指定された周波数プランは見つかりませんでした",
"lib.shared-messages.frameCounterWidth": "フレームカウンター幅",
+ "lib.shared-messages.freqAdd": "周波数を追加",
+ "lib.shared-messages.frequencyPlaceholder": "周波数(Hz)",
"lib.shared-messages.frequencyPlan": "周波数プラン",
"lib.shared-messages.frequencyPlanWarning": "周波数プランを選択しないと、ゲートウェイからのパケットは正しく処理されません",
"lib.shared-messages.furtherResources": "その他のリソース",
@@ -1315,18 +1197,20 @@
"lib.shared-messages.gatewayLocationPublic": "ネットワーク内での位置情報の共有",
"lib.shared-messages.gatewayName": "ゲートウェイ名",
"lib.shared-messages.gatewayNamePlaceholder": "私の新しいゲートウェイ",
- "lib.shared-messages.gateways": "ゲートウェイ",
"lib.shared-messages.gatewayScheduleDownlinkLate": "スケジュールダウンリンクの遅延",
"lib.shared-messages.gatewayServerAddress": "ゲートウェイサーバのアドレス",
"lib.shared-messages.gatewayStatus": "ゲートウェイの状態",
"lib.shared-messages.gatewayStatusPublic": "ネットワーク内でステータスを共有",
"lib.shared-messages.gatewayUpdateOptions": "ゲートウェイの更新",
- "lib.shared-messages.generateAPIKeyCups": "CUPSのAPIキーを生成",
- "lib.shared-messages.generateAPIKeyLNS": "LNSのAPIキーを生成",
+ "lib.shared-messages.gateways": "ゲートウェイ",
"lib.shared-messages.general": "一般",
"lib.shared-messages.generalInformation": "一般情報",
"lib.shared-messages.generalSettings": "一般設定",
+ "lib.shared-messages.generateAPIKeyCups": "CUPSのAPIキーを生成",
+ "lib.shared-messages.generateAPIKeyLNS": "LNSのAPIキーを生成",
"lib.shared-messages.getSupport": "サポートを受ける",
+ "lib.shared-messages.grantAdminStatus": "管理者権限を付与",
+ "lib.shared-messages.grpcService": "gRPCサービス",
"lib.shared-messages.gsServerAddressDescription": "接続先のゲートウェイサーバのアドレス",
"lib.shared-messages.hardware": "ハードウェア",
"lib.shared-messages.hardwareVersion": "ハードウェアバージョン",
@@ -1337,12 +1221,12 @@
"lib.shared-messages.idAlreadyExists": "IDはすでに存在しています。",
"lib.shared-messages.import": "インポート",
"lib.shared-messages.importDevices": "エンドデバイスのインポート",
- "lib.shared-messages.integrations": "インテグレーション",
- "lib.shared-messages.invite": "招待",
- "lib.shared-messages.joinAccept": "Join受け入れ",
"lib.shared-messages.inputMethod": "入力方法",
"lib.shared-messages.insufficientAppKeyRights": "AppKeyを設定する権限が不足しています",
"lib.shared-messages.insufficientNwkKeyRights": "NwkKeyを設定する権限が不足しています",
+ "lib.shared-messages.integrations": "インテグレーション",
+ "lib.shared-messages.invite": "招待",
+ "lib.shared-messages.joinAccept": "Join受け入れ",
"lib.shared-messages.joinEUI": "JoinEUI",
"lib.shared-messages.joinServerAddress": "Joinサーバーアドレス",
"lib.shared-messages.key": "キー",
@@ -1359,18 +1243,19 @@
"lib.shared-messages.location": "場所",
"lib.shared-messages.locationDescription": "公開に設定すると、ゲートウェイの位置がネットワークの他のユーザーから見えることがあります",
"lib.shared-messages.locationMarkerDescriptionNonUser": "この位置は、このデバイスの受信メッセージから自動的に設定されました",
- "lib.shared-messages.locationMarkerDescriptionUser": "この場所は手動で設定されています(例:\"場所 \"タブを使用した場合)",
"lib.shared-messages.locationMarkerDescriptionUntrusted": "この位置は信頼できないステータスメッセージにより決定されたため、不正確である可能性があります",
+ "lib.shared-messages.locationMarkerDescriptionUser": "この場所は手動で設定されています(例:\"場所 \"タブを使用した場合)",
"lib.shared-messages.locationSolved": "解決済みの場所",
+ "lib.shared-messages.locationSourceBtRssi": "Bluetooth RSSIジオロケーション",
+ "lib.shared-messages.locationSourceCombined": "組み合わせたジオロケーション",
"lib.shared-messages.locationSourceGps": "GPSに基づく位置",
- "lib.shared-messages.locationSourceRegistry": "手動で設定された位置",
"lib.shared-messages.locationSourceIpGeolocation": "IPに基づくジオロケーション",
- "lib.shared-messages.locationSourceWifiRssi": "Wifi RSSIジオロケーション",
- "lib.shared-messages.locationSourceBtRssi": "Bluetooth RSSIジオロケーション",
"lib.shared-messages.locationSourceLoraRssi": "LoRa RSSIジオロケーション",
"lib.shared-messages.locationSourceLoraTdoa": "LoRa TDOAジオロケーション",
- "lib.shared-messages.locationSourceCombined": "組み合わせたジオロケーション",
+ "lib.shared-messages.locationSourceRegistry": "手動で設定された位置",
+ "lib.shared-messages.locationSourceWifiRssi": "Wifi RSSIジオロケーション",
"lib.shared-messages.login": "ログイン",
+ "lib.shared-messages.loginFailed": "ログインに失敗しました",
"lib.shared-messages.logout": "ログアウト",
"lib.shared-messages.longitude": "経度",
"lib.shared-messages.longitudeDesc": "東西の位置を度数で表したもので、0は主子午線(グリニッジ)です",
@@ -1380,10 +1265,12 @@
"lib.shared-messages.lorawanInformation": "LoRaWAN情報",
"lib.shared-messages.lorawanOptions": "LoRaWANオプション",
"lib.shared-messages.lorawanPhyVersionDescription": "エンドデバイスのLoRaWAN PHYバージョン",
+ "lib.shared-messages.macData": "MACデータ",
+ "lib.shared-messages.macSettingsError": "MAC設定エラー",
"lib.shared-messages.macVersion": "LoRaWANバージョン",
+ "lib.shared-messages.messageTypes": "メッセージの種類",
"lib.shared-messages.messages": "メッセージ",
"lib.shared-messages.messaging": "メッセージング",
- "lib.shared-messages.messageTypes": "メッセージの種類",
"lib.shared-messages.milliseconds": "ミリ秒",
"lib.shared-messages.minutes": "分",
"lib.shared-messages.model": "モデル",
@@ -1392,24 +1279,25 @@
"lib.shared-messages.multicast": "マルチキャスト",
"lib.shared-messages.name": "名前",
"lib.shared-messages.netId": "Net ID",
- "lib.shared-messages.networks": "ネットワーク",
+ "lib.shared-messages.networkInformation": "",
"lib.shared-messages.networkServerAddress": "ネットワークサーバーアドレス",
+ "lib.shared-messages.networks": "ネットワーク",
"lib.shared-messages.never": "ネバー",
"lib.shared-messages.next": "次へ",
"lib.shared-messages.noActivityYet": "まだ活動はしていません",
- "lib.shared-messages.noRecentActivity": "最近の活動はありません",
"lib.shared-messages.noDesc": "このエンドデバイスには説明がありません",
"lib.shared-messages.noEvents": "{entityId} からのイベント待ち...",
"lib.shared-messages.noLocation": "位置情報はありません",
"lib.shared-messages.noMatch": "アイテムが見つかりませんでした",
+ "lib.shared-messages.noMatchingUserFound": "",
+ "lib.shared-messages.noRecentActivity": "最近の活動はありません",
"lib.shared-messages.none": "なし",
- "lib.shared-messages.normalizedPayloadSoil": "土壌",
"lib.shared-messages.normalizedPayloadAir": "空気",
+ "lib.shared-messages.normalizedPayloadSoil": "土壌",
"lib.shared-messages.normalizedPayloadWind": "風",
"lib.shared-messages.notAvailable": "n/a",
"lib.shared-messages.notLinked": "リンクされていません",
"lib.shared-messages.notSet": "未設定",
- "lib.shared-messages.nsAddress": "ネットワークサーバアドレス",
"lib.shared-messages.nsEmptyDefault": "同じクラスタ内のネットワークサーバーにリンクするには空のままにします",
"lib.shared-messages.nsServerKekLabel": "ネットワークサーバーKEKラベル",
"lib.shared-messages.nsServerKekLabelDescription": "ネットワーク・セッション・キーのラッピングに使用するネットワーク・サーバの KEK ラベル",
@@ -1417,9 +1305,9 @@
"lib.shared-messages.nwkSEncKey": "NwkSEncKey",
"lib.shared-messages.nwkSEncKeyDescription": "ネットワークセッション暗号化キー",
"lib.shared-messages.nwkSKey": "NwkSKey",
- "lib.shared-messages.oauthClients": "OAuth クライアント",
- "lib.shared-messages.oauthClientId": "OAuth クライアント ID",
"lib.shared-messages.oauthClientAuthorizations": "OAuthクライアント認証",
+ "lib.shared-messages.oauthClientId": "OAuth クライアント ID",
+ "lib.shared-messages.oauthClients": "OAuth クライアント",
"lib.shared-messages.offline": "オフライン",
"lib.shared-messages.ok": "OK",
"lib.shared-messages.online": "オンライン",
@@ -1444,6 +1332,8 @@
"lib.shared-messages.personalApiKeys": "個人用APIキー",
"lib.shared-messages.phyVersion": "地域パラメータのバージョン",
"lib.shared-messages.phyVersionDescription": "デバイスメーカーが提供する地域パラメータバージョン(PHY)",
+ "lib.shared-messages.pingSlotFrequency": "",
+ "lib.shared-messages.pingSlotPeriodicity": "",
"lib.shared-messages.port": "ポート",
"lib.shared-messages.privacyPolicy": "個人情報保護方針",
"lib.shared-messages.profileSettings": "プロファイル設定",
@@ -1458,56 +1348,65 @@
"lib.shared-messages.refresh": "リフレッシュ",
"lib.shared-messages.registerEndDevice": "エンドデバイスの登録",
"lib.shared-messages.registerGateway": "ゲートウェイの登録",
- "lib.shared-messages.replaceWebhook": "webhookの交換",
+ "lib.shared-messages.remove": "",
"lib.shared-messages.removeCollaborator": "コラボレーターの削除",
- "lib.shared-messages.removeCollaboratorSelf": "自分をコラボレーターとして外す",
"lib.shared-messages.removeCollaboratorLast": "最後のコラボレーターを削除できません",
+ "lib.shared-messages.removeCollaboratorSelf": "自分をコラボレーターとして外す",
+ "lib.shared-messages.replaceWebhook": "webhookの交換",
"lib.shared-messages.requireAuthenticatedConnection": "認証された接続を必要とします",
"lib.shared-messages.requireAuthenticatedConnectionDescription": "このゲートウェイが認証されたBasic StationまたはMQTT接続を使用する場合にのみ接続できるかどうかを制御します",
"lib.shared-messages.reset": "リセット",
+ "lib.shared-messages.resetWarning": "リセットは安全ではないため、エンドデバイスはリプレイ攻撃の影響を受けやすくなります",
"lib.shared-messages.resetsFCnt": "フレームカウンターのリセット",
"lib.shared-messages.resetsJoinNonces": "join noncesをリセットします",
- "lib.shared-messages.resetWarning": "リセットは安全ではないため、エンドデバイスはリプレイ攻撃の影響を受けやすくなります",
"lib.shared-messages.restartStream": "ストリームの再起動",
"lib.shared-messages.restore": "復元",
"lib.shared-messages.restrictedUser": "自分自身を連絡先として設定することしかできません。別のコラボレーターを連絡先として設定したい場合は、そのコラボレーターに連絡して自己割り当てを依頼してください。",
"lib.shared-messages.resume": "履歴書",
"lib.shared-messages.rights": "著作権",
"lib.shared-messages.rootKeys": "ルートキー",
+ "lib.shared-messages.rx1DataRateOffset": "",
+ "lib.shared-messages.rx1Delay": "",
+ "lib.shared-messages.rx2Frequency": "",
+ "lib.shared-messages.sNwkSIKey": "SNwkSetKey",
+ "lib.shared-messages.sNwkSIKeyDescription": "ネットワークセッション整合性キーの提供",
"lib.shared-messages.saveChanges": "変更を保存",
+ "lib.shared-messages.scanEndDevice": "",
"lib.shared-messages.scheduleAnyTimeDelay": "任意の時間遅延をスケジュール",
"lib.shared-messages.scheduleAnyTimeDescription": "ゲートウェイ遅延の設定 (最小値: {minimumValue}ms, デフォルト値: {defaultValue}ms)",
"lib.shared-messages.scheduleDownlinkLateDescription": "ダウンリンクメッセージのサーバ側バッファを有効にします",
"lib.shared-messages.search": "検索",
+ "lib.shared-messages.secondInterval": "",
"lib.shared-messages.seconds": "秒",
"lib.shared-messages.secondsAbbreviated": "sec",
"lib.shared-messages.secret": "秘密",
"lib.shared-messages.secure": "セキュア",
"lib.shared-messages.sendInvitation": "招待状送付",
- "lib.shared-messages.sessions": "セッション",
"lib.shared-messages.serverUrl": "サーバーURL",
"lib.shared-messages.serviceData": "サービスデータ",
+ "lib.shared-messages.sessions": "セッション",
+ "lib.shared-messages.setLoRaCloudToken": "",
"lib.shared-messages.settings": "設定",
+ "lib.shared-messages.setup": "",
"lib.shared-messages.shareGatewayInfo": "ゲートウェイ情報を共有",
"lib.shared-messages.skipCryptoDescription": "アップリンクペイロードの復号化とダウンリンクペイロードの暗号化をスキップします",
"lib.shared-messages.skipCryptoPlaceholder": "暗号化/復号化無効",
"lib.shared-messages.skipCryptoTitle": "ペイロードの暗号化と復号化をスキップ",
- "lib.shared-messages.sNwkSIKey": "SNwkSIntKey",
- "lib.shared-messages.sNwkSIKeyDescription": "ネットワークセッション整合性キーの提供",
"lib.shared-messages.source": "ソース",
"lib.shared-messages.stable": "安定した",
"lib.shared-messages.state": "状態",
- "lib.shared-messages.stateDescription": "状態の説明",
"lib.shared-messages.stateApproved": "承認済み",
+ "lib.shared-messages.stateDescription": "状態の説明",
"lib.shared-messages.stateFlagged": "フラグ付き",
"lib.shared-messages.stateRejected": "拒絶された",
"lib.shared-messages.stateRequested": "要求された",
"lib.shared-messages.stateSuspended": "中断された",
"lib.shared-messages.status": "ステータス",
"lib.shared-messages.statusDescription": "このゲートウェイの状態を公開することができます",
- "lib.shared-messages.statusUnknown": "ステータス不明",
"lib.shared-messages.statusPage": "ステータスページ",
+ "lib.shared-messages.statusUnknown": "ステータス不明",
"lib.shared-messages.success": "成功",
+ "lib.shared-messages.suggestions": "",
"lib.shared-messages.supportsClassB": "クラスBをサポート",
"lib.shared-messages.supportsClassC": "クラスCをサポート",
"lib.shared-messages.takeMeBack": "私を連れ戻して",
@@ -1524,9 +1423,10 @@
"lib.shared-messages.troubleshooting": "トラブルシューティング",
"lib.shared-messages.type": "タイプ",
"lib.shared-messages.typeToSearch": "検索に入力する…",
- "lib.shared-messages.unknownHwOption": "不明ver.",
+ "lib.shared-messages.unexposed": "未公開",
"lib.shared-messages.unknown": "不明",
"lib.shared-messages.unknownError": "DevEUIの生成時に不明なエラーが発生",
+ "lib.shared-messages.unknownHwOption": "不明ver.",
"lib.shared-messages.updateChannelDescription": "ゲートウェイ自動更新のためのチャンネル",
"lib.shared-messages.updatedAt": "最終更新日",
"lib.shared-messages.uplink": "アップリンク",
@@ -1534,26 +1434,34 @@
"lib.shared-messages.uplinkMessage": "アップリンクメッセージ",
"lib.shared-messages.uplinkNormalized": "正規化されたアップリンク",
"lib.shared-messages.uplinksReceived": "アップリンクを受信",
- "lib.shared-messages.unexposed": "未公開",
+ "lib.shared-messages.uploadAnImage": "",
"lib.shared-messages.used": "{currentValue}/{maxValue} 使用",
+ "lib.shared-messages.useDefaultPolicy": "",
"lib.shared-messages.user": "ユーザー",
"lib.shared-messages.userAdd": "ユーザーを追加",
"lib.shared-messages.userDelete": "ユーザーを削除",
+ "lib.shared-messages.userDescDescription": "",
+ "lib.shared-messages.userDescription": "",
"lib.shared-messages.userEdit": "ユーザーを編集",
"lib.shared-messages.userId": "ユーザーID",
+ "lib.shared-messages.userIdPlaceholder": "",
"lib.shared-messages.userInvitations": "ユーザー招待",
"lib.shared-messages.userManagement": "ユーザー管理",
+ "lib.shared-messages.userNamePlaceholder": "",
+ "lib.shared-messages.userOrgId": "",
"lib.shared-messages.username": "ユーザー名",
"lib.shared-messages.users": "ユーザー",
+ "lib.shared-messages.validFrom": "から有効です",
+ "lib.shared-messages.validTo": "に有効です",
"lib.shared-messages.validateAddressFormat": "{field} は \"host \"または \"host:port \"の形式でなければなりません",
"lib.shared-messages.validateApiKey": "API キーは、\"NNSXS.[...].[.... ]\"の形式に従う必要があります",
"lib.shared-messages.validateDateInPast": "{field}は未来の日付でなければなりません",
"lib.shared-messages.validateDelayFormat": "{field} は正の整数でなければなりません。",
"lib.shared-messages.validateDigit": "{field} は少なくとも{digit} {digit, multiple, one {digit} other {digits}}を持っている必要があります",
"lib.shared-messages.validateEmail": "メールアドレスには、「@」と「.」を1つだけ使用し、特殊文字は使用しないでください",
+ "lib.shared-messages.validateFreqDynamic": "ダイナミック周波数が100000Hz以上の場合、{field}は0でなければなりません",
"lib.shared-messages.validateFreqNumeric": "周波数の値はすべて正の整数でなければなりません",
"lib.shared-messages.validateFreqRequired": "すべての周波数の値が必要です。空の項目は削除してください",
- "lib.shared-messages.validateFreqDynamic": "ダイナミック周波数が100000Hz以上の場合、{field}は0でなければなりません",
"lib.shared-messages.validateHexLength": "{field} は完全な16進数の値でなければなりません",
"lib.shared-messages.validateIdFormat": "{field} には小文字、数字、ダッシュ(-)のみを含める必要があります",
"lib.shared-messages.validateInt32": "{field}は整数、負または正でなければなりません",
@@ -1575,13 +1483,14 @@
"lib.shared-messages.validateTooShort": "{field} には少なくとも{min}文字が必要です",
"lib.shared-messages.validateUppercase": "{field} は、少なくとも {upper} uppercase {upper, plural, one {character} other {characters}}を使用しなければなりません",
"lib.shared-messages.validateUrl": "有効なURL形式でなければならず、スペースや特殊文字は含まれていません",
- "lib.shared-messages.validFrom": "から有効です",
- "lib.shared-messages.validTo": "に有効です",
"lib.shared-messages.value": "値",
+ "lib.shared-messages.webhookActivated": "Webhookがアクティブになりました",
"lib.shared-messages.webhookAlreadyExistsModalMessage": "ID \"{id}\" を持つwebhookが既に存在します。このウェブフックを置き換えますか?",
"lib.shared-messages.webhookBaseUrl": "ベースURL",
+ "lib.shared-messages.webhookDeleted": "Webhookが削除されました",
"lib.shared-messages.webhookFormat": "Webhook フォーマット",
"lib.shared-messages.webhookId": "Webhook ID",
+ "lib.shared-messages.webhookUpdated": "",
"lib.shared-messages.webhooks": "Webhooks",
"enum:CHANNEL_MASKS": "チャネルマスク",
"enum:CID_ADR_PARAM_SETUP": "ADRパラメータ",
@@ -1600,6 +1509,13 @@
"enum:CID_PING_SLOT_INFO": "スロット情報へPing",
"enum:CID_REJOIN_PARAM_SETUP": "再ジョインパラメータ",
"enum:CID_REKEY": "再キー",
+ "enum:CID_RELAY_CONF": "",
+ "enum:CID_RELAY_CONFIGURE_FWD_LIMIT": "",
+ "enum:CID_RELAY_CTRL_UPLINK_LIST": "",
+ "enum:CID_RELAY_END_DEVICE_CONF": "",
+ "enum:CID_RELAY_FILTER_LIST": "",
+ "enum:CID_RELAY_NOTIFY_NEW_END_DEVICE": "",
+ "enum:CID_RELAY_UPDATE_UPLINK_LIST": "",
"enum:CID_RESET": "リセット",
"enum:CID_RFU_0": "RFU",
"enum:CID_RX_PARAM_SETUP": "受信パラメータ",
@@ -1973,6 +1889,12 @@
"error:pkg/config:format": "無効なフォーマット `{input}`",
"error:pkg/config:missing_blob_config": "Blobストア設定が見つかりません",
"error:pkg/config:unknown_blob_provider": "無効なBlobストアプロバイダ `{provider}`",
+ "error:pkg/console/internal/events/protocol:message_type": "",
+ "error:pkg/console/internal/events/subscriptions:already_subscribed": "",
+ "error:pkg/console/internal/events/subscriptions:no_identifiers": "",
+ "error:pkg/console/internal/events/subscriptions:not_subscribed": "",
+ "error:pkg/console/internal/events:rate_exceeded": "",
+ "error:pkg/console/internal/events:unknown_caller": "",
"error:pkg/crypto/cryptoservices:no_app_key": "指定されたAppKeyがありません",
"error:pkg/crypto/cryptoservices:no_dev_eui": "指定されたDevEUIがありません",
"error:pkg/crypto/cryptoservices:no_join_eui": "指定されたJoinEUIがありません",
@@ -2070,13 +1992,13 @@
"error:pkg/errors:x509_certificate_invalid": "証明書が無効",
"error:pkg/errors:x509_hostname": "証明書の承認された名前が要求された名前と一致しません",
"error:pkg/errors:x509_unknown_authority": "不明の証明書発行機関",
- "error:pkg/events/grpc:invalid_regexp": "無効な正規表現",
"error:pkg/events/grpc:no_identifiers": "識別子がありません",
- "error:pkg/events/grpc:no_matching_events": "正規表現`{regexp}`に一致するイベントがありません",
"error:pkg/events/grpc:storage_disabled": "イベントストレージが有効になっていません",
- "error:pkg/events/grpc:unknown_event_name": "不明なイベント`{name}`",
"error:pkg/events/redis:channel_closed": "チャネルが閉じています",
"error:pkg/events/redis:unknown_encoding": "不明なエンコーディング",
+ "error:pkg/events:invalid_regexp": "無効な正規表現",
+ "error:pkg/events:no_matching_events": "正規表現`{regexp}`に一致するイベントがありません",
+ "error:pkg/events:unknown_event_name": "不明なイベント`{name}`",
"error:pkg/fetch:fetch_file": "ファイル `{filename}` を取得できません",
"error:pkg/fetch:file_not_found": "ファイル `{filename}` が見つかりません",
"error:pkg/fetch:filename_not_specified": "ファイル名が特定されません",
@@ -2370,6 +2292,7 @@
"error:pkg/messageprocessors/devicerepository:no_version_identifiers": "デバイスのバージョン識別子がありません",
"error:pkg/messageprocessors/javascript:input": "無効な入力",
"error:pkg/messageprocessors/javascript:output": "無効な出力",
+ "error:pkg/messageprocessors/javascript:output_encoding": "",
"error:pkg/messageprocessors/javascript:output_errors": "{errors}",
"error:pkg/messageprocessors/normalizedpayload:field_exclusive_maximum": "`{path}`は`{maximum}`未満であるべきです",
"error:pkg/messageprocessors/normalizedpayload:field_exclusive_minimum": "`{path}`は`{minimum}`より大きいべきです",
@@ -2401,11 +2324,14 @@
"error:pkg/networkserver/redis:invalid_identifiers": "無効な識別子",
"error:pkg/networkserver/redis:invalid_member_type": "無効なメンバータイプ",
"error:pkg/networkserver/redis:invalid_payload": "無効なペイロード",
+ "error:pkg/networkserver/redis:invalid_uid": "",
"error:pkg/networkserver/redis:missing_downlink_correlation_id": "ダウンリンクメッセージの識別子相関IDがありません",
"error:pkg/networkserver/redis:missing_payload": "ペイロードが見つかりません",
"error:pkg/networkserver/redis:missing_session_data": "セッションデータがありません",
+ "error:pkg/networkserver/redis:missing_uid": "",
"error:pkg/networkserver/redis:no_uplink_match": "デバイスがアップリンクと一致しません",
"error:pkg/networkserver/redis:read_only_field": "読み取り専用フィールド `{field}`",
+ "error:pkg/networkserver/redis:relay_served": "",
"error:pkg/networkserver:abp_join_request": "ABPデバイスからジョインリクエストを受信しました",
"error:pkg/networkserver:absolute_time": "アプリケーションダウンリンクに無効なアブソリュートタイムが設定されています",
"error:pkg/networkserver:application_downlink_too_long": "アプリケーションダウンリンク長 `{length}` が最大値 '{max}' を超えています",
@@ -2441,6 +2367,15 @@
"error:pkg/networkserver:payload": "無効なペイロード",
"error:pkg/networkserver:raw_payload_too_short": "RawPayload長は4より大きい値でなければいけません",
"error:pkg/networkserver:rejoin_request": "再ジョイン要求制御が未実装",
+ "error:pkg/networkserver:relay_full_f_cnt": "",
+ "error:pkg/networkserver:relay_m_type": "",
+ "error:pkg/networkserver:relay_recent_uplinks": "",
+ "error:pkg/networkserver:relay_rx_windows_available": "",
+ "error:pkg/networkserver:relay_schedule": "",
+ "error:pkg/networkserver:relay_serving": "",
+ "error:pkg/networkserver:relay_session": "",
+ "error:pkg/networkserver:relay_session_key_id": "",
+ "error:pkg/networkserver:relay_uplink_token": "",
"error:pkg/networkserver:schedule": "全てのスケジュールされたダウンリンクが失敗に終わりました",
"error:pkg/networkserver:transmission": "ダウンリンク伝送が結果 `{result}` で失敗しました",
"error:pkg/networkserver:unknown_mac_state": "不明なMAC状態",
@@ -2752,7 +2687,7 @@
"event:ns.mac.new_channel.answer.reject": "新チャネル拒否を受信",
"event:ns.mac.new_channel.request": "新チャネル要求がエンキューされました",
"event:ns.mac.ping_slot_channel.answer.accept": "スロットチャネルへのPing許可を受信",
- "event:ns.mac.ping_slot_channel.answer.reject": "",
+ "event:ns.mac.ping_slot_channel.answer.reject": "スロットチャネルへのPing拒否を受信",
"event:ns.mac.ping_slot_channel.request": "スロットチャネルへのPing要求がエンキューされました",
"event:ns.mac.ping_slot_info.answer": "スロット情報へのPing応答がエンキューされました",
"event:ns.mac.ping_slot_info.request": "スロット情報へのPing要求を受信",
@@ -2761,6 +2696,20 @@
"event:ns.mac.rejoin_param_setup.request": "再ジョインパラメータ設定要求がエンキューされました",
"event:ns.mac.rekey.confirmation": "デバイス再キー確認がエンキューされました",
"event:ns.mac.rekey.indication": "デバイス再キー指示を受信",
+ "event:ns.mac.relay_conf.answer.accept": "",
+ "event:ns.mac.relay_conf.answer.reject": "",
+ "event:ns.mac.relay_conf.request": "",
+ "event:ns.mac.relay_configure_fwd_limit.answer": "",
+ "event:ns.mac.relay_configure_fwd_limit.request": "",
+ "event:ns.mac.relay_ctrl_uplink_list.answer.accept": "",
+ "event:ns.mac.relay_ctrl_uplink_list.answer.reject": "",
+ "event:ns.mac.relay_ctrl_uplink_list.request": "",
+ "event:ns.mac.relay_end_device_conf.answer.accept": "",
+ "event:ns.mac.relay_end_device_conf.answer.reject": "",
+ "event:ns.mac.relay_end_device_conf.request": "",
+ "event:ns.mac.relay_notify_new_end_device.indication": "",
+ "event:ns.mac.relay_update_uplink_list.answer": "",
+ "event:ns.mac.relay_update_uplink_list.request": "",
"event:ns.mac.reset.confirmation": "デバイスリセット確認がエンキューされました",
"event:ns.mac.reset.indication": "デバイスリセット指示を受信",
"event:ns.mac.rx_param_setup.answer.accept": "受信パラメータ設定許可を受信",
@@ -2784,6 +2733,8 @@
"event:ns.up.join.interop.success": "相互接続ジョインサーバへのジョイン要求成功",
"event:ns.up.join.process": "ジョイン要求処理に成功",
"event:ns.up.join.receive": "ジョイン要求を受信",
+ "event:ns.up.relay.drop": "",
+ "event:ns.up.relay.process": "",
"event:oauth.authorize": "OAuthクラアントを認証",
"event:oauth.session.terminated": "ユーザセッションを終了",
"event:oauth.token.deleted": "アクセストークンを削除",
diff --git a/sdk/js/generated/api-definition.json b/sdk/js/generated/api-definition.json
index c844543b19..95581bf4b9 100644
--- a/sdk/js/generated/api-definition.json
+++ b/sdk/js/generated/api-definition.json
@@ -4064,6 +4064,42 @@
"mac_settings.desired_ping_slot_data_rate_index.value",
"mac_settings.desired_ping_slot_frequency",
"mac_settings.desired_ping_slot_frequency.value",
+ "mac_settings.desired_relay",
+ "mac_settings.desired_relay.mode",
+ "mac_settings.desired_relay.mode.served",
+ "mac_settings.desired_relay.mode.served.backoff",
+ "mac_settings.desired_relay.mode.served.mode",
+ "mac_settings.desired_relay.mode.served.mode.always",
+ "mac_settings.desired_relay.mode.served.mode.dynamic",
+ "mac_settings.desired_relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_settings.desired_relay.mode.served.mode.end_device_controlled",
+ "mac_settings.desired_relay.mode.served.second_channel",
+ "mac_settings.desired_relay.mode.served.second_channel.ack_offset",
+ "mac_settings.desired_relay.mode.served.second_channel.data_rate_index",
+ "mac_settings.desired_relay.mode.served.second_channel.frequency",
+ "mac_settings.desired_relay.mode.served.serving_device_id",
+ "mac_settings.desired_relay.mode.serving",
+ "mac_settings.desired_relay.mode.serving.cad_periodicity",
+ "mac_settings.desired_relay.mode.serving.default_channel_index",
+ "mac_settings.desired_relay.mode.serving.limits",
+ "mac_settings.desired_relay.mode.serving.limits.join_requests",
+ "mac_settings.desired_relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_settings.desired_relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_settings.desired_relay.mode.serving.limits.notifications",
+ "mac_settings.desired_relay.mode.serving.limits.notifications.bucket_size",
+ "mac_settings.desired_relay.mode.serving.limits.notifications.reload_rate",
+ "mac_settings.desired_relay.mode.serving.limits.overall",
+ "mac_settings.desired_relay.mode.serving.limits.overall.bucket_size",
+ "mac_settings.desired_relay.mode.serving.limits.overall.reload_rate",
+ "mac_settings.desired_relay.mode.serving.limits.reset_behavior",
+ "mac_settings.desired_relay.mode.serving.limits.uplink_messages",
+ "mac_settings.desired_relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_settings.desired_relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_settings.desired_relay.mode.serving.second_channel",
+ "mac_settings.desired_relay.mode.serving.second_channel.ack_offset",
+ "mac_settings.desired_relay.mode.serving.second_channel.data_rate_index",
+ "mac_settings.desired_relay.mode.serving.second_channel.frequency",
+ "mac_settings.desired_relay.mode.serving.uplink_forwarding_rules",
"mac_settings.desired_rx1_data_rate_offset",
"mac_settings.desired_rx1_data_rate_offset.value",
"mac_settings.desired_rx1_delay",
@@ -4081,6 +4117,42 @@
"mac_settings.ping_slot_frequency.value",
"mac_settings.ping_slot_periodicity",
"mac_settings.ping_slot_periodicity.value",
+ "mac_settings.relay",
+ "mac_settings.relay.mode",
+ "mac_settings.relay.mode.served",
+ "mac_settings.relay.mode.served.backoff",
+ "mac_settings.relay.mode.served.mode",
+ "mac_settings.relay.mode.served.mode.always",
+ "mac_settings.relay.mode.served.mode.dynamic",
+ "mac_settings.relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_settings.relay.mode.served.mode.end_device_controlled",
+ "mac_settings.relay.mode.served.second_channel",
+ "mac_settings.relay.mode.served.second_channel.ack_offset",
+ "mac_settings.relay.mode.served.second_channel.data_rate_index",
+ "mac_settings.relay.mode.served.second_channel.frequency",
+ "mac_settings.relay.mode.served.serving_device_id",
+ "mac_settings.relay.mode.serving",
+ "mac_settings.relay.mode.serving.cad_periodicity",
+ "mac_settings.relay.mode.serving.default_channel_index",
+ "mac_settings.relay.mode.serving.limits",
+ "mac_settings.relay.mode.serving.limits.join_requests",
+ "mac_settings.relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_settings.relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_settings.relay.mode.serving.limits.notifications",
+ "mac_settings.relay.mode.serving.limits.notifications.bucket_size",
+ "mac_settings.relay.mode.serving.limits.notifications.reload_rate",
+ "mac_settings.relay.mode.serving.limits.overall",
+ "mac_settings.relay.mode.serving.limits.overall.bucket_size",
+ "mac_settings.relay.mode.serving.limits.overall.reload_rate",
+ "mac_settings.relay.mode.serving.limits.reset_behavior",
+ "mac_settings.relay.mode.serving.limits.uplink_messages",
+ "mac_settings.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_settings.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_settings.relay.mode.serving.second_channel",
+ "mac_settings.relay.mode.serving.second_channel.ack_offset",
+ "mac_settings.relay.mode.serving.second_channel.data_rate_index",
+ "mac_settings.relay.mode.serving.second_channel.frequency",
+ "mac_settings.relay.mode.serving.uplink_forwarding_rules",
"mac_settings.resets_f_cnt",
"mac_settings.resets_f_cnt.value",
"mac_settings.rx1_data_rate_offset",
@@ -4123,6 +4195,42 @@
"mac_state.current_parameters.ping_slot_frequency",
"mac_state.current_parameters.rejoin_count_periodicity",
"mac_state.current_parameters.rejoin_time_periodicity",
+ "mac_state.current_parameters.relay",
+ "mac_state.current_parameters.relay.mode",
+ "mac_state.current_parameters.relay.mode.served",
+ "mac_state.current_parameters.relay.mode.served.backoff",
+ "mac_state.current_parameters.relay.mode.served.mode",
+ "mac_state.current_parameters.relay.mode.served.mode.always",
+ "mac_state.current_parameters.relay.mode.served.mode.dynamic",
+ "mac_state.current_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_state.current_parameters.relay.mode.served.mode.end_device_controlled",
+ "mac_state.current_parameters.relay.mode.served.second_channel",
+ "mac_state.current_parameters.relay.mode.served.second_channel.ack_offset",
+ "mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index",
+ "mac_state.current_parameters.relay.mode.served.second_channel.frequency",
+ "mac_state.current_parameters.relay.mode.served.serving_device_id",
+ "mac_state.current_parameters.relay.mode.serving",
+ "mac_state.current_parameters.relay.mode.serving.cad_periodicity",
+ "mac_state.current_parameters.relay.mode.serving.default_channel_index",
+ "mac_state.current_parameters.relay.mode.serving.limits",
+ "mac_state.current_parameters.relay.mode.serving.limits.join_requests",
+ "mac_state.current_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.limits.notifications",
+ "mac_state.current_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.limits.overall",
+ "mac_state.current_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.limits.reset_behavior",
+ "mac_state.current_parameters.relay.mode.serving.limits.uplink_messages",
+ "mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.second_channel",
+ "mac_state.current_parameters.relay.mode.serving.second_channel.ack_offset",
+ "mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "mac_state.current_parameters.relay.mode.serving.second_channel.frequency",
+ "mac_state.current_parameters.relay.mode.serving.uplink_forwarding_rules",
"mac_state.current_parameters.rx1_data_rate_offset",
"mac_state.current_parameters.rx1_delay",
"mac_state.current_parameters.rx2_data_rate_index",
@@ -4148,6 +4256,42 @@
"mac_state.desired_parameters.ping_slot_frequency",
"mac_state.desired_parameters.rejoin_count_periodicity",
"mac_state.desired_parameters.rejoin_time_periodicity",
+ "mac_state.desired_parameters.relay",
+ "mac_state.desired_parameters.relay.mode",
+ "mac_state.desired_parameters.relay.mode.served",
+ "mac_state.desired_parameters.relay.mode.served.backoff",
+ "mac_state.desired_parameters.relay.mode.served.mode",
+ "mac_state.desired_parameters.relay.mode.served.mode.always",
+ "mac_state.desired_parameters.relay.mode.served.mode.dynamic",
+ "mac_state.desired_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_state.desired_parameters.relay.mode.served.mode.end_device_controlled",
+ "mac_state.desired_parameters.relay.mode.served.second_channel",
+ "mac_state.desired_parameters.relay.mode.served.second_channel.ack_offset",
+ "mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index",
+ "mac_state.desired_parameters.relay.mode.served.second_channel.frequency",
+ "mac_state.desired_parameters.relay.mode.served.serving_device_id",
+ "mac_state.desired_parameters.relay.mode.serving",
+ "mac_state.desired_parameters.relay.mode.serving.cad_periodicity",
+ "mac_state.desired_parameters.relay.mode.serving.default_channel_index",
+ "mac_state.desired_parameters.relay.mode.serving.limits",
+ "mac_state.desired_parameters.relay.mode.serving.limits.join_requests",
+ "mac_state.desired_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.limits.notifications",
+ "mac_state.desired_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.limits.overall",
+ "mac_state.desired_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.limits.reset_behavior",
+ "mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages",
+ "mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel.ack_offset",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel.frequency",
+ "mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules",
"mac_state.desired_parameters.rx1_data_rate_offset",
"mac_state.desired_parameters.rx1_delay",
"mac_state.desired_parameters.rx2_data_rate_index",
@@ -4172,6 +4316,8 @@
"mac_state.pending_application_downlink.frm_payload",
"mac_state.pending_application_downlink.priority",
"mac_state.pending_application_downlink.session_key_id",
+ "mac_state.pending_relay_downlink",
+ "mac_state.pending_relay_downlink.raw_payload",
"mac_state.pending_requests",
"mac_state.ping_slot_periodicity",
"mac_state.ping_slot_periodicity.value",
@@ -4207,6 +4353,42 @@
"pending_mac_state.current_parameters.ping_slot_frequency",
"pending_mac_state.current_parameters.rejoin_count_periodicity",
"pending_mac_state.current_parameters.rejoin_time_periodicity",
+ "pending_mac_state.current_parameters.relay",
+ "pending_mac_state.current_parameters.relay.mode",
+ "pending_mac_state.current_parameters.relay.mode.served",
+ "pending_mac_state.current_parameters.relay.mode.served.backoff",
+ "pending_mac_state.current_parameters.relay.mode.served.mode",
+ "pending_mac_state.current_parameters.relay.mode.served.mode.always",
+ "pending_mac_state.current_parameters.relay.mode.served.mode.dynamic",
+ "pending_mac_state.current_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "pending_mac_state.current_parameters.relay.mode.served.mode.end_device_controlled",
+ "pending_mac_state.current_parameters.relay.mode.served.second_channel",
+ "pending_mac_state.current_parameters.relay.mode.served.second_channel.ack_offset",
+ "pending_mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index",
+ "pending_mac_state.current_parameters.relay.mode.served.second_channel.frequency",
+ "pending_mac_state.current_parameters.relay.mode.served.serving_device_id",
+ "pending_mac_state.current_parameters.relay.mode.serving",
+ "pending_mac_state.current_parameters.relay.mode.serving.cad_periodicity",
+ "pending_mac_state.current_parameters.relay.mode.serving.default_channel_index",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.notifications",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.overall",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.reset_behavior",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "pending_mac_state.current_parameters.relay.mode.serving.second_channel",
+ "pending_mac_state.current_parameters.relay.mode.serving.second_channel.ack_offset",
+ "pending_mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "pending_mac_state.current_parameters.relay.mode.serving.second_channel.frequency",
+ "pending_mac_state.current_parameters.relay.mode.serving.uplink_forwarding_rules",
"pending_mac_state.current_parameters.rx1_data_rate_offset",
"pending_mac_state.current_parameters.rx1_delay",
"pending_mac_state.current_parameters.rx2_data_rate_index",
@@ -4232,6 +4414,42 @@
"pending_mac_state.desired_parameters.ping_slot_frequency",
"pending_mac_state.desired_parameters.rejoin_count_periodicity",
"pending_mac_state.desired_parameters.rejoin_time_periodicity",
+ "pending_mac_state.desired_parameters.relay",
+ "pending_mac_state.desired_parameters.relay.mode",
+ "pending_mac_state.desired_parameters.relay.mode.served",
+ "pending_mac_state.desired_parameters.relay.mode.served.backoff",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode.always",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode.dynamic",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode.end_device_controlled",
+ "pending_mac_state.desired_parameters.relay.mode.served.second_channel",
+ "pending_mac_state.desired_parameters.relay.mode.served.second_channel.ack_offset",
+ "pending_mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index",
+ "pending_mac_state.desired_parameters.relay.mode.served.second_channel.frequency",
+ "pending_mac_state.desired_parameters.relay.mode.served.serving_device_id",
+ "pending_mac_state.desired_parameters.relay.mode.serving",
+ "pending_mac_state.desired_parameters.relay.mode.serving.cad_periodicity",
+ "pending_mac_state.desired_parameters.relay.mode.serving.default_channel_index",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.overall",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.reset_behavior",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "pending_mac_state.desired_parameters.relay.mode.serving.second_channel",
+ "pending_mac_state.desired_parameters.relay.mode.serving.second_channel.ack_offset",
+ "pending_mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "pending_mac_state.desired_parameters.relay.mode.serving.second_channel.frequency",
+ "pending_mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules",
"pending_mac_state.desired_parameters.rx1_data_rate_offset",
"pending_mac_state.desired_parameters.rx1_delay",
"pending_mac_state.desired_parameters.rx2_data_rate_index",
@@ -4405,6 +4623,42 @@
"mac_settings.desired_ping_slot_data_rate_index.value",
"mac_settings.desired_ping_slot_frequency",
"mac_settings.desired_ping_slot_frequency.value",
+ "mac_settings.desired_relay",
+ "mac_settings.desired_relay.mode",
+ "mac_settings.desired_relay.mode.served",
+ "mac_settings.desired_relay.mode.served.backoff",
+ "mac_settings.desired_relay.mode.served.mode",
+ "mac_settings.desired_relay.mode.served.mode.always",
+ "mac_settings.desired_relay.mode.served.mode.dynamic",
+ "mac_settings.desired_relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_settings.desired_relay.mode.served.mode.end_device_controlled",
+ "mac_settings.desired_relay.mode.served.second_channel",
+ "mac_settings.desired_relay.mode.served.second_channel.ack_offset",
+ "mac_settings.desired_relay.mode.served.second_channel.data_rate_index",
+ "mac_settings.desired_relay.mode.served.second_channel.frequency",
+ "mac_settings.desired_relay.mode.served.serving_device_id",
+ "mac_settings.desired_relay.mode.serving",
+ "mac_settings.desired_relay.mode.serving.cad_periodicity",
+ "mac_settings.desired_relay.mode.serving.default_channel_index",
+ "mac_settings.desired_relay.mode.serving.limits",
+ "mac_settings.desired_relay.mode.serving.limits.join_requests",
+ "mac_settings.desired_relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_settings.desired_relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_settings.desired_relay.mode.serving.limits.notifications",
+ "mac_settings.desired_relay.mode.serving.limits.notifications.bucket_size",
+ "mac_settings.desired_relay.mode.serving.limits.notifications.reload_rate",
+ "mac_settings.desired_relay.mode.serving.limits.overall",
+ "mac_settings.desired_relay.mode.serving.limits.overall.bucket_size",
+ "mac_settings.desired_relay.mode.serving.limits.overall.reload_rate",
+ "mac_settings.desired_relay.mode.serving.limits.reset_behavior",
+ "mac_settings.desired_relay.mode.serving.limits.uplink_messages",
+ "mac_settings.desired_relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_settings.desired_relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_settings.desired_relay.mode.serving.second_channel",
+ "mac_settings.desired_relay.mode.serving.second_channel.ack_offset",
+ "mac_settings.desired_relay.mode.serving.second_channel.data_rate_index",
+ "mac_settings.desired_relay.mode.serving.second_channel.frequency",
+ "mac_settings.desired_relay.mode.serving.uplink_forwarding_rules",
"mac_settings.desired_rx1_data_rate_offset",
"mac_settings.desired_rx1_data_rate_offset.value",
"mac_settings.desired_rx1_delay",
@@ -4422,6 +4676,42 @@
"mac_settings.ping_slot_frequency.value",
"mac_settings.ping_slot_periodicity",
"mac_settings.ping_slot_periodicity.value",
+ "mac_settings.relay",
+ "mac_settings.relay.mode",
+ "mac_settings.relay.mode.served",
+ "mac_settings.relay.mode.served.backoff",
+ "mac_settings.relay.mode.served.mode",
+ "mac_settings.relay.mode.served.mode.always",
+ "mac_settings.relay.mode.served.mode.dynamic",
+ "mac_settings.relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_settings.relay.mode.served.mode.end_device_controlled",
+ "mac_settings.relay.mode.served.second_channel",
+ "mac_settings.relay.mode.served.second_channel.ack_offset",
+ "mac_settings.relay.mode.served.second_channel.data_rate_index",
+ "mac_settings.relay.mode.served.second_channel.frequency",
+ "mac_settings.relay.mode.served.serving_device_id",
+ "mac_settings.relay.mode.serving",
+ "mac_settings.relay.mode.serving.cad_periodicity",
+ "mac_settings.relay.mode.serving.default_channel_index",
+ "mac_settings.relay.mode.serving.limits",
+ "mac_settings.relay.mode.serving.limits.join_requests",
+ "mac_settings.relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_settings.relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_settings.relay.mode.serving.limits.notifications",
+ "mac_settings.relay.mode.serving.limits.notifications.bucket_size",
+ "mac_settings.relay.mode.serving.limits.notifications.reload_rate",
+ "mac_settings.relay.mode.serving.limits.overall",
+ "mac_settings.relay.mode.serving.limits.overall.bucket_size",
+ "mac_settings.relay.mode.serving.limits.overall.reload_rate",
+ "mac_settings.relay.mode.serving.limits.reset_behavior",
+ "mac_settings.relay.mode.serving.limits.uplink_messages",
+ "mac_settings.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_settings.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_settings.relay.mode.serving.second_channel",
+ "mac_settings.relay.mode.serving.second_channel.ack_offset",
+ "mac_settings.relay.mode.serving.second_channel.data_rate_index",
+ "mac_settings.relay.mode.serving.second_channel.frequency",
+ "mac_settings.relay.mode.serving.uplink_forwarding_rules",
"mac_settings.resets_f_cnt",
"mac_settings.resets_f_cnt.value",
"mac_settings.rx1_data_rate_offset",
@@ -4464,6 +4754,42 @@
"mac_state.current_parameters.ping_slot_frequency",
"mac_state.current_parameters.rejoin_count_periodicity",
"mac_state.current_parameters.rejoin_time_periodicity",
+ "mac_state.current_parameters.relay",
+ "mac_state.current_parameters.relay.mode",
+ "mac_state.current_parameters.relay.mode.served",
+ "mac_state.current_parameters.relay.mode.served.backoff",
+ "mac_state.current_parameters.relay.mode.served.mode",
+ "mac_state.current_parameters.relay.mode.served.mode.always",
+ "mac_state.current_parameters.relay.mode.served.mode.dynamic",
+ "mac_state.current_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_state.current_parameters.relay.mode.served.mode.end_device_controlled",
+ "mac_state.current_parameters.relay.mode.served.second_channel",
+ "mac_state.current_parameters.relay.mode.served.second_channel.ack_offset",
+ "mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index",
+ "mac_state.current_parameters.relay.mode.served.second_channel.frequency",
+ "mac_state.current_parameters.relay.mode.served.serving_device_id",
+ "mac_state.current_parameters.relay.mode.serving",
+ "mac_state.current_parameters.relay.mode.serving.cad_periodicity",
+ "mac_state.current_parameters.relay.mode.serving.default_channel_index",
+ "mac_state.current_parameters.relay.mode.serving.limits",
+ "mac_state.current_parameters.relay.mode.serving.limits.join_requests",
+ "mac_state.current_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.limits.notifications",
+ "mac_state.current_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.limits.overall",
+ "mac_state.current_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.limits.reset_behavior",
+ "mac_state.current_parameters.relay.mode.serving.limits.uplink_messages",
+ "mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.second_channel",
+ "mac_state.current_parameters.relay.mode.serving.second_channel.ack_offset",
+ "mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "mac_state.current_parameters.relay.mode.serving.second_channel.frequency",
+ "mac_state.current_parameters.relay.mode.serving.uplink_forwarding_rules",
"mac_state.current_parameters.rx1_data_rate_offset",
"mac_state.current_parameters.rx1_delay",
"mac_state.current_parameters.rx2_data_rate_index",
@@ -4489,6 +4815,42 @@
"mac_state.desired_parameters.ping_slot_frequency",
"mac_state.desired_parameters.rejoin_count_periodicity",
"mac_state.desired_parameters.rejoin_time_periodicity",
+ "mac_state.desired_parameters.relay",
+ "mac_state.desired_parameters.relay.mode",
+ "mac_state.desired_parameters.relay.mode.served",
+ "mac_state.desired_parameters.relay.mode.served.backoff",
+ "mac_state.desired_parameters.relay.mode.served.mode",
+ "mac_state.desired_parameters.relay.mode.served.mode.always",
+ "mac_state.desired_parameters.relay.mode.served.mode.dynamic",
+ "mac_state.desired_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_state.desired_parameters.relay.mode.served.mode.end_device_controlled",
+ "mac_state.desired_parameters.relay.mode.served.second_channel",
+ "mac_state.desired_parameters.relay.mode.served.second_channel.ack_offset",
+ "mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index",
+ "mac_state.desired_parameters.relay.mode.served.second_channel.frequency",
+ "mac_state.desired_parameters.relay.mode.served.serving_device_id",
+ "mac_state.desired_parameters.relay.mode.serving",
+ "mac_state.desired_parameters.relay.mode.serving.cad_periodicity",
+ "mac_state.desired_parameters.relay.mode.serving.default_channel_index",
+ "mac_state.desired_parameters.relay.mode.serving.limits",
+ "mac_state.desired_parameters.relay.mode.serving.limits.join_requests",
+ "mac_state.desired_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.limits.notifications",
+ "mac_state.desired_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.limits.overall",
+ "mac_state.desired_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.limits.reset_behavior",
+ "mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages",
+ "mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel.ack_offset",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel.frequency",
+ "mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules",
"mac_state.desired_parameters.rx1_data_rate_offset",
"mac_state.desired_parameters.rx1_delay",
"mac_state.desired_parameters.rx2_data_rate_index",
@@ -4513,6 +4875,8 @@
"mac_state.pending_application_downlink.frm_payload",
"mac_state.pending_application_downlink.priority",
"mac_state.pending_application_downlink.session_key_id",
+ "mac_state.pending_relay_downlink",
+ "mac_state.pending_relay_downlink.raw_payload",
"mac_state.pending_requests",
"mac_state.ping_slot_periodicity",
"mac_state.ping_slot_periodicity.value",
@@ -4548,6 +4912,42 @@
"pending_mac_state.current_parameters.ping_slot_frequency",
"pending_mac_state.current_parameters.rejoin_count_periodicity",
"pending_mac_state.current_parameters.rejoin_time_periodicity",
+ "pending_mac_state.current_parameters.relay",
+ "pending_mac_state.current_parameters.relay.mode",
+ "pending_mac_state.current_parameters.relay.mode.served",
+ "pending_mac_state.current_parameters.relay.mode.served.backoff",
+ "pending_mac_state.current_parameters.relay.mode.served.mode",
+ "pending_mac_state.current_parameters.relay.mode.served.mode.always",
+ "pending_mac_state.current_parameters.relay.mode.served.mode.dynamic",
+ "pending_mac_state.current_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "pending_mac_state.current_parameters.relay.mode.served.mode.end_device_controlled",
+ "pending_mac_state.current_parameters.relay.mode.served.second_channel",
+ "pending_mac_state.current_parameters.relay.mode.served.second_channel.ack_offset",
+ "pending_mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index",
+ "pending_mac_state.current_parameters.relay.mode.served.second_channel.frequency",
+ "pending_mac_state.current_parameters.relay.mode.served.serving_device_id",
+ "pending_mac_state.current_parameters.relay.mode.serving",
+ "pending_mac_state.current_parameters.relay.mode.serving.cad_periodicity",
+ "pending_mac_state.current_parameters.relay.mode.serving.default_channel_index",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.notifications",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.overall",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.reset_behavior",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "pending_mac_state.current_parameters.relay.mode.serving.second_channel",
+ "pending_mac_state.current_parameters.relay.mode.serving.second_channel.ack_offset",
+ "pending_mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "pending_mac_state.current_parameters.relay.mode.serving.second_channel.frequency",
+ "pending_mac_state.current_parameters.relay.mode.serving.uplink_forwarding_rules",
"pending_mac_state.current_parameters.rx1_data_rate_offset",
"pending_mac_state.current_parameters.rx1_delay",
"pending_mac_state.current_parameters.rx2_data_rate_index",
@@ -4573,6 +4973,42 @@
"pending_mac_state.desired_parameters.ping_slot_frequency",
"pending_mac_state.desired_parameters.rejoin_count_periodicity",
"pending_mac_state.desired_parameters.rejoin_time_periodicity",
+ "pending_mac_state.desired_parameters.relay",
+ "pending_mac_state.desired_parameters.relay.mode",
+ "pending_mac_state.desired_parameters.relay.mode.served",
+ "pending_mac_state.desired_parameters.relay.mode.served.backoff",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode.always",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode.dynamic",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode.end_device_controlled",
+ "pending_mac_state.desired_parameters.relay.mode.served.second_channel",
+ "pending_mac_state.desired_parameters.relay.mode.served.second_channel.ack_offset",
+ "pending_mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index",
+ "pending_mac_state.desired_parameters.relay.mode.served.second_channel.frequency",
+ "pending_mac_state.desired_parameters.relay.mode.served.serving_device_id",
+ "pending_mac_state.desired_parameters.relay.mode.serving",
+ "pending_mac_state.desired_parameters.relay.mode.serving.cad_periodicity",
+ "pending_mac_state.desired_parameters.relay.mode.serving.default_channel_index",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.overall",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.reset_behavior",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "pending_mac_state.desired_parameters.relay.mode.serving.second_channel",
+ "pending_mac_state.desired_parameters.relay.mode.serving.second_channel.ack_offset",
+ "pending_mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "pending_mac_state.desired_parameters.relay.mode.serving.second_channel.frequency",
+ "pending_mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules",
"pending_mac_state.desired_parameters.rx1_data_rate_offset",
"pending_mac_state.desired_parameters.rx1_delay",
"pending_mac_state.desired_parameters.rx2_data_rate_index",
@@ -4742,6 +5178,42 @@
"mac_settings.desired_ping_slot_data_rate_index.value",
"mac_settings.desired_ping_slot_frequency",
"mac_settings.desired_ping_slot_frequency.value",
+ "mac_settings.desired_relay",
+ "mac_settings.desired_relay.mode",
+ "mac_settings.desired_relay.mode.served",
+ "mac_settings.desired_relay.mode.served.backoff",
+ "mac_settings.desired_relay.mode.served.mode",
+ "mac_settings.desired_relay.mode.served.mode.always",
+ "mac_settings.desired_relay.mode.served.mode.dynamic",
+ "mac_settings.desired_relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_settings.desired_relay.mode.served.mode.end_device_controlled",
+ "mac_settings.desired_relay.mode.served.second_channel",
+ "mac_settings.desired_relay.mode.served.second_channel.ack_offset",
+ "mac_settings.desired_relay.mode.served.second_channel.data_rate_index",
+ "mac_settings.desired_relay.mode.served.second_channel.frequency",
+ "mac_settings.desired_relay.mode.served.serving_device_id",
+ "mac_settings.desired_relay.mode.serving",
+ "mac_settings.desired_relay.mode.serving.cad_periodicity",
+ "mac_settings.desired_relay.mode.serving.default_channel_index",
+ "mac_settings.desired_relay.mode.serving.limits",
+ "mac_settings.desired_relay.mode.serving.limits.join_requests",
+ "mac_settings.desired_relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_settings.desired_relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_settings.desired_relay.mode.serving.limits.notifications",
+ "mac_settings.desired_relay.mode.serving.limits.notifications.bucket_size",
+ "mac_settings.desired_relay.mode.serving.limits.notifications.reload_rate",
+ "mac_settings.desired_relay.mode.serving.limits.overall",
+ "mac_settings.desired_relay.mode.serving.limits.overall.bucket_size",
+ "mac_settings.desired_relay.mode.serving.limits.overall.reload_rate",
+ "mac_settings.desired_relay.mode.serving.limits.reset_behavior",
+ "mac_settings.desired_relay.mode.serving.limits.uplink_messages",
+ "mac_settings.desired_relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_settings.desired_relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_settings.desired_relay.mode.serving.second_channel",
+ "mac_settings.desired_relay.mode.serving.second_channel.ack_offset",
+ "mac_settings.desired_relay.mode.serving.second_channel.data_rate_index",
+ "mac_settings.desired_relay.mode.serving.second_channel.frequency",
+ "mac_settings.desired_relay.mode.serving.uplink_forwarding_rules",
"mac_settings.desired_rx1_data_rate_offset",
"mac_settings.desired_rx1_data_rate_offset.value",
"mac_settings.desired_rx1_delay",
@@ -4759,6 +5231,42 @@
"mac_settings.ping_slot_frequency.value",
"mac_settings.ping_slot_periodicity",
"mac_settings.ping_slot_periodicity.value",
+ "mac_settings.relay",
+ "mac_settings.relay.mode",
+ "mac_settings.relay.mode.served",
+ "mac_settings.relay.mode.served.backoff",
+ "mac_settings.relay.mode.served.mode",
+ "mac_settings.relay.mode.served.mode.always",
+ "mac_settings.relay.mode.served.mode.dynamic",
+ "mac_settings.relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_settings.relay.mode.served.mode.end_device_controlled",
+ "mac_settings.relay.mode.served.second_channel",
+ "mac_settings.relay.mode.served.second_channel.ack_offset",
+ "mac_settings.relay.mode.served.second_channel.data_rate_index",
+ "mac_settings.relay.mode.served.second_channel.frequency",
+ "mac_settings.relay.mode.served.serving_device_id",
+ "mac_settings.relay.mode.serving",
+ "mac_settings.relay.mode.serving.cad_periodicity",
+ "mac_settings.relay.mode.serving.default_channel_index",
+ "mac_settings.relay.mode.serving.limits",
+ "mac_settings.relay.mode.serving.limits.join_requests",
+ "mac_settings.relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_settings.relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_settings.relay.mode.serving.limits.notifications",
+ "mac_settings.relay.mode.serving.limits.notifications.bucket_size",
+ "mac_settings.relay.mode.serving.limits.notifications.reload_rate",
+ "mac_settings.relay.mode.serving.limits.overall",
+ "mac_settings.relay.mode.serving.limits.overall.bucket_size",
+ "mac_settings.relay.mode.serving.limits.overall.reload_rate",
+ "mac_settings.relay.mode.serving.limits.reset_behavior",
+ "mac_settings.relay.mode.serving.limits.uplink_messages",
+ "mac_settings.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_settings.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_settings.relay.mode.serving.second_channel",
+ "mac_settings.relay.mode.serving.second_channel.ack_offset",
+ "mac_settings.relay.mode.serving.second_channel.data_rate_index",
+ "mac_settings.relay.mode.serving.second_channel.frequency",
+ "mac_settings.relay.mode.serving.uplink_forwarding_rules",
"mac_settings.resets_f_cnt",
"mac_settings.resets_f_cnt.value",
"mac_settings.rx1_data_rate_offset",
@@ -4801,6 +5309,42 @@
"mac_state.current_parameters.ping_slot_frequency",
"mac_state.current_parameters.rejoin_count_periodicity",
"mac_state.current_parameters.rejoin_time_periodicity",
+ "mac_state.current_parameters.relay",
+ "mac_state.current_parameters.relay.mode",
+ "mac_state.current_parameters.relay.mode.served",
+ "mac_state.current_parameters.relay.mode.served.backoff",
+ "mac_state.current_parameters.relay.mode.served.mode",
+ "mac_state.current_parameters.relay.mode.served.mode.always",
+ "mac_state.current_parameters.relay.mode.served.mode.dynamic",
+ "mac_state.current_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_state.current_parameters.relay.mode.served.mode.end_device_controlled",
+ "mac_state.current_parameters.relay.mode.served.second_channel",
+ "mac_state.current_parameters.relay.mode.served.second_channel.ack_offset",
+ "mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index",
+ "mac_state.current_parameters.relay.mode.served.second_channel.frequency",
+ "mac_state.current_parameters.relay.mode.served.serving_device_id",
+ "mac_state.current_parameters.relay.mode.serving",
+ "mac_state.current_parameters.relay.mode.serving.cad_periodicity",
+ "mac_state.current_parameters.relay.mode.serving.default_channel_index",
+ "mac_state.current_parameters.relay.mode.serving.limits",
+ "mac_state.current_parameters.relay.mode.serving.limits.join_requests",
+ "mac_state.current_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.limits.notifications",
+ "mac_state.current_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.limits.overall",
+ "mac_state.current_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.limits.reset_behavior",
+ "mac_state.current_parameters.relay.mode.serving.limits.uplink_messages",
+ "mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_state.current_parameters.relay.mode.serving.second_channel",
+ "mac_state.current_parameters.relay.mode.serving.second_channel.ack_offset",
+ "mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "mac_state.current_parameters.relay.mode.serving.second_channel.frequency",
+ "mac_state.current_parameters.relay.mode.serving.uplink_forwarding_rules",
"mac_state.current_parameters.rx1_data_rate_offset",
"mac_state.current_parameters.rx1_delay",
"mac_state.current_parameters.rx2_data_rate_index",
@@ -4826,6 +5370,42 @@
"mac_state.desired_parameters.ping_slot_frequency",
"mac_state.desired_parameters.rejoin_count_periodicity",
"mac_state.desired_parameters.rejoin_time_periodicity",
+ "mac_state.desired_parameters.relay",
+ "mac_state.desired_parameters.relay.mode",
+ "mac_state.desired_parameters.relay.mode.served",
+ "mac_state.desired_parameters.relay.mode.served.backoff",
+ "mac_state.desired_parameters.relay.mode.served.mode",
+ "mac_state.desired_parameters.relay.mode.served.mode.always",
+ "mac_state.desired_parameters.relay.mode.served.mode.dynamic",
+ "mac_state.desired_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "mac_state.desired_parameters.relay.mode.served.mode.end_device_controlled",
+ "mac_state.desired_parameters.relay.mode.served.second_channel",
+ "mac_state.desired_parameters.relay.mode.served.second_channel.ack_offset",
+ "mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index",
+ "mac_state.desired_parameters.relay.mode.served.second_channel.frequency",
+ "mac_state.desired_parameters.relay.mode.served.serving_device_id",
+ "mac_state.desired_parameters.relay.mode.serving",
+ "mac_state.desired_parameters.relay.mode.serving.cad_periodicity",
+ "mac_state.desired_parameters.relay.mode.serving.default_channel_index",
+ "mac_state.desired_parameters.relay.mode.serving.limits",
+ "mac_state.desired_parameters.relay.mode.serving.limits.join_requests",
+ "mac_state.desired_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.limits.notifications",
+ "mac_state.desired_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.limits.overall",
+ "mac_state.desired_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.limits.reset_behavior",
+ "mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages",
+ "mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel.ack_offset",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "mac_state.desired_parameters.relay.mode.serving.second_channel.frequency",
+ "mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules",
"mac_state.desired_parameters.rx1_data_rate_offset",
"mac_state.desired_parameters.rx1_delay",
"mac_state.desired_parameters.rx2_data_rate_index",
@@ -4850,6 +5430,8 @@
"mac_state.pending_application_downlink.frm_payload",
"mac_state.pending_application_downlink.priority",
"mac_state.pending_application_downlink.session_key_id",
+ "mac_state.pending_relay_downlink",
+ "mac_state.pending_relay_downlink.raw_payload",
"mac_state.pending_requests",
"mac_state.ping_slot_periodicity",
"mac_state.ping_slot_periodicity.value",
@@ -4885,6 +5467,42 @@
"pending_mac_state.current_parameters.ping_slot_frequency",
"pending_mac_state.current_parameters.rejoin_count_periodicity",
"pending_mac_state.current_parameters.rejoin_time_periodicity",
+ "pending_mac_state.current_parameters.relay",
+ "pending_mac_state.current_parameters.relay.mode",
+ "pending_mac_state.current_parameters.relay.mode.served",
+ "pending_mac_state.current_parameters.relay.mode.served.backoff",
+ "pending_mac_state.current_parameters.relay.mode.served.mode",
+ "pending_mac_state.current_parameters.relay.mode.served.mode.always",
+ "pending_mac_state.current_parameters.relay.mode.served.mode.dynamic",
+ "pending_mac_state.current_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "pending_mac_state.current_parameters.relay.mode.served.mode.end_device_controlled",
+ "pending_mac_state.current_parameters.relay.mode.served.second_channel",
+ "pending_mac_state.current_parameters.relay.mode.served.second_channel.ack_offset",
+ "pending_mac_state.current_parameters.relay.mode.served.second_channel.data_rate_index",
+ "pending_mac_state.current_parameters.relay.mode.served.second_channel.frequency",
+ "pending_mac_state.current_parameters.relay.mode.served.serving_device_id",
+ "pending_mac_state.current_parameters.relay.mode.serving",
+ "pending_mac_state.current_parameters.relay.mode.serving.cad_periodicity",
+ "pending_mac_state.current_parameters.relay.mode.serving.default_channel_index",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.notifications",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.overall",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.reset_behavior",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "pending_mac_state.current_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "pending_mac_state.current_parameters.relay.mode.serving.second_channel",
+ "pending_mac_state.current_parameters.relay.mode.serving.second_channel.ack_offset",
+ "pending_mac_state.current_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "pending_mac_state.current_parameters.relay.mode.serving.second_channel.frequency",
+ "pending_mac_state.current_parameters.relay.mode.serving.uplink_forwarding_rules",
"pending_mac_state.current_parameters.rx1_data_rate_offset",
"pending_mac_state.current_parameters.rx1_delay",
"pending_mac_state.current_parameters.rx2_data_rate_index",
@@ -4910,6 +5528,42 @@
"pending_mac_state.desired_parameters.ping_slot_frequency",
"pending_mac_state.desired_parameters.rejoin_count_periodicity",
"pending_mac_state.desired_parameters.rejoin_time_periodicity",
+ "pending_mac_state.desired_parameters.relay",
+ "pending_mac_state.desired_parameters.relay.mode",
+ "pending_mac_state.desired_parameters.relay.mode.served",
+ "pending_mac_state.desired_parameters.relay.mode.served.backoff",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode.always",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode.dynamic",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode.dynamic.smart_enable_level",
+ "pending_mac_state.desired_parameters.relay.mode.served.mode.end_device_controlled",
+ "pending_mac_state.desired_parameters.relay.mode.served.second_channel",
+ "pending_mac_state.desired_parameters.relay.mode.served.second_channel.ack_offset",
+ "pending_mac_state.desired_parameters.relay.mode.served.second_channel.data_rate_index",
+ "pending_mac_state.desired_parameters.relay.mode.served.second_channel.frequency",
+ "pending_mac_state.desired_parameters.relay.mode.served.serving_device_id",
+ "pending_mac_state.desired_parameters.relay.mode.serving",
+ "pending_mac_state.desired_parameters.relay.mode.serving.cad_periodicity",
+ "pending_mac_state.desired_parameters.relay.mode.serving.default_channel_index",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests.bucket_size",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.join_requests.reload_rate",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications.bucket_size",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.notifications.reload_rate",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.overall",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.overall.bucket_size",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.overall.reload_rate",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.reset_behavior",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.bucket_size",
+ "pending_mac_state.desired_parameters.relay.mode.serving.limits.uplink_messages.reload_rate",
+ "pending_mac_state.desired_parameters.relay.mode.serving.second_channel",
+ "pending_mac_state.desired_parameters.relay.mode.serving.second_channel.ack_offset",
+ "pending_mac_state.desired_parameters.relay.mode.serving.second_channel.data_rate_index",
+ "pending_mac_state.desired_parameters.relay.mode.serving.second_channel.frequency",
+ "pending_mac_state.desired_parameters.relay.mode.serving.uplink_forwarding_rules",
"pending_mac_state.desired_parameters.rx1_data_rate_offset",
"pending_mac_state.desired_parameters.rx1_delay",
"pending_mac_state.desired_parameters.rx2_data_rate_index",
diff --git a/sdk/js/generated/api.json b/sdk/js/generated/api.json
index b5985b6c4a..f23650871f 100644
--- a/sdk/js/generated/api.json
+++ b/sdk/js/generated/api.json
@@ -9378,6 +9378,30 @@
"oneofdecl": "",
"defaultValue": ""
},
+ {
+ "name": "relay_forward_delay",
+ "description": "",
+ "label": "",
+ "type": "Duration",
+ "longType": "google.protobuf.Duration",
+ "fullType": "google.protobuf.Duration",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "relay_receive_delay",
+ "description": "",
+ "label": "",
+ "type": "Duration",
+ "longType": "google.protobuf.Duration",
+ "fullType": "google.protobuf.Duration",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
{
"name": "tx_param_setup_req_support",
"description": "",
@@ -9857,6 +9881,18 @@
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
+ },
+ {
+ "name": "band_id",
+ "description": "",
+ "label": "",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
}
]
},
@@ -10129,6 +10165,18 @@
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
+ },
+ {
+ "name": "band_id",
+ "description": "Optional Band ID to filter the results.",
+ "label": "",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
}
]
},
@@ -17260,7 +17308,7 @@
},
{
"name": "uplink_dwell_time",
- "description": "Whether uplink dwell time is set (400ms).\nIf this field is not set, then the value is either unknown or irrelevant(Network Server cannot modify it).",
+ "description": "Whether uplink dwell time is set (400ms).\nIf unset, then the value is either unknown or irrelevant(Network Server cannot modify it).",
"label": "",
"type": "BoolValue",
"longType": "BoolValue",
@@ -17272,7 +17320,7 @@
},
{
"name": "downlink_dwell_time",
- "description": "Whether downlink dwell time is set (400ms).\nIf this field is not set, then the value is either unknown or irrelevant(Network Server cannot modify it).",
+ "description": "Whether downlink dwell time is set (400ms).\nIf unset, then the value is either unknown or irrelevant(Network Server cannot modify it).",
"label": "",
"type": "BoolValue",
"longType": "BoolValue",
@@ -17317,6 +17365,18 @@
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
+ },
+ {
+ "name": "relay",
+ "description": "Relay parameters.",
+ "label": "",
+ "type": "RelayParameters",
+ "longType": "RelayParameters",
+ "fullType": "ttn.lorawan.v3.RelayParameters",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
}
]
},
@@ -17859,6 +17919,30 @@
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
+ },
+ {
+ "name": "relay",
+ "description": "The relay parameters the end device is using.\nIf unset, the default value from Network Server configuration or regional parameters specification will be used.",
+ "label": "",
+ "type": "RelayParameters",
+ "longType": "RelayParameters",
+ "fullType": "ttn.lorawan.v3.RelayParameters",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "desired_relay",
+ "description": "The relay parameters the Network Server should configure device to use via MAC commands.\nIf unset, the default value from Network Server configuration or regional parameters specification will be used.",
+ "label": "",
+ "type": "RelayParameters",
+ "longType": "RelayParameters",
+ "fullType": "ttn.lorawan.v3.RelayParameters",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
}
]
},
@@ -18211,6 +18295,18 @@
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
+ },
+ {
+ "name": "pending_relay_downlink",
+ "description": "Pending relay downlink contents.\nThe pending downlink will be scheduled to the relay in either Rx1 or Rx2.\nThe pending downlink will be cleared after the scheduling attempt.",
+ "label": "",
+ "type": "RelayForwardDownlinkReq",
+ "longType": "RelayForwardDownlinkReq",
+ "fullType": "ttn.lorawan.v3.RelayForwardDownlinkReq",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
}
]
},
@@ -18911,6 +19007,18 @@
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
+ },
+ {
+ "name": "relay",
+ "description": "",
+ "label": "",
+ "type": "RelayMetadata",
+ "longType": "MACState.UplinkMessage.RxMetadata.RelayMetadata",
+ "fullType": "ttn.lorawan.v3.MACState.UplinkMessage.RxMetadata.RelayMetadata",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
}
]
},
@@ -18925,6 +19033,17 @@
"extensions": [],
"fields": []
},
+ {
+ "name": "RelayMetadata",
+ "longName": "MACState.UplinkMessage.RxMetadata.RelayMetadata",
+ "fullName": "ttn.lorawan.v3.MACState.UplinkMessage.RxMetadata.RelayMetadata",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": false,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": []
+ },
{
"name": "TxSettings",
"longName": "MACState.UplinkMessage.TxSettings",
@@ -18958,53 +19077,45 @@
]
},
{
- "name": "ResetAndGetEndDeviceRequest",
- "longName": "ResetAndGetEndDeviceRequest",
- "fullName": "ttn.lorawan.v3.ResetAndGetEndDeviceRequest",
- "description": "",
+ "name": "RelayParameters",
+ "longName": "RelayParameters",
+ "fullName": "ttn.lorawan.v3.RelayParameters",
+ "description": "RelayParameters represent the parameters of a relay.\nThis is used internally by the Network Server.",
"hasExtensions": false,
"hasFields": true,
- "hasOneofs": false,
+ "hasOneofs": true,
"extensions": [],
"fields": [
{
- "name": "end_device_ids",
- "description": "",
+ "name": "serving",
+ "description": "Parameters related to a relay which is serving end devices.",
"label": "",
- "type": "EndDeviceIdentifiers",
- "longType": "EndDeviceIdentifiers",
- "fullType": "ttn.lorawan.v3.EndDeviceIdentifiers",
+ "type": "ServingRelayParameters",
+ "longType": "ServingRelayParameters",
+ "fullType": "ttn.lorawan.v3.ServingRelayParameters",
"ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "message.required",
- "value": true
- }
- ]
- }
+ "isoneof": true,
+ "oneofdecl": "mode",
+ "defaultValue": ""
},
{
- "name": "field_mask",
- "description": "The names of the end device fields that should be returned.\nSee the API reference for which fields can be returned by the different services.",
+ "name": "served",
+ "description": "Parameters related to an end device served by a relay.",
"label": "",
- "type": "FieldMask",
- "longType": "google.protobuf.FieldMask",
- "fullType": "google.protobuf.FieldMask",
+ "type": "ServedRelayParameters",
+ "longType": "ServedRelayParameters",
+ "fullType": "ttn.lorawan.v3.ServedRelayParameters",
"ismap": false,
- "isoneof": false,
- "oneofdecl": "",
+ "isoneof": true,
+ "oneofdecl": "mode",
"defaultValue": ""
}
]
},
{
- "name": "Session",
- "longName": "Session",
- "fullName": "ttn.lorawan.v3.Session",
+ "name": "RelayUplinkForwardingRule",
+ "longName": "RelayUplinkForwardingRule",
+ "fullName": "ttn.lorawan.v3.RelayUplinkForwardingRule",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -19012,72 +19123,20 @@
"extensions": [],
"fields": [
{
- "name": "dev_addr",
- "description": "Device Address, issued by the Network Server or chosen by device manufacturer in case of testing range (beginning with 00-03).\nKnown by Network Server, Application Server and Join Server. Owned by Network Server.",
- "label": "",
- "type": "bytes",
- "longType": "bytes",
- "fullType": "bytes",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "bytes.len",
- "value": 4
- }
- ]
- }
- },
- {
- "name": "keys",
- "description": "",
- "label": "",
- "type": "SessionKeys",
- "longType": "SessionKeys",
- "fullType": "ttn.lorawan.v3.SessionKeys",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "message.required",
- "value": true
- }
- ]
- }
- },
- {
- "name": "last_f_cnt_up",
- "description": "Last uplink frame counter value used. Network Server only. Application Server assumes the Network Server checked it.",
- "label": "",
- "type": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
- },
- {
- "name": "last_n_f_cnt_down",
- "description": "Last network downlink frame counter value used. Network Server only.",
+ "name": "limits",
+ "description": "Bucket configuration for the served end device.\nIf unset, no individual limits will apply to the end device, but the relay global limitations will apply.",
"label": "",
- "type": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
+ "type": "RelayUplinkForwardLimits",
+ "longType": "RelayUplinkForwardLimits",
+ "fullType": "ttn.lorawan.v3.RelayUplinkForwardLimits",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "last_a_f_cnt_down",
- "description": "Last application downlink frame counter value used. Application Server only.",
+ "name": "last_w_f_cnt",
+ "description": "Last wake on radio frame counter used by the served end device.",
"label": "",
"type": "uint32",
"longType": "uint32",
@@ -19088,36 +19147,36 @@
"defaultValue": ""
},
{
- "name": "last_conf_f_cnt_down",
- "description": "Frame counter of the last confirmed downlink message sent. Network Server only.",
+ "name": "device_id",
+ "description": "End device identifier of the served end device.",
"label": "",
- "type": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "string.max_len",
+ "value": 36
+ },
+ {
+ "name": "string.pattern",
+ "value": "^[a-z0-9](?:[-]?[a-z0-9]){2,}$"
+ }
+ ]
+ }
},
{
- "name": "started_at",
- "description": "Time when the session started. Network Server only.",
+ "name": "session_key_id",
+ "description": "Session key ID of the session keys used to derive the root relay session key.",
"label": "",
- "type": "Timestamp",
- "longType": "google.protobuf.Timestamp",
- "fullType": "google.protobuf.Timestamp",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
- },
- {
- "name": "queued_application_downlinks",
- "description": "Queued Application downlink messages. Stored in Application Server and Network Server.",
- "label": "repeated",
- "type": "ApplicationDownlink",
- "longType": "ApplicationDownlink",
- "fullType": "ttn.lorawan.v3.ApplicationDownlink",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -19126,9 +19185,9 @@
]
},
{
- "name": "SetEndDeviceRequest",
- "longName": "SetEndDeviceRequest",
- "fullName": "ttn.lorawan.v3.SetEndDeviceRequest",
+ "name": "ResetAndGetEndDeviceRequest",
+ "longName": "ResetAndGetEndDeviceRequest",
+ "fullName": "ttn.lorawan.v3.ResetAndGetEndDeviceRequest",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -19136,12 +19195,12 @@
"extensions": [],
"fields": [
{
- "name": "end_device",
+ "name": "end_device_ids",
"description": "",
"label": "",
- "type": "EndDevice",
- "longType": "EndDevice",
- "fullType": "ttn.lorawan.v3.EndDevice",
+ "type": "EndDeviceIdentifiers",
+ "longType": "EndDeviceIdentifiers",
+ "fullType": "ttn.lorawan.v3.EndDeviceIdentifiers",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -19157,7 +19216,7 @@
},
{
"name": "field_mask",
- "description": "The names of the end device fields that should be updated.\nSee the API reference for which fields can be set on the different services.",
+ "description": "The names of the end device fields that should be returned.\nSee the API reference for which fields can be returned by the different services.",
"label": "",
"type": "FieldMask",
"longType": "google.protobuf.FieldMask",
@@ -19170,22 +19229,58 @@
]
},
{
- "name": "UpdateEndDeviceRequest",
- "longName": "UpdateEndDeviceRequest",
- "fullName": "ttn.lorawan.v3.UpdateEndDeviceRequest",
+ "name": "ServedRelayParameters",
+ "longName": "ServedRelayParameters",
+ "fullName": "ttn.lorawan.v3.ServedRelayParameters",
"description": "",
"hasExtensions": false,
"hasFields": true,
- "hasOneofs": false,
+ "hasOneofs": true,
"extensions": [],
"fields": [
{
- "name": "end_device",
- "description": "",
+ "name": "always",
+ "description": "The end device will always attempt to use the relay mode in order to send uplink messages.",
"label": "",
- "type": "EndDevice",
- "longType": "EndDevice",
- "fullType": "ttn.lorawan.v3.EndDevice",
+ "type": "RelayEndDeviceAlwaysMode",
+ "longType": "RelayEndDeviceAlwaysMode",
+ "fullType": "ttn.lorawan.v3.RelayEndDeviceAlwaysMode",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "mode",
+ "defaultValue": ""
+ },
+ {
+ "name": "dynamic",
+ "description": "The end device will attempt to use relay mode only after a number of uplink messages have been sent without\nreceiving a valid a downlink message.",
+ "label": "",
+ "type": "RelayEndDeviceDynamicMode",
+ "longType": "RelayEndDeviceDynamicMode",
+ "fullType": "ttn.lorawan.v3.RelayEndDeviceDynamicMode",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "mode",
+ "defaultValue": ""
+ },
+ {
+ "name": "end_device_controlled",
+ "description": "The end device will control when it uses the relay mode. This is the default mode.",
+ "label": "",
+ "type": "RelayEndDeviceControlledMode",
+ "longType": "RelayEndDeviceControlledMode",
+ "fullType": "ttn.lorawan.v3.RelayEndDeviceControlledMode",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "mode",
+ "defaultValue": ""
+ },
+ {
+ "name": "backoff",
+ "description": "Number of uplinks to be sent without a wake on radio frame.",
+ "label": "",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -19193,552 +19288,423 @@
"options": {
"validate.rules": [
{
- "name": "message.required",
- "value": true
+ "name": "uint32.lte",
+ "value": 63
}
]
}
},
{
- "name": "field_mask",
- "description": "The names of the end device fields that should be updated.\nSee the API reference for which fields can be set on the different services.",
+ "name": "second_channel",
+ "description": "Second wake on radio channel configuration.",
"label": "",
- "type": "FieldMask",
- "longType": "google.protobuf.FieldMask",
- "fullType": "google.protobuf.FieldMask",
+ "type": "RelaySecondChannel",
+ "longType": "RelaySecondChannel",
+ "fullType": "ttn.lorawan.v3.RelaySecondChannel",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
+ },
+ {
+ "name": "serving_device_id",
+ "description": "End device identifier of the serving end device.",
+ "label": "",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "string.max_len",
+ "value": 36
+ },
+ {
+ "name": "string.pattern",
+ "value": "^[a-z0-9](?:[-]?[a-z0-9]){2,}$"
+ }
+ ]
+ }
}
]
- }
- ],
- "services": []
- },
- {
- "name": "ttn/lorawan/v3/end_device_services.proto",
- "description": "",
- "package": "ttn.lorawan.v3",
- "hasEnums": false,
- "hasExtensions": false,
- "hasMessages": false,
- "hasServices": true,
- "enums": [],
- "extensions": [],
- "messages": [],
- "services": [
+ },
{
- "name": "EndDeviceBatchRegistry",
- "longName": "EndDeviceBatchRegistry",
- "fullName": "ttn.lorawan.v3.EndDeviceBatchRegistry",
- "description": "The EndDeviceBatchRegistry service, exposed by the Identity Server, is used to manage\nend device registrations in batches.",
- "methods": [
+ "name": "ServingRelayForwardingLimits",
+ "longName": "ServingRelayForwardingLimits",
+ "fullName": "ttn.lorawan.v3.ServingRelayForwardingLimits",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "Get",
- "description": "Get a batch of end devices with the given identifiers, selecting the fields specified\nin the field mask.\nMore or less fields may be returned, depending on the rights of the caller.\nDevices not found are skipped and no error is returned.",
- "requestType": "BatchGetEndDevicesRequest",
- "requestLongType": "BatchGetEndDevicesRequest",
- "requestFullType": "ttn.lorawan.v3.BatchGetEndDevicesRequest",
- "requestStreaming": false,
- "responseType": "EndDevices",
- "responseLongType": "EndDevices",
- "responseFullType": "ttn.lorawan.v3.EndDevices",
- "responseStreaming": false,
- "options": {
- "google.api.http": {
- "rules": [
- {
- "method": "GET",
- "pattern": "/applications/{application_ids.application_id}/devices/batch"
- }
- ]
- }
- }
+ "name": "reset_behavior",
+ "description": "Reset behavior of the buckets upon limit update.",
+ "label": "",
+ "type": "RelayResetLimitCounter",
+ "longType": "RelayResetLimitCounter",
+ "fullType": "ttn.lorawan.v3.RelayResetLimitCounter",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
},
{
- "name": "Delete",
- "description": "Delete a batch of end devices with the given IDs.\n\nThis operation is atomic; either all devices are deleted or none.\nDevices not found are skipped and no error is returned.\nBefore calling this RPC, use the corresponding BatchDelete RPCs\nof NsEndDeviceRegistry, AsEndDeviceRegistry and\noptionally the JsEndDeviceRegistry to delete the end devices.\nIf the devices were claimed on a Join Server, use the BatchUnclaim RPC\nof the DeviceClaimingServer.\nThis is NOT done automatically.",
- "requestType": "BatchDeleteEndDevicesRequest",
- "requestLongType": "BatchDeleteEndDevicesRequest",
- "requestFullType": "ttn.lorawan.v3.BatchDeleteEndDevicesRequest",
- "requestStreaming": false,
- "responseType": "Empty",
- "responseLongType": ".google.protobuf.Empty",
- "responseFullType": "google.protobuf.Empty",
- "responseStreaming": false,
- "options": {
- "google.api.http": {
- "rules": [
- {
- "method": "DELETE",
- "pattern": "/applications/{application_ids.application_id}/devices/batch"
- }
- ]
- }
- }
+ "name": "join_requests",
+ "description": "Bucket configuration for join requests.\nIf unset, no individual limits will apply to join requests, but the relay overall limitations will apply.",
+ "label": "",
+ "type": "RelayForwardLimits",
+ "longType": "RelayForwardLimits",
+ "fullType": "ttn.lorawan.v3.RelayForwardLimits",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "notifications",
+ "description": "Bucket configuration for unknown device notifications.\nIf unset, no individual limits will apply to unknown end device notifications, but the relay overall\nlimitations will still apply.",
+ "label": "",
+ "type": "RelayForwardLimits",
+ "longType": "RelayForwardLimits",
+ "fullType": "ttn.lorawan.v3.RelayForwardLimits",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "uplink_messages",
+ "description": "Bucket configuration for uplink messages across all served end devices.\nIf unset, no individual limits will apply to uplink messages across all served end devices, but the relay\noverall limitations will still apply.",
+ "label": "",
+ "type": "RelayForwardLimits",
+ "longType": "RelayForwardLimits",
+ "fullType": "ttn.lorawan.v3.RelayForwardLimits",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "overall",
+ "description": "Bucket configuration for all relay messages.\nIf unset, no overall limits will apply to the relay, but individual limitations will still apply.",
+ "label": "",
+ "type": "RelayForwardLimits",
+ "longType": "RelayForwardLimits",
+ "fullType": "ttn.lorawan.v3.RelayForwardLimits",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
}
]
},
{
- "name": "EndDeviceRegistry",
- "longName": "EndDeviceRegistry",
- "fullName": "ttn.lorawan.v3.EndDeviceRegistry",
- "description": "The EndDeviceRegistry service, exposed by the Identity Server, is used to manage\nend device registrations.\n\nAfter registering an end device, it also needs to be registered in\nthe NsEndDeviceRegistry that is exposed by the Network Server,\nthe AsEndDeviceRegistry that is exposed by the Application Server,\nand the JsEndDeviceRegistry that is exposed by the Join Server.\n\nBefore deleting an end device it first needs to be deleted from the\nNsEndDeviceRegistry, the AsEndDeviceRegistry and the JsEndDeviceRegistry.",
- "methods": [
+ "name": "ServingRelayParameters",
+ "longName": "ServingRelayParameters",
+ "fullName": "ttn.lorawan.v3.ServingRelayParameters",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "Create",
- "description": "Create a new end device within an application.\n\nAfter registering an end device, it also needs to be registered in\nthe NsEndDeviceRegistry that is exposed by the Network Server,\nthe AsEndDeviceRegistry that is exposed by the Application Server,\nand the JsEndDeviceRegistry that is exposed by the Join Server.",
- "requestType": "CreateEndDeviceRequest",
- "requestLongType": "CreateEndDeviceRequest",
- "requestFullType": "ttn.lorawan.v3.CreateEndDeviceRequest",
- "requestStreaming": false,
- "responseType": "EndDevice",
- "responseLongType": "EndDevice",
- "responseFullType": "ttn.lorawan.v3.EndDevice",
- "responseStreaming": false,
- "options": {
- "google.api.http": {
- "rules": [
- {
- "method": "POST",
- "pattern": "/applications/{end_device.ids.application_ids.application_id}/devices",
- "body": "*"
- }
- ]
- }
- }
+ "name": "second_channel",
+ "description": "Second wake on radio channel configuration.",
+ "label": "",
+ "type": "RelaySecondChannel",
+ "longType": "RelaySecondChannel",
+ "fullType": "ttn.lorawan.v3.RelaySecondChannel",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
},
{
- "name": "Get",
- "description": "Get the end device with the given identifiers, selecting the fields specified\nin the field mask.\nMore or less fields may be returned, depending on the rights of the caller.",
- "requestType": "GetEndDeviceRequest",
- "requestLongType": "GetEndDeviceRequest",
- "requestFullType": "ttn.lorawan.v3.GetEndDeviceRequest",
- "requestStreaming": false,
- "responseType": "EndDevice",
- "responseLongType": "EndDevice",
- "responseFullType": "ttn.lorawan.v3.EndDevice",
- "responseStreaming": false,
+ "name": "default_channel_index",
+ "description": "Index of the default wake on radio channel.",
+ "label": "",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
"options": {
- "google.api.http": {
- "rules": [
- {
- "method": "GET",
- "pattern": "/applications/{end_device_ids.application_ids.application_id}/devices/{end_device_ids.device_id}"
- }
- ]
- }
+ "validate.rules": [
+ {
+ "name": "uint32.lte",
+ "value": 255
+ }
+ ]
}
},
{
- "name": "GetIdentifiersForEUIs",
- "description": "Get the identifiers of the end device that has the given EUIs registered.",
- "requestType": "GetEndDeviceIdentifiersForEUIsRequest",
- "requestLongType": "GetEndDeviceIdentifiersForEUIsRequest",
- "requestFullType": "ttn.lorawan.v3.GetEndDeviceIdentifiersForEUIsRequest",
- "requestStreaming": false,
- "responseType": "EndDeviceIdentifiers",
- "responseLongType": "EndDeviceIdentifiers",
- "responseFullType": "ttn.lorawan.v3.EndDeviceIdentifiers",
- "responseStreaming": false
+ "name": "cad_periodicity",
+ "description": "Channel activity detection periodicity.",
+ "label": "",
+ "type": "RelayCADPeriodicity",
+ "longType": "RelayCADPeriodicity",
+ "fullType": "ttn.lorawan.v3.RelayCADPeriodicity",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "enum.defined_only",
+ "value": true
+ }
+ ]
+ }
},
{
- "name": "List",
- "description": "List end devices in the given application.\nSimilar to Get, this selects the fields given by the field mask.\nMore or less fields may be returned, depending on the rights of the caller.",
- "requestType": "ListEndDevicesRequest",
- "requestLongType": "ListEndDevicesRequest",
- "requestFullType": "ttn.lorawan.v3.ListEndDevicesRequest",
- "requestStreaming": false,
- "responseType": "EndDevices",
- "responseLongType": "EndDevices",
- "responseFullType": "ttn.lorawan.v3.EndDevices",
- "responseStreaming": false,
- "options": {
- "google.api.http": {
- "rules": [
- {
- "method": "GET",
- "pattern": "/applications/{application_ids.application_id}/devices"
- }
- ]
- }
- }
- },
- {
- "name": "Update",
- "description": "Update the end device, changing the fields specified by the field mask to the provided values.",
- "requestType": "UpdateEndDeviceRequest",
- "requestLongType": "UpdateEndDeviceRequest",
- "requestFullType": "ttn.lorawan.v3.UpdateEndDeviceRequest",
- "requestStreaming": false,
- "responseType": "EndDevice",
- "responseLongType": "EndDevice",
- "responseFullType": "ttn.lorawan.v3.EndDevice",
- "responseStreaming": false,
+ "name": "uplink_forwarding_rules",
+ "description": "Configured uplink forwarding rules.",
+ "label": "repeated",
+ "type": "RelayUplinkForwardingRule",
+ "longType": "RelayUplinkForwardingRule",
+ "fullType": "ttn.lorawan.v3.RelayUplinkForwardingRule",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
"options": {
- "google.api.http": {
- "rules": [
- {
- "method": "PUT",
- "pattern": "/applications/{end_device.ids.application_ids.application_id}/devices/{end_device.ids.device_id}",
- "body": "*"
- }
- ]
- }
+ "validate.rules": [
+ {
+ "name": "repeated.max_items",
+ "value": 16
+ }
+ ]
}
},
{
- "name": "BatchUpdateLastSeen",
- "description": "Update the last seen timestamp for a batch of end devices.",
- "requestType": "BatchUpdateEndDeviceLastSeenRequest",
- "requestLongType": "BatchUpdateEndDeviceLastSeenRequest",
- "requestFullType": "ttn.lorawan.v3.BatchUpdateEndDeviceLastSeenRequest",
- "requestStreaming": false,
- "responseType": "Empty",
- "responseLongType": ".google.protobuf.Empty",
- "responseFullType": "google.protobuf.Empty",
- "responseStreaming": false
- },
- {
- "name": "Delete",
- "description": "Delete the end device with the given IDs.\n\nBefore deleting an end device it first needs to be deleted from the\nNsEndDeviceRegistry, the AsEndDeviceRegistry and the JsEndDeviceRegistry.\nIn addition, if the device claimed on a Join Server, it also needs to be\nunclaimed via the DeviceClaimingServer so it can be claimed in the future.\nThis is NOT done automatically.",
- "requestType": "EndDeviceIdentifiers",
- "requestLongType": "EndDeviceIdentifiers",
- "requestFullType": "ttn.lorawan.v3.EndDeviceIdentifiers",
- "requestStreaming": false,
- "responseType": "Empty",
- "responseLongType": ".google.protobuf.Empty",
- "responseFullType": "google.protobuf.Empty",
- "responseStreaming": false,
- "options": {
- "google.api.http": {
- "rules": [
- {
- "method": "DELETE",
- "pattern": "/applications/{application_ids.application_id}/devices/{device_id}"
- }
- ]
- }
- }
+ "name": "limits",
+ "description": "Configured forwarding limits.\nIf unset, the default value from Network Server configuration will be used.",
+ "label": "",
+ "type": "ServingRelayForwardingLimits",
+ "longType": "ServingRelayForwardingLimits",
+ "fullType": "ttn.lorawan.v3.ServingRelayForwardingLimits",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
}
]
},
{
- "name": "EndDeviceTemplateConverter",
- "longName": "EndDeviceTemplateConverter",
- "fullName": "ttn.lorawan.v3.EndDeviceTemplateConverter",
+ "name": "Session",
+ "longName": "Session",
+ "fullName": "ttn.lorawan.v3.Session",
"description": "",
- "methods": [
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "ListFormats",
- "description": "Returns the configured formats to convert from.",
- "requestType": "Empty",
- "requestLongType": ".google.protobuf.Empty",
- "requestFullType": "google.protobuf.Empty",
- "requestStreaming": false,
- "responseType": "EndDeviceTemplateFormats",
- "responseLongType": "EndDeviceTemplateFormats",
- "responseFullType": "ttn.lorawan.v3.EndDeviceTemplateFormats",
- "responseStreaming": false,
+ "name": "dev_addr",
+ "description": "Device Address, issued by the Network Server or chosen by device manufacturer in case of testing range (beginning with 00-03).\nKnown by Network Server, Application Server and Join Server. Owned by Network Server.",
+ "label": "",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
"options": {
- "google.api.http": {
- "rules": [
- {
- "method": "GET",
- "pattern": "/edtc/formats"
- }
- ]
- }
+ "validate.rules": [
+ {
+ "name": "bytes.len",
+ "value": 4
+ }
+ ]
}
},
{
- "name": "Convert",
- "description": "Converts the binary data to a stream of end device templates.",
- "requestType": "ConvertEndDeviceTemplateRequest",
- "requestLongType": "ConvertEndDeviceTemplateRequest",
- "requestFullType": "ttn.lorawan.v3.ConvertEndDeviceTemplateRequest",
- "requestStreaming": false,
- "responseType": "EndDeviceTemplate",
- "responseLongType": "EndDeviceTemplate",
- "responseFullType": "ttn.lorawan.v3.EndDeviceTemplate",
- "responseStreaming": true,
+ "name": "keys",
+ "description": "",
+ "label": "",
+ "type": "SessionKeys",
+ "longType": "SessionKeys",
+ "fullType": "ttn.lorawan.v3.SessionKeys",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
"options": {
- "google.api.http": {
- "rules": [
- {
- "method": "POST",
- "pattern": "/edtc/convert",
- "body": "*"
- }
- ]
- }
+ "validate.rules": [
+ {
+ "name": "message.required",
+ "value": true
+ }
+ ]
}
- }
- ]
- }
- ]
- },
- {
- "name": "ttn/lorawan/v3/enums.proto",
- "description": "",
- "package": "ttn.lorawan.v3",
- "hasEnums": true,
- "hasExtensions": false,
- "hasMessages": false,
- "hasServices": false,
- "enums": [
- {
- "name": "ClusterRole",
- "longName": "ClusterRole",
- "fullName": "ttn.lorawan.v3.ClusterRole",
- "description": "",
- "values": [
+ },
{
- "name": "NONE",
- "number": "0",
- "description": ""
+ "name": "last_f_cnt_up",
+ "description": "Last uplink frame counter value used. Network Server only. Application Server assumes the Network Server checked it.",
+ "label": "",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
},
{
- "name": "ENTITY_REGISTRY",
- "number": "1",
- "description": ""
+ "name": "last_n_f_cnt_down",
+ "description": "Last network downlink frame counter value used. Network Server only.",
+ "label": "",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
},
{
- "name": "ACCESS",
- "number": "2",
- "description": ""
+ "name": "last_a_f_cnt_down",
+ "description": "Last application downlink frame counter value used. Application Server only.",
+ "label": "",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
},
{
- "name": "GATEWAY_SERVER",
- "number": "3",
- "description": ""
+ "name": "last_conf_f_cnt_down",
+ "description": "Frame counter of the last confirmed downlink message sent. Network Server only.",
+ "label": "",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
},
{
- "name": "NETWORK_SERVER",
- "number": "4",
- "description": ""
+ "name": "started_at",
+ "description": "Time when the session started. Network Server only.",
+ "label": "",
+ "type": "Timestamp",
+ "longType": "google.protobuf.Timestamp",
+ "fullType": "google.protobuf.Timestamp",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
},
{
- "name": "APPLICATION_SERVER",
- "number": "5",
- "description": ""
- },
- {
- "name": "JOIN_SERVER",
- "number": "6",
- "description": ""
- },
- {
- "name": "CRYPTO_SERVER",
- "number": "7",
- "description": ""
- },
- {
- "name": "DEVICE_TEMPLATE_CONVERTER",
- "number": "8",
- "description": ""
- },
- {
- "name": "DEVICE_CLAIMING_SERVER",
- "number": "9",
- "description": ""
- },
- {
- "name": "GATEWAY_CONFIGURATION_SERVER",
- "number": "10",
- "description": ""
- },
- {
- "name": "QR_CODE_GENERATOR",
- "number": "11",
- "description": ""
- },
- {
- "name": "PACKET_BROKER_AGENT",
- "number": "12",
- "description": ""
- },
- {
- "name": "DEVICE_REPOSITORY",
- "number": "13",
- "description": ""
+ "name": "queued_application_downlinks",
+ "description": "Queued Application downlink messages. Stored in Application Server and Network Server.",
+ "label": "repeated",
+ "type": "ApplicationDownlink",
+ "longType": "ApplicationDownlink",
+ "fullType": "ttn.lorawan.v3.ApplicationDownlink",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
}
]
},
{
- "name": "DownlinkPathConstraint",
- "longName": "DownlinkPathConstraint",
- "fullName": "ttn.lorawan.v3.DownlinkPathConstraint",
+ "name": "SetEndDeviceRequest",
+ "longName": "SetEndDeviceRequest",
+ "fullName": "ttn.lorawan.v3.SetEndDeviceRequest",
"description": "",
- "values": [
- {
- "name": "DOWNLINK_PATH_CONSTRAINT_NONE",
- "number": "0",
- "description": "Indicates that the gateway can be selected for downlink without constraints by the Network Server."
- },
- {
- "name": "DOWNLINK_PATH_CONSTRAINT_PREFER_OTHER",
- "number": "1",
- "description": "Indicates that the gateway can be selected for downlink only if no other or better gateway can be selected."
- },
- {
- "name": "DOWNLINK_PATH_CONSTRAINT_NEVER",
- "number": "2",
- "description": "Indicates that this gateway will never be selected for downlink, even if that results in no available downlink path."
- }
- ]
- },
- {
- "name": "State",
- "longName": "State",
- "fullName": "ttn.lorawan.v3.State",
- "description": "State enum defines states that an entity can be in.",
- "values": [
- {
- "name": "STATE_REQUESTED",
- "number": "0",
- "description": "Denotes that the entity has been requested and is pending review by an admin."
- },
- {
- "name": "STATE_APPROVED",
- "number": "1",
- "description": "Denotes that the entity has been reviewed and approved by an admin."
- },
- {
- "name": "STATE_REJECTED",
- "number": "2",
- "description": "Denotes that the entity has been reviewed and rejected by an admin."
- },
- {
- "name": "STATE_FLAGGED",
- "number": "3",
- "description": "Denotes that the entity has been flagged and is pending review by an admin."
- },
- {
- "name": "STATE_SUSPENDED",
- "number": "4",
- "description": "Denotes that the entity has been reviewed and suspended by an admin."
- }
- ]
- }
- ],
- "extensions": [],
- "messages": [],
- "services": []
- },
- {
- "name": "ttn/lorawan/v3/error.proto",
- "description": "",
- "package": "ttn.lorawan.v3",
- "hasEnums": false,
- "hasExtensions": false,
- "hasMessages": true,
- "hasServices": false,
- "enums": [],
- "extensions": [],
- "messages": [
- {
- "name": "ErrorDetails",
- "longName": "ErrorDetails",
- "fullName": "ttn.lorawan.v3.ErrorDetails",
- "description": "Error details that are communicated over gRPC (and HTTP) APIs.\nThe messages (for translation) are stored as \"error:\u003cnamespace\u003e:\u003cname\u003e\".",
"hasExtensions": false,
"hasFields": true,
"hasOneofs": false,
"extensions": [],
"fields": [
{
- "name": "namespace",
- "description": "Namespace of the error (typically the package name in The Things Stack).",
- "label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
- },
- {
- "name": "name",
- "description": "Name of the error.",
- "label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
- },
- {
- "name": "message_format",
- "description": "The default (fallback) message format that should be used for the error.\nThis is also used if the client does not have a translation for the error.",
- "label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
- },
- {
- "name": "attributes",
- "description": "Attributes that should be filled into the message format. Any extra attributes\ncan be displayed as error details.",
+ "name": "end_device",
+ "description": "",
"label": "",
- "type": "Struct",
- "longType": "google.protobuf.Struct",
- "fullType": "google.protobuf.Struct",
+ "type": "EndDevice",
+ "longType": "EndDevice",
+ "fullType": "ttn.lorawan.v3.EndDevice",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "message.required",
+ "value": true
+ }
+ ]
+ }
},
{
- "name": "correlation_id",
- "description": "The correlation ID of the error can be used to correlate the error to stack\ntraces the network may (or may not) store about recent errors.",
+ "name": "field_mask",
+ "description": "The names of the end device fields that should be updated.\nSee the API reference for which fields can be set on the different services.",
"label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
+ "type": "FieldMask",
+ "longType": "google.protobuf.FieldMask",
+ "fullType": "google.protobuf.FieldMask",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
- },
+ }
+ ]
+ },
+ {
+ "name": "UpdateEndDeviceRequest",
+ "longName": "UpdateEndDeviceRequest",
+ "fullName": "ttn.lorawan.v3.UpdateEndDeviceRequest",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "cause",
- "description": "The error that caused this error.",
+ "name": "end_device",
+ "description": "",
"label": "",
- "type": "ErrorDetails",
- "longType": "ErrorDetails",
- "fullType": "ttn.lorawan.v3.ErrorDetails",
+ "type": "EndDevice",
+ "longType": "EndDevice",
+ "fullType": "ttn.lorawan.v3.EndDevice",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "message.required",
+ "value": true
+ }
+ ]
+ }
},
{
- "name": "code",
- "description": "The status code of the error.",
+ "name": "field_mask",
+ "description": "The names of the end device fields that should be updated.\nSee the API reference for which fields can be set on the different services.",
"label": "",
- "type": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
- },
- {
- "name": "details",
- "description": "The details of the error.",
- "label": "repeated",
- "type": "Any",
- "longType": "google.protobuf.Any",
- "fullType": "google.protobuf.Any",
+ "type": "FieldMask",
+ "longType": "google.protobuf.FieldMask",
+ "fullType": "google.protobuf.FieldMask",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -19750,249 +19716,440 @@
"services": []
},
{
- "name": "ttn/lorawan/v3/events.proto",
+ "name": "ttn/lorawan/v3/end_device_services.proto",
"description": "",
"package": "ttn.lorawan.v3",
"hasEnums": false,
"hasExtensions": false,
- "hasMessages": true,
+ "hasMessages": false,
"hasServices": true,
"enums": [],
"extensions": [],
- "messages": [
+ "messages": [],
+ "services": [
{
- "name": "Event",
- "longName": "Event",
- "fullName": "ttn.lorawan.v3.Event",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ "name": "EndDeviceBatchRegistry",
+ "longName": "EndDeviceBatchRegistry",
+ "fullName": "ttn.lorawan.v3.EndDeviceBatchRegistry",
+ "description": "The EndDeviceBatchRegistry service, exposed by the Identity Server, is used to manage\nend device registrations in batches.",
+ "methods": [
{
- "name": "name",
- "description": "Name of the event. This can be used to find the (localized) event description.",
- "label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
+ "name": "Get",
+ "description": "Get a batch of end devices with the given identifiers, selecting the fields specified\nin the field mask.\nMore or less fields may be returned, depending on the rights of the caller.\nDevices not found are skipped and no error is returned.",
+ "requestType": "BatchGetEndDevicesRequest",
+ "requestLongType": "BatchGetEndDevicesRequest",
+ "requestFullType": "ttn.lorawan.v3.BatchGetEndDevicesRequest",
+ "requestStreaming": false,
+ "responseType": "EndDevices",
+ "responseLongType": "EndDevices",
+ "responseFullType": "ttn.lorawan.v3.EndDevices",
+ "responseStreaming": false,
+ "options": {
+ "google.api.http": {
+ "rules": [
+ {
+ "method": "GET",
+ "pattern": "/applications/{application_ids.application_id}/devices/batch"
+ }
+ ]
+ }
+ }
},
{
- "name": "time",
- "description": "Time at which the event was triggered.",
- "label": "",
- "type": "Timestamp",
- "longType": "google.protobuf.Timestamp",
- "fullType": "google.protobuf.Timestamp",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
+ "name": "Delete",
+ "description": "Delete a batch of end devices with the given IDs.\n\nThis operation is atomic; either all devices are deleted or none.\nDevices not found are skipped and no error is returned.\nBefore calling this RPC, use the corresponding BatchDelete RPCs\nof NsEndDeviceRegistry, AsEndDeviceRegistry and\noptionally the JsEndDeviceRegistry to delete the end devices.\nIf the devices were claimed on a Join Server, use the BatchUnclaim RPC\nof the DeviceClaimingServer.\nThis is NOT done automatically.",
+ "requestType": "BatchDeleteEndDevicesRequest",
+ "requestLongType": "BatchDeleteEndDevicesRequest",
+ "requestFullType": "ttn.lorawan.v3.BatchDeleteEndDevicesRequest",
+ "requestStreaming": false,
+ "responseType": "Empty",
+ "responseLongType": ".google.protobuf.Empty",
+ "responseFullType": "google.protobuf.Empty",
+ "responseStreaming": false,
"options": {
- "validate.rules": [
- {
- "name": "timestamp.required",
- "value": true
- }
- ]
+ "google.api.http": {
+ "rules": [
+ {
+ "method": "DELETE",
+ "pattern": "/applications/{application_ids.application_id}/devices/batch"
+ }
+ ]
+ }
+ }
+ }
+ ]
+ },
+ {
+ "name": "EndDeviceRegistry",
+ "longName": "EndDeviceRegistry",
+ "fullName": "ttn.lorawan.v3.EndDeviceRegistry",
+ "description": "The EndDeviceRegistry service, exposed by the Identity Server, is used to manage\nend device registrations.\n\nAfter registering an end device, it also needs to be registered in\nthe NsEndDeviceRegistry that is exposed by the Network Server,\nthe AsEndDeviceRegistry that is exposed by the Application Server,\nand the JsEndDeviceRegistry that is exposed by the Join Server.\n\nBefore deleting an end device it first needs to be deleted from the\nNsEndDeviceRegistry, the AsEndDeviceRegistry and the JsEndDeviceRegistry.",
+ "methods": [
+ {
+ "name": "Create",
+ "description": "Create a new end device within an application.\n\nAfter registering an end device, it also needs to be registered in\nthe NsEndDeviceRegistry that is exposed by the Network Server,\nthe AsEndDeviceRegistry that is exposed by the Application Server,\nand the JsEndDeviceRegistry that is exposed by the Join Server.",
+ "requestType": "CreateEndDeviceRequest",
+ "requestLongType": "CreateEndDeviceRequest",
+ "requestFullType": "ttn.lorawan.v3.CreateEndDeviceRequest",
+ "requestStreaming": false,
+ "responseType": "EndDevice",
+ "responseLongType": "EndDevice",
+ "responseFullType": "ttn.lorawan.v3.EndDevice",
+ "responseStreaming": false,
+ "options": {
+ "google.api.http": {
+ "rules": [
+ {
+ "method": "POST",
+ "pattern": "/applications/{end_device.ids.application_ids.application_id}/devices",
+ "body": "*"
+ }
+ ]
+ }
}
},
{
- "name": "identifiers",
- "description": "Identifiers of the entity (or entities) involved.",
- "label": "repeated",
- "type": "EntityIdentifiers",
- "longType": "EntityIdentifiers",
- "fullType": "ttn.lorawan.v3.EntityIdentifiers",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
+ "name": "Get",
+ "description": "Get the end device with the given identifiers, selecting the fields specified\nin the field mask.\nMore or less fields may be returned, depending on the rights of the caller.",
+ "requestType": "GetEndDeviceRequest",
+ "requestLongType": "GetEndDeviceRequest",
+ "requestFullType": "ttn.lorawan.v3.GetEndDeviceRequest",
+ "requestStreaming": false,
+ "responseType": "EndDevice",
+ "responseLongType": "EndDevice",
+ "responseFullType": "ttn.lorawan.v3.EndDevice",
+ "responseStreaming": false,
+ "options": {
+ "google.api.http": {
+ "rules": [
+ {
+ "method": "GET",
+ "pattern": "/applications/{end_device_ids.application_ids.application_id}/devices/{end_device_ids.device_id}"
+ }
+ ]
+ }
+ }
},
{
- "name": "data",
- "description": "Optional data attached to the event.",
- "label": "",
- "type": "Any",
- "longType": "google.protobuf.Any",
- "fullType": "google.protobuf.Any",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
+ "name": "GetIdentifiersForEUIs",
+ "description": "Get the identifiers of the end device that has the given EUIs registered.",
+ "requestType": "GetEndDeviceIdentifiersForEUIsRequest",
+ "requestLongType": "GetEndDeviceIdentifiersForEUIsRequest",
+ "requestFullType": "ttn.lorawan.v3.GetEndDeviceIdentifiersForEUIsRequest",
+ "requestStreaming": false,
+ "responseType": "EndDeviceIdentifiers",
+ "responseLongType": "EndDeviceIdentifiers",
+ "responseFullType": "ttn.lorawan.v3.EndDeviceIdentifiers",
+ "responseStreaming": false
},
{
- "name": "correlation_ids",
- "description": "Correlation IDs can be used to find related events and actions such as API calls.",
- "label": "repeated",
- "type": "string",
- "longType": "string",
- "fullType": "string",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
+ "name": "List",
+ "description": "List end devices in the given application.\nSimilar to Get, this selects the fields given by the field mask.\nMore or less fields may be returned, depending on the rights of the caller.",
+ "requestType": "ListEndDevicesRequest",
+ "requestLongType": "ListEndDevicesRequest",
+ "requestFullType": "ttn.lorawan.v3.ListEndDevicesRequest",
+ "requestStreaming": false,
+ "responseType": "EndDevices",
+ "responseLongType": "EndDevices",
+ "responseFullType": "ttn.lorawan.v3.EndDevices",
+ "responseStreaming": false,
"options": {
- "validate.rules": [
- {
- "name": "repeated.items.string.max_len",
- "value": 100
- }
- ]
+ "google.api.http": {
+ "rules": [
+ {
+ "method": "GET",
+ "pattern": "/applications/{application_ids.application_id}/devices"
+ }
+ ]
+ }
}
},
{
- "name": "origin",
- "description": "The origin of the event. Typically the hostname of the server that created it.",
- "label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
+ "name": "Update",
+ "description": "Update the end device, changing the fields specified by the field mask to the provided values.",
+ "requestType": "UpdateEndDeviceRequest",
+ "requestLongType": "UpdateEndDeviceRequest",
+ "requestFullType": "ttn.lorawan.v3.UpdateEndDeviceRequest",
+ "requestStreaming": false,
+ "responseType": "EndDevice",
+ "responseLongType": "EndDevice",
+ "responseFullType": "ttn.lorawan.v3.EndDevice",
+ "responseStreaming": false,
+ "options": {
+ "google.api.http": {
+ "rules": [
+ {
+ "method": "PUT",
+ "pattern": "/applications/{end_device.ids.application_ids.application_id}/devices/{end_device.ids.device_id}",
+ "body": "*"
+ }
+ ]
+ }
+ }
},
{
- "name": "context",
- "description": "Event context, internal use only.",
- "label": "repeated",
- "type": "ContextEntry",
- "longType": "Event.ContextEntry",
- "fullType": "ttn.lorawan.v3.Event.ContextEntry",
- "ismap": true,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
+ "name": "BatchUpdateLastSeen",
+ "description": "Update the last seen timestamp for a batch of end devices.",
+ "requestType": "BatchUpdateEndDeviceLastSeenRequest",
+ "requestLongType": "BatchUpdateEndDeviceLastSeenRequest",
+ "requestFullType": "ttn.lorawan.v3.BatchUpdateEndDeviceLastSeenRequest",
+ "requestStreaming": false,
+ "responseType": "Empty",
+ "responseLongType": ".google.protobuf.Empty",
+ "responseFullType": "google.protobuf.Empty",
+ "responseStreaming": false
},
{
- "name": "visibility",
- "description": "The event will be visible to a caller that has any of these rights.",
- "label": "",
- "type": "Rights",
- "longType": "Rights",
- "fullType": "ttn.lorawan.v3.Rights",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
+ "name": "Delete",
+ "description": "Delete the end device with the given IDs.\n\nBefore deleting an end device it first needs to be deleted from the\nNsEndDeviceRegistry, the AsEndDeviceRegistry and the JsEndDeviceRegistry.\nIn addition, if the device claimed on a Join Server, it also needs to be\nunclaimed via the DeviceClaimingServer so it can be claimed in the future.\nThis is NOT done automatically.",
+ "requestType": "EndDeviceIdentifiers",
+ "requestLongType": "EndDeviceIdentifiers",
+ "requestFullType": "ttn.lorawan.v3.EndDeviceIdentifiers",
+ "requestStreaming": false,
+ "responseType": "Empty",
+ "responseLongType": ".google.protobuf.Empty",
+ "responseFullType": "google.protobuf.Empty",
+ "responseStreaming": false,
+ "options": {
+ "google.api.http": {
+ "rules": [
+ {
+ "method": "DELETE",
+ "pattern": "/applications/{application_ids.application_id}/devices/{device_id}"
+ }
+ ]
+ }
+ }
+ }
+ ]
+ },
+ {
+ "name": "EndDeviceTemplateConverter",
+ "longName": "EndDeviceTemplateConverter",
+ "fullName": "ttn.lorawan.v3.EndDeviceTemplateConverter",
+ "description": "",
+ "methods": [
+ {
+ "name": "ListFormats",
+ "description": "Returns the configured formats to convert from.",
+ "requestType": "Empty",
+ "requestLongType": ".google.protobuf.Empty",
+ "requestFullType": "google.protobuf.Empty",
+ "requestStreaming": false,
+ "responseType": "EndDeviceTemplateFormats",
+ "responseLongType": "EndDeviceTemplateFormats",
+ "responseFullType": "ttn.lorawan.v3.EndDeviceTemplateFormats",
+ "responseStreaming": false,
+ "options": {
+ "google.api.http": {
+ "rules": [
+ {
+ "method": "GET",
+ "pattern": "/edtc/formats"
+ }
+ ]
+ }
+ }
},
{
- "name": "authentication",
- "description": "Details on the authentication provided by the caller that triggered this event.",
- "label": "",
- "type": "Authentication",
- "longType": "Event.Authentication",
- "fullType": "ttn.lorawan.v3.Event.Authentication",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
+ "name": "Convert",
+ "description": "Converts the binary data to a stream of end device templates.",
+ "requestType": "ConvertEndDeviceTemplateRequest",
+ "requestLongType": "ConvertEndDeviceTemplateRequest",
+ "requestFullType": "ttn.lorawan.v3.ConvertEndDeviceTemplateRequest",
+ "requestStreaming": false,
+ "responseType": "EndDeviceTemplate",
+ "responseLongType": "EndDeviceTemplate",
+ "responseFullType": "ttn.lorawan.v3.EndDeviceTemplate",
+ "responseStreaming": true,
+ "options": {
+ "google.api.http": {
+ "rules": [
+ {
+ "method": "POST",
+ "pattern": "/edtc/convert",
+ "body": "*"
+ }
+ ]
+ }
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "ttn/lorawan/v3/enums.proto",
+ "description": "",
+ "package": "ttn.lorawan.v3",
+ "hasEnums": true,
+ "hasExtensions": false,
+ "hasMessages": false,
+ "hasServices": false,
+ "enums": [
+ {
+ "name": "ClusterRole",
+ "longName": "ClusterRole",
+ "fullName": "ttn.lorawan.v3.ClusterRole",
+ "description": "",
+ "values": [
+ {
+ "name": "NONE",
+ "number": "0",
+ "description": ""
},
{
- "name": "remote_ip",
- "description": "The IP address of the caller that triggered this event.",
- "label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
+ "name": "ENTITY_REGISTRY",
+ "number": "1",
+ "description": ""
},
{
- "name": "user_agent",
- "description": "The IP address of the caller that triggered this event.",
- "label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
+ "name": "ACCESS",
+ "number": "2",
+ "description": ""
},
{
- "name": "unique_id",
- "description": "The unique identifier of the event, assigned on creation.",
- "label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
+ "name": "GATEWAY_SERVER",
+ "number": "3",
+ "description": ""
+ },
+ {
+ "name": "NETWORK_SERVER",
+ "number": "4",
+ "description": ""
+ },
+ {
+ "name": "APPLICATION_SERVER",
+ "number": "5",
+ "description": ""
+ },
+ {
+ "name": "JOIN_SERVER",
+ "number": "6",
+ "description": ""
+ },
+ {
+ "name": "CRYPTO_SERVER",
+ "number": "7",
+ "description": ""
+ },
+ {
+ "name": "DEVICE_TEMPLATE_CONVERTER",
+ "number": "8",
+ "description": ""
+ },
+ {
+ "name": "DEVICE_CLAIMING_SERVER",
+ "number": "9",
+ "description": ""
+ },
+ {
+ "name": "GATEWAY_CONFIGURATION_SERVER",
+ "number": "10",
+ "description": ""
+ },
+ {
+ "name": "QR_CODE_GENERATOR",
+ "number": "11",
+ "description": ""
+ },
+ {
+ "name": "PACKET_BROKER_AGENT",
+ "number": "12",
+ "description": ""
+ },
+ {
+ "name": "DEVICE_REPOSITORY",
+ "number": "13",
+ "description": ""
}
]
},
{
- "name": "Authentication",
- "longName": "Event.Authentication",
- "fullName": "ttn.lorawan.v3.Event.Authentication",
+ "name": "DownlinkPathConstraint",
+ "longName": "DownlinkPathConstraint",
+ "fullName": "ttn.lorawan.v3.DownlinkPathConstraint",
"description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ "values": [
{
- "name": "type",
- "description": "The type of authentication that was used. This is typically a bearer token.",
- "label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
+ "name": "DOWNLINK_PATH_CONSTRAINT_NONE",
+ "number": "0",
+ "description": "Indicates that the gateway can be selected for downlink without constraints by the Network Server."
},
{
- "name": "token_type",
- "description": "The type of token that was used. Common types are APIKey, AccessToken and SessionToken.",
- "label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
+ "name": "DOWNLINK_PATH_CONSTRAINT_PREFER_OTHER",
+ "number": "1",
+ "description": "Indicates that the gateway can be selected for downlink only if no other or better gateway can be selected."
},
{
- "name": "token_id",
- "description": "The ID of the token that was used.",
- "label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
+ "name": "DOWNLINK_PATH_CONSTRAINT_NEVER",
+ "number": "2",
+ "description": "Indicates that this gateway will never be selected for downlink, even if that results in no available downlink path."
}
]
},
{
- "name": "ContextEntry",
- "longName": "Event.ContextEntry",
- "fullName": "ttn.lorawan.v3.Event.ContextEntry",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
- {
- "name": "key",
- "description": "",
+ "name": "State",
+ "longName": "State",
+ "fullName": "ttn.lorawan.v3.State",
+ "description": "State enum defines states that an entity can be in.",
+ "values": [
+ {
+ "name": "STATE_REQUESTED",
+ "number": "0",
+ "description": "Denotes that the entity has been requested and is pending review by an admin."
+ },
+ {
+ "name": "STATE_APPROVED",
+ "number": "1",
+ "description": "Denotes that the entity has been reviewed and approved by an admin."
+ },
+ {
+ "name": "STATE_REJECTED",
+ "number": "2",
+ "description": "Denotes that the entity has been reviewed and rejected by an admin."
+ },
+ {
+ "name": "STATE_FLAGGED",
+ "number": "3",
+ "description": "Denotes that the entity has been flagged and is pending review by an admin."
+ },
+ {
+ "name": "STATE_SUSPENDED",
+ "number": "4",
+ "description": "Denotes that the entity has been reviewed and suspended by an admin."
+ }
+ ]
+ }
+ ],
+ "extensions": [],
+ "messages": [],
+ "services": []
+ },
+ {
+ "name": "ttn/lorawan/v3/error.proto",
+ "description": "",
+ "package": "ttn.lorawan.v3",
+ "hasEnums": false,
+ "hasExtensions": false,
+ "hasMessages": true,
+ "hasServices": false,
+ "enums": [],
+ "extensions": [],
+ "messages": [
+ {
+ "name": "ErrorDetails",
+ "longName": "ErrorDetails",
+ "fullName": "ttn.lorawan.v3.ErrorDetails",
+ "description": "Error details that are communicated over gRPC (and HTTP) APIs.\nThe messages (for translation) are stored as \"error:\u003cnamespace\u003e:\u003cname\u003e\".",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "namespace",
+ "description": "Namespace of the error (typically the package name in The Things Stack).",
"label": "",
"type": "string",
"longType": "string",
@@ -20003,32 +20160,44 @@
"defaultValue": ""
},
{
- "name": "value",
- "description": "",
+ "name": "name",
+ "description": "Name of the error.",
"label": "",
- "type": "bytes",
- "longType": "bytes",
- "fullType": "bytes",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
- }
- ]
- },
- {
- "name": "FindRelatedEventsRequest",
- "longName": "FindRelatedEventsRequest",
- "fullName": "ttn.lorawan.v3.FindRelatedEventsRequest",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ },
+ {
+ "name": "message_format",
+ "description": "The default (fallback) message format that should be used for the error.\nThis is also used if the client does not have a translation for the error.",
+ "label": "",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "attributes",
+ "description": "Attributes that should be filled into the message format. Any extra attributes\ncan be displayed as error details.",
+ "label": "",
+ "type": "Struct",
+ "longType": "google.protobuf.Struct",
+ "fullType": "google.protobuf.Struct",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
{
"name": "correlation_id",
- "description": "",
+ "description": "The correlation ID of the error can be used to correlate the error to stack\ntraces the network may (or may not) store about recent errors.",
"label": "",
"type": "string",
"longType": "string",
@@ -20036,50 +20205,64 @@
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "string.min_len",
- "value": 1
- },
- {
- "name": "string.max_len",
- "value": 100
- }
- ]
- }
- }
- ]
- },
- {
- "name": "FindRelatedEventsResponse",
- "longName": "FindRelatedEventsResponse",
- "fullName": "ttn.lorawan.v3.FindRelatedEventsResponse",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ "defaultValue": ""
+ },
{
- "name": "events",
- "description": "",
+ "name": "cause",
+ "description": "The error that caused this error.",
+ "label": "",
+ "type": "ErrorDetails",
+ "longType": "ErrorDetails",
+ "fullType": "ttn.lorawan.v3.ErrorDetails",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "code",
+ "description": "The status code of the error.",
+ "label": "",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "details",
+ "description": "The details of the error.",
"label": "repeated",
- "type": "Event",
- "longType": "Event",
- "fullType": "ttn.lorawan.v3.Event",
+ "type": "Any",
+ "longType": "google.protobuf.Any",
+ "fullType": "google.protobuf.Any",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
}
]
- },
+ }
+ ],
+ "services": []
+ },
+ {
+ "name": "ttn/lorawan/v3/events.proto",
+ "description": "",
+ "package": "ttn.lorawan.v3",
+ "hasEnums": false,
+ "hasExtensions": false,
+ "hasMessages": true,
+ "hasServices": true,
+ "enums": [],
+ "extensions": [],
+ "messages": [
{
- "name": "StreamEventsRequest",
- "longName": "StreamEventsRequest",
- "fullName": "ttn.lorawan.v3.StreamEventsRequest",
+ "name": "Event",
+ "longName": "Event",
+ "fullName": "ttn.lorawan.v3.Event",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -20087,44 +20270,64 @@
"extensions": [],
"fields": [
{
- "name": "identifiers",
- "description": "",
- "label": "repeated",
- "type": "EntityIdentifiers",
- "longType": "EntityIdentifiers",
- "fullType": "ttn.lorawan.v3.EntityIdentifiers",
+ "name": "name",
+ "description": "Name of the event. This can be used to find the (localized) event description.",
+ "label": "",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "tail",
- "description": "If greater than zero, this will return historical events, up to this maximum when the stream starts.\nIf used in combination with \"after\", the limit that is reached first, is used.\nThe availability of historical events depends on server support and retention policy.",
+ "name": "time",
+ "description": "Time at which the event was triggered.",
"label": "",
- "type": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
+ "type": "Timestamp",
+ "longType": "google.protobuf.Timestamp",
+ "fullType": "google.protobuf.Timestamp",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "timestamp.required",
+ "value": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "identifiers",
+ "description": "Identifiers of the entity (or entities) involved.",
+ "label": "repeated",
+ "type": "EntityIdentifiers",
+ "longType": "EntityIdentifiers",
+ "fullType": "ttn.lorawan.v3.EntityIdentifiers",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "after",
- "description": "If not empty, this will return historical events after the given time when the stream starts.\nIf used in combination with \"tail\", the limit that is reached first, is used.\nThe availability of historical events depends on server support and retention policy.",
+ "name": "data",
+ "description": "Optional data attached to the event.",
"label": "",
- "type": "Timestamp",
- "longType": "google.protobuf.Timestamp",
- "fullType": "google.protobuf.Timestamp",
+ "type": "Any",
+ "longType": "google.protobuf.Any",
+ "fullType": "google.protobuf.Any",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "names",
- "description": "If provided, this will filter events, so that only events with the given names are returned.\nNames can be provided as either exact event names (e.g. 'gs.up.receive'),\nor as regular expressions (e.g. '/^gs\\..+/').",
+ "name": "correlation_ids",
+ "description": "Correlation IDs can be used to find related events and actions such as API calls.",
"label": "repeated",
"type": "string",
"longType": "string",
@@ -20132,135 +20335,67 @@
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
- }
- ]
- }
- ],
- "services": [
- {
- "name": "Events",
- "longName": "Events",
- "fullName": "ttn.lorawan.v3.Events",
- "description": "The Events service serves events from the cluster.",
- "methods": [
- {
- "name": "Stream",
- "description": "Stream live events, optionally with a tail of historical events (depending on server support and retention policy).\nEvents may arrive out-of-order.",
- "requestType": "StreamEventsRequest",
- "requestLongType": "StreamEventsRequest",
- "requestFullType": "ttn.lorawan.v3.StreamEventsRequest",
- "requestStreaming": false,
- "responseType": "Event",
- "responseLongType": "Event",
- "responseFullType": "ttn.lorawan.v3.Event",
- "responseStreaming": true,
+ "defaultValue": "",
"options": {
- "google.api.http": {
- "rules": [
- {
- "method": "POST",
- "pattern": "/events",
- "body": "*"
- }
- ]
- }
+ "validate.rules": [
+ {
+ "name": "repeated.items.string.max_len",
+ "value": 100
+ }
+ ]
}
},
{
- "name": "FindRelated",
- "description": "",
- "requestType": "FindRelatedEventsRequest",
- "requestLongType": "FindRelatedEventsRequest",
- "requestFullType": "ttn.lorawan.v3.FindRelatedEventsRequest",
- "requestStreaming": false,
- "responseType": "FindRelatedEventsResponse",
- "responseLongType": "FindRelatedEventsResponse",
- "responseFullType": "ttn.lorawan.v3.FindRelatedEventsResponse",
- "responseStreaming": false,
- "options": {
- "google.api.http": {
- "rules": [
- {
- "method": "GET",
- "pattern": "/events/related"
- }
- ]
- }
- }
- }
- ]
- }
- ]
- },
- {
- "name": "ttn/lorawan/v3/gateway.proto",
- "description": "",
- "package": "ttn.lorawan.v3",
- "hasEnums": true,
- "hasExtensions": false,
- "hasMessages": true,
- "hasServices": false,
- "enums": [
- {
- "name": "GatewayAntennaPlacement",
- "longName": "GatewayAntennaPlacement",
- "fullName": "ttn.lorawan.v3.GatewayAntennaPlacement",
- "description": "",
- "values": [
- {
- "name": "PLACEMENT_UNKNOWN",
- "number": "0",
- "description": ""
+ "name": "origin",
+ "description": "The origin of the event. Typically the hostname of the server that created it.",
+ "label": "",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
},
{
- "name": "INDOOR",
- "number": "1",
- "description": ""
+ "name": "context",
+ "description": "Event context, internal use only.",
+ "label": "repeated",
+ "type": "ContextEntry",
+ "longType": "Event.ContextEntry",
+ "fullType": "ttn.lorawan.v3.Event.ContextEntry",
+ "ismap": true,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
},
{
- "name": "OUTDOOR",
- "number": "2",
- "description": ""
- }
- ]
- }
- ],
- "extensions": [],
- "messages": [
- {
- "name": "CreateGatewayAPIKeyRequest",
- "longName": "CreateGatewayAPIKeyRequest",
- "fullName": "ttn.lorawan.v3.CreateGatewayAPIKeyRequest",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ "name": "visibility",
+ "description": "The event will be visible to a caller that has any of these rights.",
+ "label": "",
+ "type": "Rights",
+ "longType": "Rights",
+ "fullType": "ttn.lorawan.v3.Rights",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
{
- "name": "gateway_ids",
- "description": "",
+ "name": "authentication",
+ "description": "Details on the authentication provided by the caller that triggered this event.",
"label": "",
- "type": "GatewayIdentifiers",
- "longType": "GatewayIdentifiers",
- "fullType": "ttn.lorawan.v3.GatewayIdentifiers",
+ "type": "Authentication",
+ "longType": "Event.Authentication",
+ "fullType": "ttn.lorawan.v3.Event.Authentication",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "message.required",
- "value": true
- }
- ]
- }
+ "defaultValue": ""
},
{
- "name": "name",
- "description": "",
+ "name": "remote_ip",
+ "description": "The IP address of the caller that triggered this event.",
"label": "",
"type": "string",
"longType": "string",
@@ -20268,70 +20403,38 @@
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "string.max_len",
- "value": 50
- }
- ]
- }
+ "defaultValue": ""
},
{
- "name": "rights",
- "description": "",
- "label": "repeated",
- "type": "Right",
- "longType": "Right",
- "fullType": "ttn.lorawan.v3.Right",
+ "name": "user_agent",
+ "description": "The IP address of the caller that triggered this event.",
+ "label": "",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "repeated.min_items",
- "value": 1
- },
- {
- "name": "repeated.unique",
- "value": true
- },
- {
- "name": "repeated.items.enum.defined_only",
- "value": true
- }
- ]
- }
+ "defaultValue": ""
},
{
- "name": "expires_at",
- "description": "",
+ "name": "unique_id",
+ "description": "The unique identifier of the event, assigned on creation.",
"label": "",
- "type": "Timestamp",
- "longType": "google.protobuf.Timestamp",
- "fullType": "google.protobuf.Timestamp",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "timestamp.gt_now",
- "value": true
- }
- ]
- }
+ "defaultValue": ""
}
]
},
{
- "name": "CreateGatewayRequest",
- "longName": "CreateGatewayRequest",
- "fullName": "ttn.lorawan.v3.CreateGatewayRequest",
+ "name": "Authentication",
+ "longName": "Event.Authentication",
+ "fullName": "ttn.lorawan.v3.Event.Authentication",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -20339,51 +20442,47 @@
"extensions": [],
"fields": [
{
- "name": "gateway",
- "description": "",
+ "name": "type",
+ "description": "The type of authentication that was used. This is typically a bearer token.",
"label": "",
- "type": "Gateway",
- "longType": "Gateway",
- "fullType": "ttn.lorawan.v3.Gateway",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "message.required",
- "value": true
- }
- ]
- }
+ "defaultValue": ""
},
{
- "name": "collaborator",
- "description": "Collaborator to grant all rights on the newly created gateway.",
+ "name": "token_type",
+ "description": "The type of token that was used. Common types are APIKey, AccessToken and SessionToken.",
"label": "",
- "type": "OrganizationOrUserIdentifiers",
- "longType": "OrganizationOrUserIdentifiers",
- "fullType": "ttn.lorawan.v3.OrganizationOrUserIdentifiers",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "message.required",
- "value": true
- }
- ]
- }
+ "defaultValue": ""
+ },
+ {
+ "name": "token_id",
+ "description": "The ID of the token that was used.",
+ "label": "",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
}
]
},
{
- "name": "DeleteGatewayAPIKeyRequest",
- "longName": "DeleteGatewayAPIKeyRequest",
- "fullName": "ttn.lorawan.v3.DeleteGatewayAPIKeyRequest",
+ "name": "ContextEntry",
+ "longName": "Event.ContextEntry",
+ "fullName": "ttn.lorawan.v3.Event.ContextEntry",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -20391,32 +20490,24 @@
"extensions": [],
"fields": [
{
- "name": "gateway_ids",
+ "name": "key",
"description": "",
"label": "",
- "type": "GatewayIdentifiers",
- "longType": "GatewayIdentifiers",
- "fullType": "ttn.lorawan.v3.GatewayIdentifiers",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "message.required",
- "value": true
- }
- ]
- }
+ "defaultValue": ""
},
{
- "name": "key_id",
+ "name": "value",
"description": "",
"label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -20425,9 +20516,9 @@
]
},
{
- "name": "DeleteGatewayCollaboratorRequest",
- "longName": "DeleteGatewayCollaboratorRequest",
- "fullName": "ttn.lorawan.v3.DeleteGatewayCollaboratorRequest",
+ "name": "FindRelatedEventsRequest",
+ "longName": "FindRelatedEventsRequest",
+ "fullName": "ttn.lorawan.v3.FindRelatedEventsRequest",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -20435,12 +20526,12 @@
"extensions": [],
"fields": [
{
- "name": "gateway_ids",
+ "name": "correlation_id",
"description": "",
"label": "",
- "type": "GatewayIdentifiers",
- "longType": "GatewayIdentifiers",
- "fullType": "ttn.lorawan.v3.GatewayIdentifiers",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -20448,28 +20539,12 @@
"options": {
"validate.rules": [
{
- "name": "message.required",
- "value": true
- }
- ]
- }
- },
- {
- "name": "collaborator_ids",
- "description": "",
- "label": "",
- "type": "OrganizationOrUserIdentifiers",
- "longType": "OrganizationOrUserIdentifiers",
- "fullType": "ttn.lorawan.v3.OrganizationOrUserIdentifiers",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
+ "name": "string.min_len",
+ "value": 1
+ },
{
- "name": "message.required",
- "value": true
+ "name": "string.max_len",
+ "value": 100
}
]
}
@@ -20477,62 +20552,66 @@
]
},
{
- "name": "Gateway",
- "longName": "Gateway",
- "fullName": "ttn.lorawan.v3.Gateway",
- "description": "Gateway is the message that defines a gateway on the network.",
+ "name": "FindRelatedEventsResponse",
+ "longName": "FindRelatedEventsResponse",
+ "fullName": "ttn.lorawan.v3.FindRelatedEventsResponse",
+ "description": "",
"hasExtensions": false,
"hasFields": true,
"hasOneofs": false,
"extensions": [],
"fields": [
{
- "name": "ids",
- "description": "The identifiers of the gateway. These are public and can be seen by any authenticated user in the network.",
- "label": "",
- "type": "GatewayIdentifiers",
- "longType": "GatewayIdentifiers",
- "fullType": "ttn.lorawan.v3.GatewayIdentifiers",
+ "name": "events",
+ "description": "",
+ "label": "repeated",
+ "type": "Event",
+ "longType": "Event",
+ "fullType": "ttn.lorawan.v3.Event",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "message.required",
- "value": true
- }
- ]
- }
- },
+ "defaultValue": ""
+ }
+ ]
+ },
+ {
+ "name": "StreamEventsRequest",
+ "longName": "StreamEventsRequest",
+ "fullName": "ttn.lorawan.v3.StreamEventsRequest",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "created_at",
- "description": "When the gateway was created. This information is public and can be seen by any authenticated user in the network.",
- "label": "",
- "type": "Timestamp",
- "longType": "google.protobuf.Timestamp",
- "fullType": "google.protobuf.Timestamp",
+ "name": "identifiers",
+ "description": "",
+ "label": "repeated",
+ "type": "EntityIdentifiers",
+ "longType": "EntityIdentifiers",
+ "fullType": "ttn.lorawan.v3.EntityIdentifiers",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "updated_at",
- "description": "When the gateway was last updated. This information is public and can be seen by any authenticated user in the network.",
+ "name": "tail",
+ "description": "If greater than zero, this will return historical events, up to this maximum when the stream starts.\nIf used in combination with \"after\", the limit that is reached first, is used.\nThe availability of historical events depends on server support and retention policy.",
"label": "",
- "type": "Timestamp",
- "longType": "google.protobuf.Timestamp",
- "fullType": "google.protobuf.Timestamp",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "deleted_at",
- "description": "When the gateway was deleted. This information is public and can be seen by any authenticated user in the network.",
+ "name": "after",
+ "description": "If not empty, this will return historical events after the given time when the stream starts.\nIf used in combination with \"tail\", the limit that is reached first, is used.\nThe availability of historical events depends on server support and retention policy.",
"label": "",
"type": "Timestamp",
"longType": "google.protobuf.Timestamp",
@@ -20543,138 +20622,145 @@
"defaultValue": ""
},
{
- "name": "name",
- "description": "The name of the gateway. This information is public and can be seen by any authenticated user in the network.",
- "label": "",
+ "name": "names",
+ "description": "If provided, this will filter events, so that only events with the given names are returned.\nNames can be provided as either exact event names (e.g. 'gs.up.receive'),\nor as regular expressions (e.g. '/^gs\\..+/').",
+ "label": "repeated",
"type": "string",
"longType": "string",
"fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "string.max_len",
- "value": 50
- }
- ]
- }
- },
+ "defaultValue": ""
+ }
+ ]
+ }
+ ],
+ "services": [
+ {
+ "name": "Events",
+ "longName": "Events",
+ "fullName": "ttn.lorawan.v3.Events",
+ "description": "The Events service serves events from the cluster.",
+ "methods": [
{
- "name": "description",
- "description": "A description for the gateway. This information is public and can be seen by any authenticated user in the network.",
- "label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
+ "name": "Stream",
+ "description": "Stream live events, optionally with a tail of historical events (depending on server support and retention policy).\nEvents may arrive out-of-order.",
+ "requestType": "StreamEventsRequest",
+ "requestLongType": "StreamEventsRequest",
+ "requestFullType": "ttn.lorawan.v3.StreamEventsRequest",
+ "requestStreaming": false,
+ "responseType": "Event",
+ "responseLongType": "Event",
+ "responseFullType": "ttn.lorawan.v3.Event",
+ "responseStreaming": true,
"options": {
- "validate.rules": [
- {
- "name": "string.max_len",
- "value": 2000
- }
- ]
+ "google.api.http": {
+ "rules": [
+ {
+ "method": "POST",
+ "pattern": "/events",
+ "body": "*"
+ }
+ ]
+ }
}
},
{
- "name": "attributes",
- "description": "Key-value attributes for this gateway. Typically used for organizing gateways or for storing integration-specific data.",
- "label": "repeated",
- "type": "AttributesEntry",
- "longType": "Gateway.AttributesEntry",
- "fullType": "ttn.lorawan.v3.Gateway.AttributesEntry",
- "ismap": true,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
+ "name": "FindRelated",
+ "description": "",
+ "requestType": "FindRelatedEventsRequest",
+ "requestLongType": "FindRelatedEventsRequest",
+ "requestFullType": "ttn.lorawan.v3.FindRelatedEventsRequest",
+ "requestStreaming": false,
+ "responseType": "FindRelatedEventsResponse",
+ "responseLongType": "FindRelatedEventsResponse",
+ "responseFullType": "ttn.lorawan.v3.FindRelatedEventsResponse",
+ "responseStreaming": false,
"options": {
- "validate.rules": [
- {
- "name": "map.max_pairs",
- "value": 10
- },
- {
- "name": "map.keys.string.max_len",
- "value": 36
- },
- {
- "name": "map.keys.string.pattern",
- "value": "^[a-z0-9](?:[-]?[a-z0-9]){2,}$"
- },
- {
- "name": "map.values.string.max_len",
- "value": 200
- }
- ]
+ "google.api.http": {
+ "rules": [
+ {
+ "method": "GET",
+ "pattern": "/events/related"
+ }
+ ]
+ }
}
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "ttn/lorawan/v3/gateway.proto",
+ "description": "",
+ "package": "ttn.lorawan.v3",
+ "hasEnums": true,
+ "hasExtensions": false,
+ "hasMessages": true,
+ "hasServices": false,
+ "enums": [
+ {
+ "name": "GatewayAntennaPlacement",
+ "longName": "GatewayAntennaPlacement",
+ "fullName": "ttn.lorawan.v3.GatewayAntennaPlacement",
+ "description": "",
+ "values": [
+ {
+ "name": "PLACEMENT_UNKNOWN",
+ "number": "0",
+ "description": ""
},
{
- "name": "contact_info",
- "description": "Contact information for this gateway. Typically used to indicate who to contact with technical/security questions about the gateway.\nThis field is deprecated. Use administrative_contact and technical_contact instead.",
- "label": "repeated",
- "type": "ContactInfo",
- "longType": "ContactInfo",
- "fullType": "ttn.lorawan.v3.ContactInfo",
+ "name": "INDOOR",
+ "number": "1",
+ "description": ""
+ },
+ {
+ "name": "OUTDOOR",
+ "number": "2",
+ "description": ""
+ }
+ ]
+ }
+ ],
+ "extensions": [],
+ "messages": [
+ {
+ "name": "CreateGatewayAPIKeyRequest",
+ "longName": "CreateGatewayAPIKeyRequest",
+ "fullName": "ttn.lorawan.v3.CreateGatewayAPIKeyRequest",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "gateway_ids",
+ "description": "",
+ "label": "",
+ "type": "GatewayIdentifiers",
+ "longType": "GatewayIdentifiers",
+ "fullType": "ttn.lorawan.v3.GatewayIdentifiers",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": "",
"options": {
- "deprecated": true,
"validate.rules": [
{
- "name": "repeated.max_items",
- "value": 10
+ "name": "message.required",
+ "value": true
}
]
}
},
{
- "name": "administrative_contact",
- "description": "",
- "label": "",
- "type": "OrganizationOrUserIdentifiers",
- "longType": "OrganizationOrUserIdentifiers",
- "fullType": "ttn.lorawan.v3.OrganizationOrUserIdentifiers",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
- },
- {
- "name": "technical_contact",
- "description": "",
- "label": "",
- "type": "OrganizationOrUserIdentifiers",
- "longType": "OrganizationOrUserIdentifiers",
- "fullType": "ttn.lorawan.v3.OrganizationOrUserIdentifiers",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
- },
- {
- "name": "version_ids",
+ "name": "name",
"description": "",
"label": "",
- "type": "GatewayVersionIdentifiers",
- "longType": "GatewayVersionIdentifiers",
- "fullType": "ttn.lorawan.v3.GatewayVersionIdentifiers",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
- },
- {
- "name": "gateway_server_address",
- "description": "The address of the Gateway Server to connect to.\nThis information is public and can be seen by any authenticated user in the network if status_public is true.\nThe typical format of the address is \"scheme://host:port\". The scheme is optional. If the port is omitted,\nthe normal port inference (with DNS lookup, otherwise defaults) is used.\nThe connection shall be established with transport layer security (TLS).\nCustom certificate authorities may be configured out-of-band.",
- "label": "",
"type": "string",
"longType": "string",
"fullType": "string",
@@ -20685,31 +20771,47 @@
"options": {
"validate.rules": [
{
- "name": "string.pattern",
- "value": "^([a-z]{2,5}://)?(?:(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*(?:[A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])(?::[0-9]{1,5})?$|^$"
+ "name": "string.max_len",
+ "value": 50
}
]
}
},
{
- "name": "auto_update",
+ "name": "rights",
"description": "",
- "label": "",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
+ "label": "repeated",
+ "type": "Right",
+ "longType": "Right",
+ "fullType": "ttn.lorawan.v3.Right",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "repeated.min_items",
+ "value": 1
+ },
+ {
+ "name": "repeated.unique",
+ "value": true
+ },
+ {
+ "name": "repeated.items.enum.defined_only",
+ "value": true
+ }
+ ]
+ }
},
{
- "name": "update_channel",
+ "name": "expires_at",
"description": "",
"label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
+ "type": "Timestamp",
+ "longType": "google.protobuf.Timestamp",
+ "fullType": "google.protobuf.Timestamp",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -20717,19 +20819,31 @@
"options": {
"validate.rules": [
{
- "name": "string.max_len",
- "value": 128
+ "name": "timestamp.gt_now",
+ "value": true
}
]
}
- },
+ }
+ ]
+ },
+ {
+ "name": "CreateGatewayRequest",
+ "longName": "CreateGatewayRequest",
+ "fullName": "ttn.lorawan.v3.CreateGatewayRequest",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "frequency_plan_id",
- "description": "Frequency plan ID of the gateway.\nThis information is public and can be seen by any authenticated user in the network.\nDEPRECATED: use frequency_plan_ids.\nThis equals the first element of the frequency_plan_ids field.",
+ "name": "gateway",
+ "description": "",
"label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
+ "type": "Gateway",
+ "longType": "Gateway",
+ "fullType": "ttn.lorawan.v3.Gateway",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -20737,19 +20851,19 @@
"options": {
"validate.rules": [
{
- "name": "string.max_len",
- "value": 64
+ "name": "message.required",
+ "value": true
}
]
}
},
{
- "name": "frequency_plan_ids",
- "description": "Frequency plan IDs of the gateway.\nThis information is public and can be seen by any authenticated user in the network.\nThe first element equals the frequency_plan_id field.",
- "label": "repeated",
- "type": "string",
- "longType": "string",
- "fullType": "string",
+ "name": "collaborator",
+ "description": "Collaborator to grant all rights on the newly created gateway.",
+ "label": "",
+ "type": "OrganizationOrUserIdentifiers",
+ "longType": "OrganizationOrUserIdentifiers",
+ "fullType": "ttn.lorawan.v3.OrganizationOrUserIdentifiers",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -20757,23 +20871,31 @@
"options": {
"validate.rules": [
{
- "name": "repeated.max_items",
- "value": 8
- },
- {
- "name": "repeated.items.string.max_len",
- "value": 64
+ "name": "message.required",
+ "value": true
}
]
}
- },
+ }
+ ]
+ },
+ {
+ "name": "DeleteGatewayAPIKeyRequest",
+ "longName": "DeleteGatewayAPIKeyRequest",
+ "fullName": "ttn.lorawan.v3.DeleteGatewayAPIKeyRequest",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "antennas",
- "description": "Antennas of the gateway. Location information of the antennas is public and can be seen by any authenticated user in the network if location_public=true.",
- "label": "repeated",
- "type": "GatewayAntenna",
- "longType": "GatewayAntenna",
- "fullType": "ttn.lorawan.v3.GatewayAntenna",
+ "name": "gateway_ids",
+ "description": "",
+ "label": "",
+ "type": "GatewayIdentifiers",
+ "longType": "GatewayIdentifiers",
+ "fullType": "ttn.lorawan.v3.GatewayIdentifiers",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -20781,67 +20903,95 @@
"options": {
"validate.rules": [
{
- "name": "repeated.max_items",
- "value": 8
+ "name": "message.required",
+ "value": true
}
]
}
},
{
- "name": "status_public",
- "description": "The status of this gateway may be publicly displayed.",
+ "name": "key_id",
+ "description": "",
"label": "",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
- },
- {
- "name": "location_public",
- "description": "The location of this gateway may be publicly displayed.",
- "label": "",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
- },
+ }
+ ]
+ },
+ {
+ "name": "DeleteGatewayCollaboratorRequest",
+ "longName": "DeleteGatewayCollaboratorRequest",
+ "fullName": "ttn.lorawan.v3.DeleteGatewayCollaboratorRequest",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "schedule_downlink_late",
- "description": "Enable server-side buffering of downlink messages. This is recommended for gateways using the Semtech UDP Packet\nForwarder v2.x or older, as it does not feature a just-in-time queue. If enabled, the Gateway Server schedules the\ndownlink message late to the gateway so that it does not overwrite previously scheduled downlink messages that have\nnot been transmitted yet.",
+ "name": "gateway_ids",
+ "description": "",
"label": "",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
+ "type": "GatewayIdentifiers",
+ "longType": "GatewayIdentifiers",
+ "fullType": "ttn.lorawan.v3.GatewayIdentifiers",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "message.required",
+ "value": true
+ }
+ ]
+ }
},
{
- "name": "enforce_duty_cycle",
- "description": "Enforcing gateway duty cycle is recommended for all gateways to respect spectrum regulations. Disable enforcing the\nduty cycle only in controlled research and development environments.",
+ "name": "collaborator_ids",
+ "description": "",
"label": "",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
+ "type": "OrganizationOrUserIdentifiers",
+ "longType": "OrganizationOrUserIdentifiers",
+ "fullType": "ttn.lorawan.v3.OrganizationOrUserIdentifiers",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
- },
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "message.required",
+ "value": true
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "Gateway",
+ "longName": "Gateway",
+ "fullName": "ttn.lorawan.v3.Gateway",
+ "description": "Gateway is the message that defines a gateway on the network.",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "downlink_path_constraint",
- "description": "",
+ "name": "ids",
+ "description": "The identifiers of the gateway. These are public and can be seen by any authenticated user in the network.",
"label": "",
- "type": "DownlinkPathConstraint",
- "longType": "DownlinkPathConstraint",
- "fullType": "ttn.lorawan.v3.DownlinkPathConstraint",
+ "type": "GatewayIdentifiers",
+ "longType": "GatewayIdentifiers",
+ "fullType": "ttn.lorawan.v3.GatewayIdentifiers",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -20849,63 +20999,71 @@
"options": {
"validate.rules": [
{
- "name": "enum.defined_only",
+ "name": "message.required",
"value": true
}
]
}
},
{
- "name": "schedule_anytime_delay",
- "description": "Adjust the time that GS schedules class C messages in advance. This is useful for gateways that have a known high latency backhaul, like 3G and satellite.",
+ "name": "created_at",
+ "description": "When the gateway was created. This information is public and can be seen by any authenticated user in the network.",
"label": "",
- "type": "Duration",
- "longType": "google.protobuf.Duration",
- "fullType": "google.protobuf.Duration",
+ "type": "Timestamp",
+ "longType": "google.protobuf.Timestamp",
+ "fullType": "google.protobuf.Timestamp",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "update_location_from_status",
- "description": "Update the location of this gateway from status messages. This only works for gateways connecting with authentication; gateways connected over UDP are not supported.",
+ "name": "updated_at",
+ "description": "When the gateway was last updated. This information is public and can be seen by any authenticated user in the network.",
"label": "",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
+ "type": "Timestamp",
+ "longType": "google.protobuf.Timestamp",
+ "fullType": "google.protobuf.Timestamp",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "lbs_lns_secret",
- "description": "The LoRa Basics Station LNS secret.\nThis is either an auth token (such as an API Key) or a TLS private certificate.\nRequires the RIGHT_GATEWAY_READ_SECRETS for reading and RIGHT_GATEWAY_WRITE_SECRETS for updating this value.",
+ "name": "deleted_at",
+ "description": "When the gateway was deleted. This information is public and can be seen by any authenticated user in the network.",
"label": "",
- "type": "Secret",
- "longType": "Secret",
- "fullType": "ttn.lorawan.v3.Secret",
+ "type": "Timestamp",
+ "longType": "google.protobuf.Timestamp",
+ "fullType": "google.protobuf.Timestamp",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "claim_authentication_code",
- "description": "The authentication code for gateway claiming.\nRequires the RIGHT_GATEWAY_READ_SECRETS for reading and RIGHT_GATEWAY_WRITE_SECRETS for updating this value.\nThe entire field must be used in RPCs since sub-fields are validated wrt to each other. Direct selection/update of sub-fields only are not allowed.\nUse the top level field mask `claim_authentication_code` even when updating single fields.",
+ "name": "name",
+ "description": "The name of the gateway. This information is public and can be seen by any authenticated user in the network.",
"label": "",
- "type": "GatewayClaimAuthenticationCode",
- "longType": "GatewayClaimAuthenticationCode",
- "fullType": "ttn.lorawan.v3.GatewayClaimAuthenticationCode",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "string.max_len",
+ "value": 50
+ }
+ ]
+ }
},
{
- "name": "target_cups_uri",
- "description": "CUPS URI for LoRa Basics Station CUPS redirection.\nThe CUPS Trust field will be automatically fetched from the cert chain presented by the target server.",
+ "name": "description",
+ "description": "A description for the gateway. This information is public and can be seen by any authenticated user in the network.",
"label": "",
"type": "string",
"longType": "string",
@@ -20917,87 +21075,104 @@
"options": {
"validate.rules": [
{
- "name": "string.uri",
- "value": true
+ "name": "string.max_len",
+ "value": 2000
}
]
}
},
{
- "name": "target_cups_key",
- "description": "CUPS Key for LoRa Basics Station CUPS redirection.\nIf redirecting to another instance of TTS, use the CUPS API Key for the gateway on the target instance.\nRequires the RIGHT_GATEWAY_READ_SECRETS for reading and RIGHT_GATEWAY_WRITE_SECRETS for updating this value.",
- "label": "",
- "type": "Secret",
- "longType": "Secret",
- "fullType": "ttn.lorawan.v3.Secret",
- "ismap": false,
+ "name": "attributes",
+ "description": "Key-value attributes for this gateway. Typically used for organizing gateways or for storing integration-specific data.",
+ "label": "repeated",
+ "type": "AttributesEntry",
+ "longType": "Gateway.AttributesEntry",
+ "fullType": "ttn.lorawan.v3.Gateway.AttributesEntry",
+ "ismap": true,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "map.max_pairs",
+ "value": 10
+ },
+ {
+ "name": "map.keys.string.max_len",
+ "value": 36
+ },
+ {
+ "name": "map.keys.string.pattern",
+ "value": "^[a-z0-9](?:[-]?[a-z0-9]){2,}$"
+ },
+ {
+ "name": "map.values.string.max_len",
+ "value": 200
+ }
+ ]
+ }
},
{
- "name": "require_authenticated_connection",
- "description": "Require an authenticated gateway connection. This prevents the gateway from using the UDP protocol and requires authentication when using other protocols.",
- "label": "",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
+ "name": "contact_info",
+ "description": "Contact information for this gateway. Typically used to indicate who to contact with technical/security questions about the gateway.\nThis field is deprecated. Use administrative_contact and technical_contact instead.",
+ "label": "repeated",
+ "type": "ContactInfo",
+ "longType": "ContactInfo",
+ "fullType": "ttn.lorawan.v3.ContactInfo",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
+ "defaultValue": "",
+ "options": {
+ "deprecated": true,
+ "validate.rules": [
+ {
+ "name": "repeated.max_items",
+ "value": 10
+ }
+ ]
+ }
},
{
- "name": "lrfhss",
+ "name": "administrative_contact",
"description": "",
"label": "",
- "type": "LRFHSS",
- "longType": "Gateway.LRFHSS",
- "fullType": "ttn.lorawan.v3.Gateway.LRFHSS",
+ "type": "OrganizationOrUserIdentifiers",
+ "longType": "OrganizationOrUserIdentifiers",
+ "fullType": "ttn.lorawan.v3.OrganizationOrUserIdentifiers",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "disable_packet_broker_forwarding",
+ "name": "technical_contact",
"description": "",
"label": "",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
+ "type": "OrganizationOrUserIdentifiers",
+ "longType": "OrganizationOrUserIdentifiers",
+ "fullType": "ttn.lorawan.v3.OrganizationOrUserIdentifiers",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
- }
- ]
- },
- {
- "name": "AttributesEntry",
- "longName": "Gateway.AttributesEntry",
- "fullName": "ttn.lorawan.v3.Gateway.AttributesEntry",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ },
{
- "name": "key",
+ "name": "version_ids",
"description": "",
"label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
+ "type": "GatewayVersionIdentifiers",
+ "longType": "GatewayVersionIdentifiers",
+ "fullType": "ttn.lorawan.v3.GatewayVersionIdentifiers",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "value",
- "description": "",
+ "name": "gateway_server_address",
+ "description": "The address of the Gateway Server to connect to.\nThis information is public and can be seen by any authenticated user in the network if status_public is true.\nThe typical format of the address is \"scheme://host:port\". The scheme is optional. If the port is omitted,\nthe normal port inference (with DNS lookup, otherwise defaults) is used.\nThe connection shall be established with transport layer security (TLS).\nCustom certificate authorities may be configured out-of-band.",
"label": "",
"type": "string",
"longType": "string",
@@ -21005,23 +21180,19 @@
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
- }
- ]
- },
- {
- "name": "LRFHSS",
- "longName": "Gateway.LRFHSS",
- "fullName": "ttn.lorawan.v3.Gateway.LRFHSS",
- "description": "LR-FHSS gateway capabilities.",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "string.pattern",
+ "value": "^([a-z]{2,5}://)?(?:(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*(?:[A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])(?::[0-9]{1,5})?$|^$"
+ }
+ ]
+ }
+ },
{
- "name": "supported",
- "description": "The gateway supports the LR-FHSS uplink channels.",
+ "name": "auto_update",
+ "description": "",
"label": "",
"type": "bool",
"longType": "bool",
@@ -21030,199 +21201,186 @@
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
- }
- ]
- },
- {
- "name": "GatewayAntenna",
- "longName": "GatewayAntenna",
- "fullName": "ttn.lorawan.v3.GatewayAntenna",
- "description": "GatewayAntenna is the message that defines a gateway antenna.",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ },
{
- "name": "gain",
- "description": "Antenna gain relative to the gateway, in dBi.",
+ "name": "update_channel",
+ "description": "",
"label": "",
- "type": "float",
- "longType": "float",
- "fullType": "float",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "string.max_len",
+ "value": 128
+ }
+ ]
+ }
},
{
- "name": "location",
- "description": "location is the antenna's location.",
+ "name": "frequency_plan_id",
+ "description": "Frequency plan ID of the gateway.\nThis information is public and can be seen by any authenticated user in the network.\nDEPRECATED: use frequency_plan_ids.\nThis equals the first element of the frequency_plan_ids field.",
"label": "",
- "type": "Location",
- "longType": "Location",
- "fullType": "ttn.lorawan.v3.Location",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "string.max_len",
+ "value": 64
+ }
+ ]
+ }
},
{
- "name": "attributes",
- "description": "",
+ "name": "frequency_plan_ids",
+ "description": "Frequency plan IDs of the gateway.\nThis information is public and can be seen by any authenticated user in the network.\nThe first element equals the frequency_plan_id field.",
"label": "repeated",
- "type": "AttributesEntry",
- "longType": "GatewayAntenna.AttributesEntry",
- "fullType": "ttn.lorawan.v3.GatewayAntenna.AttributesEntry",
- "ismap": true,
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
+ "ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": "",
"options": {
- "deprecated": true,
"validate.rules": [
{
- "name": "map.max_pairs",
- "value": 10
- },
- {
- "name": "map.keys.string.max_len",
- "value": 36
+ "name": "repeated.max_items",
+ "value": 8
},
{
- "name": "map.keys.string.pattern",
- "value": "^[a-z0-9](?:[-]?[a-z0-9]){2,}$"
- },
+ "name": "repeated.items.string.max_len",
+ "value": 64
+ }
+ ]
+ }
+ },
+ {
+ "name": "antennas",
+ "description": "Antennas of the gateway. Location information of the antennas is public and can be seen by any authenticated user in the network if location_public=true.",
+ "label": "repeated",
+ "type": "GatewayAntenna",
+ "longType": "GatewayAntenna",
+ "fullType": "ttn.lorawan.v3.GatewayAntenna",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
{
- "name": "map.values.string.max_len",
- "value": 200
+ "name": "repeated.max_items",
+ "value": 8
}
]
}
},
{
- "name": "placement",
- "description": "",
+ "name": "status_public",
+ "description": "The status of this gateway may be publicly displayed.",
"label": "",
- "type": "GatewayAntennaPlacement",
- "longType": "GatewayAntennaPlacement",
- "fullType": "ttn.lorawan.v3.GatewayAntennaPlacement",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
- }
- ]
- },
- {
- "name": "AttributesEntry",
- "longName": "GatewayAntenna.AttributesEntry",
- "fullName": "ttn.lorawan.v3.GatewayAntenna.AttributesEntry",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ },
{
- "name": "key",
- "description": "",
+ "name": "location_public",
+ "description": "The location of this gateway may be publicly displayed.",
"label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "value",
- "description": "",
+ "name": "schedule_downlink_late",
+ "description": "Enable server-side buffering of downlink messages. This is recommended for gateways using the Semtech UDP Packet\nForwarder v2.x or older, as it does not feature a just-in-time queue. If enabled, the Gateway Server schedules the\ndownlink message late to the gateway so that it does not overwrite previously scheduled downlink messages that have\nnot been transmitted yet.",
"label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
- }
- ]
- },
- {
- "name": "GatewayBrand",
- "longName": "GatewayBrand",
- "fullName": "ttn.lorawan.v3.GatewayBrand",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ },
{
- "name": "id",
- "description": "",
+ "name": "enforce_duty_cycle",
+ "description": "Enforcing gateway duty cycle is recommended for all gateways to respect spectrum regulations. Disable enforcing the\nduty cycle only in controlled research and development environments.",
"label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "name",
+ "name": "downlink_path_constraint",
"description": "",
"label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
+ "type": "DownlinkPathConstraint",
+ "longType": "DownlinkPathConstraint",
+ "fullType": "ttn.lorawan.v3.DownlinkPathConstraint",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "enum.defined_only",
+ "value": true
+ }
+ ]
+ }
},
{
- "name": "url",
- "description": "",
+ "name": "schedule_anytime_delay",
+ "description": "Adjust the time that GS schedules class C messages in advance. This is useful for gateways that have a known high latency backhaul, like 3G and satellite.",
"label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
+ "type": "Duration",
+ "longType": "google.protobuf.Duration",
+ "fullType": "google.protobuf.Duration",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "logos",
- "description": "Logos contains file names of brand logos.",
- "label": "repeated",
- "type": "string",
- "longType": "string",
- "fullType": "string",
+ "name": "update_location_from_status",
+ "description": "Update the location of this gateway from status messages. This only works for gateways connecting with authentication; gateways connected over UDP are not supported.",
+ "label": "",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
- }
- ]
- },
- {
- "name": "GatewayClaimAuthenticationCode",
- "longName": "GatewayClaimAuthenticationCode",
- "fullName": "ttn.lorawan.v3.GatewayClaimAuthenticationCode",
- "description": "Authentication code for claiming gateways.",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ },
{
- "name": "secret",
- "description": "",
+ "name": "lbs_lns_secret",
+ "description": "The LoRa Basics Station LNS secret.\nThis is either an auth token (such as an API Key) or a TLS private certificate.\nRequires the RIGHT_GATEWAY_READ_SECRETS for reading and RIGHT_GATEWAY_WRITE_SECRETS for updating this value.",
"label": "",
"type": "Secret",
"longType": "Secret",
@@ -21233,204 +21391,257 @@
"defaultValue": ""
},
{
- "name": "valid_from",
- "description": "",
+ "name": "claim_authentication_code",
+ "description": "The authentication code for gateway claiming.\nRequires the RIGHT_GATEWAY_READ_SECRETS for reading and RIGHT_GATEWAY_WRITE_SECRETS for updating this value.\nThe entire field must be used in RPCs since sub-fields are validated wrt to each other. Direct selection/update of sub-fields only are not allowed.\nUse the top level field mask `claim_authentication_code` even when updating single fields.",
"label": "",
- "type": "Timestamp",
- "longType": "google.protobuf.Timestamp",
- "fullType": "google.protobuf.Timestamp",
+ "type": "GatewayClaimAuthenticationCode",
+ "longType": "GatewayClaimAuthenticationCode",
+ "fullType": "ttn.lorawan.v3.GatewayClaimAuthenticationCode",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "valid_to",
- "description": "",
- "label": "",
- "type": "Timestamp",
- "longType": "google.protobuf.Timestamp",
- "fullType": "google.protobuf.Timestamp",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
- }
- ]
- },
- {
- "name": "GatewayConnectionStats",
- "longName": "GatewayConnectionStats",
- "fullName": "ttn.lorawan.v3.GatewayConnectionStats",
- "description": "Connection stats as monitored by the Gateway Server.",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
- {
- "name": "connected_at",
- "description": "",
+ "name": "target_cups_uri",
+ "description": "CUPS URI for LoRa Basics Station CUPS redirection.\nThe CUPS Trust field will be automatically fetched from the cert chain presented by the target server.",
"label": "",
- "type": "Timestamp",
- "longType": "google.protobuf.Timestamp",
- "fullType": "google.protobuf.Timestamp",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "string.uri",
+ "value": true
+ }
+ ]
+ }
},
{
- "name": "disconnected_at",
- "description": "",
+ "name": "target_cups_key",
+ "description": "CUPS Key for LoRa Basics Station CUPS redirection.\nIf redirecting to another instance of TTS, use the CUPS API Key for the gateway on the target instance.\nRequires the RIGHT_GATEWAY_READ_SECRETS for reading and RIGHT_GATEWAY_WRITE_SECRETS for updating this value.",
"label": "",
- "type": "Timestamp",
- "longType": "google.protobuf.Timestamp",
- "fullType": "google.protobuf.Timestamp",
+ "type": "Secret",
+ "longType": "Secret",
+ "fullType": "ttn.lorawan.v3.Secret",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "protocol",
- "description": "Protocol used to connect (for example, udp, mqtt, grpc)",
+ "name": "require_authenticated_connection",
+ "description": "Require an authenticated gateway connection. This prevents the gateway from using the UDP protocol and requires authentication when using other protocols.",
"label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "last_status_received_at",
+ "name": "lrfhss",
"description": "",
"label": "",
- "type": "Timestamp",
- "longType": "google.protobuf.Timestamp",
- "fullType": "google.protobuf.Timestamp",
+ "type": "LRFHSS",
+ "longType": "Gateway.LRFHSS",
+ "fullType": "ttn.lorawan.v3.Gateway.LRFHSS",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "last_status",
+ "name": "disable_packet_broker_forwarding",
"description": "",
"label": "",
- "type": "GatewayStatus",
- "longType": "GatewayStatus",
- "fullType": "ttn.lorawan.v3.GatewayStatus",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
- },
+ }
+ ]
+ },
+ {
+ "name": "AttributesEntry",
+ "longName": "Gateway.AttributesEntry",
+ "fullName": "ttn.lorawan.v3.Gateway.AttributesEntry",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "last_uplink_received_at",
+ "name": "key",
"description": "",
"label": "",
- "type": "Timestamp",
- "longType": "google.protobuf.Timestamp",
- "fullType": "google.protobuf.Timestamp",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "uplink_count",
+ "name": "value",
"description": "",
"label": "",
- "type": "uint64",
- "longType": "uint64",
- "fullType": "uint64",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
- },
+ }
+ ]
+ },
+ {
+ "name": "LRFHSS",
+ "longName": "Gateway.LRFHSS",
+ "fullName": "ttn.lorawan.v3.Gateway.LRFHSS",
+ "description": "LR-FHSS gateway capabilities.",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "last_downlink_received_at",
- "description": "",
+ "name": "supported",
+ "description": "The gateway supports the LR-FHSS uplink channels.",
"label": "",
- "type": "Timestamp",
- "longType": "google.protobuf.Timestamp",
- "fullType": "google.protobuf.Timestamp",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
- },
+ }
+ ]
+ },
+ {
+ "name": "GatewayAntenna",
+ "longName": "GatewayAntenna",
+ "fullName": "ttn.lorawan.v3.GatewayAntenna",
+ "description": "GatewayAntenna is the message that defines a gateway antenna.",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "downlink_count",
- "description": "",
+ "name": "gain",
+ "description": "Antenna gain relative to the gateway, in dBi.",
"label": "",
- "type": "uint64",
- "longType": "uint64",
- "fullType": "uint64",
+ "type": "float",
+ "longType": "float",
+ "fullType": "float",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "last_tx_acknowledgment_received_at",
- "description": "",
+ "name": "location",
+ "description": "location is the antenna's location.",
"label": "",
- "type": "Timestamp",
- "longType": "google.protobuf.Timestamp",
- "fullType": "google.protobuf.Timestamp",
+ "type": "Location",
+ "longType": "Location",
+ "fullType": "ttn.lorawan.v3.Location",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "tx_acknowledgment_count",
+ "name": "attributes",
"description": "",
- "label": "",
- "type": "uint64",
- "longType": "uint64",
- "fullType": "uint64",
- "ismap": false,
+ "label": "repeated",
+ "type": "AttributesEntry",
+ "longType": "GatewayAntenna.AttributesEntry",
+ "fullType": "ttn.lorawan.v3.GatewayAntenna.AttributesEntry",
+ "ismap": true,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
+ "defaultValue": "",
+ "options": {
+ "deprecated": true,
+ "validate.rules": [
+ {
+ "name": "map.max_pairs",
+ "value": 10
+ },
+ {
+ "name": "map.keys.string.max_len",
+ "value": 36
+ },
+ {
+ "name": "map.keys.string.pattern",
+ "value": "^[a-z0-9](?:[-]?[a-z0-9]){2,}$"
+ },
+ {
+ "name": "map.values.string.max_len",
+ "value": 200
+ }
+ ]
+ }
},
{
- "name": "round_trip_times",
+ "name": "placement",
"description": "",
"label": "",
- "type": "RoundTripTimes",
- "longType": "GatewayConnectionStats.RoundTripTimes",
- "fullType": "ttn.lorawan.v3.GatewayConnectionStats.RoundTripTimes",
+ "type": "GatewayAntennaPlacement",
+ "longType": "GatewayAntennaPlacement",
+ "fullType": "ttn.lorawan.v3.GatewayAntennaPlacement",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
- },
+ }
+ ]
+ },
+ {
+ "name": "AttributesEntry",
+ "longName": "GatewayAntenna.AttributesEntry",
+ "fullName": "ttn.lorawan.v3.GatewayAntenna.AttributesEntry",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "sub_bands",
- "description": "Statistics for each sub band.",
- "label": "repeated",
- "type": "SubBand",
- "longType": "GatewayConnectionStats.SubBand",
- "fullType": "ttn.lorawan.v3.GatewayConnectionStats.SubBand",
+ "name": "key",
+ "description": "",
+ "label": "",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "gateway_remote_address",
- "description": "Gateway Remote Address.",
+ "name": "value",
+ "description": "",
"label": "",
- "type": "GatewayRemoteAddress",
- "longType": "GatewayRemoteAddress",
- "fullType": "ttn.lorawan.v3.GatewayRemoteAddress",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -21439,9 +21650,9 @@
]
},
{
- "name": "RoundTripTimes",
- "longName": "GatewayConnectionStats.RoundTripTimes",
- "fullName": "ttn.lorawan.v3.GatewayConnectionStats.RoundTripTimes",
+ "name": "GatewayBrand",
+ "longName": "GatewayBrand",
+ "fullName": "ttn.lorawan.v3.GatewayBrand",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -21449,72 +21660,48 @@
"extensions": [],
"fields": [
{
- "name": "min",
+ "name": "id",
"description": "",
"label": "",
- "type": "Duration",
- "longType": "google.protobuf.Duration",
- "fullType": "google.protobuf.Duration",
- "ismap": false,
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
+ "ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "duration.required",
- "value": true
- }
- ]
- }
+ "defaultValue": ""
},
{
- "name": "max",
+ "name": "name",
"description": "",
"label": "",
- "type": "Duration",
- "longType": "google.protobuf.Duration",
- "fullType": "google.protobuf.Duration",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "duration.required",
- "value": true
- }
- ]
- }
+ "defaultValue": ""
},
{
- "name": "median",
+ "name": "url",
"description": "",
"label": "",
- "type": "Duration",
- "longType": "google.protobuf.Duration",
- "fullType": "google.protobuf.Duration",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "duration.required",
- "value": true
- }
- ]
- }
+ "defaultValue": ""
},
{
- "name": "count",
- "description": "",
- "label": "",
- "type": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
+ "name": "logos",
+ "description": "Logos contains file names of brand logos.",
+ "label": "repeated",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -21523,58 +21710,46 @@
]
},
{
- "name": "SubBand",
- "longName": "GatewayConnectionStats.SubBand",
- "fullName": "ttn.lorawan.v3.GatewayConnectionStats.SubBand",
- "description": "",
+ "name": "GatewayClaimAuthenticationCode",
+ "longName": "GatewayClaimAuthenticationCode",
+ "fullName": "ttn.lorawan.v3.GatewayClaimAuthenticationCode",
+ "description": "Authentication code for claiming gateways.",
"hasExtensions": false,
"hasFields": true,
"hasOneofs": false,
"extensions": [],
"fields": [
{
- "name": "min_frequency",
+ "name": "secret",
"description": "",
"label": "",
- "type": "uint64",
- "longType": "uint64",
- "fullType": "uint64",
+ "type": "Secret",
+ "longType": "Secret",
+ "fullType": "ttn.lorawan.v3.Secret",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "max_frequency",
+ "name": "valid_from",
"description": "",
"label": "",
- "type": "uint64",
- "longType": "uint64",
- "fullType": "uint64",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
- },
- {
- "name": "downlink_utilization_limit",
- "description": "Duty-cycle limit of the sub-band as a fraction of time.",
- "label": "",
- "type": "float",
- "longType": "float",
- "fullType": "float",
+ "type": "Timestamp",
+ "longType": "google.protobuf.Timestamp",
+ "fullType": "google.protobuf.Timestamp",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "downlink_utilization",
- "description": "Utilization rate of the available duty-cycle. This value should not exceed downlink_utilization_limit.",
+ "name": "valid_to",
+ "description": "",
"label": "",
- "type": "float",
- "longType": "float",
- "fullType": "float",
+ "type": "Timestamp",
+ "longType": "google.protobuf.Timestamp",
+ "fullType": "google.protobuf.Timestamp",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -21583,113 +21758,89 @@
]
},
{
- "name": "GatewayModel",
- "longName": "GatewayModel",
- "fullName": "ttn.lorawan.v3.GatewayModel",
- "description": "",
+ "name": "GatewayConnectionStats",
+ "longName": "GatewayConnectionStats",
+ "fullName": "ttn.lorawan.v3.GatewayConnectionStats",
+ "description": "Connection stats as monitored by the Gateway Server.",
"hasExtensions": false,
"hasFields": true,
"hasOneofs": false,
"extensions": [],
"fields": [
{
- "name": "brand_id",
+ "name": "connected_at",
"description": "",
"label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
+ "type": "Timestamp",
+ "longType": "google.protobuf.Timestamp",
+ "fullType": "google.protobuf.Timestamp",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "string.max_len",
- "value": 36
- },
- {
- "name": "string.pattern",
- "value": "^[a-z0-9](?:[-]?[a-z0-9]){2,}$"
- }
- ]
- }
+ "defaultValue": ""
},
{
- "name": "id",
+ "name": "disconnected_at",
"description": "",
"label": "",
+ "type": "Timestamp",
+ "longType": "google.protobuf.Timestamp",
+ "fullType": "google.protobuf.Timestamp",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "protocol",
+ "description": "Protocol used to connect (for example, udp, mqtt, grpc)",
+ "label": "",
"type": "string",
"longType": "string",
"fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "string.max_len",
- "value": 36
- },
- {
- "name": "string.pattern",
- "value": "^[a-z0-9](?:[-]?[a-z0-9]){2,}$"
- }
- ]
- }
+ "defaultValue": ""
},
{
- "name": "name",
+ "name": "last_status_received_at",
"description": "",
"label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
+ "type": "Timestamp",
+ "longType": "google.protobuf.Timestamp",
+ "fullType": "google.protobuf.Timestamp",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
- }
- ]
- },
- {
- "name": "GatewayRadio",
- "longName": "GatewayRadio",
- "fullName": "ttn.lorawan.v3.GatewayRadio",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ },
{
- "name": "enable",
+ "name": "last_status",
"description": "",
"label": "",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
+ "type": "GatewayStatus",
+ "longType": "GatewayStatus",
+ "fullType": "ttn.lorawan.v3.GatewayStatus",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "chip_type",
+ "name": "last_uplink_received_at",
"description": "",
"label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
+ "type": "Timestamp",
+ "longType": "google.protobuf.Timestamp",
+ "fullType": "google.protobuf.Timestamp",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "frequency",
+ "name": "uplink_count",
"description": "",
"label": "",
"type": "uint64",
@@ -21701,55 +21852,43 @@
"defaultValue": ""
},
{
- "name": "rssi_offset",
+ "name": "last_downlink_received_at",
"description": "",
"label": "",
- "type": "float",
- "longType": "float",
- "fullType": "float",
+ "type": "Timestamp",
+ "longType": "google.protobuf.Timestamp",
+ "fullType": "google.protobuf.Timestamp",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "tx_configuration",
+ "name": "downlink_count",
"description": "",
"label": "",
- "type": "TxConfiguration",
- "longType": "GatewayRadio.TxConfiguration",
- "fullType": "ttn.lorawan.v3.GatewayRadio.TxConfiguration",
+ "type": "uint64",
+ "longType": "uint64",
+ "fullType": "uint64",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
- }
- ]
- },
- {
- "name": "TxConfiguration",
- "longName": "GatewayRadio.TxConfiguration",
- "fullName": "ttn.lorawan.v3.GatewayRadio.TxConfiguration",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ },
{
- "name": "min_frequency",
+ "name": "last_tx_acknowledgment_received_at",
"description": "",
"label": "",
- "type": "uint64",
- "longType": "uint64",
- "fullType": "uint64",
+ "type": "Timestamp",
+ "longType": "google.protobuf.Timestamp",
+ "fullType": "google.protobuf.Timestamp",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "max_frequency",
+ "name": "tx_acknowledgment_count",
"description": "",
"label": "",
"type": "uint64",
@@ -21761,36 +21900,36 @@
"defaultValue": ""
},
{
- "name": "notch_frequency",
+ "name": "round_trip_times",
"description": "",
"label": "",
- "type": "uint64",
- "longType": "uint64",
- "fullType": "uint64",
+ "type": "RoundTripTimes",
+ "longType": "GatewayConnectionStats.RoundTripTimes",
+ "fullType": "ttn.lorawan.v3.GatewayConnectionStats.RoundTripTimes",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
- }
- ]
- },
- {
- "name": "GatewayRemoteAddress",
- "longName": "GatewayRemoteAddress",
- "fullName": "ttn.lorawan.v3.GatewayRemoteAddress",
- "description": "Remote Address of the Gateway, as seen by the Gateway Server.",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ },
{
- "name": "ip",
- "description": "IPv4 or IPv6 address.",
+ "name": "sub_bands",
+ "description": "Statistics for each sub band.",
+ "label": "repeated",
+ "type": "SubBand",
+ "longType": "GatewayConnectionStats.SubBand",
+ "fullType": "ttn.lorawan.v3.GatewayConnectionStats.SubBand",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "gateway_remote_address",
+ "description": "Gateway Remote Address.",
"label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
+ "type": "GatewayRemoteAddress",
+ "longType": "GatewayRemoteAddress",
+ "fullType": "ttn.lorawan.v3.GatewayRemoteAddress",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -21799,9 +21938,9 @@
]
},
{
- "name": "GatewayStatus",
- "longName": "GatewayStatus",
- "fullName": "ttn.lorawan.v3.GatewayStatus",
+ "name": "RoundTripTimes",
+ "longName": "GatewayConnectionStats.RoundTripTimes",
+ "fullName": "ttn.lorawan.v3.GatewayConnectionStats.RoundTripTimes",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -21809,68 +21948,32 @@
"extensions": [],
"fields": [
{
- "name": "time",
- "description": "Current time of the gateway",
- "label": "",
- "type": "Timestamp",
- "longType": "google.protobuf.Timestamp",
- "fullType": "google.protobuf.Timestamp",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
- },
- {
- "name": "boot_time",
- "description": "Boot time of the gateway\n- can be left out to save bandwidth; old value will be kept",
+ "name": "min",
+ "description": "",
"label": "",
- "type": "Timestamp",
- "longType": "google.protobuf.Timestamp",
- "fullType": "google.protobuf.Timestamp",
+ "type": "Duration",
+ "longType": "google.protobuf.Duration",
+ "fullType": "google.protobuf.Duration",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
- },
- {
- "name": "versions",
- "description": "Versions of gateway subsystems\n- each field can be left out to save bandwidth; old value will be kept\n- map keys are written in snake_case\n- for example:\n firmware: \"2.0.4\"\n forwarder: \"v2-3.3.1\"\n fpga: \"48\"\n dsp: \"27\"\n hal: \"v2-3.5.0\"",
- "label": "repeated",
- "type": "VersionsEntry",
- "longType": "GatewayStatus.VersionsEntry",
- "fullType": "ttn.lorawan.v3.GatewayStatus.VersionsEntry",
- "ismap": true,
- "isoneof": false,
- "oneofdecl": "",
"defaultValue": "",
"options": {
"validate.rules": [
{
- "name": "map.max_pairs",
- "value": 10
- },
- {
- "name": "map.keys.string.max_len",
- "value": 36
- },
- {
- "name": "map.keys.string.pattern",
- "value": "^[a-z0-9](?:[_-]?[a-z0-9]){2,}$"
- },
- {
- "name": "map.values.string.max_len",
- "value": 128
+ "name": "duration.required",
+ "value": true
}
]
}
},
{
- "name": "antenna_locations",
- "description": "Location of each gateway's antenna\n- if left out, server uses registry-set location as fallback",
- "label": "repeated",
- "type": "Location",
- "longType": "Location",
- "fullType": "ttn.lorawan.v3.Location",
+ "name": "max",
+ "description": "",
+ "label": "",
+ "type": "Duration",
+ "longType": "google.protobuf.Duration",
+ "fullType": "google.protobuf.Duration",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -21878,19 +21981,19 @@
"options": {
"validate.rules": [
{
- "name": "repeated.max_items",
- "value": 8
+ "name": "duration.required",
+ "value": true
}
]
}
},
{
- "name": "ip",
- "description": "IP addresses of this gateway.\nRepeated addresses can be used to communicate addresses of multiple interfaces (LAN, Public IP, ...).",
- "label": "repeated",
- "type": "string",
- "longType": "string",
- "fullType": "string",
+ "name": "median",
+ "description": "",
+ "label": "",
+ "type": "Duration",
+ "longType": "google.protobuf.Duration",
+ "fullType": "google.protobuf.Duration",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -21898,51 +22001,19 @@
"options": {
"validate.rules": [
{
- "name": "repeated.max_items",
- "value": 10
- },
- {
- "name": "repeated.items.string.ip",
+ "name": "duration.required",
"value": true
}
]
}
},
{
- "name": "metrics",
- "description": "Metrics\n- can be used for forwarding gateway metrics such as temperatures or performance metrics\n- map keys are written in snake_case",
- "label": "repeated",
- "type": "MetricsEntry",
- "longType": "GatewayStatus.MetricsEntry",
- "fullType": "ttn.lorawan.v3.GatewayStatus.MetricsEntry",
- "ismap": true,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "map.max_pairs",
- "value": 32
- },
- {
- "name": "map.keys.string.max_len",
- "value": 36
- },
- {
- "name": "map.keys.string.pattern",
- "value": "^[a-z0-9](?:[_-]?[a-z0-9]){2,}$"
- }
- ]
- }
- },
- {
- "name": "advanced",
- "description": "Advanced metadata fields\n- can be used for advanced information or experimental features that are not yet formally defined in the API\n- field names are written in snake_case",
+ "name": "count",
+ "description": "",
"label": "",
- "type": "Struct",
- "longType": "google.protobuf.Struct",
- "fullType": "google.protobuf.Struct",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -21951,9 +22022,9 @@
]
},
{
- "name": "MetricsEntry",
- "longName": "GatewayStatus.MetricsEntry",
- "fullName": "ttn.lorawan.v3.GatewayStatus.MetricsEntry",
+ "name": "SubBand",
+ "longName": "GatewayConnectionStats.SubBand",
+ "fullName": "ttn.lorawan.v3.GatewayConnectionStats.SubBand",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -21961,60 +22032,48 @@
"extensions": [],
"fields": [
{
- "name": "key",
+ "name": "min_frequency",
"description": "",
"label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
+ "type": "uint64",
+ "longType": "uint64",
+ "fullType": "uint64",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "value",
+ "name": "max_frequency",
"description": "",
"label": "",
- "type": "float",
- "longType": "float",
- "fullType": "float",
+ "type": "uint64",
+ "longType": "uint64",
+ "fullType": "uint64",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
- }
- ]
- },
- {
- "name": "VersionsEntry",
- "longName": "GatewayStatus.VersionsEntry",
- "fullName": "ttn.lorawan.v3.GatewayStatus.VersionsEntry",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ },
{
- "name": "key",
- "description": "",
+ "name": "downlink_utilization_limit",
+ "description": "Duty-cycle limit of the sub-band as a fraction of time.",
"label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
+ "type": "float",
+ "longType": "float",
+ "fullType": "float",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "value",
- "description": "",
+ "name": "downlink_utilization",
+ "description": "Utilization rate of the available duty-cycle. This value should not exceed downlink_utilization_limit.",
"label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
+ "type": "float",
+ "longType": "float",
+ "fullType": "float",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -22023,10 +22082,10 @@
]
},
{
- "name": "GatewayVersionIdentifiers",
- "longName": "GatewayVersionIdentifiers",
- "fullName": "ttn.lorawan.v3.GatewayVersionIdentifiers",
- "description": "Identifies an end device model with version information.",
+ "name": "GatewayModel",
+ "longName": "GatewayModel",
+ "fullName": "ttn.lorawan.v3.GatewayModel",
+ "description": "",
"hasExtensions": false,
"hasFields": true,
"hasOneofs": false,
@@ -22057,7 +22116,7 @@
}
},
{
- "name": "model_id",
+ "name": "id",
"description": "",
"label": "",
"type": "string",
@@ -22081,7 +22140,7 @@
}
},
{
- "name": "hardware_version",
+ "name": "name",
"description": "",
"label": "",
"type": "string",
@@ -22090,18 +22149,34 @@
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "string.max_len",
- "value": 32
- }
- ]
- }
- },
+ "defaultValue": ""
+ }
+ ]
+ },
+ {
+ "name": "GatewayRadio",
+ "longName": "GatewayRadio",
+ "fullName": "ttn.lorawan.v3.GatewayRadio",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "firmware_version",
+ "name": "enable",
+ "description": "",
+ "label": "",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "chip_type",
"description": "",
"label": "",
"type": "string",
@@ -22110,79 +22185,39 @@
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "string.max_len",
- "value": 32
- }
- ]
- }
- }
- ]
- },
- {
- "name": "Gateways",
- "longName": "Gateways",
- "fullName": "ttn.lorawan.v3.Gateways",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ "defaultValue": ""
+ },
{
- "name": "gateways",
+ "name": "frequency",
"description": "",
- "label": "repeated",
- "type": "Gateway",
- "longType": "Gateway",
- "fullType": "ttn.lorawan.v3.Gateway",
+ "label": "",
+ "type": "uint64",
+ "longType": "uint64",
+ "fullType": "uint64",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
- }
- ]
- },
- {
- "name": "GetGatewayAPIKeyRequest",
- "longName": "GetGatewayAPIKeyRequest",
- "fullName": "ttn.lorawan.v3.GetGatewayAPIKeyRequest",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ },
{
- "name": "gateway_ids",
+ "name": "rssi_offset",
"description": "",
"label": "",
- "type": "GatewayIdentifiers",
- "longType": "GatewayIdentifiers",
- "fullType": "ttn.lorawan.v3.GatewayIdentifiers",
+ "type": "float",
+ "longType": "float",
+ "fullType": "float",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "message.required",
- "value": true
- }
- ]
- }
+ "defaultValue": ""
},
{
- "name": "key_id",
- "description": "Unique public identifier for the API key.",
+ "name": "tx_configuration",
+ "description": "",
"label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
+ "type": "TxConfiguration",
+ "longType": "GatewayRadio.TxConfiguration",
+ "fullType": "ttn.lorawan.v3.GatewayRadio.TxConfiguration",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -22191,9 +22226,9 @@
]
},
{
- "name": "GetGatewayCollaboratorRequest",
- "longName": "GetGatewayCollaboratorRequest",
- "fullName": "ttn.lorawan.v3.GetGatewayCollaboratorRequest",
+ "name": "TxConfiguration",
+ "longName": "GatewayRadio.TxConfiguration",
+ "fullName": "ttn.lorawan.v3.GatewayRadio.TxConfiguration",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -22201,83 +22236,71 @@
"extensions": [],
"fields": [
{
- "name": "gateway_ids",
+ "name": "min_frequency",
"description": "",
"label": "",
- "type": "GatewayIdentifiers",
- "longType": "GatewayIdentifiers",
- "fullType": "ttn.lorawan.v3.GatewayIdentifiers",
+ "type": "uint64",
+ "longType": "uint64",
+ "fullType": "uint64",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "message.required",
- "value": true
- }
- ]
- }
+ "defaultValue": ""
},
{
- "name": "collaborator",
+ "name": "max_frequency",
"description": "",
"label": "",
- "type": "OrganizationOrUserIdentifiers",
- "longType": "OrganizationOrUserIdentifiers",
- "fullType": "ttn.lorawan.v3.OrganizationOrUserIdentifiers",
+ "type": "uint64",
+ "longType": "uint64",
+ "fullType": "uint64",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "message.required",
- "value": true
- }
- ]
- }
+ "defaultValue": ""
+ },
+ {
+ "name": "notch_frequency",
+ "description": "",
+ "label": "",
+ "type": "uint64",
+ "longType": "uint64",
+ "fullType": "uint64",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
}
]
},
{
- "name": "GetGatewayIdentifiersForEUIRequest",
- "longName": "GetGatewayIdentifiersForEUIRequest",
- "fullName": "ttn.lorawan.v3.GetGatewayIdentifiersForEUIRequest",
- "description": "",
+ "name": "GatewayRemoteAddress",
+ "longName": "GatewayRemoteAddress",
+ "fullName": "ttn.lorawan.v3.GatewayRemoteAddress",
+ "description": "Remote Address of the Gateway, as seen by the Gateway Server.",
"hasExtensions": false,
"hasFields": true,
"hasOneofs": false,
"extensions": [],
"fields": [
{
- "name": "eui",
- "description": "",
+ "name": "ip",
+ "description": "IPv4 or IPv6 address.",
"label": "",
- "type": "bytes",
- "longType": "bytes",
- "fullType": "bytes",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "bytes.len",
- "value": 8
- }
- ]
- }
+ "defaultValue": ""
}
]
},
{
- "name": "GetGatewayRequest",
- "longName": "GetGatewayRequest",
- "fullName": "ttn.lorawan.v3.GetGatewayRequest",
+ "name": "GatewayStatus",
+ "longName": "GatewayStatus",
+ "fullName": "ttn.lorawan.v3.GatewayStatus",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -22285,76 +22308,68 @@
"extensions": [],
"fields": [
{
- "name": "gateway_ids",
- "description": "",
+ "name": "time",
+ "description": "Current time of the gateway",
"label": "",
- "type": "GatewayIdentifiers",
- "longType": "GatewayIdentifiers",
- "fullType": "ttn.lorawan.v3.GatewayIdentifiers",
+ "type": "Timestamp",
+ "longType": "google.protobuf.Timestamp",
+ "fullType": "google.protobuf.Timestamp",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "message.required",
- "value": true
- }
- ]
- }
+ "defaultValue": ""
},
{
- "name": "field_mask",
- "description": "The names of the gateway fields that should be returned.",
+ "name": "boot_time",
+ "description": "Boot time of the gateway\n- can be left out to save bandwidth; old value will be kept",
"label": "",
- "type": "FieldMask",
- "longType": "google.protobuf.FieldMask",
- "fullType": "google.protobuf.FieldMask",
+ "type": "Timestamp",
+ "longType": "google.protobuf.Timestamp",
+ "fullType": "google.protobuf.Timestamp",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
- }
- ]
- },
- {
- "name": "ListGatewayAPIKeysRequest",
- "longName": "ListGatewayAPIKeysRequest",
- "fullName": "ttn.lorawan.v3.ListGatewayAPIKeysRequest",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ },
{
- "name": "gateway_ids",
- "description": "",
- "label": "",
- "type": "GatewayIdentifiers",
- "longType": "GatewayIdentifiers",
- "fullType": "ttn.lorawan.v3.GatewayIdentifiers",
- "ismap": false,
+ "name": "versions",
+ "description": "Versions of gateway subsystems\n- each field can be left out to save bandwidth; old value will be kept\n- map keys are written in snake_case\n- for example:\n firmware: \"2.0.4\"\n forwarder: \"v2-3.3.1\"\n fpga: \"48\"\n dsp: \"27\"\n hal: \"v2-3.5.0\"",
+ "label": "repeated",
+ "type": "VersionsEntry",
+ "longType": "GatewayStatus.VersionsEntry",
+ "fullType": "ttn.lorawan.v3.GatewayStatus.VersionsEntry",
+ "ismap": true,
"isoneof": false,
"oneofdecl": "",
"defaultValue": "",
"options": {
"validate.rules": [
{
- "name": "message.required",
- "value": true
+ "name": "map.max_pairs",
+ "value": 10
+ },
+ {
+ "name": "map.keys.string.max_len",
+ "value": 36
+ },
+ {
+ "name": "map.keys.string.pattern",
+ "value": "^[a-z0-9](?:[_-]?[a-z0-9]){2,}$"
+ },
+ {
+ "name": "map.values.string.max_len",
+ "value": 128
}
]
}
},
{
- "name": "order",
- "description": "Order the results by this field path.\nDefault ordering is by ID. Prepend with a minus (-) to reverse the order.",
- "label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
+ "name": "antenna_locations",
+ "description": "Location of each gateway's antenna\n- if left out, server uses registry-set location as fallback",
+ "label": "repeated",
+ "type": "Location",
+ "longType": "Location",
+ "fullType": "ttn.lorawan.v3.Location",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -22362,29 +22377,19 @@
"options": {
"validate.rules": [
{
- "name": "string.in",
- "value": [
- "",
- "api_key_id",
- "-api_key_id",
- "name",
- "-name",
- "created_at",
- "-created_at",
- "expires_at",
- "-expires_at"
- ]
+ "name": "repeated.max_items",
+ "value": 8
}
]
}
},
{
- "name": "limit",
- "description": "Limit the number of results per page.",
- "label": "",
- "type": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
+ "name": "ip",
+ "description": "IP addresses of this gateway.\nRepeated addresses can be used to communicate addresses of multiple interfaces (LAN, Public IP, ...).",
+ "label": "repeated",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -22392,19 +22397,51 @@
"options": {
"validate.rules": [
{
- "name": "uint32.lte",
- "value": 1000
+ "name": "repeated.max_items",
+ "value": 10
+ },
+ {
+ "name": "repeated.items.string.ip",
+ "value": true
}
]
}
},
{
- "name": "page",
- "description": "Page number for pagination. 0 is interpreted as 1.",
+ "name": "metrics",
+ "description": "Metrics\n- can be used for forwarding gateway metrics such as temperatures or performance metrics\n- map keys are written in snake_case",
+ "label": "repeated",
+ "type": "MetricsEntry",
+ "longType": "GatewayStatus.MetricsEntry",
+ "fullType": "ttn.lorawan.v3.GatewayStatus.MetricsEntry",
+ "ismap": true,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "map.max_pairs",
+ "value": 32
+ },
+ {
+ "name": "map.keys.string.max_len",
+ "value": 36
+ },
+ {
+ "name": "map.keys.string.pattern",
+ "value": "^[a-z0-9](?:[_-]?[a-z0-9]){2,}$"
+ }
+ ]
+ }
+ },
+ {
+ "name": "advanced",
+ "description": "Advanced metadata fields\n- can be used for advanced information or experimental features that are not yet formally defined in the API\n- field names are written in snake_case",
"label": "",
- "type": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
+ "type": "Struct",
+ "longType": "google.protobuf.Struct",
+ "fullType": "google.protobuf.Struct",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -22413,9 +22450,9 @@
]
},
{
- "name": "ListGatewayCollaboratorsRequest",
- "longName": "ListGatewayCollaboratorsRequest",
- "fullName": "ttn.lorawan.v3.ListGatewayCollaboratorsRequest",
+ "name": "MetricsEntry",
+ "longName": "GatewayStatus.MetricsEntry",
+ "fullName": "ttn.lorawan.v3.GatewayStatus.MetricsEntry",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -22423,60 +22460,56 @@
"extensions": [],
"fields": [
{
- "name": "gateway_ids",
+ "name": "key",
"description": "",
"label": "",
- "type": "GatewayIdentifiers",
- "longType": "GatewayIdentifiers",
- "fullType": "ttn.lorawan.v3.GatewayIdentifiers",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "message.required",
- "value": true
- }
- ]
- }
+ "defaultValue": ""
},
{
- "name": "limit",
- "description": "Limit the number of results per page.",
+ "name": "value",
+ "description": "",
"label": "",
- "type": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
+ "type": "float",
+ "longType": "float",
+ "fullType": "float",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "uint32.lte",
- "value": 1000
- }
- ]
- }
- },
+ "defaultValue": ""
+ }
+ ]
+ },
+ {
+ "name": "VersionsEntry",
+ "longName": "GatewayStatus.VersionsEntry",
+ "fullName": "ttn.lorawan.v3.GatewayStatus.VersionsEntry",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "page",
- "description": "Page number for pagination. 0 is interpreted as 1.",
+ "name": "key",
+ "description": "",
"label": "",
- "type": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "order",
- "description": "Order the results by this field path (must be present in the field mask).\nDefault ordering is by ID. Prepend with a minus (-) to reverse the order.",
+ "name": "value",
+ "description": "",
"label": "",
"type": "string",
"longType": "string",
@@ -22484,61 +22517,47 @@
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "string.in",
- "value": [
- "",
- "id",
- "-id",
- "-rights",
- "rights"
- ]
- }
- ]
- }
+ "defaultValue": ""
}
]
},
{
- "name": "ListGatewaysRequest",
- "longName": "ListGatewaysRequest",
- "fullName": "ttn.lorawan.v3.ListGatewaysRequest",
- "description": "",
+ "name": "GatewayVersionIdentifiers",
+ "longName": "GatewayVersionIdentifiers",
+ "fullName": "ttn.lorawan.v3.GatewayVersionIdentifiers",
+ "description": "Identifies an end device model with version information.",
"hasExtensions": false,
"hasFields": true,
"hasOneofs": false,
"extensions": [],
"fields": [
{
- "name": "collaborator",
- "description": "By default we list all gateways the caller has rights on.\nSet the user or the organization (not both) to instead list the gateways\nwhere the user or organization is collaborator on.",
- "label": "",
- "type": "OrganizationOrUserIdentifiers",
- "longType": "OrganizationOrUserIdentifiers",
- "fullType": "ttn.lorawan.v3.OrganizationOrUserIdentifiers",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
- },
- {
- "name": "field_mask",
- "description": "The names of the gateway fields that should be returned.",
+ "name": "brand_id",
+ "description": "",
"label": "",
- "type": "FieldMask",
- "longType": "google.protobuf.FieldMask",
- "fullType": "google.protobuf.FieldMask",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "string.max_len",
+ "value": 36
+ },
+ {
+ "name": "string.pattern",
+ "value": "^[a-z0-9](?:[-]?[a-z0-9]){2,}$"
+ }
+ ]
+ }
},
{
- "name": "order",
- "description": "Order the results by this field path (must be present in the field mask).\nDefault ordering is by ID. Prepend with a minus (-) to reverse the order.",
+ "name": "model_id",
+ "description": "",
"label": "",
"type": "string",
"longType": "string",
@@ -22550,29 +22569,23 @@
"options": {
"validate.rules": [
{
- "name": "string.in",
- "value": [
- "",
- "gateway_id",
- "-gateway_id",
- "gateway_eui",
- "-gateway_eui",
- "name",
- "-name",
- "created_at",
- "-created_at"
- ]
+ "name": "string.max_len",
+ "value": 36
+ },
+ {
+ "name": "string.pattern",
+ "value": "^[a-z0-9](?:[-]?[a-z0-9]){2,}$"
}
]
}
},
{
- "name": "limit",
- "description": "Limit the number of results per page.",
+ "name": "hardware_version",
+ "description": "",
"label": "",
- "type": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -22580,31 +22593,51 @@
"options": {
"validate.rules": [
{
- "name": "uint32.lte",
- "value": 1000
+ "name": "string.max_len",
+ "value": 32
}
]
}
},
{
- "name": "page",
- "description": "Page number for pagination. 0 is interpreted as 1.",
+ "name": "firmware_version",
+ "description": "",
"label": "",
- "type": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
- },
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "string.max_len",
+ "value": 32
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "Gateways",
+ "longName": "Gateways",
+ "fullName": "ttn.lorawan.v3.Gateways",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "deleted",
- "description": "Only return recently deleted gateways.",
- "label": "",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
+ "name": "gateways",
+ "description": "",
+ "label": "repeated",
+ "type": "Gateway",
+ "longType": "Gateway",
+ "fullType": "ttn.lorawan.v3.Gateway",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -22613,9 +22646,9 @@
]
},
{
- "name": "SetGatewayCollaboratorRequest",
- "longName": "SetGatewayCollaboratorRequest",
- "fullName": "ttn.lorawan.v3.SetGatewayCollaboratorRequest",
+ "name": "GetGatewayAPIKeyRequest",
+ "longName": "GetGatewayAPIKeyRequest",
+ "fullName": "ttn.lorawan.v3.GetGatewayAPIKeyRequest",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -22643,31 +22676,23 @@
}
},
{
- "name": "collaborator",
- "description": "",
+ "name": "key_id",
+ "description": "Unique public identifier for the API key.",
"label": "",
- "type": "Collaborator",
- "longType": "Collaborator",
- "fullType": "ttn.lorawan.v3.Collaborator",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "message.required",
- "value": true
- }
- ]
- }
+ "defaultValue": ""
}
]
},
{
- "name": "UpdateGatewayAPIKeyRequest",
- "longName": "UpdateGatewayAPIKeyRequest",
- "fullName": "ttn.lorawan.v3.UpdateGatewayAPIKeyRequest",
+ "name": "GetGatewayCollaboratorRequest",
+ "longName": "GetGatewayCollaboratorRequest",
+ "fullName": "ttn.lorawan.v3.GetGatewayCollaboratorRequest",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -22695,12 +22720,12 @@
}
},
{
- "name": "api_key",
+ "name": "collaborator",
"description": "",
"label": "",
- "type": "APIKey",
- "longType": "APIKey",
- "fullType": "ttn.lorawan.v3.APIKey",
+ "type": "OrganizationOrUserIdentifiers",
+ "longType": "OrganizationOrUserIdentifiers",
+ "fullType": "ttn.lorawan.v3.OrganizationOrUserIdentifiers",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -22713,25 +22738,45 @@
}
]
}
- },
+ }
+ ]
+ },
+ {
+ "name": "GetGatewayIdentifiersForEUIRequest",
+ "longName": "GetGatewayIdentifiersForEUIRequest",
+ "fullName": "ttn.lorawan.v3.GetGatewayIdentifiersForEUIRequest",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "field_mask",
- "description": "The names of the api key fields that should be updated.",
+ "name": "eui",
+ "description": "",
"label": "",
- "type": "FieldMask",
- "longType": "google.protobuf.FieldMask",
- "fullType": "google.protobuf.FieldMask",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "bytes.len",
+ "value": 8
+ }
+ ]
+ }
}
]
},
{
- "name": "UpdateGatewayRequest",
- "longName": "UpdateGatewayRequest",
- "fullName": "ttn.lorawan.v3.UpdateGatewayRequest",
+ "name": "GetGatewayRequest",
+ "longName": "GetGatewayRequest",
+ "fullName": "ttn.lorawan.v3.GetGatewayRequest",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -22739,12 +22784,12 @@
"extensions": [],
"fields": [
{
- "name": "gateway",
+ "name": "gateway_ids",
"description": "",
"label": "",
- "type": "Gateway",
- "longType": "Gateway",
- "fullType": "ttn.lorawan.v3.Gateway",
+ "type": "GatewayIdentifiers",
+ "longType": "GatewayIdentifiers",
+ "fullType": "ttn.lorawan.v3.GatewayIdentifiers",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -22760,7 +22805,7 @@
},
{
"name": "field_mask",
- "description": "The names of the gateway fields that should be updated.",
+ "description": "The names of the gateway fields that should be returned.",
"label": "",
"type": "FieldMask",
"longType": "google.protobuf.FieldMask",
@@ -22771,25 +22816,11 @@
"defaultValue": ""
}
]
- }
- ],
- "services": []
- },
- {
- "name": "ttn/lorawan/v3/gateway_configuration.proto",
- "description": "",
- "package": "ttn.lorawan.v3",
- "hasEnums": false,
- "hasExtensions": false,
- "hasMessages": true,
- "hasServices": true,
- "enums": [],
- "extensions": [],
- "messages": [
+ },
{
- "name": "GetGatewayConfigurationRequest",
- "longName": "GetGatewayConfigurationRequest",
- "fullName": "ttn.lorawan.v3.GetGatewayConfigurationRequest",
+ "name": "ListGatewayAPIKeysRequest",
+ "longName": "ListGatewayAPIKeysRequest",
+ "fullName": "ttn.lorawan.v3.ListGatewayAPIKeysRequest",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -22817,8 +22848,8 @@
}
},
{
- "name": "format",
- "description": "",
+ "name": "order",
+ "description": "Order the results by this field path.\nDefault ordering is by ID. Prepend with a minus (-) to reverse the order.",
"label": "",
"type": "string",
"longType": "string",
@@ -22830,23 +22861,29 @@
"options": {
"validate.rules": [
{
- "name": "string.max_len",
- "value": 36
- },
- {
- "name": "string.pattern",
- "value": "^[a-z0-9](?:[-]?[a-z0-9]){2,}$|^$"
+ "name": "string.in",
+ "value": [
+ "",
+ "api_key_id",
+ "-api_key_id",
+ "name",
+ "-name",
+ "created_at",
+ "-created_at",
+ "expires_at",
+ "-expires_at"
+ ]
}
]
}
},
{
- "name": "type",
- "description": "",
+ "name": "limit",
+ "description": "Limit the number of results per page.",
"label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -22854,46 +22891,30 @@
"options": {
"validate.rules": [
{
- "name": "string.max_len",
- "value": 36
- },
- {
- "name": "string.pattern",
- "value": "^[a-z0-9](?:[-]?[a-z0-9]){2,}$|^$"
+ "name": "uint32.lte",
+ "value": 1000
}
]
}
},
{
- "name": "filename",
- "description": "",
+ "name": "page",
+ "description": "Page number for pagination. 0 is interpreted as 1.",
"label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "string.max_len",
- "value": 36
- },
- {
- "name": "string.pattern",
- "value": "^[a-z0-9](?:[-._]?[a-z0-9]){2,}$|^$"
- }
- ]
- }
+ "defaultValue": ""
}
]
},
{
- "name": "GetGatewayConfigurationResponse",
- "longName": "GetGatewayConfigurationResponse",
- "fullName": "ttn.lorawan.v3.GetGatewayConfigurationResponse",
+ "name": "ListGatewayCollaboratorsRequest",
+ "longName": "ListGatewayCollaboratorsRequest",
+ "fullName": "ttn.lorawan.v3.ListGatewayCollaboratorsRequest",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -22901,76 +22922,89 @@
"extensions": [],
"fields": [
{
- "name": "contents",
+ "name": "gateway_ids",
"description": "",
"label": "",
- "type": "bytes",
- "longType": "bytes",
- "fullType": "bytes",
+ "type": "GatewayIdentifiers",
+ "longType": "GatewayIdentifiers",
+ "fullType": "ttn.lorawan.v3.GatewayIdentifiers",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
- }
- ]
- }
- ],
- "services": [
- {
- "name": "GatewayConfigurationService",
- "longName": "GatewayConfigurationService",
- "fullName": "ttn.lorawan.v3.GatewayConfigurationService",
- "description": "",
- "methods": [
- {
- "name": "GetGatewayConfiguration",
- "description": "",
- "requestType": "GetGatewayConfigurationRequest",
- "requestLongType": "GetGatewayConfigurationRequest",
- "requestFullType": "ttn.lorawan.v3.GetGatewayConfigurationRequest",
- "requestStreaming": false,
- "responseType": "GetGatewayConfigurationResponse",
- "responseLongType": "GetGatewayConfigurationResponse",
- "responseFullType": "ttn.lorawan.v3.GetGatewayConfigurationResponse",
- "responseStreaming": false,
+ "defaultValue": "",
"options": {
- "google.api.http": {
- "rules": [
- {
- "method": "",
- "pattern": ""
- },
- {
- "method": "GET",
- "pattern": "/gcs/gateways/configuration/{gateway_ids.gateway_id}/{format}/{filename}"
- },
- {
- "method": "GET",
- "pattern": "/gcs/gateways/configuration/{gateway_ids.gateway_id}/{format}/{type}/{filename}"
- }
- ]
- }
+ "validate.rules": [
+ {
+ "name": "message.required",
+ "value": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "limit",
+ "description": "Limit the number of results per page.",
+ "label": "",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "uint32.lte",
+ "value": 1000
+ }
+ ]
+ }
+ },
+ {
+ "name": "page",
+ "description": "Page number for pagination. 0 is interpreted as 1.",
+ "label": "",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "order",
+ "description": "Order the results by this field path (must be present in the field mask).\nDefault ordering is by ID. Prepend with a minus (-) to reverse the order.",
+ "label": "",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "string.in",
+ "value": [
+ "",
+ "id",
+ "-id",
+ "-rights",
+ "rights"
+ ]
+ }
+ ]
}
}
]
- }
- ]
- },
- {
- "name": "ttn/lorawan/v3/gateway_services.proto",
- "description": "",
- "package": "ttn.lorawan.v3",
- "hasEnums": false,
- "hasExtensions": false,
- "hasMessages": true,
- "hasServices": true,
- "enums": [],
- "extensions": [],
- "messages": [
+ },
{
- "name": "AssertGatewayRightsRequest",
- "longName": "AssertGatewayRightsRequest",
- "fullName": "ttn.lorawan.v3.AssertGatewayRightsRequest",
+ "name": "ListGatewaysRequest",
+ "longName": "ListGatewaysRequest",
+ "fullName": "ttn.lorawan.v3.ListGatewaysRequest",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -22978,12 +23012,36 @@
"extensions": [],
"fields": [
{
- "name": "gateway_ids",
- "description": "",
- "label": "repeated",
- "type": "GatewayIdentifiers",
- "longType": "GatewayIdentifiers",
- "fullType": "ttn.lorawan.v3.GatewayIdentifiers",
+ "name": "collaborator",
+ "description": "By default we list all gateways the caller has rights on.\nSet the user or the organization (not both) to instead list the gateways\nwhere the user or organization is collaborator on.",
+ "label": "",
+ "type": "OrganizationOrUserIdentifiers",
+ "longType": "OrganizationOrUserIdentifiers",
+ "fullType": "ttn.lorawan.v3.OrganizationOrUserIdentifiers",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "field_mask",
+ "description": "The names of the gateway fields that should be returned.",
+ "label": "",
+ "type": "FieldMask",
+ "longType": "google.protobuf.FieldMask",
+ "fullType": "google.protobuf.FieldMask",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "order",
+ "description": "Order the results by this field path (must be present in the field mask).\nDefault ordering is by ID. Prepend with a minus (-) to reverse the order.",
+ "label": "",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -22991,23 +23049,29 @@
"options": {
"validate.rules": [
{
- "name": "repeated.min_items",
- "value": 1
- },
- {
- "name": "repeated.max_items",
- "value": 20
+ "name": "string.in",
+ "value": [
+ "",
+ "gateway_id",
+ "-gateway_id",
+ "gateway_eui",
+ "-gateway_eui",
+ "name",
+ "-name",
+ "created_at",
+ "-created_at"
+ ]
}
]
}
},
{
- "name": "required",
- "description": "",
+ "name": "limit",
+ "description": "Limit the number of results per page.",
"label": "",
- "type": "Rights",
- "longType": "Rights",
- "fullType": "ttn.lorawan.v3.Rights",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -23015,18 +23079,42 @@
"options": {
"validate.rules": [
{
- "name": "message.required",
- "value": true
+ "name": "uint32.lte",
+ "value": 1000
}
]
}
+ },
+ {
+ "name": "page",
+ "description": "Page number for pagination. 0 is interpreted as 1.",
+ "label": "",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "deleted",
+ "description": "Only return recently deleted gateways.",
+ "label": "",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
}
]
},
{
- "name": "BatchDeleteGatewaysRequest",
- "longName": "BatchDeleteGatewaysRequest",
- "fullName": "ttn.lorawan.v3.BatchDeleteGatewaysRequest",
+ "name": "SetGatewayCollaboratorRequest",
+ "longName": "SetGatewayCollaboratorRequest",
+ "fullName": "ttn.lorawan.v3.SetGatewayCollaboratorRequest",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -23036,7 +23124,7 @@
{
"name": "gateway_ids",
"description": "",
- "label": "repeated",
+ "label": "",
"type": "GatewayIdentifiers",
"longType": "GatewayIdentifiers",
"fullType": "ttn.lorawan.v3.GatewayIdentifiers",
@@ -23047,12 +23135,28 @@
"options": {
"validate.rules": [
{
- "name": "repeated.min_items",
- "value": 1
- },
+ "name": "message.required",
+ "value": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "collaborator",
+ "description": "",
+ "label": "",
+ "type": "Collaborator",
+ "longType": "Collaborator",
+ "fullType": "ttn.lorawan.v3.Collaborator",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
{
- "name": "repeated.max_items",
- "value": 20
+ "name": "message.required",
+ "value": true
}
]
}
@@ -23060,9 +23164,9 @@
]
},
{
- "name": "PullGatewayConfigurationRequest",
- "longName": "PullGatewayConfigurationRequest",
- "fullName": "ttn.lorawan.v3.PullGatewayConfigurationRequest",
+ "name": "UpdateGatewayAPIKeyRequest",
+ "longName": "UpdateGatewayAPIKeyRequest",
+ "fullName": "ttn.lorawan.v3.UpdateGatewayAPIKeyRequest",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -23079,174 +23183,254 @@
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "message.required",
+ "value": true
+ }
+ ]
+ }
},
{
- "name": "field_mask",
+ "name": "api_key",
"description": "",
"label": "",
- "type": "FieldMask",
- "longType": "google.protobuf.FieldMask",
- "fullType": "google.protobuf.FieldMask",
+ "type": "APIKey",
+ "longType": "APIKey",
+ "fullType": "ttn.lorawan.v3.APIKey",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
- }
- ]
- }
- ],
- "services": [
- {
- "name": "GatewayAccess",
- "longName": "GatewayAccess",
- "fullName": "ttn.lorawan.v3.GatewayAccess",
- "description": "The GatewayAccess service, exposed by the Identity Server, is used to manage\nAPI keys and collaborators of gateways.",
- "methods": [
- {
- "name": "ListRights",
- "description": "List the rights the caller has on this gateway.",
- "requestType": "GatewayIdentifiers",
- "requestLongType": "GatewayIdentifiers",
- "requestFullType": "ttn.lorawan.v3.GatewayIdentifiers",
- "requestStreaming": false,
- "responseType": "Rights",
- "responseLongType": "Rights",
- "responseFullType": "ttn.lorawan.v3.Rights",
- "responseStreaming": false,
+ "defaultValue": "",
"options": {
- "google.api.http": {
- "rules": [
- {
- "method": "GET",
- "pattern": "/gateways/{gateway_id}/rights"
- }
- ]
- }
+ "validate.rules": [
+ {
+ "name": "message.required",
+ "value": true
+ }
+ ]
}
},
{
- "name": "CreateAPIKey",
- "description": "Create an API key scoped to this gateway.",
- "requestType": "CreateGatewayAPIKeyRequest",
- "requestLongType": "CreateGatewayAPIKeyRequest",
- "requestFullType": "ttn.lorawan.v3.CreateGatewayAPIKeyRequest",
- "requestStreaming": false,
- "responseType": "APIKey",
- "responseLongType": "APIKey",
- "responseFullType": "ttn.lorawan.v3.APIKey",
- "responseStreaming": false,
- "options": {
- "google.api.http": {
- "rules": [
- {
- "method": "POST",
- "pattern": "/gateways/{gateway_ids.gateway_id}/api-keys",
- "body": "*"
- }
- ]
- }
- }
- },
+ "name": "field_mask",
+ "description": "The names of the api key fields that should be updated.",
+ "label": "",
+ "type": "FieldMask",
+ "longType": "google.protobuf.FieldMask",
+ "fullType": "google.protobuf.FieldMask",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ }
+ ]
+ },
+ {
+ "name": "UpdateGatewayRequest",
+ "longName": "UpdateGatewayRequest",
+ "fullName": "ttn.lorawan.v3.UpdateGatewayRequest",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "ListAPIKeys",
- "description": "List the API keys for this gateway.",
- "requestType": "ListGatewayAPIKeysRequest",
- "requestLongType": "ListGatewayAPIKeysRequest",
- "requestFullType": "ttn.lorawan.v3.ListGatewayAPIKeysRequest",
- "requestStreaming": false,
- "responseType": "APIKeys",
- "responseLongType": "APIKeys",
- "responseFullType": "ttn.lorawan.v3.APIKeys",
- "responseStreaming": false,
+ "name": "gateway",
+ "description": "",
+ "label": "",
+ "type": "Gateway",
+ "longType": "Gateway",
+ "fullType": "ttn.lorawan.v3.Gateway",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
"options": {
- "google.api.http": {
- "rules": [
- {
- "method": "GET",
- "pattern": "/gateways/{gateway_ids.gateway_id}/api-keys"
- }
- ]
- }
+ "validate.rules": [
+ {
+ "name": "message.required",
+ "value": true
+ }
+ ]
}
},
{
- "name": "GetAPIKey",
- "description": "Get a single API key of this gateway.",
- "requestType": "GetGatewayAPIKeyRequest",
- "requestLongType": "GetGatewayAPIKeyRequest",
- "requestFullType": "ttn.lorawan.v3.GetGatewayAPIKeyRequest",
- "requestStreaming": false,
- "responseType": "APIKey",
- "responseLongType": "APIKey",
- "responseFullType": "ttn.lorawan.v3.APIKey",
- "responseStreaming": false,
+ "name": "field_mask",
+ "description": "The names of the gateway fields that should be updated.",
+ "label": "",
+ "type": "FieldMask",
+ "longType": "google.protobuf.FieldMask",
+ "fullType": "google.protobuf.FieldMask",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ }
+ ]
+ }
+ ],
+ "services": []
+ },
+ {
+ "name": "ttn/lorawan/v3/gateway_configuration.proto",
+ "description": "",
+ "package": "ttn.lorawan.v3",
+ "hasEnums": false,
+ "hasExtensions": false,
+ "hasMessages": true,
+ "hasServices": true,
+ "enums": [],
+ "extensions": [],
+ "messages": [
+ {
+ "name": "GetGatewayConfigurationRequest",
+ "longName": "GetGatewayConfigurationRequest",
+ "fullName": "ttn.lorawan.v3.GetGatewayConfigurationRequest",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "gateway_ids",
+ "description": "",
+ "label": "",
+ "type": "GatewayIdentifiers",
+ "longType": "GatewayIdentifiers",
+ "fullType": "ttn.lorawan.v3.GatewayIdentifiers",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
"options": {
- "google.api.http": {
- "rules": [
- {
- "method": "GET",
- "pattern": "/gateways/{gateway_ids.gateway_id}/api-keys/{key_id}"
- }
- ]
- }
+ "validate.rules": [
+ {
+ "name": "message.required",
+ "value": true
+ }
+ ]
}
},
{
- "name": "UpdateAPIKey",
- "description": "Update the rights of an API key of the gateway.\nThis method can also be used to delete the API key, by giving it no rights.\nThe caller is required to have all assigned or/and removed rights.",
- "requestType": "UpdateGatewayAPIKeyRequest",
- "requestLongType": "UpdateGatewayAPIKeyRequest",
- "requestFullType": "ttn.lorawan.v3.UpdateGatewayAPIKeyRequest",
- "requestStreaming": false,
- "responseType": "APIKey",
- "responseLongType": "APIKey",
- "responseFullType": "ttn.lorawan.v3.APIKey",
- "responseStreaming": false,
+ "name": "format",
+ "description": "",
+ "label": "",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
"options": {
- "google.api.http": {
- "rules": [
- {
- "method": "PUT",
- "pattern": "/gateways/{gateway_ids.gateway_id}/api-keys/{api_key.id}",
- "body": "*"
- }
- ]
- }
+ "validate.rules": [
+ {
+ "name": "string.max_len",
+ "value": 36
+ },
+ {
+ "name": "string.pattern",
+ "value": "^[a-z0-9](?:[-]?[a-z0-9]){2,}$|^$"
+ }
+ ]
}
},
{
- "name": "DeleteAPIKey",
- "description": "Delete a single API key of this gateway.",
- "requestType": "DeleteGatewayAPIKeyRequest",
- "requestLongType": "DeleteGatewayAPIKeyRequest",
- "requestFullType": "ttn.lorawan.v3.DeleteGatewayAPIKeyRequest",
- "requestStreaming": false,
- "responseType": "Empty",
- "responseLongType": ".google.protobuf.Empty",
- "responseFullType": "google.protobuf.Empty",
- "responseStreaming": false,
+ "name": "type",
+ "description": "",
+ "label": "",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
"options": {
- "google.api.http": {
- "rules": [
- {
- "method": "DELETE",
- "pattern": "/gateways/{gateway_ids.gateway_id}/api-keys/{key_id}"
- }
- ]
- }
+ "validate.rules": [
+ {
+ "name": "string.max_len",
+ "value": 36
+ },
+ {
+ "name": "string.pattern",
+ "value": "^[a-z0-9](?:[-]?[a-z0-9]){2,}$|^$"
+ }
+ ]
}
},
{
- "name": "GetCollaborator",
- "description": "Get the rights of a collaborator (member) of the gateway.\nPseudo-rights in the response (such as the \"_ALL\" right) are not expanded.",
- "requestType": "GetGatewayCollaboratorRequest",
- "requestLongType": "GetGatewayCollaboratorRequest",
- "requestFullType": "ttn.lorawan.v3.GetGatewayCollaboratorRequest",
+ "name": "filename",
+ "description": "",
+ "label": "",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "string.max_len",
+ "value": 36
+ },
+ {
+ "name": "string.pattern",
+ "value": "^[a-z0-9](?:[-._]?[a-z0-9]){2,}$|^$"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "GetGatewayConfigurationResponse",
+ "longName": "GetGatewayConfigurationResponse",
+ "fullName": "ttn.lorawan.v3.GetGatewayConfigurationResponse",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "contents",
+ "description": "",
+ "label": "",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ }
+ ]
+ }
+ ],
+ "services": [
+ {
+ "name": "GatewayConfigurationService",
+ "longName": "GatewayConfigurationService",
+ "fullName": "ttn.lorawan.v3.GatewayConfigurationService",
+ "description": "",
+ "methods": [
+ {
+ "name": "GetGatewayConfiguration",
+ "description": "",
+ "requestType": "GetGatewayConfigurationRequest",
+ "requestLongType": "GetGatewayConfigurationRequest",
+ "requestFullType": "ttn.lorawan.v3.GetGatewayConfigurationRequest",
"requestStreaming": false,
- "responseType": "GetCollaboratorResponse",
- "responseLongType": "GetCollaboratorResponse",
- "responseFullType": "ttn.lorawan.v3.GetCollaboratorResponse",
+ "responseType": "GetGatewayConfigurationResponse",
+ "responseLongType": "GetGatewayConfigurationResponse",
+ "responseFullType": "ttn.lorawan.v3.GetGatewayConfigurationResponse",
"responseStreaming": false,
"options": {
"google.api.http": {
@@ -23257,201 +23441,206 @@
},
{
"method": "GET",
- "pattern": "/gateways/{gateway_ids.gateway_id}/collaborator/user/{collaborator.user_ids.user_id}"
+ "pattern": "/gcs/gateways/configuration/{gateway_ids.gateway_id}/{format}/{filename}"
},
{
"method": "GET",
- "pattern": "/gateways/{gateway_ids.gateway_id}/collaborator/organization/{collaborator.organization_ids.organization_id}"
+ "pattern": "/gcs/gateways/configuration/{gateway_ids.gateway_id}/{format}/{type}/{filename}"
}
]
}
}
- },
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "ttn/lorawan/v3/gateway_services.proto",
+ "description": "",
+ "package": "ttn.lorawan.v3",
+ "hasEnums": false,
+ "hasExtensions": false,
+ "hasMessages": true,
+ "hasServices": true,
+ "enums": [],
+ "extensions": [],
+ "messages": [
+ {
+ "name": "AssertGatewayRightsRequest",
+ "longName": "AssertGatewayRightsRequest",
+ "fullName": "ttn.lorawan.v3.AssertGatewayRightsRequest",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "SetCollaborator",
- "description": "Set the rights of a collaborator (member) on the gateway.\nThis method can also be used to delete the collaborator, by giving them no rights.\nThe caller is required to have all assigned or/and removed rights.",
- "requestType": "SetGatewayCollaboratorRequest",
- "requestLongType": "SetGatewayCollaboratorRequest",
- "requestFullType": "ttn.lorawan.v3.SetGatewayCollaboratorRequest",
- "requestStreaming": false,
- "responseType": "Empty",
- "responseLongType": ".google.protobuf.Empty",
- "responseFullType": "google.protobuf.Empty",
- "responseStreaming": false,
+ "name": "gateway_ids",
+ "description": "",
+ "label": "repeated",
+ "type": "GatewayIdentifiers",
+ "longType": "GatewayIdentifiers",
+ "fullType": "ttn.lorawan.v3.GatewayIdentifiers",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
"options": {
- "google.api.http": {
- "rules": [
- {
- "method": "PUT",
- "pattern": "/gateways/{gateway_ids.gateway_id}/collaborators",
- "body": "*"
- }
- ]
- }
+ "validate.rules": [
+ {
+ "name": "repeated.min_items",
+ "value": 1
+ },
+ {
+ "name": "repeated.max_items",
+ "value": 100
+ }
+ ]
}
},
{
- "name": "ListCollaborators",
- "description": "List the collaborators on this gateway.",
- "requestType": "ListGatewayCollaboratorsRequest",
- "requestLongType": "ListGatewayCollaboratorsRequest",
- "requestFullType": "ttn.lorawan.v3.ListGatewayCollaboratorsRequest",
- "requestStreaming": false,
- "responseType": "Collaborators",
- "responseLongType": "Collaborators",
- "responseFullType": "ttn.lorawan.v3.Collaborators",
- "responseStreaming": false,
+ "name": "required",
+ "description": "",
+ "label": "",
+ "type": "Rights",
+ "longType": "Rights",
+ "fullType": "ttn.lorawan.v3.Rights",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
"options": {
- "google.api.http": {
- "rules": [
- {
- "method": "GET",
- "pattern": "/gateways/{gateway_ids.gateway_id}/collaborators"
- }
- ]
- }
+ "validate.rules": [
+ {
+ "name": "message.required",
+ "value": true
+ }
+ ]
}
- },
+ }
+ ]
+ },
+ {
+ "name": "BatchDeleteGatewaysRequest",
+ "longName": "BatchDeleteGatewaysRequest",
+ "fullName": "ttn.lorawan.v3.BatchDeleteGatewaysRequest",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "DeleteCollaborator",
- "description": "DeleteCollaborator removes a collaborator from a gateway.",
- "requestType": "DeleteGatewayCollaboratorRequest",
- "requestLongType": "DeleteGatewayCollaboratorRequest",
- "requestFullType": "ttn.lorawan.v3.DeleteGatewayCollaboratorRequest",
- "requestStreaming": false,
- "responseType": "Empty",
- "responseLongType": ".google.protobuf.Empty",
- "responseFullType": "google.protobuf.Empty",
- "responseStreaming": false,
+ "name": "gateway_ids",
+ "description": "",
+ "label": "repeated",
+ "type": "GatewayIdentifiers",
+ "longType": "GatewayIdentifiers",
+ "fullType": "ttn.lorawan.v3.GatewayIdentifiers",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
"options": {
- "google.api.http": {
- "rules": [
- {
- "method": "",
- "pattern": ""
- },
- {
- "method": "DELETE",
- "pattern": "/gateways/{gateway_ids.gateway_id}/collaborators/user/{collaborator_ids.user_ids.user_id}"
- },
- {
- "method": "DELETE",
- "pattern": "/gateways/{gateway_ids.gateway_id}/collaborators/organization/{collaborator_ids.organization_ids.organization_id}"
- }
- ]
- }
+ "validate.rules": [
+ {
+ "name": "repeated.min_items",
+ "value": 1
+ },
+ {
+ "name": "repeated.max_items",
+ "value": 20
+ }
+ ]
}
}
]
},
{
- "name": "GatewayBatchAccess",
- "longName": "GatewayBatchAccess",
- "fullName": "ttn.lorawan.v3.GatewayBatchAccess",
- "description": "The GatewayBatchAccess service, exposed by the Identity Server, is used to\ncheck the rights of the caller on multiple gateways at once.\nEXPERIMENTAL: This service is subject to change.",
- "methods": [
+ "name": "PullGatewayConfigurationRequest",
+ "longName": "PullGatewayConfigurationRequest",
+ "fullName": "ttn.lorawan.v3.PullGatewayConfigurationRequest",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "AssertRights",
- "description": "Assert that the caller has the requested rights on all the requested gateways.\nThe check is successful if there are no errors.",
- "requestType": "AssertGatewayRightsRequest",
- "requestLongType": "AssertGatewayRightsRequest",
- "requestFullType": "ttn.lorawan.v3.AssertGatewayRightsRequest",
- "requestStreaming": false,
- "responseType": "Empty",
- "responseLongType": ".google.protobuf.Empty",
- "responseFullType": "google.protobuf.Empty",
- "responseStreaming": false,
- "options": {
- "google.api.http": {
- "rules": [
- {
- "method": "GET",
- "pattern": "/gateways/rights/batch"
- }
- ]
- }
- }
+ "name": "gateway_ids",
+ "description": "",
+ "label": "",
+ "type": "GatewayIdentifiers",
+ "longType": "GatewayIdentifiers",
+ "fullType": "ttn.lorawan.v3.GatewayIdentifiers",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "field_mask",
+ "description": "",
+ "label": "",
+ "type": "FieldMask",
+ "longType": "google.protobuf.FieldMask",
+ "fullType": "google.protobuf.FieldMask",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
}
]
- },
+ }
+ ],
+ "services": [
{
- "name": "GatewayBatchRegistry",
- "longName": "GatewayBatchRegistry",
- "fullName": "ttn.lorawan.v3.GatewayBatchRegistry",
- "description": "The GatewayBatchRegistry service, exposed by the Identity Server, is used to manage\ngateway registrations in batches.",
+ "name": "GatewayAccess",
+ "longName": "GatewayAccess",
+ "fullName": "ttn.lorawan.v3.GatewayAccess",
+ "description": "The GatewayAccess service, exposed by the Identity Server, is used to manage\nAPI keys and collaborators of gateways.",
"methods": [
{
- "name": "Delete",
- "description": "Delete a batch of gateways.\nThis operation is atomic; either all gateways are deleted or none.\nThe caller must have delete rights on all requested gateways.",
- "requestType": "BatchDeleteGatewaysRequest",
- "requestLongType": "BatchDeleteGatewaysRequest",
- "requestFullType": "ttn.lorawan.v3.BatchDeleteGatewaysRequest",
+ "name": "ListRights",
+ "description": "List the rights the caller has on this gateway.",
+ "requestType": "GatewayIdentifiers",
+ "requestLongType": "GatewayIdentifiers",
+ "requestFullType": "ttn.lorawan.v3.GatewayIdentifiers",
"requestStreaming": false,
- "responseType": "Empty",
- "responseLongType": ".google.protobuf.Empty",
- "responseFullType": "google.protobuf.Empty",
+ "responseType": "Rights",
+ "responseLongType": "Rights",
+ "responseFullType": "ttn.lorawan.v3.Rights",
"responseStreaming": false,
"options": {
"google.api.http": {
"rules": [
{
- "method": "DELETE",
- "pattern": "/gateways/batch"
+ "method": "GET",
+ "pattern": "/gateways/{gateway_id}/rights"
}
]
}
}
- }
- ]
- },
- {
- "name": "GatewayConfigurator",
- "longName": "GatewayConfigurator",
- "fullName": "ttn.lorawan.v3.GatewayConfigurator",
- "description": "",
- "methods": [
- {
- "name": "PullConfiguration",
- "description": "",
- "requestType": "PullGatewayConfigurationRequest",
- "requestLongType": "PullGatewayConfigurationRequest",
- "requestFullType": "ttn.lorawan.v3.PullGatewayConfigurationRequest",
- "requestStreaming": false,
- "responseType": "Gateway",
- "responseLongType": "Gateway",
- "responseFullType": "ttn.lorawan.v3.Gateway",
- "responseStreaming": true
- }
- ]
- },
- {
- "name": "GatewayRegistry",
- "longName": "GatewayRegistry",
- "fullName": "ttn.lorawan.v3.GatewayRegistry",
- "description": "The GatewayRegistry service, exposed by the Identity Server, is used to manage\ngateway registrations.",
- "methods": [
+ },
{
- "name": "Create",
- "description": "Create a new gateway. This also sets the given organization or user as\nfirst collaborator with all possible rights.",
- "requestType": "CreateGatewayRequest",
- "requestLongType": "CreateGatewayRequest",
- "requestFullType": "ttn.lorawan.v3.CreateGatewayRequest",
+ "name": "CreateAPIKey",
+ "description": "Create an API key scoped to this gateway.",
+ "requestType": "CreateGatewayAPIKeyRequest",
+ "requestLongType": "CreateGatewayAPIKeyRequest",
+ "requestFullType": "ttn.lorawan.v3.CreateGatewayAPIKeyRequest",
"requestStreaming": false,
- "responseType": "Gateway",
- "responseLongType": "Gateway",
- "responseFullType": "ttn.lorawan.v3.Gateway",
+ "responseType": "APIKey",
+ "responseLongType": "APIKey",
+ "responseFullType": "ttn.lorawan.v3.APIKey",
"responseStreaming": false,
"options": {
"google.api.http": {
"rules": [
{
"method": "POST",
- "pattern": "/users/{collaborator.user_ids.user_id}/gateways",
- "body": "*"
- },
- {
- "method": "POST",
- "pattern": "/organizations/{collaborator.organization_ids.organization_id}/gateways",
+ "pattern": "/gateways/{gateway_ids.gateway_id}/api-keys",
"body": "*"
}
]
@@ -23459,86 +23648,66 @@
}
},
{
- "name": "Get",
- "description": "Get the gateway with the given identifiers, selecting the fields specified\nin the field mask.\nMore or less fields may be returned, depending on the rights of the caller.",
- "requestType": "GetGatewayRequest",
- "requestLongType": "GetGatewayRequest",
- "requestFullType": "ttn.lorawan.v3.GetGatewayRequest",
+ "name": "ListAPIKeys",
+ "description": "List the API keys for this gateway.",
+ "requestType": "ListGatewayAPIKeysRequest",
+ "requestLongType": "ListGatewayAPIKeysRequest",
+ "requestFullType": "ttn.lorawan.v3.ListGatewayAPIKeysRequest",
"requestStreaming": false,
- "responseType": "Gateway",
- "responseLongType": "Gateway",
- "responseFullType": "ttn.lorawan.v3.Gateway",
+ "responseType": "APIKeys",
+ "responseLongType": "APIKeys",
+ "responseFullType": "ttn.lorawan.v3.APIKeys",
"responseStreaming": false,
"options": {
"google.api.http": {
"rules": [
{
"method": "GET",
- "pattern": "/gateways/{gateway_ids.gateway_id}"
+ "pattern": "/gateways/{gateway_ids.gateway_id}/api-keys"
}
]
}
}
},
{
- "name": "GetIdentifiersForEUI",
- "description": "Get the identifiers of the gateway that has the given EUI registered.",
- "requestType": "GetGatewayIdentifiersForEUIRequest",
- "requestLongType": "GetGatewayIdentifiersForEUIRequest",
- "requestFullType": "ttn.lorawan.v3.GetGatewayIdentifiersForEUIRequest",
- "requestStreaming": false,
- "responseType": "GatewayIdentifiers",
- "responseLongType": "GatewayIdentifiers",
- "responseFullType": "ttn.lorawan.v3.GatewayIdentifiers",
- "responseStreaming": false
- },
- {
- "name": "List",
- "description": "List gateways where the given user or organization is a direct collaborator.\nIf no user or organization is given, this returns the gateways the caller\nhas access to.\nSimilar to Get, this selects the fields given by the field mask.\nMore or less fields may be returned, depending on the rights of the caller.",
- "requestType": "ListGatewaysRequest",
- "requestLongType": "ListGatewaysRequest",
- "requestFullType": "ttn.lorawan.v3.ListGatewaysRequest",
+ "name": "GetAPIKey",
+ "description": "Get a single API key of this gateway.",
+ "requestType": "GetGatewayAPIKeyRequest",
+ "requestLongType": "GetGatewayAPIKeyRequest",
+ "requestFullType": "ttn.lorawan.v3.GetGatewayAPIKeyRequest",
"requestStreaming": false,
- "responseType": "Gateways",
- "responseLongType": "Gateways",
- "responseFullType": "ttn.lorawan.v3.Gateways",
+ "responseType": "APIKey",
+ "responseLongType": "APIKey",
+ "responseFullType": "ttn.lorawan.v3.APIKey",
"responseStreaming": false,
"options": {
"google.api.http": {
"rules": [
{
"method": "GET",
- "pattern": "/gateways"
- },
- {
- "method": "GET",
- "pattern": "/users/{collaborator.user_ids.user_id}/gateways"
- },
- {
- "method": "GET",
- "pattern": "/organizations/{collaborator.organization_ids.organization_id}/gateways"
+ "pattern": "/gateways/{gateway_ids.gateway_id}/api-keys/{key_id}"
}
]
}
}
},
{
- "name": "Update",
- "description": "Update the gateway, changing the fields specified by the field mask to the provided values.",
- "requestType": "UpdateGatewayRequest",
- "requestLongType": "UpdateGatewayRequest",
- "requestFullType": "ttn.lorawan.v3.UpdateGatewayRequest",
+ "name": "UpdateAPIKey",
+ "description": "Update the rights of an API key of the gateway.\nThis method can also be used to delete the API key, by giving it no rights.\nThe caller is required to have all assigned or/and removed rights.",
+ "requestType": "UpdateGatewayAPIKeyRequest",
+ "requestLongType": "UpdateGatewayAPIKeyRequest",
+ "requestFullType": "ttn.lorawan.v3.UpdateGatewayAPIKeyRequest",
"requestStreaming": false,
- "responseType": "Gateway",
- "responseLongType": "Gateway",
- "responseFullType": "ttn.lorawan.v3.Gateway",
+ "responseType": "APIKey",
+ "responseLongType": "APIKey",
+ "responseFullType": "ttn.lorawan.v3.APIKey",
"responseStreaming": false,
"options": {
"google.api.http": {
"rules": [
{
"method": "PUT",
- "pattern": "/gateways/{gateway.ids.gateway_id}",
+ "pattern": "/gateways/{gateway_ids.gateway_id}/api-keys/{api_key.id}",
"body": "*"
}
]
@@ -23546,11 +23715,11 @@
}
},
{
- "name": "Delete",
- "description": "Delete the gateway. This may not release the gateway ID for reuse, but it does release the EUI.",
- "requestType": "GatewayIdentifiers",
- "requestLongType": "GatewayIdentifiers",
- "requestFullType": "ttn.lorawan.v3.GatewayIdentifiers",
+ "name": "DeleteAPIKey",
+ "description": "Delete a single API key of this gateway.",
+ "requestType": "DeleteGatewayAPIKeyRequest",
+ "requestLongType": "DeleteGatewayAPIKeyRequest",
+ "requestFullType": "ttn.lorawan.v3.DeleteGatewayAPIKeyRequest",
"requestStreaming": false,
"responseType": "Empty",
"responseLongType": ".google.protobuf.Empty",
@@ -23561,40 +23730,48 @@
"rules": [
{
"method": "DELETE",
- "pattern": "/gateways/{gateway_id}"
+ "pattern": "/gateways/{gateway_ids.gateway_id}/api-keys/{key_id}"
}
]
}
}
},
{
- "name": "Restore",
- "description": "Restore a recently deleted gateway. This does not restore the EUI,\nas that was released when deleting the gateway.\n\nDeployment configuration may specify if, and for how long after deletion,\nentities can be restored.",
- "requestType": "GatewayIdentifiers",
- "requestLongType": "GatewayIdentifiers",
- "requestFullType": "ttn.lorawan.v3.GatewayIdentifiers",
+ "name": "GetCollaborator",
+ "description": "Get the rights of a collaborator (member) of the gateway.\nPseudo-rights in the response (such as the \"_ALL\" right) are not expanded.",
+ "requestType": "GetGatewayCollaboratorRequest",
+ "requestLongType": "GetGatewayCollaboratorRequest",
+ "requestFullType": "ttn.lorawan.v3.GetGatewayCollaboratorRequest",
"requestStreaming": false,
- "responseType": "Empty",
- "responseLongType": ".google.protobuf.Empty",
- "responseFullType": "google.protobuf.Empty",
+ "responseType": "GetCollaboratorResponse",
+ "responseLongType": "GetCollaboratorResponse",
+ "responseFullType": "ttn.lorawan.v3.GetCollaboratorResponse",
"responseStreaming": false,
"options": {
"google.api.http": {
"rules": [
{
- "method": "POST",
- "pattern": "/gateways/{gateway_id}/restore"
+ "method": "",
+ "pattern": ""
+ },
+ {
+ "method": "GET",
+ "pattern": "/gateways/{gateway_ids.gateway_id}/collaborator/user/{collaborator.user_ids.user_id}"
+ },
+ {
+ "method": "GET",
+ "pattern": "/gateways/{gateway_ids.gateway_id}/collaborator/organization/{collaborator.organization_ids.organization_id}"
}
]
}
}
},
{
- "name": "Purge",
- "description": "Purge the gateway. This will release both gateway ID and EUI for reuse.\nThe gateway owner is responsible for clearing data from any (external) integrations\nthat may store and expose data by gateway ID.",
- "requestType": "GatewayIdentifiers",
- "requestLongType": "GatewayIdentifiers",
- "requestFullType": "ttn.lorawan.v3.GatewayIdentifiers",
+ "name": "SetCollaborator",
+ "description": "Set the rights of a collaborator (member) on the gateway.\nThis method can also be used to delete the collaborator, by giving them no rights.\nThe caller is required to have all assigned or/and removed rights.",
+ "requestType": "SetGatewayCollaboratorRequest",
+ "requestLongType": "SetGatewayCollaboratorRequest",
+ "requestFullType": "ttn.lorawan.v3.SetGatewayCollaboratorRequest",
"requestStreaming": false,
"responseType": "Empty",
"responseLongType": ".google.protobuf.Empty",
@@ -23604,468 +23781,354 @@
"google.api.http": {
"rules": [
{
- "method": "DELETE",
- "pattern": "/gateways/{gateway_id}/purge"
+ "method": "PUT",
+ "pattern": "/gateways/{gateway_ids.gateway_id}/collaborators",
+ "body": "*"
}
]
}
}
- }
- ]
- }
- ]
- },
- {
- "name": "ttn/lorawan/v3/gatewayserver.proto",
- "description": "",
- "package": "ttn.lorawan.v3",
- "hasEnums": false,
- "hasExtensions": false,
- "hasMessages": true,
- "hasServices": true,
- "enums": [],
- "extensions": [],
- "messages": [
- {
- "name": "BatchGetGatewayConnectionStatsRequest",
- "longName": "BatchGetGatewayConnectionStatsRequest",
- "fullName": "ttn.lorawan.v3.BatchGetGatewayConnectionStatsRequest",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ },
{
- "name": "gateway_ids",
- "description": "",
- "label": "repeated",
- "type": "GatewayIdentifiers",
- "longType": "GatewayIdentifiers",
- "fullType": "ttn.lorawan.v3.GatewayIdentifiers",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
+ "name": "ListCollaborators",
+ "description": "List the collaborators on this gateway.",
+ "requestType": "ListGatewayCollaboratorsRequest",
+ "requestLongType": "ListGatewayCollaboratorsRequest",
+ "requestFullType": "ttn.lorawan.v3.ListGatewayCollaboratorsRequest",
+ "requestStreaming": false,
+ "responseType": "Collaborators",
+ "responseLongType": "Collaborators",
+ "responseFullType": "ttn.lorawan.v3.Collaborators",
+ "responseStreaming": false,
"options": {
- "validate.rules": [
- {
- "name": "repeated.min_items",
- "value": 1
- },
- {
- "name": "repeated.max_items",
- "value": 100
- }
- ]
+ "google.api.http": {
+ "rules": [
+ {
+ "method": "GET",
+ "pattern": "/gateways/{gateway_ids.gateway_id}/collaborators"
+ }
+ ]
+ }
}
},
{
- "name": "field_mask",
- "description": "The names of the gateway stats fields that should be returned.\nThis mask will be applied on each entry returned.",
- "label": "",
- "type": "FieldMask",
- "longType": "google.protobuf.FieldMask",
- "fullType": "google.protobuf.FieldMask",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
+ "name": "DeleteCollaborator",
+ "description": "DeleteCollaborator removes a collaborator from a gateway.",
+ "requestType": "DeleteGatewayCollaboratorRequest",
+ "requestLongType": "DeleteGatewayCollaboratorRequest",
+ "requestFullType": "ttn.lorawan.v3.DeleteGatewayCollaboratorRequest",
+ "requestStreaming": false,
+ "responseType": "Empty",
+ "responseLongType": ".google.protobuf.Empty",
+ "responseFullType": "google.protobuf.Empty",
+ "responseStreaming": false,
+ "options": {
+ "google.api.http": {
+ "rules": [
+ {
+ "method": "",
+ "pattern": ""
+ },
+ {
+ "method": "DELETE",
+ "pattern": "/gateways/{gateway_ids.gateway_id}/collaborators/user/{collaborator_ids.user_ids.user_id}"
+ },
+ {
+ "method": "DELETE",
+ "pattern": "/gateways/{gateway_ids.gateway_id}/collaborators/organization/{collaborator_ids.organization_ids.organization_id}"
+ }
+ ]
+ }
+ }
}
]
},
{
- "name": "BatchGetGatewayConnectionStatsResponse",
- "longName": "BatchGetGatewayConnectionStatsResponse",
- "fullName": "ttn.lorawan.v3.BatchGetGatewayConnectionStatsResponse",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ "name": "GatewayBatchAccess",
+ "longName": "GatewayBatchAccess",
+ "fullName": "ttn.lorawan.v3.GatewayBatchAccess",
+ "description": "The GatewayBatchAccess service, exposed by the Identity Server, is used to\ncheck the rights of the caller on multiple gateways at once.\nEXPERIMENTAL: This service is subject to change.",
+ "methods": [
{
- "name": "entries",
- "description": "The map key is the gateway identifier.",
- "label": "repeated",
- "type": "EntriesEntry",
- "longType": "BatchGetGatewayConnectionStatsResponse.EntriesEntry",
- "fullType": "ttn.lorawan.v3.BatchGetGatewayConnectionStatsResponse.EntriesEntry",
- "ismap": true,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
+ "name": "AssertRights",
+ "description": "Assert that the caller has the requested rights on all the requested gateways.\nThe check is successful if there are no errors.",
+ "requestType": "AssertGatewayRightsRequest",
+ "requestLongType": "AssertGatewayRightsRequest",
+ "requestFullType": "ttn.lorawan.v3.AssertGatewayRightsRequest",
+ "requestStreaming": false,
+ "responseType": "Empty",
+ "responseLongType": ".google.protobuf.Empty",
+ "responseFullType": "google.protobuf.Empty",
+ "responseStreaming": false,
+ "options": {
+ "google.api.http": {
+ "rules": [
+ {
+ "method": "GET",
+ "pattern": "/gateways/rights/batch"
+ }
+ ]
+ }
+ }
}
]
},
{
- "name": "EntriesEntry",
- "longName": "BatchGetGatewayConnectionStatsResponse.EntriesEntry",
- "fullName": "ttn.lorawan.v3.BatchGetGatewayConnectionStatsResponse.EntriesEntry",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
- {
- "name": "key",
- "description": "",
- "label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
- },
+ "name": "GatewayBatchRegistry",
+ "longName": "GatewayBatchRegistry",
+ "fullName": "ttn.lorawan.v3.GatewayBatchRegistry",
+ "description": "The GatewayBatchRegistry service, exposed by the Identity Server, is used to manage\ngateway registrations in batches.",
+ "methods": [
{
- "name": "value",
- "description": "",
- "label": "",
- "type": "GatewayConnectionStats",
- "longType": "GatewayConnectionStats",
- "fullType": "ttn.lorawan.v3.GatewayConnectionStats",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
+ "name": "Delete",
+ "description": "Delete a batch of gateways.\nThis operation is atomic; either all gateways are deleted or none.\nThe caller must have delete rights on all requested gateways.",
+ "requestType": "BatchDeleteGatewaysRequest",
+ "requestLongType": "BatchDeleteGatewaysRequest",
+ "requestFullType": "ttn.lorawan.v3.BatchDeleteGatewaysRequest",
+ "requestStreaming": false,
+ "responseType": "Empty",
+ "responseLongType": ".google.protobuf.Empty",
+ "responseFullType": "google.protobuf.Empty",
+ "responseStreaming": false,
+ "options": {
+ "google.api.http": {
+ "rules": [
+ {
+ "method": "DELETE",
+ "pattern": "/gateways/batch"
+ }
+ ]
+ }
+ }
}
]
},
{
- "name": "GatewayDown",
- "longName": "GatewayDown",
- "fullName": "ttn.lorawan.v3.GatewayDown",
- "description": "GatewayDown contains downlink messages for the gateway.",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ "name": "GatewayConfigurator",
+ "longName": "GatewayConfigurator",
+ "fullName": "ttn.lorawan.v3.GatewayConfigurator",
+ "description": "",
+ "methods": [
{
- "name": "downlink_message",
- "description": "DownlinkMessage for the gateway.",
- "label": "",
- "type": "DownlinkMessage",
- "longType": "DownlinkMessage",
- "fullType": "ttn.lorawan.v3.DownlinkMessage",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
+ "name": "PullConfiguration",
+ "description": "",
+ "requestType": "PullGatewayConfigurationRequest",
+ "requestLongType": "PullGatewayConfigurationRequest",
+ "requestFullType": "ttn.lorawan.v3.PullGatewayConfigurationRequest",
+ "requestStreaming": false,
+ "responseType": "Gateway",
+ "responseLongType": "Gateway",
+ "responseFullType": "ttn.lorawan.v3.Gateway",
+ "responseStreaming": true
}
]
},
{
- "name": "GatewayUp",
- "longName": "GatewayUp",
- "fullName": "ttn.lorawan.v3.GatewayUp",
- "description": "GatewayUp may contain zero or more uplink messages and/or a status message for the gateway.",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ "name": "GatewayRegistry",
+ "longName": "GatewayRegistry",
+ "fullName": "ttn.lorawan.v3.GatewayRegistry",
+ "description": "The GatewayRegistry service, exposed by the Identity Server, is used to manage\ngateway registrations.",
+ "methods": [
{
- "name": "uplink_messages",
- "description": "Uplink messages received by the gateway.",
- "label": "repeated",
- "type": "UplinkMessage",
- "longType": "UplinkMessage",
- "fullType": "ttn.lorawan.v3.UplinkMessage",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
- },
- {
- "name": "gateway_status",
- "description": "Gateway status produced by the gateway.",
- "label": "",
- "type": "GatewayStatus",
- "longType": "GatewayStatus",
- "fullType": "ttn.lorawan.v3.GatewayStatus",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
- },
- {
- "name": "tx_acknowledgment",
- "description": "A Tx acknowledgment or error.",
- "label": "",
- "type": "TxAcknowledgment",
- "longType": "TxAcknowledgment",
- "fullType": "ttn.lorawan.v3.TxAcknowledgment",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
- }
- ]
- },
- {
- "name": "ScheduleDownlinkErrorDetails",
- "longName": "ScheduleDownlinkErrorDetails",
- "fullName": "ttn.lorawan.v3.ScheduleDownlinkErrorDetails",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
- {
- "name": "path_errors",
- "description": "Errors per path when downlink scheduling failed.",
- "label": "repeated",
- "type": "ErrorDetails",
- "longType": "ErrorDetails",
- "fullType": "ttn.lorawan.v3.ErrorDetails",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
- }
- ]
- },
- {
- "name": "ScheduleDownlinkResponse",
- "longName": "ScheduleDownlinkResponse",
- "fullName": "ttn.lorawan.v3.ScheduleDownlinkResponse",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
- {
- "name": "delay",
- "description": "The amount of time between the message has been scheduled and it will be transmitted by the gateway.",
- "label": "",
- "type": "Duration",
- "longType": "google.protobuf.Duration",
- "fullType": "google.protobuf.Duration",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "duration.required",
- "value": true
- }
- ]
- }
- },
- {
- "name": "downlink_path",
- "description": "Downlink path chosen by the Gateway Server.",
- "label": "",
- "type": "DownlinkPath",
- "longType": "DownlinkPath",
- "fullType": "ttn.lorawan.v3.DownlinkPath",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
- },
- {
- "name": "rx1",
- "description": "Whether RX1 has been chosen for the downlink message.\nBoth RX1 and RX2 can be used for transmitting the same message by the same gateway.",
- "label": "",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
- },
- {
- "name": "rx2",
- "description": "Whether RX2 has been chosen for the downlink message.\nBoth RX1 and RX2 can be used for transmitting the same message by the same gateway.",
- "label": "",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
- }
- ]
- }
- ],
- "services": [
- {
- "name": "Gs",
- "longName": "Gs",
- "fullName": "ttn.lorawan.v3.Gs",
- "description": "",
- "methods": [
- {
- "name": "GetGatewayConnectionStats",
- "description": "Get statistics about the current gateway connection to the Gateway Server.\nThis is not persisted between reconnects.",
- "requestType": "GatewayIdentifiers",
- "requestLongType": "GatewayIdentifiers",
- "requestFullType": "ttn.lorawan.v3.GatewayIdentifiers",
+ "name": "Create",
+ "description": "Create a new gateway. This also sets the given organization or user as\nfirst collaborator with all possible rights.",
+ "requestType": "CreateGatewayRequest",
+ "requestLongType": "CreateGatewayRequest",
+ "requestFullType": "ttn.lorawan.v3.CreateGatewayRequest",
"requestStreaming": false,
- "responseType": "GatewayConnectionStats",
- "responseLongType": "GatewayConnectionStats",
- "responseFullType": "ttn.lorawan.v3.GatewayConnectionStats",
+ "responseType": "Gateway",
+ "responseLongType": "Gateway",
+ "responseFullType": "ttn.lorawan.v3.Gateway",
"responseStreaming": false,
"options": {
"google.api.http": {
"rules": [
{
- "method": "GET",
- "pattern": "/gs/gateways/{gateway_id}/connection/stats"
+ "method": "POST",
+ "pattern": "/users/{collaborator.user_ids.user_id}/gateways",
+ "body": "*"
+ },
+ {
+ "method": "POST",
+ "pattern": "/organizations/{collaborator.organization_ids.organization_id}/gateways",
+ "body": "*"
}
]
}
}
},
{
- "name": "BatchGetGatewayConnectionStats",
- "description": "Get statistics about gateway connections to the Gateway Server of a batch of gateways.\n- Statistics are not persisted between reconnects.\n- Gateways that are not connected or are part of a different cluster are ignored.\n- The client should ensure that the requested gateways are in the requested cluster.\n- The client should have the right to get the gateway connection stats on all requested gateways.",
- "requestType": "BatchGetGatewayConnectionStatsRequest",
- "requestLongType": "BatchGetGatewayConnectionStatsRequest",
- "requestFullType": "ttn.lorawan.v3.BatchGetGatewayConnectionStatsRequest",
+ "name": "Get",
+ "description": "Get the gateway with the given identifiers, selecting the fields specified\nin the field mask.\nMore or less fields may be returned, depending on the rights of the caller.",
+ "requestType": "GetGatewayRequest",
+ "requestLongType": "GetGatewayRequest",
+ "requestFullType": "ttn.lorawan.v3.GetGatewayRequest",
"requestStreaming": false,
- "responseType": "BatchGetGatewayConnectionStatsResponse",
- "responseLongType": "BatchGetGatewayConnectionStatsResponse",
- "responseFullType": "ttn.lorawan.v3.BatchGetGatewayConnectionStatsResponse",
+ "responseType": "Gateway",
+ "responseLongType": "Gateway",
+ "responseFullType": "ttn.lorawan.v3.Gateway",
"responseStreaming": false,
"options": {
"google.api.http": {
"rules": [
{
- "method": "POST",
- "pattern": "/gs/gateways/connection/stats",
- "body": "*"
+ "method": "GET",
+ "pattern": "/gateways/{gateway_ids.gateway_id}"
}
]
}
}
- }
- ]
- },
- {
- "name": "GtwGs",
- "longName": "GtwGs",
- "fullName": "ttn.lorawan.v3.GtwGs",
- "description": "The GtwGs service connects a gateway to a Gateway Server.",
- "methods": [
- {
- "name": "LinkGateway",
- "description": "Link a gateway to the Gateway Server for streaming upstream messages and downstream messages.",
- "requestType": "GatewayUp",
- "requestLongType": "GatewayUp",
- "requestFullType": "ttn.lorawan.v3.GatewayUp",
- "requestStreaming": true,
- "responseType": "GatewayDown",
- "responseLongType": "GatewayDown",
- "responseFullType": "ttn.lorawan.v3.GatewayDown",
- "responseStreaming": true
},
{
- "name": "GetConcentratorConfig",
- "description": "Get configuration for the concentrator.",
- "requestType": "Empty",
- "requestLongType": ".google.protobuf.Empty",
- "requestFullType": "google.protobuf.Empty",
+ "name": "GetIdentifiersForEUI",
+ "description": "Get the identifiers of the gateway that has the given EUI registered.",
+ "requestType": "GetGatewayIdentifiersForEUIRequest",
+ "requestLongType": "GetGatewayIdentifiersForEUIRequest",
+ "requestFullType": "ttn.lorawan.v3.GetGatewayIdentifiersForEUIRequest",
"requestStreaming": false,
- "responseType": "ConcentratorConfig",
- "responseLongType": "ConcentratorConfig",
- "responseFullType": "ttn.lorawan.v3.ConcentratorConfig",
+ "responseType": "GatewayIdentifiers",
+ "responseLongType": "GatewayIdentifiers",
+ "responseFullType": "ttn.lorawan.v3.GatewayIdentifiers",
"responseStreaming": false
},
{
- "name": "GetMQTTConnectionInfo",
- "description": "Get connection information to connect an MQTT gateway.",
- "requestType": "GatewayIdentifiers",
- "requestLongType": "GatewayIdentifiers",
- "requestFullType": "ttn.lorawan.v3.GatewayIdentifiers",
+ "name": "List",
+ "description": "List gateways where the given user or organization is a direct collaborator.\nIf no user or organization is given, this returns the gateways the caller\nhas access to.\nSimilar to Get, this selects the fields given by the field mask.\nMore or less fields may be returned, depending on the rights of the caller.",
+ "requestType": "ListGatewaysRequest",
+ "requestLongType": "ListGatewaysRequest",
+ "requestFullType": "ttn.lorawan.v3.ListGatewaysRequest",
"requestStreaming": false,
- "responseType": "MQTTConnectionInfo",
- "responseLongType": "MQTTConnectionInfo",
- "responseFullType": "ttn.lorawan.v3.MQTTConnectionInfo",
+ "responseType": "Gateways",
+ "responseLongType": "Gateways",
+ "responseFullType": "ttn.lorawan.v3.Gateways",
"responseStreaming": false,
"options": {
"google.api.http": {
"rules": [
{
"method": "GET",
- "pattern": "/gs/gateways/{gateway_id}/mqtt-connection-info"
+ "pattern": "/gateways"
+ },
+ {
+ "method": "GET",
+ "pattern": "/users/{collaborator.user_ids.user_id}/gateways"
+ },
+ {
+ "method": "GET",
+ "pattern": "/organizations/{collaborator.organization_ids.organization_id}/gateways"
}
]
}
}
},
{
- "name": "GetMQTTV2ConnectionInfo",
- "description": "Get legacy connection information to connect a The Things Network Stack V2 MQTT gateway.",
- "requestType": "GatewayIdentifiers",
- "requestLongType": "GatewayIdentifiers",
- "requestFullType": "ttn.lorawan.v3.GatewayIdentifiers",
+ "name": "Update",
+ "description": "Update the gateway, changing the fields specified by the field mask to the provided values.",
+ "requestType": "UpdateGatewayRequest",
+ "requestLongType": "UpdateGatewayRequest",
+ "requestFullType": "ttn.lorawan.v3.UpdateGatewayRequest",
"requestStreaming": false,
- "responseType": "MQTTConnectionInfo",
- "responseLongType": "MQTTConnectionInfo",
- "responseFullType": "ttn.lorawan.v3.MQTTConnectionInfo",
+ "responseType": "Gateway",
+ "responseLongType": "Gateway",
+ "responseFullType": "ttn.lorawan.v3.Gateway",
"responseStreaming": false,
"options": {
"google.api.http": {
"rules": [
{
- "method": "GET",
- "pattern": "/gs/gateways/{gateway_id}/mqttv2-connection-info"
- }
+ "method": "PUT",
+ "pattern": "/gateways/{gateway.ids.gateway_id}",
+ "body": "*"
+ }
]
}
}
- }
- ]
- },
- {
- "name": "NsGs",
- "longName": "NsGs",
- "fullName": "ttn.lorawan.v3.NsGs",
- "description": "The NsGs service connects a Network Server to a Gateway Server.",
- "methods": [
+ },
{
- "name": "ScheduleDownlink",
- "description": "Instructs the Gateway Server to schedule a downlink message.\nThe Gateway Server may refuse if there are any conflicts in the schedule or\nif a duty cycle prevents the gateway from transmitting.",
- "requestType": "DownlinkMessage",
- "requestLongType": "DownlinkMessage",
- "requestFullType": "ttn.lorawan.v3.DownlinkMessage",
+ "name": "Delete",
+ "description": "Delete the gateway. This may not release the gateway ID for reuse, but it does release the EUI.",
+ "requestType": "GatewayIdentifiers",
+ "requestLongType": "GatewayIdentifiers",
+ "requestFullType": "ttn.lorawan.v3.GatewayIdentifiers",
"requestStreaming": false,
- "responseType": "ScheduleDownlinkResponse",
- "responseLongType": "ScheduleDownlinkResponse",
- "responseFullType": "ttn.lorawan.v3.ScheduleDownlinkResponse",
- "responseStreaming": false
+ "responseType": "Empty",
+ "responseLongType": ".google.protobuf.Empty",
+ "responseFullType": "google.protobuf.Empty",
+ "responseStreaming": false,
+ "options": {
+ "google.api.http": {
+ "rules": [
+ {
+ "method": "DELETE",
+ "pattern": "/gateways/{gateway_id}"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "name": "Restore",
+ "description": "Restore a recently deleted gateway. This does not restore the EUI,\nas that was released when deleting the gateway.\n\nDeployment configuration may specify if, and for how long after deletion,\nentities can be restored.",
+ "requestType": "GatewayIdentifiers",
+ "requestLongType": "GatewayIdentifiers",
+ "requestFullType": "ttn.lorawan.v3.GatewayIdentifiers",
+ "requestStreaming": false,
+ "responseType": "Empty",
+ "responseLongType": ".google.protobuf.Empty",
+ "responseFullType": "google.protobuf.Empty",
+ "responseStreaming": false,
+ "options": {
+ "google.api.http": {
+ "rules": [
+ {
+ "method": "POST",
+ "pattern": "/gateways/{gateway_id}/restore"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "name": "Purge",
+ "description": "Purge the gateway. This will release both gateway ID and EUI for reuse.\nThe gateway owner is responsible for clearing data from any (external) integrations\nthat may store and expose data by gateway ID.",
+ "requestType": "GatewayIdentifiers",
+ "requestLongType": "GatewayIdentifiers",
+ "requestFullType": "ttn.lorawan.v3.GatewayIdentifiers",
+ "requestStreaming": false,
+ "responseType": "Empty",
+ "responseLongType": ".google.protobuf.Empty",
+ "responseFullType": "google.protobuf.Empty",
+ "responseStreaming": false,
+ "options": {
+ "google.api.http": {
+ "rules": [
+ {
+ "method": "DELETE",
+ "pattern": "/gateways/{gateway_id}/purge"
+ }
+ ]
+ }
+ }
}
]
}
]
},
{
- "name": "ttn/lorawan/v3/identifiers.proto",
+ "name": "ttn/lorawan/v3/gatewayserver.proto",
"description": "",
"package": "ttn.lorawan.v3",
"hasEnums": false,
"hasExtensions": false,
"hasMessages": true,
- "hasServices": false,
+ "hasServices": true,
"enums": [],
"extensions": [],
"messages": [
{
- "name": "ApplicationIdentifiers",
- "longName": "ApplicationIdentifiers",
- "fullName": "ttn.lorawan.v3.ApplicationIdentifiers",
+ "name": "BatchGetGatewayConnectionStatsRequest",
+ "longName": "BatchGetGatewayConnectionStatsRequest",
+ "fullName": "ttn.lorawan.v3.BatchGetGatewayConnectionStatsRequest",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -24073,12 +24136,12 @@
"extensions": [],
"fields": [
{
- "name": "application_id",
+ "name": "gateway_ids",
"description": "",
- "label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
+ "label": "repeated",
+ "type": "GatewayIdentifiers",
+ "longType": "GatewayIdentifiers",
+ "fullType": "ttn.lorawan.v3.GatewayIdentifiers",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -24086,22 +24149,34 @@
"options": {
"validate.rules": [
{
- "name": "string.max_len",
- "value": 36
+ "name": "repeated.min_items",
+ "value": 1
},
{
- "name": "string.pattern",
- "value": "^[a-z0-9](?:[-]?[a-z0-9]){2,}$"
+ "name": "repeated.max_items",
+ "value": 100
}
]
}
+ },
+ {
+ "name": "field_mask",
+ "description": "The names of the gateway stats fields that should be returned.\nThis mask will be applied on each entry returned.",
+ "label": "",
+ "type": "FieldMask",
+ "longType": "google.protobuf.FieldMask",
+ "fullType": "google.protobuf.FieldMask",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
}
]
},
{
- "name": "ClientIdentifiers",
- "longName": "ClientIdentifiers",
- "fullName": "ttn.lorawan.v3.ClientIdentifiers",
+ "name": "BatchGetGatewayConnectionStatsResponse",
+ "longName": "BatchGetGatewayConnectionStatsResponse",
+ "fullName": "ttn.lorawan.v3.BatchGetGatewayConnectionStatsResponse",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -24109,35 +24184,23 @@
"extensions": [],
"fields": [
{
- "name": "client_id",
- "description": "",
- "label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
- "ismap": false,
+ "name": "entries",
+ "description": "The map key is the gateway identifier.",
+ "label": "repeated",
+ "type": "EntriesEntry",
+ "longType": "BatchGetGatewayConnectionStatsResponse.EntriesEntry",
+ "fullType": "ttn.lorawan.v3.BatchGetGatewayConnectionStatsResponse.EntriesEntry",
+ "ismap": true,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "string.max_len",
- "value": 36
- },
- {
- "name": "string.pattern",
- "value": "^[a-z0-9](?:[-]?[a-z0-9]){2,}$"
- }
- ]
- }
+ "defaultValue": ""
}
]
},
{
- "name": "EndDeviceIdentifiers",
- "longName": "EndDeviceIdentifiers",
- "fullName": "ttn.lorawan.v3.EndDeviceIdentifiers",
+ "name": "EntriesEntry",
+ "longName": "BatchGetGatewayConnectionStatsResponse.EntriesEntry",
+ "fullName": "ttn.lorawan.v3.BatchGetGatewayConnectionStatsResponse.EntriesEntry",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -24145,7 +24208,7 @@
"extensions": [],
"fields": [
{
- "name": "device_id",
+ "name": "key",
"description": "",
"label": "",
"type": "string",
@@ -24154,106 +24217,98 @@
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "string.max_len",
- "value": 36
- },
- {
- "name": "string.pattern",
- "value": "^[a-z0-9](?:[-]?[a-z0-9]){2,}$"
- }
- ]
- }
+ "defaultValue": ""
},
{
- "name": "application_ids",
+ "name": "value",
"description": "",
"label": "",
- "type": "ApplicationIdentifiers",
- "longType": "ApplicationIdentifiers",
- "fullType": "ttn.lorawan.v3.ApplicationIdentifiers",
+ "type": "GatewayConnectionStats",
+ "longType": "GatewayConnectionStats",
+ "fullType": "ttn.lorawan.v3.GatewayConnectionStats",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "message.required",
- "value": true
- }
- ]
- }
- },
+ "defaultValue": ""
+ }
+ ]
+ },
+ {
+ "name": "GatewayDown",
+ "longName": "GatewayDown",
+ "fullName": "ttn.lorawan.v3.GatewayDown",
+ "description": "GatewayDown contains downlink messages for the gateway.",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "dev_eui",
- "description": "The LoRaWAN DevEUI.",
+ "name": "downlink_message",
+ "description": "DownlinkMessage for the gateway.",
"label": "",
- "type": "bytes",
- "longType": "bytes",
- "fullType": "bytes",
+ "type": "DownlinkMessage",
+ "longType": "DownlinkMessage",
+ "fullType": "ttn.lorawan.v3.DownlinkMessage",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "bytes.len",
- "value": 8
- }
- ]
- }
- },
+ "defaultValue": ""
+ }
+ ]
+ },
+ {
+ "name": "GatewayUp",
+ "longName": "GatewayUp",
+ "fullName": "ttn.lorawan.v3.GatewayUp",
+ "description": "GatewayUp may contain zero or more uplink messages and/or a status message for the gateway.",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "join_eui",
- "description": "The LoRaWAN JoinEUI (AppEUI until LoRaWAN 1.0.3 end devices).",
- "label": "",
- "type": "bytes",
- "longType": "bytes",
- "fullType": "bytes",
- "ismap": false,
- "isoneof": false,
+ "name": "uplink_messages",
+ "description": "Uplink messages received by the gateway.",
+ "label": "repeated",
+ "type": "UplinkMessage",
+ "longType": "UplinkMessage",
+ "fullType": "ttn.lorawan.v3.UplinkMessage",
+ "ismap": false,
+ "isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "bytes.len",
- "value": 8
- }
- ]
- }
+ "defaultValue": ""
},
{
- "name": "dev_addr",
- "description": "The LoRaWAN DevAddr.",
+ "name": "gateway_status",
+ "description": "Gateway status produced by the gateway.",
"label": "",
- "type": "bytes",
- "longType": "bytes",
- "fullType": "bytes",
+ "type": "GatewayStatus",
+ "longType": "GatewayStatus",
+ "fullType": "ttn.lorawan.v3.GatewayStatus",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "bytes.len",
- "value": 4
- }
- ]
- }
+ "defaultValue": ""
+ },
+ {
+ "name": "tx_acknowledgment",
+ "description": "A Tx acknowledgment or error.",
+ "label": "",
+ "type": "TxAcknowledgment",
+ "longType": "TxAcknowledgment",
+ "fullType": "ttn.lorawan.v3.TxAcknowledgment",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
}
]
},
{
- "name": "EndDeviceIdentifiersList",
- "longName": "EndDeviceIdentifiersList",
- "fullName": "ttn.lorawan.v3.EndDeviceIdentifiersList",
+ "name": "ScheduleDownlinkErrorDetails",
+ "longName": "ScheduleDownlinkErrorDetails",
+ "fullName": "ttn.lorawan.v3.ScheduleDownlinkErrorDetails",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -24261,12 +24316,12 @@
"extensions": [],
"fields": [
{
- "name": "end_device_ids",
- "description": "",
+ "name": "path_errors",
+ "description": "Errors per path when downlink scheduling failed.",
"label": "repeated",
- "type": "EndDeviceIdentifiers",
- "longType": "EndDeviceIdentifiers",
- "fullType": "ttn.lorawan.v3.EndDeviceIdentifiers",
+ "type": "ErrorDetails",
+ "longType": "ErrorDetails",
+ "fullType": "ttn.lorawan.v3.ErrorDetails",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -24275,22 +24330,22 @@
]
},
{
- "name": "EndDeviceVersionIdentifiers",
- "longName": "EndDeviceVersionIdentifiers",
- "fullName": "ttn.lorawan.v3.EndDeviceVersionIdentifiers",
- "description": "Identifies an end device model with version information.",
+ "name": "ScheduleDownlinkResponse",
+ "longName": "ScheduleDownlinkResponse",
+ "fullName": "ttn.lorawan.v3.ScheduleDownlinkResponse",
+ "description": "",
"hasExtensions": false,
"hasFields": true,
"hasOneofs": false,
"extensions": [],
"fields": [
{
- "name": "brand_id",
- "description": "",
+ "name": "delay",
+ "description": "The amount of time between the message has been scheduled and it will be transmitted by the gateway.",
"label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
+ "type": "Duration",
+ "longType": "google.protobuf.Duration",
+ "fullType": "google.protobuf.Duration",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -24298,190 +24353,218 @@
"options": {
"validate.rules": [
{
- "name": "string.max_len",
- "value": 36
- },
- {
- "name": "string.pattern",
- "value": "^[a-z0-9](?:[-]?[a-z0-9]){2,}$"
+ "name": "duration.required",
+ "value": true
}
]
}
},
{
- "name": "model_id",
- "description": "",
+ "name": "downlink_path",
+ "description": "Downlink path chosen by the Gateway Server.",
"label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
+ "type": "DownlinkPath",
+ "longType": "DownlinkPath",
+ "fullType": "ttn.lorawan.v3.DownlinkPath",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "string.max_len",
- "value": 36
- },
- {
- "name": "string.pattern",
- "value": "^[a-z0-9](?:[-]?[a-z0-9]){2,}$"
- }
- ]
- }
+ "defaultValue": ""
},
{
- "name": "hardware_version",
- "description": "",
+ "name": "rx1",
+ "description": "Whether RX1 has been chosen for the downlink message.\nBoth RX1 and RX2 can be used for transmitting the same message by the same gateway.",
"label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "string.max_len",
- "value": 32
- }
- ]
- }
+ "defaultValue": ""
},
{
- "name": "firmware_version",
- "description": "",
+ "name": "rx2",
+ "description": "Whether RX2 has been chosen for the downlink message.\nBoth RX1 and RX2 can be used for transmitting the same message by the same gateway.",
"label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
+ "defaultValue": ""
+ }
+ ]
+ }
+ ],
+ "services": [
+ {
+ "name": "Gs",
+ "longName": "Gs",
+ "fullName": "ttn.lorawan.v3.Gs",
+ "description": "",
+ "methods": [
+ {
+ "name": "GetGatewayConnectionStats",
+ "description": "Get statistics about the current gateway connection to the Gateway Server.\nThis is not persisted between reconnects.",
+ "requestType": "GatewayIdentifiers",
+ "requestLongType": "GatewayIdentifiers",
+ "requestFullType": "ttn.lorawan.v3.GatewayIdentifiers",
+ "requestStreaming": false,
+ "responseType": "GatewayConnectionStats",
+ "responseLongType": "GatewayConnectionStats",
+ "responseFullType": "ttn.lorawan.v3.GatewayConnectionStats",
+ "responseStreaming": false,
"options": {
- "validate.rules": [
- {
- "name": "string.max_len",
- "value": 32
- }
- ]
+ "google.api.http": {
+ "rules": [
+ {
+ "method": "GET",
+ "pattern": "/gs/gateways/{gateway_id}/connection/stats"
+ }
+ ]
+ }
}
},
{
- "name": "band_id",
- "description": "",
- "label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
+ "name": "BatchGetGatewayConnectionStats",
+ "description": "Get statistics about gateway connections to the Gateway Server of a batch of gateways.\n- Statistics are not persisted between reconnects.\n- Gateways that are not connected or are part of a different cluster are ignored.\n- The client should ensure that the requested gateways are in the requested cluster.\n- The client should have the right to get the gateway connection stats on all requested gateways.",
+ "requestType": "BatchGetGatewayConnectionStatsRequest",
+ "requestLongType": "BatchGetGatewayConnectionStatsRequest",
+ "requestFullType": "ttn.lorawan.v3.BatchGetGatewayConnectionStatsRequest",
+ "requestStreaming": false,
+ "responseType": "BatchGetGatewayConnectionStatsResponse",
+ "responseLongType": "BatchGetGatewayConnectionStatsResponse",
+ "responseFullType": "ttn.lorawan.v3.BatchGetGatewayConnectionStatsResponse",
+ "responseStreaming": false,
"options": {
- "validate.rules": [
- {
- "name": "string.max_len",
- "value": 32
- }
- ]
+ "google.api.http": {
+ "rules": [
+ {
+ "method": "POST",
+ "pattern": "/gs/gateways/connection/stats",
+ "body": "*"
+ }
+ ]
+ }
}
}
]
},
{
- "name": "EntityIdentifiers",
- "longName": "EntityIdentifiers",
- "fullName": "ttn.lorawan.v3.EntityIdentifiers",
- "description": "EntityIdentifiers contains one of the possible entity identifiers.",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": true,
- "extensions": [],
- "fields": [
+ "name": "GtwGs",
+ "longName": "GtwGs",
+ "fullName": "ttn.lorawan.v3.GtwGs",
+ "description": "The GtwGs service connects a gateway to a Gateway Server.",
+ "methods": [
{
- "name": "application_ids",
- "description": "",
- "label": "",
- "type": "ApplicationIdentifiers",
- "longType": "ApplicationIdentifiers",
- "fullType": "ttn.lorawan.v3.ApplicationIdentifiers",
- "ismap": false,
- "isoneof": true,
- "oneofdecl": "ids",
- "defaultValue": ""
+ "name": "LinkGateway",
+ "description": "Link a gateway to the Gateway Server for streaming upstream messages and downstream messages.",
+ "requestType": "GatewayUp",
+ "requestLongType": "GatewayUp",
+ "requestFullType": "ttn.lorawan.v3.GatewayUp",
+ "requestStreaming": true,
+ "responseType": "GatewayDown",
+ "responseLongType": "GatewayDown",
+ "responseFullType": "ttn.lorawan.v3.GatewayDown",
+ "responseStreaming": true
},
{
- "name": "client_ids",
- "description": "",
- "label": "",
- "type": "ClientIdentifiers",
- "longType": "ClientIdentifiers",
- "fullType": "ttn.lorawan.v3.ClientIdentifiers",
- "ismap": false,
- "isoneof": true,
- "oneofdecl": "ids",
- "defaultValue": ""
- },
- {
- "name": "device_ids",
- "description": "",
- "label": "",
- "type": "EndDeviceIdentifiers",
- "longType": "EndDeviceIdentifiers",
- "fullType": "ttn.lorawan.v3.EndDeviceIdentifiers",
- "ismap": false,
- "isoneof": true,
- "oneofdecl": "ids",
- "defaultValue": ""
- },
- {
- "name": "gateway_ids",
- "description": "",
- "label": "",
- "type": "GatewayIdentifiers",
- "longType": "GatewayIdentifiers",
- "fullType": "ttn.lorawan.v3.GatewayIdentifiers",
- "ismap": false,
- "isoneof": true,
- "oneofdecl": "ids",
- "defaultValue": ""
+ "name": "GetConcentratorConfig",
+ "description": "Get configuration for the concentrator.",
+ "requestType": "Empty",
+ "requestLongType": ".google.protobuf.Empty",
+ "requestFullType": "google.protobuf.Empty",
+ "requestStreaming": false,
+ "responseType": "ConcentratorConfig",
+ "responseLongType": "ConcentratorConfig",
+ "responseFullType": "ttn.lorawan.v3.ConcentratorConfig",
+ "responseStreaming": false
},
{
- "name": "organization_ids",
- "description": "",
- "label": "",
- "type": "OrganizationIdentifiers",
- "longType": "OrganizationIdentifiers",
- "fullType": "ttn.lorawan.v3.OrganizationIdentifiers",
- "ismap": false,
- "isoneof": true,
- "oneofdecl": "ids",
- "defaultValue": ""
+ "name": "GetMQTTConnectionInfo",
+ "description": "Get connection information to connect an MQTT gateway.",
+ "requestType": "GatewayIdentifiers",
+ "requestLongType": "GatewayIdentifiers",
+ "requestFullType": "ttn.lorawan.v3.GatewayIdentifiers",
+ "requestStreaming": false,
+ "responseType": "MQTTConnectionInfo",
+ "responseLongType": "MQTTConnectionInfo",
+ "responseFullType": "ttn.lorawan.v3.MQTTConnectionInfo",
+ "responseStreaming": false,
+ "options": {
+ "google.api.http": {
+ "rules": [
+ {
+ "method": "GET",
+ "pattern": "/gs/gateways/{gateway_id}/mqtt-connection-info"
+ }
+ ]
+ }
+ }
},
{
- "name": "user_ids",
- "description": "",
- "label": "",
- "type": "UserIdentifiers",
- "longType": "UserIdentifiers",
- "fullType": "ttn.lorawan.v3.UserIdentifiers",
- "ismap": false,
- "isoneof": true,
- "oneofdecl": "ids",
- "defaultValue": ""
+ "name": "GetMQTTV2ConnectionInfo",
+ "description": "Get legacy connection information to connect a The Things Network Stack V2 MQTT gateway.",
+ "requestType": "GatewayIdentifiers",
+ "requestLongType": "GatewayIdentifiers",
+ "requestFullType": "ttn.lorawan.v3.GatewayIdentifiers",
+ "requestStreaming": false,
+ "responseType": "MQTTConnectionInfo",
+ "responseLongType": "MQTTConnectionInfo",
+ "responseFullType": "ttn.lorawan.v3.MQTTConnectionInfo",
+ "responseStreaming": false,
+ "options": {
+ "google.api.http": {
+ "rules": [
+ {
+ "method": "GET",
+ "pattern": "/gs/gateways/{gateway_id}/mqttv2-connection-info"
+ }
+ ]
+ }
+ }
}
]
},
{
- "name": "GatewayIdentifiers",
- "longName": "GatewayIdentifiers",
- "fullName": "ttn.lorawan.v3.GatewayIdentifiers",
+ "name": "NsGs",
+ "longName": "NsGs",
+ "fullName": "ttn.lorawan.v3.NsGs",
+ "description": "The NsGs service connects a Network Server to a Gateway Server.",
+ "methods": [
+ {
+ "name": "ScheduleDownlink",
+ "description": "Instructs the Gateway Server to schedule a downlink message.\nThe Gateway Server may refuse if there are any conflicts in the schedule or\nif a duty cycle prevents the gateway from transmitting.",
+ "requestType": "DownlinkMessage",
+ "requestLongType": "DownlinkMessage",
+ "requestFullType": "ttn.lorawan.v3.DownlinkMessage",
+ "requestStreaming": false,
+ "responseType": "ScheduleDownlinkResponse",
+ "responseLongType": "ScheduleDownlinkResponse",
+ "responseFullType": "ttn.lorawan.v3.ScheduleDownlinkResponse",
+ "responseStreaming": false
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "ttn/lorawan/v3/identifiers.proto",
+ "description": "",
+ "package": "ttn.lorawan.v3",
+ "hasEnums": false,
+ "hasExtensions": false,
+ "hasMessages": true,
+ "hasServices": false,
+ "enums": [],
+ "extensions": [],
+ "messages": [
+ {
+ "name": "ApplicationIdentifiers",
+ "longName": "ApplicationIdentifiers",
+ "fullName": "ttn.lorawan.v3.ApplicationIdentifiers",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -24489,7 +24572,7 @@
"extensions": [],
"fields": [
{
- "name": "gateway_id",
+ "name": "application_id",
"description": "",
"label": "",
"type": "string",
@@ -24511,33 +24594,13 @@
}
]
}
- },
- {
- "name": "eui",
- "description": "Secondary identifier, which can only be used in specific requests.",
- "label": "",
- "type": "bytes",
- "longType": "bytes",
- "fullType": "bytes",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "bytes.len",
- "value": 8
- }
- ]
- }
}
]
},
{
- "name": "GatewayIdentifiersList",
- "longName": "GatewayIdentifiersList",
- "fullName": "ttn.lorawan.v3.GatewayIdentifiersList",
+ "name": "ClientIdentifiers",
+ "longName": "ClientIdentifiers",
+ "fullName": "ttn.lorawan.v3.ClientIdentifiers",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -24545,72 +24608,48 @@
"extensions": [],
"fields": [
{
- "name": "gateway_ids",
+ "name": "client_id",
"description": "",
- "label": "repeated",
- "type": "GatewayIdentifiers",
- "longType": "GatewayIdentifiers",
- "fullType": "ttn.lorawan.v3.GatewayIdentifiers",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
- }
- ]
- },
- {
- "name": "LoRaAllianceProfileIdentifiers",
- "longName": "LoRaAllianceProfileIdentifiers",
- "fullName": "ttn.lorawan.v3.LoRaAllianceProfileIdentifiers",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
- {
- "name": "vendor_id",
- "description": "VendorID managed by the LoRa Alliance, as defined in TR005.",
- "label": "",
- "type": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
- },
- {
- "name": "vendor_profile_id",
- "description": "ID of the LoRaWAN end device profile assigned by the vendor.",
"label": "",
- "type": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "string.max_len",
+ "value": 36
+ },
+ {
+ "name": "string.pattern",
+ "value": "^[a-z0-9](?:[-]?[a-z0-9]){2,}$"
+ }
+ ]
+ }
}
]
},
{
- "name": "NetworkIdentifiers",
- "longName": "NetworkIdentifiers",
- "fullName": "ttn.lorawan.v3.NetworkIdentifiers",
- "description": "Identifies a Network Server.",
+ "name": "EndDeviceIdentifiers",
+ "longName": "EndDeviceIdentifiers",
+ "fullName": "ttn.lorawan.v3.EndDeviceIdentifiers",
+ "description": "",
"hasExtensions": false,
"hasFields": true,
"hasOneofs": false,
"extensions": [],
"fields": [
{
- "name": "net_id",
- "description": "LoRa Alliance NetID.",
+ "name": "device_id",
+ "description": "",
"label": "",
- "type": "bytes",
- "longType": "bytes",
- "fullType": "bytes",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -24618,15 +24657,39 @@
"options": {
"validate.rules": [
{
- "name": "bytes.len",
- "value": 3
+ "name": "string.max_len",
+ "value": 36
+ },
+ {
+ "name": "string.pattern",
+ "value": "^[a-z0-9](?:[-]?[a-z0-9]){2,}$"
}
]
}
},
{
- "name": "ns_id",
- "description": "LoRaWAN NSID (EUI-64) that uniquely identifies the Network Server instance.",
+ "name": "application_ids",
+ "description": "",
+ "label": "",
+ "type": "ApplicationIdentifiers",
+ "longType": "ApplicationIdentifiers",
+ "fullType": "ttn.lorawan.v3.ApplicationIdentifiers",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "message.required",
+ "value": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "dev_eui",
+ "description": "The LoRaWAN DevEUI.",
"label": "",
"type": "bytes",
"longType": "bytes",
@@ -24645,8 +24708,84 @@
}
},
{
- "name": "tenant_id",
- "description": "Optional tenant identifier for multi-tenant deployments.",
+ "name": "join_eui",
+ "description": "The LoRaWAN JoinEUI (AppEUI until LoRaWAN 1.0.3 end devices).",
+ "label": "",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "bytes.len",
+ "value": 8
+ }
+ ]
+ }
+ },
+ {
+ "name": "dev_addr",
+ "description": "The LoRaWAN DevAddr.",
+ "label": "",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "bytes.len",
+ "value": 4
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "EndDeviceIdentifiersList",
+ "longName": "EndDeviceIdentifiersList",
+ "fullName": "ttn.lorawan.v3.EndDeviceIdentifiersList",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "end_device_ids",
+ "description": "",
+ "label": "repeated",
+ "type": "EndDeviceIdentifiers",
+ "longType": "EndDeviceIdentifiers",
+ "fullType": "ttn.lorawan.v3.EndDeviceIdentifiers",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ }
+ ]
+ },
+ {
+ "name": "EndDeviceVersionIdentifiers",
+ "longName": "EndDeviceVersionIdentifiers",
+ "fullName": "ttn.lorawan.v3.EndDeviceVersionIdentifiers",
+ "description": "Identifies an end device model with version information.",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "brand_id",
+ "description": "",
"label": "",
"type": "string",
"longType": "string",
@@ -24663,14 +24802,14 @@
},
{
"name": "string.pattern",
- "value": "^[a-z0-9](?:[-]?[a-z0-9]){2,}$|^$"
+ "value": "^[a-z0-9](?:[-]?[a-z0-9]){2,}$"
}
]
}
},
{
- "name": "cluster_id",
- "description": "Cluster identifier of the Network Server.",
+ "name": "model_id",
+ "description": "",
"label": "",
"type": "string",
"longType": "string",
@@ -24683,14 +24822,18 @@
"validate.rules": [
{
"name": "string.max_len",
- "value": 64
+ "value": 36
+ },
+ {
+ "name": "string.pattern",
+ "value": "^[a-z0-9](?:[-]?[a-z0-9]){2,}$"
}
]
}
},
{
- "name": "cluster_address",
- "description": "Cluster address of the Network Server.",
+ "name": "hardware_version",
+ "description": "",
"label": "",
"type": "string",
"longType": "string",
@@ -24703,14 +24846,14 @@
"validate.rules": [
{
"name": "string.max_len",
- "value": 256
+ "value": 32
}
]
}
},
{
- "name": "tenant_address",
- "description": "Optional tenant address for multi-tenant deployments.",
+ "name": "firmware_version",
+ "description": "",
"label": "",
"type": "string",
"longType": "string",
@@ -24723,26 +24866,14 @@
"validate.rules": [
{
"name": "string.max_len",
- "value": 256
+ "value": 32
}
]
}
- }
- ]
- },
- {
- "name": "OrganizationIdentifiers",
- "longName": "OrganizationIdentifiers",
- "fullName": "ttn.lorawan.v3.OrganizationIdentifiers",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ },
{
- "name": "organization_id",
- "description": "This ID shares namespace with user IDs.",
+ "name": "band_id",
+ "description": "",
"label": "",
"type": "string",
"longType": "string",
@@ -24755,11 +24886,7 @@
"validate.rules": [
{
"name": "string.max_len",
- "value": 36
- },
- {
- "name": "string.pattern",
- "value": "^[a-z0-9](?:[-]?[a-z0-9]){2,}$"
+ "value": 32
}
]
}
@@ -24767,15 +24894,63 @@
]
},
{
- "name": "OrganizationOrUserIdentifiers",
- "longName": "OrganizationOrUserIdentifiers",
- "fullName": "ttn.lorawan.v3.OrganizationOrUserIdentifiers",
- "description": "OrganizationOrUserIdentifiers contains either organization or user identifiers.",
+ "name": "EntityIdentifiers",
+ "longName": "EntityIdentifiers",
+ "fullName": "ttn.lorawan.v3.EntityIdentifiers",
+ "description": "EntityIdentifiers contains one of the possible entity identifiers.",
"hasExtensions": false,
"hasFields": true,
"hasOneofs": true,
"extensions": [],
"fields": [
+ {
+ "name": "application_ids",
+ "description": "",
+ "label": "",
+ "type": "ApplicationIdentifiers",
+ "longType": "ApplicationIdentifiers",
+ "fullType": "ttn.lorawan.v3.ApplicationIdentifiers",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "ids",
+ "defaultValue": ""
+ },
+ {
+ "name": "client_ids",
+ "description": "",
+ "label": "",
+ "type": "ClientIdentifiers",
+ "longType": "ClientIdentifiers",
+ "fullType": "ttn.lorawan.v3.ClientIdentifiers",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "ids",
+ "defaultValue": ""
+ },
+ {
+ "name": "device_ids",
+ "description": "",
+ "label": "",
+ "type": "EndDeviceIdentifiers",
+ "longType": "EndDeviceIdentifiers",
+ "fullType": "ttn.lorawan.v3.EndDeviceIdentifiers",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "ids",
+ "defaultValue": ""
+ },
+ {
+ "name": "gateway_ids",
+ "description": "",
+ "label": "",
+ "type": "GatewayIdentifiers",
+ "longType": "GatewayIdentifiers",
+ "fullType": "ttn.lorawan.v3.GatewayIdentifiers",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "ids",
+ "defaultValue": ""
+ },
{
"name": "organization_ids",
"description": "",
@@ -24803,9 +24978,9 @@
]
},
{
- "name": "UserIdentifiers",
- "longName": "UserIdentifiers",
- "fullName": "ttn.lorawan.v3.UserIdentifiers",
+ "name": "GatewayIdentifiers",
+ "longName": "GatewayIdentifiers",
+ "fullName": "ttn.lorawan.v3.GatewayIdentifiers",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -24813,8 +24988,8 @@
"extensions": [],
"fields": [
{
- "name": "user_id",
- "description": "This ID shares namespace with organization IDs.",
+ "name": "gateway_id",
+ "description": "",
"label": "",
"type": "string",
"longType": "string",
@@ -24831,116 +25006,86 @@
},
{
"name": "string.pattern",
- "value": "^[a-z0-9](?:[-]?[a-z0-9]){1,}$"
+ "value": "^[a-z0-9](?:[-]?[a-z0-9]){2,}$"
}
]
}
},
{
- "name": "email",
+ "name": "eui",
"description": "Secondary identifier, which can only be used in specific requests.",
"label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "bytes.len",
+ "value": 8
+ }
+ ]
+ }
}
]
- }
- ],
- "services": []
- },
- {
- "name": "ttn/lorawan/v3/identityserver.proto",
- "description": "",
- "package": "ttn.lorawan.v3",
- "hasEnums": false,
- "hasExtensions": false,
- "hasMessages": true,
- "hasServices": true,
- "enums": [],
- "extensions": [],
- "messages": [
+ },
{
- "name": "AuthInfoResponse",
- "longName": "AuthInfoResponse",
- "fullName": "ttn.lorawan.v3.AuthInfoResponse",
+ "name": "GatewayIdentifiersList",
+ "longName": "GatewayIdentifiersList",
+ "fullName": "ttn.lorawan.v3.GatewayIdentifiersList",
"description": "",
"hasExtensions": false,
"hasFields": true,
- "hasOneofs": true,
+ "hasOneofs": false,
"extensions": [],
"fields": [
{
- "name": "api_key",
- "description": "",
- "label": "",
- "type": "APIKeyAccess",
- "longType": "AuthInfoResponse.APIKeyAccess",
- "fullType": "ttn.lorawan.v3.AuthInfoResponse.APIKeyAccess",
- "ismap": false,
- "isoneof": true,
- "oneofdecl": "access_method",
- "defaultValue": ""
- },
- {
- "name": "oauth_access_token",
- "description": "",
- "label": "",
- "type": "OAuthAccessToken",
- "longType": "OAuthAccessToken",
- "fullType": "ttn.lorawan.v3.OAuthAccessToken",
- "ismap": false,
- "isoneof": true,
- "oneofdecl": "access_method",
- "defaultValue": ""
- },
- {
- "name": "user_session",
- "description": "Warning: A user authorized by session cookie will be granted all\ncurrent and future rights. When using this auth type, the respective\nhandlers need to ensure thorough CSRF and CORS protection using\nappropriate middleware.",
- "label": "",
- "type": "UserSession",
- "longType": "UserSession",
- "fullType": "ttn.lorawan.v3.UserSession",
- "ismap": false,
- "isoneof": true,
- "oneofdecl": "access_method",
- "defaultValue": ""
- },
- {
- "name": "gateway_token",
+ "name": "gateway_ids",
"description": "",
- "label": "",
- "type": "GatewayToken",
- "longType": "AuthInfoResponse.GatewayToken",
- "fullType": "ttn.lorawan.v3.AuthInfoResponse.GatewayToken",
+ "label": "repeated",
+ "type": "GatewayIdentifiers",
+ "longType": "GatewayIdentifiers",
+ "fullType": "ttn.lorawan.v3.GatewayIdentifiers",
"ismap": false,
- "isoneof": true,
- "oneofdecl": "access_method",
+ "isoneof": false,
+ "oneofdecl": "",
"defaultValue": ""
- },
+ }
+ ]
+ },
+ {
+ "name": "LoRaAllianceProfileIdentifiers",
+ "longName": "LoRaAllianceProfileIdentifiers",
+ "fullName": "ttn.lorawan.v3.LoRaAllianceProfileIdentifiers",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "universal_rights",
- "description": "",
+ "name": "vendor_id",
+ "description": "VendorID managed by the LoRa Alliance, as defined in TR005.",
"label": "",
- "type": "Rights",
- "longType": "Rights",
- "fullType": "ttn.lorawan.v3.Rights",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "is_admin",
- "description": "",
+ "name": "vendor_profile_id",
+ "description": "ID of the LoRaWAN end device profile assigned by the vendor.",
"label": "",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -24949,22 +25094,22 @@
]
},
{
- "name": "APIKeyAccess",
- "longName": "AuthInfoResponse.APIKeyAccess",
- "fullName": "ttn.lorawan.v3.AuthInfoResponse.APIKeyAccess",
- "description": "",
+ "name": "NetworkIdentifiers",
+ "longName": "NetworkIdentifiers",
+ "fullName": "ttn.lorawan.v3.NetworkIdentifiers",
+ "description": "Identifies a Network Server.",
"hasExtensions": false,
"hasFields": true,
"hasOneofs": false,
"extensions": [],
"fields": [
{
- "name": "api_key",
- "description": "",
+ "name": "net_id",
+ "description": "LoRa Alliance NetID.",
"label": "",
- "type": "APIKey",
- "longType": "APIKey",
- "fullType": "ttn.lorawan.v3.APIKey",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -24972,19 +25117,19 @@
"options": {
"validate.rules": [
{
- "name": "message.required",
- "value": true
+ "name": "bytes.len",
+ "value": 3
}
]
}
},
{
- "name": "entity_ids",
- "description": "",
+ "name": "ns_id",
+ "description": "LoRaWAN NSID (EUI-64) that uniquely identifies the Network Server instance.",
"label": "",
- "type": "EntityIdentifiers",
- "longType": "EntityIdentifiers",
- "fullType": "ttn.lorawan.v3.EntityIdentifiers",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -24992,31 +25137,19 @@
"options": {
"validate.rules": [
{
- "name": "message.required",
- "value": true
+ "name": "bytes.len",
+ "value": 8
}
]
}
- }
- ]
- },
- {
- "name": "GatewayToken",
- "longName": "AuthInfoResponse.GatewayToken",
- "fullName": "ttn.lorawan.v3.AuthInfoResponse.GatewayToken",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ },
{
- "name": "gateway_ids",
- "description": "",
+ "name": "tenant_id",
+ "description": "Optional tenant identifier for multi-tenant deployments.",
"label": "",
- "type": "GatewayIdentifiers",
- "longType": "GatewayIdentifiers",
- "fullType": "ttn.lorawan.v3.GatewayIdentifiers",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -25024,65 +25157,82 @@
"options": {
"validate.rules": [
{
- "name": "message.required",
- "value": true
+ "name": "string.max_len",
+ "value": 36
+ },
+ {
+ "name": "string.pattern",
+ "value": "^[a-z0-9](?:[-]?[a-z0-9]){2,}$|^$"
}
]
}
},
{
- "name": "rights",
- "description": "",
- "label": "repeated",
- "type": "Right",
- "longType": "Right",
- "fullType": "ttn.lorawan.v3.Right",
+ "name": "cluster_id",
+ "description": "Cluster identifier of the Network Server.",
+ "label": "",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
- }
- ]
- },
- {
- "name": "GetIsConfigurationRequest",
- "longName": "GetIsConfigurationRequest",
- "fullName": "ttn.lorawan.v3.GetIsConfigurationRequest",
- "description": "",
- "hasExtensions": false,
- "hasFields": false,
- "hasOneofs": false,
- "extensions": [],
- "fields": []
- },
- {
- "name": "GetIsConfigurationResponse",
- "longName": "GetIsConfigurationResponse",
- "fullName": "ttn.lorawan.v3.GetIsConfigurationResponse",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "string.max_len",
+ "value": 64
+ }
+ ]
+ }
+ },
{
- "name": "configuration",
- "description": "",
+ "name": "cluster_address",
+ "description": "Cluster address of the Network Server.",
"label": "",
- "type": "IsConfiguration",
- "longType": "IsConfiguration",
- "fullType": "ttn.lorawan.v3.IsConfiguration",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "string.max_len",
+ "value": 256
+ }
+ ]
+ }
+ },
+ {
+ "name": "tenant_address",
+ "description": "Optional tenant address for multi-tenant deployments.",
+ "label": "",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "string.max_len",
+ "value": 256
+ }
+ ]
+ }
}
]
},
{
- "name": "IsConfiguration",
- "longName": "IsConfiguration",
- "fullName": "ttn.lorawan.v3.IsConfiguration",
+ "name": "OrganizationIdentifiers",
+ "longName": "OrganizationIdentifiers",
+ "fullName": "ttn.lorawan.v3.OrganizationIdentifiers",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -25090,84 +25240,206 @@
"extensions": [],
"fields": [
{
- "name": "user_registration",
- "description": "",
+ "name": "organization_id",
+ "description": "This ID shares namespace with user IDs.",
"label": "",
- "type": "UserRegistration",
- "longType": "IsConfiguration.UserRegistration",
- "fullType": "ttn.lorawan.v3.IsConfiguration.UserRegistration",
- "ismap": false,
- "isoneof": false,
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
+ "ismap": false,
+ "isoneof": false,
"oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "string.max_len",
+ "value": 36
+ },
+ {
+ "name": "string.pattern",
+ "value": "^[a-z0-9](?:[-]?[a-z0-9]){2,}$"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "OrganizationOrUserIdentifiers",
+ "longName": "OrganizationOrUserIdentifiers",
+ "fullName": "ttn.lorawan.v3.OrganizationOrUserIdentifiers",
+ "description": "OrganizationOrUserIdentifiers contains either organization or user identifiers.",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": true,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "organization_ids",
+ "description": "",
+ "label": "",
+ "type": "OrganizationIdentifiers",
+ "longType": "OrganizationIdentifiers",
+ "fullType": "ttn.lorawan.v3.OrganizationIdentifiers",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "ids",
"defaultValue": ""
},
{
- "name": "profile_picture",
+ "name": "user_ids",
"description": "",
"label": "",
- "type": "ProfilePicture",
- "longType": "IsConfiguration.ProfilePicture",
- "fullType": "ttn.lorawan.v3.IsConfiguration.ProfilePicture",
+ "type": "UserIdentifiers",
+ "longType": "UserIdentifiers",
+ "fullType": "ttn.lorawan.v3.UserIdentifiers",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "ids",
+ "defaultValue": ""
+ }
+ ]
+ },
+ {
+ "name": "UserIdentifiers",
+ "longName": "UserIdentifiers",
+ "fullName": "ttn.lorawan.v3.UserIdentifiers",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "user_id",
+ "description": "This ID shares namespace with organization IDs.",
+ "label": "",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "string.max_len",
+ "value": 36
+ },
+ {
+ "name": "string.pattern",
+ "value": "^[a-z0-9](?:[-]?[a-z0-9]){1,}$"
+ }
+ ]
+ }
},
{
- "name": "end_device_picture",
- "description": "",
+ "name": "email",
+ "description": "Secondary identifier, which can only be used in specific requests.",
"label": "",
- "type": "EndDevicePicture",
- "longType": "IsConfiguration.EndDevicePicture",
- "fullType": "ttn.lorawan.v3.IsConfiguration.EndDevicePicture",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
+ }
+ ]
+ }
+ ],
+ "services": []
+ },
+ {
+ "name": "ttn/lorawan/v3/identityserver.proto",
+ "description": "",
+ "package": "ttn.lorawan.v3",
+ "hasEnums": false,
+ "hasExtensions": false,
+ "hasMessages": true,
+ "hasServices": true,
+ "enums": [],
+ "extensions": [],
+ "messages": [
+ {
+ "name": "AuthInfoResponse",
+ "longName": "AuthInfoResponse",
+ "fullName": "ttn.lorawan.v3.AuthInfoResponse",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": true,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "api_key",
+ "description": "",
+ "label": "",
+ "type": "APIKeyAccess",
+ "longType": "AuthInfoResponse.APIKeyAccess",
+ "fullType": "ttn.lorawan.v3.AuthInfoResponse.APIKeyAccess",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "access_method",
+ "defaultValue": ""
},
{
- "name": "user_rights",
+ "name": "oauth_access_token",
"description": "",
"label": "",
- "type": "UserRights",
- "longType": "IsConfiguration.UserRights",
- "fullType": "ttn.lorawan.v3.IsConfiguration.UserRights",
+ "type": "OAuthAccessToken",
+ "longType": "OAuthAccessToken",
+ "fullType": "ttn.lorawan.v3.OAuthAccessToken",
"ismap": false,
- "isoneof": false,
- "oneofdecl": "",
+ "isoneof": true,
+ "oneofdecl": "access_method",
"defaultValue": ""
},
{
- "name": "user_login",
+ "name": "user_session",
+ "description": "Warning: A user authorized by session cookie will be granted all\ncurrent and future rights. When using this auth type, the respective\nhandlers need to ensure thorough CSRF and CORS protection using\nappropriate middleware.",
+ "label": "",
+ "type": "UserSession",
+ "longType": "UserSession",
+ "fullType": "ttn.lorawan.v3.UserSession",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "access_method",
+ "defaultValue": ""
+ },
+ {
+ "name": "gateway_token",
"description": "",
"label": "",
- "type": "UserLogin",
- "longType": "IsConfiguration.UserLogin",
- "fullType": "ttn.lorawan.v3.IsConfiguration.UserLogin",
+ "type": "GatewayToken",
+ "longType": "AuthInfoResponse.GatewayToken",
+ "fullType": "ttn.lorawan.v3.AuthInfoResponse.GatewayToken",
"ismap": false,
- "isoneof": false,
- "oneofdecl": "",
+ "isoneof": true,
+ "oneofdecl": "access_method",
"defaultValue": ""
},
{
- "name": "admin_rights",
+ "name": "universal_rights",
"description": "",
"label": "",
- "type": "AdminRights",
- "longType": "IsConfiguration.AdminRights",
- "fullType": "ttn.lorawan.v3.IsConfiguration.AdminRights",
+ "type": "Rights",
+ "longType": "Rights",
+ "fullType": "ttn.lorawan.v3.Rights",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "collaborator_rights",
+ "name": "is_admin",
"description": "",
"label": "",
- "type": "CollaboratorRights",
- "longType": "IsConfiguration.CollaboratorRights",
- "fullType": "ttn.lorawan.v3.IsConfiguration.CollaboratorRights",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -25176,9 +25448,9 @@
]
},
{
- "name": "AdminRights",
- "longName": "IsConfiguration.AdminRights",
- "fullName": "ttn.lorawan.v3.IsConfiguration.AdminRights",
+ "name": "APIKeyAccess",
+ "longName": "AuthInfoResponse.APIKeyAccess",
+ "fullName": "ttn.lorawan.v3.AuthInfoResponse.APIKeyAccess",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -25186,47 +25458,51 @@
"extensions": [],
"fields": [
{
- "name": "all",
+ "name": "api_key",
"description": "",
"label": "",
- "type": "BoolValue",
- "longType": "google.protobuf.BoolValue",
- "fullType": "google.protobuf.BoolValue",
+ "type": "APIKey",
+ "longType": "APIKey",
+ "fullType": "ttn.lorawan.v3.APIKey",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
- }
- ]
- },
- {
- "name": "CollaboratorRights",
- "longName": "IsConfiguration.CollaboratorRights",
- "fullName": "ttn.lorawan.v3.IsConfiguration.CollaboratorRights",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "message.required",
+ "value": true
+ }
+ ]
+ }
+ },
{
- "name": "set_others_as_contacts",
+ "name": "entity_ids",
"description": "",
"label": "",
- "type": "BoolValue",
- "longType": "google.protobuf.BoolValue",
- "fullType": "google.protobuf.BoolValue",
+ "type": "EntityIdentifiers",
+ "longType": "EntityIdentifiers",
+ "fullType": "ttn.lorawan.v3.EntityIdentifiers",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "message.required",
+ "value": true
+ }
+ ]
+ }
}
]
},
{
- "name": "EndDevicePicture",
- "longName": "IsConfiguration.EndDevicePicture",
- "fullName": "ttn.lorawan.v3.IsConfiguration.EndDevicePicture",
+ "name": "GatewayToken",
+ "longName": "AuthInfoResponse.GatewayToken",
+ "fullName": "ttn.lorawan.v3.AuthInfoResponse.GatewayToken",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -25234,14 +25510,237 @@
"extensions": [],
"fields": [
{
- "name": "disable_upload",
+ "name": "gateway_ids",
"description": "",
"label": "",
- "type": "BoolValue",
- "longType": "google.protobuf.BoolValue",
- "fullType": "google.protobuf.BoolValue",
- "ismap": false,
- "isoneof": false,
+ "type": "GatewayIdentifiers",
+ "longType": "GatewayIdentifiers",
+ "fullType": "ttn.lorawan.v3.GatewayIdentifiers",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "message.required",
+ "value": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "rights",
+ "description": "",
+ "label": "repeated",
+ "type": "Right",
+ "longType": "Right",
+ "fullType": "ttn.lorawan.v3.Right",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ }
+ ]
+ },
+ {
+ "name": "GetIsConfigurationRequest",
+ "longName": "GetIsConfigurationRequest",
+ "fullName": "ttn.lorawan.v3.GetIsConfigurationRequest",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": false,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": []
+ },
+ {
+ "name": "GetIsConfigurationResponse",
+ "longName": "GetIsConfigurationResponse",
+ "fullName": "ttn.lorawan.v3.GetIsConfigurationResponse",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "configuration",
+ "description": "",
+ "label": "",
+ "type": "IsConfiguration",
+ "longType": "IsConfiguration",
+ "fullType": "ttn.lorawan.v3.IsConfiguration",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ }
+ ]
+ },
+ {
+ "name": "IsConfiguration",
+ "longName": "IsConfiguration",
+ "fullName": "ttn.lorawan.v3.IsConfiguration",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "user_registration",
+ "description": "",
+ "label": "",
+ "type": "UserRegistration",
+ "longType": "IsConfiguration.UserRegistration",
+ "fullType": "ttn.lorawan.v3.IsConfiguration.UserRegistration",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "profile_picture",
+ "description": "",
+ "label": "",
+ "type": "ProfilePicture",
+ "longType": "IsConfiguration.ProfilePicture",
+ "fullType": "ttn.lorawan.v3.IsConfiguration.ProfilePicture",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "end_device_picture",
+ "description": "",
+ "label": "",
+ "type": "EndDevicePicture",
+ "longType": "IsConfiguration.EndDevicePicture",
+ "fullType": "ttn.lorawan.v3.IsConfiguration.EndDevicePicture",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "user_rights",
+ "description": "",
+ "label": "",
+ "type": "UserRights",
+ "longType": "IsConfiguration.UserRights",
+ "fullType": "ttn.lorawan.v3.IsConfiguration.UserRights",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "user_login",
+ "description": "",
+ "label": "",
+ "type": "UserLogin",
+ "longType": "IsConfiguration.UserLogin",
+ "fullType": "ttn.lorawan.v3.IsConfiguration.UserLogin",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "admin_rights",
+ "description": "",
+ "label": "",
+ "type": "AdminRights",
+ "longType": "IsConfiguration.AdminRights",
+ "fullType": "ttn.lorawan.v3.IsConfiguration.AdminRights",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "collaborator_rights",
+ "description": "",
+ "label": "",
+ "type": "CollaboratorRights",
+ "longType": "IsConfiguration.CollaboratorRights",
+ "fullType": "ttn.lorawan.v3.IsConfiguration.CollaboratorRights",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ }
+ ]
+ },
+ {
+ "name": "AdminRights",
+ "longName": "IsConfiguration.AdminRights",
+ "fullName": "ttn.lorawan.v3.IsConfiguration.AdminRights",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "all",
+ "description": "",
+ "label": "",
+ "type": "BoolValue",
+ "longType": "google.protobuf.BoolValue",
+ "fullType": "google.protobuf.BoolValue",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ }
+ ]
+ },
+ {
+ "name": "CollaboratorRights",
+ "longName": "IsConfiguration.CollaboratorRights",
+ "fullName": "ttn.lorawan.v3.IsConfiguration.CollaboratorRights",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "set_others_as_contacts",
+ "description": "",
+ "label": "",
+ "type": "BoolValue",
+ "longType": "google.protobuf.BoolValue",
+ "fullType": "google.protobuf.BoolValue",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ }
+ ]
+ },
+ {
+ "name": "EndDevicePicture",
+ "longName": "IsConfiguration.EndDevicePicture",
+ "fullName": "ttn.lorawan.v3.IsConfiguration.EndDevicePicture",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "disable_upload",
+ "description": "",
+ "label": "",
+ "type": "BoolValue",
+ "longType": "google.protobuf.BoolValue",
+ "fullType": "google.protobuf.BoolValue",
+ "ismap": false,
+ "isoneof": false,
"oneofdecl": "",
"defaultValue": ""
}
@@ -27509,2235 +28008,3504 @@
"responseStreaming": false
},
{
- "name": "EncryptRejoinAccept",
- "description": "Encrypt the rejoin-accept payload.",
- "requestType": "CryptoServicePayloadRequest",
- "requestLongType": "CryptoServicePayloadRequest",
- "requestFullType": "ttn.lorawan.v3.CryptoServicePayloadRequest",
- "requestStreaming": false,
- "responseType": "CryptoServicePayloadResponse",
- "responseLongType": "CryptoServicePayloadResponse",
- "responseFullType": "ttn.lorawan.v3.CryptoServicePayloadResponse",
- "responseStreaming": false
+ "name": "EncryptRejoinAccept",
+ "description": "Encrypt the rejoin-accept payload.",
+ "requestType": "CryptoServicePayloadRequest",
+ "requestLongType": "CryptoServicePayloadRequest",
+ "requestFullType": "ttn.lorawan.v3.CryptoServicePayloadRequest",
+ "requestStreaming": false,
+ "responseType": "CryptoServicePayloadResponse",
+ "responseLongType": "CryptoServicePayloadResponse",
+ "responseFullType": "ttn.lorawan.v3.CryptoServicePayloadResponse",
+ "responseStreaming": false
+ },
+ {
+ "name": "DeriveNwkSKeys",
+ "description": "Derive network session keys (NwkSKey, or FNwkSKey, SNwkSKey and NwkSEncKey)",
+ "requestType": "DeriveSessionKeysRequest",
+ "requestLongType": "DeriveSessionKeysRequest",
+ "requestFullType": "ttn.lorawan.v3.DeriveSessionKeysRequest",
+ "requestStreaming": false,
+ "responseType": "NwkSKeysResponse",
+ "responseLongType": "NwkSKeysResponse",
+ "responseFullType": "ttn.lorawan.v3.NwkSKeysResponse",
+ "responseStreaming": false
+ },
+ {
+ "name": "GetNwkKey",
+ "description": "Get the NwkKey. Crypto Servers may return status code FAILED_PRECONDITION when root keys are not exposed.",
+ "requestType": "GetRootKeysRequest",
+ "requestLongType": "GetRootKeysRequest",
+ "requestFullType": "ttn.lorawan.v3.GetRootKeysRequest",
+ "requestStreaming": false,
+ "responseType": "KeyEnvelope",
+ "responseLongType": "KeyEnvelope",
+ "responseFullType": "ttn.lorawan.v3.KeyEnvelope",
+ "responseStreaming": false
+ }
+ ]
+ },
+ {
+ "name": "NsJs",
+ "longName": "NsJs",
+ "fullName": "ttn.lorawan.v3.NsJs",
+ "description": "The NsJs service connects a Network Server to a Join Server.",
+ "methods": [
+ {
+ "name": "HandleJoin",
+ "description": "Handle a join-request message.",
+ "requestType": "JoinRequest",
+ "requestLongType": "JoinRequest",
+ "requestFullType": "ttn.lorawan.v3.JoinRequest",
+ "requestStreaming": false,
+ "responseType": "JoinResponse",
+ "responseLongType": "JoinResponse",
+ "responseFullType": "ttn.lorawan.v3.JoinResponse",
+ "responseStreaming": false
+ },
+ {
+ "name": "GetNwkSKeys",
+ "description": "Request the network session keys for a particular session.",
+ "requestType": "SessionKeyRequest",
+ "requestLongType": "SessionKeyRequest",
+ "requestFullType": "ttn.lorawan.v3.SessionKeyRequest",
+ "requestStreaming": false,
+ "responseType": "NwkSKeysResponse",
+ "responseLongType": "NwkSKeysResponse",
+ "responseFullType": "ttn.lorawan.v3.NwkSKeysResponse",
+ "responseStreaming": false
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "ttn/lorawan/v3/keys.proto",
+ "description": "",
+ "package": "ttn.lorawan.v3",
+ "hasEnums": false,
+ "hasExtensions": false,
+ "hasMessages": true,
+ "hasServices": false,
+ "enums": [],
+ "extensions": [],
+ "messages": [
+ {
+ "name": "KeyEnvelope",
+ "longName": "KeyEnvelope",
+ "fullName": "ttn.lorawan.v3.KeyEnvelope",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "key",
+ "description": "The unencrypted AES key.",
+ "label": "",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "bytes.len",
+ "value": 16
+ }
+ ]
+ }
+ },
+ {
+ "name": "kek_label",
+ "description": "The label of the RFC 3394 key-encryption-key (KEK) that was used to encrypt the key.",
+ "label": "",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "string.max_len",
+ "value": 2048
+ }
+ ]
+ }
+ },
+ {
+ "name": "encrypted_key",
+ "description": "",
+ "label": "",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "bytes.max_len",
+ "value": 1024
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "RootKeys",
+ "longName": "RootKeys",
+ "fullName": "ttn.lorawan.v3.RootKeys",
+ "description": "Root keys for a LoRaWAN device.\nThese are stored on the Join Server.",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "root_key_id",
+ "description": "Join Server issued identifier for the root keys.",
+ "label": "",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "string.max_len",
+ "value": 2048
+ }
+ ]
+ }
+ },
+ {
+ "name": "app_key",
+ "description": "The (encrypted) Application Key.",
+ "label": "",
+ "type": "KeyEnvelope",
+ "longType": "KeyEnvelope",
+ "fullType": "ttn.lorawan.v3.KeyEnvelope",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "nwk_key",
+ "description": "The (encrypted) Network Key.",
+ "label": "",
+ "type": "KeyEnvelope",
+ "longType": "KeyEnvelope",
+ "fullType": "ttn.lorawan.v3.KeyEnvelope",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ }
+ ]
+ },
+ {
+ "name": "SessionKeys",
+ "longName": "SessionKeys",
+ "fullName": "ttn.lorawan.v3.SessionKeys",
+ "description": "Session keys for a LoRaWAN session.\nOnly the components for which the keys were meant, will have the key-encryption-key (KEK) to decrypt the individual keys.",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "session_key_id",
+ "description": "Join Server issued identifier for the session keys.\nThis ID can be used to request the keys from the Join Server in case the are lost.",
+ "label": "",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "bytes.max_len",
+ "value": 2048
+ }
+ ]
+ }
+ },
+ {
+ "name": "f_nwk_s_int_key",
+ "description": "The (encrypted) Forwarding Network Session Integrity Key (or Network Session Key in 1.0 compatibility mode).\nThis key is stored by the (forwarding) Network Server.",
+ "label": "",
+ "type": "KeyEnvelope",
+ "longType": "KeyEnvelope",
+ "fullType": "ttn.lorawan.v3.KeyEnvelope",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "s_nwk_s_int_key",
+ "description": "The (encrypted) Serving Network Session Integrity Key.\nThis key is stored by the (serving) Network Server.",
+ "label": "",
+ "type": "KeyEnvelope",
+ "longType": "KeyEnvelope",
+ "fullType": "ttn.lorawan.v3.KeyEnvelope",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "nwk_s_enc_key",
+ "description": "The (encrypted) Network Session Encryption Key.\nThis key is stored by the (serving) Network Server.",
+ "label": "",
+ "type": "KeyEnvelope",
+ "longType": "KeyEnvelope",
+ "fullType": "ttn.lorawan.v3.KeyEnvelope",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "app_s_key",
+ "description": "The (encrypted) Application Session Key.\nThis key is stored by the Application Server.",
+ "label": "",
+ "type": "KeyEnvelope",
+ "longType": "KeyEnvelope",
+ "fullType": "ttn.lorawan.v3.KeyEnvelope",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ }
+ ]
+ }
+ ],
+ "services": []
+ },
+ {
+ "name": "ttn/lorawan/v3/lorawan.proto",
+ "description": "",
+ "package": "ttn.lorawan.v3",
+ "hasEnums": true,
+ "hasExtensions": false,
+ "hasMessages": true,
+ "hasServices": false,
+ "enums": [
+ {
+ "name": "ADRAckDelayExponent",
+ "longName": "ADRAckDelayExponent",
+ "fullName": "ttn.lorawan.v3.ADRAckDelayExponent",
+ "description": "",
+ "values": [
+ {
+ "name": "ADR_ACK_DELAY_1",
+ "number": "0",
+ "description": ""
+ },
+ {
+ "name": "ADR_ACK_DELAY_2",
+ "number": "1",
+ "description": ""
+ },
+ {
+ "name": "ADR_ACK_DELAY_4",
+ "number": "2",
+ "description": ""
+ },
+ {
+ "name": "ADR_ACK_DELAY_8",
+ "number": "3",
+ "description": ""
+ },
+ {
+ "name": "ADR_ACK_DELAY_16",
+ "number": "4",
+ "description": ""
+ },
+ {
+ "name": "ADR_ACK_DELAY_32",
+ "number": "5",
+ "description": ""
+ },
+ {
+ "name": "ADR_ACK_DELAY_64",
+ "number": "6",
+ "description": ""
+ },
+ {
+ "name": "ADR_ACK_DELAY_128",
+ "number": "7",
+ "description": ""
+ },
+ {
+ "name": "ADR_ACK_DELAY_256",
+ "number": "8",
+ "description": ""
+ },
+ {
+ "name": "ADR_ACK_DELAY_512",
+ "number": "9",
+ "description": ""
+ },
+ {
+ "name": "ADR_ACK_DELAY_1024",
+ "number": "10",
+ "description": ""
+ },
+ {
+ "name": "ADR_ACK_DELAY_2048",
+ "number": "11",
+ "description": ""
+ },
+ {
+ "name": "ADR_ACK_DELAY_4096",
+ "number": "12",
+ "description": ""
+ },
+ {
+ "name": "ADR_ACK_DELAY_8192",
+ "number": "13",
+ "description": ""
+ },
+ {
+ "name": "ADR_ACK_DELAY_16384",
+ "number": "14",
+ "description": ""
+ },
+ {
+ "name": "ADR_ACK_DELAY_32768",
+ "number": "15",
+ "description": ""
+ }
+ ]
+ },
+ {
+ "name": "ADRAckLimitExponent",
+ "longName": "ADRAckLimitExponent",
+ "fullName": "ttn.lorawan.v3.ADRAckLimitExponent",
+ "description": "",
+ "values": [
+ {
+ "name": "ADR_ACK_LIMIT_1",
+ "number": "0",
+ "description": ""
+ },
+ {
+ "name": "ADR_ACK_LIMIT_2",
+ "number": "1",
+ "description": ""
+ },
+ {
+ "name": "ADR_ACK_LIMIT_4",
+ "number": "2",
+ "description": ""
+ },
+ {
+ "name": "ADR_ACK_LIMIT_8",
+ "number": "3",
+ "description": ""
+ },
+ {
+ "name": "ADR_ACK_LIMIT_16",
+ "number": "4",
+ "description": ""
+ },
+ {
+ "name": "ADR_ACK_LIMIT_32",
+ "number": "5",
+ "description": ""
+ },
+ {
+ "name": "ADR_ACK_LIMIT_64",
+ "number": "6",
+ "description": ""
+ },
+ {
+ "name": "ADR_ACK_LIMIT_128",
+ "number": "7",
+ "description": ""
+ },
+ {
+ "name": "ADR_ACK_LIMIT_256",
+ "number": "8",
+ "description": ""
+ },
+ {
+ "name": "ADR_ACK_LIMIT_512",
+ "number": "9",
+ "description": ""
+ },
+ {
+ "name": "ADR_ACK_LIMIT_1024",
+ "number": "10",
+ "description": ""
+ },
+ {
+ "name": "ADR_ACK_LIMIT_2048",
+ "number": "11",
+ "description": ""
+ },
+ {
+ "name": "ADR_ACK_LIMIT_4096",
+ "number": "12",
+ "description": ""
+ },
+ {
+ "name": "ADR_ACK_LIMIT_8192",
+ "number": "13",
+ "description": ""
+ },
+ {
+ "name": "ADR_ACK_LIMIT_16384",
+ "number": "14",
+ "description": ""
+ },
+ {
+ "name": "ADR_ACK_LIMIT_32768",
+ "number": "15",
+ "description": ""
+ }
+ ]
+ },
+ {
+ "name": "AggregatedDutyCycle",
+ "longName": "AggregatedDutyCycle",
+ "fullName": "ttn.lorawan.v3.AggregatedDutyCycle",
+ "description": "",
+ "values": [
+ {
+ "name": "DUTY_CYCLE_1",
+ "number": "0",
+ "description": "100%."
+ },
+ {
+ "name": "DUTY_CYCLE_2",
+ "number": "1",
+ "description": "50%."
+ },
+ {
+ "name": "DUTY_CYCLE_4",
+ "number": "2",
+ "description": "25%."
+ },
+ {
+ "name": "DUTY_CYCLE_8",
+ "number": "3",
+ "description": "12.5%."
+ },
+ {
+ "name": "DUTY_CYCLE_16",
+ "number": "4",
+ "description": "6.25%."
+ },
+ {
+ "name": "DUTY_CYCLE_32",
+ "number": "5",
+ "description": "3.125%."
+ },
+ {
+ "name": "DUTY_CYCLE_64",
+ "number": "6",
+ "description": "1.5625%."
+ },
+ {
+ "name": "DUTY_CYCLE_128",
+ "number": "7",
+ "description": "Roughly 0.781%."
+ },
+ {
+ "name": "DUTY_CYCLE_256",
+ "number": "8",
+ "description": "Roughly 0.390%."
+ },
+ {
+ "name": "DUTY_CYCLE_512",
+ "number": "9",
+ "description": "Roughly 0.195%."
+ },
+ {
+ "name": "DUTY_CYCLE_1024",
+ "number": "10",
+ "description": "Roughly 0.098%."
+ },
+ {
+ "name": "DUTY_CYCLE_2048",
+ "number": "11",
+ "description": "Roughly 0.049%."
+ },
+ {
+ "name": "DUTY_CYCLE_4096",
+ "number": "12",
+ "description": "Roughly 0.024%."
+ },
+ {
+ "name": "DUTY_CYCLE_8192",
+ "number": "13",
+ "description": "Roughly 0.012%."
+ },
+ {
+ "name": "DUTY_CYCLE_16384",
+ "number": "14",
+ "description": "Roughly 0.006%."
+ },
+ {
+ "name": "DUTY_CYCLE_32768",
+ "number": "15",
+ "description": "Roughly 0.003%."
+ }
+ ]
+ },
+ {
+ "name": "CFListType",
+ "longName": "CFListType",
+ "fullName": "ttn.lorawan.v3.CFListType",
+ "description": "",
+ "values": [
+ {
+ "name": "FREQUENCIES",
+ "number": "0",
+ "description": ""
+ },
+ {
+ "name": "CHANNEL_MASKS",
+ "number": "1",
+ "description": ""
+ }
+ ]
+ },
+ {
+ "name": "Class",
+ "longName": "Class",
+ "fullName": "ttn.lorawan.v3.Class",
+ "description": "",
+ "values": [
+ {
+ "name": "CLASS_A",
+ "number": "0",
+ "description": ""
+ },
+ {
+ "name": "CLASS_B",
+ "number": "1",
+ "description": ""
+ },
+ {
+ "name": "CLASS_C",
+ "number": "2",
+ "description": ""
+ }
+ ]
+ },
+ {
+ "name": "DataRateIndex",
+ "longName": "DataRateIndex",
+ "fullName": "ttn.lorawan.v3.DataRateIndex",
+ "description": "",
+ "values": [
+ {
+ "name": "DATA_RATE_0",
+ "number": "0",
+ "description": ""
+ },
+ {
+ "name": "DATA_RATE_1",
+ "number": "1",
+ "description": ""
+ },
+ {
+ "name": "DATA_RATE_2",
+ "number": "2",
+ "description": ""
+ },
+ {
+ "name": "DATA_RATE_3",
+ "number": "3",
+ "description": ""
+ },
+ {
+ "name": "DATA_RATE_4",
+ "number": "4",
+ "description": ""
+ },
+ {
+ "name": "DATA_RATE_5",
+ "number": "5",
+ "description": ""
+ },
+ {
+ "name": "DATA_RATE_6",
+ "number": "6",
+ "description": ""
+ },
+ {
+ "name": "DATA_RATE_7",
+ "number": "7",
+ "description": ""
+ },
+ {
+ "name": "DATA_RATE_8",
+ "number": "8",
+ "description": ""
+ },
+ {
+ "name": "DATA_RATE_9",
+ "number": "9",
+ "description": ""
+ },
+ {
+ "name": "DATA_RATE_10",
+ "number": "10",
+ "description": ""
+ },
+ {
+ "name": "DATA_RATE_11",
+ "number": "11",
+ "description": ""
+ },
+ {
+ "name": "DATA_RATE_12",
+ "number": "12",
+ "description": ""
+ },
+ {
+ "name": "DATA_RATE_13",
+ "number": "13",
+ "description": ""
+ },
+ {
+ "name": "DATA_RATE_14",
+ "number": "14",
+ "description": ""
+ },
+ {
+ "name": "DATA_RATE_15",
+ "number": "15",
+ "description": ""
+ }
+ ]
+ },
+ {
+ "name": "DataRateOffset",
+ "longName": "DataRateOffset",
+ "fullName": "ttn.lorawan.v3.DataRateOffset",
+ "description": "",
+ "values": [
+ {
+ "name": "DATA_RATE_OFFSET_0",
+ "number": "0",
+ "description": ""
+ },
+ {
+ "name": "DATA_RATE_OFFSET_1",
+ "number": "1",
+ "description": ""
+ },
+ {
+ "name": "DATA_RATE_OFFSET_2",
+ "number": "2",
+ "description": ""
+ },
+ {
+ "name": "DATA_RATE_OFFSET_3",
+ "number": "3",
+ "description": ""
+ },
+ {
+ "name": "DATA_RATE_OFFSET_4",
+ "number": "4",
+ "description": ""
+ },
+ {
+ "name": "DATA_RATE_OFFSET_5",
+ "number": "5",
+ "description": ""
+ },
+ {
+ "name": "DATA_RATE_OFFSET_6",
+ "number": "6",
+ "description": ""
+ },
+ {
+ "name": "DATA_RATE_OFFSET_7",
+ "number": "7",
+ "description": ""
+ }
+ ]
+ },
+ {
+ "name": "DeviceEIRP",
+ "longName": "DeviceEIRP",
+ "fullName": "ttn.lorawan.v3.DeviceEIRP",
+ "description": "",
+ "values": [
+ {
+ "name": "DEVICE_EIRP_8",
+ "number": "0",
+ "description": "8 dBm."
+ },
+ {
+ "name": "DEVICE_EIRP_10",
+ "number": "1",
+ "description": "10 dBm."
+ },
+ {
+ "name": "DEVICE_EIRP_12",
+ "number": "2",
+ "description": "12 dBm."
+ },
+ {
+ "name": "DEVICE_EIRP_13",
+ "number": "3",
+ "description": "13 dBm."
+ },
+ {
+ "name": "DEVICE_EIRP_14",
+ "number": "4",
+ "description": "14 dBm."
+ },
+ {
+ "name": "DEVICE_EIRP_16",
+ "number": "5",
+ "description": "16 dBm."
+ },
+ {
+ "name": "DEVICE_EIRP_18",
+ "number": "6",
+ "description": "18 dBm."
+ },
+ {
+ "name": "DEVICE_EIRP_20",
+ "number": "7",
+ "description": "20 dBm."
+ },
+ {
+ "name": "DEVICE_EIRP_21",
+ "number": "8",
+ "description": "21 dBm."
+ },
+ {
+ "name": "DEVICE_EIRP_24",
+ "number": "9",
+ "description": "24 dBm."
+ },
+ {
+ "name": "DEVICE_EIRP_26",
+ "number": "10",
+ "description": "26 dBm."
+ },
+ {
+ "name": "DEVICE_EIRP_27",
+ "number": "11",
+ "description": "27 dBm."
+ },
+ {
+ "name": "DEVICE_EIRP_29",
+ "number": "12",
+ "description": "29 dBm."
+ },
+ {
+ "name": "DEVICE_EIRP_30",
+ "number": "13",
+ "description": "30 dBm."
+ },
+ {
+ "name": "DEVICE_EIRP_33",
+ "number": "14",
+ "description": "33 dBm."
+ },
+ {
+ "name": "DEVICE_EIRP_36",
+ "number": "15",
+ "description": "36 dBm."
+ }
+ ]
+ },
+ {
+ "name": "JoinRequestType",
+ "longName": "JoinRequestType",
+ "fullName": "ttn.lorawan.v3.JoinRequestType",
+ "description": "",
+ "values": [
+ {
+ "name": "REJOIN_CONTEXT",
+ "number": "0",
+ "description": "Resets DevAddr, Session Keys, Frame Counters, Radio Parameters."
+ },
+ {
+ "name": "REJOIN_SESSION",
+ "number": "1",
+ "description": "Equivalent to the initial JoinRequest."
+ },
+ {
+ "name": "REJOIN_KEYS",
+ "number": "2",
+ "description": "Resets DevAddr, Session Keys, Frame Counters, while keeping the Radio Parameters."
+ },
+ {
+ "name": "JOIN",
+ "number": "255",
+ "description": "Normal join-request."
+ }
+ ]
+ },
+ {
+ "name": "MACCommandIdentifier",
+ "longName": "MACCommandIdentifier",
+ "fullName": "ttn.lorawan.v3.MACCommandIdentifier",
+ "description": "",
+ "values": [
+ {
+ "name": "CID_RFU_0",
+ "number": "0",
+ "description": ""
+ },
+ {
+ "name": "CID_RESET",
+ "number": "1",
+ "description": ""
+ },
+ {
+ "name": "CID_LINK_CHECK",
+ "number": "2",
+ "description": ""
+ },
+ {
+ "name": "CID_LINK_ADR",
+ "number": "3",
+ "description": ""
+ },
+ {
+ "name": "CID_DUTY_CYCLE",
+ "number": "4",
+ "description": ""
+ },
+ {
+ "name": "CID_RX_PARAM_SETUP",
+ "number": "5",
+ "description": ""
+ },
+ {
+ "name": "CID_DEV_STATUS",
+ "number": "6",
+ "description": ""
+ },
+ {
+ "name": "CID_NEW_CHANNEL",
+ "number": "7",
+ "description": ""
+ },
+ {
+ "name": "CID_RX_TIMING_SETUP",
+ "number": "8",
+ "description": ""
+ },
+ {
+ "name": "CID_TX_PARAM_SETUP",
+ "number": "9",
+ "description": ""
+ },
+ {
+ "name": "CID_DL_CHANNEL",
+ "number": "10",
+ "description": ""
+ },
+ {
+ "name": "CID_REKEY",
+ "number": "11",
+ "description": ""
+ },
+ {
+ "name": "CID_ADR_PARAM_SETUP",
+ "number": "12",
+ "description": ""
+ },
+ {
+ "name": "CID_DEVICE_TIME",
+ "number": "13",
+ "description": ""
+ },
+ {
+ "name": "CID_FORCE_REJOIN",
+ "number": "14",
+ "description": ""
+ },
+ {
+ "name": "CID_REJOIN_PARAM_SETUP",
+ "number": "15",
+ "description": ""
+ },
+ {
+ "name": "CID_PING_SLOT_INFO",
+ "number": "16",
+ "description": ""
+ },
+ {
+ "name": "CID_PING_SLOT_CHANNEL",
+ "number": "17",
+ "description": ""
+ },
+ {
+ "name": "CID_BEACON_TIMING",
+ "number": "18",
+ "description": "Deprecated"
+ },
+ {
+ "name": "CID_BEACON_FREQ",
+ "number": "19",
+ "description": ""
+ },
+ {
+ "name": "CID_DEVICE_MODE",
+ "number": "32",
+ "description": ""
+ },
+ {
+ "name": "CID_RELAY_CONF",
+ "number": "64",
+ "description": ""
+ },
+ {
+ "name": "CID_RELAY_END_DEVICE_CONF",
+ "number": "65",
+ "description": ""
+ },
+ {
+ "name": "CID_RELAY_FILTER_LIST",
+ "number": "66",
+ "description": ""
+ },
+ {
+ "name": "CID_RELAY_UPDATE_UPLINK_LIST",
+ "number": "67",
+ "description": ""
+ },
+ {
+ "name": "CID_RELAY_CTRL_UPLINK_LIST",
+ "number": "68",
+ "description": ""
},
{
- "name": "DeriveNwkSKeys",
- "description": "Derive network session keys (NwkSKey, or FNwkSKey, SNwkSKey and NwkSEncKey)",
- "requestType": "DeriveSessionKeysRequest",
- "requestLongType": "DeriveSessionKeysRequest",
- "requestFullType": "ttn.lorawan.v3.DeriveSessionKeysRequest",
- "requestStreaming": false,
- "responseType": "NwkSKeysResponse",
- "responseLongType": "NwkSKeysResponse",
- "responseFullType": "ttn.lorawan.v3.NwkSKeysResponse",
- "responseStreaming": false
+ "name": "CID_RELAY_CONFIGURE_FWD_LIMIT",
+ "number": "69",
+ "description": ""
},
{
- "name": "GetNwkKey",
- "description": "Get the NwkKey. Crypto Servers may return status code FAILED_PRECONDITION when root keys are not exposed.",
- "requestType": "GetRootKeysRequest",
- "requestLongType": "GetRootKeysRequest",
- "requestFullType": "ttn.lorawan.v3.GetRootKeysRequest",
- "requestStreaming": false,
- "responseType": "KeyEnvelope",
- "responseLongType": "KeyEnvelope",
- "responseFullType": "ttn.lorawan.v3.KeyEnvelope",
- "responseStreaming": false
+ "name": "CID_RELAY_NOTIFY_NEW_END_DEVICE",
+ "number": "70",
+ "description": ""
}
]
},
{
- "name": "NsJs",
- "longName": "NsJs",
- "fullName": "ttn.lorawan.v3.NsJs",
- "description": "The NsJs service connects a Network Server to a Join Server.",
- "methods": [
+ "name": "MACVersion",
+ "longName": "MACVersion",
+ "fullName": "ttn.lorawan.v3.MACVersion",
+ "description": "",
+ "values": [
{
- "name": "HandleJoin",
- "description": "Handle a join-request message.",
- "requestType": "JoinRequest",
- "requestLongType": "JoinRequest",
- "requestFullType": "ttn.lorawan.v3.JoinRequest",
- "requestStreaming": false,
- "responseType": "JoinResponse",
- "responseLongType": "JoinResponse",
- "responseFullType": "ttn.lorawan.v3.JoinResponse",
- "responseStreaming": false
+ "name": "MAC_UNKNOWN",
+ "number": "0",
+ "description": ""
},
{
- "name": "GetNwkSKeys",
- "description": "Request the network session keys for a particular session.",
- "requestType": "SessionKeyRequest",
- "requestLongType": "SessionKeyRequest",
- "requestFullType": "ttn.lorawan.v3.SessionKeyRequest",
- "requestStreaming": false,
- "responseType": "NwkSKeysResponse",
- "responseLongType": "NwkSKeysResponse",
- "responseFullType": "ttn.lorawan.v3.NwkSKeysResponse",
- "responseStreaming": false
- }
- ]
- }
- ]
- },
- {
- "name": "ttn/lorawan/v3/keys.proto",
- "description": "",
- "package": "ttn.lorawan.v3",
- "hasEnums": false,
- "hasExtensions": false,
- "hasMessages": true,
- "hasServices": false,
- "enums": [],
- "extensions": [],
- "messages": [
- {
- "name": "KeyEnvelope",
- "longName": "KeyEnvelope",
- "fullName": "ttn.lorawan.v3.KeyEnvelope",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
- {
- "name": "key",
- "description": "The unencrypted AES key.",
- "label": "",
- "type": "bytes",
- "longType": "bytes",
- "fullType": "bytes",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "bytes.len",
- "value": 16
- }
- ]
- }
+ "name": "MAC_V1_0",
+ "number": "1",
+ "description": ""
},
{
- "name": "kek_label",
- "description": "The label of the RFC 3394 key-encryption-key (KEK) that was used to encrypt the key.",
- "label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "string.max_len",
- "value": 2048
- }
- ]
- }
+ "name": "MAC_V1_0_1",
+ "number": "2",
+ "description": ""
},
{
- "name": "encrypted_key",
- "description": "",
- "label": "",
- "type": "bytes",
- "longType": "bytes",
- "fullType": "bytes",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "bytes.max_len",
- "value": 1024
- }
- ]
- }
- }
- ]
- },
- {
- "name": "RootKeys",
- "longName": "RootKeys",
- "fullName": "ttn.lorawan.v3.RootKeys",
- "description": "Root keys for a LoRaWAN device.\nThese are stored on the Join Server.",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ "name": "MAC_V1_0_2",
+ "number": "3",
+ "description": ""
+ },
{
- "name": "root_key_id",
- "description": "Join Server issued identifier for the root keys.",
- "label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "string.max_len",
- "value": 2048
- }
- ]
- }
+ "name": "MAC_V1_1",
+ "number": "4",
+ "description": ""
},
{
- "name": "app_key",
- "description": "The (encrypted) Application Key.",
- "label": "",
- "type": "KeyEnvelope",
- "longType": "KeyEnvelope",
- "fullType": "ttn.lorawan.v3.KeyEnvelope",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
+ "name": "MAC_V1_0_3",
+ "number": "5",
+ "description": ""
},
{
- "name": "nwk_key",
- "description": "The (encrypted) Network Key.",
- "label": "",
- "type": "KeyEnvelope",
- "longType": "KeyEnvelope",
- "fullType": "ttn.lorawan.v3.KeyEnvelope",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
+ "name": "MAC_V1_0_4",
+ "number": "6",
+ "description": ""
}
]
},
{
- "name": "SessionKeys",
- "longName": "SessionKeys",
- "fullName": "ttn.lorawan.v3.SessionKeys",
- "description": "Session keys for a LoRaWAN session.\nOnly the components for which the keys were meant, will have the key-encryption-key (KEK) to decrypt the individual keys.",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ "name": "MType",
+ "longName": "MType",
+ "fullName": "ttn.lorawan.v3.MType",
+ "description": "",
+ "values": [
{
- "name": "session_key_id",
- "description": "Join Server issued identifier for the session keys.\nThis ID can be used to request the keys from the Join Server in case the are lost.",
- "label": "",
- "type": "bytes",
- "longType": "bytes",
- "fullType": "bytes",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "bytes.max_len",
- "value": 2048
- }
- ]
- }
+ "name": "JOIN_REQUEST",
+ "number": "0",
+ "description": ""
+ },
+ {
+ "name": "JOIN_ACCEPT",
+ "number": "1",
+ "description": ""
},
{
- "name": "f_nwk_s_int_key",
- "description": "The (encrypted) Forwarding Network Session Integrity Key (or Network Session Key in 1.0 compatibility mode).\nThis key is stored by the (forwarding) Network Server.",
- "label": "",
- "type": "KeyEnvelope",
- "longType": "KeyEnvelope",
- "fullType": "ttn.lorawan.v3.KeyEnvelope",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
+ "name": "UNCONFIRMED_UP",
+ "number": "2",
+ "description": ""
},
{
- "name": "s_nwk_s_int_key",
- "description": "The (encrypted) Serving Network Session Integrity Key.\nThis key is stored by the (serving) Network Server.",
- "label": "",
- "type": "KeyEnvelope",
- "longType": "KeyEnvelope",
- "fullType": "ttn.lorawan.v3.KeyEnvelope",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
+ "name": "UNCONFIRMED_DOWN",
+ "number": "3",
+ "description": ""
},
{
- "name": "nwk_s_enc_key",
- "description": "The (encrypted) Network Session Encryption Key.\nThis key is stored by the (serving) Network Server.",
- "label": "",
- "type": "KeyEnvelope",
- "longType": "KeyEnvelope",
- "fullType": "ttn.lorawan.v3.KeyEnvelope",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
+ "name": "CONFIRMED_UP",
+ "number": "4",
+ "description": ""
},
{
- "name": "app_s_key",
- "description": "The (encrypted) Application Session Key.\nThis key is stored by the Application Server.",
- "label": "",
- "type": "KeyEnvelope",
- "longType": "KeyEnvelope",
- "fullType": "ttn.lorawan.v3.KeyEnvelope",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
+ "name": "CONFIRMED_DOWN",
+ "number": "5",
+ "description": ""
+ },
+ {
+ "name": "REJOIN_REQUEST",
+ "number": "6",
+ "description": ""
+ },
+ {
+ "name": "PROPRIETARY",
+ "number": "7",
+ "description": ""
}
]
- }
- ],
- "services": []
- },
- {
- "name": "ttn/lorawan/v3/lorawan.proto",
- "description": "",
- "package": "ttn.lorawan.v3",
- "hasEnums": true,
- "hasExtensions": false,
- "hasMessages": true,
- "hasServices": false,
- "enums": [
+ },
{
- "name": "ADRAckDelayExponent",
- "longName": "ADRAckDelayExponent",
- "fullName": "ttn.lorawan.v3.ADRAckDelayExponent",
+ "name": "Major",
+ "longName": "Major",
+ "fullName": "ttn.lorawan.v3.Major",
"description": "",
"values": [
{
- "name": "ADR_ACK_DELAY_1",
+ "name": "LORAWAN_R1",
+ "number": "0",
+ "description": ""
+ }
+ ]
+ },
+ {
+ "name": "Minor",
+ "longName": "Minor",
+ "fullName": "ttn.lorawan.v3.Minor",
+ "description": "",
+ "values": [
+ {
+ "name": "MINOR_RFU_0",
"number": "0",
"description": ""
},
{
- "name": "ADR_ACK_DELAY_2",
+ "name": "MINOR_1",
"number": "1",
"description": ""
},
{
- "name": "ADR_ACK_DELAY_4",
+ "name": "MINOR_RFU_2",
"number": "2",
"description": ""
},
{
- "name": "ADR_ACK_DELAY_8",
+ "name": "MINOR_RFU_3",
"number": "3",
"description": ""
},
{
- "name": "ADR_ACK_DELAY_16",
+ "name": "MINOR_RFU_4",
"number": "4",
"description": ""
},
{
- "name": "ADR_ACK_DELAY_32",
+ "name": "MINOR_RFU_5",
"number": "5",
"description": ""
},
{
- "name": "ADR_ACK_DELAY_64",
+ "name": "MINOR_RFU_6",
"number": "6",
"description": ""
},
{
- "name": "ADR_ACK_DELAY_128",
+ "name": "MINOR_RFU_7",
"number": "7",
"description": ""
},
{
- "name": "ADR_ACK_DELAY_256",
+ "name": "MINOR_RFU_8",
"number": "8",
"description": ""
},
{
- "name": "ADR_ACK_DELAY_512",
+ "name": "MINOR_RFU_9",
"number": "9",
"description": ""
},
{
- "name": "ADR_ACK_DELAY_1024",
+ "name": "MINOR_RFU_10",
"number": "10",
"description": ""
},
{
- "name": "ADR_ACK_DELAY_2048",
+ "name": "MINOR_RFU_11",
"number": "11",
"description": ""
},
{
- "name": "ADR_ACK_DELAY_4096",
+ "name": "MINOR_RFU_12",
"number": "12",
"description": ""
},
{
- "name": "ADR_ACK_DELAY_8192",
+ "name": "MINOR_RFU_13",
"number": "13",
"description": ""
},
{
- "name": "ADR_ACK_DELAY_16384",
+ "name": "MINOR_RFU_14",
"number": "14",
"description": ""
},
{
- "name": "ADR_ACK_DELAY_32768",
+ "name": "MINOR_RFU_15",
"number": "15",
"description": ""
}
]
},
{
- "name": "ADRAckLimitExponent",
- "longName": "ADRAckLimitExponent",
- "fullName": "ttn.lorawan.v3.ADRAckLimitExponent",
+ "name": "PHYVersion",
+ "longName": "PHYVersion",
+ "fullName": "ttn.lorawan.v3.PHYVersion",
"description": "",
"values": [
{
- "name": "ADR_ACK_LIMIT_1",
+ "name": "PHY_UNKNOWN",
"number": "0",
"description": ""
},
{
- "name": "ADR_ACK_LIMIT_2",
+ "name": "PHY_V1_0",
"number": "1",
"description": ""
},
{
- "name": "ADR_ACK_LIMIT_4",
+ "name": "TS001_V1_0",
+ "number": "1",
+ "description": ""
+ },
+ {
+ "name": "PHY_V1_0_1",
"number": "2",
"description": ""
},
{
- "name": "ADR_ACK_LIMIT_8",
+ "name": "TS001_V1_0_1",
+ "number": "2",
+ "description": ""
+ },
+ {
+ "name": "PHY_V1_0_2_REV_A",
"number": "3",
"description": ""
},
{
- "name": "ADR_ACK_LIMIT_16",
+ "name": "RP001_V1_0_2",
+ "number": "3",
+ "description": ""
+ },
+ {
+ "name": "PHY_V1_0_2_REV_B",
"number": "4",
"description": ""
},
{
- "name": "ADR_ACK_LIMIT_32",
+ "name": "RP001_V1_0_2_REV_B",
+ "number": "4",
+ "description": ""
+ },
+ {
+ "name": "PHY_V1_1_REV_A",
"number": "5",
"description": ""
},
{
- "name": "ADR_ACK_LIMIT_64",
+ "name": "RP001_V1_1_REV_A",
+ "number": "5",
+ "description": ""
+ },
+ {
+ "name": "PHY_V1_1_REV_B",
"number": "6",
"description": ""
},
{
- "name": "ADR_ACK_LIMIT_128",
+ "name": "RP001_V1_1_REV_B",
+ "number": "6",
+ "description": ""
+ },
+ {
+ "name": "PHY_V1_0_3_REV_A",
"number": "7",
"description": ""
},
{
- "name": "ADR_ACK_LIMIT_256",
+ "name": "RP001_V1_0_3_REV_A",
+ "number": "7",
+ "description": ""
+ },
+ {
+ "name": "RP002_V1_0_0",
"number": "8",
"description": ""
},
{
- "name": "ADR_ACK_LIMIT_512",
+ "name": "RP002_V1_0_1",
"number": "9",
"description": ""
},
{
- "name": "ADR_ACK_LIMIT_1024",
+ "name": "RP002_V1_0_2",
"number": "10",
"description": ""
},
{
- "name": "ADR_ACK_LIMIT_2048",
+ "name": "RP002_V1_0_3",
"number": "11",
"description": ""
},
{
- "name": "ADR_ACK_LIMIT_4096",
+ "name": "RP002_V1_0_4",
"number": "12",
"description": ""
+ }
+ ]
+ },
+ {
+ "name": "PingSlotPeriod",
+ "longName": "PingSlotPeriod",
+ "fullName": "ttn.lorawan.v3.PingSlotPeriod",
+ "description": "",
+ "values": [
+ {
+ "name": "PING_EVERY_1S",
+ "number": "0",
+ "description": "Every second."
},
{
- "name": "ADR_ACK_LIMIT_8192",
- "number": "13",
- "description": ""
+ "name": "PING_EVERY_2S",
+ "number": "1",
+ "description": "Every 2 seconds."
},
{
- "name": "ADR_ACK_LIMIT_16384",
- "number": "14",
- "description": ""
+ "name": "PING_EVERY_4S",
+ "number": "2",
+ "description": "Every 4 seconds."
},
{
- "name": "ADR_ACK_LIMIT_32768",
- "number": "15",
- "description": ""
+ "name": "PING_EVERY_8S",
+ "number": "3",
+ "description": "Every 8 seconds."
+ },
+ {
+ "name": "PING_EVERY_16S",
+ "number": "4",
+ "description": "Every 16 seconds."
+ },
+ {
+ "name": "PING_EVERY_32S",
+ "number": "5",
+ "description": "Every 32 seconds."
+ },
+ {
+ "name": "PING_EVERY_64S",
+ "number": "6",
+ "description": "Every 64 seconds."
+ },
+ {
+ "name": "PING_EVERY_128S",
+ "number": "7",
+ "description": "Every 128 seconds."
}
]
},
{
- "name": "AggregatedDutyCycle",
- "longName": "AggregatedDutyCycle",
- "fullName": "ttn.lorawan.v3.AggregatedDutyCycle",
+ "name": "RejoinCountExponent",
+ "longName": "RejoinCountExponent",
+ "fullName": "ttn.lorawan.v3.RejoinCountExponent",
"description": "",
"values": [
{
- "name": "DUTY_CYCLE_1",
+ "name": "REJOIN_COUNT_16",
"number": "0",
- "description": "100%."
+ "description": ""
},
{
- "name": "DUTY_CYCLE_2",
+ "name": "REJOIN_COUNT_32",
"number": "1",
- "description": "50%."
+ "description": ""
},
{
- "name": "DUTY_CYCLE_4",
+ "name": "REJOIN_COUNT_64",
"number": "2",
- "description": "25%."
+ "description": ""
},
{
- "name": "DUTY_CYCLE_8",
+ "name": "REJOIN_COUNT_128",
"number": "3",
- "description": "12.5%."
+ "description": ""
},
{
- "name": "DUTY_CYCLE_16",
+ "name": "REJOIN_COUNT_256",
"number": "4",
- "description": "6.25%."
+ "description": ""
},
{
- "name": "DUTY_CYCLE_32",
+ "name": "REJOIN_COUNT_512",
"number": "5",
- "description": "3.125%."
+ "description": ""
},
{
- "name": "DUTY_CYCLE_64",
+ "name": "REJOIN_COUNT_1024",
"number": "6",
- "description": "1.5625%."
+ "description": ""
},
{
- "name": "DUTY_CYCLE_128",
+ "name": "REJOIN_COUNT_2048",
"number": "7",
- "description": "Roughly 0.781%."
+ "description": ""
},
{
- "name": "DUTY_CYCLE_256",
+ "name": "REJOIN_COUNT_4096",
"number": "8",
- "description": "Roughly 0.390%."
+ "description": ""
},
{
- "name": "DUTY_CYCLE_512",
+ "name": "REJOIN_COUNT_8192",
"number": "9",
- "description": "Roughly 0.195%."
+ "description": ""
},
{
- "name": "DUTY_CYCLE_1024",
+ "name": "REJOIN_COUNT_16384",
"number": "10",
- "description": "Roughly 0.098%."
+ "description": ""
},
{
- "name": "DUTY_CYCLE_2048",
+ "name": "REJOIN_COUNT_32768",
"number": "11",
- "description": "Roughly 0.049%."
+ "description": ""
},
{
- "name": "DUTY_CYCLE_4096",
+ "name": "REJOIN_COUNT_65536",
"number": "12",
- "description": "Roughly 0.024%."
+ "description": ""
},
{
- "name": "DUTY_CYCLE_8192",
+ "name": "REJOIN_COUNT_131072",
"number": "13",
- "description": "Roughly 0.012%."
+ "description": ""
},
{
- "name": "DUTY_CYCLE_16384",
+ "name": "REJOIN_COUNT_262144",
"number": "14",
- "description": "Roughly 0.006%."
+ "description": ""
},
{
- "name": "DUTY_CYCLE_32768",
+ "name": "REJOIN_COUNT_524288",
"number": "15",
- "description": "Roughly 0.003%."
+ "description": ""
}
]
},
{
- "name": "CFListType",
- "longName": "CFListType",
- "fullName": "ttn.lorawan.v3.CFListType",
+ "name": "RejoinPeriodExponent",
+ "longName": "RejoinPeriodExponent",
+ "fullName": "ttn.lorawan.v3.RejoinPeriodExponent",
"description": "",
"values": [
{
- "name": "FREQUENCIES",
+ "name": "REJOIN_PERIOD_0",
"number": "0",
- "description": ""
+ "description": "Every 32 to 64 seconds."
},
{
- "name": "CHANNEL_MASKS",
+ "name": "REJOIN_PERIOD_1",
"number": "1",
- "description": ""
+ "description": "Every 64 to 96 seconds."
+ },
+ {
+ "name": "REJOIN_PERIOD_2",
+ "number": "2",
+ "description": "Every 128 to 160 seconds."
+ },
+ {
+ "name": "REJOIN_PERIOD_3",
+ "number": "3",
+ "description": "Every 256 to 288 seconds."
+ },
+ {
+ "name": "REJOIN_PERIOD_4",
+ "number": "4",
+ "description": "Every 512 to 544 seconds."
+ },
+ {
+ "name": "REJOIN_PERIOD_5",
+ "number": "5",
+ "description": "Every 1024 to 1056 seconds."
+ },
+ {
+ "name": "REJOIN_PERIOD_6",
+ "number": "6",
+ "description": "Every 2048 to 2080 seconds."
+ },
+ {
+ "name": "REJOIN_PERIOD_7",
+ "number": "7",
+ "description": "Every 4096 to 4128 seconds."
}
]
},
{
- "name": "Class",
- "longName": "Class",
- "fullName": "ttn.lorawan.v3.Class",
+ "name": "RejoinRequestType",
+ "longName": "RejoinRequestType",
+ "fullName": "ttn.lorawan.v3.RejoinRequestType",
"description": "",
"values": [
{
- "name": "CLASS_A",
+ "name": "CONTEXT",
"number": "0",
- "description": ""
+ "description": "Resets DevAddr, Session Keys, Frame Counters, Radio Parameters."
},
{
- "name": "CLASS_B",
+ "name": "SESSION",
"number": "1",
- "description": ""
+ "description": "Equivalent to the initial JoinRequest."
},
{
- "name": "CLASS_C",
+ "name": "KEYS",
"number": "2",
- "description": ""
+ "description": "Resets DevAddr, Session Keys, Frame Counters, while keeping the Radio Parameters."
}
]
},
{
- "name": "DataRateIndex",
- "longName": "DataRateIndex",
- "fullName": "ttn.lorawan.v3.DataRateIndex",
+ "name": "RejoinTimeExponent",
+ "longName": "RejoinTimeExponent",
+ "fullName": "ttn.lorawan.v3.RejoinTimeExponent",
"description": "",
"values": [
{
- "name": "DATA_RATE_0",
+ "name": "REJOIN_TIME_0",
"number": "0",
- "description": ""
+ "description": "Every ~17.1 minutes."
},
{
- "name": "DATA_RATE_1",
+ "name": "REJOIN_TIME_1",
"number": "1",
- "description": ""
+ "description": "Every ~34.1 minutes."
},
{
- "name": "DATA_RATE_2",
+ "name": "REJOIN_TIME_2",
"number": "2",
- "description": ""
+ "description": "Every ~1.1 hours."
},
{
- "name": "DATA_RATE_3",
+ "name": "REJOIN_TIME_3",
"number": "3",
- "description": ""
+ "description": "Every ~2.3 hours."
},
{
- "name": "DATA_RATE_4",
+ "name": "REJOIN_TIME_4",
"number": "4",
- "description": ""
+ "description": "Every ~4.6 hours."
},
{
- "name": "DATA_RATE_5",
+ "name": "REJOIN_TIME_5",
"number": "5",
- "description": ""
+ "description": "Every ~9.1 hours."
},
{
- "name": "DATA_RATE_6",
+ "name": "REJOIN_TIME_6",
"number": "6",
- "description": ""
+ "description": "Every ~18.2 hours."
},
{
- "name": "DATA_RATE_7",
+ "name": "REJOIN_TIME_7",
"number": "7",
- "description": ""
+ "description": "Every ~1.5 days."
},
{
- "name": "DATA_RATE_8",
+ "name": "REJOIN_TIME_8",
"number": "8",
- "description": ""
+ "description": "Every ~3.0 days."
},
{
- "name": "DATA_RATE_9",
+ "name": "REJOIN_TIME_9",
"number": "9",
- "description": ""
+ "description": "Every ~6.1 days."
},
{
- "name": "DATA_RATE_10",
+ "name": "REJOIN_TIME_10",
"number": "10",
- "description": ""
+ "description": "Every ~12.1 days."
},
{
- "name": "DATA_RATE_11",
+ "name": "REJOIN_TIME_11",
"number": "11",
- "description": ""
+ "description": "Every ~3.5 weeks."
},
{
- "name": "DATA_RATE_12",
+ "name": "REJOIN_TIME_12",
"number": "12",
- "description": ""
+ "description": "Every ~1.6 months."
},
{
- "name": "DATA_RATE_13",
+ "name": "REJOIN_TIME_13",
"number": "13",
- "description": ""
+ "description": "Every ~3.2 months."
},
{
- "name": "DATA_RATE_14",
+ "name": "REJOIN_TIME_14",
"number": "14",
- "description": ""
+ "description": "Every ~6.4 months."
},
{
- "name": "DATA_RATE_15",
+ "name": "REJOIN_TIME_15",
"number": "15",
- "description": ""
+ "description": "Every ~1.1 year."
}
]
},
{
- "name": "DataRateOffset",
- "longName": "DataRateOffset",
- "fullName": "ttn.lorawan.v3.DataRateOffset",
+ "name": "RelayCADPeriodicity",
+ "longName": "RelayCADPeriodicity",
+ "fullName": "ttn.lorawan.v3.RelayCADPeriodicity",
"description": "",
"values": [
{
- "name": "DATA_RATE_OFFSET_0",
+ "name": "RELAY_CAD_PERIODICITY_1_SECOND",
"number": "0",
"description": ""
},
{
- "name": "DATA_RATE_OFFSET_1",
+ "name": "RELAY_CAD_PERIODICITY_500_MILLISECONDS",
"number": "1",
"description": ""
},
{
- "name": "DATA_RATE_OFFSET_2",
+ "name": "RELAY_CAD_PERIODICITY_250_MILLISECONDS",
"number": "2",
"description": ""
},
{
- "name": "DATA_RATE_OFFSET_3",
+ "name": "RELAY_CAD_PERIODICITY_100_MILLISECONDS",
"number": "3",
"description": ""
},
{
- "name": "DATA_RATE_OFFSET_4",
+ "name": "RELAY_CAD_PERIODICITY_50_MILLISECONDS",
"number": "4",
"description": ""
},
{
- "name": "DATA_RATE_OFFSET_5",
+ "name": "RELAY_CAD_PERIODICITY_20_MILLISECONDS",
"number": "5",
- "description": ""
- },
+ "description": "sic"
+ }
+ ]
+ },
+ {
+ "name": "RelayCtrlUplinkListAction",
+ "longName": "RelayCtrlUplinkListAction",
+ "fullName": "ttn.lorawan.v3.RelayCtrlUplinkListAction",
+ "description": "",
+ "values": [
{
- "name": "DATA_RATE_OFFSET_6",
- "number": "6",
+ "name": "RELAY_CTRL_UPLINK_LIST_ACTION_READ_W_F_CNT",
+ "number": "0",
"description": ""
},
{
- "name": "DATA_RATE_OFFSET_7",
- "number": "7",
+ "name": "RELAY_CTRL_UPLINK_LIST_ACTION_REMOVE_TRUSTED_END_DEVICE",
+ "number": "1",
"description": ""
}
]
},
{
- "name": "DeviceEIRP",
- "longName": "DeviceEIRP",
- "fullName": "ttn.lorawan.v3.DeviceEIRP",
+ "name": "RelayLimitBucketSize",
+ "longName": "RelayLimitBucketSize",
+ "fullName": "ttn.lorawan.v3.RelayLimitBucketSize",
"description": "",
"values": [
{
- "name": "DEVICE_EIRP_8",
+ "name": "RELAY_LIMIT_BUCKET_SIZE_1",
"number": "0",
- "description": "8 dBm."
+ "description": ""
},
{
- "name": "DEVICE_EIRP_10",
+ "name": "RELAY_LIMIT_BUCKET_SIZE_2",
"number": "1",
- "description": "10 dBm."
+ "description": ""
},
{
- "name": "DEVICE_EIRP_12",
+ "name": "RELAY_LIMIT_BUCKET_SIZE_4",
"number": "2",
- "description": "12 dBm."
+ "description": ""
},
{
- "name": "DEVICE_EIRP_13",
+ "name": "RELAY_LIMIT_BUCKET_SIZE_12",
"number": "3",
- "description": "13 dBm."
- },
- {
- "name": "DEVICE_EIRP_14",
- "number": "4",
- "description": "14 dBm."
- },
- {
- "name": "DEVICE_EIRP_16",
- "number": "5",
- "description": "16 dBm."
- },
+ "description": "sic"
+ }
+ ]
+ },
+ {
+ "name": "RelayResetLimitCounter",
+ "longName": "RelayResetLimitCounter",
+ "fullName": "ttn.lorawan.v3.RelayResetLimitCounter",
+ "description": "",
+ "values": [
{
- "name": "DEVICE_EIRP_18",
- "number": "6",
- "description": "18 dBm."
+ "name": "RELAY_RESET_LIMIT_COUNTER_ZERO",
+ "number": "0",
+ "description": ""
},
{
- "name": "DEVICE_EIRP_20",
- "number": "7",
- "description": "20 dBm."
+ "name": "RELAY_RESET_LIMIT_COUNTER_RELOAD_RATE",
+ "number": "1",
+ "description": ""
},
{
- "name": "DEVICE_EIRP_21",
- "number": "8",
- "description": "21 dBm."
+ "name": "RELAY_RESET_LIMIT_COUNTER_MAX_VALUE",
+ "number": "2",
+ "description": ""
},
{
- "name": "DEVICE_EIRP_24",
- "number": "9",
- "description": "24 dBm."
- },
+ "name": "RELAY_RESET_LIMIT_COUNTER_NO_RESET",
+ "number": "3",
+ "description": ""
+ }
+ ]
+ },
+ {
+ "name": "RelaySecondChAckOffset",
+ "longName": "RelaySecondChAckOffset",
+ "fullName": "ttn.lorawan.v3.RelaySecondChAckOffset",
+ "description": "",
+ "values": [
{
- "name": "DEVICE_EIRP_26",
- "number": "10",
- "description": "26 dBm."
+ "name": "RELAY_SECOND_CH_ACK_OFFSET_0",
+ "number": "0",
+ "description": "0 kHz"
},
{
- "name": "DEVICE_EIRP_27",
- "number": "11",
- "description": "27 dBm."
+ "name": "RELAY_SECOND_CH_ACK_OFFSET_200",
+ "number": "1",
+ "description": "200 kHz"
},
{
- "name": "DEVICE_EIRP_29",
- "number": "12",
- "description": "29 dBm."
+ "name": "RELAY_SECOND_CH_ACK_OFFSET_400",
+ "number": "2",
+ "description": "400 kHz"
},
{
- "name": "DEVICE_EIRP_30",
- "number": "13",
- "description": "30 dBm."
+ "name": "RELAY_SECOND_CH_ACK_OFFSET_800",
+ "number": "3",
+ "description": "800 kHz"
},
{
- "name": "DEVICE_EIRP_33",
- "number": "14",
- "description": "33 dBm."
+ "name": "RELAY_SECOND_CH_ACK_OFFSET_1600",
+ "number": "4",
+ "description": "1.6 MHz"
},
{
- "name": "DEVICE_EIRP_36",
- "number": "15",
- "description": "36 dBm."
+ "name": "RELAY_SECOND_CH_ACK_OFFSET_3200",
+ "number": "5",
+ "description": "3.2 MHz"
}
]
},
{
- "name": "JoinRequestType",
- "longName": "JoinRequestType",
- "fullName": "ttn.lorawan.v3.JoinRequestType",
+ "name": "RelaySmartEnableLevel",
+ "longName": "RelaySmartEnableLevel",
+ "fullName": "ttn.lorawan.v3.RelaySmartEnableLevel",
"description": "",
"values": [
{
- "name": "REJOIN_CONTEXT",
+ "name": "RELAY_SMART_ENABLE_LEVEL_8",
"number": "0",
- "description": "Resets DevAddr, Session Keys, Frame Counters, Radio Parameters."
+ "description": ""
},
{
- "name": "REJOIN_SESSION",
+ "name": "RELAY_SMART_ENABLE_LEVEL_16",
"number": "1",
- "description": "Equivalent to the initial JoinRequest."
+ "description": ""
},
{
- "name": "REJOIN_KEYS",
+ "name": "RELAY_SMART_ENABLE_LEVEL_32",
"number": "2",
- "description": "Resets DevAddr, Session Keys, Frame Counters, while keeping the Radio Parameters."
+ "description": ""
},
{
- "name": "JOIN",
- "number": "255",
- "description": "Normal join-request."
+ "name": "RELAY_SMART_ENABLE_LEVEL_64",
+ "number": "3",
+ "description": ""
}
]
},
{
- "name": "MACCommandIdentifier",
- "longName": "MACCommandIdentifier",
- "fullName": "ttn.lorawan.v3.MACCommandIdentifier",
+ "name": "RelayWORChannel",
+ "longName": "RelayWORChannel",
+ "fullName": "ttn.lorawan.v3.RelayWORChannel",
"description": "",
"values": [
{
- "name": "CID_RFU_0",
+ "name": "RELAY_WOR_CHANNEL_DEFAULT",
"number": "0",
"description": ""
},
{
- "name": "CID_RESET",
+ "name": "RELAY_WOR_CHANNEL_SECONDARY",
"number": "1",
"description": ""
+ }
+ ]
+ },
+ {
+ "name": "RxDelay",
+ "longName": "RxDelay",
+ "fullName": "ttn.lorawan.v3.RxDelay",
+ "description": "",
+ "values": [
+ {
+ "name": "RX_DELAY_0",
+ "number": "0",
+ "description": "1 second."
},
{
- "name": "CID_LINK_CHECK",
+ "name": "RX_DELAY_1",
+ "number": "1",
+ "description": "1 second."
+ },
+ {
+ "name": "RX_DELAY_2",
"number": "2",
- "description": ""
+ "description": "2 seconds."
},
{
- "name": "CID_LINK_ADR",
+ "name": "RX_DELAY_3",
"number": "3",
- "description": ""
+ "description": "3 seconds."
},
{
- "name": "CID_DUTY_CYCLE",
+ "name": "RX_DELAY_4",
"number": "4",
- "description": ""
+ "description": "4 seconds."
},
{
- "name": "CID_RX_PARAM_SETUP",
+ "name": "RX_DELAY_5",
"number": "5",
- "description": ""
+ "description": "5 seconds."
},
{
- "name": "CID_DEV_STATUS",
+ "name": "RX_DELAY_6",
"number": "6",
- "description": ""
+ "description": "6 seconds."
},
{
- "name": "CID_NEW_CHANNEL",
+ "name": "RX_DELAY_7",
"number": "7",
- "description": ""
+ "description": "7 seconds."
},
{
- "name": "CID_RX_TIMING_SETUP",
+ "name": "RX_DELAY_8",
"number": "8",
- "description": ""
+ "description": "8 seconds."
},
{
- "name": "CID_TX_PARAM_SETUP",
+ "name": "RX_DELAY_9",
"number": "9",
- "description": ""
+ "description": "9 seconds."
},
{
- "name": "CID_DL_CHANNEL",
+ "name": "RX_DELAY_10",
"number": "10",
- "description": ""
+ "description": "10 seconds."
},
{
- "name": "CID_REKEY",
+ "name": "RX_DELAY_11",
"number": "11",
- "description": ""
+ "description": "11 seconds."
},
{
- "name": "CID_ADR_PARAM_SETUP",
+ "name": "RX_DELAY_12",
"number": "12",
- "description": ""
+ "description": "12 seconds."
},
{
- "name": "CID_DEVICE_TIME",
+ "name": "RX_DELAY_13",
"number": "13",
- "description": ""
+ "description": "13 seconds."
},
{
- "name": "CID_FORCE_REJOIN",
+ "name": "RX_DELAY_14",
"number": "14",
- "description": ""
+ "description": "14 seconds."
},
{
- "name": "CID_REJOIN_PARAM_SETUP",
+ "name": "RX_DELAY_15",
"number": "15",
+ "description": "15 seconds."
+ }
+ ]
+ },
+ {
+ "name": "TxSchedulePriority",
+ "longName": "TxSchedulePriority",
+ "fullName": "ttn.lorawan.v3.TxSchedulePriority",
+ "description": "",
+ "values": [
+ {
+ "name": "LOWEST",
+ "number": "0",
"description": ""
},
{
- "name": "CID_PING_SLOT_INFO",
- "number": "16",
+ "name": "LOW",
+ "number": "1",
"description": ""
},
{
- "name": "CID_PING_SLOT_CHANNEL",
- "number": "17",
+ "name": "BELOW_NORMAL",
+ "number": "2",
"description": ""
},
{
- "name": "CID_BEACON_TIMING",
- "number": "18",
- "description": "Deprecated"
+ "name": "NORMAL",
+ "number": "3",
+ "description": ""
},
{
- "name": "CID_BEACON_FREQ",
- "number": "19",
+ "name": "ABOVE_NORMAL",
+ "number": "4",
"description": ""
},
{
- "name": "CID_DEVICE_MODE",
- "number": "32",
+ "name": "HIGH",
+ "number": "5",
+ "description": ""
+ },
+ {
+ "name": "HIGHEST",
+ "number": "6",
"description": ""
}
]
+ }
+ ],
+ "extensions": [],
+ "messages": [
+ {
+ "name": "ADRAckDelayExponentValue",
+ "longName": "ADRAckDelayExponentValue",
+ "fullName": "ttn.lorawan.v3.ADRAckDelayExponentValue",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "value",
+ "description": "",
+ "label": "",
+ "type": "ADRAckDelayExponent",
+ "longType": "ADRAckDelayExponent",
+ "fullType": "ttn.lorawan.v3.ADRAckDelayExponent",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "enum.defined_only",
+ "value": true
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "ADRAckLimitExponentValue",
+ "longName": "ADRAckLimitExponentValue",
+ "fullName": "ttn.lorawan.v3.ADRAckLimitExponentValue",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "value",
+ "description": "",
+ "label": "",
+ "type": "ADRAckLimitExponent",
+ "longType": "ADRAckLimitExponent",
+ "fullType": "ttn.lorawan.v3.ADRAckLimitExponent",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "enum.defined_only",
+ "value": true
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "AggregatedDutyCycleValue",
+ "longName": "AggregatedDutyCycleValue",
+ "fullName": "ttn.lorawan.v3.AggregatedDutyCycleValue",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "value",
+ "description": "",
+ "label": "",
+ "type": "AggregatedDutyCycle",
+ "longType": "AggregatedDutyCycle",
+ "fullType": "ttn.lorawan.v3.AggregatedDutyCycle",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "enum.defined_only",
+ "value": true
+ }
+ ]
+ }
+ }
+ ]
},
{
- "name": "MACVersion",
- "longName": "MACVersion",
- "fullName": "ttn.lorawan.v3.MACVersion",
+ "name": "CFList",
+ "longName": "CFList",
+ "fullName": "ttn.lorawan.v3.CFList",
"description": "",
- "values": [
- {
- "name": "MAC_UNKNOWN",
- "number": "0",
- "description": ""
- },
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "MAC_V1_0",
- "number": "1",
- "description": ""
+ "name": "type",
+ "description": "",
+ "label": "",
+ "type": "CFListType",
+ "longType": "CFListType",
+ "fullType": "ttn.lorawan.v3.CFListType",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "enum.defined_only",
+ "value": true
+ }
+ ]
+ }
},
{
- "name": "MAC_V1_0_1",
- "number": "2",
- "description": ""
+ "name": "freq",
+ "description": "Frequencies to be broadcasted, in hecto-Hz.\nThese values are broadcasted as 24 bits unsigned integers.\nThis field should not contain default values.",
+ "label": "repeated",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
},
{
- "name": "MAC_V1_0_2",
- "number": "3",
- "description": ""
- },
+ "name": "ch_masks",
+ "description": "ChMasks controlling the channels to be used.\nLength of this field must be equal to the amount of uplink channels\ndefined by the selected frequency plan.",
+ "label": "repeated",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ }
+ ]
+ },
+ {
+ "name": "ClassBCGatewayIdentifiers",
+ "longName": "ClassBCGatewayIdentifiers",
+ "fullName": "ttn.lorawan.v3.ClassBCGatewayIdentifiers",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "MAC_V1_1",
- "number": "4",
- "description": ""
+ "name": "gateway_ids",
+ "description": "",
+ "label": "",
+ "type": "GatewayIdentifiers",
+ "longType": "GatewayIdentifiers",
+ "fullType": "ttn.lorawan.v3.GatewayIdentifiers",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "message.required",
+ "value": true
+ }
+ ]
+ }
},
{
- "name": "MAC_V1_0_3",
- "number": "5",
- "description": ""
+ "name": "antenna_index",
+ "description": "",
+ "label": "",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
},
{
- "name": "MAC_V1_0_4",
- "number": "6",
- "description": ""
+ "name": "group_index",
+ "description": "",
+ "label": "",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
}
]
},
{
- "name": "MType",
- "longName": "MType",
- "fullName": "ttn.lorawan.v3.MType",
+ "name": "DLSettings",
+ "longName": "DLSettings",
+ "fullName": "ttn.lorawan.v3.DLSettings",
"description": "",
- "values": [
- {
- "name": "JOIN_REQUEST",
- "number": "0",
- "description": ""
- },
- {
- "name": "JOIN_ACCEPT",
- "number": "1",
- "description": ""
- },
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "UNCONFIRMED_UP",
- "number": "2",
- "description": ""
+ "name": "rx1_dr_offset",
+ "description": "",
+ "label": "",
+ "type": "DataRateOffset",
+ "longType": "DataRateOffset",
+ "fullType": "ttn.lorawan.v3.DataRateOffset",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "enum.defined_only",
+ "value": true
+ }
+ ]
+ }
},
{
- "name": "UNCONFIRMED_DOWN",
- "number": "3",
- "description": ""
+ "name": "rx2_dr",
+ "description": "",
+ "label": "",
+ "type": "DataRateIndex",
+ "longType": "DataRateIndex",
+ "fullType": "ttn.lorawan.v3.DataRateIndex",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "enum.defined_only",
+ "value": true
+ }
+ ]
+ }
},
{
- "name": "CONFIRMED_UP",
- "number": "4",
- "description": ""
- },
+ "name": "opt_neg",
+ "description": "OptNeg is set if Network Server implements LoRaWAN 1.1 or greater.",
+ "label": "",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ }
+ ]
+ },
+ {
+ "name": "DataRate",
+ "longName": "DataRate",
+ "fullName": "ttn.lorawan.v3.DataRate",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": true,
+ "extensions": [],
+ "fields": [
{
- "name": "CONFIRMED_DOWN",
- "number": "5",
- "description": ""
+ "name": "lora",
+ "description": "",
+ "label": "",
+ "type": "LoRaDataRate",
+ "longType": "LoRaDataRate",
+ "fullType": "ttn.lorawan.v3.LoRaDataRate",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "modulation",
+ "defaultValue": ""
},
{
- "name": "REJOIN_REQUEST",
- "number": "6",
- "description": ""
+ "name": "fsk",
+ "description": "",
+ "label": "",
+ "type": "FSKDataRate",
+ "longType": "FSKDataRate",
+ "fullType": "ttn.lorawan.v3.FSKDataRate",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "modulation",
+ "defaultValue": ""
},
{
- "name": "PROPRIETARY",
- "number": "7",
- "description": ""
+ "name": "lrfhss",
+ "description": "",
+ "label": "",
+ "type": "LRFHSSDataRate",
+ "longType": "LRFHSSDataRate",
+ "fullType": "ttn.lorawan.v3.LRFHSSDataRate",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "modulation",
+ "defaultValue": ""
}
]
},
{
- "name": "Major",
- "longName": "Major",
- "fullName": "ttn.lorawan.v3.Major",
+ "name": "DataRateIndexValue",
+ "longName": "DataRateIndexValue",
+ "fullName": "ttn.lorawan.v3.DataRateIndexValue",
"description": "",
- "values": [
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "LORAWAN_R1",
- "number": "0",
- "description": ""
+ "name": "value",
+ "description": "",
+ "label": "",
+ "type": "DataRateIndex",
+ "longType": "DataRateIndex",
+ "fullType": "ttn.lorawan.v3.DataRateIndex",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "enum.defined_only",
+ "value": true
+ }
+ ]
+ }
}
]
},
{
- "name": "Minor",
- "longName": "Minor",
- "fullName": "ttn.lorawan.v3.Minor",
+ "name": "DataRateOffsetValue",
+ "longName": "DataRateOffsetValue",
+ "fullName": "ttn.lorawan.v3.DataRateOffsetValue",
"description": "",
- "values": [
- {
- "name": "MINOR_RFU_0",
- "number": "0",
- "description": ""
- },
- {
- "name": "MINOR_1",
- "number": "1",
- "description": ""
- },
- {
- "name": "MINOR_RFU_2",
- "number": "2",
- "description": ""
- },
- {
- "name": "MINOR_RFU_3",
- "number": "3",
- "description": ""
- },
- {
- "name": "MINOR_RFU_4",
- "number": "4",
- "description": ""
- },
- {
- "name": "MINOR_RFU_5",
- "number": "5",
- "description": ""
- },
- {
- "name": "MINOR_RFU_6",
- "number": "6",
- "description": ""
- },
- {
- "name": "MINOR_RFU_7",
- "number": "7",
- "description": ""
- },
- {
- "name": "MINOR_RFU_8",
- "number": "8",
- "description": ""
- },
- {
- "name": "MINOR_RFU_9",
- "number": "9",
- "description": ""
- },
- {
- "name": "MINOR_RFU_10",
- "number": "10",
- "description": ""
- },
- {
- "name": "MINOR_RFU_11",
- "number": "11",
- "description": ""
- },
- {
- "name": "MINOR_RFU_12",
- "number": "12",
- "description": ""
- },
- {
- "name": "MINOR_RFU_13",
- "number": "13",
- "description": ""
- },
- {
- "name": "MINOR_RFU_14",
- "number": "14",
- "description": ""
- },
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "MINOR_RFU_15",
- "number": "15",
- "description": ""
+ "name": "value",
+ "description": "",
+ "label": "",
+ "type": "DataRateOffset",
+ "longType": "DataRateOffset",
+ "fullType": "ttn.lorawan.v3.DataRateOffset",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "enum.defined_only",
+ "value": true
+ }
+ ]
+ }
}
]
},
{
- "name": "PHYVersion",
- "longName": "PHYVersion",
- "fullName": "ttn.lorawan.v3.PHYVersion",
+ "name": "DeviceEIRPValue",
+ "longName": "DeviceEIRPValue",
+ "fullName": "ttn.lorawan.v3.DeviceEIRPValue",
"description": "",
- "values": [
- {
- "name": "PHY_UNKNOWN",
- "number": "0",
- "description": ""
- },
- {
- "name": "PHY_V1_0",
- "number": "1",
- "description": ""
- },
- {
- "name": "TS001_V1_0",
- "number": "1",
- "description": ""
- },
- {
- "name": "PHY_V1_0_1",
- "number": "2",
- "description": ""
- },
- {
- "name": "TS001_V1_0_1",
- "number": "2",
- "description": ""
- },
- {
- "name": "PHY_V1_0_2_REV_A",
- "number": "3",
- "description": ""
- },
- {
- "name": "RP001_V1_0_2",
- "number": "3",
- "description": ""
- },
- {
- "name": "PHY_V1_0_2_REV_B",
- "number": "4",
- "description": ""
- },
- {
- "name": "RP001_V1_0_2_REV_B",
- "number": "4",
- "description": ""
- },
- {
- "name": "PHY_V1_1_REV_A",
- "number": "5",
- "description": ""
- },
- {
- "name": "RP001_V1_1_REV_A",
- "number": "5",
- "description": ""
- },
- {
- "name": "PHY_V1_1_REV_B",
- "number": "6",
- "description": ""
- },
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "RP001_V1_1_REV_B",
- "number": "6",
- "description": ""
- },
+ "name": "value",
+ "description": "",
+ "label": "",
+ "type": "DeviceEIRP",
+ "longType": "DeviceEIRP",
+ "fullType": "ttn.lorawan.v3.DeviceEIRP",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "enum.defined_only",
+ "value": true
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "DownlinkPath",
+ "longName": "DownlinkPath",
+ "fullName": "ttn.lorawan.v3.DownlinkPath",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": true,
+ "extensions": [],
+ "fields": [
{
- "name": "PHY_V1_0_3_REV_A",
- "number": "7",
- "description": ""
+ "name": "uplink_token",
+ "description": "",
+ "label": "",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "path",
+ "defaultValue": ""
},
{
- "name": "RP001_V1_0_3_REV_A",
- "number": "7",
- "description": ""
- },
+ "name": "fixed",
+ "description": "",
+ "label": "",
+ "type": "GatewayAntennaIdentifiers",
+ "longType": "GatewayAntennaIdentifiers",
+ "fullType": "ttn.lorawan.v3.GatewayAntennaIdentifiers",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "path",
+ "defaultValue": ""
+ }
+ ]
+ },
+ {
+ "name": "FCtrl",
+ "longName": "FCtrl",
+ "fullName": "ttn.lorawan.v3.FCtrl",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "RP002_V1_0_0",
- "number": "8",
- "description": ""
+ "name": "adr",
+ "description": "",
+ "label": "",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
},
{
- "name": "RP002_V1_0_1",
- "number": "9",
- "description": ""
+ "name": "adr_ack_req",
+ "description": "Only on uplink.",
+ "label": "",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
},
{
- "name": "RP002_V1_0_2",
- "number": "10",
- "description": ""
+ "name": "ack",
+ "description": "",
+ "label": "",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
},
{
- "name": "RP002_V1_0_3",
- "number": "11",
- "description": ""
+ "name": "f_pending",
+ "description": "Only on downlink.",
+ "label": "",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
},
{
- "name": "RP002_V1_0_4",
- "number": "12",
- "description": ""
+ "name": "class_b",
+ "description": "Only on uplink.",
+ "label": "",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
}
]
},
{
- "name": "PingSlotPeriod",
- "longName": "PingSlotPeriod",
- "fullName": "ttn.lorawan.v3.PingSlotPeriod",
+ "name": "FHDR",
+ "longName": "FHDR",
+ "fullName": "ttn.lorawan.v3.FHDR",
"description": "",
- "values": [
- {
- "name": "PING_EVERY_1S",
- "number": "0",
- "description": "Every second."
- },
- {
- "name": "PING_EVERY_2S",
- "number": "1",
- "description": "Every 2 seconds."
- },
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "PING_EVERY_4S",
- "number": "2",
- "description": "Every 4 seconds."
+ "name": "dev_addr",
+ "description": "",
+ "label": "",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "bytes.len",
+ "value": 4
+ }
+ ]
+ }
},
{
- "name": "PING_EVERY_8S",
- "number": "3",
- "description": "Every 8 seconds."
+ "name": "f_ctrl",
+ "description": "",
+ "label": "",
+ "type": "FCtrl",
+ "longType": "FCtrl",
+ "fullType": "ttn.lorawan.v3.FCtrl",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "message.required",
+ "value": true
+ }
+ ]
+ }
},
{
- "name": "PING_EVERY_16S",
- "number": "4",
- "description": "Every 16 seconds."
+ "name": "f_cnt",
+ "description": "",
+ "label": "",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "uint32.lte",
+ "value": 65535
+ }
+ ]
+ }
},
{
- "name": "PING_EVERY_32S",
- "number": "5",
- "description": "Every 32 seconds."
- },
+ "name": "f_opts",
+ "description": "",
+ "label": "",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "bytes.max_len",
+ "value": 15
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "FSKDataRate",
+ "longName": "FSKDataRate",
+ "fullName": "ttn.lorawan.v3.FSKDataRate",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "PING_EVERY_64S",
- "number": "6",
- "description": "Every 64 seconds."
- },
+ "name": "bit_rate",
+ "description": "Bit rate (bps).",
+ "label": "",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ }
+ ]
+ },
+ {
+ "name": "FrequencyValue",
+ "longName": "FrequencyValue",
+ "fullName": "ttn.lorawan.v3.FrequencyValue",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "PING_EVERY_128S",
- "number": "7",
- "description": "Every 128 seconds."
+ "name": "value",
+ "description": "",
+ "label": "",
+ "type": "uint64",
+ "longType": "uint64",
+ "fullType": "uint64",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "uint64.gte",
+ "value": 100000
+ }
+ ]
+ }
}
]
},
{
- "name": "RejoinCountExponent",
- "longName": "RejoinCountExponent",
- "fullName": "ttn.lorawan.v3.RejoinCountExponent",
+ "name": "GatewayAntennaIdentifiers",
+ "longName": "GatewayAntennaIdentifiers",
+ "fullName": "ttn.lorawan.v3.GatewayAntennaIdentifiers",
"description": "",
- "values": [
- {
- "name": "REJOIN_COUNT_16",
- "number": "0",
- "description": ""
- },
- {
- "name": "REJOIN_COUNT_32",
- "number": "1",
- "description": ""
- },
- {
- "name": "REJOIN_COUNT_64",
- "number": "2",
- "description": ""
- },
- {
- "name": "REJOIN_COUNT_128",
- "number": "3",
- "description": ""
- },
- {
- "name": "REJOIN_COUNT_256",
- "number": "4",
- "description": ""
- },
- {
- "name": "REJOIN_COUNT_512",
- "number": "5",
- "description": ""
- },
- {
- "name": "REJOIN_COUNT_1024",
- "number": "6",
- "description": ""
- },
- {
- "name": "REJOIN_COUNT_2048",
- "number": "7",
- "description": ""
- },
- {
- "name": "REJOIN_COUNT_4096",
- "number": "8",
- "description": ""
- },
- {
- "name": "REJOIN_COUNT_8192",
- "number": "9",
- "description": ""
- },
- {
- "name": "REJOIN_COUNT_16384",
- "number": "10",
- "description": ""
- },
- {
- "name": "REJOIN_COUNT_32768",
- "number": "11",
- "description": ""
- },
- {
- "name": "REJOIN_COUNT_65536",
- "number": "12",
- "description": ""
- },
- {
- "name": "REJOIN_COUNT_131072",
- "number": "13",
- "description": ""
- },
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "REJOIN_COUNT_262144",
- "number": "14",
- "description": ""
+ "name": "gateway_ids",
+ "description": "",
+ "label": "",
+ "type": "GatewayIdentifiers",
+ "longType": "GatewayIdentifiers",
+ "fullType": "ttn.lorawan.v3.GatewayIdentifiers",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "message.required",
+ "value": true
+ }
+ ]
+ }
},
{
- "name": "REJOIN_COUNT_524288",
- "number": "15",
- "description": ""
+ "name": "antenna_index",
+ "description": "",
+ "label": "",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
}
]
},
{
- "name": "RejoinPeriodExponent",
- "longName": "RejoinPeriodExponent",
- "fullName": "ttn.lorawan.v3.RejoinPeriodExponent",
+ "name": "JoinAcceptPayload",
+ "longName": "JoinAcceptPayload",
+ "fullName": "ttn.lorawan.v3.JoinAcceptPayload",
"description": "",
- "values": [
- {
- "name": "REJOIN_PERIOD_0",
- "number": "0",
- "description": "Every 32 to 64 seconds."
- },
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "REJOIN_PERIOD_1",
- "number": "1",
- "description": "Every 64 to 96 seconds."
+ "name": "encrypted",
+ "description": "",
+ "label": "",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
},
{
- "name": "REJOIN_PERIOD_2",
- "number": "2",
- "description": "Every 128 to 160 seconds."
+ "name": "join_nonce",
+ "description": "",
+ "label": "",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "bytes.len",
+ "value": 3
+ }
+ ]
+ }
},
{
- "name": "REJOIN_PERIOD_3",
- "number": "3",
- "description": "Every 256 to 288 seconds."
+ "name": "net_id",
+ "description": "",
+ "label": "",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "bytes.len",
+ "value": 3
+ }
+ ]
+ }
},
{
- "name": "REJOIN_PERIOD_4",
- "number": "4",
- "description": "Every 512 to 544 seconds."
+ "name": "dev_addr",
+ "description": "",
+ "label": "",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "bytes.len",
+ "value": 4
+ }
+ ]
+ }
},
{
- "name": "REJOIN_PERIOD_5",
- "number": "5",
- "description": "Every 1024 to 1056 seconds."
+ "name": "dl_settings",
+ "description": "",
+ "label": "",
+ "type": "DLSettings",
+ "longType": "DLSettings",
+ "fullType": "ttn.lorawan.v3.DLSettings",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "message.required",
+ "value": true
+ }
+ ]
+ }
},
{
- "name": "REJOIN_PERIOD_6",
- "number": "6",
- "description": "Every 2048 to 2080 seconds."
+ "name": "rx_delay",
+ "description": "",
+ "label": "",
+ "type": "RxDelay",
+ "longType": "RxDelay",
+ "fullType": "ttn.lorawan.v3.RxDelay",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "enum.defined_only",
+ "value": true
+ }
+ ]
+ }
},
{
- "name": "REJOIN_PERIOD_7",
- "number": "7",
- "description": "Every 4096 to 4128 seconds."
+ "name": "cf_list",
+ "description": "",
+ "label": "",
+ "type": "CFList",
+ "longType": "CFList",
+ "fullType": "ttn.lorawan.v3.CFList",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
}
]
},
{
- "name": "RejoinRequestType",
- "longName": "RejoinRequestType",
- "fullName": "ttn.lorawan.v3.RejoinRequestType",
+ "name": "JoinRequestPayload",
+ "longName": "JoinRequestPayload",
+ "fullName": "ttn.lorawan.v3.JoinRequestPayload",
"description": "",
- "values": [
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "CONTEXT",
- "number": "0",
- "description": "Resets DevAddr, Session Keys, Frame Counters, Radio Parameters."
+ "name": "join_eui",
+ "description": "",
+ "label": "",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "bytes.len",
+ "value": 8
+ }
+ ]
+ }
},
{
- "name": "SESSION",
- "number": "1",
- "description": "Equivalent to the initial JoinRequest."
+ "name": "dev_eui",
+ "description": "",
+ "label": "",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "bytes.len",
+ "value": 8
+ }
+ ]
+ }
},
{
- "name": "KEYS",
- "number": "2",
- "description": "Resets DevAddr, Session Keys, Frame Counters, while keeping the Radio Parameters."
+ "name": "dev_nonce",
+ "description": "",
+ "label": "",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "bytes.len",
+ "value": 2
+ }
+ ]
+ }
}
]
},
{
- "name": "RejoinTimeExponent",
- "longName": "RejoinTimeExponent",
- "fullName": "ttn.lorawan.v3.RejoinTimeExponent",
+ "name": "LRFHSSDataRate",
+ "longName": "LRFHSSDataRate",
+ "fullName": "ttn.lorawan.v3.LRFHSSDataRate",
"description": "",
- "values": [
- {
- "name": "REJOIN_TIME_0",
- "number": "0",
- "description": "Every ~17.1 minutes."
- },
- {
- "name": "REJOIN_TIME_1",
- "number": "1",
- "description": "Every ~34.1 minutes."
- },
- {
- "name": "REJOIN_TIME_2",
- "number": "2",
- "description": "Every ~1.1 hours."
- },
- {
- "name": "REJOIN_TIME_3",
- "number": "3",
- "description": "Every ~2.3 hours."
- },
- {
- "name": "REJOIN_TIME_4",
- "number": "4",
- "description": "Every ~4.6 hours."
- },
- {
- "name": "REJOIN_TIME_5",
- "number": "5",
- "description": "Every ~9.1 hours."
- },
- {
- "name": "REJOIN_TIME_6",
- "number": "6",
- "description": "Every ~18.2 hours."
- },
- {
- "name": "REJOIN_TIME_7",
- "number": "7",
- "description": "Every ~1.5 days."
- },
- {
- "name": "REJOIN_TIME_8",
- "number": "8",
- "description": "Every ~3.0 days."
- },
- {
- "name": "REJOIN_TIME_9",
- "number": "9",
- "description": "Every ~6.1 days."
- },
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "REJOIN_TIME_10",
- "number": "10",
- "description": "Every ~12.1 days."
+ "name": "modulation_type",
+ "description": "",
+ "label": "",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
},
{
- "name": "REJOIN_TIME_11",
- "number": "11",
- "description": "Every ~3.5 weeks."
+ "name": "operating_channel_width",
+ "description": "Operating Channel Width (Hz).",
+ "label": "",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
},
{
- "name": "REJOIN_TIME_12",
- "number": "12",
- "description": "Every ~1.6 months."
- },
+ "name": "coding_rate",
+ "description": "",
+ "label": "",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ }
+ ]
+ },
+ {
+ "name": "LoRaDataRate",
+ "longName": "LoRaDataRate",
+ "fullName": "ttn.lorawan.v3.LoRaDataRate",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "REJOIN_TIME_13",
- "number": "13",
- "description": "Every ~3.2 months."
+ "name": "bandwidth",
+ "description": "Bandwidth (Hz).",
+ "label": "",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
},
{
- "name": "REJOIN_TIME_14",
- "number": "14",
- "description": "Every ~6.4 months."
+ "name": "spreading_factor",
+ "description": "",
+ "label": "",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
},
{
- "name": "REJOIN_TIME_15",
- "number": "15",
- "description": "Every ~1.1 year."
+ "name": "coding_rate",
+ "description": "",
+ "label": "",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
}
]
},
{
- "name": "RxDelay",
- "longName": "RxDelay",
- "fullName": "ttn.lorawan.v3.RxDelay",
+ "name": "MACCommand",
+ "longName": "MACCommand",
+ "fullName": "ttn.lorawan.v3.MACCommand",
"description": "",
- "values": [
- {
- "name": "RX_DELAY_0",
- "number": "0",
- "description": "1 second."
- },
- {
- "name": "RX_DELAY_1",
- "number": "1",
- "description": "1 second."
- },
- {
- "name": "RX_DELAY_2",
- "number": "2",
- "description": "2 seconds."
- },
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": true,
+ "extensions": [],
+ "fields": [
{
- "name": "RX_DELAY_3",
- "number": "3",
- "description": "3 seconds."
+ "name": "cid",
+ "description": "",
+ "label": "",
+ "type": "MACCommandIdentifier",
+ "longType": "MACCommandIdentifier",
+ "fullType": "ttn.lorawan.v3.MACCommandIdentifier",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "enum.defined_only",
+ "value": true
+ },
+ {
+ "name": "enum.not_in",
+ "value": [
+ 0
+ ]
+ }
+ ]
+ }
},
{
- "name": "RX_DELAY_4",
- "number": "4",
- "description": "4 seconds."
+ "name": "raw_payload",
+ "description": "",
+ "label": "",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
},
{
- "name": "RX_DELAY_5",
- "number": "5",
- "description": "5 seconds."
+ "name": "reset_ind",
+ "description": "",
+ "label": "",
+ "type": "ResetInd",
+ "longType": "MACCommand.ResetInd",
+ "fullType": "ttn.lorawan.v3.MACCommand.ResetInd",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
},
{
- "name": "RX_DELAY_6",
- "number": "6",
- "description": "6 seconds."
+ "name": "reset_conf",
+ "description": "",
+ "label": "",
+ "type": "ResetConf",
+ "longType": "MACCommand.ResetConf",
+ "fullType": "ttn.lorawan.v3.MACCommand.ResetConf",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
},
{
- "name": "RX_DELAY_7",
- "number": "7",
- "description": "7 seconds."
+ "name": "link_check_ans",
+ "description": "",
+ "label": "",
+ "type": "LinkCheckAns",
+ "longType": "MACCommand.LinkCheckAns",
+ "fullType": "ttn.lorawan.v3.MACCommand.LinkCheckAns",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
},
{
- "name": "RX_DELAY_8",
- "number": "8",
- "description": "8 seconds."
+ "name": "link_adr_req",
+ "description": "",
+ "label": "",
+ "type": "LinkADRReq",
+ "longType": "MACCommand.LinkADRReq",
+ "fullType": "ttn.lorawan.v3.MACCommand.LinkADRReq",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
},
{
- "name": "RX_DELAY_9",
- "number": "9",
- "description": "9 seconds."
+ "name": "link_adr_ans",
+ "description": "",
+ "label": "",
+ "type": "LinkADRAns",
+ "longType": "MACCommand.LinkADRAns",
+ "fullType": "ttn.lorawan.v3.MACCommand.LinkADRAns",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
},
{
- "name": "RX_DELAY_10",
- "number": "10",
- "description": "10 seconds."
+ "name": "duty_cycle_req",
+ "description": "",
+ "label": "",
+ "type": "DutyCycleReq",
+ "longType": "MACCommand.DutyCycleReq",
+ "fullType": "ttn.lorawan.v3.MACCommand.DutyCycleReq",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
},
{
- "name": "RX_DELAY_11",
- "number": "11",
- "description": "11 seconds."
+ "name": "rx_param_setup_req",
+ "description": "",
+ "label": "",
+ "type": "RxParamSetupReq",
+ "longType": "MACCommand.RxParamSetupReq",
+ "fullType": "ttn.lorawan.v3.MACCommand.RxParamSetupReq",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
},
{
- "name": "RX_DELAY_12",
- "number": "12",
- "description": "12 seconds."
+ "name": "rx_param_setup_ans",
+ "description": "",
+ "label": "",
+ "type": "RxParamSetupAns",
+ "longType": "MACCommand.RxParamSetupAns",
+ "fullType": "ttn.lorawan.v3.MACCommand.RxParamSetupAns",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
},
{
- "name": "RX_DELAY_13",
- "number": "13",
- "description": "13 seconds."
+ "name": "dev_status_ans",
+ "description": "",
+ "label": "",
+ "type": "DevStatusAns",
+ "longType": "MACCommand.DevStatusAns",
+ "fullType": "ttn.lorawan.v3.MACCommand.DevStatusAns",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
},
{
- "name": "RX_DELAY_14",
- "number": "14",
- "description": "14 seconds."
+ "name": "new_channel_req",
+ "description": "",
+ "label": "",
+ "type": "NewChannelReq",
+ "longType": "MACCommand.NewChannelReq",
+ "fullType": "ttn.lorawan.v3.MACCommand.NewChannelReq",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
},
{
- "name": "RX_DELAY_15",
- "number": "15",
- "description": "15 seconds."
- }
- ]
- },
- {
- "name": "TxSchedulePriority",
- "longName": "TxSchedulePriority",
- "fullName": "ttn.lorawan.v3.TxSchedulePriority",
- "description": "",
- "values": [
- {
- "name": "LOWEST",
- "number": "0",
- "description": ""
+ "name": "new_channel_ans",
+ "description": "",
+ "label": "",
+ "type": "NewChannelAns",
+ "longType": "MACCommand.NewChannelAns",
+ "fullType": "ttn.lorawan.v3.MACCommand.NewChannelAns",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
},
{
- "name": "LOW",
- "number": "1",
- "description": ""
+ "name": "dl_channel_req",
+ "description": "",
+ "label": "",
+ "type": "DLChannelReq",
+ "longType": "MACCommand.DLChannelReq",
+ "fullType": "ttn.lorawan.v3.MACCommand.DLChannelReq",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
},
{
- "name": "BELOW_NORMAL",
- "number": "2",
- "description": ""
+ "name": "dl_channel_ans",
+ "description": "",
+ "label": "",
+ "type": "DLChannelAns",
+ "longType": "MACCommand.DLChannelAns",
+ "fullType": "ttn.lorawan.v3.MACCommand.DLChannelAns",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
},
{
- "name": "NORMAL",
- "number": "3",
- "description": ""
+ "name": "rx_timing_setup_req",
+ "description": "",
+ "label": "",
+ "type": "RxTimingSetupReq",
+ "longType": "MACCommand.RxTimingSetupReq",
+ "fullType": "ttn.lorawan.v3.MACCommand.RxTimingSetupReq",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
},
{
- "name": "ABOVE_NORMAL",
- "number": "4",
- "description": ""
+ "name": "tx_param_setup_req",
+ "description": "",
+ "label": "",
+ "type": "TxParamSetupReq",
+ "longType": "MACCommand.TxParamSetupReq",
+ "fullType": "ttn.lorawan.v3.MACCommand.TxParamSetupReq",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
},
{
- "name": "HIGH",
- "number": "5",
- "description": ""
+ "name": "rekey_ind",
+ "description": "",
+ "label": "",
+ "type": "RekeyInd",
+ "longType": "MACCommand.RekeyInd",
+ "fullType": "ttn.lorawan.v3.MACCommand.RekeyInd",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
},
{
- "name": "HIGHEST",
- "number": "6",
- "description": ""
- }
- ]
- }
- ],
- "extensions": [],
- "messages": [
- {
- "name": "ADRAckDelayExponentValue",
- "longName": "ADRAckDelayExponentValue",
- "fullName": "ttn.lorawan.v3.ADRAckDelayExponentValue",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
- {
- "name": "value",
+ "name": "rekey_conf",
"description": "",
"label": "",
- "type": "ADRAckDelayExponent",
- "longType": "ADRAckDelayExponent",
- "fullType": "ttn.lorawan.v3.ADRAckDelayExponent",
+ "type": "RekeyConf",
+ "longType": "MACCommand.RekeyConf",
+ "fullType": "ttn.lorawan.v3.MACCommand.RekeyConf",
"ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "enum.defined_only",
- "value": true
- }
- ]
- }
- }
- ]
- },
- {
- "name": "ADRAckLimitExponentValue",
- "longName": "ADRAckLimitExponentValue",
- "fullName": "ttn.lorawan.v3.ADRAckLimitExponentValue",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
+ },
{
- "name": "value",
+ "name": "adr_param_setup_req",
"description": "",
"label": "",
- "type": "ADRAckLimitExponent",
- "longType": "ADRAckLimitExponent",
- "fullType": "ttn.lorawan.v3.ADRAckLimitExponent",
+ "type": "ADRParamSetupReq",
+ "longType": "MACCommand.ADRParamSetupReq",
+ "fullType": "ttn.lorawan.v3.MACCommand.ADRParamSetupReq",
"ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "enum.defined_only",
- "value": true
- }
- ]
- }
- }
- ]
- },
- {
- "name": "AggregatedDutyCycleValue",
- "longName": "AggregatedDutyCycleValue",
- "fullName": "ttn.lorawan.v3.AggregatedDutyCycleValue",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
+ },
{
- "name": "value",
+ "name": "device_time_ans",
"description": "",
"label": "",
- "type": "AggregatedDutyCycle",
- "longType": "AggregatedDutyCycle",
- "fullType": "ttn.lorawan.v3.AggregatedDutyCycle",
+ "type": "DeviceTimeAns",
+ "longType": "MACCommand.DeviceTimeAns",
+ "fullType": "ttn.lorawan.v3.MACCommand.DeviceTimeAns",
"ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "enum.defined_only",
- "value": true
- }
- ]
- }
- }
- ]
- },
- {
- "name": "CFList",
- "longName": "CFList",
- "fullName": "ttn.lorawan.v3.CFList",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
+ },
{
- "name": "type",
+ "name": "force_rejoin_req",
"description": "",
"label": "",
- "type": "CFListType",
- "longType": "CFListType",
- "fullType": "ttn.lorawan.v3.CFListType",
+ "type": "ForceRejoinReq",
+ "longType": "MACCommand.ForceRejoinReq",
+ "fullType": "ttn.lorawan.v3.MACCommand.ForceRejoinReq",
"ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "enum.defined_only",
- "value": true
- }
- ]
- }
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
},
{
- "name": "freq",
- "description": "Frequencies to be broadcasted, in hecto-Hz.\nThese values are broadcasted as 24 bits unsigned integers.\nThis field should not contain default values.",
- "label": "repeated",
- "type": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
+ "name": "rejoin_param_setup_req",
+ "description": "",
+ "label": "",
+ "type": "RejoinParamSetupReq",
+ "longType": "MACCommand.RejoinParamSetupReq",
+ "fullType": "ttn.lorawan.v3.MACCommand.RejoinParamSetupReq",
"ismap": false,
- "isoneof": false,
- "oneofdecl": "",
+ "isoneof": true,
+ "oneofdecl": "payload",
"defaultValue": ""
},
{
- "name": "ch_masks",
- "description": "ChMasks controlling the channels to be used.\nLength of this field must be equal to the amount of uplink channels\ndefined by the selected frequency plan.",
- "label": "repeated",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
+ "name": "rejoin_param_setup_ans",
+ "description": "",
+ "label": "",
+ "type": "RejoinParamSetupAns",
+ "longType": "MACCommand.RejoinParamSetupAns",
+ "fullType": "ttn.lorawan.v3.MACCommand.RejoinParamSetupAns",
"ismap": false,
- "isoneof": false,
- "oneofdecl": "",
+ "isoneof": true,
+ "oneofdecl": "payload",
"defaultValue": ""
- }
- ]
- },
- {
- "name": "ClassBCGatewayIdentifiers",
- "longName": "ClassBCGatewayIdentifiers",
- "fullName": "ttn.lorawan.v3.ClassBCGatewayIdentifiers",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ },
{
- "name": "gateway_ids",
+ "name": "ping_slot_info_req",
"description": "",
"label": "",
- "type": "GatewayIdentifiers",
- "longType": "GatewayIdentifiers",
- "fullType": "ttn.lorawan.v3.GatewayIdentifiers",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "message.required",
- "value": true
- }
- ]
- }
+ "type": "PingSlotInfoReq",
+ "longType": "MACCommand.PingSlotInfoReq",
+ "fullType": "ttn.lorawan.v3.MACCommand.PingSlotInfoReq",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
},
{
- "name": "antenna_index",
+ "name": "ping_slot_channel_req",
"description": "",
"label": "",
- "type": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
+ "type": "PingSlotChannelReq",
+ "longType": "MACCommand.PingSlotChannelReq",
+ "fullType": "ttn.lorawan.v3.MACCommand.PingSlotChannelReq",
"ismap": false,
- "isoneof": false,
- "oneofdecl": "",
+ "isoneof": true,
+ "oneofdecl": "payload",
"defaultValue": ""
},
{
- "name": "group_index",
+ "name": "ping_slot_channel_ans",
"description": "",
"label": "",
- "type": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
+ "type": "PingSlotChannelAns",
+ "longType": "MACCommand.PingSlotChannelAns",
+ "fullType": "ttn.lorawan.v3.MACCommand.PingSlotChannelAns",
"ismap": false,
- "isoneof": false,
- "oneofdecl": "",
+ "isoneof": true,
+ "oneofdecl": "payload",
"defaultValue": ""
- }
- ]
- },
- {
- "name": "DLSettings",
- "longName": "DLSettings",
- "fullName": "ttn.lorawan.v3.DLSettings",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ },
{
- "name": "rx1_dr_offset",
+ "name": "beacon_timing_ans",
"description": "",
"label": "",
- "type": "DataRateOffset",
- "longType": "DataRateOffset",
- "fullType": "ttn.lorawan.v3.DataRateOffset",
+ "type": "BeaconTimingAns",
+ "longType": "MACCommand.BeaconTimingAns",
+ "fullType": "ttn.lorawan.v3.MACCommand.BeaconTimingAns",
"ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "enum.defined_only",
- "value": true
- }
- ]
- }
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
},
{
- "name": "rx2_dr",
+ "name": "beacon_freq_req",
"description": "",
"label": "",
- "type": "DataRateIndex",
- "longType": "DataRateIndex",
- "fullType": "ttn.lorawan.v3.DataRateIndex",
+ "type": "BeaconFreqReq",
+ "longType": "MACCommand.BeaconFreqReq",
+ "fullType": "ttn.lorawan.v3.MACCommand.BeaconFreqReq",
"ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "enum.defined_only",
- "value": true
- }
- ]
- }
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
},
{
- "name": "opt_neg",
- "description": "OptNeg is set if Network Server implements LoRaWAN 1.1 or greater.",
+ "name": "beacon_freq_ans",
+ "description": "",
"label": "",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
+ "type": "BeaconFreqAns",
+ "longType": "MACCommand.BeaconFreqAns",
+ "fullType": "ttn.lorawan.v3.MACCommand.BeaconFreqAns",
"ismap": false,
- "isoneof": false,
- "oneofdecl": "",
+ "isoneof": true,
+ "oneofdecl": "payload",
"defaultValue": ""
- }
- ]
- },
- {
- "name": "DataRate",
- "longName": "DataRate",
- "fullName": "ttn.lorawan.v3.DataRate",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": true,
- "extensions": [],
- "fields": [
+ },
{
- "name": "lora",
+ "name": "device_mode_ind",
"description": "",
"label": "",
- "type": "LoRaDataRate",
- "longType": "LoRaDataRate",
- "fullType": "ttn.lorawan.v3.LoRaDataRate",
+ "type": "DeviceModeInd",
+ "longType": "MACCommand.DeviceModeInd",
+ "fullType": "ttn.lorawan.v3.MACCommand.DeviceModeInd",
"ismap": false,
"isoneof": true,
- "oneofdecl": "modulation",
+ "oneofdecl": "payload",
"defaultValue": ""
},
{
- "name": "fsk",
+ "name": "device_mode_conf",
"description": "",
"label": "",
- "type": "FSKDataRate",
- "longType": "FSKDataRate",
- "fullType": "ttn.lorawan.v3.FSKDataRate",
+ "type": "DeviceModeConf",
+ "longType": "MACCommand.DeviceModeConf",
+ "fullType": "ttn.lorawan.v3.MACCommand.DeviceModeConf",
"ismap": false,
"isoneof": true,
- "oneofdecl": "modulation",
+ "oneofdecl": "payload",
"defaultValue": ""
},
{
- "name": "lrfhss",
+ "name": "relay_conf_req",
"description": "",
"label": "",
- "type": "LRFHSSDataRate",
- "longType": "LRFHSSDataRate",
- "fullType": "ttn.lorawan.v3.LRFHSSDataRate",
+ "type": "RelayConfReq",
+ "longType": "MACCommand.RelayConfReq",
+ "fullType": "ttn.lorawan.v3.MACCommand.RelayConfReq",
"ismap": false,
"isoneof": true,
- "oneofdecl": "modulation",
+ "oneofdecl": "payload",
"defaultValue": ""
- }
- ]
- },
- {
- "name": "DataRateIndexValue",
- "longName": "DataRateIndexValue",
- "fullName": "ttn.lorawan.v3.DataRateIndexValue",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ },
{
- "name": "value",
+ "name": "relay_conf_ans",
"description": "",
"label": "",
- "type": "DataRateIndex",
- "longType": "DataRateIndex",
- "fullType": "ttn.lorawan.v3.DataRateIndex",
+ "type": "RelayConfAns",
+ "longType": "MACCommand.RelayConfAns",
+ "fullType": "ttn.lorawan.v3.MACCommand.RelayConfAns",
"ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "enum.defined_only",
- "value": true
- }
- ]
- }
- }
- ]
- },
- {
- "name": "DataRateOffsetValue",
- "longName": "DataRateOffsetValue",
- "fullName": "ttn.lorawan.v3.DataRateOffsetValue",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
+ },
{
- "name": "value",
+ "name": "relay_end_device_conf_req",
"description": "",
"label": "",
- "type": "DataRateOffset",
- "longType": "DataRateOffset",
- "fullType": "ttn.lorawan.v3.DataRateOffset",
+ "type": "RelayEndDeviceConfReq",
+ "longType": "MACCommand.RelayEndDeviceConfReq",
+ "fullType": "ttn.lorawan.v3.MACCommand.RelayEndDeviceConfReq",
"ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "enum.defined_only",
- "value": true
- }
- ]
- }
- }
- ]
- },
- {
- "name": "DeviceEIRPValue",
- "longName": "DeviceEIRPValue",
- "fullName": "ttn.lorawan.v3.DeviceEIRPValue",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
+ },
{
- "name": "value",
+ "name": "relay_end_device_conf_ans",
"description": "",
"label": "",
- "type": "DeviceEIRP",
- "longType": "DeviceEIRP",
- "fullType": "ttn.lorawan.v3.DeviceEIRP",
+ "type": "RelayEndDeviceConfAns",
+ "longType": "MACCommand.RelayEndDeviceConfAns",
+ "fullType": "ttn.lorawan.v3.MACCommand.RelayEndDeviceConfAns",
"ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "enum.defined_only",
- "value": true
- }
- ]
- }
- }
- ]
- },
- {
- "name": "DownlinkPath",
- "longName": "DownlinkPath",
- "fullName": "ttn.lorawan.v3.DownlinkPath",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": true,
- "extensions": [],
- "fields": [
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
+ },
{
- "name": "uplink_token",
- "description": "",
- "label": "",
- "type": "bytes",
- "longType": "bytes",
- "fullType": "bytes",
+ "name": "relay_update_uplink_list_req",
+ "description": "",
+ "label": "",
+ "type": "RelayUpdateUplinkListReq",
+ "longType": "MACCommand.RelayUpdateUplinkListReq",
+ "fullType": "ttn.lorawan.v3.MACCommand.RelayUpdateUplinkListReq",
"ismap": false,
"isoneof": true,
- "oneofdecl": "path",
+ "oneofdecl": "payload",
"defaultValue": ""
},
{
- "name": "fixed",
+ "name": "relay_update_uplink_list_ans",
"description": "",
"label": "",
- "type": "GatewayAntennaIdentifiers",
- "longType": "GatewayAntennaIdentifiers",
- "fullType": "ttn.lorawan.v3.GatewayAntennaIdentifiers",
+ "type": "RelayUpdateUplinkListAns",
+ "longType": "MACCommand.RelayUpdateUplinkListAns",
+ "fullType": "ttn.lorawan.v3.MACCommand.RelayUpdateUplinkListAns",
"ismap": false,
"isoneof": true,
- "oneofdecl": "path",
+ "oneofdecl": "payload",
"defaultValue": ""
- }
- ]
- },
- {
- "name": "FCtrl",
- "longName": "FCtrl",
- "fullName": "ttn.lorawan.v3.FCtrl",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ },
{
- "name": "adr",
+ "name": "relay_ctrl_uplink_list_req",
"description": "",
"label": "",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
+ "type": "RelayCtrlUplinkListReq",
+ "longType": "MACCommand.RelayCtrlUplinkListReq",
+ "fullType": "ttn.lorawan.v3.MACCommand.RelayCtrlUplinkListReq",
"ismap": false,
- "isoneof": false,
- "oneofdecl": "",
+ "isoneof": true,
+ "oneofdecl": "payload",
"defaultValue": ""
},
{
- "name": "adr_ack_req",
- "description": "Only on uplink.",
+ "name": "relay_ctrl_uplink_list_ans",
+ "description": "",
"label": "",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
+ "type": "RelayCtrlUplinkListAns",
+ "longType": "MACCommand.RelayCtrlUplinkListAns",
+ "fullType": "ttn.lorawan.v3.MACCommand.RelayCtrlUplinkListAns",
"ismap": false,
- "isoneof": false,
- "oneofdecl": "",
+ "isoneof": true,
+ "oneofdecl": "payload",
"defaultValue": ""
},
{
- "name": "ack",
+ "name": "relay_configure_fwd_limit_req",
"description": "",
"label": "",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
+ "type": "RelayConfigureFwdLimitReq",
+ "longType": "MACCommand.RelayConfigureFwdLimitReq",
+ "fullType": "ttn.lorawan.v3.MACCommand.RelayConfigureFwdLimitReq",
"ismap": false,
- "isoneof": false,
- "oneofdecl": "",
+ "isoneof": true,
+ "oneofdecl": "payload",
"defaultValue": ""
},
{
- "name": "f_pending",
- "description": "Only on downlink.",
+ "name": "relay_configure_fwd_limit_ans",
+ "description": "",
"label": "",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
+ "type": "RelayConfigureFwdLimitAns",
+ "longType": "MACCommand.RelayConfigureFwdLimitAns",
+ "fullType": "ttn.lorawan.v3.MACCommand.RelayConfigureFwdLimitAns",
"ismap": false,
- "isoneof": false,
- "oneofdecl": "",
+ "isoneof": true,
+ "oneofdecl": "payload",
"defaultValue": ""
},
{
- "name": "class_b",
- "description": "Only on uplink.",
+ "name": "relay_notify_new_end_device_req",
+ "description": "",
"label": "",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
+ "type": "RelayNotifyNewEndDeviceReq",
+ "longType": "MACCommand.RelayNotifyNewEndDeviceReq",
+ "fullType": "ttn.lorawan.v3.MACCommand.RelayNotifyNewEndDeviceReq",
"ismap": false,
- "isoneof": false,
- "oneofdecl": "",
+ "isoneof": true,
+ "oneofdecl": "payload",
"defaultValue": ""
}
]
},
{
- "name": "FHDR",
- "longName": "FHDR",
- "fullName": "ttn.lorawan.v3.FHDR",
+ "name": "ADRParamSetupReq",
+ "longName": "MACCommand.ADRParamSetupReq",
+ "fullName": "ttn.lorawan.v3.MACCommand.ADRParamSetupReq",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -29745,32 +31513,12 @@
"extensions": [],
"fields": [
{
- "name": "dev_addr",
- "description": "",
- "label": "",
- "type": "bytes",
- "longType": "bytes",
- "fullType": "bytes",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "bytes.len",
- "value": 4
- }
- ]
- }
- },
- {
- "name": "f_ctrl",
- "description": "",
+ "name": "adr_ack_limit_exponent",
+ "description": "Exponent e that configures the ADR_ACK_LIMIT = 2^e messages.",
"label": "",
- "type": "FCtrl",
- "longType": "FCtrl",
- "fullType": "ttn.lorawan.v3.FCtrl",
+ "type": "ADRAckLimitExponent",
+ "longType": "ADRAckLimitExponent",
+ "fullType": "ttn.lorawan.v3.ADRAckLimitExponent",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -29778,39 +31526,19 @@
"options": {
"validate.rules": [
{
- "name": "message.required",
+ "name": "enum.defined_only",
"value": true
}
]
}
},
{
- "name": "f_cnt",
- "description": "",
- "label": "",
- "type": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "uint32.lte",
- "value": 65535
- }
- ]
- }
- },
- {
- "name": "f_opts",
- "description": "",
+ "name": "adr_ack_delay_exponent",
+ "description": "Exponent e that configures the ADR_ACK_DELAY = 2^e messages.",
"label": "",
- "type": "bytes",
- "longType": "bytes",
- "fullType": "bytes",
+ "type": "ADRAckDelayExponent",
+ "longType": "ADRAckDelayExponent",
+ "fullType": "ttn.lorawan.v3.ADRAckDelayExponent",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -29818,8 +31546,8 @@
"options": {
"validate.rules": [
{
- "name": "bytes.max_len",
- "value": 15
+ "name": "enum.defined_only",
+ "value": true
}
]
}
@@ -29827,9 +31555,9 @@
]
},
{
- "name": "FSKDataRate",
- "longName": "FSKDataRate",
- "fullName": "ttn.lorawan.v3.FSKDataRate",
+ "name": "BeaconFreqAns",
+ "longName": "MACCommand.BeaconFreqAns",
+ "fullName": "ttn.lorawan.v3.MACCommand.BeaconFreqAns",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -29837,12 +31565,12 @@
"extensions": [],
"fields": [
{
- "name": "bit_rate",
- "description": "Bit rate (bps).",
+ "name": "frequency_ack",
+ "description": "",
"label": "",
- "type": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -29851,9 +31579,9 @@
]
},
{
- "name": "FrequencyValue",
- "longName": "FrequencyValue",
- "fullName": "ttn.lorawan.v3.FrequencyValue",
+ "name": "BeaconFreqReq",
+ "longName": "MACCommand.BeaconFreqReq",
+ "fullName": "ttn.lorawan.v3.MACCommand.BeaconFreqReq",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -29861,8 +31589,8 @@
"extensions": [],
"fields": [
{
- "name": "value",
- "description": "",
+ "name": "frequency",
+ "description": "Frequency of the Class B beacons (Hz).",
"label": "",
"type": "uint64",
"longType": "uint64",
@@ -29873,6 +31601,10 @@
"defaultValue": "",
"options": {
"validate.rules": [
+ {
+ "name": "uint64.lte",
+ "value": 0
+ },
{
"name": "uint64.gte",
"value": 100000
@@ -29883,9 +31615,9 @@
]
},
{
- "name": "GatewayAntennaIdentifiers",
- "longName": "GatewayAntennaIdentifiers",
- "fullName": "ttn.lorawan.v3.GatewayAntennaIdentifiers",
+ "name": "BeaconTimingAns",
+ "longName": "MACCommand.BeaconTimingAns",
+ "fullName": "ttn.lorawan.v3.MACCommand.BeaconTimingAns",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -29893,12 +31625,12 @@
"extensions": [],
"fields": [
{
- "name": "gateway_ids",
- "description": "",
+ "name": "delay",
+ "description": "(uint16) See LoRaWAN specification.",
"label": "",
- "type": "GatewayIdentifiers",
- "longType": "GatewayIdentifiers",
- "fullType": "ttn.lorawan.v3.GatewayIdentifiers",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -29906,14 +31638,14 @@
"options": {
"validate.rules": [
{
- "name": "message.required",
- "value": true
+ "name": "uint32.lte",
+ "value": 65535
}
]
}
},
{
- "name": "antenna_index",
+ "name": "channel_index",
"description": "",
"label": "",
"type": "uint32",
@@ -29922,14 +31654,22 @@
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "uint32.lte",
+ "value": 255
+ }
+ ]
+ }
}
]
},
{
- "name": "JoinAcceptPayload",
- "longName": "JoinAcceptPayload",
- "fullName": "ttn.lorawan.v3.JoinAcceptPayload",
+ "name": "DLChannelAns",
+ "longName": "MACCommand.DLChannelAns",
+ "fullName": "ttn.lorawan.v3.MACCommand.DLChannelAns",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -29937,24 +31677,48 @@
"extensions": [],
"fields": [
{
- "name": "encrypted",
+ "name": "channel_index_ack",
"description": "",
"label": "",
- "type": "bytes",
- "longType": "bytes",
- "fullType": "bytes",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "join_nonce",
+ "name": "frequency_ack",
"description": "",
"label": "",
- "type": "bytes",
- "longType": "bytes",
- "fullType": "bytes",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ }
+ ]
+ },
+ {
+ "name": "DLChannelReq",
+ "longName": "MACCommand.DLChannelReq",
+ "fullName": "ttn.lorawan.v3.MACCommand.DLChannelReq",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "channel_index",
+ "description": "",
+ "label": "",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -29962,19 +31726,19 @@
"options": {
"validate.rules": [
{
- "name": "bytes.len",
- "value": 3
+ "name": "uint32.lte",
+ "value": 255
}
]
}
},
{
- "name": "net_id",
- "description": "",
+ "name": "frequency",
+ "description": "Downlink channel frequency (Hz).",
"label": "",
- "type": "bytes",
- "longType": "bytes",
- "fullType": "bytes",
+ "type": "uint64",
+ "longType": "uint64",
+ "fullType": "uint64",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -29982,19 +31746,31 @@
"options": {
"validate.rules": [
{
- "name": "bytes.len",
- "value": 3
+ "name": "uint64.gte",
+ "value": 100000
}
]
}
- },
+ }
+ ]
+ },
+ {
+ "name": "DevStatusAns",
+ "longName": "MACCommand.DevStatusAns",
+ "fullName": "ttn.lorawan.v3.MACCommand.DevStatusAns",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "dev_addr",
- "description": "",
+ "name": "battery",
+ "description": "Device battery status.\n0 indicates that the device is connected to an external power source.\n1..254 indicates a battery level.\n255 indicates that the device was not able to measure the battery level.",
"label": "",
- "type": "bytes",
- "longType": "bytes",
- "fullType": "bytes",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -30002,19 +31778,19 @@
"options": {
"validate.rules": [
{
- "name": "bytes.len",
- "value": 4
+ "name": "uint32.lte",
+ "value": 255
}
]
}
},
{
- "name": "dl_settings",
- "description": "",
+ "name": "margin",
+ "description": "SNR of the last downlink (dB; [-32, +31]).",
"label": "",
- "type": "DLSettings",
- "longType": "DLSettings",
- "fullType": "ttn.lorawan.v3.DLSettings",
+ "type": "int32",
+ "longType": "int32",
+ "fullType": "int32",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -30022,19 +31798,35 @@
"options": {
"validate.rules": [
{
- "name": "message.required",
- "value": true
+ "name": "int32.lte",
+ "value": 31
+ },
+ {
+ "name": "int32.gte",
+ "value": -32
}
]
}
- },
+ }
+ ]
+ },
+ {
+ "name": "DeviceModeConf",
+ "longName": "MACCommand.DeviceModeConf",
+ "fullName": "ttn.lorawan.v3.MACCommand.DeviceModeConf",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "rx_delay",
+ "name": "class",
"description": "",
"label": "",
- "type": "RxDelay",
- "longType": "RxDelay",
- "fullType": "ttn.lorawan.v3.RxDelay",
+ "type": "Class",
+ "longType": "Class",
+ "fullType": "ttn.lorawan.v3.Class",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -30047,25 +31839,13 @@
}
]
}
- },
- {
- "name": "cf_list",
- "description": "",
- "label": "",
- "type": "CFList",
- "longType": "CFList",
- "fullType": "ttn.lorawan.v3.CFList",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
}
]
},
{
- "name": "JoinRequestPayload",
- "longName": "JoinRequestPayload",
- "fullName": "ttn.lorawan.v3.JoinRequestPayload",
+ "name": "DeviceModeInd",
+ "longName": "MACCommand.DeviceModeInd",
+ "fullName": "ttn.lorawan.v3.MACCommand.DeviceModeInd",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -30073,12 +31853,12 @@
"extensions": [],
"fields": [
{
- "name": "join_eui",
+ "name": "class",
"description": "",
"label": "",
- "type": "bytes",
- "longType": "bytes",
- "fullType": "bytes",
+ "type": "Class",
+ "longType": "Class",
+ "fullType": "ttn.lorawan.v3.Class",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -30086,19 +31866,31 @@
"options": {
"validate.rules": [
{
- "name": "bytes.len",
- "value": 8
+ "name": "enum.defined_only",
+ "value": true
}
]
}
- },
+ }
+ ]
+ },
+ {
+ "name": "DeviceTimeAns",
+ "longName": "MACCommand.DeviceTimeAns",
+ "fullName": "ttn.lorawan.v3.MACCommand.DeviceTimeAns",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "dev_eui",
+ "name": "time",
"description": "",
"label": "",
- "type": "bytes",
- "longType": "bytes",
- "fullType": "bytes",
+ "type": "Timestamp",
+ "longType": "google.protobuf.Timestamp",
+ "fullType": "google.protobuf.Timestamp",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -30106,19 +31898,31 @@
"options": {
"validate.rules": [
{
- "name": "bytes.len",
- "value": 8
+ "name": "timestamp.required",
+ "value": true
}
]
}
- },
+ }
+ ]
+ },
+ {
+ "name": "DutyCycleReq",
+ "longName": "MACCommand.DutyCycleReq",
+ "fullName": "ttn.lorawan.v3.MACCommand.DutyCycleReq",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "dev_nonce",
+ "name": "max_duty_cycle",
"description": "",
"label": "",
- "type": "bytes",
- "longType": "bytes",
- "fullType": "bytes",
+ "type": "AggregatedDutyCycle",
+ "longType": "AggregatedDutyCycle",
+ "fullType": "ttn.lorawan.v3.AggregatedDutyCycle",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -30126,8 +31930,8 @@
"options": {
"validate.rules": [
{
- "name": "bytes.len",
- "value": 2
+ "name": "enum.defined_only",
+ "value": true
}
]
}
@@ -30135,9 +31939,9 @@
]
},
{
- "name": "LRFHSSDataRate",
- "longName": "LRFHSSDataRate",
- "fullName": "ttn.lorawan.v3.LRFHSSDataRate",
+ "name": "ForceRejoinReq",
+ "longName": "MACCommand.ForceRejoinReq",
+ "fullName": "ttn.lorawan.v3.MACCommand.ForceRejoinReq",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -30145,20 +31949,48 @@
"extensions": [],
"fields": [
{
- "name": "modulation_type",
+ "name": "rejoin_type",
"description": "",
"label": "",
- "type": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
+ "type": "RejoinRequestType",
+ "longType": "RejoinRequestType",
+ "fullType": "ttn.lorawan.v3.RejoinRequestType",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "enum.defined_only",
+ "value": true
+ }
+ ]
+ }
},
{
- "name": "operating_channel_width",
- "description": "Operating Channel Width (Hz).",
+ "name": "data_rate_index",
+ "description": "",
+ "label": "",
+ "type": "DataRateIndex",
+ "longType": "DataRateIndex",
+ "fullType": "ttn.lorawan.v3.DataRateIndex",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "enum.defined_only",
+ "value": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "max_retries",
+ "description": "",
"label": "",
"type": "uint32",
"longType": "uint32",
@@ -30166,26 +31998,42 @@
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "uint32.lte",
+ "value": 7
+ }
+ ]
+ }
},
{
- "name": "coding_rate",
- "description": "",
+ "name": "period_exponent",
+ "description": "Exponent e that configures the rejoin period = 32 * 2^e + rand(0,32) seconds.",
"label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
+ "type": "RejoinPeriodExponent",
+ "longType": "RejoinPeriodExponent",
+ "fullType": "ttn.lorawan.v3.RejoinPeriodExponent",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "enum.defined_only",
+ "value": true
+ }
+ ]
+ }
}
]
},
{
- "name": "LoRaDataRate",
- "longName": "LoRaDataRate",
- "fullName": "ttn.lorawan.v3.LoRaDataRate",
+ "name": "LinkADRAns",
+ "longName": "MACCommand.LinkADRAns",
+ "fullName": "ttn.lorawan.v3.MACCommand.LinkADRAns",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -30193,36 +32041,36 @@
"extensions": [],
"fields": [
{
- "name": "bandwidth",
- "description": "Bandwidth (Hz).",
+ "name": "channel_mask_ack",
+ "description": "",
"label": "",
- "type": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "spreading_factor",
+ "name": "data_rate_index_ack",
"description": "",
"label": "",
- "type": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "coding_rate",
+ "name": "tx_power_index_ack",
"description": "",
"label": "",
- "type": "string",
- "longType": "string",
- "fullType": "string",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -30231,22 +32079,22 @@
]
},
{
- "name": "MACCommand",
- "longName": "MACCommand",
- "fullName": "ttn.lorawan.v3.MACCommand",
+ "name": "LinkADRReq",
+ "longName": "MACCommand.LinkADRReq",
+ "fullName": "ttn.lorawan.v3.MACCommand.LinkADRReq",
"description": "",
"hasExtensions": false,
"hasFields": true,
- "hasOneofs": true,
+ "hasOneofs": false,
"extensions": [],
"fields": [
{
- "name": "cid",
+ "name": "data_rate_index",
"description": "",
"label": "",
- "type": "MACCommandIdentifier",
- "longType": "MACCommandIdentifier",
- "fullType": "ttn.lorawan.v3.MACCommandIdentifier",
+ "type": "DataRateIndex",
+ "longType": "DataRateIndex",
+ "fullType": "ttn.lorawan.v3.DataRateIndex",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -30256,394 +32104,480 @@
{
"name": "enum.defined_only",
"value": true
- },
- {
- "name": "enum.not_in",
- "value": [
- 0
- ]
}
]
}
},
{
- "name": "raw_payload",
- "description": "",
- "label": "",
- "type": "bytes",
- "longType": "bytes",
- "fullType": "bytes",
- "ismap": false,
- "isoneof": true,
- "oneofdecl": "payload",
- "defaultValue": ""
- },
- {
- "name": "reset_ind",
- "description": "",
- "label": "",
- "type": "ResetInd",
- "longType": "MACCommand.ResetInd",
- "fullType": "ttn.lorawan.v3.MACCommand.ResetInd",
- "ismap": false,
- "isoneof": true,
- "oneofdecl": "payload",
- "defaultValue": ""
- },
- {
- "name": "reset_conf",
- "description": "",
- "label": "",
- "type": "ResetConf",
- "longType": "MACCommand.ResetConf",
- "fullType": "ttn.lorawan.v3.MACCommand.ResetConf",
- "ismap": false,
- "isoneof": true,
- "oneofdecl": "payload",
- "defaultValue": ""
- },
- {
- "name": "link_check_ans",
- "description": "",
- "label": "",
- "type": "LinkCheckAns",
- "longType": "MACCommand.LinkCheckAns",
- "fullType": "ttn.lorawan.v3.MACCommand.LinkCheckAns",
- "ismap": false,
- "isoneof": true,
- "oneofdecl": "payload",
- "defaultValue": ""
- },
- {
- "name": "link_adr_req",
- "description": "",
- "label": "",
- "type": "LinkADRReq",
- "longType": "MACCommand.LinkADRReq",
- "fullType": "ttn.lorawan.v3.MACCommand.LinkADRReq",
- "ismap": false,
- "isoneof": true,
- "oneofdecl": "payload",
- "defaultValue": ""
- },
- {
- "name": "link_adr_ans",
- "description": "",
- "label": "",
- "type": "LinkADRAns",
- "longType": "MACCommand.LinkADRAns",
- "fullType": "ttn.lorawan.v3.MACCommand.LinkADRAns",
- "ismap": false,
- "isoneof": true,
- "oneofdecl": "payload",
- "defaultValue": ""
- },
- {
- "name": "duty_cycle_req",
- "description": "",
- "label": "",
- "type": "DutyCycleReq",
- "longType": "MACCommand.DutyCycleReq",
- "fullType": "ttn.lorawan.v3.MACCommand.DutyCycleReq",
- "ismap": false,
- "isoneof": true,
- "oneofdecl": "payload",
- "defaultValue": ""
- },
- {
- "name": "rx_param_setup_req",
- "description": "",
- "label": "",
- "type": "RxParamSetupReq",
- "longType": "MACCommand.RxParamSetupReq",
- "fullType": "ttn.lorawan.v3.MACCommand.RxParamSetupReq",
- "ismap": false,
- "isoneof": true,
- "oneofdecl": "payload",
- "defaultValue": ""
- },
- {
- "name": "rx_param_setup_ans",
- "description": "",
- "label": "",
- "type": "RxParamSetupAns",
- "longType": "MACCommand.RxParamSetupAns",
- "fullType": "ttn.lorawan.v3.MACCommand.RxParamSetupAns",
- "ismap": false,
- "isoneof": true,
- "oneofdecl": "payload",
- "defaultValue": ""
- },
- {
- "name": "dev_status_ans",
- "description": "",
- "label": "",
- "type": "DevStatusAns",
- "longType": "MACCommand.DevStatusAns",
- "fullType": "ttn.lorawan.v3.MACCommand.DevStatusAns",
- "ismap": false,
- "isoneof": true,
- "oneofdecl": "payload",
- "defaultValue": ""
- },
- {
- "name": "new_channel_req",
- "description": "",
- "label": "",
- "type": "NewChannelReq",
- "longType": "MACCommand.NewChannelReq",
- "fullType": "ttn.lorawan.v3.MACCommand.NewChannelReq",
- "ismap": false,
- "isoneof": true,
- "oneofdecl": "payload",
- "defaultValue": ""
- },
- {
- "name": "new_channel_ans",
+ "name": "tx_power_index",
"description": "",
"label": "",
- "type": "NewChannelAns",
- "longType": "MACCommand.NewChannelAns",
- "fullType": "ttn.lorawan.v3.MACCommand.NewChannelAns",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
"ismap": false,
- "isoneof": true,
- "oneofdecl": "payload",
- "defaultValue": ""
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "uint32.lte",
+ "value": 15
+ }
+ ]
+ }
},
{
- "name": "dl_channel_req",
+ "name": "channel_mask",
"description": "",
- "label": "",
- "type": "DLChannelReq",
- "longType": "MACCommand.DLChannelReq",
- "fullType": "ttn.lorawan.v3.MACCommand.DLChannelReq",
+ "label": "repeated",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
"ismap": false,
- "isoneof": true,
- "oneofdecl": "payload",
- "defaultValue": ""
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "repeated.max_items",
+ "value": 16
+ }
+ ]
+ }
},
{
- "name": "dl_channel_ans",
+ "name": "channel_mask_control",
"description": "",
"label": "",
- "type": "DLChannelAns",
- "longType": "MACCommand.DLChannelAns",
- "fullType": "ttn.lorawan.v3.MACCommand.DLChannelAns",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
"ismap": false,
- "isoneof": true,
- "oneofdecl": "payload",
- "defaultValue": ""
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "uint32.lte",
+ "value": 7
+ }
+ ]
+ }
},
{
- "name": "rx_timing_setup_req",
+ "name": "nb_trans",
"description": "",
"label": "",
- "type": "RxTimingSetupReq",
- "longType": "MACCommand.RxTimingSetupReq",
- "fullType": "ttn.lorawan.v3.MACCommand.RxTimingSetupReq",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
"ismap": false,
- "isoneof": true,
- "oneofdecl": "payload",
- "defaultValue": ""
- },
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "uint32.lte",
+ "value": 15
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "LinkCheckAns",
+ "longName": "MACCommand.LinkCheckAns",
+ "fullName": "ttn.lorawan.v3.MACCommand.LinkCheckAns",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "tx_param_setup_req",
- "description": "",
+ "name": "margin",
+ "description": "Indicates the link margin in dB of the received LinkCheckReq, relative to the demodulation floor.",
"label": "",
- "type": "TxParamSetupReq",
- "longType": "MACCommand.TxParamSetupReq",
- "fullType": "ttn.lorawan.v3.MACCommand.TxParamSetupReq",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
"ismap": false,
- "isoneof": true,
- "oneofdecl": "payload",
- "defaultValue": ""
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "uint32.lte",
+ "value": 254
+ }
+ ]
+ }
},
{
- "name": "rekey_ind",
+ "name": "gateway_count",
"description": "",
"label": "",
- "type": "RekeyInd",
- "longType": "MACCommand.RekeyInd",
- "fullType": "ttn.lorawan.v3.MACCommand.RekeyInd",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
"ismap": false,
- "isoneof": true,
- "oneofdecl": "payload",
- "defaultValue": ""
- },
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "uint32.lte",
+ "value": 255
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "NewChannelAns",
+ "longName": "MACCommand.NewChannelAns",
+ "fullName": "ttn.lorawan.v3.MACCommand.NewChannelAns",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "rekey_conf",
+ "name": "frequency_ack",
"description": "",
"label": "",
- "type": "RekeyConf",
- "longType": "MACCommand.RekeyConf",
- "fullType": "ttn.lorawan.v3.MACCommand.RekeyConf",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
"ismap": false,
- "isoneof": true,
- "oneofdecl": "payload",
+ "isoneof": false,
+ "oneofdecl": "",
"defaultValue": ""
},
{
- "name": "adr_param_setup_req",
+ "name": "data_rate_ack",
"description": "",
"label": "",
- "type": "ADRParamSetupReq",
- "longType": "MACCommand.ADRParamSetupReq",
- "fullType": "ttn.lorawan.v3.MACCommand.ADRParamSetupReq",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
"ismap": false,
- "isoneof": true,
- "oneofdecl": "payload",
+ "isoneof": false,
+ "oneofdecl": "",
"defaultValue": ""
- },
+ }
+ ]
+ },
+ {
+ "name": "NewChannelReq",
+ "longName": "MACCommand.NewChannelReq",
+ "fullName": "ttn.lorawan.v3.MACCommand.NewChannelReq",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "device_time_ans",
+ "name": "channel_index",
"description": "",
"label": "",
- "type": "DeviceTimeAns",
- "longType": "MACCommand.DeviceTimeAns",
- "fullType": "ttn.lorawan.v3.MACCommand.DeviceTimeAns",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
"ismap": false,
- "isoneof": true,
- "oneofdecl": "payload",
- "defaultValue": ""
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "uint32.lte",
+ "value": 255
+ }
+ ]
+ }
},
{
- "name": "force_rejoin_req",
- "description": "",
+ "name": "frequency",
+ "description": "Channel frequency (Hz).",
"label": "",
- "type": "ForceRejoinReq",
- "longType": "MACCommand.ForceRejoinReq",
- "fullType": "ttn.lorawan.v3.MACCommand.ForceRejoinReq",
+ "type": "uint64",
+ "longType": "uint64",
+ "fullType": "uint64",
"ismap": false,
- "isoneof": true,
- "oneofdecl": "payload",
- "defaultValue": ""
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "uint64.lte",
+ "value": 0
+ },
+ {
+ "name": "uint64.gte",
+ "value": 100000
+ }
+ ]
+ }
},
{
- "name": "rejoin_param_setup_req",
+ "name": "min_data_rate_index",
"description": "",
"label": "",
- "type": "RejoinParamSetupReq",
- "longType": "MACCommand.RejoinParamSetupReq",
- "fullType": "ttn.lorawan.v3.MACCommand.RejoinParamSetupReq",
+ "type": "DataRateIndex",
+ "longType": "DataRateIndex",
+ "fullType": "ttn.lorawan.v3.DataRateIndex",
"ismap": false,
- "isoneof": true,
- "oneofdecl": "payload",
- "defaultValue": ""
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "enum.defined_only",
+ "value": true
+ }
+ ]
+ }
},
{
- "name": "rejoin_param_setup_ans",
+ "name": "max_data_rate_index",
"description": "",
"label": "",
- "type": "RejoinParamSetupAns",
- "longType": "MACCommand.RejoinParamSetupAns",
- "fullType": "ttn.lorawan.v3.MACCommand.RejoinParamSetupAns",
+ "type": "DataRateIndex",
+ "longType": "DataRateIndex",
+ "fullType": "ttn.lorawan.v3.DataRateIndex",
"ismap": false,
- "isoneof": true,
- "oneofdecl": "payload",
- "defaultValue": ""
- },
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "enum.defined_only",
+ "value": true
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "PingSlotChannelAns",
+ "longName": "MACCommand.PingSlotChannelAns",
+ "fullName": "ttn.lorawan.v3.MACCommand.PingSlotChannelAns",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "ping_slot_info_req",
+ "name": "frequency_ack",
"description": "",
"label": "",
- "type": "PingSlotInfoReq",
- "longType": "MACCommand.PingSlotInfoReq",
- "fullType": "ttn.lorawan.v3.MACCommand.PingSlotInfoReq",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
"ismap": false,
- "isoneof": true,
- "oneofdecl": "payload",
+ "isoneof": false,
+ "oneofdecl": "",
"defaultValue": ""
},
{
- "name": "ping_slot_channel_req",
+ "name": "data_rate_index_ack",
"description": "",
"label": "",
- "type": "PingSlotChannelReq",
- "longType": "MACCommand.PingSlotChannelReq",
- "fullType": "ttn.lorawan.v3.MACCommand.PingSlotChannelReq",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
"ismap": false,
- "isoneof": true,
- "oneofdecl": "payload",
+ "isoneof": false,
+ "oneofdecl": "",
"defaultValue": ""
- },
+ }
+ ]
+ },
+ {
+ "name": "PingSlotChannelReq",
+ "longName": "MACCommand.PingSlotChannelReq",
+ "fullName": "ttn.lorawan.v3.MACCommand.PingSlotChannelReq",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "ping_slot_channel_ans",
- "description": "",
+ "name": "frequency",
+ "description": "Ping slot channel frequency (Hz).",
"label": "",
- "type": "PingSlotChannelAns",
- "longType": "MACCommand.PingSlotChannelAns",
- "fullType": "ttn.lorawan.v3.MACCommand.PingSlotChannelAns",
+ "type": "uint64",
+ "longType": "uint64",
+ "fullType": "uint64",
"ismap": false,
- "isoneof": true,
- "oneofdecl": "payload",
- "defaultValue": ""
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "uint64.lte",
+ "value": 0
+ },
+ {
+ "name": "uint64.gte",
+ "value": 100000
+ }
+ ]
+ }
},
{
- "name": "beacon_timing_ans",
+ "name": "data_rate_index",
"description": "",
"label": "",
- "type": "BeaconTimingAns",
- "longType": "MACCommand.BeaconTimingAns",
- "fullType": "ttn.lorawan.v3.MACCommand.BeaconTimingAns",
+ "type": "DataRateIndex",
+ "longType": "DataRateIndex",
+ "fullType": "ttn.lorawan.v3.DataRateIndex",
"ismap": false,
- "isoneof": true,
- "oneofdecl": "payload",
- "defaultValue": ""
- },
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "enum.defined_only",
+ "value": true
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "PingSlotInfoReq",
+ "longName": "MACCommand.PingSlotInfoReq",
+ "fullName": "ttn.lorawan.v3.MACCommand.PingSlotInfoReq",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "beacon_freq_req",
+ "name": "period",
"description": "",
"label": "",
- "type": "BeaconFreqReq",
- "longType": "MACCommand.BeaconFreqReq",
- "fullType": "ttn.lorawan.v3.MACCommand.BeaconFreqReq",
+ "type": "PingSlotPeriod",
+ "longType": "PingSlotPeriod",
+ "fullType": "ttn.lorawan.v3.PingSlotPeriod",
"ismap": false,
- "isoneof": true,
- "oneofdecl": "payload",
- "defaultValue": ""
- },
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "enum.defined_only",
+ "value": true
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "RejoinParamSetupAns",
+ "longName": "MACCommand.RejoinParamSetupAns",
+ "fullName": "ttn.lorawan.v3.MACCommand.RejoinParamSetupAns",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "beacon_freq_ans",
+ "name": "max_time_exponent_ack",
"description": "",
"label": "",
- "type": "BeaconFreqAns",
- "longType": "MACCommand.BeaconFreqAns",
- "fullType": "ttn.lorawan.v3.MACCommand.BeaconFreqAns",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
"ismap": false,
- "isoneof": true,
- "oneofdecl": "payload",
+ "isoneof": false,
+ "oneofdecl": "",
"defaultValue": ""
- },
+ }
+ ]
+ },
+ {
+ "name": "RejoinParamSetupReq",
+ "longName": "MACCommand.RejoinParamSetupReq",
+ "fullName": "ttn.lorawan.v3.MACCommand.RejoinParamSetupReq",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "device_mode_ind",
- "description": "",
+ "name": "max_count_exponent",
+ "description": "Exponent e that configures the rejoin counter = 2^(e+4) messages.",
"label": "",
- "type": "DeviceModeInd",
- "longType": "MACCommand.DeviceModeInd",
- "fullType": "ttn.lorawan.v3.MACCommand.DeviceModeInd",
+ "type": "RejoinCountExponent",
+ "longType": "RejoinCountExponent",
+ "fullType": "ttn.lorawan.v3.RejoinCountExponent",
"ismap": false,
- "isoneof": true,
- "oneofdecl": "payload",
- "defaultValue": ""
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "enum.defined_only",
+ "value": true
+ }
+ ]
+ }
},
{
- "name": "device_mode_conf",
- "description": "",
+ "name": "max_time_exponent",
+ "description": "Exponent e that configures the rejoin timer = 2^(e+10) seconds.",
"label": "",
- "type": "DeviceModeConf",
- "longType": "MACCommand.DeviceModeConf",
- "fullType": "ttn.lorawan.v3.MACCommand.DeviceModeConf",
+ "type": "RejoinTimeExponent",
+ "longType": "RejoinTimeExponent",
+ "fullType": "ttn.lorawan.v3.RejoinTimeExponent",
"ismap": false,
- "isoneof": true,
- "oneofdecl": "payload",
- "defaultValue": ""
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "enum.defined_only",
+ "value": true
+ }
+ ]
+ }
}
]
},
{
- "name": "ADRParamSetupReq",
- "longName": "MACCommand.ADRParamSetupReq",
- "fullName": "ttn.lorawan.v3.MACCommand.ADRParamSetupReq",
+ "name": "RekeyConf",
+ "longName": "MACCommand.RekeyConf",
+ "fullName": "ttn.lorawan.v3.MACCommand.RekeyConf",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -30651,12 +32585,12 @@
"extensions": [],
"fields": [
{
- "name": "adr_ack_limit_exponent",
- "description": "Exponent e that configures the ADR_ACK_LIMIT = 2^e messages.",
+ "name": "minor_version",
+ "description": "",
"label": "",
- "type": "ADRAckLimitExponent",
- "longType": "ADRAckLimitExponent",
- "fullType": "ttn.lorawan.v3.ADRAckLimitExponent",
+ "type": "Minor",
+ "longType": "Minor",
+ "fullType": "ttn.lorawan.v3.Minor",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -30669,14 +32603,26 @@
}
]
}
- },
+ }
+ ]
+ },
+ {
+ "name": "RekeyInd",
+ "longName": "MACCommand.RekeyInd",
+ "fullName": "ttn.lorawan.v3.MACCommand.RekeyInd",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "adr_ack_delay_exponent",
- "description": "Exponent e that configures the ADR_ACK_DELAY = 2^e messages.",
+ "name": "minor_version",
+ "description": "",
"label": "",
- "type": "ADRAckDelayExponent",
- "longType": "ADRAckDelayExponent",
- "fullType": "ttn.lorawan.v3.ADRAckDelayExponent",
+ "type": "Minor",
+ "longType": "Minor",
+ "fullType": "ttn.lorawan.v3.Minor",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -30693,9 +32639,9 @@
]
},
{
- "name": "BeaconFreqAns",
- "longName": "MACCommand.BeaconFreqAns",
- "fullName": "ttn.lorawan.v3.MACCommand.BeaconFreqAns",
+ "name": "RelayConfAns",
+ "longName": "MACCommand.RelayConfAns",
+ "fullName": "ttn.lorawan.v3.MACCommand.RelayConfAns",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -30703,7 +32649,67 @@
"extensions": [],
"fields": [
{
- "name": "frequency_ack",
+ "name": "second_channel_frequency_ack",
+ "description": "",
+ "label": "",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "second_channel_ack_offset_ack",
+ "description": "",
+ "label": "",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "second_channel_data_rate_index_ack",
+ "description": "",
+ "label": "",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "second_channel_index_ack",
+ "description": "",
+ "label": "",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "default_channel_index_ack",
+ "description": "",
+ "label": "",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "cad_periodicity_ack",
"description": "",
"label": "",
"type": "bool",
@@ -30717,9 +32723,9 @@
]
},
{
- "name": "BeaconFreqReq",
- "longName": "MACCommand.BeaconFreqReq",
- "fullName": "ttn.lorawan.v3.MACCommand.BeaconFreqReq",
+ "name": "RelayConfReq",
+ "longName": "MACCommand.RelayConfReq",
+ "fullName": "ttn.lorawan.v3.MACCommand.RelayConfReq",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -30727,35 +32733,23 @@
"extensions": [],
"fields": [
{
- "name": "frequency",
- "description": "Frequency of the Class B beacons (Hz).",
+ "name": "configuration",
+ "description": "",
"label": "",
- "type": "uint64",
- "longType": "uint64",
- "fullType": "uint64",
+ "type": "Configuration",
+ "longType": "MACCommand.RelayConfReq.Configuration",
+ "fullType": "ttn.lorawan.v3.MACCommand.RelayConfReq.Configuration",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "uint64.lte",
- "value": 0
- },
- {
- "name": "uint64.gte",
- "value": 100000
- }
- ]
- }
+ "defaultValue": ""
}
]
},
{
- "name": "BeaconTimingAns",
- "longName": "MACCommand.BeaconTimingAns",
- "fullName": "ttn.lorawan.v3.MACCommand.BeaconTimingAns",
+ "name": "Configuration",
+ "longName": "MACCommand.RelayConfReq.Configuration",
+ "fullName": "ttn.lorawan.v3.MACCommand.RelayConfReq.Configuration",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -30763,8 +32757,20 @@
"extensions": [],
"fields": [
{
- "name": "delay",
- "description": "(uint16) See LoRaWAN specification.",
+ "name": "second_channel",
+ "description": "",
+ "label": "",
+ "type": "RelaySecondChannel",
+ "longType": "RelaySecondChannel",
+ "fullType": "ttn.lorawan.v3.RelaySecondChannel",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "default_channel_index",
+ "description": "",
"label": "",
"type": "uint32",
"longType": "uint32",
@@ -30777,18 +32783,18 @@
"validate.rules": [
{
"name": "uint32.lte",
- "value": 65535
+ "value": 255
}
]
}
},
{
- "name": "channel_index",
+ "name": "cad_periodicity",
"description": "",
"label": "",
- "type": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
+ "type": "RelayCADPeriodicity",
+ "longType": "RelayCADPeriodicity",
+ "fullType": "ttn.lorawan.v3.RelayCADPeriodicity",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -30796,8 +32802,8 @@
"options": {
"validate.rules": [
{
- "name": "uint32.lte",
- "value": 255
+ "name": "enum.defined_only",
+ "value": true
}
]
}
@@ -30805,9 +32811,20 @@
]
},
{
- "name": "DLChannelAns",
- "longName": "MACCommand.DLChannelAns",
- "fullName": "ttn.lorawan.v3.MACCommand.DLChannelAns",
+ "name": "RelayConfigureFwdLimitAns",
+ "longName": "MACCommand.RelayConfigureFwdLimitAns",
+ "fullName": "ttn.lorawan.v3.MACCommand.RelayConfigureFwdLimitAns",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": false,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": []
+ },
+ {
+ "name": "RelayConfigureFwdLimitReq",
+ "longName": "MACCommand.RelayConfigureFwdLimitReq",
+ "fullName": "ttn.lorawan.v3.MACCommand.RelayConfigureFwdLimitReq",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -30815,24 +32832,60 @@
"extensions": [],
"fields": [
{
- "name": "channel_index_ack",
+ "name": "reset_limit_counter",
"description": "",
"label": "",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
+ "type": "RelayResetLimitCounter",
+ "longType": "RelayResetLimitCounter",
+ "fullType": "ttn.lorawan.v3.RelayResetLimitCounter",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "frequency_ack",
+ "name": "join_request_limits",
"description": "",
"label": "",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
+ "type": "RelayForwardLimits",
+ "longType": "RelayForwardLimits",
+ "fullType": "ttn.lorawan.v3.RelayForwardLimits",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "notify_limits",
+ "description": "",
+ "label": "",
+ "type": "RelayForwardLimits",
+ "longType": "RelayForwardLimits",
+ "fullType": "ttn.lorawan.v3.RelayForwardLimits",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "global_uplink_limits",
+ "description": "",
+ "label": "",
+ "type": "RelayForwardLimits",
+ "longType": "RelayForwardLimits",
+ "fullType": "ttn.lorawan.v3.RelayForwardLimits",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "overall_limits",
+ "description": "",
+ "label": "",
+ "type": "RelayForwardLimits",
+ "longType": "RelayForwardLimits",
+ "fullType": "ttn.lorawan.v3.RelayForwardLimits",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -30841,9 +32894,9 @@
]
},
{
- "name": "DLChannelReq",
- "longName": "MACCommand.DLChannelReq",
- "fullName": "ttn.lorawan.v3.MACCommand.DLChannelReq",
+ "name": "RelayCtrlUplinkListAns",
+ "longName": "MACCommand.RelayCtrlUplinkListAns",
+ "fullName": "ttn.lorawan.v3.MACCommand.RelayCtrlUplinkListAns",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -30851,51 +32904,35 @@
"extensions": [],
"fields": [
{
- "name": "channel_index",
+ "name": "rule_index_ack",
"description": "",
"label": "",
- "type": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "uint32.lte",
- "value": 255
- }
- ]
- }
+ "defaultValue": ""
},
{
- "name": "frequency",
- "description": "Downlink channel frequency (Hz).",
+ "name": "w_f_cnt",
+ "description": "",
"label": "",
- "type": "uint64",
- "longType": "uint64",
- "fullType": "uint64",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "uint64.gte",
- "value": 100000
- }
- ]
- }
+ "defaultValue": ""
}
]
},
{
- "name": "DevStatusAns",
- "longName": "MACCommand.DevStatusAns",
- "fullName": "ttn.lorawan.v3.MACCommand.DevStatusAns",
+ "name": "RelayCtrlUplinkListReq",
+ "longName": "MACCommand.RelayCtrlUplinkListReq",
+ "fullName": "ttn.lorawan.v3.MACCommand.RelayCtrlUplinkListReq",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -30903,8 +32940,8 @@
"extensions": [],
"fields": [
{
- "name": "battery",
- "description": "Device battery status.\n0 indicates that the device is connected to an external power source.\n1..254 indicates a battery level.\n255 indicates that the device was not able to measure the battery level.",
+ "name": "rule_index",
+ "description": "",
"label": "",
"type": "uint32",
"longType": "uint32",
@@ -30917,41 +32954,29 @@
"validate.rules": [
{
"name": "uint32.lte",
- "value": 255
+ "value": 15
}
]
}
},
{
- "name": "margin",
- "description": "SNR of the last downlink (dB; [-32, +31]).",
+ "name": "action",
+ "description": "",
"label": "",
- "type": "int32",
- "longType": "int32",
- "fullType": "int32",
+ "type": "RelayCtrlUplinkListAction",
+ "longType": "RelayCtrlUplinkListAction",
+ "fullType": "ttn.lorawan.v3.RelayCtrlUplinkListAction",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "int32.lte",
- "value": 31
- },
- {
- "name": "int32.gte",
- "value": -32
- }
- ]
- }
+ "defaultValue": ""
}
]
},
{
- "name": "DeviceModeConf",
- "longName": "MACCommand.DeviceModeConf",
- "fullName": "ttn.lorawan.v3.MACCommand.DeviceModeConf",
+ "name": "RelayEndDeviceConfAns",
+ "longName": "MACCommand.RelayEndDeviceConfAns",
+ "fullName": "ttn.lorawan.v3.MACCommand.RelayEndDeviceConfAns",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -30959,95 +32984,59 @@
"extensions": [],
"fields": [
{
- "name": "class",
+ "name": "second_channel_frequency_ack",
"description": "",
"label": "",
- "type": "Class",
- "longType": "Class",
- "fullType": "ttn.lorawan.v3.Class",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "enum.defined_only",
- "value": true
- }
- ]
- }
- }
- ]
- },
- {
- "name": "DeviceModeInd",
- "longName": "MACCommand.DeviceModeInd",
- "fullName": "ttn.lorawan.v3.MACCommand.DeviceModeInd",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ "defaultValue": ""
+ },
{
- "name": "class",
+ "name": "second_channel_data_rate_index_ack",
"description": "",
"label": "",
- "type": "Class",
- "longType": "Class",
- "fullType": "ttn.lorawan.v3.Class",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "enum.defined_only",
- "value": true
- }
- ]
- }
- }
- ]
- },
- {
- "name": "DeviceTimeAns",
- "longName": "MACCommand.DeviceTimeAns",
- "fullName": "ttn.lorawan.v3.MACCommand.DeviceTimeAns",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ "defaultValue": ""
+ },
+ {
+ "name": "second_channel_index_ack",
+ "description": "",
+ "label": "",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
{
- "name": "time",
+ "name": "backoff_ack",
"description": "",
"label": "",
- "type": "Timestamp",
- "longType": "google.protobuf.Timestamp",
- "fullType": "google.protobuf.Timestamp",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "timestamp.required",
- "value": true
- }
- ]
- }
+ "defaultValue": ""
}
]
},
{
- "name": "DutyCycleReq",
- "longName": "MACCommand.DutyCycleReq",
- "fullName": "ttn.lorawan.v3.MACCommand.DutyCycleReq",
+ "name": "RelayEndDeviceConfReq",
+ "longName": "MACCommand.RelayEndDeviceConfReq",
+ "fullName": "ttn.lorawan.v3.MACCommand.RelayEndDeviceConfReq",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -31055,79 +33044,67 @@
"extensions": [],
"fields": [
{
- "name": "max_duty_cycle",
+ "name": "configuration",
"description": "",
"label": "",
- "type": "AggregatedDutyCycle",
- "longType": "AggregatedDutyCycle",
- "fullType": "ttn.lorawan.v3.AggregatedDutyCycle",
+ "type": "Configuration",
+ "longType": "MACCommand.RelayEndDeviceConfReq.Configuration",
+ "fullType": "ttn.lorawan.v3.MACCommand.RelayEndDeviceConfReq.Configuration",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "enum.defined_only",
- "value": true
- }
- ]
- }
+ "defaultValue": ""
}
]
},
{
- "name": "ForceRejoinReq",
- "longName": "MACCommand.ForceRejoinReq",
- "fullName": "ttn.lorawan.v3.MACCommand.ForceRejoinReq",
+ "name": "Configuration",
+ "longName": "MACCommand.RelayEndDeviceConfReq.Configuration",
+ "fullName": "ttn.lorawan.v3.MACCommand.RelayEndDeviceConfReq.Configuration",
"description": "",
"hasExtensions": false,
"hasFields": true,
- "hasOneofs": false,
+ "hasOneofs": true,
"extensions": [],
"fields": [
{
- "name": "rejoin_type",
+ "name": "always",
"description": "",
"label": "",
- "type": "RejoinRequestType",
- "longType": "RejoinRequestType",
- "fullType": "ttn.lorawan.v3.RejoinRequestType",
+ "type": "RelayEndDeviceAlwaysMode",
+ "longType": "RelayEndDeviceAlwaysMode",
+ "fullType": "ttn.lorawan.v3.RelayEndDeviceAlwaysMode",
"ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "enum.defined_only",
- "value": true
- }
- ]
- }
+ "isoneof": true,
+ "oneofdecl": "mode",
+ "defaultValue": ""
},
{
- "name": "data_rate_index",
+ "name": "dynamic",
"description": "",
"label": "",
- "type": "DataRateIndex",
- "longType": "DataRateIndex",
- "fullType": "ttn.lorawan.v3.DataRateIndex",
+ "type": "RelayEndDeviceDynamicMode",
+ "longType": "RelayEndDeviceDynamicMode",
+ "fullType": "ttn.lorawan.v3.RelayEndDeviceDynamicMode",
"ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "enum.defined_only",
- "value": true
- }
- ]
- }
+ "isoneof": true,
+ "oneofdecl": "mode",
+ "defaultValue": ""
},
{
- "name": "max_retries",
+ "name": "end_device_controlled",
+ "description": "",
+ "label": "",
+ "type": "RelayEndDeviceControlledMode",
+ "longType": "RelayEndDeviceControlledMode",
+ "fullType": "ttn.lorawan.v3.RelayEndDeviceControlledMode",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "mode",
+ "defaultValue": ""
+ },
+ {
+ "name": "backoff",
"description": "",
"label": "",
"type": "uint32",
@@ -31141,18 +33118,30 @@
"validate.rules": [
{
"name": "uint32.lte",
- "value": 7
+ "value": 63
}
]
}
},
{
- "name": "period_exponent",
- "description": "Exponent e that configures the rejoin period = 32 * 2^e + rand(0,32) seconds.",
+ "name": "second_channel",
+ "description": "",
"label": "",
- "type": "RejoinPeriodExponent",
- "longType": "RejoinPeriodExponent",
- "fullType": "ttn.lorawan.v3.RejoinPeriodExponent",
+ "type": "RelaySecondChannel",
+ "longType": "RelaySecondChannel",
+ "fullType": "ttn.lorawan.v3.RelaySecondChannel",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "serving_device_id",
+ "description": "",
+ "label": "",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -31160,8 +33149,12 @@
"options": {
"validate.rules": [
{
- "name": "enum.defined_only",
- "value": true
+ "name": "string.max_len",
+ "value": 36
+ },
+ {
+ "name": "string.pattern",
+ "value": "^[a-z0-9](?:[-]?[a-z0-9]){2,}$"
}
]
}
@@ -31169,9 +33162,9 @@
]
},
{
- "name": "LinkADRAns",
- "longName": "MACCommand.LinkADRAns",
- "fullName": "ttn.lorawan.v3.MACCommand.LinkADRAns",
+ "name": "RelayNotifyNewEndDeviceReq",
+ "longName": "MACCommand.RelayNotifyNewEndDeviceReq",
+ "fullName": "ttn.lorawan.v3.MACCommand.RelayNotifyNewEndDeviceReq",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -31179,47 +33172,90 @@
"extensions": [],
"fields": [
{
- "name": "channel_mask_ack",
+ "name": "dev_addr",
"description": "",
"label": "",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "bytes.len",
+ "value": 4
+ }
+ ]
+ }
},
{
- "name": "data_rate_index_ack",
+ "name": "snr",
"description": "",
"label": "",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
+ "type": "int32",
+ "longType": "int32",
+ "fullType": "int32",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "int32.lte",
+ "value": 11
+ },
+ {
+ "name": "int32.gte",
+ "value": -20
+ }
+ ]
+ }
},
{
- "name": "tx_power_index_ack",
+ "name": "rssi",
"description": "",
"label": "",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
+ "type": "int32",
+ "longType": "int32",
+ "fullType": "int32",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "int32.lte",
+ "value": -15
+ },
+ {
+ "name": "int32.gte",
+ "value": -142
+ }
+ ]
+ }
}
]
},
{
- "name": "LinkADRReq",
- "longName": "MACCommand.LinkADRReq",
- "fullName": "ttn.lorawan.v3.MACCommand.LinkADRReq",
+ "name": "RelayUpdateUplinkListAns",
+ "longName": "MACCommand.RelayUpdateUplinkListAns",
+ "fullName": "ttn.lorawan.v3.MACCommand.RelayUpdateUplinkListAns",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": false,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": []
+ },
+ {
+ "name": "RelayUpdateUplinkListReq",
+ "longName": "MACCommand.RelayUpdateUplinkListReq",
+ "fullName": "ttn.lorawan.v3.MACCommand.RelayUpdateUplinkListReq",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -31227,12 +33263,12 @@
"extensions": [],
"fields": [
{
- "name": "data_rate_index",
+ "name": "rule_index",
"description": "",
"label": "",
- "type": "DataRateIndex",
- "longType": "DataRateIndex",
- "fullType": "ttn.lorawan.v3.DataRateIndex",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -31240,39 +33276,31 @@
"options": {
"validate.rules": [
{
- "name": "enum.defined_only",
- "value": true
+ "name": "uint32.lte",
+ "value": 15
}
]
}
},
{
- "name": "tx_power_index",
+ "name": "forward_limits",
"description": "",
"label": "",
- "type": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
+ "type": "RelayUplinkForwardLimits",
+ "longType": "RelayUplinkForwardLimits",
+ "fullType": "ttn.lorawan.v3.RelayUplinkForwardLimits",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "uint32.lte",
- "value": 15
- }
- ]
- }
+ "defaultValue": ""
},
{
- "name": "channel_mask",
+ "name": "dev_addr",
"description": "",
- "label": "repeated",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
+ "label": "",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -31280,14 +33308,14 @@
"options": {
"validate.rules": [
{
- "name": "repeated.max_items",
- "value": 16
+ "name": "bytes.len",
+ "value": 4
}
]
}
},
{
- "name": "channel_mask_control",
+ "name": "w_f_cnt",
"description": "",
"label": "",
"type": "uint32",
@@ -31296,23 +33324,35 @@
"ismap": false,
"isoneof": false,
"oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "root_wor_s_key",
+ "description": "",
+ "label": "",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
"defaultValue": "",
"options": {
"validate.rules": [
{
- "name": "uint32.lte",
- "value": 7
+ "name": "bytes.len",
+ "value": 16
}
]
}
},
{
- "name": "nb_trans",
+ "name": "device_id",
"description": "",
"label": "",
- "type": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -31320,18 +33360,34 @@
"options": {
"validate.rules": [
{
- "name": "uint32.lte",
- "value": 15
+ "name": "string.max_len",
+ "value": 36
+ },
+ {
+ "name": "string.pattern",
+ "value": "^[a-z0-9](?:[-]?[a-z0-9]){2,}$"
}
]
}
+ },
+ {
+ "name": "session_key_id",
+ "description": "",
+ "label": "",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
}
]
},
{
- "name": "LinkCheckAns",
- "longName": "MACCommand.LinkCheckAns",
- "fullName": "ttn.lorawan.v3.MACCommand.LinkCheckAns",
+ "name": "ResetConf",
+ "longName": "MACCommand.ResetConf",
+ "fullName": "ttn.lorawan.v3.MACCommand.ResetConf",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -31339,12 +33395,12 @@
"extensions": [],
"fields": [
{
- "name": "margin",
- "description": "Indicates the link margin in dB of the received LinkCheckReq, relative to the demodulation floor.",
+ "name": "minor_version",
+ "description": "",
"label": "",
- "type": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
+ "type": "Minor",
+ "longType": "Minor",
+ "fullType": "ttn.lorawan.v3.Minor",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -31352,19 +33408,37 @@
"options": {
"validate.rules": [
{
- "name": "uint32.lte",
- "value": 254
+ "name": "enum.defined_only",
+ "value": true
+ },
+ {
+ "name": "enum.in",
+ "value": [
+ 1
+ ]
}
]
}
- },
+ }
+ ]
+ },
+ {
+ "name": "ResetInd",
+ "longName": "MACCommand.ResetInd",
+ "fullName": "ttn.lorawan.v3.MACCommand.ResetInd",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "gateway_count",
+ "name": "minor_version",
"description": "",
"label": "",
- "type": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
+ "type": "Minor",
+ "longType": "Minor",
+ "fullType": "ttn.lorawan.v3.Minor",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -31372,8 +33446,14 @@
"options": {
"validate.rules": [
{
- "name": "uint32.lte",
- "value": 255
+ "name": "enum.defined_only",
+ "value": true
+ },
+ {
+ "name": "enum.in",
+ "value": [
+ 1
+ ]
}
]
}
@@ -31381,9 +33461,9 @@
]
},
{
- "name": "NewChannelAns",
- "longName": "MACCommand.NewChannelAns",
- "fullName": "ttn.lorawan.v3.MACCommand.NewChannelAns",
+ "name": "RxParamSetupAns",
+ "longName": "MACCommand.RxParamSetupAns",
+ "fullName": "ttn.lorawan.v3.MACCommand.RxParamSetupAns",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -31391,7 +33471,7 @@
"extensions": [],
"fields": [
{
- "name": "frequency_ack",
+ "name": "rx2_data_rate_index_ack",
"description": "",
"label": "",
"type": "bool",
@@ -31403,7 +33483,19 @@
"defaultValue": ""
},
{
- "name": "data_rate_ack",
+ "name": "rx1_data_rate_offset_ack",
+ "description": "",
+ "label": "",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "rx2_frequency_ack",
"description": "",
"label": "",
"type": "bool",
@@ -31417,9 +33509,9 @@
]
},
{
- "name": "NewChannelReq",
- "longName": "MACCommand.NewChannelReq",
- "fullName": "ttn.lorawan.v3.MACCommand.NewChannelReq",
+ "name": "RxParamSetupReq",
+ "longName": "MACCommand.RxParamSetupReq",
+ "fullName": "ttn.lorawan.v3.MACCommand.RxParamSetupReq",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -31427,32 +33519,12 @@
"extensions": [],
"fields": [
{
- "name": "channel_index",
+ "name": "rx2_data_rate_index",
"description": "",
"label": "",
- "type": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "uint32.lte",
- "value": 255
- }
- ]
- }
- },
- {
- "name": "frequency",
- "description": "Channel frequency (Hz).",
- "label": "",
- "type": "uint64",
- "longType": "uint64",
- "fullType": "uint64",
+ "type": "DataRateIndex",
+ "longType": "DataRateIndex",
+ "fullType": "ttn.lorawan.v3.DataRateIndex",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -31460,23 +33532,19 @@
"options": {
"validate.rules": [
{
- "name": "uint64.lte",
- "value": 0
- },
- {
- "name": "uint64.gte",
- "value": 100000
+ "name": "enum.defined_only",
+ "value": true
}
]
}
},
{
- "name": "min_data_rate_index",
+ "name": "rx1_data_rate_offset",
"description": "",
"label": "",
- "type": "DataRateIndex",
- "longType": "DataRateIndex",
- "fullType": "ttn.lorawan.v3.DataRateIndex",
+ "type": "DataRateOffset",
+ "longType": "DataRateOffset",
+ "fullType": "ttn.lorawan.v3.DataRateOffset",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -31491,12 +33559,12 @@
}
},
{
- "name": "max_data_rate_index",
- "description": "",
+ "name": "rx2_frequency",
+ "description": "Rx2 frequency (Hz).",
"label": "",
- "type": "DataRateIndex",
- "longType": "DataRateIndex",
- "fullType": "ttn.lorawan.v3.DataRateIndex",
+ "type": "uint64",
+ "longType": "uint64",
+ "fullType": "uint64",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -31504,8 +33572,8 @@
"options": {
"validate.rules": [
{
- "name": "enum.defined_only",
- "value": true
+ "name": "uint64.gte",
+ "value": 100000
}
]
}
@@ -31513,9 +33581,9 @@
]
},
{
- "name": "PingSlotChannelAns",
- "longName": "MACCommand.PingSlotChannelAns",
- "fullName": "ttn.lorawan.v3.MACCommand.PingSlotChannelAns",
+ "name": "RxTimingSetupReq",
+ "longName": "MACCommand.RxTimingSetupReq",
+ "fullName": "ttn.lorawan.v3.MACCommand.RxTimingSetupReq",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -31523,35 +33591,31 @@
"extensions": [],
"fields": [
{
- "name": "frequency_ack",
- "description": "",
- "label": "",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
- },
- {
- "name": "data_rate_index_ack",
+ "name": "delay",
"description": "",
"label": "",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
+ "type": "RxDelay",
+ "longType": "RxDelay",
+ "fullType": "ttn.lorawan.v3.RxDelay",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "enum.defined_only",
+ "value": true
+ }
+ ]
+ }
}
]
},
{
- "name": "PingSlotChannelReq",
- "longName": "MACCommand.PingSlotChannelReq",
- "fullName": "ttn.lorawan.v3.MACCommand.PingSlotChannelReq",
+ "name": "TxParamSetupReq",
+ "longName": "MACCommand.TxParamSetupReq",
+ "fullName": "ttn.lorawan.v3.MACCommand.TxParamSetupReq",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -31559,12 +33623,12 @@
"extensions": [],
"fields": [
{
- "name": "frequency",
- "description": "Ping slot channel frequency (Hz).",
+ "name": "max_eirp_index",
+ "description": "Indicates the maximum EIRP value in dBm, indexed by the following vector:\n[ 8 10 12 13 14 16 18 20 21 24 26 27 29 30 33 36 ]",
"label": "",
- "type": "uint64",
- "longType": "uint64",
- "fullType": "uint64",
+ "type": "DeviceEIRP",
+ "longType": "DeviceEIRP",
+ "fullType": "ttn.lorawan.v3.DeviceEIRP",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -31572,74 +33636,42 @@
"options": {
"validate.rules": [
{
- "name": "uint64.lte",
- "value": 0
- },
- {
- "name": "uint64.gte",
- "value": 100000
+ "name": "enum.defined_only",
+ "value": true
}
]
}
},
{
- "name": "data_rate_index",
+ "name": "uplink_dwell_time",
"description": "",
"label": "",
- "type": "DataRateIndex",
- "longType": "DataRateIndex",
- "fullType": "ttn.lorawan.v3.DataRateIndex",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "enum.defined_only",
- "value": true
- }
- ]
- }
- }
- ]
- },
- {
- "name": "PingSlotInfoReq",
- "longName": "MACCommand.PingSlotInfoReq",
- "fullName": "ttn.lorawan.v3.MACCommand.PingSlotInfoReq",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ "defaultValue": ""
+ },
{
- "name": "period",
+ "name": "downlink_dwell_time",
"description": "",
"label": "",
- "type": "PingSlotPeriod",
- "longType": "PingSlotPeriod",
- "fullType": "ttn.lorawan.v3.PingSlotPeriod",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "enum.defined_only",
- "value": true
- }
- ]
- }
+ "defaultValue": ""
}
]
},
{
- "name": "RejoinParamSetupAns",
- "longName": "MACCommand.RejoinParamSetupAns",
- "fullName": "ttn.lorawan.v3.MACCommand.RejoinParamSetupAns",
+ "name": "MACCommands",
+ "longName": "MACCommands",
+ "fullName": "ttn.lorawan.v3.MACCommands",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -31647,12 +33679,12 @@
"extensions": [],
"fields": [
{
- "name": "max_time_exponent_ack",
+ "name": "commands",
"description": "",
- "label": "",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
+ "label": "repeated",
+ "type": "MACCommand",
+ "longType": "MACCommand",
+ "fullType": "ttn.lorawan.v3.MACCommand",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -31661,9 +33693,9 @@
]
},
{
- "name": "RejoinParamSetupReq",
- "longName": "MACCommand.RejoinParamSetupReq",
- "fullName": "ttn.lorawan.v3.MACCommand.RejoinParamSetupReq",
+ "name": "MACPayload",
+ "longName": "MACPayload",
+ "fullName": "ttn.lorawan.v3.MACPayload",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -31671,12 +33703,12 @@
"extensions": [],
"fields": [
{
- "name": "max_count_exponent",
- "description": "Exponent e that configures the rejoin counter = 2^(e+4) messages.",
+ "name": "f_hdr",
+ "description": "",
"label": "",
- "type": "RejoinCountExponent",
- "longType": "RejoinCountExponent",
- "fullType": "ttn.lorawan.v3.RejoinCountExponent",
+ "type": "FHDR",
+ "longType": "FHDR",
+ "fullType": "ttn.lorawan.v3.FHDR",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -31684,19 +33716,19 @@
"options": {
"validate.rules": [
{
- "name": "enum.defined_only",
+ "name": "message.required",
"value": true
}
]
}
},
{
- "name": "max_time_exponent",
- "description": "Exponent e that configures the rejoin timer = 2^(e+10) seconds.",
+ "name": "f_port",
+ "description": "",
"label": "",
- "type": "RejoinTimeExponent",
- "longType": "RejoinTimeExponent",
- "fullType": "ttn.lorawan.v3.RejoinTimeExponent",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -31704,18 +33736,54 @@
"options": {
"validate.rules": [
{
- "name": "enum.defined_only",
- "value": true
+ "name": "uint32.lte",
+ "value": 255
}
]
}
+ },
+ {
+ "name": "frm_payload",
+ "description": "",
+ "label": "",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "decoded_payload",
+ "description": "",
+ "label": "",
+ "type": "Struct",
+ "longType": "google.protobuf.Struct",
+ "fullType": "google.protobuf.Struct",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "full_f_cnt",
+ "description": "Full 32-bit FCnt value. Used internally by Network Server.",
+ "label": "",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
}
]
},
{
- "name": "RekeyConf",
- "longName": "MACCommand.RekeyConf",
- "fullName": "ttn.lorawan.v3.MACCommand.RekeyConf",
+ "name": "MHDR",
+ "longName": "MHDR",
+ "fullName": "ttn.lorawan.v3.MHDR",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -31723,12 +33791,12 @@
"extensions": [],
"fields": [
{
- "name": "minor_version",
+ "name": "m_type",
"description": "",
"label": "",
- "type": "Minor",
- "longType": "Minor",
- "fullType": "ttn.lorawan.v3.Minor",
+ "type": "MType",
+ "longType": "MType",
+ "fullType": "ttn.lorawan.v3.MType",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -31741,26 +33809,14 @@
}
]
}
- }
- ]
- },
- {
- "name": "RekeyInd",
- "longName": "MACCommand.RekeyInd",
- "fullName": "ttn.lorawan.v3.MACCommand.RekeyInd",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ },
{
- "name": "minor_version",
+ "name": "major",
"description": "",
"label": "",
- "type": "Minor",
- "longType": "Minor",
- "fullType": "ttn.lorawan.v3.Minor",
+ "type": "Major",
+ "longType": "Major",
+ "fullType": "ttn.lorawan.v3.Major",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -31777,22 +33833,22 @@
]
},
{
- "name": "ResetConf",
- "longName": "MACCommand.ResetConf",
- "fullName": "ttn.lorawan.v3.MACCommand.ResetConf",
- "description": "",
+ "name": "Message",
+ "longName": "Message",
+ "fullName": "ttn.lorawan.v3.Message",
+ "description": "Message represents a LoRaWAN message",
"hasExtensions": false,
"hasFields": true,
- "hasOneofs": false,
+ "hasOneofs": true,
"extensions": [],
"fields": [
{
- "name": "minor_version",
+ "name": "m_hdr",
"description": "",
"label": "",
- "type": "Minor",
- "longType": "Minor",
- "fullType": "ttn.lorawan.v3.Minor",
+ "type": "MHDR",
+ "longType": "MHDR",
+ "fullType": "ttn.lorawan.v3.MHDR",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -31800,37 +33856,19 @@
"options": {
"validate.rules": [
{
- "name": "enum.defined_only",
+ "name": "message.required",
"value": true
- },
- {
- "name": "enum.in",
- "value": [
- 1
- ]
}
]
}
- }
- ]
- },
- {
- "name": "ResetInd",
- "longName": "MACCommand.ResetInd",
- "fullName": "ttn.lorawan.v3.MACCommand.ResetInd",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ },
{
- "name": "minor_version",
+ "name": "mic",
"description": "",
"label": "",
- "type": "Minor",
- "longType": "Minor",
- "fullType": "ttn.lorawan.v3.Minor",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -31838,72 +33876,102 @@
"options": {
"validate.rules": [
{
- "name": "enum.defined_only",
- "value": true
+ "name": "bytes.min_len",
+ "value": 0
},
{
- "name": "enum.in",
- "value": [
- 1
- ]
+ "name": "bytes.max_len",
+ "value": 4
}
]
}
- }
- ]
- },
- {
- "name": "RxParamSetupAns",
- "longName": "MACCommand.RxParamSetupAns",
- "fullName": "ttn.lorawan.v3.MACCommand.RxParamSetupAns",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ },
{
- "name": "rx2_data_rate_index_ack",
+ "name": "mac_payload",
"description": "",
"label": "",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
+ "type": "MACPayload",
+ "longType": "MACPayload",
+ "fullType": "ttn.lorawan.v3.MACPayload",
"ismap": false,
- "isoneof": false,
- "oneofdecl": "",
+ "isoneof": true,
+ "oneofdecl": "Payload",
"defaultValue": ""
},
{
- "name": "rx1_data_rate_offset_ack",
+ "name": "join_request_payload",
"description": "",
"label": "",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
+ "type": "JoinRequestPayload",
+ "longType": "JoinRequestPayload",
+ "fullType": "ttn.lorawan.v3.JoinRequestPayload",
"ismap": false,
- "isoneof": false,
- "oneofdecl": "",
+ "isoneof": true,
+ "oneofdecl": "Payload",
+ "defaultValue": ""
+ },
+ {
+ "name": "join_accept_payload",
+ "description": "",
+ "label": "",
+ "type": "JoinAcceptPayload",
+ "longType": "JoinAcceptPayload",
+ "fullType": "ttn.lorawan.v3.JoinAcceptPayload",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "Payload",
"defaultValue": ""
},
{
- "name": "rx2_frequency_ack",
+ "name": "rejoin_request_payload",
+ "description": "",
+ "label": "",
+ "type": "RejoinRequestPayload",
+ "longType": "RejoinRequestPayload",
+ "fullType": "ttn.lorawan.v3.RejoinRequestPayload",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "Payload",
+ "defaultValue": ""
+ }
+ ]
+ },
+ {
+ "name": "PingSlotPeriodValue",
+ "longName": "PingSlotPeriodValue",
+ "fullName": "ttn.lorawan.v3.PingSlotPeriodValue",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "value",
"description": "",
"label": "",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
+ "type": "PingSlotPeriod",
+ "longType": "PingSlotPeriod",
+ "fullType": "ttn.lorawan.v3.PingSlotPeriod",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "enum.defined_only",
+ "value": true
+ }
+ ]
+ }
}
]
},
{
- "name": "RxParamSetupReq",
- "longName": "MACCommand.RxParamSetupReq",
- "fullName": "ttn.lorawan.v3.MACCommand.RxParamSetupReq",
+ "name": "RejoinRequestPayload",
+ "longName": "RejoinRequestPayload",
+ "fullName": "ttn.lorawan.v3.RejoinRequestPayload",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -31911,12 +33979,12 @@
"extensions": [],
"fields": [
{
- "name": "rx2_data_rate_index",
+ "name": "rejoin_type",
"description": "",
"label": "",
- "type": "DataRateIndex",
- "longType": "DataRateIndex",
- "fullType": "ttn.lorawan.v3.DataRateIndex",
+ "type": "RejoinRequestType",
+ "longType": "RejoinRequestType",
+ "fullType": "ttn.lorawan.v3.RejoinRequestType",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -31931,12 +33999,12 @@
}
},
{
- "name": "rx1_data_rate_offset",
+ "name": "net_id",
"description": "",
"label": "",
- "type": "DataRateOffset",
- "longType": "DataRateOffset",
- "fullType": "ttn.lorawan.v3.DataRateOffset",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -31944,19 +34012,19 @@
"options": {
"validate.rules": [
{
- "name": "enum.defined_only",
- "value": true
+ "name": "bytes.len",
+ "value": 3
}
]
}
},
{
- "name": "rx2_frequency",
- "description": "Rx2 frequency (Hz).",
+ "name": "join_eui",
+ "description": "",
"label": "",
- "type": "uint64",
- "longType": "uint64",
- "fullType": "uint64",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -31964,31 +34032,19 @@
"options": {
"validate.rules": [
{
- "name": "uint64.gte",
- "value": 100000
+ "name": "bytes.len",
+ "value": 8
}
]
}
- }
- ]
- },
- {
- "name": "RxTimingSetupReq",
- "longName": "MACCommand.RxTimingSetupReq",
- "fullName": "ttn.lorawan.v3.MACCommand.RxTimingSetupReq",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ },
{
- "name": "delay",
+ "name": "dev_eui",
"description": "",
"label": "",
- "type": "RxDelay",
- "longType": "RxDelay",
- "fullType": "ttn.lorawan.v3.RxDelay",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -31996,18 +34052,52 @@
"options": {
"validate.rules": [
{
- "name": "enum.defined_only",
- "value": true
+ "name": "bytes.len",
+ "value": 8
}
]
}
+ },
+ {
+ "name": "rejoin_cnt",
+ "description": "Contains RJCount0 or RJCount1 depending on rejoin_type.",
+ "label": "",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
}
]
},
{
- "name": "TxParamSetupReq",
- "longName": "MACCommand.TxParamSetupReq",
- "fullName": "ttn.lorawan.v3.MACCommand.TxParamSetupReq",
+ "name": "RelayEndDeviceAlwaysMode",
+ "longName": "RelayEndDeviceAlwaysMode",
+ "fullName": "ttn.lorawan.v3.RelayEndDeviceAlwaysMode",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": false,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": []
+ },
+ {
+ "name": "RelayEndDeviceControlledMode",
+ "longName": "RelayEndDeviceControlledMode",
+ "fullName": "ttn.lorawan.v3.RelayEndDeviceControlledMode",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": false,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": []
+ },
+ {
+ "name": "RelayEndDeviceDynamicMode",
+ "longName": "RelayEndDeviceDynamicMode",
+ "fullName": "ttn.lorawan.v3.RelayEndDeviceDynamicMode",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -32015,12 +34105,12 @@
"extensions": [],
"fields": [
{
- "name": "max_eirp_index",
- "description": "Indicates the maximum EIRP value in dBm, indexed by the following vector:\n[ 8 10 12 13 14 16 18 20 21 24 26 27 29 30 33 36 ]",
+ "name": "smart_enable_level",
+ "description": "The number of consecutive uplinks without a valid downlink before the end device attempts\nto use the relay mode to transmit messages.",
"label": "",
- "type": "DeviceEIRP",
- "longType": "DeviceEIRP",
- "fullType": "ttn.lorawan.v3.DeviceEIRP",
+ "type": "RelaySmartEnableLevel",
+ "longType": "RelaySmartEnableLevel",
+ "fullType": "ttn.lorawan.v3.RelaySmartEnableLevel",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -32033,37 +34123,13 @@
}
]
}
- },
- {
- "name": "uplink_dwell_time",
- "description": "",
- "label": "",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
- },
- {
- "name": "downlink_dwell_time",
- "description": "",
- "label": "",
- "type": "bool",
- "longType": "bool",
- "fullType": "bool",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": ""
}
]
},
{
- "name": "MACCommands",
- "longName": "MACCommands",
- "fullName": "ttn.lorawan.v3.MACCommands",
+ "name": "RelayForwardDownlinkReq",
+ "longName": "RelayForwardDownlinkReq",
+ "fullName": "ttn.lorawan.v3.RelayForwardDownlinkReq",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -32071,12 +34137,12 @@
"extensions": [],
"fields": [
{
- "name": "commands",
+ "name": "raw_payload",
"description": "",
- "label": "repeated",
- "type": "MACCommand",
- "longType": "MACCommand",
- "fullType": "ttn.lorawan.v3.MACCommand",
+ "label": "",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -32085,9 +34151,9 @@
]
},
{
- "name": "MACPayload",
- "longName": "MACPayload",
- "fullName": "ttn.lorawan.v3.MACPayload",
+ "name": "RelayForwardLimits",
+ "longName": "RelayForwardLimits",
+ "fullName": "ttn.lorawan.v3.RelayForwardLimits",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -32095,12 +34161,12 @@
"extensions": [],
"fields": [
{
- "name": "f_hdr",
- "description": "",
+ "name": "bucket_size",
+ "description": "The multiplier used to compute the total bucket size for the limits.\nThe multiplier is multiplied by the reload rate in order to compute the total bucket size.",
"label": "",
- "type": "FHDR",
- "longType": "FHDR",
- "fullType": "ttn.lorawan.v3.FHDR",
+ "type": "RelayLimitBucketSize",
+ "longType": "RelayLimitBucketSize",
+ "fullType": "ttn.lorawan.v3.RelayLimitBucketSize",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -32108,15 +34174,15 @@
"options": {
"validate.rules": [
{
- "name": "message.required",
+ "name": "enum.defined_only",
"value": true
}
]
}
},
{
- "name": "f_port",
- "description": "",
+ "name": "reload_rate",
+ "description": "The number of tokens which are replenished in the bucket every hour.",
"label": "",
"type": "uint32",
"longType": "uint32",
@@ -32129,66 +34195,98 @@
"validate.rules": [
{
"name": "uint32.lte",
- "value": 255
+ "value": 126
}
]
}
- },
+ }
+ ]
+ },
+ {
+ "name": "RelayForwardUplinkReq",
+ "longName": "RelayForwardUplinkReq",
+ "fullName": "ttn.lorawan.v3.RelayForwardUplinkReq",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "frm_payload",
+ "name": "data_rate",
"description": "",
"label": "",
- "type": "bytes",
- "longType": "bytes",
- "fullType": "bytes",
+ "type": "DataRate",
+ "longType": "DataRate",
+ "fullType": "ttn.lorawan.v3.DataRate",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "message.required",
+ "value": true
+ }
+ ]
+ }
},
{
- "name": "decoded_payload",
+ "name": "snr",
"description": "",
"label": "",
- "type": "Struct",
- "longType": "google.protobuf.Struct",
- "fullType": "google.protobuf.Struct",
+ "type": "int32",
+ "longType": "int32",
+ "fullType": "int32",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "int32.lte",
+ "value": 11
+ },
+ {
+ "name": "int32.gte",
+ "value": -20
+ }
+ ]
+ }
},
{
- "name": "full_f_cnt",
- "description": "Full 32-bit FCnt value. Used internally by Network Server.",
+ "name": "rssi",
+ "description": "",
"label": "",
- "type": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
+ "type": "int32",
+ "longType": "int32",
+ "fullType": "int32",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": ""
- }
- ]
- },
- {
- "name": "MHDR",
- "longName": "MHDR",
- "fullName": "ttn.lorawan.v3.MHDR",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "int32.lte",
+ "value": -15
+ },
+ {
+ "name": "int32.gte",
+ "value": -142
+ }
+ ]
+ }
+ },
{
- "name": "m_type",
+ "name": "wor_channel",
"description": "",
"label": "",
- "type": "MType",
- "longType": "MType",
- "fullType": "ttn.lorawan.v3.MType",
+ "type": "RelayWORChannel",
+ "longType": "RelayWORChannel",
+ "fullType": "ttn.lorawan.v3.RelayWORChannel",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -32203,12 +34301,12 @@
}
},
{
- "name": "major",
- "description": "",
+ "name": "frequency",
+ "description": "Uplink channel frequency (Hz).",
"label": "",
- "type": "Major",
- "longType": "Major",
- "fullType": "ttn.lorawan.v3.Major",
+ "type": "uint64",
+ "longType": "uint64",
+ "fullType": "uint64",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -32216,31 +34314,43 @@
"options": {
"validate.rules": [
{
- "name": "enum.defined_only",
- "value": true
+ "name": "uint64.gte",
+ "value": 100000
}
]
}
+ },
+ {
+ "name": "raw_payload",
+ "description": "",
+ "label": "",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
}
]
},
{
- "name": "Message",
- "longName": "Message",
- "fullName": "ttn.lorawan.v3.Message",
- "description": "Message represents a LoRaWAN message",
+ "name": "RelaySecondChannel",
+ "longName": "RelaySecondChannel",
+ "fullName": "ttn.lorawan.v3.RelaySecondChannel",
+ "description": "",
"hasExtensions": false,
"hasFields": true,
- "hasOneofs": true,
+ "hasOneofs": false,
"extensions": [],
"fields": [
{
- "name": "m_hdr",
- "description": "",
+ "name": "ack_offset",
+ "description": "The frequency (Hz) offset used for the WOR acknowledgement.",
"label": "",
- "type": "MHDR",
- "longType": "MHDR",
- "fullType": "ttn.lorawan.v3.MHDR",
+ "type": "RelaySecondChAckOffset",
+ "longType": "RelaySecondChAckOffset",
+ "fullType": "ttn.lorawan.v3.RelaySecondChAckOffset",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -32248,19 +34358,19 @@
"options": {
"validate.rules": [
{
- "name": "message.required",
+ "name": "enum.defined_only",
"value": true
}
]
}
},
{
- "name": "mic",
- "description": "",
+ "name": "data_rate_index",
+ "description": "The data rate index used by the WOR and WOR acknowledgement.",
"label": "",
- "type": "bytes",
- "longType": "bytes",
- "fullType": "bytes",
+ "type": "DataRateIndex",
+ "longType": "DataRateIndex",
+ "fullType": "ttn.lorawan.v3.DataRateIndex",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -32268,83 +34378,19 @@
"options": {
"validate.rules": [
{
- "name": "bytes.min_len",
- "value": 0
- },
- {
- "name": "bytes.max_len",
- "value": 4
+ "name": "enum.defined_only",
+ "value": true
}
]
}
},
{
- "name": "mac_payload",
- "description": "",
- "label": "",
- "type": "MACPayload",
- "longType": "MACPayload",
- "fullType": "ttn.lorawan.v3.MACPayload",
- "ismap": false,
- "isoneof": true,
- "oneofdecl": "Payload",
- "defaultValue": ""
- },
- {
- "name": "join_request_payload",
- "description": "",
- "label": "",
- "type": "JoinRequestPayload",
- "longType": "JoinRequestPayload",
- "fullType": "ttn.lorawan.v3.JoinRequestPayload",
- "ismap": false,
- "isoneof": true,
- "oneofdecl": "Payload",
- "defaultValue": ""
- },
- {
- "name": "join_accept_payload",
- "description": "",
- "label": "",
- "type": "JoinAcceptPayload",
- "longType": "JoinAcceptPayload",
- "fullType": "ttn.lorawan.v3.JoinAcceptPayload",
- "ismap": false,
- "isoneof": true,
- "oneofdecl": "Payload",
- "defaultValue": ""
- },
- {
- "name": "rejoin_request_payload",
- "description": "",
- "label": "",
- "type": "RejoinRequestPayload",
- "longType": "RejoinRequestPayload",
- "fullType": "ttn.lorawan.v3.RejoinRequestPayload",
- "ismap": false,
- "isoneof": true,
- "oneofdecl": "Payload",
- "defaultValue": ""
- }
- ]
- },
- {
- "name": "PingSlotPeriodValue",
- "longName": "PingSlotPeriodValue",
- "fullName": "ttn.lorawan.v3.PingSlotPeriodValue",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
- {
- "name": "value",
- "description": "",
+ "name": "frequency",
+ "description": "The frequency (Hz) used by the wake on radio message.",
"label": "",
- "type": "PingSlotPeriod",
- "longType": "PingSlotPeriod",
- "fullType": "ttn.lorawan.v3.PingSlotPeriod",
+ "type": "uint64",
+ "longType": "uint64",
+ "fullType": "uint64",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -32352,8 +34398,8 @@
"options": {
"validate.rules": [
{
- "name": "enum.defined_only",
- "value": true
+ "name": "uint64.gte",
+ "value": 100000
}
]
}
@@ -32361,9 +34407,9 @@
]
},
{
- "name": "RejoinRequestPayload",
- "longName": "RejoinRequestPayload",
- "fullName": "ttn.lorawan.v3.RejoinRequestPayload",
+ "name": "RelayUplinkForwardLimits",
+ "longName": "RelayUplinkForwardLimits",
+ "fullName": "ttn.lorawan.v3.RelayUplinkForwardLimits",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -32371,12 +34417,12 @@
"extensions": [],
"fields": [
{
- "name": "rejoin_type",
- "description": "",
+ "name": "bucket_size",
+ "description": "The multiplier used to compute the total bucket size for the limits.\nThe multiplier is multiplied by the reload rate in order to compute the total bucket size.",
"label": "",
- "type": "RejoinRequestType",
- "longType": "RejoinRequestType",
- "fullType": "ttn.lorawan.v3.RejoinRequestType",
+ "type": "RelayLimitBucketSize",
+ "longType": "RelayLimitBucketSize",
+ "fullType": "ttn.lorawan.v3.RelayLimitBucketSize",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -32391,12 +34437,12 @@
}
},
{
- "name": "net_id",
- "description": "",
+ "name": "reload_rate",
+ "description": "The number of tokens which are replenished in the bucket every hour.",
"label": "",
- "type": "bytes",
- "longType": "bytes",
- "fullType": "bytes",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -32404,19 +34450,31 @@
"options": {
"validate.rules": [
{
- "name": "bytes.len",
- "value": 3
+ "name": "uint32.lte",
+ "value": 62
}
]
}
- },
+ }
+ ]
+ },
+ {
+ "name": "RelayUplinkToken",
+ "longName": "RelayUplinkToken",
+ "fullName": "ttn.lorawan.v3.RelayUplinkToken",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "join_eui",
+ "name": "ids",
"description": "",
"label": "",
- "type": "bytes",
- "longType": "bytes",
- "fullType": "bytes",
+ "type": "EndDeviceIdentifiers",
+ "longType": "EndDeviceIdentifiers",
+ "fullType": "ttn.lorawan.v3.EndDeviceIdentifiers",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -32424,14 +34482,14 @@
"options": {
"validate.rules": [
{
- "name": "bytes.len",
- "value": 8
+ "name": "message.required",
+ "value": true
}
]
}
},
{
- "name": "dev_eui",
+ "name": "session_key_id",
"description": "",
"label": "",
"type": "bytes",
@@ -32440,19 +34498,11 @@
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "bytes.len",
- "value": 8
- }
- ]
- }
+ "defaultValue": ""
},
{
- "name": "rejoin_cnt",
- "description": "Contains RJCount0 or RJCount1 depending on rejoin_type.",
+ "name": "full_f_cnt",
+ "description": "",
"label": "",
"type": "uint32",
"longType": "uint32",
@@ -35503,6 +37553,62 @@
}
]
},
+ {
+ "name": "RelayMetadata",
+ "longName": "RelayMetadata",
+ "fullName": "ttn.lorawan.v3.RelayMetadata",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "device_id",
+ "description": "End device identifiers of the relay.",
+ "label": "",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "string.max_len",
+ "value": 36
+ },
+ {
+ "name": "string.pattern",
+ "value": "^[a-z0-9](?:[-]?[a-z0-9]){2,}$"
+ }
+ ]
+ }
+ },
+ {
+ "name": "wor_channel",
+ "description": "Wake on radio channel.",
+ "label": "",
+ "type": "RelayWORChannel",
+ "longType": "RelayWORChannel",
+ "fullType": "ttn.lorawan.v3.RelayWORChannel",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "enum.defined_only",
+ "value": true
+ }
+ ]
+ }
+ }
+ ]
+ },
{
"name": "RxMetadata",
"longName": "RxMetadata",
@@ -35545,6 +37651,18 @@
"oneofdecl": "",
"defaultValue": ""
},
+ {
+ "name": "relay",
+ "description": "",
+ "label": "",
+ "type": "RelayMetadata",
+ "longType": "RelayMetadata",
+ "fullType": "ttn.lorawan.v3.RelayMetadata",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
{
"name": "antenna_index",
"description": "",
diff --git a/sdk/js/generated/device-entity-map.json b/sdk/js/generated/device-entity-map.json
index 21baca6d33..bc8ad6cddc 100644
--- a/sdk/js/generated/device-entity-map.json
+++ b/sdk/js/generated/device-entity-map.json
@@ -726,6 +726,176 @@
"ns"
]
},
+ "desired_relay": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "mode": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "served": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "backoff": [
+ "ns",
+ "ns"
+ ],
+ "mode": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "always": [
+ "ns",
+ "ns"
+ ],
+ "dynamic": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "smart_enable_level": [
+ "ns",
+ "ns"
+ ]
+ },
+ "end_device_controlled": [
+ "ns",
+ "ns"
+ ]
+ },
+ "second_channel": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "ack_offset": [
+ "ns",
+ "ns"
+ ],
+ "data_rate_index": [
+ "ns",
+ "ns"
+ ],
+ "frequency": [
+ "ns",
+ "ns"
+ ]
+ },
+ "serving_device_id": [
+ "ns",
+ "ns"
+ ]
+ },
+ "serving": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "cad_periodicity": [
+ "ns",
+ "ns"
+ ],
+ "default_channel_index": [
+ "ns",
+ "ns"
+ ],
+ "limits": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "join_requests": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "bucket_size": [
+ "ns",
+ "ns"
+ ],
+ "reload_rate": [
+ "ns",
+ "ns"
+ ]
+ },
+ "notifications": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "bucket_size": [
+ "ns",
+ "ns"
+ ],
+ "reload_rate": [
+ "ns",
+ "ns"
+ ]
+ },
+ "overall": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "bucket_size": [
+ "ns",
+ "ns"
+ ],
+ "reload_rate": [
+ "ns",
+ "ns"
+ ]
+ },
+ "reset_behavior": [
+ "ns",
+ "ns"
+ ],
+ "uplink_messages": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "bucket_size": [
+ "ns",
+ "ns"
+ ],
+ "reload_rate": [
+ "ns",
+ "ns"
+ ]
+ }
+ },
+ "second_channel": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "ack_offset": [
+ "ns",
+ "ns"
+ ],
+ "data_rate_index": [
+ "ns",
+ "ns"
+ ],
+ "frequency": [
+ "ns",
+ "ns"
+ ]
+ },
+ "uplink_forwarding_rules": [
+ "ns",
+ "ns"
+ ]
+ }
+ }
+ },
"desired_rx1_data_rate_offset": {
"_root": [
"ns",
@@ -810,6 +980,176 @@
"ns"
]
},
+ "relay": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "mode": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "served": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "backoff": [
+ "ns",
+ "ns"
+ ],
+ "mode": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "always": [
+ "ns",
+ "ns"
+ ],
+ "dynamic": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "smart_enable_level": [
+ "ns",
+ "ns"
+ ]
+ },
+ "end_device_controlled": [
+ "ns",
+ "ns"
+ ]
+ },
+ "second_channel": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "ack_offset": [
+ "ns",
+ "ns"
+ ],
+ "data_rate_index": [
+ "ns",
+ "ns"
+ ],
+ "frequency": [
+ "ns",
+ "ns"
+ ]
+ },
+ "serving_device_id": [
+ "ns",
+ "ns"
+ ]
+ },
+ "serving": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "cad_periodicity": [
+ "ns",
+ "ns"
+ ],
+ "default_channel_index": [
+ "ns",
+ "ns"
+ ],
+ "limits": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "join_requests": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "bucket_size": [
+ "ns",
+ "ns"
+ ],
+ "reload_rate": [
+ "ns",
+ "ns"
+ ]
+ },
+ "notifications": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "bucket_size": [
+ "ns",
+ "ns"
+ ],
+ "reload_rate": [
+ "ns",
+ "ns"
+ ]
+ },
+ "overall": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "bucket_size": [
+ "ns",
+ "ns"
+ ],
+ "reload_rate": [
+ "ns",
+ "ns"
+ ]
+ },
+ "reset_behavior": [
+ "ns",
+ "ns"
+ ],
+ "uplink_messages": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "bucket_size": [
+ "ns",
+ "ns"
+ ],
+ "reload_rate": [
+ "ns",
+ "ns"
+ ]
+ }
+ },
+ "second_channel": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "ack_offset": [
+ "ns",
+ "ns"
+ ],
+ "data_rate_index": [
+ "ns",
+ "ns"
+ ],
+ "frequency": [
+ "ns",
+ "ns"
+ ]
+ },
+ "uplink_forwarding_rules": [
+ "ns",
+ "ns"
+ ]
+ }
+ }
+ },
"resets_f_cnt": {
"_root": [
"ns",
@@ -997,18 +1337,188 @@
"ns"
]
},
- "ping_slot_frequency": [
- "ns",
- "ns"
- ],
- "rejoin_count_periodicity": [
- "ns",
- "ns"
- ],
- "rejoin_time_periodicity": [
- "ns",
- "ns"
- ],
+ "ping_slot_frequency": [
+ "ns",
+ "ns"
+ ],
+ "rejoin_count_periodicity": [
+ "ns",
+ "ns"
+ ],
+ "rejoin_time_periodicity": [
+ "ns",
+ "ns"
+ ],
+ "relay": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "mode": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "served": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "backoff": [
+ "ns",
+ "ns"
+ ],
+ "mode": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "always": [
+ "ns",
+ "ns"
+ ],
+ "dynamic": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "smart_enable_level": [
+ "ns",
+ "ns"
+ ]
+ },
+ "end_device_controlled": [
+ "ns",
+ "ns"
+ ]
+ },
+ "second_channel": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "ack_offset": [
+ "ns",
+ "ns"
+ ],
+ "data_rate_index": [
+ "ns",
+ "ns"
+ ],
+ "frequency": [
+ "ns",
+ "ns"
+ ]
+ },
+ "serving_device_id": [
+ "ns",
+ "ns"
+ ]
+ },
+ "serving": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "cad_periodicity": [
+ "ns",
+ "ns"
+ ],
+ "default_channel_index": [
+ "ns",
+ "ns"
+ ],
+ "limits": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "join_requests": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "bucket_size": [
+ "ns",
+ "ns"
+ ],
+ "reload_rate": [
+ "ns",
+ "ns"
+ ]
+ },
+ "notifications": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "bucket_size": [
+ "ns",
+ "ns"
+ ],
+ "reload_rate": [
+ "ns",
+ "ns"
+ ]
+ },
+ "overall": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "bucket_size": [
+ "ns",
+ "ns"
+ ],
+ "reload_rate": [
+ "ns",
+ "ns"
+ ]
+ },
+ "reset_behavior": [
+ "ns",
+ "ns"
+ ],
+ "uplink_messages": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "bucket_size": [
+ "ns",
+ "ns"
+ ],
+ "reload_rate": [
+ "ns",
+ "ns"
+ ]
+ }
+ },
+ "second_channel": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "ack_offset": [
+ "ns",
+ "ns"
+ ],
+ "data_rate_index": [
+ "ns",
+ "ns"
+ ],
+ "frequency": [
+ "ns",
+ "ns"
+ ]
+ },
+ "uplink_forwarding_rules": [
+ "ns",
+ "ns"
+ ]
+ }
+ }
+ },
"rx1_data_rate_offset": [
"ns",
"ns"
@@ -1121,6 +1631,176 @@
"ns",
"ns"
],
+ "relay": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "mode": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "served": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "backoff": [
+ "ns",
+ "ns"
+ ],
+ "mode": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "always": [
+ "ns",
+ "ns"
+ ],
+ "dynamic": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "smart_enable_level": [
+ "ns",
+ "ns"
+ ]
+ },
+ "end_device_controlled": [
+ "ns",
+ "ns"
+ ]
+ },
+ "second_channel": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "ack_offset": [
+ "ns",
+ "ns"
+ ],
+ "data_rate_index": [
+ "ns",
+ "ns"
+ ],
+ "frequency": [
+ "ns",
+ "ns"
+ ]
+ },
+ "serving_device_id": [
+ "ns",
+ "ns"
+ ]
+ },
+ "serving": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "cad_periodicity": [
+ "ns",
+ "ns"
+ ],
+ "default_channel_index": [
+ "ns",
+ "ns"
+ ],
+ "limits": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "join_requests": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "bucket_size": [
+ "ns",
+ "ns"
+ ],
+ "reload_rate": [
+ "ns",
+ "ns"
+ ]
+ },
+ "notifications": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "bucket_size": [
+ "ns",
+ "ns"
+ ],
+ "reload_rate": [
+ "ns",
+ "ns"
+ ]
+ },
+ "overall": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "bucket_size": [
+ "ns",
+ "ns"
+ ],
+ "reload_rate": [
+ "ns",
+ "ns"
+ ]
+ },
+ "reset_behavior": [
+ "ns",
+ "ns"
+ ],
+ "uplink_messages": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "bucket_size": [
+ "ns",
+ "ns"
+ ],
+ "reload_rate": [
+ "ns",
+ "ns"
+ ]
+ }
+ },
+ "second_channel": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "ack_offset": [
+ "ns",
+ "ns"
+ ],
+ "data_rate_index": [
+ "ns",
+ "ns"
+ ],
+ "frequency": [
+ "ns",
+ "ns"
+ ]
+ },
+ "uplink_forwarding_rules": [
+ "ns",
+ "ns"
+ ]
+ }
+ }
+ },
"rx1_data_rate_offset": [
"ns",
"ns"
@@ -1224,6 +1904,16 @@
"ns"
]
},
+ "pending_relay_downlink": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "raw_payload": [
+ "ns",
+ "ns"
+ ]
+ },
"pending_requests": [
"ns",
"ns"
@@ -1377,6 +2067,176 @@
"ns",
"ns"
],
+ "relay": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "mode": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "served": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "backoff": [
+ "ns",
+ "ns"
+ ],
+ "mode": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "always": [
+ "ns",
+ "ns"
+ ],
+ "dynamic": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "smart_enable_level": [
+ "ns",
+ "ns"
+ ]
+ },
+ "end_device_controlled": [
+ "ns",
+ "ns"
+ ]
+ },
+ "second_channel": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "ack_offset": [
+ "ns",
+ "ns"
+ ],
+ "data_rate_index": [
+ "ns",
+ "ns"
+ ],
+ "frequency": [
+ "ns",
+ "ns"
+ ]
+ },
+ "serving_device_id": [
+ "ns",
+ "ns"
+ ]
+ },
+ "serving": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "cad_periodicity": [
+ "ns",
+ "ns"
+ ],
+ "default_channel_index": [
+ "ns",
+ "ns"
+ ],
+ "limits": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "join_requests": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "bucket_size": [
+ "ns",
+ "ns"
+ ],
+ "reload_rate": [
+ "ns",
+ "ns"
+ ]
+ },
+ "notifications": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "bucket_size": [
+ "ns",
+ "ns"
+ ],
+ "reload_rate": [
+ "ns",
+ "ns"
+ ]
+ },
+ "overall": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "bucket_size": [
+ "ns",
+ "ns"
+ ],
+ "reload_rate": [
+ "ns",
+ "ns"
+ ]
+ },
+ "reset_behavior": [
+ "ns",
+ "ns"
+ ],
+ "uplink_messages": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "bucket_size": [
+ "ns",
+ "ns"
+ ],
+ "reload_rate": [
+ "ns",
+ "ns"
+ ]
+ }
+ },
+ "second_channel": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "ack_offset": [
+ "ns",
+ "ns"
+ ],
+ "data_rate_index": [
+ "ns",
+ "ns"
+ ],
+ "frequency": [
+ "ns",
+ "ns"
+ ]
+ },
+ "uplink_forwarding_rules": [
+ "ns",
+ "ns"
+ ]
+ }
+ }
+ },
"rx1_data_rate_offset": [
"ns",
"ns"
@@ -1489,6 +2349,176 @@
"ns",
"ns"
],
+ "relay": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "mode": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "served": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "backoff": [
+ "ns",
+ "ns"
+ ],
+ "mode": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "always": [
+ "ns",
+ "ns"
+ ],
+ "dynamic": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "smart_enable_level": [
+ "ns",
+ "ns"
+ ]
+ },
+ "end_device_controlled": [
+ "ns",
+ "ns"
+ ]
+ },
+ "second_channel": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "ack_offset": [
+ "ns",
+ "ns"
+ ],
+ "data_rate_index": [
+ "ns",
+ "ns"
+ ],
+ "frequency": [
+ "ns",
+ "ns"
+ ]
+ },
+ "serving_device_id": [
+ "ns",
+ "ns"
+ ]
+ },
+ "serving": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "cad_periodicity": [
+ "ns",
+ "ns"
+ ],
+ "default_channel_index": [
+ "ns",
+ "ns"
+ ],
+ "limits": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "join_requests": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "bucket_size": [
+ "ns",
+ "ns"
+ ],
+ "reload_rate": [
+ "ns",
+ "ns"
+ ]
+ },
+ "notifications": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "bucket_size": [
+ "ns",
+ "ns"
+ ],
+ "reload_rate": [
+ "ns",
+ "ns"
+ ]
+ },
+ "overall": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "bucket_size": [
+ "ns",
+ "ns"
+ ],
+ "reload_rate": [
+ "ns",
+ "ns"
+ ]
+ },
+ "reset_behavior": [
+ "ns",
+ "ns"
+ ],
+ "uplink_messages": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "bucket_size": [
+ "ns",
+ "ns"
+ ],
+ "reload_rate": [
+ "ns",
+ "ns"
+ ]
+ }
+ },
+ "second_channel": {
+ "_root": [
+ "ns",
+ "ns"
+ ],
+ "ack_offset": [
+ "ns",
+ "ns"
+ ],
+ "data_rate_index": [
+ "ns",
+ "ns"
+ ],
+ "frequency": [
+ "ns",
+ "ns"
+ ]
+ },
+ "uplink_forwarding_rules": [
+ "ns",
+ "ns"
+ ]
+ }
+ }
+ },
"rx1_data_rate_offset": [
"ns",
"ns"
diff --git a/sdk/js/package.json b/sdk/js/package.json
index 56f7bddc89..19405384b3 100644
--- a/sdk/js/package.json
+++ b/sdk/js/package.json
@@ -1,6 +1,6 @@
{
"name": "ttn-lw",
- "version": "3.27.2",
+ "version": "3.28.1",
"description": "The Things Stack for LoRaWAN JavaScript SDK",
"url": "https://github.com/TheThingsNetwork/lorawan-stack/tree/default/sdk/js",
"main": "dist/index.js",
diff --git a/sdk/js/src/api/http.js b/sdk/js/src/api/http.js
index d4df5501bf..67dc7fbd88 100644
--- a/sdk/js/src/api/http.js
+++ b/sdk/js/src/api/http.js
@@ -24,7 +24,7 @@ import {
RATE_LIMIT_RETRIES,
} from '../util/constants'
-import stream from './stream/stream-node'
+import subscribeToHttpStream from './stream/subscribeToHttpStream'
/**
* Http Class is a connector for the API that uses the HTTP bridge to connect.
@@ -100,7 +100,7 @@ class Http {
try {
if (isStream) {
const url = this._stackConfig.getComponentUrlByName(parsedComponent) + endpoint
- return stream(payload, url)
+ return subscribeToHttpStream(payload, url)
}
const config = {
diff --git a/sdk/js/src/api/stream/shared.js b/sdk/js/src/api/stream/shared.js
index 643209a7a9..8d1b8b18ff 100644
--- a/sdk/js/src/api/stream/shared.js
+++ b/sdk/js/src/api/stream/shared.js
@@ -19,8 +19,15 @@ export const notify = (listener, ...args) => {
}
export const EVENTS = Object.freeze({
- START: 'start',
- CHUNK: 'chunk',
+ OPEN: 'open',
+ MESSAGE: 'message',
ERROR: 'error',
CLOSE: 'close',
})
+
+export const MESSAGE_TYPES = Object.freeze({
+ SUBSCRIBE: 'subscribe',
+ UNSUBSCRIBE: 'unsubscribe',
+ PUBLISH: 'publish',
+ ERROR: 'error',
+})
diff --git a/sdk/js/src/api/stream/stream-node.js b/sdk/js/src/api/stream/stream-node.js
deleted file mode 100644
index 7b41db8291..0000000000
--- a/sdk/js/src/api/stream/stream-node.js
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright © 2019 The Things Network Foundation, The Things Industries B.V.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import axios from 'axios'
-
-import Token from '../../util/token'
-
-import { notify, EVENTS } from './shared'
-
-/**
- * Opens a new stream.
- *
- * @async
- * @param {object} payload - - The body of the initial request.
- * @param {string} url - The stream endpoint.
- *
- * @example
- * (async () => {
- * const stream = await stream(
- * { identifiers: [{ application_ids: { application_id: 'my-app' }}]},
- * 'http://localhost:1885/api/v3/events',
- * )
- *
- * // Add listeners to the stream.
- * stream
- * .on('start', () => console.log('conn opened'))
- * .on('chunk', chunk => console.log('received chunk', chunk))
- * .on('error', error => console.log(error))
- * .on('close', wasClientRequest => console.log(wasClientRequest ? 'conn closed by client' : 'conn closed by server'))
- *
- * // Start the stream after attaching the listeners.
- * stream.open()
- *
- * // Close the stream after 20 s.
- * setTimeout(() => stream.close(), 20000)
- * })()
- *
- * @returns {object} The stream subscription object with the `on` function for
- * attaching listeners and the `close` function to close the stream.
- */
-export default async (payload, url) => {
- let listeners = Object.values(EVENTS).reduce((acc, curr) => ({ ...acc, [curr]: null }), {})
- let reader = null
- let closeRequested = false
-
- const token = new Token().get()
-
- let Authorization = null
- if (typeof token === 'function') {
- Authorization = `Bearer ${(await token()).access_token}`
- } else {
- Authorization = `Bearer ${token}`
- }
-
- let buffer = ''
- axios({
- url,
- data: JSON.stringify(payload),
- method: 'POST',
- responseType: 'stream',
- headers: {
- Authorization,
- Accept: 'text/event-stream',
- },
- })
- .then(response => response.data)
- .then(stream => {
- reader = stream
- })
-
- return {
- open: () => {
- notify(listeners[EVENTS.START])
-
- reader.on('data', data => {
- const parsed = data.toString('utf8')
- buffer += parsed
- const lines = buffer.split(/\n\n/)
- buffer = lines.pop()
- for (const line of lines) {
- notify(listeners[EVENTS.CHUNK], JSON.parse(line).result)
- }
- })
- reader.on('end', () => {
- notify(listeners[EVENTS.CLOSE], closeRequested)
- listeners = {}
- })
- reader.on('error', error => {
- notify(listeners[EVENTS.ERROR], error)
- listeners = {}
- })
- },
- on(eventName, callback) {
- if (listeners[eventName] === undefined) {
- throw new Error(
- `${eventName} event is not supported. Should be one of: start, error, chunk or close`,
- )
- }
-
- listeners[eventName] = callback
-
- return this
- },
- close: () => {
- if (reader) {
- closeRequested = true
- reader.cancel()
- }
- },
- }
-}
diff --git a/sdk/js/src/api/stream/stream.js b/sdk/js/src/api/stream/subscribeToHttpStream.js
similarity index 92%
rename from sdk/js/src/api/stream/stream.js
rename to sdk/js/src/api/stream/subscribeToHttpStream.js
index 3fd4999574..b57dd13eee 100644
--- a/sdk/js/src/api/stream/stream.js
+++ b/sdk/js/src/api/stream/subscribeToHttpStream.js
@@ -36,7 +36,7 @@ import 'web-streams-polyfill/dist/polyfill'
* // Add listeners to the stream.
* stream
* .on('start', () => console.log('conn opened'))
- * .on('chunk', chunk => console.log('received chunk', chunk))
+ * .on('message', message => console.log('received message', message))
* .on('error', error => console.log(error))
* .on('close', wasClientRequest => console.log(wasClientRequest ? 'conn closed by client' : 'conn closed by server'))
*
@@ -85,7 +85,7 @@ export default async (payload, url) => {
let buffer = ''
const reader = response.body.getReader()
- const onChunk = ({ done, value }) => {
+ const onMessage = ({ done, value }) => {
if (done) {
notify(listeners[EVENTS.CLOSE], closeRequested)
listeners = initialListeners
@@ -97,10 +97,10 @@ export default async (payload, url) => {
const lines = buffer.split(/\n\n/)
buffer = lines.pop()
for (const line of lines) {
- notify(listeners[EVENTS.CHUNK], JSON.parse(line).result)
+ notify(listeners[EVENTS.MESSAGE], JSON.parse(line).result)
}
- return reader.read().then(onChunk)
+ return reader.read().then(onMessage)
}
return {
@@ -112,7 +112,7 @@ export default async (payload, url) => {
return data
})
- .then(onChunk)
+ .then(onMessage)
.catch(error => {
notify(listeners[EVENTS.ERROR], error)
listeners = initialListeners
@@ -121,7 +121,7 @@ export default async (payload, url) => {
on(eventName, callback) {
if (listeners[eventName] === undefined) {
throw new Error(
- `${eventName} event is not supported. Should be one of: start, error, chunk or close`,
+ `${eventName} event is not supported. Should be one of: start, error, message or close`,
)
}
diff --git a/sdk/js/src/api/stream/subscribeToWebSocketStream.js b/sdk/js/src/api/stream/subscribeToWebSocketStream.js
new file mode 100644
index 0000000000..7d38acebbb
--- /dev/null
+++ b/sdk/js/src/api/stream/subscribeToWebSocketStream.js
@@ -0,0 +1,211 @@
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import Token from '../../util/token'
+import { warn } from '../../../../../pkg/webui/lib/log'
+
+import { notify, EVENTS, MESSAGE_TYPES } from './shared'
+
+const wsInstances = {}
+let subscriptions = {}
+const initialListeners = Object.values(EVENTS).reduce((acc, curr) => ({ ...acc, [curr]: {} }), {})
+
+/**
+ * Opens a new stream.
+ *
+ * @async
+ * @param {object} payload - - The body of the initial request.
+ * @param {string} baseUrl - The stream baseUrl.
+ * @param {string} endpoint - The stream endpoint.
+ * @param {number} timeout - The timeout for the stream.
+ *
+ * @example
+ * (async () => {
+ * const stream = await stream(
+ * { identifiers: [{ application_ids: { application_id: 'my-app' }}]},
+ * 'http://localhost:8080',
+ * '/api/v3',
+ * )
+ *
+ * // Add listeners to the stream.
+ * stream
+ * .on('open', () => console.log('conn opened'))
+ * .on('message', ({ data }) => console.log('received data', JSON.parse(data)))
+ * .on('error', error => console.log(error))
+ * .on('close', wasClientRequest => console.log(wasClientRequest ? 'conn closed by client' : 'conn closed by server'))
+ *
+ * // Close the stream after 20 s.
+ * setTimeout(() => stream.close(), 20000)
+ * })()
+ *
+ * @returns {object} The stream subscription object with the `on` function for
+ * attaching listeners and the `close` function to close the stream.
+ */
+export default async (
+ payload,
+ baseUrl,
+ endpoint = '/console/internal/events/',
+ timeout = 10000,
+) => {
+ const subscriptionId = Date.now()
+ const subscriptionPayload = JSON.stringify({
+ type: MESSAGE_TYPES.SUBSCRIBE,
+ id: subscriptionId,
+ ...payload,
+ })
+ const unsubscribePayload = JSON.stringify({
+ type: MESSAGE_TYPES.UNSUBSCRIBE,
+ id: subscriptionId,
+ })
+ let closeRequested = false
+ const url = baseUrl + endpoint
+
+ await Promise.race([
+ new Promise(async (resolve, reject) => {
+ // Add the new subscription to the subscriptions object.
+ // Also add the resolver function to the subscription object to be able
+ // to resolve the promise after the subscription confirmation message.
+ subscriptions = {
+ ...subscriptions,
+ [subscriptionId]: { ...initialListeners, url, _resolver: resolve },
+ }
+
+ try {
+ const token = new Token().get()
+ const tokenParsed = typeof token === 'function' ? `${(await token()).access_token}` : token
+ const baseUrlParsed = baseUrl.replace('http', 'ws')
+
+ // Open up the WebSocket connection if it doesn't exist.
+ if (!wsInstances[url]) {
+ wsInstances[url] = new WebSocket(`${baseUrlParsed}${endpoint}`, [
+ 'ttn.lorawan.v3.console.internal.events.v1',
+ `ttn.lorawan.v3.header.authorization.bearer.${tokenParsed}`,
+ ])
+
+ // Event listener for 'open'
+ wsInstances[url].addEventListener('open', () => {
+ wsInstances[url].send(subscriptionPayload)
+ })
+
+ // Broadcast connection errors to all listeners.
+ wsInstances[url].addEventListener('error', error => {
+ Object.values(subscriptions)
+ .filter(s => s.url === url)
+ .forEach(s => notify(s[EVENTS.ERROR], new Error(error)))
+ // The error is an error event, but we should only throw proper errors.
+ // It has an optional error code that we could use to map to a proper error.
+ // However, the error codes are optional and not always used.
+ reject(new Error('Error in WebSocket connection'))
+ })
+
+ // Event listener for 'close'
+ wsInstances[url].addEventListener('close', closeEvent => {
+ // TODO: Handle close event codes.
+ // https://github.com/TheThingsNetwork/lorawan-stack/issues/6752
+
+ delete wsInstances[url]
+ Object.values(subscriptions)
+ .filter(s => s.url === url)
+ .forEach(s => notify(s[EVENTS.CLOSE], closeRequested))
+
+ if (closeRequested) {
+ resolve()
+ } else {
+ reject(
+ new Error(`WebSocket connection closed unexpectedly with code ${closeEvent.code}`),
+ )
+ }
+ })
+
+ // After the WebSocket connection is open, add the event listeners.
+ // Wait for the subscription confirmation message before resolving.
+ wsInstances[url].addEventListener('message', ({ data }) => {
+ const dataParsed = JSON.parse(data)
+ const listeners = subscriptions[dataParsed.id]
+
+ if (!listeners) {
+ warn('Message received for closed or unknown subscription with ID', dataParsed.id)
+
+ return
+ }
+
+ if (dataParsed.type === MESSAGE_TYPES.SUBSCRIBE) {
+ notify(listeners[EVENTS.OPEN])
+ // Resolve the promise after the subscription confirmation message.
+ listeners._resolver()
+ }
+
+ if (dataParsed.type === MESSAGE_TYPES.ERROR) {
+ notify(listeners[EVENTS.ERROR], dataParsed)
+ }
+
+ if (dataParsed.type === MESSAGE_TYPES.PUBLISH) {
+ notify(listeners[EVENTS.MESSAGE], dataParsed.event)
+ }
+
+ if (dataParsed.type === MESSAGE_TYPES.UNSUBSCRIBE) {
+ notify(listeners[EVENTS.CLOSE], closeRequested)
+ // Remove the subscription.
+ delete subscriptions[dataParsed.id]
+ if (!Object.values(subscriptions).some(s => s.url === url)) {
+ wsInstances[url].close()
+ }
+ }
+ })
+ } else if (wsInstances[url] && wsInstances[url].readyState === WebSocket.OPEN) {
+ // If the WebSocket connection is already open, only add the subscription.
+ wsInstances[url].send(subscriptionPayload)
+ }
+ } catch (error) {
+ const err = error instanceof Error ? error : new Error(error)
+ Object.values(subscriptions)
+ .filter(s => s.url === url)
+ .forEach(s => notify(s[EVENTS.ERROR], err))
+ reject(err)
+ }
+ }),
+ new Promise((resolve, reject) => setTimeout(() => reject(new Error('timeout')), timeout)),
+ ])
+
+ // Return an observer object with the `on` and `close` functions for
+ // the current subscription.
+ return {
+ on(eventName, callback) {
+ if (!Object.values(EVENTS).includes(eventName)) {
+ throw new Error(
+ `${eventName} event is not supported. Should be one of: open, message, error or close`,
+ )
+ }
+ subscriptions[subscriptionId][eventName] = callback
+
+ return this
+ },
+ close: () => {
+ if (wsInstances[url]) {
+ closeRequested = true
+ wsInstances[url].send(unsubscribePayload)
+
+ // Wait for the server to confirm the unsubscribe.
+ return new Promise(resolve => {
+ wsInstances[url].addEventListener('message', ({ data }) => {
+ const { type, id } = JSON.parse(data)
+ if (id === subscriptionId && type === MESSAGE_TYPES.UNSUBSCRIBE) {
+ resolve()
+ }
+ })
+ })
+ }
+ },
+ }
+}
diff --git a/sdk/js/src/index.js b/sdk/js/src/index.js
index 20af399f98..248ab976ad 100644
--- a/sdk/js/src/index.js
+++ b/sdk/js/src/index.js
@@ -55,7 +55,10 @@ class TTS {
this.Ns = new Ns(this.api.Ns)
this.Is = new Is(this.api.Is)
this.As = new As(this.api)
- this.Organizations = new Organizations(this.api)
+ this.Organizations = new Organizations(this.api, {
+ defaultUserId,
+ stackConfig: stackConfiguration,
+ })
this.Users = new Users(this.api)
this.Auth = new Auth(this.api.EntityAccess)
this.Sessions = new Sessions(this.api)
diff --git a/sdk/js/src/service/applications.js b/sdk/js/src/service/applications.js
index 8204be0a54..42cde4598e 100644
--- a/sdk/js/src/service/applications.js
+++ b/sdk/js/src/service/applications.js
@@ -15,6 +15,7 @@
import autoBind from 'auto-bind'
import Marshaler from '../util/marshaler'
+import subscribeToWebSocketStream from '../api/stream/subscribeToWebSocketStream'
import combineStreams from '../util/combine-streams'
import { STACK_COMPONENTS_MAP } from '../util/constants'
@@ -26,8 +27,7 @@ import Webhooks from './webhooks'
import PubSubs from './pubsubs'
import Packages from './application-packages'
-const { is: IS, as: AS, ns: NS, js: JS, dtc: DTC } = STACK_COMPONENTS_MAP
-
+const { is: IS, gs: GS } = STACK_COMPONENTS_MAP
/**
* Applications Class provides an abstraction on all applications and manages
* data handling from different sources. It exposes an API to easily work with
@@ -230,18 +230,14 @@ class Applications {
// Event streams can come from multiple stack components. It is necessary to
// check for stack components on different hosts and open distinct stream
// connections for any distinct host if need be.
- const distinctComponents = this._stackConfig.getComponentsWithDistinctBaseUrls([
- IS,
- JS,
- NS,
- AS,
- DTC,
- ])
-
- const streams = distinctComponents.map(component =>
- this._api.Events.Stream({ component }, payload),
+ const distinctComponents = this._stackConfig.getComponentsWithDistinctBaseUrls([IS, GS])
+
+ const baseUrls = new Set(
+ distinctComponents.map(component => this._stackConfig.getComponentUrlByName(component)),
)
+ const streams = [...baseUrls].map(baseUrl => subscribeToWebSocketStream(payload, baseUrl))
+
// Combine all stream sources to one subscription generator.
return combineStreams(streams)
}
diff --git a/sdk/js/src/service/devices/index.js b/sdk/js/src/service/devices/index.js
index f075d58849..5b8e0021d4 100644
--- a/sdk/js/src/service/devices/index.js
+++ b/sdk/js/src/service/devices/index.js
@@ -19,18 +19,18 @@ import traverse from 'traverse'
import { notify, EVENTS } from '../../api/stream/shared'
import Marshaler from '../../util/marshaler'
-import combineStreams from '../../util/combine-streams'
+import subscribeToWebSocketStream from '../../api/stream/subscribeToWebSocketStream'
import deviceEntityMap from '../../../generated/device-entity-map.json'
import DownlinkQueue from '../downlink-queue'
import { STACK_COMPONENTS_MAP } from '../../util/constants'
import DeviceClaim from '../claim'
+import combineStreams from '../../util/combine-streams'
import Repository from './repository'
import { splitSetPaths, splitGetPaths, makeRequests } from './split'
import mergeDevice from './merge'
-const { is: IS, ns: NS, as: AS, js: JS, dtc: DTC } = STACK_COMPONENTS_MAP
-
+const { is: IS, ns: NS, as: AS, js: JS, gs: GS } = STACK_COMPONENTS_MAP
/**
* Devices Class provides an abstraction on all devices and manages data
* handling from different sources. It exposes an API to easily work with
@@ -645,7 +645,7 @@ class Devices {
const result = await this.create(applicationId, end_device, paths)
- notify(listeners[EVENTS.CHUNK], result)
+ notify(listeners[EVENTS.MESSAGE], result)
finishedCount++
} catch (error) {
notify(listeners[EVENTS.ERROR], error)
@@ -664,7 +664,7 @@ class Devices {
on(eventName, callback) {
if (listeners[eventName] === undefined) {
throw new Error(
- `${eventName} event is not supported. Should be one of: start, error, chunk or close`,
+ `${eventName} event is not supported. Should be one of: open, error, message or close`,
)
}
@@ -693,18 +693,14 @@ class Devices {
// Event streams can come from multiple stack components. It is necessary to
// check for stack components on different hosts and open distinct stream
// connections for any distinct host if need be.
- const distinctComponents = this._stackConfig.getComponentsWithDistinctBaseUrls([
- IS,
- JS,
- NS,
- AS,
- DTC,
- ])
-
- const streams = distinctComponents.map(component =>
- this._api.Events.Stream({ component }, payload),
+ const distinctComponents = this._stackConfig.getComponentsWithDistinctBaseUrls([IS, GS])
+
+ const baseUrls = new Set(
+ distinctComponents.map(component => this._stackConfig.getComponentUrlByName(component)),
)
+ const streams = [...baseUrls].map(baseUrl => subscribeToWebSocketStream(payload, baseUrl))
+
// Combine all stream sources to one subscription generator.
return combineStreams(streams)
}
diff --git a/sdk/js/src/service/gateways.js b/sdk/js/src/service/gateways.js
index 2a566e5c58..41f5d820a7 100644
--- a/sdk/js/src/service/gateways.js
+++ b/sdk/js/src/service/gateways.js
@@ -15,8 +15,9 @@
import autoBind from 'auto-bind'
import Marshaler from '../util/marshaler'
-import combineStreams from '../util/combine-streams'
+import subscribeToWebSocketStream from '../api/stream/subscribeToWebSocketStream'
import { STACK_COMPONENTS_MAP } from '../util/constants'
+import combineStreams from '../util/combine-streams'
import ApiKeys from './api-keys'
import Collaborators from './collaborators'
@@ -221,6 +222,14 @@ class Gateways {
return Marshaler.payloadSingleResponse(response)
}
+ async getBatchStatistics(gatewayIds) {
+ const response = await this._api.Gs.BatchGetGatewayConnectionStats(undefined, {
+ gateway_ids: gatewayIds,
+ })
+
+ return Marshaler.payloadSingleResponse(response)
+ }
+
async getRightsById(gatewayId) {
const result = await this._api.GatewayAccess.ListRights({
routeParams: { gateway_id: gatewayId },
@@ -249,10 +258,12 @@ class Gateways {
STACK_COMPONENTS_MAP.gs,
])
- const streams = distinctComponents.map(component =>
- this._api.Events.Stream({ component }, payload),
+ const baseUrls = new Set(
+ distinctComponents.map(component => this._stackConfig.getComponentUrlByName(component)),
)
+ const streams = [...baseUrls].map(baseUrl => subscribeToWebSocketStream(payload, baseUrl))
+
// Combine all stream sources to one subscription generator.
return combineStreams(streams)
}
@@ -265,7 +276,7 @@ class Gateways {
// https://github.com/TheThingsNetwork/lorawan-stack/issues/3280
const endpoint = `/gcs/gateways/${gatewayId}/semtechudp/global_conf.json`
- const response = await this._api._connector.handleRequest('get', endpoint, 'gcs', false)
+ const response = await this._api._connector.handleRequest('get', endpoint, 'gcs')
return Marshaler.payloadSingleResponse(response.data)
}
diff --git a/sdk/js/src/service/organizations.js b/sdk/js/src/service/organizations.js
index 5f0981109a..5469acd031 100644
--- a/sdk/js/src/service/organizations.js
+++ b/sdk/js/src/service/organizations.js
@@ -15,13 +15,16 @@
import autoBind from 'auto-bind'
import Marshaler from '../util/marshaler'
+import subscribeToWebSocketStream from '../api/stream/subscribeToWebSocketStream'
+import { STACK_COMPONENTS_MAP } from '../util/constants'
import ApiKeys from './api-keys'
import Collaborators from './collaborators'
class Organizations {
- constructor(api) {
+ constructor(api, { stackConfig }) {
this._api = api
+ this._stackConfig = stackConfig
this.ApiKeys = new ApiKeys(api.OrganizationAccess, {
parentRoutes: {
@@ -163,7 +166,9 @@ class Organizations {
after,
}
- return this._api.Events.Stream(undefined, payload)
+ const baseUrl = this._stackConfig.getComponentUrlByName(STACK_COMPONENTS_MAP.is)
+
+ return subscribeToWebSocketStream(payload, baseUrl)
}
}
diff --git a/sdk/js/src/util/combine-streams.js b/sdk/js/src/util/combine-streams.js
index 92ab832595..75e20855b5 100644
--- a/sdk/js/src/util/combine-streams.js
+++ b/sdk/js/src/util/combine-streams.js
@@ -1,4 +1,4 @@
-// Copyright © 2020 The Things Network Foundation, The Things Industries B.V.
+// Copyright © 2023 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -29,11 +29,6 @@ const combinedStream = async streams => {
const subscribers = await Promise.all(streams)
return {
- open: () => {
- for (const subscriber of subscribers) {
- subscriber.open()
- }
- },
on: (eventName, callback) => {
for (const subscriber of subscribers) {
subscriber.on(eventName, callback)
diff --git a/sdk/js/yarn.lock b/sdk/js/yarn.lock
index d3864770fe..4db0550a64 100644
--- a/sdk/js/yarn.lock
+++ b/sdk/js/yarn.lock
@@ -18,9 +18,9 @@ auto-bind@^5.0.1:
integrity sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg==
axios@^1.4.0:
- version "1.5.1"
- resolved "https://registry.yarnpkg.com/axios/-/axios-1.5.1.tgz#11fbaa11fc35f431193a9564109c88c1f27b585f"
- integrity sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==
+ version "1.6.2"
+ resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.2.tgz#de67d42c755b571d3e698df1b6504cde9b0ee9f2"
+ integrity sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==
dependencies:
follow-redirects "^1.15.0"
form-data "^4.0.0"
diff --git a/tools/go.mod b/tools/go.mod
index 36fb3ae89f..e767a14246 100644
--- a/tools/go.mod
+++ b/tools/go.mod
@@ -1,6 +1,6 @@
module go.thethings.network/lorawan-stack/tools
-go 1.20
+go 1.21
replace go.thethings.network/lorawan-stack/v3 => ../
@@ -19,10 +19,10 @@ require (
)
require (
- cloud.google.com/go v0.110.7 // indirect
- cloud.google.com/go/compute v1.23.0 // indirect
+ cloud.google.com/go v0.110.9 // indirect
+ cloud.google.com/go/compute v1.23.2 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
- cloud.google.com/go/iam v1.1.1 // indirect
+ cloud.google.com/go/iam v1.1.4 // indirect
cloud.google.com/go/pubsub v1.33.0 // indirect
cloud.google.com/go/storage v1.31.0 // indirect
contrib.go.opencensus.io/exporter/prometheus v0.4.2 // indirect
@@ -41,8 +41,8 @@ require (
github.com/TheThingsIndustries/mystique v0.0.0-20221125120501-80ab21781b6d // indirect
github.com/TheThingsIndustries/protoc-gen-go-flags v1.2.0 // indirect
github.com/TheThingsIndustries/protoc-gen-go-json v1.6.0 // indirect
- github.com/TheThingsNetwork/go-cayenne-lib v1.1.0 // indirect
- github.com/aws/aws-sdk-go v1.45.19 // indirect
+ github.com/TheThingsNetwork/go-cayenne-lib v1.2.0 // indirect
+ github.com/aws/aws-sdk-go v1.47.1 // indirect
github.com/aws/aws-sdk-go-v2 v1.20.0 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.11 // indirect
github.com/aws/aws-sdk-go-v2/config v1.18.32 // indirect
@@ -87,17 +87,17 @@ require (
github.com/disintegration/imaging v1.6.2 // indirect
github.com/dlclark/regexp2 v1.7.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
- github.com/dop251/goja v0.0.0-20230828202809-3dbe69dd2b8e // indirect
+ github.com/dop251/goja v0.0.0-20231027120936-b396bb4c349d // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/eclipse/paho.mqtt.golang v1.4.4-0.20230810210351-7b759f1d9ddf // indirect
github.com/envoyproxy/protoc-gen-validate v1.0.2 // indirect
- github.com/felixge/httpsnoop v1.0.3 // indirect
- github.com/fsnotify/fsnotify v1.6.0 // indirect
- github.com/getsentry/sentry-go v0.24.1 // indirect
+ github.com/felixge/httpsnoop v1.0.4 // indirect
+ github.com/fsnotify/fsnotify v1.7.0 // indirect
+ github.com/getsentry/sentry-go v0.25.0 // indirect
github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2 // indirect
github.com/go-kit/log v0.2.1 // indirect
github.com/go-logfmt/logfmt v0.6.0 // indirect
- github.com/go-logr/logr v1.2.4 // indirect
+ github.com/go-logr/logr v1.3.0 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect
github.com/godbus/dbus/v5 v5.0.6 // indirect
@@ -107,16 +107,15 @@ require (
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/certificate-transparency-go v1.1.4 // indirect
- github.com/google/go-cmp v0.5.9 // indirect
github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect
- github.com/google/s2a-go v0.1.4 // indirect
- github.com/google/uuid v1.3.1 // indirect
+ github.com/google/s2a-go v0.1.7 // indirect
+ github.com/google/uuid v1.4.0 // indirect
github.com/google/wire v0.5.0 // indirect
- github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect
+ github.com/googleapis/enterprise-certificate-proxy v0.3.1 // indirect
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
github.com/gorilla/csrf v1.7.1 // indirect
github.com/gorilla/handlers v1.5.1 // indirect
- github.com/gorilla/mux v1.8.0 // indirect
+ github.com/gorilla/mux v1.8.1 // indirect
github.com/gorilla/schema v1.2.0 // indirect
github.com/gorilla/securecookie v1.1.1 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
@@ -126,10 +125,10 @@ require (
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0 // indirect
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3 // indirect
- github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 // indirect
+ github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.2-0.20231120080707-5e5867a3a4b0 // indirect
github.com/hashicorp/golang-lru v0.6.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
- github.com/hellofresh/health-go/v5 v5.3.0 // indirect
+ github.com/hellofresh/health-go/v5 v5.5.0 // indirect
github.com/howeyc/gopass v0.0.0-20210920133722-c8aef6fb66ef // indirect
github.com/huandu/xstrings v1.3.3 // indirect
github.com/imdario/mergo v0.3.13 // indirect
@@ -145,53 +144,55 @@ require (
github.com/jmoiron/sqlx v1.3.3 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/jtacoma/uritemplates v1.0.0 // indirect
- github.com/klauspost/compress v1.17.0 // indirect
+ github.com/klauspost/compress v1.17.2 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect
- github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
+ github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
github.com/mitchellh/copystructure v1.0.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/reflectwalk v1.0.1 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/mschoch/smat v0.2.0 // indirect
- github.com/nats-io/nats.go v1.30.2 // indirect
- github.com/nats-io/nkeys v0.4.5 // indirect
+ github.com/nats-io/nats.go v1.31.0 // indirect
+ github.com/nats-io/nkeys v0.4.6 // indirect
github.com/nats-io/nuid v1.0.1 // indirect
github.com/oklog/ulid/v2 v2.1.0 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 // indirect
github.com/openshift/osin v1.0.2-0.20220317075346-0f4d38c6e53f // indirect
github.com/pborman/uuid v1.2.0 // indirect
- github.com/pelletier/go-toml/v2 v2.0.8 // indirect
+ github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/philhofer/fwd v1.0.0 // indirect
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_golang v1.17.0 // indirect
github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 // indirect
- github.com/prometheus/common v0.44.0 // indirect
+ github.com/prometheus/common v0.45.0 // indirect
github.com/prometheus/procfs v0.11.1 // indirect
github.com/prometheus/statsd_exporter v0.22.7 // indirect
- github.com/redis/go-redis/v9 v9.2.1 // indirect
+ github.com/redis/go-redis/v9 v9.3.0 // indirect
github.com/rivo/uniseg v0.4.3 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
+ github.com/sagikazarmark/locafero v0.3.0 // indirect
+ github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/satori/go.uuid v1.2.0 // indirect
github.com/sendgrid/rest v2.6.9+incompatible // indirect
github.com/sendgrid/sendgrid-go v3.13.0+incompatible // indirect
github.com/shopspring/decimal v1.2.0 // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect
- github.com/spf13/afero v1.9.5 // indirect
+ github.com/sourcegraph/conc v0.3.0 // indirect
+ github.com/spf13/afero v1.10.0 // indirect
github.com/spf13/cast v1.5.1 // indirect
github.com/spf13/cobra v1.7.0 // indirect
- github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
- github.com/spf13/viper v1.16.0 // indirect
+ github.com/spf13/viper v1.17.0 // indirect
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect
github.com/steveyen/gtreap v0.1.0 // indirect
- github.com/subosito/gotenv v1.4.2 // indirect
+ github.com/subosito/gotenv v1.6.0 // indirect
github.com/throttled/throttled v2.2.5+incompatible // indirect
github.com/throttled/throttled/v2 v2.12.0 // indirect
github.com/tinylib/msgp v1.1.0 // indirect
@@ -199,7 +200,7 @@ require (
github.com/uptrace/bun v1.1.16 // indirect
github.com/uptrace/bun/dialect/pgdialect v1.1.16 // indirect
github.com/uptrace/bun/driver/pgdriver v1.1.16 // indirect
- github.com/vmihailenco/msgpack/v5 v5.4.0 // indirect
+ github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
github.com/weppos/publicsuffix-go v0.15.1-0.20210511084619-b1f36a2d6c0b // indirect
github.com/willf/bitset v1.1.11 // indirect
@@ -207,22 +208,22 @@ require (
github.com/zmap/zlint/v3 v3.1.0 // indirect
go.etcd.io/bbolt v1.3.6 // indirect
go.opencensus.io v0.24.0 // indirect
- go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux v0.45.0 // indirect
- go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.45.0 // indirect
- go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // indirect
- go.opentelemetry.io/otel v1.19.0 // indirect
- go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 // indirect
- go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 // indirect
- go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.19.0 // indirect
- go.opentelemetry.io/otel/metric v1.19.0 // indirect
- go.opentelemetry.io/otel/sdk v1.19.0 // indirect
- go.opentelemetry.io/otel/trace v1.19.0 // indirect
+ go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux v0.46.0 // indirect
+ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.0 // indirect
+ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.0 // indirect
+ go.opentelemetry.io/otel v1.20.0 // indirect
+ go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0 // indirect
+ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0 // indirect
+ go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.20.0 // indirect
+ go.opentelemetry.io/otel/metric v1.20.0 // indirect
+ go.opentelemetry.io/otel/sdk v1.20.0 // indirect
+ go.opentelemetry.io/otel/trace v1.20.0 // indirect
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
- go.packetbroker.org/api/iam v1.7.0 // indirect
- go.packetbroker.org/api/iam/v2 v2.7.13 // indirect
- go.packetbroker.org/api/mapping/v2 v2.1.32 // indirect
- go.packetbroker.org/api/routing v1.8.23 // indirect
- go.packetbroker.org/api/v3 v3.15.2 // indirect
+ go.packetbroker.org/api/iam v1.8.1 // indirect
+ go.packetbroker.org/api/iam/v2 v2.9.0 // indirect
+ go.packetbroker.org/api/mapping/v2 v2.3.0 // indirect
+ go.packetbroker.org/api/routing v1.9.1 // indirect
+ go.packetbroker.org/api/v3 v3.17.0 // indirect
go.thethings.network/lorawan-application-payload v0.0.0-20220125153912-1198ff1e403e // indirect
go.thethings.network/lorawan-stack-legacy/v2 v2.1.0 // indirect
go.uber.org/automaxprocs v1.5.3 // indirect
@@ -230,25 +231,25 @@ require (
go.uber.org/zap v1.26.0 // indirect
gocloud.dev v0.34.0 // indirect
gocloud.dev/pubsub/natspubsub v0.34.0 // indirect
- golang.org/x/crypto v0.13.0 // indirect
- golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
- golang.org/x/image v0.5.0 // indirect
- golang.org/x/mod v0.12.0 // indirect
- golang.org/x/net v0.15.0 // indirect
- golang.org/x/oauth2 v0.12.0 // indirect
- golang.org/x/sync v0.3.0 // indirect
- golang.org/x/sys v0.12.0 // indirect
- golang.org/x/term v0.12.0 // indirect
- golang.org/x/text v0.13.0 // indirect
+ golang.org/x/crypto v0.15.0 // indirect
+ golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
+ golang.org/x/image v0.10.0 // indirect
+ golang.org/x/mod v0.13.0 // indirect
+ golang.org/x/net v0.18.0 // indirect
+ golang.org/x/oauth2 v0.14.0 // indirect
+ golang.org/x/sync v0.4.0 // indirect
+ golang.org/x/sys v0.14.0 // indirect
+ golang.org/x/term v0.14.0 // indirect
+ golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.3.0 // indirect
- golang.org/x/tools v0.13.0 // indirect
+ golang.org/x/tools v0.14.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
- google.golang.org/api v0.134.0 // indirect
- google.golang.org/appengine v1.6.7 // indirect
- google.golang.org/genproto v0.0.0-20230911183012-2d3300fd4832 // indirect
- google.golang.org/genproto/googleapis/api v0.0.0-20230911183012-2d3300fd4832 // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20230911183012-2d3300fd4832 // indirect
- google.golang.org/grpc v1.58.2 // indirect
+ google.golang.org/api v0.143.0 // indirect
+ google.golang.org/appengine v1.6.8 // indirect
+ google.golang.org/genproto v0.0.0-20231030173426-d783a09b4405 // indirect
+ google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 // indirect
+ google.golang.org/grpc v1.59.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
@@ -257,4 +258,5 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/klog/v2 v2.90.1 // indirect
mellium.im/sasl v0.3.1 // indirect
+ nhooyr.io/websocket v1.8.10 // indirect
)
diff --git a/tools/go.sum b/tools/go.sum
index f3bcd40c2e..d5263f63d2 100644
--- a/tools/go.sum
+++ b/tools/go.sum
@@ -18,22 +18,22 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHOb
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY=
-cloud.google.com/go v0.110.7 h1:rJyC7nWRg2jWGZ4wSJ5nY65GTdYJkg0cd/uXb+ACI6o=
-cloud.google.com/go v0.110.7/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI=
+cloud.google.com/go v0.110.9 h1:e7ITSqGFFk4rbz/JFIqZh3G4VEHguhAL4BQcFlWtU68=
+cloud.google.com/go v0.110.9/go.mod h1:rpxevX/0Lqvlbc88b7Sc1SPNdyK1riNBTUU6JXhYNpM=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
-cloud.google.com/go/compute v1.23.0 h1:tP41Zoavr8ptEqaW6j+LQOnyBBhO7OkOMAGrgLopTwY=
-cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM=
+cloud.google.com/go/compute v1.23.2 h1:nWEMDhgbBkBJjfpVySqU4jgWdc22PLR0o4vEexZHers=
+cloud.google.com/go/compute v1.23.2/go.mod h1:JJ0atRC0J/oWYiiVBmsSsrRnh92DhZPG4hFDcR04Rns=
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
-cloud.google.com/go/iam v1.1.1 h1:lW7fzj15aVIXYHREOqjRBV9PsH0Z6u8Y46a1YGvQP4Y=
-cloud.google.com/go/iam v1.1.1/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU=
+cloud.google.com/go/iam v1.1.4 h1:K6n/GZHFTtEoKT5aUG3l9diPi0VduZNQ1PfdnpkkIFk=
+cloud.google.com/go/iam v1.1.4/go.mod h1:l/rg8l1AaA+VFMho/HYx2Vv6xinPSLMF8qfhRPIZ0L8=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
@@ -58,6 +58,7 @@ github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0/go.mod h1:OQeznEEkTZ9Orh
github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.2.0 h1:Ma67P/GGprNwsslzEH6+Kb8nybI8jpDTm4Wmzu2ReK8=
+github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.2.0/go.mod h1:c+Lifp3EDEamAkPVzMooRNOK6CZjNSdEnf1A7jsI9u4=
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.1.0 h1:nVocQV40OQne5613EeLayJiRAJuKlBGy+m22qWG+WRg=
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.1.0/go.mod h1:7QJP7dr2wznCMeqIrhMgWGf7XpAQnVrJqDm9nvV3Cu4=
github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
@@ -88,18 +89,17 @@ github.com/TheThingsIndustries/protoc-gen-go-json v1.6.0 h1:FTaVxiDPoV9o6k2OFBij
github.com/TheThingsIndustries/protoc-gen-go-json v1.6.0/go.mod h1:6ourNr6TBk/2SB2V4In+o2eqZd/DIdiBLnoxvQ3UyWk=
github.com/TheThingsIndustries/throttled/v2 v2.7.1-noredis h1:uashKgjy7XCNZNb00+3GheWtJXnS9DnAkYQ1X89cAIg=
github.com/TheThingsIndustries/throttled/v2 v2.7.1-noredis/go.mod h1:XC/YhKcHsxRy8shbYICwf+oWeYTCC2kpL5/clSJbt+U=
-github.com/TheThingsNetwork/go-cayenne-lib v1.1.0 h1:uw+WnTMSSwTo58/ob3ktWNBiCY2psIof8p3lKdxreAE=
-github.com/TheThingsNetwork/go-cayenne-lib v1.1.0/go.mod h1:HTTus7UIBhXKvLIeNGybbG1o7wr4zwwVbbUXwFqrtp0=
+github.com/TheThingsNetwork/go-cayenne-lib v1.2.0 h1:yW4x7mNk2vyNTUYNRhda9oV8caLePMNR7Z5QbaG5Ifs=
+github.com/TheThingsNetwork/go-cayenne-lib v1.2.0/go.mod h1:HTTus7UIBhXKvLIeNGybbG1o7wr4zwwVbbUXwFqrtp0=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE=
-github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
-github.com/aws/aws-sdk-go v1.45.19 h1:+4yXWhldhCVXWFOQRF99ZTJ92t4DtoHROZIbN7Ujk/U=
-github.com/aws/aws-sdk-go v1.45.19/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
+github.com/aws/aws-sdk-go v1.47.1 h1:j9ih0Ashcw8tQcnfqNimBM8ARQ/CMpoBwjKue1D6Fuk=
+github.com/aws/aws-sdk-go v1.47.1/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
github.com/aws/aws-sdk-go-v2 v1.20.0 h1:INUDpYLt4oiPOJl0XwZDK2OVAVf0Rzo+MGVTv9f+gy8=
github.com/aws/aws-sdk-go-v2 v1.20.0/go.mod h1:uWOr0m0jDsiWw8nnXiqZ+YG6LdvAlGYDLLf2NmHZoy4=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.11 h1:/MS8AzqYNAhhRNalOmxUvYs8VEbNGifTnzhPFdcRQkQ=
@@ -176,7 +176,9 @@ github.com/bluele/gcache v0.0.2 h1:WcbfdXICg7G/DGBh1PFfcirkWOQV+v077yF1pSy3DGw=
github.com/bluele/gcache v0.0.2/go.mod h1:m15KV+ECjptwSPxKhOhQoAFQVtUFjTVkc3H8o0t/fp0=
github.com/bradfitz/gomemcache v0.0.0-20170208213004-1952afaa557d/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60=
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
+github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
+github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
@@ -199,11 +201,8 @@ github.com/cloudflare/cfssl v1.6.4/go.mod h1:8b3CQMxfWPAeom3zBnGJ6sd+G1NkL5TXqmD
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
-github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
-github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
-github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
-github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k=
+github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/containerd/cgroups/v3 v3.0.1 h1:4hfGvu8rfGIwVIDd+nLzn/B9ZXx4BcCjzt5ToenJRaE=
github.com/containerd/cgroups/v3 v3.0.1/go.mod h1:/vtwk1VXrtoa5AaZLkypuOJgA/6DyPMZHJPGQNtlHnw=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
@@ -224,8 +223,9 @@ github.com/cznic/b v0.0.0-20181122101859-a26611c4d92d/go.mod h1:URriBxXwVq5ijiJ1
github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM=
github.com/cznic/strutil v0.0.0-20181122101858-275e90344537/go.mod h1:AHHPPPXTw0h6pVabbcbyGRK1DckRn7r/STdZEeIDzZc=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
@@ -235,11 +235,12 @@ github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwu
github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo=
github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI=
+github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk=
-github.com/dop251/goja v0.0.0-20230828202809-3dbe69dd2b8e h1:UvQD6hTSfeM6hhTQ24Dlw2RppP05W7SWbWb6kubJAog=
-github.com/dop251/goja v0.0.0-20230828202809-3dbe69dd2b8e/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4=
+github.com/dop251/goja v0.0.0-20231027120936-b396bb4c349d h1:wi6jN5LVt/ljaBG4ue79Ekzb12QfJ52L9Q98tl8SWhw=
+github.com/dop251/goja v0.0.0-20231027120936-b396bb4c349d/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4=
github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y=
github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
@@ -247,14 +248,15 @@ github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+m
github.com/eclipse/paho.mqtt.golang v1.4.4-0.20230810210351-7b759f1d9ddf h1:gXeSWFfqzyZi45lUWjwEequEpynFo7LElrZCKqX42lw=
github.com/eclipse/paho.mqtt.golang v1.4.4-0.20230810210351-7b759f1d9ddf/go.mod h1:+mWC33KckYlkRnK7Gm+IjL1DD/gNg3Px/Yk/PSfBCU0=
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21 h1:OJyUGMJTzHTd1XQp98QTaHernxMYzRaOasRir9hUlFQ=
+github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ=
github.com/emersion/go-smtp v0.18.1 h1:4DFV0jxKhq0Gqt/Br3BRHyKZy5TStk6NIMHAx6GE/LA=
+github.com/emersion/go-smtp v0.18.1/go.mod h1:qm27SGYgoIPRot6ubfQ/GpiPy/g3PaZAVRxiO/sDUgQ=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
-github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA=
github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE=
@@ -262,22 +264,23 @@ github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htX
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg=
github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0=
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
-github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
-github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
+github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
+github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
+github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.4.3-0.20170329110642-4da3e2cfbabc/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
-github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
-github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
+github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
+github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/garyburd/redigo v1.1.1-0.20170914051019-70e1b1943d4f/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
-github.com/getsentry/sentry-go v0.24.1 h1:W6/0GyTy8J6ge6lVCc94WB6Gx2ZuLrgopnn9w8Hiwuk=
-github.com/getsentry/sentry-go v0.24.1/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY=
-github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/getsentry/sentry-go v0.25.0 h1:q6Eo+hS+yoJlTO3uu/azhQadsD8V+jQn2D8VvX1eOyI=
+github.com/getsentry/sentry-go v0.25.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY=
github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2 h1:Ujru1hufTHVb++eG6OuNDKMxZnGIvF6o/u8q/8h2+I4=
github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31 h1:gclg6gY70GLy3PbkQ1AERPfmLMMagS60DKF78eWwLn8=
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
+github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
@@ -295,8 +298,8 @@ github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
-github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
+github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU=
@@ -315,7 +318,6 @@ github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w
github.com/golang/gddo v0.0.0-20210115222349-20d68f94ee1f h1:16RtHeWGkJMc80Etb8RPCcKevXGldr57+LOyZt8zOlg=
github.com/golang/gddo v0.0.0-20210115222349-20d68f94ee1f/go.mod h1:ijRvpgDJDI262hYq/IQVYgf8hd8IHUs93Ol0kvMBAx4=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
-github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@@ -353,6 +355,7 @@ github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/gomodule/redigo v1.8.9 h1:Sl3u+2BI/kk+VEatbj0scLdrFhjPmbxOc1myhDP41ws=
+github.com/gomodule/redigo v1.8.9/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs06a1uzZE=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/certificate-transparency-go v1.1.4 h1:hCyXHDbtqlr/lMXU0D4WgbalXL0Zk4dSWWMbPV8VrqY=
@@ -370,16 +373,19 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
-github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-replayers/grpcreplay v1.1.0 h1:S5+I3zYyZ+GQz68OfbURDdt/+cSMqCK1wrvNx7WBzTE=
+github.com/google/go-replayers/grpcreplay v1.1.0/go.mod h1:qzAvJ8/wi57zq7gWqaE6AwLM6miiXUQwP1S+I9icmhk=
github.com/google/go-replayers/httpreplay v1.2.0 h1:VM1wEyyjaoU53BwrOnaf9VhAyQQEEioJvFYxYcLRKzk=
+github.com/google/go-replayers/httpreplay v1.2.0/go.mod h1:WahEFFZZ7a1P4VM1qEeHy+tME4bwyqPcwWbNlUI1Mcg=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw=
+github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
@@ -393,18 +399,18 @@ github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLe
github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U=
github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
-github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc=
-github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A=
+github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o=
+github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw=
github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
-github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
+github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/wire v0.5.0 h1:I7ELFeVBr3yfPIcc8+MWvrjk+3VjbcSzoXm3JVa+jD8=
github.com/google/wire v0.5.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU=
-github.com/googleapis/enterprise-certificate-proxy v0.2.5 h1:UR4rDjcgpgEnqpIEvkiqTYKBCKLNmlge2eVjoZfySzM=
-github.com/googleapis/enterprise-certificate-proxy v0.2.5/go.mod h1:RxW0N9901Cko1VOCW3SXCpWP+mlIEkk2tP7jnHy9a3w=
+github.com/googleapis/enterprise-certificate-proxy v0.3.1 h1:SBWmZhjUDRorQxrN0nwzf+AHBxnbFjViHQS4P0yVpmQ=
+github.com/googleapis/enterprise-certificate-proxy v0.3.1/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
@@ -417,8 +423,8 @@ github.com/gorilla/csrf v1.7.1 h1:Ir3o2c1/Uzj6FBxMlAUB6SivgVMy1ONXwYgXn+/aHPE=
github.com/gorilla/csrf v1.7.1/go.mod h1:+a/4tCmqhG6/w4oafeAZ9pEa3/NZOWYVbD9fV0FwIQA=
github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
-github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
-github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
+github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
+github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/gorilla/schema v1.2.0 h1:YufUaxZYCKGFuAq3c96BOhjgd5nmXiOY9NGzF247Tsc=
github.com/gorilla/schema v1.2.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
@@ -438,9 +444,8 @@ github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0 h1:f4tg
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0/go.mod h1:hKAkSgNkL0FII46ZkJcpVEAai4KV+swlIWCKfekd1pA=
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3 h1:o95KDiV/b1xdkumY5YbLR0/n2+wBxUpgf3HgfKgTyLI=
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3/go.mod h1:hTxjzRcX49ogbTGVJ1sM5mz5s+SSgiGIyL3jjPxl32E=
-github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 h1:RtRsiaGvWxcwd8y3BiRZxsylPT8hLWZ5SPcfI+3IDNk=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0/go.mod h1:TzP6duP4Py2pHLVPPQp42aoYI92+PCrVotyR5e8Vqlk=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.2-0.20231120080707-5e5867a3a4b0 h1:GrtGrVoGhFkqHHD4CkcULpMFE3b+PCrYHrf+Z2zlAgQ=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.2-0.20231120080707-5e5867a3a4b0/go.mod h1:TqYzBEZ4nh11Kg7YWLR3xZ0WgChhCC8NrheYg/WyqaI=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
@@ -449,14 +454,15 @@ github.com/hashicorp/golang-lru v0.6.0/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uG
github.com/hashicorp/hcl v0.0.0-20170914154624-68e816d1c783/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
-github.com/hellofresh/health-go/v5 v5.3.0 h1:T0tapAAuqVIiagRn0YQzFoIPAQek120/vQYPxpMMJ9M=
-github.com/hellofresh/health-go/v5 v5.3.0/go.mod h1:N6MLoACjLHjQQhQh+m2S1rXj1PuSBs/5uI32JKBzwf8=
+github.com/hellofresh/health-go/v5 v5.5.0 h1:N6zl1kOTTRsn26Bvo0KLTFSrK3iBOekhCLj3jbP9brI=
+github.com/hellofresh/health-go/v5 v5.5.0/go.mod h1:+eIMwQtFWKlrl9kE+eLeK//f97xAewFg2pP1U1v+Svg=
github.com/howeyc/gopass v0.0.0-20210920133722-c8aef6fb66ef h1:A9HsByNhogrvm9cWb28sjiS3i7tcKCkflWFEkHfuAgM=
github.com/howeyc/gopass v0.0.0-20210920133722-c8aef6fb66ef/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4=
github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI=
+github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
@@ -479,10 +485,15 @@ github.com/jackc/pgx/v5 v5.4.3/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSlj
github.com/jacobsa/crypto v0.0.0-20190317225127-9f44e2d11115 h1:YuDUUFNM21CAbyPOpOP8BicaTD/0klJEKt5p8yuw+uY=
github.com/jacobsa/crypto v0.0.0-20190317225127-9f44e2d11115/go.mod h1:LadVJg0XuawGk+8L1rYnIED8451UyNxEMdTWCEt5kmU=
github.com/jacobsa/oglematchers v0.0.0-20150720000706-141901ea67cd h1:9GCSedGjMcLZCrusBZuo4tyKLpKUPenUUqi34AkuFmA=
+github.com/jacobsa/oglematchers v0.0.0-20150720000706-141901ea67cd/go.mod h1:TlmyIZDpGmwRoTWiakdr+HA1Tukze6C6XbRVidYq02M=
github.com/jacobsa/oglemock v0.0.0-20150831005832-e94d794d06ff h1:2xRHTvkpJ5zJmglXLRqHiZQNjUoOkhUyhTAhEQvPAWw=
+github.com/jacobsa/oglemock v0.0.0-20150831005832-e94d794d06ff/go.mod h1:gJWba/XXGl0UoOmBQKRWCJdHrr3nE0T65t6ioaj3mLI=
github.com/jacobsa/ogletest v0.0.0-20170503003838-80d50a735a11 h1:BMb8s3ENQLt5ulwVIHVDWFHp8eIXmbfSExkvdn9qMXI=
+github.com/jacobsa/ogletest v0.0.0-20170503003838-80d50a735a11/go.mod h1:+DBdDyfoO2McrOyDemRBq0q9CMEByef7sYl7JH5Q3BI=
github.com/jacobsa/reqtrace v0.0.0-20150505043853-245c9e0234cb h1:uSWBjJdMf47kQlXMwWEfmc864bA1wAC+Kl3ApryuG9Y=
+github.com/jacobsa/reqtrace v0.0.0-20150505043853-245c9e0234cb/go.mod h1:ivcmUvxXWjb27NsPEaiYK7AidlZXS7oQ5PowUS9z3I4=
github.com/jarcoal/httpmock v1.3.1 h1:iUx3whfZWVf3jT01hQTO/Eo5sAYtB2/rqaUuOtpInww=
+github.com/jarcoal/httpmock v1.3.1/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg=
github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 h1:iCHtR9CQyktQ5+f3dMVZfwD2KWJUgm7M0gdL9NGr8KA=
github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
@@ -511,8 +522,8 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM=
-github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
+github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4=
+github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/kljensen/snowball v0.6.0/go.mod h1:27N7E8fVU5H68RlUmnWwZCfxgt4POBJfENGMvNRhldw=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -523,6 +534,7 @@ github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@@ -548,9 +560,10 @@ github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A
github.com/mattn/goveralls v0.0.12 h1:PEEeF0k1SsTjOBQ8FOmrOAoCu4ytuMaWCnWe94zxbCg=
github.com/mattn/goveralls v0.0.12/go.mod h1:44ImGEUfmqH8bBtaMrYKsM65LXfNLWmwaxFGjZwgMSQ=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
-github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
-github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
+github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg=
+github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k=
github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g=
+github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY=
github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ=
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
@@ -569,6 +582,7 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
+github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474/go.mod h1:OQA4XLvDbMgS8P0CevmM4m9Q3Jq4phKUzcocxuGJ5m8=
github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg=
github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM=
@@ -576,11 +590,13 @@ github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOl
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nats-io/jwt/v2 v2.5.2 h1:DhGH+nKt+wIkDxM6qnVSKjokq5t59AZV5HRcFW0zJwU=
-github.com/nats-io/nats-server/v2 v2.10.1 h1:MIJ614dhOIdo71iSzY8ln78miXwrYvlvXHUyS+XdKZQ=
-github.com/nats-io/nats.go v1.30.2 h1:aloM0TGpPorZKQhbAkdCzYDj+ZmsJDyeo3Gkbr72NuY=
-github.com/nats-io/nats.go v1.30.2/go.mod h1:dcfhUgmQNN4GJEfIb2f9R7Fow+gzBF4emzDHrVBd5qM=
-github.com/nats-io/nkeys v0.4.5 h1:Zdz2BUlFm4fJlierwvGK+yl20IAKUm7eV6AAZXEhkPk=
-github.com/nats-io/nkeys v0.4.5/go.mod h1:XUkxdLPTufzlihbamfzQ7mw/VGx6ObUs+0bN5sNvt64=
+github.com/nats-io/jwt/v2 v2.5.2/go.mod h1:24BeQtRwxRV8ruvC4CojXlx/WQ/VjuwlYiH+vu/+ibI=
+github.com/nats-io/nats-server/v2 v2.10.4 h1:uB9xcwon3tPXWAdmTJqqqC6cie3yuPWHJjjTBgaPNus=
+github.com/nats-io/nats-server/v2 v2.10.4/go.mod h1:eWm2JmHP9Lqm2oemB6/XGi0/GwsZwtWf8HIPUsh+9ns=
+github.com/nats-io/nats.go v1.31.0 h1:/WFBHEc/dOKBF6qf1TZhrdEfTmOZ5JzdJ+Y3m6Y/p7E=
+github.com/nats-io/nats.go v1.31.0/go.mod h1:di3Bm5MLsoB4Bx61CBTsxuarI36WbhAwOm8QrW39+i8=
+github.com/nats-io/nkeys v0.4.6 h1:IzVe95ru2CT6ta874rt9saQRkWfe2nFj1NtvYSLqMzY=
+github.com/nats-io/nkeys v0.4.6/go.mod h1:4DxZNzenSVd1cYQoAa8948QY3QDjrHfcfVADymtkpts=
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/oklog/ulid/v2 v2.1.0 h1:+9lhoxAP56we25tyYETBBY1YLA2SaoLvUFgrP2miPJU=
@@ -603,11 +619,12 @@ github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.0.1-0.20170904195809-1d6b12b7cb29/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
-github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
-github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
+github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
+github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ=
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
+github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -615,9 +632,11 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
-github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
+github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
@@ -639,8 +658,8 @@ github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
-github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY=
-github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY=
+github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM=
+github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
@@ -652,19 +671,23 @@ github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/
github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT1pX2CziuyQR0=
github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI=
github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
-github.com/redis/go-redis/v9 v9.2.1 h1:WlYJg71ODF0dVspZZCpYmoF1+U1Jjk9Rwd7pq6QmlCg=
-github.com/redis/go-redis/v9 v9.2.1/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
+github.com/redis/go-redis/v9 v9.3.0 h1:RiVDjmig62jIWp7Kk4XVLs0hzV6pI3PyTnnL0cnn0u0=
+github.com/redis/go-redis/v9 v9.3.0/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw=
github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
-github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
+github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/sagikazarmark/locafero v0.3.0 h1:zT7VEGWC2DTflmccN/5T1etyKvxSxpHsjb9cJvm4SvQ=
+github.com/sagikazarmark/locafero v0.3.0/go.mod h1:w+v7UsPNFwzF1cHuOajOOzoq4U7v/ig1mpRjqV+Bu1U=
+github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
+github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sendgrid/rest v2.6.9+incompatible h1:1EyIcsNdn9KIisLW50MKwmSRSK+ekueiEMJ7NEoxJo0=
@@ -683,12 +706,16 @@ github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVs
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
github.com/smarty/assertions v1.15.1 h1:812oFiXI+G55vxsFf+8bIZ1ux30qtkdqzKbEFwyX3Tk=
+github.com/smarty/assertions v1.15.1/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec=
github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
github.com/smartystreets/assertions v1.13.1 h1:Ef7KhSmjZcK6AVf9YbJdvPYG9avaF0ZxudX+ThRdWfU=
+github.com/smartystreets/assertions v1.13.1/go.mod h1:cXr/IwVfSo/RbCSPhoAPv73p3hlSdrBH/b3SdnW/LMY=
+github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
+github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
github.com/spf13/afero v0.0.0-20170901052352-ee1bd8ee15a1/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
-github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM=
-github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
+github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY=
+github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
github.com/spf13/cast v1.1.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
@@ -699,16 +726,14 @@ github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
github.com/spf13/jwalterweatherman v0.0.0-20170901151539-12bd96e66386/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
-github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
-github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v1.0.1-0.20170901120850-7aff26db30c1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.0.0/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
-github.com/spf13/viper v1.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc=
-github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg=
+github.com/spf13/viper v1.17.0 h1:I5txKw7MJasPL/BrfkbA0Jyo/oELqVmux4pR/UxOMfI=
+github.com/spf13/viper v1.17.0/go.mod h1:BmMMMLQXSbcHK6KAOiFLz0l5JHrU89OdIRHvsk0+yVI=
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf h1:pvbZ0lM0XWPBqUKqFU8cmavspvIl9nulOYwdy6IFRRo=
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf/go.mod h1:RJID2RhlZKId02nZ62WenDCkgHFerpIOmW0iT7GKmXM=
github.com/steveyen/gtreap v0.1.0 h1:CjhzTa274PyJLJuMZwIzCO1PfC00oRa8d1Kc78bFXJM=
@@ -727,11 +752,11 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
-github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc=
-github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
-github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
+github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
+github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
github.com/tebeka/snowball v0.4.2/go.mod h1:4IfL14h1lvwZcp1sfXuuc7/7yCsvVffTWxWxCLfFpYg=
@@ -751,8 +776,9 @@ github.com/uptrace/bun/dialect/pgdialect v1.1.16/go.mod h1:KQjfx/r6JM0OXfbv0rFrx
github.com/uptrace/bun/driver/pgdriver v1.1.16 h1:b/NiSXk6Ldw7KLfMLbOqIkm4odHd7QiNOCPLqPFJjK4=
github.com/uptrace/bun/driver/pgdriver v1.1.16/go.mod h1:Rmfbc+7lx1z/umjMyAxkOHK81LgnGj71XC5YpA6k1vU=
github.com/vitorsalgado/mocha/v2 v2.0.2 h1:wb1QCRzVkp8uhRcUYmb9jJfbMj/qbiqcDyD8rD+Ldfw=
-github.com/vmihailenco/msgpack/v5 v5.4.0 h1:hRM0digJwyR6vll33NNAwCFguy5JuBD6jxDmQP3l608=
-github.com/vmihailenco/msgpack/v5 v5.4.0/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
+github.com/vitorsalgado/mocha/v2 v2.0.2/go.mod h1:l7jRVm7KTL4VAxxazH99UVo+KzwztjrYpFTksTmL1DE=
+github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=
+github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
github.com/weppos/publicsuffix-go v0.13.1-0.20210123135404-5fd73613514e/go.mod h1:HYux0V0Zi04bHNwOHy4cXJVz/TQjYonnF6aoYhj+3QE=
@@ -786,39 +812,38 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
-go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux v0.45.0 h1:CaagQrotQLgtDlHU6u9pE/Mf4mAwiLD8wrReIVt06lY=
-go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux v0.45.0/go.mod h1:LOjFy00/ZMyMYfKFPta6kZe2cDUc1sNo/qtv1pSORWA=
-go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.45.0 h1:RsQi0qJ2imFfCvZabqzM9cNXBG8k6gXMv1A0cXRmH6A=
-go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.45.0/go.mod h1:vsh3ySueQCiKPxFLvjWC4Z135gIa34TQ/NSqkDTZYUM=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 h1:x8Z78aZx8cOF0+Kkazoc7lwUNMGy0LrzEMxTm4BbTxg=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0/go.mod h1:62CPTSry9QZtOaSsE3tOzhx6LzDhHnXJ6xHeMNNiM6Q=
-go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs=
-go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 h1:Mne5On7VWdx7omSrSSZvM4Kw7cS7NQkOOmLcgscI51U=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0/go.mod h1:IPtUMKL4O3tH5y+iXVyAXqpAwMuzC1IrxVS81rummfE=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 h1:3d+S281UTjM+AbF31XSOYn1qXn3BgIdWl8HNEpx08Jk=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0/go.mod h1:0+KuTDyKL4gjKCF75pHOX4wuzYDUZYfAQdSu43o+Z2I=
-go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.19.0 h1:Nw7Dv4lwvGrI68+wULbcq7su9K2cebeCUrDjVrUJHxM=
-go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.19.0/go.mod h1:1MsF6Y7gTqosgoZvHlzcaaM8DIMNZgJh87ykokoNH7Y=
-go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE=
-go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8=
-go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o=
-go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A=
-go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg=
-go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo=
-go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
+go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux v0.46.0 h1:HxJLvY878W39Q/yHlZW//4TXCPNth9t1MV1DcpoXzs0=
+go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux v0.46.0/go.mod h1:obCHBtvpRB//1iCFOeLyJtdd5aN2ZT0MAmYbxhIpo4M=
+go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.0 h1:PzIubN4/sjByhDRHLviCjJuweBXWFZWhghjg7cS28+M=
+go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.0/go.mod h1:Ct6zzQEuGK3WpJs2n4dn+wfJYzd/+hNnxMRTWjGn30M=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.0 h1:1eHu3/pUSWaOgltNK3WJFaywKsTIr/PwvHyDmi0lQA0=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.0/go.mod h1:HyABWq60Uy1kjJSa2BVOxUVao8Cdick5AWSKPutqy6U=
+go.opentelemetry.io/otel v1.20.0 h1:vsb/ggIY+hUjD/zCAQHpzTmndPqv/ml2ArbsbfBYTAc=
+go.opentelemetry.io/otel v1.20.0/go.mod h1:oUIGj3D77RwJdM6PPZImDpSZGDvkD9fhesHny69JFrs=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0 h1:DeFD0VgTZ+Cj6hxravYYZE2W4GlneVH81iAOPjZkzk8=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0/go.mod h1:GijYcYmNpX1KazD5JmWGsi4P7dDTTTnfv1UbGn84MnU=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0 h1:gvmNvqrPYovvyRmCSygkUDyL8lC5Tl845MLEwqpxhEU=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0/go.mod h1:vNUq47TGFioo+ffTSnKNdob241vePmtNZnAODKapKd0=
+go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.20.0 h1:4s9HxB4azeeQkhY0GE5wZlMj4/pz8tE5gx2OQpGUw58=
+go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.20.0/go.mod h1:djVA3TUJ2fSdMX0JE5XxFBOaZzprElJoP7fD4vnV2SU=
+go.opentelemetry.io/otel/metric v1.20.0 h1:ZlrO8Hu9+GAhnepmRGhSU7/VkpjrNowxRN9GyKR4wzA=
+go.opentelemetry.io/otel/metric v1.20.0/go.mod h1:90DRw3nfK4D7Sm/75yQ00gTJxtkBxX+wu6YaNymbpVM=
+go.opentelemetry.io/otel/sdk v1.20.0 h1:5Jf6imeFZlZtKv9Qbo6qt2ZkmWtdWx/wzcCbNUlAWGM=
+go.opentelemetry.io/otel/sdk v1.20.0/go.mod h1:rmkSx1cZCm/tn16iWDn1GQbLtsW/LvsdEEFzCSRM6V0=
+go.opentelemetry.io/otel/trace v1.20.0 h1:+yxVAPZPbQhbC3OfAkeIVTky6iTFpcr4SiY9om7mXSQ=
+go.opentelemetry.io/otel/trace v1.20.0/go.mod h1:HJSK7F/hA5RlzpZ0zKDCHCDHm556LCDtKaAo6JmBFUU=
go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=
go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM=
-go.packetbroker.org/api/iam v1.7.0 h1:JBPaR6xLcmZvCx7VXIET6SgIjyswnpvsoMyPTMPsVls=
-go.packetbroker.org/api/iam v1.7.0/go.mod h1:3xdC7qtWtDJh3Tjb1TueoDGAtrOizE2onrY1K6+Gm6U=
-go.packetbroker.org/api/iam/v2 v2.7.13 h1:uVNOGFAUttLcvYcC+ZrOXOPEZYkV47gxMyLm9viv+vo=
-go.packetbroker.org/api/iam/v2 v2.7.13/go.mod h1:HPBEl7oTtmxSq762h9WW3zyGMvZXnoNQIopczUV7gEE=
-go.packetbroker.org/api/mapping/v2 v2.1.32 h1:SeJ4oc+BYAUzUpZWkGJg9YtKZy/D1IDss9O2dX/NW54=
-go.packetbroker.org/api/mapping/v2 v2.1.32/go.mod h1:I2qf9dWkMAH+uRY8Q/5gGxv68wLJBRRt48niAlOQ1NY=
-go.packetbroker.org/api/routing v1.8.23 h1:fCPGt6zYKZ+/RW60nVnxe+yn4gck0Hcr6VAgU0PD+4U=
-go.packetbroker.org/api/routing v1.8.23/go.mod h1:NmFAo4VGGGEYIHKdD0Tmk03f5e81NSYu8QApAF7vONs=
-go.packetbroker.org/api/v3 v3.15.2 h1:CqBWwsqU3q7URTcwZEa+cJ+Stpc97ZVIXTMZlUJiFHM=
-go.packetbroker.org/api/v3 v3.15.2/go.mod h1:6bVbdWAYLnvZ5kgXxA7GBQvZTN7vxI0DoF1Di1NoAT4=
+go.packetbroker.org/api/iam v1.8.1 h1:x4p0kxfzOQ0dhxQUCAmFqXsBMB6BWpVTnPvtFzDgzd4=
+go.packetbroker.org/api/iam v1.8.1/go.mod h1:MRgGTxJwPM7spA3SB6qe6ARvbqBkUEExLe/MFb6Ol4Y=
+go.packetbroker.org/api/iam/v2 v2.9.0 h1:abBdj56opWeWFXXbLnCCf5Ao1bht+bPcWZZlPYLwhXY=
+go.packetbroker.org/api/iam/v2 v2.9.0/go.mod h1:Z2uiw0kwDHBwRgdfYfZsg4GQEpI0JfWOMOJdJo81jGU=
+go.packetbroker.org/api/mapping/v2 v2.3.0 h1:aGLF21uGcDssucTX3TMmEvrtWl29+mI/pdTFnPG2+zs=
+go.packetbroker.org/api/mapping/v2 v2.3.0/go.mod h1:SmnnK2mwsUeS09xeKXrA96VUZrd8hd1lPvrR4jAboiM=
+go.packetbroker.org/api/routing v1.9.1 h1:HhIIYH75njzPoDSFIFgqV6no3/h+x8HGIYcLHm2V86g=
+go.packetbroker.org/api/routing v1.9.1/go.mod h1:om1s5jnhezPlpsemK8uJonH9YzRoqvIp0mCBTtfpLc0=
+go.packetbroker.org/api/v3 v3.17.0 h1:7yHGYrKt457JwD/nAN8ouXD8B3NrSpbDIwZCKL3l6vc=
+go.packetbroker.org/api/v3 v3.17.0/go.mod h1:6bVbdWAYLnvZ5kgXxA7GBQvZTN7vxI0DoF1Di1NoAT4=
go.thethings.network/lorawan-application-payload v0.0.0-20220125153912-1198ff1e403e h1:TWGQ3lh7gI2W5hnb6qPdpoAa0d7s/XPwvgf2VVCMJaY=
go.thethings.network/lorawan-application-payload v0.0.0-20220125153912-1198ff1e403e/go.mod h1:/smENFuESiJCyWRsHRLBjbZGMN889BORQXIPP6NlpZE=
go.thethings.network/lorawan-stack-legacy/v2 v2.1.0 h1:xP1fElQiH8/6GWXg6JG8UqRD0uluhmicIRS4e/BzcAw=
@@ -827,7 +852,8 @@ go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8=
go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
-go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
+go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
+go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
@@ -848,11 +874,10 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
-golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
-golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
+golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA=
+golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -863,13 +888,13 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
-golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
-golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
+golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
+golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
-golang.org/x/image v0.5.0 h1:5JMiNunQeQw++mMOz48/ISeNu3Iweh/JaZU8ZLqHRrI=
-golang.org/x/image v0.5.0/go.mod h1:FVC7BI/5Ym8R25iw5OLsgshdUBbT1h5jZTpA+mvAdZ4=
+golang.org/x/image v0.10.0 h1:gXjUUtwtx5yOE0VKWq1CH4IJAClq4UGgUA3i+rpON9M=
+golang.org/x/image v0.10.0/go.mod h1:jtrku+n79PfroUbvDdeUWMAI+heR786BofxrbiSF+J0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -894,8 +919,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
-golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY=
+golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -937,12 +962,11 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
-golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
-golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
-golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
+golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg=
+golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ=
golang.org/x/oauth2 v0.0.0-20170912212905-13449ad91cb2/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -956,8 +980,8 @@ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
-golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4=
-golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4=
+golang.org/x/oauth2 v0.14.0 h1:P0Vrf/2538nmC0H+pEQ3MNFRRnVR7RlqyVw+bvm26z0=
+golang.org/x/oauth2 v0.14.0/go.mod h1:lAtNWgaWfL4cm7j2OV8TxGi9Qb7ECORx8DktCY74OwM=
golang.org/x/sync v0.0.0-20170517211232-f52d1811a629/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -972,8 +996,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
-golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
+golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
+golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1033,22 +1057,19 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
-golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
+golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
-golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU=
-golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
+golang.org/x/term v0.14.0 h1:LGK9IlZ8T9jvdy6cTdfKUCltatMFOehAQo9SRC46UQ8=
+golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -1061,8 +1082,9 @@ golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
-golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
-golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.0.0-20170424234030-8be79e1e0910/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -1123,8 +1145,8 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4=
-golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
-golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
+golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc=
+golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -1151,16 +1173,17 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz513
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
-google.golang.org/api v0.134.0 h1:ktL4Goua+UBgoP1eL1/60LwZJqa1sIzkLmvoR3hR6Gw=
-google.golang.org/api v0.134.0/go.mod h1:sjRL3UnjTx5UqNQS9EWr9N8p7xbHpy1k0XGRLCf3Spk=
+google.golang.org/api v0.143.0 h1:o8cekTkqhywkbZT6p1UHJPZ9+9uuCAJs/KYomxZB8fA=
+google.golang.org/api v0.143.0/go.mod h1:FoX9DO9hT7DLNn97OuoZAGSDuNAXdJRuGK98rSUgurk=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
-google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
+google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
google.golang.org/genproto v0.0.0-20170918111702-1e559d0a00ee/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
@@ -1186,7 +1209,6 @@ google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfG
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
@@ -1201,12 +1223,12 @@ google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20230911183012-2d3300fd4832 h1:/30npZKtUjXqju7ZA2MsvpkGKD4mQFtf+zPnZasABjg=
-google.golang.org/genproto v0.0.0-20230911183012-2d3300fd4832/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4=
-google.golang.org/genproto/googleapis/api v0.0.0-20230911183012-2d3300fd4832 h1:4E7rZzBdR5LmiZx6n47Dg4AjH8JLhMQWywsYqvXNLcs=
-google.golang.org/genproto/googleapis/api v0.0.0-20230911183012-2d3300fd4832/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20230911183012-2d3300fd4832 h1:o4LtQxebKIJ4vkzyhtD2rfUNZ20Zf0ik5YVP5E7G7VE=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20230911183012-2d3300fd4832/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M=
+google.golang.org/genproto v0.0.0-20231030173426-d783a09b4405 h1:I6WNifs6pF9tNdSob2W24JtyxIYjzFB9qDlpUC76q+U=
+google.golang.org/genproto v0.0.0-20231030173426-d783a09b4405/go.mod h1:3WDQMjmJk36UQhjQ89emUzb1mdaHcPeeAh4SCBKznB4=
+google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 h1:JpwMPBpFN3uKhdaekDpiNlImDdkUAyiJ6ez/uxGaUSo=
+google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:0xJLfVdJqpAPl8tDg1ujOCGzx6LFLttXT5NhllGOXY4=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 h1:Jyp0Hsi0bmHXG6k9eATXoYtjd6e2UzZ1SCn/wIupY14=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:oQ5rr10WTTMvP4A36n8JpR1OrO1BEiV4f78CneXZxkA=
google.golang.org/grpc v1.2.1-0.20170921194603-d4b75ebd4f9f/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
@@ -1221,15 +1243,12 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
-google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
-google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
-google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
-google.golang.org/grpc v1.58.2 h1:SXUpjxeVF3FKrTYQI4f4KvbGD5u2xccdYdurwowix5I=
-google.golang.org/grpc v1.58.2/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
+google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
+google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
google.golang.org/grpc/examples v0.0.0-20210424002626-9572fd6faeae/go.mod h1:Ly7ZA/ARzg8fnPU9TyZIxoz33sEUuWX7txiqs8lPTgE=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
@@ -1267,7 +1286,6 @@ gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
@@ -1290,6 +1308,8 @@ k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw=
k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
mellium.im/sasl v0.3.1 h1:wE0LW6g7U83vhvxjC1IY8DnXM+EU095yeo8XClvCdfo=
mellium.im/sasl v0.3.1/go.mod h1:xm59PUYpZHhgQ9ZqoJ5QaCqzWMi8IeS49dhp6plPCzw=
+nhooyr.io/websocket v1.8.10 h1:mv4p+MnGrLDcPlBoWsvPP7XCzTYMXP9F9eIGoKbgx7Q=
+nhooyr.io/websocket v1.8.10/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
diff --git a/tools/mage/js.go b/tools/mage/js.go
index f3e20d679d..1413949f02 100644
--- a/tools/mage/js.go
+++ b/tools/mage/js.go
@@ -237,7 +237,7 @@ func (js Js) ExtractLocaleFiles() error {
if mg.Verbose() {
fmt.Println("Building frontend locale files")
}
- return sh.Run("node", "tools/mage/translations.js")
+ return sh.Run("node", "tools/mage/translations.js", "--ignore-duplicates")
}
// BackendTranslations builds the backend locale files.
diff --git a/tools/mage/translations.js b/tools/mage/translations.js
index cfa013d90c..cf63da9666 100644
--- a/tools/mage/translations.js
+++ b/tools/mage/translations.js
@@ -14,6 +14,7 @@
/* global process */
/* eslint-disable no-alert, no-console */
+/* eslint-disable import/no-commonjs */
const fs = require('fs')
const path = require('path')
@@ -32,7 +33,7 @@ const env = process.env
* @param {string|Array} s - The string or array to flatten.
* @returns {Array} - A flat array of strings.
*/
-const flatten = function (s) {
+const flatten = s => {
if (!s) {
return []
}
@@ -52,6 +53,8 @@ const backendMessages = argv.backendMessages || env.MESSAGES_BACKEND || 'config/
const defaultLocale = argv.default || env.DEFAULT_LOCALE || 'en'
const exportForTranslation = argv['export-for-interpreters'] || env.EXPORT_FOR_INTERPRETERS || false
const verbose = ('verbose' in argv && argv.verbose !== 'false') || false
+const ignoreDuplicates =
+ ('ignore-duplicates' in argv && argv['ignore-duplicates'] !== 'false') || false
if (argv.help) {
console.log(`Usage: translations [opts]
@@ -76,6 +79,7 @@ Options:
--backend-only . Flag that determines whether only backend messages will be processed
--verbose verbose output for debugging purposes
--export-for-translation Flag that determines whether the messages will be exported for interpreters
+ --ignore-duplicates Flag that determines whether the program will ignore duplicate messages
--help show this help message
`)
}
@@ -85,18 +89,17 @@ Options:
*
* @param {string} pat - The glob pattern, eg. "./foo/*.js".
* @returns {Promise>} - A promise that resolves to an array of
- * filenames that match the pattern.
+ * filenames that match the pattern.
*/
-const glob = function (pat) {
- return new Promise(function (resolve, reject) {
- g(pat, function (err, res) {
+const glob = pat =>
+ new Promise((resolve, reject) => {
+ g(pat, (err, res) => {
if (err) {
return reject(err)
}
return resolve(res)
})
})
-}
/**
* Read a file from disk.
@@ -104,19 +107,18 @@ const glob = function (pat) {
* @param {string} filename - The name of the file to read.
* @returns {Promise} - The contents of the file.
*/
-const read = function (filename) {
- return new Promise(function (resolve, reject) {
+const read = filename =>
+ new Promise((resolve, reject) => {
if (verbose) {
console.log(`reading from ${filename}`)
}
- fs.readFile(filename, function (err, res) {
+ fs.readFile(filename, (err, res) => {
if (err) {
return reject(err)
}
return resolve(res)
})
})
-}
/**
* Write to a file.
@@ -126,19 +128,18 @@ const read = function (filename) {
*
* @returns {Promise} - A promise that resolves when the file has been written.
*/
-const write = function (filename, content) {
- return new Promise(function (resolve, reject) {
+const write = (filename, content) =>
+ new Promise((resolve, reject) => {
if (verbose) {
console.log('writing', filename)
}
- fs.writeFile(filename, content, function (err, res) {
+ fs.writeFile(filename, content, (err, res) => {
if (err) {
return reject(err)
}
return resolve(res)
})
})
-}
/**
* Read the locales from the localesDir (specified by --locales) and parse
@@ -147,24 +148,67 @@ const write = function (filename, content) {
* Locales that are in the localesDir but not in --support will be omitted.
*
* @returns {object} - The locales, keyed by locale name.
- * For example: `{ en: { ... }, ja: { ... }}`.
+ * For example: `{ en: { ... }, ja: { ... }}`.
*/
-const readLocales = async function () {
+const readLocales = async () => {
const loc = await Promise.all(
- support.map(async function (locale) {
+ support.map(async locale => {
let parsed = {}
+ let content
try {
- const content = await read(`${path.resolve(localesDir)}/${locale}.json`)
+ content = await read(`${path.resolve(localesDir)}/${locale}.json`)
parsed = JSON.parse(content)
- } catch (err) {}
+ } catch (err) {
+ if (err instanceof SyntaxError) {
+ // Check if there are merge conflicts in the JSON file
+ if (content.includes('<<<<<<<') && content.includes('>>>>>>>')) {
+ throw new SyntaxError(
+ `Error parsing ${locale}.json: merge conflicts found.\n\nPlease resolve merge conflicts before continuing.`,
+ )
+ }
+ throw err
+ }
+ }
parsed.__locale = locale
+ // Detect duplicate messages in the English locale and store them per message
+ // this will cause a non-zero exit code so that this issue can be caught in CI
+ if (locale === defaultLocale) {
+ const duplicates = Object.entries(parsed)
+ .reduce((acc, [id, message]) => {
+ const existing = acc.find(d => d.message === message)
+ if (existing) {
+ existing.ids.push(id)
+ } else {
+ acc.push({ message, ids: [id] })
+ }
+ return acc
+ }, [])
+ .filter(d => d.ids.length > 1)
+
+ if (duplicates.length > 0) {
+ // Write duplicates to a file
+ await write(
+ `${path.resolve(localesDir)}/${locale}-duplicates.json`,
+ JSON.stringify(duplicates, null, 2),
+ )
+
+ console.warn(
+ `Duplicate messages found in the "${locale}" locale. This means that the same message text is used more than once. See ${locale}-duplicates.json for details and resolve the issue before continuing.`,
+ )
+
+ if (!ignoreDuplicates) {
+ process.exit(1)
+ }
+ }
+ }
+
return parsed
}),
)
- return loc.reduce(function (acc, next) {
+ return loc.reduce((acc, next) => {
const locale = next.__locale
delete next.__locale
@@ -181,7 +225,7 @@ const readLocales = async function () {
*
* @returns {object} - The messages, keyed by message id.
*/
-const readMessages = async function () {
+const readMessages = async () => {
if (!messagesDir) {
return {}
}
@@ -189,10 +233,8 @@ const readMessages = async function () {
return files
.map(f => fs.readFileSync(f, 'utf-8'))
.map(c => JSON.parse(c))
- .reduce(function (acc, next) {
- return [...acc, ...next]
- }, [])
- .reduce(function (acc, next) {
+ .reduce((acc, next) => [...acc, ...next], [])
+ .reduce((acc, next) => {
if (next.id in acc) {
console.warn(`message id ${next.id} seen multiple times`)
}
@@ -209,13 +251,13 @@ const readMessages = async function () {
*
* @returns {object} - The backend messages, keyed by message id.
*/
-const readBackendMessages = async function () {
+const readBackendMessages = async () => {
if (!backendMessages) {
return {}
}
const backend = JSON.parse(await read(`${path.resolve(backendMessages)}`))
- return Object.keys(backend).reduce(function (acc, id) {
- return {
+ return Object.keys(backend).reduce(
+ (acc, id) => ({
...acc,
[id]: {
id,
@@ -223,8 +265,9 @@ const readBackendMessages = async function () {
locales: backend[id].translations,
description: backend[id].description,
},
- }
- }, {})
+ }),
+ {},
+ )
}
/**
@@ -234,7 +277,7 @@ const readBackendMessages = async function () {
* @param {Array} pth - The path to find in the object.
* @returns {any} - The value of the key at the path, or null if not found.
*/
-const get = function (object, ...pth) {
+const get = (object, ...pth) => {
if (object === null) {
return null
}
@@ -256,17 +299,17 @@ const get = function (object, ...pth) {
* Write locales to their corresponding file in the localesDir (specified by --locales).
*
* @param {object} locales - The locales to write.
- * @param backendIds
+ * @param {Array} backendIds - The ids of the backend messages.
* @returns {Promise} - A promise that resolves when all locales have been written.
*/
-const writeLocales = async function (locales, backendIds) {
- return Promise.all(
- Object.keys(locales).map(async function (key) {
+const writeLocales = async (locales, backendIds) =>
+ Promise.all(
+ Object.keys(locales).map(async key => {
const locale = locales[key]
let cleaned = locale
if (key === defaultLocale && !backendOnly) {
// Remove backend keys from the default locale
- cleaned = Object.keys(locale).reduce(function (acc, next) {
+ cleaned = Object.keys(locale).reduce((acc, next) => {
if (!backendIds.includes(next)) {
return {
...acc,
@@ -281,23 +324,22 @@ const writeLocales = async function (locales, backendIds) {
await write(`${localesDir}/${key}.json`, content)
}),
)
-}
/**
* Write messages out for supported locales as CSV, for use when translating.
*
* @param {object} locales - The locales to write.
- * @param targetLanguage - The language (locale) to translate to.
+ * @param {string} targetLanguage - The language (locale) to translate to.
* @returns {Promise} - A promise that resolves when the file has been written.
*/
-const writeInterpreterFile = async function (locales, targetLanguage) {
+const writeInterpreterFile = async (locales, targetLanguage) => {
// Write the data as CSV, the first column being the message id
// the second column being the English message, and the third being the target language message.
const locale = locales[targetLanguage]
const content = Object.keys(locale)
.filter(id => !locale[id])
- .map(function (id) {
+ .map(id => {
const message = locale[id] || ''
// Add proper escapes
const english = locales[defaultLocale][id].replace(/"/g, '""')
@@ -309,7 +351,7 @@ const writeInterpreterFile = async function (locales, targetLanguage) {
}
// Main function.
-const main = async function () {
+const main = async () => {
const [locales, messages, backend] = await Promise.all([
readLocales(),
readMessages(),
@@ -353,14 +395,14 @@ const main = async function () {
if (exportForTranslation) {
const supportWithoutDefault = support.filter(s => s !== defaultLocale)
- supportWithoutDefault.forEach(async function (targetLanguage) {
+ supportWithoutDefault.forEach(async targetLanguage => {
await writeInterpreterFile(updated, targetLanguage)
})
}
console.log('Locale files updated.')
}
-main().catch(function (err) {
+main().catch(err => {
console.error(err)
process.exit(1)
})
diff --git a/yarn.lock b/yarn.lock
index db2a5bc084..b342f56ca2 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -8,9 +8,9 @@
integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==
"@adobe/css-tools@^4.0.1":
- version "4.3.1"
- resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.3.1.tgz#abfccb8ca78075a2b6187345c26243c1a0842f28"
- integrity sha512-/62yikz7NLScCGAAST5SHdnjaDJQBDq0M2muyRTpf2VQhw6StBg2ALiu73zSJQ4fMVLA+0uBhBHAle7Wg+2kSg==
+ version "4.3.2"
+ resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.3.2.tgz#a6abc715fb6884851fca9dad37fc34739a04fd11"
+ integrity sha512-DA5a1C0gD/pLOvhv33YMrbf2FK3oUzwNl9oOJqE4XVjuEtt6XIakRcsd7eLiOSPkp1kTRQGICTA8cKra/vFbjw==
"@ampproject/remapping@^2.1.0":
version "2.2.0"
@@ -28,14 +28,14 @@
"@jridgewell/gen-mapping" "^0.3.0"
"@jridgewell/trace-mapping" "^0.3.9"
-"@babel/cli@^7.22.9":
- version "7.22.9"
- resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.22.9.tgz#501b3614aeda7399371f6d5991404f069b059986"
- integrity sha512-nb2O7AThqRo7/E53EGiuAkMaRbb7J5Qp3RvN+dmua1U+kydm0oznkhqbTEG15yk26G/C3yL6OdZjzgl+DMXVVA==
+"@babel/cli@^7.23.0":
+ version "7.23.0"
+ resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.23.0.tgz#1d7f37c44d4117c67df46749e0c86e11a58cc64b"
+ integrity sha512-17E1oSkGk2IwNILM4jtfAvgjt+ohmpfBky8aLerUfYZhiPNg7ca+CRCxZn8QDxwNhV/upsc2VHBCqGFIR+iBfA==
dependencies:
"@jridgewell/trace-mapping" "^0.3.17"
commander "^4.0.1"
- convert-source-map "^1.1.0"
+ convert-source-map "^2.0.0"
fs-readdir-recursive "^1.1.0"
glob "^7.2.0"
make-dir "^2.1.0"
@@ -65,6 +65,14 @@
dependencies:
"@babel/highlight" "^7.18.6"
+"@babel/code-frame@^7.22.13":
+ version "7.22.13"
+ resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e"
+ integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==
+ dependencies:
+ "@babel/highlight" "^7.22.13"
+ chalk "^2.4.2"
+
"@babel/code-frame@^7.22.5":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.5.tgz#234d98e1551960604f1246e6475891a570ad5658"
@@ -72,30 +80,10 @@
dependencies:
"@babel/highlight" "^7.22.5"
-"@babel/compat-data@^7.17.10":
- version "7.17.10"
- resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.10.tgz#711dc726a492dfc8be8220028b1b92482362baab"
- integrity sha512-GZt/TCsG70Ms19gfZO1tM4CVnXsPgEPBCpJu+Qz3L0LUDsY5nZqFZglIoPC1kIYOtNBZlrnFT+klg12vFGZXrw==
-
-"@babel/compat-data@^7.20.0":
- version "7.20.5"
- resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.5.tgz#86f172690b093373a933223b4745deeb6049e733"
- integrity sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==
-
-"@babel/compat-data@^7.21.5":
- version "7.21.7"
- resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.21.7.tgz#61caffb60776e49a57ba61a88f02bedd8714f6bc"
- integrity sha512-KYMqFYTaenzMK4yUtf4EW9wc4N9ef80FsbMtkwool5zpwl4YrT1SdWYSTRcT94KO4hannogdS+LxY7L+arP3gA==
-
-"@babel/compat-data@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.5.tgz#b1f6c86a02d85d2dd3368a2b67c09add8cd0c255"
- integrity sha512-4Jc/YuIaYqKnDDz892kPIledykKg12Aw1PYX5i/TY28anJtacvM1Rrr8wbieB9GfEJwlzqT0hUEao0CxEebiDA==
-
-"@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9":
- version "7.22.9"
- resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.9.tgz#71cdb00a1ce3a329ce4cbec3a44f9fef35669730"
- integrity sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==
+"@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9", "@babel/compat-data@^7.23.2":
+ version "7.23.2"
+ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.2.tgz#6a12ced93455827037bfb5ed8492820d60fc32cc"
+ integrity sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ==
"@babel/core@^7.11.6":
version "7.20.5"
@@ -228,12 +216,15 @@
"@jridgewell/trace-mapping" "^0.3.17"
jsesc "^2.5.1"
-"@babel/helper-annotate-as-pure@^7.16.7":
- version "7.16.7"
- resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz#bb2339a7534a9c128e3102024c60760a3a7f3862"
- integrity sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==
+"@babel/generator@^7.23.0":
+ version "7.23.0"
+ resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.0.tgz#df5c386e2218be505b34837acbcb874d7a983420"
+ integrity sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==
dependencies:
- "@babel/types" "^7.16.7"
+ "@babel/types" "^7.23.0"
+ "@jridgewell/gen-mapping" "^0.3.2"
+ "@jridgewell/trace-mapping" "^0.3.17"
+ jsesc "^2.5.1"
"@babel/helper-annotate-as-pure@^7.18.6":
version "7.18.6"
@@ -256,60 +247,18 @@
dependencies:
"@babel/types" "^7.22.5"
-"@babel/helper-compilation-targets@^7.17.10":
- version "7.17.10"
- resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.10.tgz#09c63106d47af93cf31803db6bc49fef354e2ebe"
- integrity sha512-gh3RxjWbauw/dFiU/7whjd0qN9K6nPJMqe6+Er7rOavFh0CQUSwhAE3IcTho2rywPJFxej6TUUHDkWcYI6gGqQ==
- dependencies:
- "@babel/compat-data" "^7.17.10"
- "@babel/helper-validator-option" "^7.16.7"
- browserslist "^4.20.2"
- semver "^6.3.0"
-
-"@babel/helper-compilation-targets@^7.20.0":
- version "7.20.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz#6bf5374d424e1b3922822f1d9bdaa43b1a139d0a"
- integrity sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==
- dependencies:
- "@babel/compat-data" "^7.20.0"
- "@babel/helper-validator-option" "^7.18.6"
- browserslist "^4.21.3"
- semver "^6.3.0"
-
-"@babel/helper-compilation-targets@^7.21.5":
- version "7.21.5"
- resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.5.tgz#631e6cc784c7b660417421349aac304c94115366"
- integrity sha512-1RkbFGUKex4lvsB9yhIfWltJM5cZKUftB2eNajaDv3dCMEp49iBG0K14uH8NnX9IPux2+mK7JGEOB0jn48/J6w==
- dependencies:
- "@babel/compat-data" "^7.21.5"
- "@babel/helper-validator-option" "^7.21.0"
- browserslist "^4.21.3"
- lru-cache "^5.1.1"
- semver "^6.3.0"
-
-"@babel/helper-compilation-targets@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.5.tgz#fc7319fc54c5e2fa14b2909cf3c5fd3046813e02"
- integrity sha512-Ji+ywpHeuqxB8WDxraCiqR0xfhYjiDE/e6k7FuIaANnoOFxAHskHChz4vA1mJC9Lbm01s1PVAGhQY4FUKSkGZw==
- dependencies:
- "@babel/compat-data" "^7.22.5"
- "@babel/helper-validator-option" "^7.22.5"
- browserslist "^4.21.3"
- lru-cache "^5.1.1"
- semver "^6.3.0"
-
-"@babel/helper-compilation-targets@^7.22.6":
- version "7.22.10"
- resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz#01d648bbc25dd88f513d862ee0df27b7d4e67024"
- integrity sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q==
+"@babel/helper-compilation-targets@^7.17.10", "@babel/helper-compilation-targets@^7.20.0", "@babel/helper-compilation-targets@^7.21.5", "@babel/helper-compilation-targets@^7.22.15", "@babel/helper-compilation-targets@^7.22.5", "@babel/helper-compilation-targets@^7.22.6":
+ version "7.22.15"
+ resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz#0698fc44551a26cf29f18d4662d5bf545a6cfc52"
+ integrity sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==
dependencies:
"@babel/compat-data" "^7.22.9"
- "@babel/helper-validator-option" "^7.22.5"
+ "@babel/helper-validator-option" "^7.22.15"
browserslist "^4.21.9"
lru-cache "^5.1.1"
semver "^6.3.1"
-"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.22.15", "@babel/helper-create-class-features-plugin@^7.22.5":
+"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.22.11", "@babel/helper-create-class-features-plugin@^7.22.15", "@babel/helper-create-class-features-plugin@^7.22.5":
version "7.22.15"
resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.15.tgz#97a61b385e57fe458496fad19f8e63b63c867de4"
integrity sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==
@@ -324,14 +273,6 @@
"@babel/helper-split-export-declaration" "^7.22.6"
semver "^6.3.1"
-"@babel/helper-create-regexp-features-plugin@^7.16.7":
- version "7.16.7"
- resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.7.tgz#0cb82b9bac358eb73bfbd73985a776bfa6b14d48"
- integrity sha512-fk5A6ymfp+O5+p2yCkXAu5Kyj6v0xh0RBeNcAkYUMDvvAAoxvSKXn+Jb37t/yWFiQVDFK1ELpUTD8/aLhCPu+g==
- dependencies:
- "@babel/helper-annotate-as-pure" "^7.16.7"
- regexpu-core "^4.7.1"
-
"@babel/helper-create-regexp-features-plugin@^7.18.6":
version "7.21.8"
resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.21.8.tgz#a7886f61c2e29e21fd4aaeaf1e473deba6b571dc"
@@ -350,10 +291,10 @@
regexpu-core "^5.3.1"
semver "^6.3.0"
-"@babel/helper-define-polyfill-provider@^0.4.2":
- version "0.4.2"
- resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.2.tgz#82c825cadeeeee7aad237618ebbe8fa1710015d7"
- integrity sha512-k0qnnOqHn5dK9pZpfD5XXZ9SojAITdCKRn2Lp6rnDGzIbaP0rHyMPk/4wsSxVBVz4RfN0q6VpXWP2pDGIoQ7hw==
+"@babel/helper-define-polyfill-provider@^0.4.3":
+ version "0.4.3"
+ resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.3.tgz#a71c10f7146d809f4a256c373f462d9bba8cf6ba"
+ integrity sha512-WBrLmuPP47n7PNwsZ57pqam6G/RGo1vw/87b0Blc53tZNGZ4x7YvZ6HgQe2vo1W/FR20OgjeZuGXzudPiXHFug==
dependencies:
"@babel/helper-compilation-targets" "^7.22.6"
"@babel/helper-plugin-utils" "^7.22.5"
@@ -388,30 +329,6 @@
resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz#f06dd41b7c1f44e1f8da6c4055b41ab3a09a7e98"
integrity sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==
-"@babel/helper-function-name@^7.17.9":
- version "7.17.9"
- resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz#136fcd54bc1da82fcb47565cf16fd8e444b1ff12"
- integrity sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg==
- dependencies:
- "@babel/template" "^7.16.7"
- "@babel/types" "^7.17.0"
-
-"@babel/helper-function-name@^7.19.0":
- version "7.19.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz#941574ed5390682e872e52d3f38ce9d1bef4648c"
- integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==
- dependencies:
- "@babel/template" "^7.18.10"
- "@babel/types" "^7.19.0"
-
-"@babel/helper-function-name@^7.21.0":
- version "7.21.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz#d552829b10ea9f120969304023cd0645fa00b1b4"
- integrity sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==
- dependencies:
- "@babel/template" "^7.20.7"
- "@babel/types" "^7.21.0"
-
"@babel/helper-function-name@^7.22.5":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz#ede300828905bb15e582c037162f99d5183af1be"
@@ -420,19 +337,13 @@
"@babel/template" "^7.22.5"
"@babel/types" "^7.22.5"
-"@babel/helper-hoist-variables@^7.16.7":
- version "7.16.7"
- resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246"
- integrity sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==
- dependencies:
- "@babel/types" "^7.16.7"
-
-"@babel/helper-hoist-variables@^7.18.6":
- version "7.18.6"
- resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678"
- integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==
+"@babel/helper-function-name@^7.23.0":
+ version "7.23.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759"
+ integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==
dependencies:
- "@babel/types" "^7.18.6"
+ "@babel/template" "^7.22.15"
+ "@babel/types" "^7.23.0"
"@babel/helper-hoist-variables@^7.22.5":
version "7.22.5"
@@ -455,6 +366,13 @@
dependencies:
"@babel/types" "^7.22.5"
+"@babel/helper-module-imports@^7.22.15":
+ version "7.22.15"
+ resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz#16146307acdc40cc00c3b2c647713076464bdbf0"
+ integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==
+ dependencies:
+ "@babel/types" "^7.22.15"
+
"@babel/helper-module-transforms@^7.18.0":
version "7.18.0"
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.18.0.tgz#baf05dec7a5875fb9235bd34ca18bad4e21221cd"
@@ -511,6 +429,17 @@
"@babel/traverse" "^7.22.5"
"@babel/types" "^7.22.5"
+"@babel/helper-module-transforms@^7.23.0":
+ version "7.23.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz#3ec246457f6c842c0aee62a01f60739906f7047e"
+ integrity sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==
+ dependencies:
+ "@babel/helper-environment-visitor" "^7.22.20"
+ "@babel/helper-module-imports" "^7.22.15"
+ "@babel/helper-simple-access" "^7.22.5"
+ "@babel/helper-split-export-declaration" "^7.22.6"
+ "@babel/helper-validator-identifier" "^7.22.20"
+
"@babel/helper-optimise-call-expression@^7.22.5":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz#f21531a9ccbff644fdd156b4077c16ff0c3f609e"
@@ -518,11 +447,20 @@
dependencies:
"@babel/types" "^7.22.5"
-"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3":
+"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295"
integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==
+"@babel/helper-remap-async-to-generator@^7.22.20":
+ version "7.22.20"
+ resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz#7b68e1cb4fa964d2996fd063723fb48eca8498e0"
+ integrity sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==
+ dependencies:
+ "@babel/helper-annotate-as-pure" "^7.22.5"
+ "@babel/helper-environment-visitor" "^7.22.20"
+ "@babel/helper-wrap-function" "^7.22.20"
+
"@babel/helper-remap-async-to-generator@^7.22.5":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.5.tgz#14a38141a7bf2165ad38da61d61cf27b43015da2"
@@ -584,16 +522,6 @@
dependencies:
"@babel/types" "^7.22.5"
-"@babel/helper-string-parser@^7.19.4":
- version "7.19.4"
- resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63"
- integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==
-
-"@babel/helper-string-parser@^7.21.5":
- version "7.21.5"
- resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz#2b3eea65443c6bdc31c22d037c65f6d323b6b2bd"
- integrity sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==
-
"@babel/helper-string-parser@^7.22.5":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f"
@@ -624,25 +552,19 @@
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193"
integrity sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==
-"@babel/helper-validator-option@^7.16.7":
- version "7.16.7"
- resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23"
- integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==
-
-"@babel/helper-validator-option@^7.18.6":
- version "7.18.6"
- resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8"
- integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==
-
-"@babel/helper-validator-option@^7.21.0":
- version "7.21.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz#8224c7e13ace4bafdc4004da2cf064ef42673180"
- integrity sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==
+"@babel/helper-validator-option@^7.22.15":
+ version "7.22.15"
+ resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz#694c30dfa1d09a6534cdfcafbe56789d36aba040"
+ integrity sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==
-"@babel/helper-validator-option@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz#de52000a15a177413c8234fa3a8af4ee8102d0ac"
- integrity sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==
+"@babel/helper-wrap-function@^7.22.20":
+ version "7.22.20"
+ resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz#15352b0b9bfb10fc9c76f79f6342c00e3411a569"
+ integrity sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==
+ dependencies:
+ "@babel/helper-function-name" "^7.22.5"
+ "@babel/template" "^7.22.15"
+ "@babel/types" "^7.22.19"
"@babel/helper-wrap-function@^7.22.5":
version "7.22.5"
@@ -708,6 +630,15 @@
chalk "^2.0.0"
js-tokens "^4.0.0"
+"@babel/highlight@^7.22.13":
+ version "7.22.20"
+ resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.20.tgz#4ca92b71d80554b01427815e06f2df965b9c1f54"
+ integrity sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==
+ dependencies:
+ "@babel/helper-validator-identifier" "^7.22.20"
+ chalk "^2.4.2"
+ js-tokens "^4.0.0"
+
"@babel/highlight@^7.22.5":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.5.tgz#aa6c05c5407a67ebce408162b7ede789b4d22031"
@@ -727,7 +658,7 @@
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.5.tgz#7f3c7335fe417665d929f34ae5dceae4c04015e8"
integrity sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==
-"@babel/parser@^7.20.7", "@babel/parser@^7.21.5":
+"@babel/parser@^7.20.7":
version "7.21.5"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.21.5.tgz#821bb520118fd25b982eaf8d37421cf5c64a312b"
integrity sha512-J+IxH2IsxV4HbnTrSWgMAQj0UEo61hDA4Ny8h8PCX0MLXiibqHbqIOVneqdocemSBc22VpBKxt4J6FQzy9HarQ==
@@ -737,26 +668,31 @@
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.21.8.tgz#642af7d0333eab9c0ad70b14ac5e76dbde7bfdf8"
integrity sha512-6zavDGdzG3gUqAdWvlLFfk+36RilI+Pwyuuh7HItyeScCWP3k6i8vKclAQ0bM/0y/Kz/xiwvxhMv9MgTJP5gmA==
+"@babel/parser@^7.22.15", "@babel/parser@^7.23.0":
+ version "7.23.0"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.0.tgz#da950e622420bf96ca0d0f2909cdddac3acd8719"
+ integrity sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==
+
"@babel/parser@^7.22.5":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.5.tgz#721fd042f3ce1896238cf1b341c77eb7dee7dbea"
integrity sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==
-"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.5.tgz#87245a21cd69a73b0b81bcda98d443d6df08f05e"
- integrity sha512-NP1M5Rf+u2Gw9qfSO4ihjcTGW5zXTi36ITLd4/EoAcEhIZ0yjMqmftDNl3QC19CX7olhrjpyU454g/2W7X0jvQ==
+"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.22.15":
+ version "7.22.15"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.15.tgz#02dc8a03f613ed5fdc29fb2f728397c78146c962"
+ integrity sha512-FB9iYlz7rURmRJyXRKEnalYPPdn87H5no108cyuQQyMwlpJ2SJtpIUBI27kdTin956pz+LPypkPVPUTlxOmrsg==
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
-"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.5.tgz#fef09f9499b1f1c930da8a0c419db42167d792ca"
- integrity sha512-31Bb65aZaUwqCbWMnZPduIZxCBngHFlzyN6Dq6KAJjtx+lx6ohKHubc61OomYi7XwVD4Ol0XCVz4h+pYFR048g==
+"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.22.15":
+ version "7.22.15"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.15.tgz#2aeb91d337d4e1a1e7ce85b76a37f5301781200f"
+ integrity sha512-Hyph9LseGvAeeXzikV88bczhsrLrIZqDPxO+sSmAunMPaGrBGhfMWzCPYTtiW9t+HzSE2wtV8e5cc5P6r1xMDQ==
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
"@babel/helper-skip-transparent-expression-wrappers" "^7.22.5"
- "@babel/plugin-transform-optional-chaining" "^7.22.5"
+ "@babel/plugin-transform-optional-chaining" "^7.22.15"
"@babel/plugin-proposal-class-properties@^7.18.6":
version "7.18.6"
@@ -782,14 +718,6 @@
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz#7844f9289546efa9febac2de4cfe358a050bd703"
integrity sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==
-"@babel/plugin-proposal-unicode-property-regex@^7.4.4":
- version "7.16.7"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.7.tgz#635d18eb10c6214210ffc5ff4932552de08188a2"
- integrity sha512-QRK0YI/40VLhNVGIjRNAAQkEHws0cswSdFFjpFyt943YmJIU1da9uW63Iu6NFV6CxTZW5eTDCrwZUstBWgp/Rg==
- dependencies:
- "@babel/helper-create-regexp-features-plugin" "^7.16.7"
- "@babel/helper-plugin-utils" "^7.16.7"
-
"@babel/plugin-syntax-async-generators@^7.8.4":
version "7.8.4"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d"
@@ -959,14 +887,14 @@
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
-"@babel/plugin-transform-async-generator-functions@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.5.tgz#7336356d23380eda9a56314974f053a020dab0c3"
- integrity sha512-gGOEvFzm3fWoyD5uZq7vVTD57pPJ3PczPUD/xCFGjzBpUosnklmXyKnGQbbbGs1NPNPskFex0j93yKbHt0cHyg==
+"@babel/plugin-transform-async-generator-functions@^7.23.2":
+ version "7.23.2"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.2.tgz#054afe290d64c6f576f371ccc321772c8ea87ebb"
+ integrity sha512-BBYVGxbDVHfoeXbOwcagAkOQAm9NxoTdMGfTqghu1GrvadSaw6iW3Je6IcL5PNOw8VwjxqBECXy50/iCQSY/lQ==
dependencies:
- "@babel/helper-environment-visitor" "^7.22.5"
+ "@babel/helper-environment-visitor" "^7.22.20"
"@babel/helper-plugin-utils" "^7.22.5"
- "@babel/helper-remap-async-to-generator" "^7.22.5"
+ "@babel/helper-remap-async-to-generator" "^7.22.20"
"@babel/plugin-syntax-async-generators" "^7.8.4"
"@babel/plugin-transform-async-to-generator@^7.22.5":
@@ -985,10 +913,10 @@
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
-"@babel/plugin-transform-block-scoping@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.5.tgz#8bfc793b3a4b2742c0983fadc1480d843ecea31b"
- integrity sha512-EcACl1i5fSQ6bt+YGuU/XGCeZKStLmyVGytWkpyhCLeQVA0eu6Wtiw92V+I1T/hnezUv7j74dA/Ro69gWcU+hg==
+"@babel/plugin-transform-block-scoping@^7.23.0":
+ version "7.23.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.0.tgz#8744d02c6c264d82e1a4bc5d2d501fd8aff6f022"
+ integrity sha512-cOsrbmIOXmf+5YbL99/S49Y3j46k/T16b9ml8bm9lP6N9US5iQ2yBK7gpui1pg0V/WMcXdkfKbTb7HXq9u+v4g==
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
@@ -1000,28 +928,28 @@
"@babel/helper-create-class-features-plugin" "^7.22.5"
"@babel/helper-plugin-utils" "^7.22.5"
-"@babel/plugin-transform-class-static-block@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.5.tgz#3e40c46f048403472d6f4183116d5e46b1bff5ba"
- integrity sha512-SPToJ5eYZLxlnp1UzdARpOGeC2GbHvr9d/UV0EukuVx8atktg194oe+C5BqQ8jRTkgLRVOPYeXRSBg1IlMoVRA==
+"@babel/plugin-transform-class-static-block@^7.22.11":
+ version "7.22.11"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.11.tgz#dc8cc6e498f55692ac6b4b89e56d87cec766c974"
+ integrity sha512-GMM8gGmqI7guS/llMFk1bJDkKfn3v3C4KHK9Yg1ey5qcHcOlKb0QvcMrgzvxo+T03/4szNh5lghY+fEC98Kq9g==
dependencies:
- "@babel/helper-create-class-features-plugin" "^7.22.5"
+ "@babel/helper-create-class-features-plugin" "^7.22.11"
"@babel/helper-plugin-utils" "^7.22.5"
"@babel/plugin-syntax-class-static-block" "^7.14.5"
-"@babel/plugin-transform-classes@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.5.tgz#635d4e98da741fad814984639f4c0149eb0135e1"
- integrity sha512-2edQhLfibpWpsVBx2n/GKOz6JdGQvLruZQfGr9l1qes2KQaWswjBzhQF7UDUZMNaMMQeYnQzxwOMPsbYF7wqPQ==
+"@babel/plugin-transform-classes@^7.22.15":
+ version "7.22.15"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.15.tgz#aaf4753aee262a232bbc95451b4bdf9599c65a0b"
+ integrity sha512-VbbC3PGjBdE0wAWDdHM9G8Gm977pnYI0XpqMd6LrKISj8/DJXEsWqgRuTYaNE9Bv0JGhTZUzHDlMk18IpOuoqw==
dependencies:
"@babel/helper-annotate-as-pure" "^7.22.5"
- "@babel/helper-compilation-targets" "^7.22.5"
+ "@babel/helper-compilation-targets" "^7.22.15"
"@babel/helper-environment-visitor" "^7.22.5"
"@babel/helper-function-name" "^7.22.5"
"@babel/helper-optimise-call-expression" "^7.22.5"
"@babel/helper-plugin-utils" "^7.22.5"
- "@babel/helper-replace-supers" "^7.22.5"
- "@babel/helper-split-export-declaration" "^7.22.5"
+ "@babel/helper-replace-supers" "^7.22.9"
+ "@babel/helper-split-export-declaration" "^7.22.6"
globals "^11.1.0"
"@babel/plugin-transform-computed-properties@^7.22.5":
@@ -1032,10 +960,10 @@
"@babel/helper-plugin-utils" "^7.22.5"
"@babel/template" "^7.22.5"
-"@babel/plugin-transform-destructuring@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.5.tgz#d3aca7438f6c26c78cdd0b0ba920a336001b27cc"
- integrity sha512-GfqcFuGW8vnEqTUBM7UtPd5A4q797LTvvwKxXTgRsFjoqaJiEg9deBG6kWeQYkVEL569NpnmpC0Pkr/8BLKGnQ==
+"@babel/plugin-transform-destructuring@^7.23.0":
+ version "7.23.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.0.tgz#6447aa686be48b32eaf65a73e0e2c0bd010a266c"
+ integrity sha512-vaMdgNXFkYrB+8lbgniSYWHsgqK5gjaMNcc84bMIOMRLH0L9AqYq3hwMdvnyqj1OPqea8UtjPEuS/DCenah1wg==
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
@@ -1047,14 +975,6 @@
"@babel/helper-create-regexp-features-plugin" "^7.22.5"
"@babel/helper-plugin-utils" "^7.22.5"
-"@babel/plugin-transform-dotall-regex@^7.4.4":
- version "7.16.7"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.7.tgz#6b2d67686fab15fb6a7fd4bd895d5982cfc81241"
- integrity sha512-Lyttaao2SjZF6Pf4vk1dVKv8YypMpomAbygW+mU5cYP3S5cWTfCJjG8xV6CFdzGFlfWK81IjL9viiTvpb6G7gQ==
- dependencies:
- "@babel/helper-create-regexp-features-plugin" "^7.16.7"
- "@babel/helper-plugin-utils" "^7.16.7"
-
"@babel/plugin-transform-duplicate-keys@^7.22.5":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.22.5.tgz#b6e6428d9416f5f0bba19c70d1e6e7e0b88ab285"
@@ -1062,10 +982,10 @@
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
-"@babel/plugin-transform-dynamic-import@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.5.tgz#d6908a8916a810468c4edff73b5b75bda6ad393e"
- integrity sha512-0MC3ppTB1AMxd8fXjSrbPa7LT9hrImt+/fcj+Pg5YMD7UQyWp/02+JWpdnCymmsXwIx5Z+sYn1bwCn4ZJNvhqQ==
+"@babel/plugin-transform-dynamic-import@^7.22.11":
+ version "7.22.11"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.11.tgz#2c7722d2a5c01839eaf31518c6ff96d408e447aa"
+ integrity sha512-g/21plo58sfteWjaO0ZNVb+uEOkJNjAaHhbejrnBmu011l/eNDScmkbjCC3l4FKb10ViaGU4aOkFznSu2zRHgA==
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
"@babel/plugin-syntax-dynamic-import" "^7.8.3"
@@ -1078,18 +998,18 @@
"@babel/helper-builder-binary-assignment-operator-visitor" "^7.22.5"
"@babel/helper-plugin-utils" "^7.22.5"
-"@babel/plugin-transform-export-namespace-from@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.5.tgz#57c41cb1d0613d22f548fddd8b288eedb9973a5b"
- integrity sha512-X4hhm7FRnPgd4nDA4b/5V280xCx6oL7Oob5+9qVS5C13Zq4bh1qq7LU0GgRU6b5dBWBvhGaXYVB4AcN6+ol6vg==
+"@babel/plugin-transform-export-namespace-from@^7.22.11":
+ version "7.22.11"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.11.tgz#b3c84c8f19880b6c7440108f8929caf6056db26c"
+ integrity sha512-xa7aad7q7OiT8oNZ1mU7NrISjlSkVdMbNxn9IuLZyL9AJEhs1Apba3I+u5riX1dIkdptP5EKDG5XDPByWxtehw==
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
"@babel/plugin-syntax-export-namespace-from" "^7.8.3"
-"@babel/plugin-transform-for-of@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.5.tgz#ab1b8a200a8f990137aff9a084f8de4099ab173f"
- integrity sha512-3kxQjX1dU9uudwSshyLeEipvrLjBCVthCgeTp6CzE/9JYrlAIaeekVxRpCWsDDfYTfRZRoCeZatCQvwo+wvK8A==
+"@babel/plugin-transform-for-of@^7.22.15":
+ version "7.22.15"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.15.tgz#f64b4ccc3a4f131a996388fae7680b472b306b29"
+ integrity sha512-me6VGeHsx30+xh9fbDLLPi0J1HzmeIIyenoOQHuw2D4m2SAU3NrspX5XxJLBpqn5yrLzrlw2Iy3RA//Bx27iOA==
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
@@ -1102,10 +1022,10 @@
"@babel/helper-function-name" "^7.22.5"
"@babel/helper-plugin-utils" "^7.22.5"
-"@babel/plugin-transform-json-strings@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.5.tgz#14b64352fdf7e1f737eed68de1a1468bd2a77ec0"
- integrity sha512-DuCRB7fu8MyTLbEQd1ew3R85nx/88yMoqo2uPSjevMj3yoN7CDM8jkgrY0wmVxfJZyJ/B9fE1iq7EQppWQmR5A==
+"@babel/plugin-transform-json-strings@^7.22.11":
+ version "7.22.11"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.11.tgz#689a34e1eed1928a40954e37f74509f48af67835"
+ integrity sha512-CxT5tCqpA9/jXFlme9xIBCc5RPtdDq3JpkkhgHQqtDdiTnTI0jtZ0QzXhr5DILeYifDPp2wvY2ad+7+hLMW5Pw==
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
"@babel/plugin-syntax-json-strings" "^7.8.3"
@@ -1117,10 +1037,10 @@
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
-"@babel/plugin-transform-logical-assignment-operators@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.5.tgz#66ae5f068fd5a9a5dc570df16f56c2a8462a9d6c"
- integrity sha512-MQQOUW1KL8X0cDWfbwYP+TbVbZm16QmQXJQ+vndPtH/BoO0lOKpVoEDMI7+PskYxH+IiE0tS8xZye0qr1lGzSA==
+"@babel/plugin-transform-logical-assignment-operators@^7.22.11":
+ version "7.22.11"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.11.tgz#24c522a61688bde045b7d9bc3c2597a4d948fc9c"
+ integrity sha512-qQwRTP4+6xFCDV5k7gZBF3C31K34ut0tbEcTKxlX/0KXxm9GLcO14p570aWxFvVzx6QAfPgq7gaeIHXJC8LswQ==
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
"@babel/plugin-syntax-logical-assignment-operators" "^7.10.4"
@@ -1132,32 +1052,32 @@
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
-"@babel/plugin-transform-modules-amd@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.22.5.tgz#4e045f55dcf98afd00f85691a68fc0780704f526"
- integrity sha512-R+PTfLTcYEmb1+kK7FNkhQ1gP4KgjpSO6HfH9+f8/yfp2Nt3ggBjiVpRwmwTlfqZLafYKJACy36yDXlEmI9HjQ==
+"@babel/plugin-transform-modules-amd@^7.23.0":
+ version "7.23.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.0.tgz#05b2bc43373faa6d30ca89214731f76f966f3b88"
+ integrity sha512-xWT5gefv2HGSm4QHtgc1sYPbseOyf+FFDo2JbpE25GWl5BqTGO9IMwTYJRoIdjsF85GE+VegHxSCUt5EvoYTAw==
dependencies:
- "@babel/helper-module-transforms" "^7.22.5"
+ "@babel/helper-module-transforms" "^7.23.0"
"@babel/helper-plugin-utils" "^7.22.5"
-"@babel/plugin-transform-modules-commonjs@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.5.tgz#7d9875908d19b8c0536085af7b053fd5bd651bfa"
- integrity sha512-B4pzOXj+ONRmuaQTg05b3y/4DuFz3WcCNAXPLb2Q0GT0TrGKGxNKV4jwsXts+StaM0LQczZbOpj8o1DLPDJIiA==
+"@babel/plugin-transform-modules-commonjs@^7.23.0":
+ version "7.23.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.0.tgz#b3dba4757133b2762c00f4f94590cf6d52602481"
+ integrity sha512-32Xzss14/UVc7k9g775yMIvkVK8xwKE0DPdP5JTapr3+Z9w4tzeOuLNY6BXDQR6BdnzIlXnCGAzsk/ICHBLVWQ==
dependencies:
- "@babel/helper-module-transforms" "^7.22.5"
+ "@babel/helper-module-transforms" "^7.23.0"
"@babel/helper-plugin-utils" "^7.22.5"
"@babel/helper-simple-access" "^7.22.5"
-"@babel/plugin-transform-modules-systemjs@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.5.tgz#18c31410b5e579a0092638f95c896c2a98a5d496"
- integrity sha512-emtEpoaTMsOs6Tzz+nbmcePl6AKVtS1yC4YNAeMun9U8YCsgadPNxnOPQ8GhHFB2qdx+LZu9LgoC0Lthuu05DQ==
+"@babel/plugin-transform-modules-systemjs@^7.23.0":
+ version "7.23.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.0.tgz#77591e126f3ff4132a40595a6cccd00a6b60d160"
+ integrity sha512-qBej6ctXZD2f+DhlOC9yO47yEYgUh5CZNz/aBoH4j/3NOlRfJXJbY7xDQCqQVf9KbrqGzIWER1f23doHGrIHFg==
dependencies:
"@babel/helper-hoist-variables" "^7.22.5"
- "@babel/helper-module-transforms" "^7.22.5"
+ "@babel/helper-module-transforms" "^7.23.0"
"@babel/helper-plugin-utils" "^7.22.5"
- "@babel/helper-validator-identifier" "^7.22.5"
+ "@babel/helper-validator-identifier" "^7.22.20"
"@babel/plugin-transform-modules-umd@^7.22.5":
version "7.22.5"
@@ -1182,32 +1102,32 @@
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
-"@babel/plugin-transform-nullish-coalescing-operator@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.5.tgz#f8872c65776e0b552e0849d7596cddd416c3e381"
- integrity sha512-6CF8g6z1dNYZ/VXok5uYkkBBICHZPiGEl7oDnAx2Mt1hlHVHOSIKWJaXHjQJA5VB43KZnXZDIexMchY4y2PGdA==
+"@babel/plugin-transform-nullish-coalescing-operator@^7.22.11":
+ version "7.22.11"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.11.tgz#debef6c8ba795f5ac67cd861a81b744c5d38d9fc"
+ integrity sha512-YZWOw4HxXrotb5xsjMJUDlLgcDXSfO9eCmdl1bgW4+/lAGdkjaEvOnQ4p5WKKdUgSzO39dgPl0pTnfxm0OAXcg==
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
"@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3"
-"@babel/plugin-transform-numeric-separator@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.5.tgz#57226a2ed9e512b9b446517ab6fa2d17abb83f58"
- integrity sha512-NbslED1/6M+sXiwwtcAB/nieypGw02Ejf4KtDeMkCEpP6gWFMX1wI9WKYua+4oBneCCEmulOkRpwywypVZzs/g==
+"@babel/plugin-transform-numeric-separator@^7.22.11":
+ version "7.22.11"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.11.tgz#498d77dc45a6c6db74bb829c02a01c1d719cbfbd"
+ integrity sha512-3dzU4QGPsILdJbASKhF/V2TVP+gJya1PsueQCxIPCEcerqF21oEcrob4mzjsp2Py/1nLfF5m+xYNMDpmA8vffg==
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
"@babel/plugin-syntax-numeric-separator" "^7.10.4"
-"@babel/plugin-transform-object-rest-spread@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.5.tgz#9686dc3447df4753b0b2a2fae7e8bc33cdc1f2e1"
- integrity sha512-Kk3lyDmEslH9DnvCDA1s1kkd3YWQITiBOHngOtDL9Pt6BZjzqb6hiOlb8VfjiiQJ2unmegBqZu0rx5RxJb5vmQ==
+"@babel/plugin-transform-object-rest-spread@^7.22.15":
+ version "7.22.15"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.15.tgz#21a95db166be59b91cde48775310c0df6e1da56f"
+ integrity sha512-fEB+I1+gAmfAyxZcX1+ZUwLeAuuf8VIg67CTznZE0MqVFumWkh8xWtn58I4dxdVf080wn7gzWoF8vndOViJe9Q==
dependencies:
- "@babel/compat-data" "^7.22.5"
- "@babel/helper-compilation-targets" "^7.22.5"
+ "@babel/compat-data" "^7.22.9"
+ "@babel/helper-compilation-targets" "^7.22.15"
"@babel/helper-plugin-utils" "^7.22.5"
"@babel/plugin-syntax-object-rest-spread" "^7.8.3"
- "@babel/plugin-transform-parameters" "^7.22.5"
+ "@babel/plugin-transform-parameters" "^7.22.15"
"@babel/plugin-transform-object-super@^7.22.5":
version "7.22.5"
@@ -1217,27 +1137,27 @@
"@babel/helper-plugin-utils" "^7.22.5"
"@babel/helper-replace-supers" "^7.22.5"
-"@babel/plugin-transform-optional-catch-binding@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.5.tgz#842080be3076703be0eaf32ead6ac8174edee333"
- integrity sha512-pH8orJahy+hzZje5b8e2QIlBWQvGpelS76C63Z+jhZKsmzfNaPQ+LaW6dcJ9bxTpo1mtXbgHwy765Ro3jftmUg==
+"@babel/plugin-transform-optional-catch-binding@^7.22.11":
+ version "7.22.11"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.11.tgz#461cc4f578a127bb055527b3e77404cad38c08e0"
+ integrity sha512-rli0WxesXUeCJnMYhzAglEjLWVDF6ahb45HuprcmQuLidBJFWjNnOzssk2kuc6e33FlLaiZhG/kUIzUMWdBKaQ==
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
"@babel/plugin-syntax-optional-catch-binding" "^7.8.3"
-"@babel/plugin-transform-optional-chaining@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.5.tgz#1003762b9c14295501beb41be72426736bedd1e0"
- integrity sha512-AconbMKOMkyG+xCng2JogMCDcqW8wedQAqpVIL4cOSescZ7+iW8utC6YDZLMCSUIReEA733gzRSaOSXMAt/4WQ==
+"@babel/plugin-transform-optional-chaining@^7.22.15", "@babel/plugin-transform-optional-chaining@^7.23.0":
+ version "7.23.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.0.tgz#73ff5fc1cf98f542f09f29c0631647d8ad0be158"
+ integrity sha512-sBBGXbLJjxTzLBF5rFWaikMnOGOk/BmK6vVByIdEggZ7Vn6CvWXZyRkkLFK6WE0IF8jSliyOkUN6SScFgzCM0g==
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
"@babel/helper-skip-transparent-expression-wrappers" "^7.22.5"
"@babel/plugin-syntax-optional-chaining" "^7.8.3"
-"@babel/plugin-transform-parameters@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.5.tgz#c3542dd3c39b42c8069936e48717a8d179d63a18"
- integrity sha512-AVkFUBurORBREOmHRKo06FjHYgjrabpdqRSwq6+C7R5iTCZOsM4QbcB27St0a4U6fffyAOqh3s/qEfybAhfivg==
+"@babel/plugin-transform-parameters@^7.22.15":
+ version "7.22.15"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.15.tgz#719ca82a01d177af358df64a514d64c2e3edb114"
+ integrity sha512-hjk7qKIqhyzhhUvRT683TYQOFa/4cQKwQy7ALvTpODswN40MljzNDa0YldevS6tGbxwaEKVn502JmY0dP7qEtQ==
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
@@ -1249,13 +1169,13 @@
"@babel/helper-create-class-features-plugin" "^7.22.5"
"@babel/helper-plugin-utils" "^7.22.5"
-"@babel/plugin-transform-private-property-in-object@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.5.tgz#07a77f28cbb251546a43d175a1dda4cf3ef83e32"
- integrity sha512-/9xnaTTJcVoBtSSmrVyhtSvO3kbqS2ODoh2juEU72c3aYonNF0OMGiaz2gjukyKM2wBBYJP38S4JiE0Wfb5VMQ==
+"@babel/plugin-transform-private-property-in-object@^7.22.11":
+ version "7.22.11"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.11.tgz#ad45c4fc440e9cb84c718ed0906d96cf40f9a4e1"
+ integrity sha512-sSCbqZDBKHetvjSwpyWzhuHkmW5RummxJBVbYLkGkaiTOWGxml7SXt0iWa03bzxFIx7wOj3g/ILRd0RcJKBeSQ==
dependencies:
"@babel/helper-annotate-as-pure" "^7.22.5"
- "@babel/helper-create-class-features-plugin" "^7.22.5"
+ "@babel/helper-create-class-features-plugin" "^7.22.11"
"@babel/helper-plugin-utils" "^7.22.5"
"@babel/plugin-syntax-private-property-in-object" "^7.14.5"
@@ -1280,16 +1200,16 @@
dependencies:
"@babel/plugin-transform-react-jsx" "^7.22.5"
-"@babel/plugin-transform-react-jsx@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.22.5.tgz#932c291eb6dd1153359e2a90cb5e557dcf068416"
- integrity sha512-rog5gZaVbUip5iWDMTYbVM15XQq+RkUKhET/IHR6oizR+JEoN6CAfTTuHcK4vwUyzca30qqHqEpzBOnaRMWYMA==
+"@babel/plugin-transform-react-jsx@^7.22.15", "@babel/plugin-transform-react-jsx@^7.22.5":
+ version "7.22.15"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.22.15.tgz#7e6266d88705d7c49f11c98db8b9464531289cd6"
+ integrity sha512-oKckg2eZFa8771O/5vi7XeTvmM6+O9cxZu+kanTU7tD4sin5nO/G8jGJhq8Hvt2Z0kUoEDRayuZLaUlYl8QuGA==
dependencies:
"@babel/helper-annotate-as-pure" "^7.22.5"
- "@babel/helper-module-imports" "^7.22.5"
+ "@babel/helper-module-imports" "^7.22.15"
"@babel/helper-plugin-utils" "^7.22.5"
"@babel/plugin-syntax-jsx" "^7.22.5"
- "@babel/types" "^7.22.5"
+ "@babel/types" "^7.22.15"
"@babel/plugin-transform-react-pure-annotations@^7.22.5":
version "7.22.5"
@@ -1299,13 +1219,13 @@
"@babel/helper-annotate-as-pure" "^7.22.5"
"@babel/helper-plugin-utils" "^7.22.5"
-"@babel/plugin-transform-regenerator@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.5.tgz#cd8a68b228a5f75fa01420e8cc2fc400f0fc32aa"
- integrity sha512-rR7KePOE7gfEtNTh9Qw+iO3Q/e4DEsoQ+hdvM6QUDH7JRJ5qxq5AA52ZzBWbI5i9lfNuvySgOGP8ZN7LAmaiPw==
+"@babel/plugin-transform-regenerator@^7.22.10":
+ version "7.22.10"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.10.tgz#8ceef3bd7375c4db7652878b0241b2be5d0c3cca"
+ integrity sha512-F28b1mDt8KcT5bUyJc/U9nwzw6cV+UmTeRlXYIl2TNqMMJif0Jeey9/RQ3C4NOd2zp0/TRsDns9ttj2L523rsw==
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
- regenerator-transform "^0.15.1"
+ regenerator-transform "^0.15.2"
"@babel/plugin-transform-reserved-words@^7.22.5":
version "7.22.5"
@@ -1369,10 +1289,10 @@
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
-"@babel/plugin-transform-unicode-escapes@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.5.tgz#ce0c248522b1cb22c7c992d88301a5ead70e806c"
- integrity sha512-biEmVg1IYB/raUO5wT1tgfacCef15Fbzhkx493D3urBI++6hpJ+RFG4SrWMn0NEZLfvilqKf3QDrRVZHo08FYg==
+"@babel/plugin-transform-unicode-escapes@^7.22.10":
+ version "7.22.10"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.10.tgz#c723f380f40a2b2f57a62df24c9005834c8616d9"
+ integrity sha512-lRfaRKGZCBqDlRU3UIFovdp9c9mEvlylmpod0/OatICsSfuQ9YFthRo1tpTkGsklEefZdqlEFdY4A2dwTb6ohg==
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
@@ -1408,17 +1328,17 @@
core-js "^2.6.5"
regenerator-runtime "^0.13.4"
-"@babel/preset-env@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.22.5.tgz#3da66078b181f3d62512c51cf7014392c511504e"
- integrity sha512-fj06hw89dpiZzGZtxn+QybifF07nNiZjZ7sazs2aVDcysAZVGjW7+7iFYxg6GLNM47R/thYfLdrXc+2f11Vi9A==
+"@babel/preset-env@^7.23.2":
+ version "7.23.2"
+ resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.23.2.tgz#1f22be0ff0e121113260337dbc3e58fafce8d059"
+ integrity sha512-BW3gsuDD+rvHL2VO2SjAUNTBe5YrjsTiDyqamPDWY723na3/yPQ65X5oQkFVJZ0o50/2d+svm1rkPoJeR1KxVQ==
dependencies:
- "@babel/compat-data" "^7.22.5"
- "@babel/helper-compilation-targets" "^7.22.5"
+ "@babel/compat-data" "^7.23.2"
+ "@babel/helper-compilation-targets" "^7.22.15"
"@babel/helper-plugin-utils" "^7.22.5"
- "@babel/helper-validator-option" "^7.22.5"
- "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.22.5"
- "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.22.5"
+ "@babel/helper-validator-option" "^7.22.15"
+ "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.22.15"
+ "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.22.15"
"@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2"
"@babel/plugin-syntax-async-generators" "^7.8.4"
"@babel/plugin-syntax-class-properties" "^7.12.13"
@@ -1439,88 +1359,86 @@
"@babel/plugin-syntax-top-level-await" "^7.14.5"
"@babel/plugin-syntax-unicode-sets-regex" "^7.18.6"
"@babel/plugin-transform-arrow-functions" "^7.22.5"
- "@babel/plugin-transform-async-generator-functions" "^7.22.5"
+ "@babel/plugin-transform-async-generator-functions" "^7.23.2"
"@babel/plugin-transform-async-to-generator" "^7.22.5"
"@babel/plugin-transform-block-scoped-functions" "^7.22.5"
- "@babel/plugin-transform-block-scoping" "^7.22.5"
+ "@babel/plugin-transform-block-scoping" "^7.23.0"
"@babel/plugin-transform-class-properties" "^7.22.5"
- "@babel/plugin-transform-class-static-block" "^7.22.5"
- "@babel/plugin-transform-classes" "^7.22.5"
+ "@babel/plugin-transform-class-static-block" "^7.22.11"
+ "@babel/plugin-transform-classes" "^7.22.15"
"@babel/plugin-transform-computed-properties" "^7.22.5"
- "@babel/plugin-transform-destructuring" "^7.22.5"
+ "@babel/plugin-transform-destructuring" "^7.23.0"
"@babel/plugin-transform-dotall-regex" "^7.22.5"
"@babel/plugin-transform-duplicate-keys" "^7.22.5"
- "@babel/plugin-transform-dynamic-import" "^7.22.5"
+ "@babel/plugin-transform-dynamic-import" "^7.22.11"
"@babel/plugin-transform-exponentiation-operator" "^7.22.5"
- "@babel/plugin-transform-export-namespace-from" "^7.22.5"
- "@babel/plugin-transform-for-of" "^7.22.5"
+ "@babel/plugin-transform-export-namespace-from" "^7.22.11"
+ "@babel/plugin-transform-for-of" "^7.22.15"
"@babel/plugin-transform-function-name" "^7.22.5"
- "@babel/plugin-transform-json-strings" "^7.22.5"
+ "@babel/plugin-transform-json-strings" "^7.22.11"
"@babel/plugin-transform-literals" "^7.22.5"
- "@babel/plugin-transform-logical-assignment-operators" "^7.22.5"
+ "@babel/plugin-transform-logical-assignment-operators" "^7.22.11"
"@babel/plugin-transform-member-expression-literals" "^7.22.5"
- "@babel/plugin-transform-modules-amd" "^7.22.5"
- "@babel/plugin-transform-modules-commonjs" "^7.22.5"
- "@babel/plugin-transform-modules-systemjs" "^7.22.5"
+ "@babel/plugin-transform-modules-amd" "^7.23.0"
+ "@babel/plugin-transform-modules-commonjs" "^7.23.0"
+ "@babel/plugin-transform-modules-systemjs" "^7.23.0"
"@babel/plugin-transform-modules-umd" "^7.22.5"
"@babel/plugin-transform-named-capturing-groups-regex" "^7.22.5"
"@babel/plugin-transform-new-target" "^7.22.5"
- "@babel/plugin-transform-nullish-coalescing-operator" "^7.22.5"
- "@babel/plugin-transform-numeric-separator" "^7.22.5"
- "@babel/plugin-transform-object-rest-spread" "^7.22.5"
+ "@babel/plugin-transform-nullish-coalescing-operator" "^7.22.11"
+ "@babel/plugin-transform-numeric-separator" "^7.22.11"
+ "@babel/plugin-transform-object-rest-spread" "^7.22.15"
"@babel/plugin-transform-object-super" "^7.22.5"
- "@babel/plugin-transform-optional-catch-binding" "^7.22.5"
- "@babel/plugin-transform-optional-chaining" "^7.22.5"
- "@babel/plugin-transform-parameters" "^7.22.5"
+ "@babel/plugin-transform-optional-catch-binding" "^7.22.11"
+ "@babel/plugin-transform-optional-chaining" "^7.23.0"
+ "@babel/plugin-transform-parameters" "^7.22.15"
"@babel/plugin-transform-private-methods" "^7.22.5"
- "@babel/plugin-transform-private-property-in-object" "^7.22.5"
+ "@babel/plugin-transform-private-property-in-object" "^7.22.11"
"@babel/plugin-transform-property-literals" "^7.22.5"
- "@babel/plugin-transform-regenerator" "^7.22.5"
+ "@babel/plugin-transform-regenerator" "^7.22.10"
"@babel/plugin-transform-reserved-words" "^7.22.5"
"@babel/plugin-transform-shorthand-properties" "^7.22.5"
"@babel/plugin-transform-spread" "^7.22.5"
"@babel/plugin-transform-sticky-regex" "^7.22.5"
"@babel/plugin-transform-template-literals" "^7.22.5"
"@babel/plugin-transform-typeof-symbol" "^7.22.5"
- "@babel/plugin-transform-unicode-escapes" "^7.22.5"
+ "@babel/plugin-transform-unicode-escapes" "^7.22.10"
"@babel/plugin-transform-unicode-property-regex" "^7.22.5"
"@babel/plugin-transform-unicode-regex" "^7.22.5"
"@babel/plugin-transform-unicode-sets-regex" "^7.22.5"
- "@babel/preset-modules" "^0.1.5"
- "@babel/types" "^7.22.5"
- babel-plugin-polyfill-corejs2 "^0.4.3"
- babel-plugin-polyfill-corejs3 "^0.8.1"
- babel-plugin-polyfill-regenerator "^0.5.0"
- core-js-compat "^3.30.2"
- semver "^6.3.0"
+ "@babel/preset-modules" "0.1.6-no-external-plugins"
+ "@babel/types" "^7.23.0"
+ babel-plugin-polyfill-corejs2 "^0.4.6"
+ babel-plugin-polyfill-corejs3 "^0.8.5"
+ babel-plugin-polyfill-regenerator "^0.5.3"
+ core-js-compat "^3.31.0"
+ semver "^6.3.1"
-"@babel/preset-modules@^0.1.5":
- version "0.1.5"
- resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.5.tgz#ef939d6e7f268827e1841638dc6ff95515e115d9"
- integrity sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==
+"@babel/preset-modules@0.1.6-no-external-plugins":
+ version "0.1.6-no-external-plugins"
+ resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz#ccb88a2c49c817236861fee7826080573b8a923a"
+ integrity sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==
dependencies:
"@babel/helper-plugin-utils" "^7.0.0"
- "@babel/plugin-proposal-unicode-property-regex" "^7.4.4"
- "@babel/plugin-transform-dotall-regex" "^7.4.4"
"@babel/types" "^7.4.4"
esutils "^2.0.2"
-"@babel/preset-react@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.22.5.tgz#c4d6058fbf80bccad02dd8c313a9aaa67e3c3dd6"
- integrity sha512-M+Is3WikOpEJHgR385HbuCITPTaPRaNkibTEa9oiofmJvIsrceb4yp9RL9Kb+TE8LznmeyZqpP+Lopwcx59xPQ==
+"@babel/preset-react@^7.22.15":
+ version "7.22.15"
+ resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.22.15.tgz#9a776892b648e13cc8ca2edf5ed1264eea6b6afc"
+ integrity sha512-Csy1IJ2uEh/PecCBXXoZGAZBeCATTuePzCSB7dLYWS0vOEj6CNpjxIhW4duWwZodBNueH7QO14WbGn8YyeuN9w==
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
- "@babel/helper-validator-option" "^7.22.5"
+ "@babel/helper-validator-option" "^7.22.15"
"@babel/plugin-transform-react-display-name" "^7.22.5"
- "@babel/plugin-transform-react-jsx" "^7.22.5"
+ "@babel/plugin-transform-react-jsx" "^7.22.15"
"@babel/plugin-transform-react-jsx-development" "^7.22.5"
"@babel/plugin-transform-react-pure-annotations" "^7.22.5"
-"@babel/register@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.22.5.tgz#e4d8d0f615ea3233a27b5c6ada6750ee59559939"
- integrity sha512-vV6pm/4CijSQ8Y47RH5SopXzursN35RQINfGJkmOlcpAtGuf94miFvIPhCKGQN7WGIcsgG1BHEX2KVdTYwTwUQ==
+"@babel/register@^7.22.15":
+ version "7.22.15"
+ resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.22.15.tgz#c2c294a361d59f5fa7bcc8b97ef7319c32ecaec7"
+ integrity sha512-V3Q3EqoQdn65RCgTLwauZaTfd1ShhwPmbBv+1dkZV/HpCGMKVyn6oFcRlI7RaKqiDQjX2Qd3AuoEguBgdjIKlg==
dependencies:
clone-deep "^4.0.1"
find-cache-dir "^2.0.0"
@@ -1533,13 +1451,13 @@
resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310"
integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==
-"@babel/runtime-corejs2@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/runtime-corejs2/-/runtime-corejs2-7.22.5.tgz#2d71228a9287e6fe07ce2e8743699ab79e549ac0"
- integrity sha512-GdiGeK5z8VKeJhqSQBgZr3xCMjAdborh5Ppn/0jQ0gtzw11UiZZAwDFZi0ZKvZ76ULooLqJn/OlrfcGZv7Pmzg==
+"@babel/runtime-corejs2@^7.23.5":
+ version "7.23.5"
+ resolved "https://registry.yarnpkg.com/@babel/runtime-corejs2/-/runtime-corejs2-7.23.5.tgz#b828c9e412d2ae0d08f3fc0406befb645b97e97d"
+ integrity sha512-htng2Ks50HN2/hvRU2P6cIzPods3CXaDt0Rf0bhsJc+hD3gaVPreL/UA24jcjqrVRUgu14KucMiCLu6hMjjryQ==
dependencies:
core-js "^2.6.12"
- regenerator-runtime "^0.13.11"
+ regenerator-runtime "^0.14.0"
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.6", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.3", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
version "7.22.5"
@@ -1580,6 +1498,15 @@
"@babel/parser" "^7.20.7"
"@babel/types" "^7.20.7"
+"@babel/template@^7.22.15":
+ version "7.22.15"
+ resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38"
+ integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==
+ dependencies:
+ "@babel/code-frame" "^7.22.13"
+ "@babel/parser" "^7.22.15"
+ "@babel/types" "^7.22.15"
+
"@babel/template@^7.22.5":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.5.tgz#0c8c4d944509875849bd0344ff0050756eefc6ec"
@@ -1589,114 +1516,23 @@
"@babel/parser" "^7.22.5"
"@babel/types" "^7.22.5"
-"@babel/traverse@^7.18.0", "@babel/traverse@^7.7.0", "@babel/traverse@^7.9.0":
- version "7.18.0"
- resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.18.0.tgz#0e5ec6db098660b2372dd63d096bf484e32d27ba"
- integrity sha512-oNOO4vaoIQoGjDQ84LgtF/IAlxlyqL4TUuoQ7xLkQETFaHkY1F7yazhB4Kt3VcZGL0ZF/jhrEpnXqUb0M7V3sw==
- dependencies:
- "@babel/code-frame" "^7.16.7"
- "@babel/generator" "^7.18.0"
- "@babel/helper-environment-visitor" "^7.16.7"
- "@babel/helper-function-name" "^7.17.9"
- "@babel/helper-hoist-variables" "^7.16.7"
- "@babel/helper-split-export-declaration" "^7.16.7"
- "@babel/parser" "^7.18.0"
- "@babel/types" "^7.18.0"
- debug "^4.1.0"
- globals "^11.1.0"
-
-"@babel/traverse@^7.20.1", "@babel/traverse@^7.20.5":
- version "7.20.5"
- resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.5.tgz#78eb244bea8270fdda1ef9af22a5d5e5b7e57133"
- integrity sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==
- dependencies:
- "@babel/code-frame" "^7.18.6"
- "@babel/generator" "^7.20.5"
- "@babel/helper-environment-visitor" "^7.18.9"
- "@babel/helper-function-name" "^7.19.0"
- "@babel/helper-hoist-variables" "^7.18.6"
- "@babel/helper-split-export-declaration" "^7.18.6"
- "@babel/parser" "^7.20.5"
- "@babel/types" "^7.20.5"
- debug "^4.1.0"
- globals "^11.1.0"
-
-"@babel/traverse@^7.21.5":
- version "7.21.5"
- resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.21.5.tgz#ad22361d352a5154b498299d523cf72998a4b133"
- integrity sha512-AhQoI3YjWi6u/y/ntv7k48mcrCXmus0t79J9qPNlk/lAsFlCiJ047RmbfMOawySTHtywXhbXgpx/8nXMYd+oFw==
+"@babel/traverse@^7.18.0", "@babel/traverse@^7.20.1", "@babel/traverse@^7.20.5", "@babel/traverse@^7.21.5", "@babel/traverse@^7.22.5", "@babel/traverse@^7.7.0", "@babel/traverse@^7.9.0":
+ version "7.23.2"
+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.2.tgz#329c7a06735e144a506bdb2cad0268b7f46f4ad8"
+ integrity sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==
dependencies:
- "@babel/code-frame" "^7.21.4"
- "@babel/generator" "^7.21.5"
- "@babel/helper-environment-visitor" "^7.21.5"
- "@babel/helper-function-name" "^7.21.0"
- "@babel/helper-hoist-variables" "^7.18.6"
- "@babel/helper-split-export-declaration" "^7.18.6"
- "@babel/parser" "^7.21.5"
- "@babel/types" "^7.21.5"
- debug "^4.1.0"
- globals "^11.1.0"
-
-"@babel/traverse@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.5.tgz#44bd276690db6f4940fdb84e1cb4abd2f729ccd1"
- integrity sha512-7DuIjPgERaNo6r+PZwItpjCZEa5vyw4eJGufeLxrPdBXBoLcCJCIasvK6pK/9DVNrLZTLFhUGqaC6X/PA007TQ==
- dependencies:
- "@babel/code-frame" "^7.22.5"
- "@babel/generator" "^7.22.5"
- "@babel/helper-environment-visitor" "^7.22.5"
- "@babel/helper-function-name" "^7.22.5"
+ "@babel/code-frame" "^7.22.13"
+ "@babel/generator" "^7.23.0"
+ "@babel/helper-environment-visitor" "^7.22.20"
+ "@babel/helper-function-name" "^7.23.0"
"@babel/helper-hoist-variables" "^7.22.5"
- "@babel/helper-split-export-declaration" "^7.22.5"
- "@babel/parser" "^7.22.5"
- "@babel/types" "^7.22.5"
+ "@babel/helper-split-export-declaration" "^7.22.6"
+ "@babel/parser" "^7.23.0"
+ "@babel/types" "^7.23.0"
debug "^4.1.0"
globals "^11.1.0"
-"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.16.7", "@babel/types@^7.17.0", "@babel/types@^7.18.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0", "@babel/types@^7.9.0":
- version "7.18.0"
- resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.0.tgz#ef523ea349722849cb4bf806e9342ede4d071553"
- integrity sha512-vhAmLPAiC8j9K2GnsnLPCIH5wCrPpYIVBCWRBFDCB7Y/BXLqi/O+1RSTTM2bsmg6U/551+FCf9PNPxjABmxHTw==
- dependencies:
- "@babel/helper-validator-identifier" "^7.16.7"
- to-fast-properties "^2.0.0"
-
-"@babel/types@^7.18.10", "@babel/types@^7.19.0", "@babel/types@^7.20.2", "@babel/types@^7.20.5":
- version "7.20.5"
- resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.20.5.tgz#e206ae370b5393d94dfd1d04cd687cace53efa84"
- integrity sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==
- dependencies:
- "@babel/helper-string-parser" "^7.19.4"
- "@babel/helper-validator-identifier" "^7.19.1"
- to-fast-properties "^2.0.0"
-
-"@babel/types@^7.18.6":
- version "7.18.7"
- resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.7.tgz#a4a2c910c15040ea52cdd1ddb1614a65c8041726"
- integrity sha512-QG3yxTcTIBoAcQmkCs+wAPYZhu7Dk9rXKacINfNbdJDNERTbLQbHGyVG8q/YGMPeCJRIhSY0+fTc5+xuh6WPSQ==
- dependencies:
- "@babel/helper-validator-identifier" "^7.18.6"
- to-fast-properties "^2.0.0"
-
-"@babel/types@^7.20.7", "@babel/types@^7.21.0", "@babel/types@^7.21.5":
- version "7.21.5"
- resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.21.5.tgz#18dfbd47c39d3904d5db3d3dc2cc80bedb60e5b6"
- integrity sha512-m4AfNvVF2mVC/F7fDEdH2El3HzUg9It/XsCxZiOTTA3m3qYfcSVSbTfM6Q9xG+hYDniZssYhlXKKUMD5m8tF4Q==
- dependencies:
- "@babel/helper-string-parser" "^7.21.5"
- "@babel/helper-validator-identifier" "^7.19.1"
- to-fast-properties "^2.0.0"
-
-"@babel/types@^7.22.5":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.5.tgz#cd93eeaab025880a3a47ec881f4b096a5b786fbe"
- integrity sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==
- dependencies:
- "@babel/helper-string-parser" "^7.22.5"
- "@babel/helper-validator-identifier" "^7.22.5"
- to-fast-properties "^2.0.0"
-
-"@babel/types@^7.23.0":
+"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.16.7", "@babel/types@^7.17.0", "@babel/types@^7.18.0", "@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.20.2", "@babel/types@^7.20.5", "@babel/types@^7.20.7", "@babel/types@^7.21.5", "@babel/types@^7.22.15", "@babel/types@^7.22.19", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0", "@babel/types@^7.9.0":
version "7.23.0"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.0.tgz#8c1f020c9df0e737e4e247c0619f58c68458aaeb"
integrity sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==
@@ -2152,6 +1988,22 @@
"@formatjs/intl-localematcher" "0.4.1"
tslib "^2.4.0"
+"@formatjs/ecma402-abstract@1.17.2":
+ version "1.17.2"
+ resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.17.2.tgz#d197c6e26b9fd96ff7ba3b3a0cc2f25f1f2dcac3"
+ integrity sha512-k2mTh0m+IV1HRdU0xXM617tSQTi53tVR2muvYOsBeYcUgEAyxV1FOC7Qj279th3fBVQ+Dj6muvNJZcHSPNdbKg==
+ dependencies:
+ "@formatjs/intl-localematcher" "0.4.2"
+ tslib "^2.4.0"
+
+"@formatjs/ecma402-abstract@1.18.0":
+ version "1.18.0"
+ resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.18.0.tgz#e2120e7101020140661b58430a7ff4262705a2f2"
+ integrity sha512-PEVLoa3zBevWSCZzPIM/lvPCi8P5l4G+NXQMc/CjEiaCWgyHieUoo0nM7Bs0n/NbuQ6JpXEolivQ9pKSBHaDlA==
+ dependencies:
+ "@formatjs/intl-localematcher" "0.5.2"
+ tslib "^2.4.0"
+
"@formatjs/fast-memoize@2.2.0":
version "2.2.0"
resolved "https://registry.yarnpkg.com/@formatjs/fast-memoize/-/fast-memoize-2.2.0.tgz#33bd616d2e486c3e8ef4e68c99648c196887802b"
@@ -2208,7 +2060,7 @@
dependencies:
tslib "^2.4.0"
-"@formatjs/intl-listformat@7.4.1", "@formatjs/intl-listformat@^7.4.0":
+"@formatjs/intl-listformat@7.4.1":
version "7.4.1"
resolved "https://registry.yarnpkg.com/@formatjs/intl-listformat/-/intl-listformat-7.4.1.tgz#cb6f1399a41b9fd568cc4b4b80fc815d0c5b37ab"
integrity sha512-mWd30ndvYw8JydOIVb5Y1ElK2iwsaDY+ajPR5aWWgEZaH04aL+4hzX/8VXPsilu7CF3DN1IP5ZSwJuj7ZyBIHw==
@@ -2217,6 +2069,15 @@
"@formatjs/intl-localematcher" "0.4.1"
tslib "^2.4.0"
+"@formatjs/intl-listformat@^7.5.3":
+ version "7.5.3"
+ resolved "https://registry.yarnpkg.com/@formatjs/intl-listformat/-/intl-listformat-7.5.3.tgz#c6f028471839cd1014760498f783fdfe011422d5"
+ integrity sha512-l7EOr0Yh1m8KagytukB90yw81uyzrM7amKFrgxXqphz4KeSIL0KPa68lPsdtZ+JmQB73GaDQRwLOwUKFZ1VZPQ==
+ dependencies:
+ "@formatjs/ecma402-abstract" "1.18.0"
+ "@formatjs/intl-localematcher" "0.5.2"
+ tslib "^2.4.0"
+
"@formatjs/intl-locale@^3.3.2":
version "3.3.2"
resolved "https://registry.yarnpkg.com/@formatjs/intl-locale/-/intl-locale-3.3.2.tgz#0a5aaafdabec1c5180064dee8e9cb8f0e7097d2d"
@@ -2241,6 +2102,20 @@
dependencies:
tslib "^2.4.0"
+"@formatjs/intl-localematcher@0.4.2":
+ version "0.4.2"
+ resolved "https://registry.yarnpkg.com/@formatjs/intl-localematcher/-/intl-localematcher-0.4.2.tgz#7e6e596dbaf2f0c5a7c22da5a01d5c55f4c37e9a"
+ integrity sha512-BGdtJFmaNJy5An/Zan4OId/yR9Ih1OojFjcduX/xOvq798OgWSyDtd6Qd5jqJXwJs1ipe4Fxu9+cshic5Ox2tA==
+ dependencies:
+ tslib "^2.4.0"
+
+"@formatjs/intl-localematcher@0.5.2":
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/@formatjs/intl-localematcher/-/intl-localematcher-0.5.2.tgz#5fcf029fd218905575e5080fa33facdcb623d532"
+ integrity sha512-txaaE2fiBMagLrR4jYhxzFO6wEdEG4TPMqrzBAcbr4HFUYzH/YC+lg6OIzKCHm8WgDdyQevxbAAV1OgcXctuGw==
+ dependencies:
+ tslib "^2.4.0"
+
"@formatjs/intl-numberformat@^8.7.0":
version "8.7.0"
resolved "https://registry.yarnpkg.com/@formatjs/intl-numberformat/-/intl-numberformat-8.7.0.tgz#981bf87c13a08fcf72616f024805c6ecf6f54fd2"
@@ -2250,13 +2125,13 @@
"@formatjs/intl-localematcher" "0.4.0"
tslib "^2.4.0"
-"@formatjs/intl-pluralrules@^5.2.4":
- version "5.2.4"
- resolved "https://registry.yarnpkg.com/@formatjs/intl-pluralrules/-/intl-pluralrules-5.2.4.tgz#b417aa503186c2cbb4715f47114ed65211b4ada9"
- integrity sha512-6meo376d8I4zikRFSUxATLnqzGwezmc57SmToP4z1/NQwTHXGe0yIG/ABPbO3QMx7IUkofH/ROP3A4DhtPTpnA==
+"@formatjs/intl-pluralrules@^5.2.7":
+ version "5.2.7"
+ resolved "https://registry.yarnpkg.com/@formatjs/intl-pluralrules/-/intl-pluralrules-5.2.7.tgz#f13ad9760f859ca67d2faddcac0d76a5b8b955f6"
+ integrity sha512-KmLGzj8VUOhMjlFP0uEOfEgH9xkRAhDNBVmsVGZnE2EIsbpVG0GDG6DHuqnyC0KYXy7UfU/XuE0H1Bo+Mr35DQ==
dependencies:
- "@formatjs/ecma402-abstract" "1.17.0"
- "@formatjs/intl-localematcher" "0.4.0"
+ "@formatjs/ecma402-abstract" "1.17.2"
+ "@formatjs/intl-localematcher" "0.4.2"
tslib "^2.4.0"
"@formatjs/intl-relativetimeformat@^11.2.4":
@@ -2689,36 +2564,33 @@
resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.7.1.tgz#fea7ac35ae4014637c130011f59428f618730498"
integrity sha512-bgVQM4ZJ2u2CM8k1ey70o1ePFXsEzYVZoWghh6WjM8p59jQ7HxzbHW4SbnWFG7V9ig9chLawQxDTZ3xzOF8MkQ==
-"@sentry-internal/tracing@7.57.0":
- version "7.57.0"
- resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.57.0.tgz#cb761931b635f8f24c84be0eecfacb8516b20551"
- integrity sha512-tpViyDd8AhQGYYhI94xi2aaDopXOPfL2Apwrtb3qirWkomIQ2K86W1mPmkce+B0cFOnW2Dxv/ZTFKz6ghjK75A==
+"@sentry-internal/tracing@7.77.0":
+ version "7.77.0"
+ resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.77.0.tgz#f3d82486f8934a955b3dd2aa54c8d29586e42a37"
+ integrity sha512-8HRF1rdqWwtINqGEdx8Iqs9UOP/n8E0vXUu3Nmbqj4p5sQPA7vvCfq+4Y4rTqZFc7sNdFpDsRION5iQEh8zfZw==
dependencies:
- "@sentry/core" "7.57.0"
- "@sentry/types" "7.57.0"
- "@sentry/utils" "7.57.0"
- tslib "^2.4.1 || ^1.9.3"
+ "@sentry/core" "7.77.0"
+ "@sentry/types" "7.77.0"
+ "@sentry/utils" "7.77.0"
-"@sentry/browser@^7.57.0":
- version "7.57.0"
- resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.57.0.tgz#6e724c9eac680dba99ced0fdf81be8d1e3b3bceb"
- integrity sha512-E0HaYYlaqHFiIRZXxcvOO8Odvlt+TR1vFFXzqUWXPOvDRxURglTOCQ3EN/u6bxtAGJ6y/Zc2obgihTtypuel/w==
+"@sentry/browser@^7.77.0":
+ version "7.77.0"
+ resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.77.0.tgz#155440f1a0d3a1bbd5d564c28d6b0c9853a51d72"
+ integrity sha512-nJ2KDZD90H8jcPx9BysQLiQW+w7k7kISCWeRjrEMJzjtge32dmHA8G4stlUTRIQugy5F+73cOayWShceFP7QJQ==
dependencies:
- "@sentry-internal/tracing" "7.57.0"
- "@sentry/core" "7.57.0"
- "@sentry/replay" "7.57.0"
- "@sentry/types" "7.57.0"
- "@sentry/utils" "7.57.0"
- tslib "^2.4.1 || ^1.9.3"
+ "@sentry-internal/tracing" "7.77.0"
+ "@sentry/core" "7.77.0"
+ "@sentry/replay" "7.77.0"
+ "@sentry/types" "7.77.0"
+ "@sentry/utils" "7.77.0"
-"@sentry/core@7.57.0":
- version "7.57.0"
- resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.57.0.tgz#65093d739c04f320a54395a21be955fcbe326acb"
- integrity sha512-l014NudPH0vQlzybtXajPxYFfs9w762NoarjObC3gu76D1jzBBFzhdRelkGpDbSLNTIsKhEDDRpgAjBWJ9icfw==
+"@sentry/core@7.77.0":
+ version "7.77.0"
+ resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.77.0.tgz#21100843132beeeff42296c8370cdcc7aa1d8510"
+ integrity sha512-Tj8oTYFZ/ZD+xW8IGIsU6gcFXD/gfE+FUxUaeSosd9KHwBQNOLhZSsYo/tTVf/rnQI/dQnsd4onPZLiL+27aTg==
dependencies:
- "@sentry/types" "7.57.0"
- "@sentry/utils" "7.57.0"
- tslib "^2.4.1 || ^1.9.3"
+ "@sentry/types" "7.77.0"
+ "@sentry/utils" "7.77.0"
"@sentry/integrations@^7.61.0":
version "7.61.0"
@@ -2730,32 +2602,25 @@
localforage "^1.8.1"
tslib "^2.4.1 || ^1.9.3"
-"@sentry/replay@7.57.0":
- version "7.57.0"
- resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-7.57.0.tgz#c8f7eae7b7edc9d32c3d2955b337f3b3c76dff39"
- integrity sha512-pN4ryNS3J5EYbkXvR+O/+hseAJha7XDl8mPFtK0OGTHG10JzCi4tQJazblHQdpb5QBaMMPCeZ+isyfoQLDNXnw==
+"@sentry/replay@7.77.0":
+ version "7.77.0"
+ resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-7.77.0.tgz#21d242c9cd70a7235237216174873fd140b6eb80"
+ integrity sha512-M9Ik2J5ekl+C1Och3wzLRZVaRGK33BlnBwfwf3qKjgLDwfKW+1YkwDfTHbc2b74RowkJbOVNcp4m8ptlehlSaQ==
dependencies:
- "@sentry/core" "7.57.0"
- "@sentry/types" "7.57.0"
- "@sentry/utils" "7.57.0"
-
-"@sentry/types@7.57.0":
- version "7.57.0"
- resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.57.0.tgz#4fdb80cbd49ba034dd8d9be0c0005a016d5db3ce"
- integrity sha512-D7ifoUfxuVCUyktIr5Gc+jXUbtcUMmfHdTtTbf1XCZHua5mJceK9wtl3YCg3eq/HK2Ppd52BKnTzEcS5ZKQM+w==
+ "@sentry-internal/tracing" "7.77.0"
+ "@sentry/core" "7.77.0"
+ "@sentry/types" "7.77.0"
+ "@sentry/utils" "7.77.0"
"@sentry/types@7.61.0":
version "7.61.0"
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.61.0.tgz#4243b5ef4658f6b0673bc4372c90e6ec920f78d8"
integrity sha512-/GLlIBNR35NKPE/SfWi9W10dK9hE8qTShzsuPVn5wAJxpT3Lb4+dkwmKCTLUYxdkmvRDEudkfOxgalsfQGTAWA==
-"@sentry/utils@7.57.0":
- version "7.57.0"
- resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.57.0.tgz#8253c6fcf35138b4c424234b8da1596e11b98ad8"
- integrity sha512-YXrkMCiNklqkXctn4mKYkrzNCf/dfVcRUQrkXjeBC+PHXbcpPyaJgInNvztR7Skl8lE3JPGPN4v5XhLxK1bUUg==
- dependencies:
- "@sentry/types" "7.57.0"
- tslib "^2.4.1 || ^1.9.3"
+"@sentry/types@7.77.0":
+ version "7.77.0"
+ resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.77.0.tgz#c5d00fe547b89ccde59cdea59143bf145cee3144"
+ integrity sha512-nfb00XRJVi0QpDHg+JkqrmEBHsqBnxJu191Ded+Cs1OJ5oPXEW6F59LVcBScGvMqe+WEk1a73eH8XezwfgrTsA==
"@sentry/utils@7.61.0":
version "7.61.0"
@@ -2765,6 +2630,13 @@
"@sentry/types" "7.61.0"
tslib "^2.4.1 || ^1.9.3"
+"@sentry/utils@7.77.0":
+ version "7.77.0"
+ resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.77.0.tgz#1f88501f0b8777de31b371cf859d13c82ebe1379"
+ integrity sha512-NmM2kDOqVchrey3N5WSzdQoCsyDkQkiRxExPaNI2oKQ/jMWHs9yt0tSy7otPBcXs0AP59ihl75Bvm1tDRcsp5g==
+ dependencies:
+ "@sentry/types" "7.77.0"
+
"@sideway/address@^4.1.3":
version "4.1.3"
resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.3.tgz#d93cce5d45c5daec92ad76db492cc2ee3c64ab27"
@@ -4139,26 +4011,15 @@ array-flatten@^2.1.2:
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099"
integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==
-array-includes@^3.1.3, array-includes@^3.1.4, array-includes@^3.1.5:
- version "3.1.5"
- resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.5.tgz#2c320010db8d31031fd2a5f6b3bbd4b1aad31bdb"
- integrity sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==
+array-includes@^3.1.3, array-includes@^3.1.5, array-includes@^3.1.6, array-includes@^3.1.7:
+ version "3.1.7"
+ resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.7.tgz#8cd2e01b26f7a3086cbc87271593fe921c62abda"
+ integrity sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==
dependencies:
call-bind "^1.0.2"
- define-properties "^1.1.4"
- es-abstract "^1.19.5"
- get-intrinsic "^1.1.1"
- is-string "^1.0.7"
-
-array-includes@^3.1.6:
- version "3.1.6"
- resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.6.tgz#9e9e720e194f198266ba9e18c29e6a9b0e4b225f"
- integrity sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==
- dependencies:
- call-bind "^1.0.2"
- define-properties "^1.1.4"
- es-abstract "^1.20.4"
- get-intrinsic "^1.1.3"
+ define-properties "^1.2.0"
+ es-abstract "^1.22.1"
+ get-intrinsic "^1.2.1"
is-string "^1.0.7"
array-union@^1.0.1:
@@ -4178,7 +4039,7 @@ array-uniq@^1.0.1:
resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=
-array.prototype.find@^2.2.1:
+array.prototype.find@^2.2.2:
version "2.2.2"
resolved "https://registry.yarnpkg.com/array.prototype.find/-/array.prototype.find-2.2.2.tgz#e862cf891e725d8f2a10e5e42d750629faaabd32"
integrity sha512-DRumkfW97iZGOfn+lIXbkVrXL04sfYKX+EfOodo8XboR5sxPDVvOjZTF/rysusa9lmhmSOeD6Vp6RKQP+eP4Tg==
@@ -4188,43 +4049,35 @@ array.prototype.find@^2.2.1:
es-abstract "^1.22.1"
es-shim-unscopables "^1.0.0"
-array.prototype.flat@^1.2.5:
- version "1.2.5"
- resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz#07e0975d84bbc7c48cd1879d609e682598d33e13"
- integrity sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==
- dependencies:
- call-bind "^1.0.2"
- define-properties "^1.1.3"
- es-abstract "^1.19.0"
-
-array.prototype.flat@^1.3.1:
- version "1.3.1"
- resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz#ffc6576a7ca3efc2f46a143b9d1dda9b4b3cf5e2"
- integrity sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==
+array.prototype.findlastindex@^1.2.3:
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz#b37598438f97b579166940814e2c0493a4f50207"
+ integrity sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==
dependencies:
call-bind "^1.0.2"
- define-properties "^1.1.4"
- es-abstract "^1.20.4"
+ define-properties "^1.2.0"
+ es-abstract "^1.22.1"
es-shim-unscopables "^1.0.0"
+ get-intrinsic "^1.2.1"
-array.prototype.flatmap@^1.3.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.0.tgz#a7e8ed4225f4788a70cd910abcf0791e76a5534f"
- integrity sha512-PZC9/8TKAIxcWKdyeb77EzULHPrIX/tIZebLJUQOMR1OwYosT8yggdfWScfTBCDj5utONvOuPQQumYsU2ULbkg==
+array.prototype.flat@^1.3.2:
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz#1476217df8cff17d72ee8f3ba06738db5b387d18"
+ integrity sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==
dependencies:
call-bind "^1.0.2"
- define-properties "^1.1.3"
- es-abstract "^1.19.2"
+ define-properties "^1.2.0"
+ es-abstract "^1.22.1"
es-shim-unscopables "^1.0.0"
-array.prototype.flatmap@^1.3.1:
- version "1.3.1"
- resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz#1aae7903c2100433cb8261cd4ed310aab5c4a183"
- integrity sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==
+array.prototype.flatmap@^1.3.0, array.prototype.flatmap@^1.3.1, array.prototype.flatmap@^1.3.2:
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz#c9a7c6831db8e719d6ce639190146c24bbd3e527"
+ integrity sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==
dependencies:
call-bind "^1.0.2"
- define-properties "^1.1.4"
- es-abstract "^1.20.4"
+ define-properties "^1.2.0"
+ es-abstract "^1.22.1"
es-shim-unscopables "^1.0.0"
array.prototype.tosorted@^1.1.1:
@@ -4328,18 +4181,10 @@ aws4@^1.8.0:
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59"
integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==
-axios@^0.27.2:
- version "0.27.2"
- resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972"
- integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==
- dependencies:
- follow-redirects "^1.14.9"
- form-data "^4.0.0"
-
-axios@^1.4.0, axios@^1.5.1:
- version "1.5.1"
- resolved "https://registry.yarnpkg.com/axios/-/axios-1.5.1.tgz#11fbaa11fc35f431193a9564109c88c1f27b585f"
- integrity sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==
+axios@^1.4.0, axios@^1.5.1, axios@^1.6.1:
+ version "1.6.2"
+ resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.2.tgz#de67d42c755b571d3e698df1b6504cde9b0ee9f2"
+ integrity sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==
dependencies:
follow-redirects "^1.15.0"
form-data "^4.0.0"
@@ -4444,29 +4289,29 @@ babel-plugin-macros@^3.1.0:
cosmiconfig "^7.0.0"
resolve "^1.19.0"
-babel-plugin-polyfill-corejs2@^0.4.3, babel-plugin-polyfill-corejs2@^0.4.5:
- version "0.4.5"
- resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.5.tgz#8097b4cb4af5b64a1d11332b6fb72ef5e64a054c"
- integrity sha512-19hwUH5FKl49JEsvyTcoHakh6BE0wgXLLptIyKZ3PijHc/Ci521wygORCUCCred+E/twuqRyAkE02BAWPmsHOg==
+babel-plugin-polyfill-corejs2@^0.4.5, babel-plugin-polyfill-corejs2@^0.4.6:
+ version "0.4.6"
+ resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.6.tgz#b2df0251d8e99f229a8e60fc4efa9a68b41c8313"
+ integrity sha512-jhHiWVZIlnPbEUKSSNb9YoWcQGdlTLq7z1GHL4AjFxaoOUMuuEVJ+Y4pAaQUGOGk93YsVCKPbqbfw3m0SM6H8Q==
dependencies:
"@babel/compat-data" "^7.22.6"
- "@babel/helper-define-polyfill-provider" "^0.4.2"
+ "@babel/helper-define-polyfill-provider" "^0.4.3"
semver "^6.3.1"
-babel-plugin-polyfill-corejs3@^0.8.1, babel-plugin-polyfill-corejs3@^0.8.3:
- version "0.8.3"
- resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.3.tgz#b4f719d0ad9bb8e0c23e3e630c0c8ec6dd7a1c52"
- integrity sha512-z41XaniZL26WLrvjy7soabMXrfPWARN25PZoriDEiLMxAp50AUW3t35BGQUMg5xK3UrpVTtagIDklxYa+MhiNA==
+babel-plugin-polyfill-corejs3@^0.8.3, babel-plugin-polyfill-corejs3@^0.8.5:
+ version "0.8.6"
+ resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.6.tgz#25c2d20002da91fe328ff89095c85a391d6856cf"
+ integrity sha512-leDIc4l4tUgU7str5BWLS2h8q2N4Nf6lGZP6UrNDxdtfF2g69eJ5L0H7S8A5Ln/arfFAfHor5InAdZuIOwZdgQ==
dependencies:
- "@babel/helper-define-polyfill-provider" "^0.4.2"
- core-js-compat "^3.31.0"
+ "@babel/helper-define-polyfill-provider" "^0.4.3"
+ core-js-compat "^3.33.1"
-babel-plugin-polyfill-regenerator@^0.5.0, babel-plugin-polyfill-regenerator@^0.5.2:
- version "0.5.2"
- resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.2.tgz#80d0f3e1098c080c8b5a65f41e9427af692dc326"
- integrity sha512-tAlOptU0Xj34V1Y2PNTL4Y0FOJMDB6bZmoW39FeCQIhigGLkqu3Fj6uiXpxIf6Ij274ENdYx64y6Au+ZKlb1IA==
+babel-plugin-polyfill-regenerator@^0.5.2, babel-plugin-polyfill-regenerator@^0.5.3:
+ version "0.5.3"
+ resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.3.tgz#d4c49e4b44614607c13fb769bcd85c72bb26a4a5"
+ integrity sha512-8sHeDOmXC8csczMrYEOf0UTNa4yE2SxV5JGeT/LP1n0OYVDUUFPxG9vdk2AlDlIit4t+Kf0xCtpgXPBwnn/9pw==
dependencies:
- "@babel/helper-define-polyfill-provider" "^0.4.2"
+ "@babel/helper-define-polyfill-provider" "^0.4.3"
babel-plugin-react-intl-auto@^3.3.0:
version "3.3.0"
@@ -4622,7 +4467,7 @@ braces@^3.0.1, braces@^3.0.2, braces@~3.0.2:
dependencies:
fill-range "^7.0.1"
-browserslist@^4.14.5, browserslist@^4.20.2, browserslist@^4.21.10, browserslist@^4.21.3, browserslist@^4.21.5, browserslist@^4.21.9:
+browserslist@^4.14.5, browserslist@^4.21.9:
version "4.21.10"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.10.tgz#dbbac576628c13d3b2231332cb2ec5a46e015bb0"
integrity sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==
@@ -4632,6 +4477,16 @@ browserslist@^4.14.5, browserslist@^4.20.2, browserslist@^4.21.10, browserslist@
node-releases "^2.0.13"
update-browserslist-db "^1.0.11"
+browserslist@^4.22.1:
+ version "4.22.1"
+ resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.1.tgz#ba91958d1a59b87dab6fed8dfbcb3da5e2e9c619"
+ integrity sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==
+ dependencies:
+ caniuse-lite "^1.0.30001541"
+ electron-to-chromium "^1.4.535"
+ node-releases "^2.0.13"
+ update-browserslist-db "^1.0.13"
+
bser@2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05"
@@ -4741,6 +4596,11 @@ caniuse-lite@^1.0.30001517:
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001525.tgz#d2e8fdec6116ffa36284ca2c33ef6d53612fe1c8"
integrity sha512-/3z+wB4icFt3r0USMwxujAqRvaD/B7rvGTsKhbhSQErVrJvkZCLhgNLJxU8MevahQVH6hCU9FsHdNUFbiwmE7Q==
+caniuse-lite@^1.0.30001541:
+ version "1.0.30001561"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001561.tgz#752f21f56f96f1b1a52e97aae98c57c562d5d9da"
+ integrity sha512-NTt0DNoKe958Q0BE0j0c1V9jbUzhBxHIEJy7asmGrpE0yG63KTV7PLHPnK2E1O9RsQrQ081I3NLuXGS6zht3cw==
+
caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
@@ -5182,7 +5042,7 @@ content-type@~1.0.4:
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918"
integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==
-convert-source-map@^1.1.0, convert-source-map@^1.5.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0:
+convert-source-map@^1.5.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369"
integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==
@@ -5216,19 +5076,12 @@ copy-webpack-plugin@^11.0.0:
schema-utils "^4.0.0"
serialize-javascript "^6.0.0"
-core-js-compat@^3.30.2:
- version "3.31.0"
- resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.31.0.tgz#4030847c0766cc0e803dcdfb30055d7ef2064bf1"
- integrity sha512-hM7YCu1cU6Opx7MXNu0NuumM0ezNeAeRKadixyiQELWY3vT3De9S4J5ZBMraWV2vZnrE1Cirl0GtFtDtMUXzPw==
- dependencies:
- browserslist "^4.21.5"
-
-core-js-compat@^3.31.0:
- version "3.32.1"
- resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.32.1.tgz#55f9a7d297c0761a8eb1d31b593e0f5b6ffae964"
- integrity sha512-GSvKDv4wE0bPnQtjklV101juQ85g6H3rm5PDP20mqlS5j0kXF3pP97YvAu5hl+uFHqMictp3b2VxOHljWMAtuA==
+core-js-compat@^3.31.0, core-js-compat@^3.33.1:
+ version "3.33.2"
+ resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.33.2.tgz#3ea4563bfd015ad4e4b52442865b02c62aba5085"
+ integrity sha512-axfo+wxFVxnqf8RvxTzoAlzW4gRoacrHeoFlc9n0x50+7BEyZL/Rt3hicaED1/CEd7I6tPCPVUYcJwCMO5XUYw==
dependencies:
- browserslist "^4.21.10"
+ browserslist "^4.22.1"
core-js-pure@^3.23.3:
version "3.25.5"
@@ -5466,7 +5319,7 @@ dayjs@^1.10.4:
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.7.tgz#2cf5f91add28116748440866a0a1d26f3a6ce468"
integrity sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig==
-debug@2.6.9, debug@^2.6.9:
+debug@2.6.9:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
@@ -5859,6 +5712,11 @@ electron-to-chromium@^1.4.477:
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.508.tgz#5641ff2f5ba11df4bd960fe6a2f9f70aa8b9af96"
integrity sha512-FFa8QKjQK/A5QuFr2167myhMesGrhlOBD+3cYNxO9/S4XzHEXesyTD/1/xF644gC8buFPz3ca6G1LOQD0tZrrg==
+electron-to-chromium@^1.4.535:
+ version "1.4.578"
+ resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.578.tgz#7a3510f333bcd55e87882799ebeb7518d6ab4d95"
+ integrity sha512-V0ZhSu1BQZKfG0yNEL6Dadzik8E1vAzfpVOapdSiT9F6yapEJ3Bk+4tZ4SMPdWiUchCgnM/ByYtBzp5ntzDMIA==
+
emittery@^0.13.1:
version "0.13.1"
resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad"
@@ -5981,7 +5839,7 @@ es-abstract@^1.19.0, es-abstract@^1.19.1:
string.prototype.trimstart "^1.0.4"
unbox-primitive "^1.0.1"
-es-abstract@^1.19.2, es-abstract@^1.19.5:
+es-abstract@^1.19.5:
version "1.20.1"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.1.tgz#027292cd6ef44bd12b1913b828116f54787d1814"
integrity sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==
@@ -6202,10 +6060,10 @@ escodegen@^2.0.0:
optionalDependencies:
source-map "~0.6.1"
-eslint-config-prettier@^8.8.0:
- version "8.8.0"
- resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz#bfda738d412adc917fd7b038857110efe98c9348"
- integrity sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==
+eslint-config-prettier@^9.0.0:
+ version "9.0.0"
+ resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz#eb25485946dd0c66cd216a46232dc05451518d1f"
+ integrity sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==
"eslint-config-ttn@git+https://github.com/TheThingsNetwork/eslint-config-ttn.git#v1.4.0":
version "1.4.0"
@@ -6218,48 +6076,33 @@ eslint-config-prettier@^8.8.0:
eslint-plugin-react-hooks "^1.7.0"
js-yaml "^3.13.1"
-eslint-import-resolver-node@^0.3.6:
- version "0.3.6"
- resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd"
- integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==
- dependencies:
- debug "^3.2.7"
- resolve "^1.20.0"
-
-eslint-import-resolver-node@^0.3.7:
- version "0.3.7"
- resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz#83b375187d412324a1963d84fa664377a23eb4d7"
- integrity sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==
+eslint-import-resolver-node@^0.3.9:
+ version "0.3.9"
+ resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac"
+ integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==
dependencies:
debug "^3.2.7"
- is-core-module "^2.11.0"
- resolve "^1.22.1"
+ is-core-module "^2.13.0"
+ resolve "^1.22.4"
-eslint-import-resolver-webpack@^0.13.7:
- version "0.13.7"
- resolved "https://registry.yarnpkg.com/eslint-import-resolver-webpack/-/eslint-import-resolver-webpack-0.13.7.tgz#49cd0108767b1f8ff81123c7e1ae362305aad47b"
- integrity sha512-2a+meyMeABBRO4K53Oj1ygkmt5lhQS79Lmx2f684Qnv6gjvD4RLOM5jfPGTXwQ0A2K03WSoKt3HRQu/uBgxF7w==
+eslint-import-resolver-webpack@^0.13.8:
+ version "0.13.8"
+ resolved "https://registry.yarnpkg.com/eslint-import-resolver-webpack/-/eslint-import-resolver-webpack-0.13.8.tgz#5f64d1d653eefa19cdfd0f0165c996b6be7012f9"
+ integrity sha512-Y7WIaXWV+Q21Rz/PJgUxiW/FTBOWmU8NTLdz+nz9mMoiz5vAev/fOaQxwD7qRzTfE3HSm1qsxZ5uRd7eX+VEtA==
dependencies:
- array.prototype.find "^2.2.1"
+ array.prototype.find "^2.2.2"
debug "^3.2.7"
enhanced-resolve "^0.9.1"
find-root "^1.1.0"
- has "^1.0.3"
+ hasown "^2.0.0"
interpret "^1.4.0"
- is-core-module "^2.13.0"
+ is-core-module "^2.13.1"
is-regex "^1.1.4"
lodash "^4.17.21"
- resolve "^2.0.0-next.4"
+ resolve "^2.0.0-next.5"
semver "^5.7.2"
-eslint-module-utils@^2.7.3:
- version "2.7.4"
- resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz#4f3e41116aaf13a20792261e61d3a2e7e0583974"
- integrity sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==
- dependencies:
- debug "^3.2.7"
-
-eslint-module-utils@^2.7.4:
+eslint-module-utils@^2.8.0:
version "2.8.0"
resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz#e439fee65fc33f6bba630ff621efc38ec0375c49"
integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==
@@ -6280,45 +6123,28 @@ eslint-plugin-cypress@^2.15.1:
dependencies:
globals "^13.20.0"
-eslint-plugin-import@^2.18.2:
- version "2.26.0"
- resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz#f812dc47be4f2b72b478a021605a59fc6fe8b88b"
- integrity sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==
+eslint-plugin-import@^2.18.2, eslint-plugin-import@^2.29.0:
+ version "2.29.0"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.29.0.tgz#8133232e4329ee344f2f612885ac3073b0b7e155"
+ integrity sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg==
dependencies:
- array-includes "^3.1.4"
- array.prototype.flat "^1.2.5"
- debug "^2.6.9"
- doctrine "^2.1.0"
- eslint-import-resolver-node "^0.3.6"
- eslint-module-utils "^2.7.3"
- has "^1.0.3"
- is-core-module "^2.8.1"
- is-glob "^4.0.3"
- minimatch "^3.1.2"
- object.values "^1.1.5"
- resolve "^1.22.0"
- tsconfig-paths "^3.14.1"
-
-eslint-plugin-import@^2.27.5:
- version "2.27.5"
- resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz#876a6d03f52608a3e5bb439c2550588e51dd6c65"
- integrity sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==
- dependencies:
- array-includes "^3.1.6"
- array.prototype.flat "^1.3.1"
- array.prototype.flatmap "^1.3.1"
+ array-includes "^3.1.7"
+ array.prototype.findlastindex "^1.2.3"
+ array.prototype.flat "^1.3.2"
+ array.prototype.flatmap "^1.3.2"
debug "^3.2.7"
doctrine "^2.1.0"
- eslint-import-resolver-node "^0.3.7"
- eslint-module-utils "^2.7.4"
- has "^1.0.3"
- is-core-module "^2.11.0"
+ eslint-import-resolver-node "^0.3.9"
+ eslint-module-utils "^2.8.0"
+ hasown "^2.0.0"
+ is-core-module "^2.13.1"
is-glob "^4.0.3"
minimatch "^3.1.2"
- object.values "^1.1.6"
- resolve "^1.22.1"
- semver "^6.3.0"
- tsconfig-paths "^3.14.1"
+ object.fromentries "^2.0.7"
+ object.groupby "^1.0.1"
+ object.values "^1.1.7"
+ semver "^6.3.1"
+ tsconfig-paths "^3.14.2"
eslint-plugin-jest@^27.2.3:
version "27.2.3"
@@ -6901,7 +6727,7 @@ focus-visible@^5.2.0:
resolved "https://registry.yarnpkg.com/focus-visible/-/focus-visible-5.2.0.tgz#3a9e41fccf587bd25dcc2ef045508284f0a4d6b3"
integrity sha512-Rwix9pBtC1Nuy5wysTmKy+UjbDJpIfg8eHjw0rjZ1mX4GNLz1Bmd16uDpI3Gk1i70Fgcs8Csg2lPm8HULFg9DQ==
-follow-redirects@^1.0.0, follow-redirects@^1.14.9, follow-redirects@^1.15.0:
+follow-redirects@^1.0.0, follow-redirects@^1.15.0:
version "1.15.2"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==
@@ -7026,6 +6852,11 @@ function-bind@^1.1.1:
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
+function-bind@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
+ integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
+
function.prototype.name@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621"
@@ -7396,6 +7227,13 @@ has@^1.0.3:
dependencies:
function-bind "^1.1.1"
+hasown@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c"
+ integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==
+ dependencies:
+ function-bind "^1.1.2"
+
hast-util-parse-selector@^2.0.0:
version "2.2.5"
resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz#d57c23f4da16ae3c63b3b6ca4616683313499c3a"
@@ -7875,12 +7713,12 @@ is-ci@^3.0.0:
dependencies:
ci-info "^3.2.0"
-is-core-module@^2.11.0, is-core-module@^2.13.0, is-core-module@^2.8.1, is-core-module@^2.9.0:
- version "2.13.0"
- resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db"
- integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==
+is-core-module@^2.13.0, is-core-module@^2.13.1:
+ version "2.13.1"
+ resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384"
+ integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==
dependencies:
- has "^1.0.3"
+ hasown "^2.0.0"
is-date-object@^1.0.1:
version "1.0.5"
@@ -8583,10 +8421,10 @@ jest@^29.6.4:
import-local "^3.0.2"
jest-cli "^29.6.4"
-joi@^17.7.0:
- version "17.9.2"
- resolved "https://registry.yarnpkg.com/joi/-/joi-17.9.2.tgz#8b2e4724188369f55451aebd1d0b1d9482470690"
- integrity sha512-Itk/r+V4Dx0V3c7RLFdRh12IOjySm2/WGPMubBT92cQvRfYZhPM2W0hZlctjj72iES8jsRCwp7S/cRmWBnJ4nw==
+joi@^17.11.0:
+ version "17.11.0"
+ resolved "https://registry.yarnpkg.com/joi/-/joi-17.11.0.tgz#aa9da753578ec7720e6f0ca2c7046996ed04fc1a"
+ integrity sha512-NgB+lZLNoqISVy1rZocE9PZI36bL/77ie924Ri43yEvi9GUUMPeyVIr8KdFTMUlby1p0PBYMk9spIxEUQYqrJQ==
dependencies:
"@hapi/hoek" "^9.0.0"
"@hapi/topo" "^5.0.0"
@@ -8706,7 +8544,7 @@ json-stringify-safe@~5.0.1:
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
-json5@^1.0.1:
+json5@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593"
integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==
@@ -9250,12 +9088,7 @@ minimatch@^5.0.1:
dependencies:
brace-expansion "^2.0.1"
-minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6:
- version "1.2.7"
- resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18"
- integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==
-
-minimist@^1.2.7, minimist@^1.2.8:
+minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6, minimist@^1.2.8:
version "1.2.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
@@ -9844,23 +9677,24 @@ object.entries@^1.1.6:
define-properties "^1.1.4"
es-abstract "^1.20.4"
-object.fromentries@^2.0.5:
- version "2.0.5"
- resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.5.tgz#7b37b205109c21e741e605727fe8b0ad5fa08251"
- integrity sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==
+object.fromentries@^2.0.5, object.fromentries@^2.0.6, object.fromentries@^2.0.7:
+ version "2.0.7"
+ resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.7.tgz#71e95f441e9a0ea6baf682ecaaf37fa2a8d7e616"
+ integrity sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==
dependencies:
call-bind "^1.0.2"
- define-properties "^1.1.3"
- es-abstract "^1.19.1"
+ define-properties "^1.2.0"
+ es-abstract "^1.22.1"
-object.fromentries@^2.0.6:
- version "2.0.6"
- resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.6.tgz#cdb04da08c539cffa912dcd368b886e0904bfa73"
- integrity sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==
+object.groupby@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.1.tgz#d41d9f3c8d6c778d9cbac86b4ee9f5af103152ee"
+ integrity sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==
dependencies:
call-bind "^1.0.2"
- define-properties "^1.1.4"
- es-abstract "^1.20.4"
+ define-properties "^1.2.0"
+ es-abstract "^1.22.1"
+ get-intrinsic "^1.2.1"
object.hasown@^1.1.1:
version "1.1.1"
@@ -9878,23 +9712,14 @@ object.hasown@^1.1.2:
define-properties "^1.1.4"
es-abstract "^1.20.4"
-object.values@^1.1.5:
- version "1.1.5"
- resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac"
- integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==
- dependencies:
- call-bind "^1.0.2"
- define-properties "^1.1.3"
- es-abstract "^1.19.1"
-
-object.values@^1.1.6:
- version "1.1.6"
- resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.6.tgz#4abbaa71eba47d63589d402856f908243eea9b1d"
- integrity sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==
+object.values@^1.1.5, object.values@^1.1.6, object.values@^1.1.7:
+ version "1.1.7"
+ resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.7.tgz#617ed13272e7e1071b43973aa1655d9291b8442a"
+ integrity sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==
dependencies:
call-bind "^1.0.2"
- define-properties "^1.1.4"
- es-abstract "^1.20.4"
+ define-properties "^1.2.0"
+ es-abstract "^1.22.1"
obuf@^1.0.0, obuf@^1.1.2:
version "1.1.2"
@@ -10379,9 +10204,9 @@ postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0:
integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
postcss@^8.4.21:
- version "8.4.24"
- resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.24.tgz#f714dba9b2284be3cc07dbd2fc57ee4dc972d2df"
- integrity sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==
+ version "8.4.31"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.31.tgz#92b451050a9f914da6755af352bdc0192508656d"
+ integrity sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==
dependencies:
nanoid "^3.3.6"
picocolors "^1.0.0"
@@ -11129,32 +10954,25 @@ regenerate-unicode-properties@^10.1.0:
dependencies:
regenerate "^1.4.2"
-regenerate-unicode-properties@^9.0.0:
- version "9.0.0"
- resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz#54d09c7115e1f53dc2314a974b32c1c344efe326"
- integrity sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA==
- dependencies:
- regenerate "^1.4.2"
-
regenerate@^1.4.2:
version "1.4.2"
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a"
integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==
-regenerator-runtime@^0.13.11:
+regenerator-runtime@^0.13.11, regenerator-runtime@^0.13.4:
version "0.13.11"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9"
integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==
-regenerator-runtime@^0.13.4:
- version "0.13.10"
- resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz#ed07b19616bcbec5da6274ebc75ae95634bfc2ee"
- integrity sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw==
+regenerator-runtime@^0.14.0:
+ version "0.14.0"
+ resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45"
+ integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==
-regenerator-transform@^0.15.1:
- version "0.15.1"
- resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.1.tgz#f6c4e99fc1b4591f780db2586328e4d9a9d8dc56"
- integrity sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==
+regenerator-transform@^0.15.2:
+ version "0.15.2"
+ resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.2.tgz#5bbae58b522098ebdf09bca2f83838929001c7a4"
+ integrity sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==
dependencies:
"@babel/runtime" "^7.8.4"
@@ -11184,18 +11002,6 @@ regexp.prototype.flags@^1.5.1:
define-properties "^1.2.0"
set-function-name "^2.0.0"
-regexpu-core@^4.7.1:
- version "4.8.0"
- resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.8.0.tgz#e5605ba361b67b1718478501327502f4479a98f0"
- integrity sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg==
- dependencies:
- regenerate "^1.4.2"
- regenerate-unicode-properties "^9.0.0"
- regjsgen "^0.5.2"
- regjsparser "^0.7.0"
- unicode-match-property-ecmascript "^2.0.0"
- unicode-match-property-value-ecmascript "^2.0.0"
-
regexpu-core@^5.3.1:
version "5.3.2"
resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.3.2.tgz#11a2b06884f3527aec3e93dbbf4a3b958a95546b"
@@ -11208,18 +11014,6 @@ regexpu-core@^5.3.1:
unicode-match-property-ecmascript "^2.0.0"
unicode-match-property-value-ecmascript "^2.1.0"
-regjsgen@^0.5.2:
- version "0.5.2"
- resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733"
- integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==
-
-regjsparser@^0.7.0:
- version "0.7.0"
- resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.7.0.tgz#a6b667b54c885e18b52554cb4960ef71187e9968"
- integrity sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ==
- dependencies:
- jsesc "~0.5.0"
-
regjsparser@^0.9.1:
version "0.9.1"
resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.9.1.tgz#272d05aa10c7c1f67095b1ff0addae8442fc5709"
@@ -11307,21 +11101,21 @@ resolve.exports@^2.0.0:
resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800"
integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==
-resolve@^1.10.0, resolve@^1.12.0, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.0, resolve@^1.22.1:
- version "1.22.2"
- resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f"
- integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==
+resolve@^1.10.0, resolve@^1.12.0, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.4:
+ version "1.22.8"
+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d"
+ integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==
dependencies:
- is-core-module "^2.11.0"
+ is-core-module "^2.13.0"
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"
-resolve@^2.0.0-next.3, resolve@^2.0.0-next.4:
- version "2.0.0-next.4"
- resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.4.tgz#3d37a113d6429f496ec4752d2a2e58efb1fd4660"
- integrity sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==
+resolve@^2.0.0-next.3, resolve@^2.0.0-next.4, resolve@^2.0.0-next.5:
+ version "2.0.0-next.5"
+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.5.tgz#6b0ec3107e671e52b68cd068ef327173b90dc03c"
+ integrity sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==
dependencies:
- is-core-module "^2.9.0"
+ is-core-module "^2.13.0"
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"
@@ -11376,14 +11170,7 @@ rxjs@^6.6.6:
dependencies:
tslib "^1.9.0"
-rxjs@^7.4.0:
- version "7.5.4"
- resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.4.tgz#3d6bd407e6b7ce9a123e76b1e770dc5761aa368d"
- integrity sha512-h5M3Hk78r6wAheJF0a5YahB1yRQKCsZ4MsGdZ5O9ETbVtjPcScGfrMmoOq7EBsCRzd4BDkvDJ7ogP8Sz5tTFiQ==
- dependencies:
- tslib "^2.1.0"
-
-rxjs@^7.8.0:
+rxjs@^7.4.0, rxjs@^7.8.1:
version "7.8.1"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543"
integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==
@@ -12405,13 +12192,13 @@ ts-dedent@^2.0.0:
resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-2.2.0.tgz#39e4bd297cd036292ae2394eb3412be63f563bb5"
integrity sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==
-tsconfig-paths@^3.14.1:
- version "3.14.1"
- resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a"
- integrity sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==
+tsconfig-paths@^3.14.2:
+ version "3.14.2"
+ resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz#6e32f1f79412decd261f92d633a9dc1cfa99f088"
+ integrity sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==
dependencies:
"@types/json5" "^0.0.29"
- json5 "^1.0.1"
+ json5 "^1.0.2"
minimist "^1.2.6"
strip-bom "^3.0.0"
@@ -12433,7 +12220,7 @@ tsutils@^3.21.0:
tslib "^1.8.1"
"ttn-lw@file:sdk/js":
- version "3.27.2"
+ version "3.28.1"
dependencies:
arraybuffer-to-string "^1.0.2"
auto-bind "^5.0.1"
@@ -12588,11 +12375,6 @@ unicode-match-property-ecmascript@^2.0.0:
unicode-canonical-property-names-ecmascript "^2.0.0"
unicode-property-aliases-ecmascript "^2.0.0"
-unicode-match-property-value-ecmascript@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz#1a01aa57247c14c568b89775a54938788189a714"
- integrity sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==
-
unicode-match-property-value-ecmascript@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz#cb5fffdcd16a05124f5a4b0bf7c3770208acbbe0"
@@ -12657,6 +12439,14 @@ update-browserslist-db@^1.0.11:
escalade "^3.1.1"
picocolors "^1.0.0"
+update-browserslist-db@^1.0.13:
+ version "1.0.13"
+ resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4"
+ integrity sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==
+ dependencies:
+ escalade "^3.1.1"
+ picocolors "^1.0.0"
+
upper-case@^1.1.1:
version "1.1.3"
resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598"
@@ -12789,16 +12579,16 @@ w3c-xmlserializer@^4.0.0:
dependencies:
xml-name-validator "^4.0.0"
-wait-on@^7.0.1:
- version "7.0.1"
- resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-7.0.1.tgz#5cff9f8427e94f4deacbc2762e6b0a489b19eae9"
- integrity sha512-9AnJE9qTjRQOlTZIldAaf/da2eW0eSRSgcqq85mXQja/DW3MriHxkpODDSUEg+Gri/rKEcXUZHe+cevvYItaog==
+wait-on@^7.2.0:
+ version "7.2.0"
+ resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-7.2.0.tgz#d76b20ed3fc1e2bebc051fae5c1ff93be7892928"
+ integrity sha512-wCQcHkRazgjG5XoAq9jbTMLpNIjoSlZslrJ2+N9MxDsGEv1HnFoVjOCexL0ESva7Y9cu350j+DWADdk54s4AFQ==
dependencies:
- axios "^0.27.2"
- joi "^17.7.0"
+ axios "^1.6.1"
+ joi "^17.11.0"
lodash "^4.17.21"
- minimist "^1.2.7"
- rxjs "^7.8.0"
+ minimist "^1.2.8"
+ rxjs "^7.8.1"
walker@^1.0.8:
version "1.0.8"