diff --git a/.github/actions/install-go-and-deps/action.yml b/.github/actions/install-go-and-deps/action.yml
index 7a174cf506..b866c7fa6a 100644
--- a/.github/actions/install-go-and-deps/action.yml
+++ b/.github/actions/install-go-and-deps/action.yml
@@ -4,7 +4,7 @@ inputs:
go-version:
description: Go Version
required: true
- default: "~1.20"
+ default: "~1.21"
runs:
using: composite
steps:
diff --git a/.github/workflows/release-tag.yml b/.github/workflows/release-tag.yml
index 12a9a17cc9..9c0ef2b2d5 100644
--- a/.github/workflows/release-tag.yml
+++ b/.github/workflows/release-tag.yml
@@ -14,12 +14,12 @@ jobs:
id-token: write
packages: write
pull-requests: write
- timeout-minutes: 60
+ timeout-minutes: 90
steps:
- name: Maximize build space
uses: easimon/maximize-build-space@v8
with:
- root-reserve-mb: 20480
+ root-reserve-mb: 30720
swap-size-mb: 4096
remove-dotnet: true
remove-android: true
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a49ccce58f..4c35ed6efe 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,57 @@ with the exception that this project **does not** follow Semantic Versioning.
For details about compatibility between different releases, see the **Commitments and Releases** section of our README.
+## [Unreleased]
+
+### Added
+
+### Changed
+
+### Deprecated
+
+### Removed
+
+### Fixed
+
+### Security
+
+## [3.28.2] - 2023-12-20
+
+### Added
+
+- Rate limiting classes for individual HTTP paths.
+- Rate limiting keys for HTTP endpoints now contain the caller API key ID when available. The caller IP is still available as a fallback.
+- Allow users to set multiple frequency plans only in the same band in the Console.
+
+### Changed
+
+- Server side events replaced with single socket connection using the native WebSocket API.
+- Gateways now disconnect if the Gateway Server address has changed.
+ - This enables CUPS-enabled gateways to change their LNS before the periodic CUPS lookup occurs.
+- The LoRa Basics Station discovery endpoint now verifies the authorization credentials of the caller.
+ - This enables the gateways to migrate to another instance gracefully while using CUPS.
+
+### Fixed
+
+- Batch gateway rights assertions when multiple membership chains are available (for example, both via a user and an organization).
+
+## [3.28.1] - 2023-11-27
+
+### Added
+
+- The `http.client.transport.compression` experimental flag. It controls whether the HTTP clients used by the stack support gzip and zstd decompression of server responses. It is enabled by default.
+- The `http.server.transport.compression` experimental flag. It controls whether the HTTP servers used by the stack support gzip compression of the server response. It is enabled by default.
+
+### Changed
+
+- The Things Stack is now built with Go 1.21.
+- Statistics for gateways are now fetched in a single request.
+
+### Fixed
+
+- Resolve scroll jumps when selecting different tabs of a table in the Console.
+- `BatchGetGatewayConnectionStats` RPC rights check in certain cases.
+
## [3.28.0] - 2023-10-31
### Added
@@ -2690,7 +2741,9 @@ For details about compatibility between different releases, see the **Commitment
NOTE: These links should respect backports. See https://github.com/TheThingsNetwork/lorawan-stack/pull/1444/files#r333379706.
-->
-[unreleased]: https://github.com/TheThingsNetwork/lorawan-stack/compare/v3.28.0...v3.28
+[unreleased]: https://github.com/TheThingsNetwork/lorawan-stack/compare/v3.28.2...v3.28
+[3.28.2]: https://github.com/TheThingsNetwork/lorawan-stack/compare/v3.28.1...v3.28.2
+[3.28.1]: https://github.com/TheThingsNetwork/lorawan-stack/compare/v3.28.0...v3.28.1
[3.28.0]: https://github.com/TheThingsNetwork/lorawan-stack/compare/v3.27.2...v3.28.0
[3.27.2]: https://github.com/TheThingsNetwork/lorawan-stack/compare/v3.27.1...v3.27.2
[3.27.1]: https://github.com/TheThingsNetwork/lorawan-stack/compare/v3.27.0...v3.27.1
diff --git a/CODEOWNERS b/CODEOWNERS
index 51685c5e3a..7db3cff7ca 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -1,97 +1,97 @@
# Root
-/** @johanstokking @adriansmares
-/CODEOWNERS @johanstokking
-/LICENSE @johanstokking
+/** @TheThingsNetwork/stack-reviewers-1
+/CODEOWNERS @TheThingsNetwork/stack-reviewers-2
+/LICENSE @TheThingsNetwork/stack-reviewers-2
/CHANGELOG.md
# Clear common folders
/pkg
# Dependencies
-/go.mod @johanstokking @adriansmares
-/go.sum @johanstokking @adriansmares
-/package.json @kschiffer @ryaplots
-/yarn.lock @kschiffer @ryaplots @mjamescompton
-/sdk/js/package.json @kschiffer @ryaplots @mjamescompton
-/sdk/js/yarn.lock @kschiffer @ryaplots @mjamescompton
+/go.mod @TheThingsNetwork/stack-reviewers-1
+/go.sum @TheThingsNetwork/stack-reviewers-1
+/package.json @TheThingsNetwork/stack-reviewers-3
+/yarn.lock @TheThingsNetwork/stack-reviewers-3
+/sdk/js/package.json @TheThingsNetwork/stack-reviewers-3
+/sdk/js/yarn.lock @TheThingsNetwork/stack-reviewers-3
# Build pipeline and tooling
-/Makefile @adriansmares
-/tools @adriansmares
-/.github/workflows @adriansmares
-/config @kschiffer @ryaplots @mjamescompton
-/config/stack @benolayinka @KrishnaIyer
-/cypress @kschiffer @ryaplots @mjamescompton
+/Makefile @TheThingsNetwork/stack-reviewers-4
+/tools @TheThingsNetwork/stack-reviewers-4
+/.github/workflows @TheThingsNetwork/stack-reviewers-4
+/config @TheThingsNetwork/stack-reviewers-3
+/config/stack @TheThingsNetwork/stack-reviewers-5
+/cypress @TheThingsNetwork/stack-reviewers-3
# API, configuration, CLI and storage compatibility
-/api/*.proto @johanstokking @adriansmares
-/cmd @adriansmares
-/pkg/**/config.go @adriansmares
-/pkg/**/registry.go @adriansmares
-/pkg/config/shared.go @adriansmares
-/pkg/goproto @johanstokking @adriansmares
-/pkg/identityserver/store @johanstokking @adriansmares
-/pkg/jsonpb @johanstokking @adriansmares
-/pkg/ttnpb @johanstokking @adriansmares
+/api/*.proto @TheThingsNetwork/stack-reviewers-1
+/cmd @TheThingsNetwork/stack-reviewers-4
+/pkg/**/config.go @TheThingsNetwork/stack-reviewers-4
+/pkg/**/registry.go @TheThingsNetwork/stack-reviewers-4
+/pkg/config/shared.go @TheThingsNetwork/stack-reviewers-4
+/pkg/goproto @TheThingsNetwork/stack-reviewers-1
+/pkg/identityserver/store @TheThingsNetwork/stack-reviewers-1
+/pkg/jsonpb @TheThingsNetwork/stack-reviewers-1
+/pkg/ttnpb @TheThingsNetwork/stack-reviewers-1
# Security
-/pkg/auth @johanstokking @adriansmares
-/pkg/crypto @johanstokking @adriansmares
+/pkg/auth @TheThingsNetwork/stack-reviewers-1
+/pkg/crypto @TheThingsNetwork/stack-reviewers-1
# Shared components
-/pkg/band @johanstokking @KrishnaIyer
-/pkg/cluster @johanstokking @adriansmares
-/pkg/component @johanstokking @adriansmares
-/pkg/errors @johanstokking @adriansmares
-/pkg/events @adriansmares
-/pkg/frequencyplans @johanstokking @KrishnaIyer
-/pkg/interop @johanstokking @adriansmares
-/pkg/rpcmiddleware @johanstokking @adriansmares
-/pkg/rpcserver @johanstokking @adriansmares
-/pkg/types @johanstokking
-/pkg/web @kschiffer @ryaplots @mjamescompton
-/pkg/webmiddleware @KrishnaIyer @kschiffer
-/pkg/webui @kschiffer @ryaplots @mjamescompton
-/pkg/ratelimit @johanstokking @KrishnaIyer
+/pkg/band @TheThingsNetwork/stack-reviewers-7
+/pkg/cluster @TheThingsNetwork/stack-reviewers-1
+/pkg/component @TheThingsNetwork/stack-reviewers-1
+/pkg/errors @TheThingsNetwork/stack-reviewers-1
+/pkg/events @TheThingsNetwork/stack-reviewers-4
+/pkg/frequencyplans @TheThingsNetwork/stack-reviewers-7
+/pkg/interop @TheThingsNetwork/stack-reviewers-1
+/pkg/rpcmiddleware @TheThingsNetwork/stack-reviewers-1
+/pkg/rpcserver @TheThingsNetwork/stack-reviewers-1
+/pkg/types @TheThingsNetwork/stack-reviewers-2
+/pkg/web @TheThingsNetwork/stack-reviewers-3
+/pkg/webmiddleware @TheThingsNetwork/stack-reviewers-8
+/pkg/webui @TheThingsNetwork/stack-reviewers-3
+/pkg/ratelimit @TheThingsNetwork/stack-reviewers-7
# Subsystems
-/pkg/identityserver @adriansmares @nicholaspcr
-/pkg/email @kschiffer @nicholaspcr
-/pkg/oauth @kschiffer @nicholaspcr
-/pkg/account @kschiffer @nicholaspcr
-/pkg/web/oauthclient @kschiffer @nicholaspcr
+/pkg/identityserver @TheThingsNetwork/stack-reviewers-9
+/pkg/email @TheThingsNetwork/stack-reviewers-10
+/pkg/oauth @TheThingsNetwork/stack-reviewers-10
+/pkg/account @TheThingsNetwork/stack-reviewers-10
+/pkg/web/oauthclient @TheThingsNetwork/stack-reviewers-10
-/pkg/gatewayserver @johanstokking @KrishnaIyer @adriansmares
-/pkg/gatewayconfigurationserver @KrishnaIyer @adriansmares
-/pkg/pfconfig @KrishnaIyer @adriansmares
-/pkg/basicstation @KrishnaIyer @adriansmares
+/pkg/gatewayserver @TheThingsNetwork/stack-reviewers-11
+/pkg/gatewayconfigurationserver @TheThingsNetwork/stack-reviewers-12
+/pkg/pfconfig @TheThingsNetwork/stack-reviewers-12
+/pkg/basicstation @TheThingsNetwork/stack-reviewers-12
-/pkg/networkserver @johanstokking @adriansmares
-/pkg/specification/macspec @johanstokking @adriansmares
-/pkg/encoding/lorawan @johanstokking @adriansmares
+/pkg/networkserver @TheThingsNetwork/stack-reviewers-1
+/pkg/specification/macspec @TheThingsNetwork/stack-reviewers-1
+/pkg/encoding/lorawan @TheThingsNetwork/stack-reviewers-1
-/pkg/applicationserver @johanstokking @adriansmares @KrishnaIyer
-/pkg/messageprocessors @johanstokking @adriansmares @KrishnaIyer
-/pkg/scripting @johanstokking @adriansmares @KrishnaIyer
+/pkg/applicationserver @TheThingsNetwork/stack-reviewers-11
+/pkg/messageprocessors @TheThingsNetwork/stack-reviewers-11
+/pkg/scripting @TheThingsNetwork/stack-reviewers-11
-/pkg/joinserver @johanstokking @adriansmares
+/pkg/joinserver @TheThingsNetwork/stack-reviewers-1
-/pkg/console @kschiffer @ryaplots @mjamescompton
+/pkg/console @TheThingsNetwork/stack-reviewers-3
-/pkg/packetbrokeragent @johanstokking @adriansmares
+/pkg/packetbrokeragent @TheThingsNetwork/stack-reviewers-1
-/pkg/devicetemplateconverter @adriansmares @KrishnaIyer
-/pkg/devicetemplates @adriansmares @KrishnaIyer
-/pkg/qrcode @adriansmares @KrishnaIyer
-/pkg/qrcodegenerator @adriansmares @KrishnaIyer
+/pkg/devicetemplateconverter @TheThingsNetwork/stack-reviewers-12
+/pkg/devicetemplates @TheThingsNetwork/stack-reviewers-12
+/pkg/qrcode @TheThingsNetwork/stack-reviewers-12
+/pkg/qrcodegenerator @TheThingsNetwork/stack-reviewers-12
-/pkg/deviceclaimingserver @nicholaspcr @KrishnaIyer
+/pkg/deviceclaimingserver @TheThingsNetwork/stack-reviewers-13
-/pkg/devicerepository @adriansmares @KrishnaIyer
+/pkg/devicerepository @TheThingsNetwork/stack-reviewers-12
# SDKs
-/sdk/js @kschiffer @ryaplots @mjamescompton
+/sdk/js @TheThingsNetwork/stack-reviewers-3
# Clear generated code
/api/api.md
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 51aaa51558..3b59b591f5 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -2,11 +2,11 @@
Thank you for your interest in building this thing together with us. We're really happy with our active community and are glad that you're a part of it. There are many ways to contribute to our project, but given the fact that you're on Github looking at the code for The Things Stack for LoRaWAN, you're probably here for one of the following reasons:
-- **Asking a question**: If you have questions, please use the [forum](https://www.thethingsnetwork.org/forum/). We have a special [category for The Things Stack](https://www.thethingsnetwork.org/forum/c/network-and-routing/v3).
+- **Asking a question**: If you have questions, please use the [forum](https://www.thethingsnetwork.org/forum/). We have a special [category for The Things Stack](https://www.thethingsnetwork.org/forum/c/ttn-network/v3/90).
- **Requesting a new feature**: If you have a great idea or think some functionality is missing, we want to know! The only thing you have to do for that is to [create an issue](https://github.com/TheThingsNetwork/lorawan-stack/issues) if it doesn't exist yet. Please use the issue template and fill out all sections.
- **Reporting an issue**: If you notice that a component of The Things Stack is not behaving as it should, there may be a bug in our systems. In this case you should [create an issue](https://github.com/TheThingsNetwork/lorawan-stack/issues) if it doesn't exist yet. Please use the issue template and fill out all sections. For sensitive (security) issues, you can [contact us directly](#security-issues).
- **Implementing a new feature or fixing a bug**: If you see an [open issue](https://github.com/TheThingsNetwork/lorawan-stack/issues) that you would like to work on, let the other contributors know by commenting in the issue.
-- **Writing documentation**: If you see that our documentation is lacking or incorrect, it would be great if you could help us improve it. This will help users and fellow contributors understand how to better work with our stack. Better documentation helps prevent making mistakes and introducing new bugs. Our documentation is spread across a number of places. Code documentation obviously lives together with the code, and is therefore probably in this repository. User documentation for The Things Stack that is published on [thethingsstack.io](https://thethingsstack.io), is built from the [`lorawan-stack-docs` repository]https://github.com/TheThingsIndustries/lorawan-stack-docs. More general documentation can be found on [The Things Network's official documentation pages](https://www.thethingsnetwork.org/docs). The source files for that documentation can be found in [the `docs` repository](https://github.com/TheThingsNetwork/docs).
+- **Writing documentation**: If you see that our documentation is lacking or incorrect, it would be great if you could help us improve it. This will help users and fellow contributors understand how to better work with our stack. Better documentation helps prevent making mistakes and introducing new bugs. Our documentation is spread across a number of places. Code documentation obviously lives together with the code, and is therefore probably in this repository. User documentation that is published on [the official The Things Stack documentation page](https://thethingsstack.io), is built from the [`lorawan-stack-docs` repository](https://github.com/TheThingsIndustries/lorawan-stack-docs). More general documentation can be found on [The Things Network's official documentation pages](https://www.thethingsnetwork.org/docs). The source files for that documentation can be found in [the `docs` repository](https://github.com/TheThingsNetwork/docs).
If you'd like to contribute by writing code, you'll find [here](DEVELOPMENT.md) how to set up your development environment.
diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md
index 203f295ed0..da49a6094b 100644
--- a/DEVELOPMENT.md
+++ b/DEVELOPMENT.md
@@ -675,7 +675,7 @@ To decide whether a component is a container component, ask yourself:
- Is this component more concerned with how things work, rather than how things look?
- Does this component connect to the store?
- Does this component fetch or send data?
-- Is the component generated by higher order components (e.g. `withFeatureRequirement`)?
+- Is the component generated by higher order components?
- Does this component render simple nodes, like a single presentational component?
If you can answer more than 2 questions with yes, then you likely have a container component.
@@ -692,7 +692,6 @@ View components always represent a single view of the application, represented b
- Fetching necessary data (via `withRequest` HOC), if not done by a container
- Unavailable "catch-all"-routes are caught by ` ` component, including subviews
- Errors should be caught by the ` ` error boundary component
-- `withFeatureRequirement` HOC is used to prevent access to routes that the user has no rights for
- Ensured responsiveness and usage of the grid system
#### Utility components
diff --git a/api/ttn/lorawan/v3/api.md b/api/ttn/lorawan/v3/api.md
index f4bd7342ab..05beb4b4f7 100644
--- a/api/ttn/lorawan/v3/api.md
+++ b/api/ttn/lorawan/v3/api.md
@@ -273,8 +273,14 @@
- [Message `MACState.UplinkMessage`](#ttn.lorawan.v3.MACState.UplinkMessage)
- [Message `MACState.UplinkMessage.RxMetadata`](#ttn.lorawan.v3.MACState.UplinkMessage.RxMetadata)
- [Message `MACState.UplinkMessage.RxMetadata.PacketBrokerMetadata`](#ttn.lorawan.v3.MACState.UplinkMessage.RxMetadata.PacketBrokerMetadata)
+ - [Message `MACState.UplinkMessage.RxMetadata.RelayMetadata`](#ttn.lorawan.v3.MACState.UplinkMessage.RxMetadata.RelayMetadata)
- [Message `MACState.UplinkMessage.TxSettings`](#ttn.lorawan.v3.MACState.UplinkMessage.TxSettings)
+ - [Message `RelayParameters`](#ttn.lorawan.v3.RelayParameters)
+ - [Message `RelayUplinkForwardingRule`](#ttn.lorawan.v3.RelayUplinkForwardingRule)
- [Message `ResetAndGetEndDeviceRequest`](#ttn.lorawan.v3.ResetAndGetEndDeviceRequest)
+ - [Message `ServedRelayParameters`](#ttn.lorawan.v3.ServedRelayParameters)
+ - [Message `ServingRelayForwardingLimits`](#ttn.lorawan.v3.ServingRelayForwardingLimits)
+ - [Message `ServingRelayParameters`](#ttn.lorawan.v3.ServingRelayParameters)
- [Message `Session`](#ttn.lorawan.v3.Session)
- [Message `SetEndDeviceRequest`](#ttn.lorawan.v3.SetEndDeviceRequest)
- [Message `UpdateEndDeviceRequest`](#ttn.lorawan.v3.UpdateEndDeviceRequest)
@@ -472,6 +478,19 @@
- [Message `MACCommand.RejoinParamSetupReq`](#ttn.lorawan.v3.MACCommand.RejoinParamSetupReq)
- [Message `MACCommand.RekeyConf`](#ttn.lorawan.v3.MACCommand.RekeyConf)
- [Message `MACCommand.RekeyInd`](#ttn.lorawan.v3.MACCommand.RekeyInd)
+ - [Message `MACCommand.RelayConfAns`](#ttn.lorawan.v3.MACCommand.RelayConfAns)
+ - [Message `MACCommand.RelayConfReq`](#ttn.lorawan.v3.MACCommand.RelayConfReq)
+ - [Message `MACCommand.RelayConfReq.Configuration`](#ttn.lorawan.v3.MACCommand.RelayConfReq.Configuration)
+ - [Message `MACCommand.RelayConfigureFwdLimitAns`](#ttn.lorawan.v3.MACCommand.RelayConfigureFwdLimitAns)
+ - [Message `MACCommand.RelayConfigureFwdLimitReq`](#ttn.lorawan.v3.MACCommand.RelayConfigureFwdLimitReq)
+ - [Message `MACCommand.RelayCtrlUplinkListAns`](#ttn.lorawan.v3.MACCommand.RelayCtrlUplinkListAns)
+ - [Message `MACCommand.RelayCtrlUplinkListReq`](#ttn.lorawan.v3.MACCommand.RelayCtrlUplinkListReq)
+ - [Message `MACCommand.RelayEndDeviceConfAns`](#ttn.lorawan.v3.MACCommand.RelayEndDeviceConfAns)
+ - [Message `MACCommand.RelayEndDeviceConfReq`](#ttn.lorawan.v3.MACCommand.RelayEndDeviceConfReq)
+ - [Message `MACCommand.RelayEndDeviceConfReq.Configuration`](#ttn.lorawan.v3.MACCommand.RelayEndDeviceConfReq.Configuration)
+ - [Message `MACCommand.RelayNotifyNewEndDeviceReq`](#ttn.lorawan.v3.MACCommand.RelayNotifyNewEndDeviceReq)
+ - [Message `MACCommand.RelayUpdateUplinkListAns`](#ttn.lorawan.v3.MACCommand.RelayUpdateUplinkListAns)
+ - [Message `MACCommand.RelayUpdateUplinkListReq`](#ttn.lorawan.v3.MACCommand.RelayUpdateUplinkListReq)
- [Message `MACCommand.ResetConf`](#ttn.lorawan.v3.MACCommand.ResetConf)
- [Message `MACCommand.ResetInd`](#ttn.lorawan.v3.MACCommand.ResetInd)
- [Message `MACCommand.RxParamSetupAns`](#ttn.lorawan.v3.MACCommand.RxParamSetupAns)
@@ -484,6 +503,15 @@
- [Message `Message`](#ttn.lorawan.v3.Message)
- [Message `PingSlotPeriodValue`](#ttn.lorawan.v3.PingSlotPeriodValue)
- [Message `RejoinRequestPayload`](#ttn.lorawan.v3.RejoinRequestPayload)
+ - [Message `RelayEndDeviceAlwaysMode`](#ttn.lorawan.v3.RelayEndDeviceAlwaysMode)
+ - [Message `RelayEndDeviceControlledMode`](#ttn.lorawan.v3.RelayEndDeviceControlledMode)
+ - [Message `RelayEndDeviceDynamicMode`](#ttn.lorawan.v3.RelayEndDeviceDynamicMode)
+ - [Message `RelayForwardDownlinkReq`](#ttn.lorawan.v3.RelayForwardDownlinkReq)
+ - [Message `RelayForwardLimits`](#ttn.lorawan.v3.RelayForwardLimits)
+ - [Message `RelayForwardUplinkReq`](#ttn.lorawan.v3.RelayForwardUplinkReq)
+ - [Message `RelaySecondChannel`](#ttn.lorawan.v3.RelaySecondChannel)
+ - [Message `RelayUplinkForwardLimits`](#ttn.lorawan.v3.RelayUplinkForwardLimits)
+ - [Message `RelayUplinkToken`](#ttn.lorawan.v3.RelayUplinkToken)
- [Message `RxDelayValue`](#ttn.lorawan.v3.RxDelayValue)
- [Message `TxRequest`](#ttn.lorawan.v3.TxRequest)
- [Message `TxSettings`](#ttn.lorawan.v3.TxSettings)
@@ -510,6 +538,13 @@
- [Enum `RejoinPeriodExponent`](#ttn.lorawan.v3.RejoinPeriodExponent)
- [Enum `RejoinRequestType`](#ttn.lorawan.v3.RejoinRequestType)
- [Enum `RejoinTimeExponent`](#ttn.lorawan.v3.RejoinTimeExponent)
+ - [Enum `RelayCADPeriodicity`](#ttn.lorawan.v3.RelayCADPeriodicity)
+ - [Enum `RelayCtrlUplinkListAction`](#ttn.lorawan.v3.RelayCtrlUplinkListAction)
+ - [Enum `RelayLimitBucketSize`](#ttn.lorawan.v3.RelayLimitBucketSize)
+ - [Enum `RelayResetLimitCounter`](#ttn.lorawan.v3.RelayResetLimitCounter)
+ - [Enum `RelaySecondChAckOffset`](#ttn.lorawan.v3.RelaySecondChAckOffset)
+ - [Enum `RelaySmartEnableLevel`](#ttn.lorawan.v3.RelaySmartEnableLevel)
+ - [Enum `RelayWORChannel`](#ttn.lorawan.v3.RelayWORChannel)
- [Enum `RxDelay`](#ttn.lorawan.v3.RxDelay)
- [Enum `TxSchedulePriority`](#ttn.lorawan.v3.TxSchedulePriority)
- [File `ttn/lorawan/v3/messages.proto`](#ttn/lorawan/v3/messages.proto)
@@ -542,6 +577,7 @@
- [Message `Location`](#ttn.lorawan.v3.Location)
- [Message `PacketBrokerMetadata`](#ttn.lorawan.v3.PacketBrokerMetadata)
- [Message `PacketBrokerRouteHop`](#ttn.lorawan.v3.PacketBrokerRouteHop)
+ - [Message `RelayMetadata`](#ttn.lorawan.v3.RelayMetadata)
- [Message `RxMetadata`](#ttn.lorawan.v3.RxMetadata)
- [Enum `LocationSource`](#ttn.lorawan.v3.LocationSource)
- [File `ttn/lorawan/v3/mqtt.proto`](#ttn/lorawan/v3/mqtt.proto)
@@ -2614,6 +2650,7 @@ PeerInfo
| `base_id` | [`string`](#string) | | The ID of the frequency that the current frequency plan is based on. |
| `name` | [`string`](#string) | | |
| `base_frequency` | [`uint32`](#uint32) | | Base frequency in MHz for hardware support (433, 470, 868 or 915) |
+| `band_id` | [`string`](#string) | | |
### Message `GetPhyVersionsRequest`
@@ -2678,6 +2715,7 @@ PeerInfo
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `base_frequency` | [`uint32`](#uint32) | | Optional base frequency in MHz for hardware support (433, 470, 868 or 915) |
+| `band_id` | [`string`](#string) | | Optional Band ID to filter the results. |
### Message `ListFrequencyPlansResponse`
@@ -4007,11 +4045,12 @@ This is used internally by the Network Server.
| `ping_slot_data_rate_index` | [`DataRateIndex`](#ttn.lorawan.v3.DataRateIndex) | | Data rate index of the class B ping slot. This field is deprecated, use ping_slot_data_rate_index_value instead. |
| `beacon_frequency` | [`uint64`](#uint64) | | Frequency of the class B beacon (Hz). |
| `channels` | [`MACParameters.Channel`](#ttn.lorawan.v3.MACParameters.Channel) | repeated | Configured uplink channels and optionally Rx1 frequency. |
-| `uplink_dwell_time` | [`BoolValue`](#ttn.lorawan.v3.BoolValue) | | 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). |
-| `downlink_dwell_time` | [`BoolValue`](#ttn.lorawan.v3.BoolValue) | | 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). |
+| `uplink_dwell_time` | [`BoolValue`](#ttn.lorawan.v3.BoolValue) | | Whether uplink dwell time is set (400ms). If unset, then the value is either unknown or irrelevant(Network Server cannot modify it). |
+| `downlink_dwell_time` | [`BoolValue`](#ttn.lorawan.v3.BoolValue) | | Whether downlink dwell time is set (400ms). If unset, then the value is either unknown or irrelevant(Network Server cannot modify it). |
| `adr_ack_limit_exponent` | [`ADRAckLimitExponentValue`](#ttn.lorawan.v3.ADRAckLimitExponentValue) | | ADR: number of messages to wait before setting ADRAckReq. |
| `adr_ack_delay_exponent` | [`ADRAckDelayExponentValue`](#ttn.lorawan.v3.ADRAckDelayExponentValue) | | ADR: number of messages to wait after setting ADRAckReq and before changing TxPower or DataRate. |
| `ping_slot_data_rate_index_value` | [`DataRateIndexValue`](#ttn.lorawan.v3.DataRateIndexValue) | | Data rate index of the class B ping slot. |
+| `relay` | [`RelayParameters`](#ttn.lorawan.v3.RelayParameters) | | Relay parameters. |
#### Field Rules
@@ -4088,6 +4127,8 @@ This is used internally by the Network Server.
| `downlink_dwell_time` | [`BoolValue`](#ttn.lorawan.v3.BoolValue) | | Whether downlink dwell time is set (400ms). If unset, the default value from Network Server configuration or regional parameters specification will be used. |
| `adr` | [`ADRSettings`](#ttn.lorawan.v3.ADRSettings) | | Adaptive Data Rate settings. If unset, the default value from Network Server configuration or regional parameters specification will be used. |
| `schedule_downlinks` | [`BoolValue`](#ttn.lorawan.v3.BoolValue) | | Whether or not downlink messages should be scheduled. 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. |
+| `relay` | [`RelayParameters`](#ttn.lorawan.v3.RelayParameters) | | The relay parameters the end device is using. If unset, the default value from Network Server configuration or regional parameters specification will be used. |
+| `desired_relay` | [`RelayParameters`](#ttn.lorawan.v3.RelayParameters) | | 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. |
#### Field Rules
@@ -4126,6 +4167,7 @@ This is used internally by the Network Server.
| `rejected_data_rate_ranges` | [`MACState.RejectedDataRateRangesEntry`](#ttn.lorawan.v3.MACState.RejectedDataRateRangesEntry) | repeated | Data rate ranges rejected by the device per frequency. |
| `last_adr_change_f_cnt_up` | [`uint32`](#uint32) | | Frame counter of uplink, which confirmed the last ADR parameter change. |
| `recent_mac_command_identifiers` | [`MACCommandIdentifier`](#ttn.lorawan.v3.MACCommandIdentifier) | repeated | MAC command identifiers sent by the end device in the last received uplink. The Network Server may choose to store only certain types of MAC command identifiers in the underlying implementation. |
+| `pending_relay_downlink` | [`RelayForwardDownlinkReq`](#ttn.lorawan.v3.RelayForwardDownlinkReq) | | 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. |
#### Field Rules
@@ -4296,6 +4338,7 @@ Used for type safe recent uplink storage.
| `downlink_path_constraint` | [`DownlinkPathConstraint`](#ttn.lorawan.v3.DownlinkPathConstraint) | | |
| `uplink_token` | [`bytes`](#bytes) | | |
| `packet_broker` | [`MACState.UplinkMessage.RxMetadata.PacketBrokerMetadata`](#ttn.lorawan.v3.MACState.UplinkMessage.RxMetadata.PacketBrokerMetadata) | | |
+| `relay` | [`MACState.UplinkMessage.RxMetadata.RelayMetadata`](#ttn.lorawan.v3.MACState.UplinkMessage.RxMetadata.RelayMetadata) | | |
#### Field Rules
@@ -4306,6 +4349,8 @@ Used for type safe recent uplink storage.
### Message `MACState.UplinkMessage.RxMetadata.PacketBrokerMetadata`
+### Message `MACState.UplinkMessage.RxMetadata.RelayMetadata`
+
### Message `MACState.UplinkMessage.TxSettings`
| Field | Type | Label | Description |
@@ -4318,6 +4363,31 @@ Used for type safe recent uplink storage.
| ----- | ----------- |
| `data_rate` |
`message.required`: `true`
|
+### Message `RelayParameters`
+
+RelayParameters represent the parameters of a relay.
+This is used internally by the Network Server.
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| `serving` | [`ServingRelayParameters`](#ttn.lorawan.v3.ServingRelayParameters) | | Parameters related to a relay which is serving end devices. |
+| `served` | [`ServedRelayParameters`](#ttn.lorawan.v3.ServedRelayParameters) | | Parameters related to an end device served by a relay. |
+
+### Message `RelayUplinkForwardingRule`
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| `limits` | [`RelayUplinkForwardLimits`](#ttn.lorawan.v3.RelayUplinkForwardLimits) | | 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. |
+| `last_w_f_cnt` | [`uint32`](#uint32) | | Last wake on radio frame counter used by the served end device. |
+| `device_id` | [`string`](#string) | | End device identifier of the served end device. |
+| `session_key_id` | [`bytes`](#bytes) | | Session key ID of the session keys used to derive the root relay session key. |
+
+#### Field Rules
+
+| Field | Validations |
+| ----- | ----------- |
+| `device_id` | `string.max_len`: `36`
`string.pattern`: `^[a-z0-9](?:[-]?[a-z0-9]){2,}$`
|
+
### Message `ResetAndGetEndDeviceRequest`
| Field | Type | Label | Description |
@@ -4331,6 +4401,52 @@ Used for type safe recent uplink storage.
| ----- | ----------- |
| `end_device_ids` | `message.required`: `true`
|
+### Message `ServedRelayParameters`
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| `always` | [`RelayEndDeviceAlwaysMode`](#ttn.lorawan.v3.RelayEndDeviceAlwaysMode) | | The end device will always attempt to use the relay mode in order to send uplink messages. |
+| `dynamic` | [`RelayEndDeviceDynamicMode`](#ttn.lorawan.v3.RelayEndDeviceDynamicMode) | | 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. |
+| `end_device_controlled` | [`RelayEndDeviceControlledMode`](#ttn.lorawan.v3.RelayEndDeviceControlledMode) | | The end device will control when it uses the relay mode. This is the default mode. |
+| `backoff` | [`uint32`](#uint32) | | Number of uplinks to be sent without a wake on radio frame. |
+| `second_channel` | [`RelaySecondChannel`](#ttn.lorawan.v3.RelaySecondChannel) | | Second wake on radio channel configuration. |
+| `serving_device_id` | [`string`](#string) | | End device identifier of the serving end device. |
+
+#### Field Rules
+
+| Field | Validations |
+| ----- | ----------- |
+| `backoff` | `uint32.lte`: `63`
|
+| `serving_device_id` | `string.max_len`: `36`
`string.pattern`: `^[a-z0-9](?:[-]?[a-z0-9]){2,}$`
|
+
+### Message `ServingRelayForwardingLimits`
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| `reset_behavior` | [`RelayResetLimitCounter`](#ttn.lorawan.v3.RelayResetLimitCounter) | | Reset behavior of the buckets upon limit update. |
+| `join_requests` | [`RelayForwardLimits`](#ttn.lorawan.v3.RelayForwardLimits) | | Bucket configuration for join requests. If unset, no individual limits will apply to join requests, but the relay overall limitations will apply. |
+| `notifications` | [`RelayForwardLimits`](#ttn.lorawan.v3.RelayForwardLimits) | | 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. |
+| `uplink_messages` | [`RelayForwardLimits`](#ttn.lorawan.v3.RelayForwardLimits) | | 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. |
+| `overall` | [`RelayForwardLimits`](#ttn.lorawan.v3.RelayForwardLimits) | | Bucket configuration for all relay messages. If unset, no overall limits will apply to the relay, but individual limitations will still apply. |
+
+### Message `ServingRelayParameters`
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| `second_channel` | [`RelaySecondChannel`](#ttn.lorawan.v3.RelaySecondChannel) | | Second wake on radio channel configuration. |
+| `default_channel_index` | [`uint32`](#uint32) | | Index of the default wake on radio channel. |
+| `cad_periodicity` | [`RelayCADPeriodicity`](#ttn.lorawan.v3.RelayCADPeriodicity) | | Channel activity detection periodicity. |
+| `uplink_forwarding_rules` | [`RelayUplinkForwardingRule`](#ttn.lorawan.v3.RelayUplinkForwardingRule) | repeated | Configured uplink forwarding rules. |
+| `limits` | [`ServingRelayForwardingLimits`](#ttn.lorawan.v3.ServingRelayForwardingLimits) | | Configured forwarding limits. If unset, the default value from Network Server configuration will be used. |
+
+#### Field Rules
+
+| Field | Validations |
+| ----- | ----------- |
+| `default_channel_index` | `uint32.lte`: `255`
|
+| `cad_periodicity` | `enum.defined_only`: `true`
|
+| `uplink_forwarding_rules` | `repeated.max_items`: `16`
|
+
### Message `Session`
| Field | Type | Label | Description |
@@ -5126,7 +5242,7 @@ Identifies an end device model with version information.
| Field | Validations |
| ----- | ----------- |
-| `gateway_ids` | `repeated.min_items`: `1`
`repeated.max_items`: `20`
|
+| `gateway_ids` | `repeated.min_items`: `1`
`repeated.max_items`: `100`
|
| `required` | `message.required`: `true`
|
### Message `BatchDeleteGatewaysRequest`
@@ -6461,6 +6577,17 @@ Only the components for which the keys were meant, will have the key-encryption-
| `beacon_freq_ans` | [`MACCommand.BeaconFreqAns`](#ttn.lorawan.v3.MACCommand.BeaconFreqAns) | | |
| `device_mode_ind` | [`MACCommand.DeviceModeInd`](#ttn.lorawan.v3.MACCommand.DeviceModeInd) | | |
| `device_mode_conf` | [`MACCommand.DeviceModeConf`](#ttn.lorawan.v3.MACCommand.DeviceModeConf) | | |
+| `relay_conf_req` | [`MACCommand.RelayConfReq`](#ttn.lorawan.v3.MACCommand.RelayConfReq) | | |
+| `relay_conf_ans` | [`MACCommand.RelayConfAns`](#ttn.lorawan.v3.MACCommand.RelayConfAns) | | |
+| `relay_end_device_conf_req` | [`MACCommand.RelayEndDeviceConfReq`](#ttn.lorawan.v3.MACCommand.RelayEndDeviceConfReq) | | |
+| `relay_end_device_conf_ans` | [`MACCommand.RelayEndDeviceConfAns`](#ttn.lorawan.v3.MACCommand.RelayEndDeviceConfAns) | | |
+| `relay_update_uplink_list_req` | [`MACCommand.RelayUpdateUplinkListReq`](#ttn.lorawan.v3.MACCommand.RelayUpdateUplinkListReq) | | |
+| `relay_update_uplink_list_ans` | [`MACCommand.RelayUpdateUplinkListAns`](#ttn.lorawan.v3.MACCommand.RelayUpdateUplinkListAns) | | |
+| `relay_ctrl_uplink_list_req` | [`MACCommand.RelayCtrlUplinkListReq`](#ttn.lorawan.v3.MACCommand.RelayCtrlUplinkListReq) | | |
+| `relay_ctrl_uplink_list_ans` | [`MACCommand.RelayCtrlUplinkListAns`](#ttn.lorawan.v3.MACCommand.RelayCtrlUplinkListAns) | | |
+| `relay_configure_fwd_limit_req` | [`MACCommand.RelayConfigureFwdLimitReq`](#ttn.lorawan.v3.MACCommand.RelayConfigureFwdLimitReq) | | |
+| `relay_configure_fwd_limit_ans` | [`MACCommand.RelayConfigureFwdLimitAns`](#ttn.lorawan.v3.MACCommand.RelayConfigureFwdLimitAns) | | |
+| `relay_notify_new_end_device_req` | [`MACCommand.RelayNotifyNewEndDeviceReq`](#ttn.lorawan.v3.MACCommand.RelayNotifyNewEndDeviceReq) | | |
#### Field Rules
@@ -6759,6 +6886,142 @@ Only the components for which the keys were meant, will have the key-encryption-
| ----- | ----------- |
| `minor_version` | `enum.defined_only`: `true`
|
+### Message `MACCommand.RelayConfAns`
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| `second_channel_frequency_ack` | [`bool`](#bool) | | |
+| `second_channel_ack_offset_ack` | [`bool`](#bool) | | |
+| `second_channel_data_rate_index_ack` | [`bool`](#bool) | | |
+| `second_channel_index_ack` | [`bool`](#bool) | | |
+| `default_channel_index_ack` | [`bool`](#bool) | | |
+| `cad_periodicity_ack` | [`bool`](#bool) | | |
+
+### Message `MACCommand.RelayConfReq`
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| `configuration` | [`MACCommand.RelayConfReq.Configuration`](#ttn.lorawan.v3.MACCommand.RelayConfReq.Configuration) | | |
+
+### Message `MACCommand.RelayConfReq.Configuration`
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| `second_channel` | [`RelaySecondChannel`](#ttn.lorawan.v3.RelaySecondChannel) | | |
+| `default_channel_index` | [`uint32`](#uint32) | | |
+| `cad_periodicity` | [`RelayCADPeriodicity`](#ttn.lorawan.v3.RelayCADPeriodicity) | | |
+
+#### Field Rules
+
+| Field | Validations |
+| ----- | ----------- |
+| `default_channel_index` | `uint32.lte`: `255`
|
+| `cad_periodicity` | `enum.defined_only`: `true`
|
+
+### Message `MACCommand.RelayConfigureFwdLimitAns`
+
+### Message `MACCommand.RelayConfigureFwdLimitReq`
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| `reset_limit_counter` | [`RelayResetLimitCounter`](#ttn.lorawan.v3.RelayResetLimitCounter) | | |
+| `join_request_limits` | [`RelayForwardLimits`](#ttn.lorawan.v3.RelayForwardLimits) | | |
+| `notify_limits` | [`RelayForwardLimits`](#ttn.lorawan.v3.RelayForwardLimits) | | |
+| `global_uplink_limits` | [`RelayForwardLimits`](#ttn.lorawan.v3.RelayForwardLimits) | | |
+| `overall_limits` | [`RelayForwardLimits`](#ttn.lorawan.v3.RelayForwardLimits) | | |
+
+### Message `MACCommand.RelayCtrlUplinkListAns`
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| `rule_index_ack` | [`bool`](#bool) | | |
+| `w_f_cnt` | [`uint32`](#uint32) | | |
+
+### Message `MACCommand.RelayCtrlUplinkListReq`
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| `rule_index` | [`uint32`](#uint32) | | |
+| `action` | [`RelayCtrlUplinkListAction`](#ttn.lorawan.v3.RelayCtrlUplinkListAction) | | |
+
+#### Field Rules
+
+| Field | Validations |
+| ----- | ----------- |
+| `rule_index` | `uint32.lte`: `15`
|
+
+### Message `MACCommand.RelayEndDeviceConfAns`
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| `second_channel_frequency_ack` | [`bool`](#bool) | | |
+| `second_channel_data_rate_index_ack` | [`bool`](#bool) | | |
+| `second_channel_index_ack` | [`bool`](#bool) | | |
+| `backoff_ack` | [`bool`](#bool) | | |
+
+### Message `MACCommand.RelayEndDeviceConfReq`
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| `configuration` | [`MACCommand.RelayEndDeviceConfReq.Configuration`](#ttn.lorawan.v3.MACCommand.RelayEndDeviceConfReq.Configuration) | | |
+
+### Message `MACCommand.RelayEndDeviceConfReq.Configuration`
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| `always` | [`RelayEndDeviceAlwaysMode`](#ttn.lorawan.v3.RelayEndDeviceAlwaysMode) | | |
+| `dynamic` | [`RelayEndDeviceDynamicMode`](#ttn.lorawan.v3.RelayEndDeviceDynamicMode) | | |
+| `end_device_controlled` | [`RelayEndDeviceControlledMode`](#ttn.lorawan.v3.RelayEndDeviceControlledMode) | | |
+| `backoff` | [`uint32`](#uint32) | | |
+| `second_channel` | [`RelaySecondChannel`](#ttn.lorawan.v3.RelaySecondChannel) | | |
+| `serving_device_id` | [`string`](#string) | | |
+
+#### Field Rules
+
+| Field | Validations |
+| ----- | ----------- |
+| `backoff` | `uint32.lte`: `63`
|
+| `serving_device_id` | `string.max_len`: `36`
`string.pattern`: `^[a-z0-9](?:[-]?[a-z0-9]){2,}$`
|
+
+### Message `MACCommand.RelayNotifyNewEndDeviceReq`
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| `dev_addr` | [`bytes`](#bytes) | | |
+| `snr` | [`int32`](#int32) | | |
+| `rssi` | [`int32`](#int32) | | |
+
+#### Field Rules
+
+| Field | Validations |
+| ----- | ----------- |
+| `dev_addr` | `bytes.len`: `4`
|
+| `snr` | `int32.lte`: `11`
`int32.gte`: `-20`
|
+| `rssi` | `int32.lte`: `-15`
`int32.gte`: `-142`
|
+
+### Message `MACCommand.RelayUpdateUplinkListAns`
+
+### Message `MACCommand.RelayUpdateUplinkListReq`
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| `rule_index` | [`uint32`](#uint32) | | |
+| `forward_limits` | [`RelayUplinkForwardLimits`](#ttn.lorawan.v3.RelayUplinkForwardLimits) | | |
+| `dev_addr` | [`bytes`](#bytes) | | |
+| `w_f_cnt` | [`uint32`](#uint32) | | |
+| `root_wor_s_key` | [`bytes`](#bytes) | | |
+| `device_id` | [`string`](#string) | | |
+| `session_key_id` | [`bytes`](#bytes) | | |
+
+#### Field Rules
+
+| Field | Validations |
+| ----- | ----------- |
+| `rule_index` | `uint32.lte`: `15`
|
+| `dev_addr` | `bytes.len`: `4`
|
+| `root_wor_s_key` | `bytes.len`: `16`
|
+| `device_id` | `string.max_len`: `36`
`string.pattern`: `^[a-z0-9](?:[-]?[a-z0-9]){2,}$`
|
+
### Message `MACCommand.ResetConf`
| Field | Type | Label | Description |
@@ -6921,6 +7184,107 @@ Message represents a LoRaWAN message
| `join_eui` | `bytes.len`: `8`
|
| `dev_eui` | `bytes.len`: `8`
|
+### Message `RelayEndDeviceAlwaysMode`
+
+### Message `RelayEndDeviceControlledMode`
+
+### Message `RelayEndDeviceDynamicMode`
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| `smart_enable_level` | [`RelaySmartEnableLevel`](#ttn.lorawan.v3.RelaySmartEnableLevel) | | The number of consecutive uplinks without a valid downlink before the end device attempts to use the relay mode to transmit messages. |
+
+#### Field Rules
+
+| Field | Validations |
+| ----- | ----------- |
+| `smart_enable_level` | `enum.defined_only`: `true`
|
+
+### Message `RelayForwardDownlinkReq`
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| `raw_payload` | [`bytes`](#bytes) | | |
+
+### Message `RelayForwardLimits`
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| `bucket_size` | [`RelayLimitBucketSize`](#ttn.lorawan.v3.RelayLimitBucketSize) | | 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. |
+| `reload_rate` | [`uint32`](#uint32) | | The number of tokens which are replenished in the bucket every hour. |
+
+#### Field Rules
+
+| Field | Validations |
+| ----- | ----------- |
+| `bucket_size` | `enum.defined_only`: `true`
|
+| `reload_rate` | `uint32.lte`: `126`
|
+
+### Message `RelayForwardUplinkReq`
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| `data_rate` | [`DataRate`](#ttn.lorawan.v3.DataRate) | | |
+| `snr` | [`int32`](#int32) | | |
+| `rssi` | [`int32`](#int32) | | |
+| `wor_channel` | [`RelayWORChannel`](#ttn.lorawan.v3.RelayWORChannel) | | |
+| `frequency` | [`uint64`](#uint64) | | Uplink channel frequency (Hz). |
+| `raw_payload` | [`bytes`](#bytes) | | |
+
+#### Field Rules
+
+| Field | Validations |
+| ----- | ----------- |
+| `data_rate` | `message.required`: `true`
|
+| `snr` | `int32.lte`: `11`
`int32.gte`: `-20`
|
+| `rssi` | `int32.lte`: `-15`
`int32.gte`: `-142`
|
+| `wor_channel` | `enum.defined_only`: `true`
|
+| `frequency` | `uint64.gte`: `100000`
|
+
+### Message `RelaySecondChannel`
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| `ack_offset` | [`RelaySecondChAckOffset`](#ttn.lorawan.v3.RelaySecondChAckOffset) | | The frequency (Hz) offset used for the WOR acknowledgement. |
+| `data_rate_index` | [`DataRateIndex`](#ttn.lorawan.v3.DataRateIndex) | | The data rate index used by the WOR and WOR acknowledgement. |
+| `frequency` | [`uint64`](#uint64) | | The frequency (Hz) used by the wake on radio message. |
+
+#### Field Rules
+
+| Field | Validations |
+| ----- | ----------- |
+| `ack_offset` | `enum.defined_only`: `true`
|
+| `data_rate_index` | `enum.defined_only`: `true`
|
+| `frequency` | `uint64.gte`: `100000`
|
+
+### Message `RelayUplinkForwardLimits`
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| `bucket_size` | [`RelayLimitBucketSize`](#ttn.lorawan.v3.RelayLimitBucketSize) | | 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. |
+| `reload_rate` | [`uint32`](#uint32) | | The number of tokens which are replenished in the bucket every hour. |
+
+#### Field Rules
+
+| Field | Validations |
+| ----- | ----------- |
+| `bucket_size` | `enum.defined_only`: `true`
|
+| `reload_rate` | `uint32.lte`: `62`
|
+
+### Message `RelayUplinkToken`
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| `ids` | [`EndDeviceIdentifiers`](#ttn.lorawan.v3.EndDeviceIdentifiers) | | |
+| `session_key_id` | [`bytes`](#bytes) | | |
+| `full_f_cnt` | [`uint32`](#uint32) | | |
+
+#### Field Rules
+
+| Field | Validations |
+| ----- | ----------- |
+| `ids` | `message.required`: `true`
|
+
### Message `RxDelayValue`
| Field | Type | Label | Description |
@@ -7190,6 +7554,13 @@ Transmission settings for downlink.
| `CID_BEACON_TIMING` | 18 | Deprecated |
| `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 | |
### Enum `MACVersion`
@@ -7344,6 +7715,69 @@ Transmission settings for downlink.
| `REJOIN_TIME_14` | 14 | Every ~6.4 months. |
| `REJOIN_TIME_15` | 15 | Every ~1.1 year. |
+### Enum `RelayCADPeriodicity`
+
+| Name | Number | Description |
+| ---- | ------ | ----------- |
+| `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 | sic |
+
+### Enum `RelayCtrlUplinkListAction`
+
+| Name | Number | Description |
+| ---- | ------ | ----------- |
+| `RELAY_CTRL_UPLINK_LIST_ACTION_READ_W_F_CNT` | 0 | |
+| `RELAY_CTRL_UPLINK_LIST_ACTION_REMOVE_TRUSTED_END_DEVICE` | 1 | |
+
+### Enum `RelayLimitBucketSize`
+
+| Name | Number | Description |
+| ---- | ------ | ----------- |
+| `RELAY_LIMIT_BUCKET_SIZE_1` | 0 | |
+| `RELAY_LIMIT_BUCKET_SIZE_2` | 1 | |
+| `RELAY_LIMIT_BUCKET_SIZE_4` | 2 | |
+| `RELAY_LIMIT_BUCKET_SIZE_12` | 3 | sic |
+
+### Enum `RelayResetLimitCounter`
+
+| Name | Number | Description |
+| ---- | ------ | ----------- |
+| `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 | |
+
+### Enum `RelaySecondChAckOffset`
+
+| Name | Number | Description |
+| ---- | ------ | ----------- |
+| `RELAY_SECOND_CH_ACK_OFFSET_0` | 0 | 0 kHz |
+| `RELAY_SECOND_CH_ACK_OFFSET_200` | 1 | 200 kHz |
+| `RELAY_SECOND_CH_ACK_OFFSET_400` | 2 | 400 kHz |
+| `RELAY_SECOND_CH_ACK_OFFSET_800` | 3 | 800 kHz |
+| `RELAY_SECOND_CH_ACK_OFFSET_1600` | 4 | 1.6 MHz |
+| `RELAY_SECOND_CH_ACK_OFFSET_3200` | 5 | 3.2 MHz |
+
+### Enum `RelaySmartEnableLevel`
+
+| Name | Number | Description |
+| ---- | ------ | ----------- |
+| `RELAY_SMART_ENABLE_LEVEL_8` | 0 | |
+| `RELAY_SMART_ENABLE_LEVEL_16` | 1 | |
+| `RELAY_SMART_ENABLE_LEVEL_32` | 2 | |
+| `RELAY_SMART_ENABLE_LEVEL_64` | 3 | |
+
+### Enum `RelayWORChannel`
+
+| Name | Number | Description |
+| ---- | ------ | ----------- |
+| `RELAY_WOR_CHANNEL_DEFAULT` | 0 | |
+| `RELAY_WOR_CHANNEL_SECONDARY` | 1 | |
+
### Enum `RxDelay`
| Name | Number | Description |
@@ -7850,6 +8284,20 @@ Mapping from UDP message (other fields can be set in "advanced"):
| `receiver_name` | [`string`](#string) | | Receiver of the message. |
| `receiver_agent` | [`string`](#string) | | Receiver agent. |
+### Message `RelayMetadata`
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| `device_id` | [`string`](#string) | | End device identifiers of the relay. |
+| `wor_channel` | [`RelayWORChannel`](#ttn.lorawan.v3.RelayWORChannel) | | Wake on radio channel. |
+
+#### Field Rules
+
+| Field | Validations |
+| ----- | ----------- |
+| `device_id` | `string.max_len`: `36`
`string.pattern`: `^[a-z0-9](?:[-]?[a-z0-9]){2,}$`
|
+| `wor_channel` | `enum.defined_only`: `true`
|
+
### Message `RxMetadata`
Contains metadata for a received message. Each antenna that receives
@@ -7859,6 +8307,7 @@ a message corresponds to one RxMetadata.
| ----- | ---- | ----- | ----------- |
| `gateway_ids` | [`GatewayIdentifiers`](#ttn.lorawan.v3.GatewayIdentifiers) | | |
| `packet_broker` | [`PacketBrokerMetadata`](#ttn.lorawan.v3.PacketBrokerMetadata) | | |
+| `relay` | [`RelayMetadata`](#ttn.lorawan.v3.RelayMetadata) | | |
| `antenna_index` | [`uint32`](#uint32) | | |
| `time` | [`google.protobuf.Timestamp`](#google.protobuf.Timestamp) | | Timestamp at the end of the transmission, provided by the gateway. The accuracy is undefined. |
| `timestamp` | [`uint32`](#uint32) | | Gateway concentrator timestamp when the Rx finished (microseconds). |
diff --git a/api/ttn/lorawan/v3/api.swagger.json b/api/ttn/lorawan/v3/api.swagger.json
index 036dda2148..cf2e11fef8 100644
--- a/api/ttn/lorawan/v3/api.swagger.json
+++ b/api/ttn/lorawan/v3/api.swagger.json
@@ -6707,6 +6707,13 @@
"required": false,
"type": "integer",
"format": "int64"
+ },
+ {
+ "name": "band_id",
+ "description": "Optional Band ID to filter the results.",
+ "in": "query",
+ "required": false,
+ "type": "string"
}
],
"tags": [
@@ -17919,15 +17926,19 @@
}
}
},
- "BandDescriptionRelayParameters": {
+ "BandDescriptionRelayParametersRelayWORChannel": {
"type": "object",
"properties": {
- "wor_channels": {
- "type": "array",
- "items": {
- "type": "object",
- "$ref": "#/definitions/RelayParametersRelayWORChannel"
- }
+ "frequency": {
+ "type": "string",
+ "format": "uint64"
+ },
+ "ack_frequency": {
+ "type": "string",
+ "format": "uint64"
+ },
+ "data_rate_index": {
+ "$ref": "#/definitions/v3DataRateIndex"
}
}
},
@@ -18841,6 +18852,202 @@
}
}
},
+ "MACCommandRelayConfAns": {
+ "type": "object",
+ "properties": {
+ "second_channel_frequency_ack": {
+ "type": "boolean"
+ },
+ "second_channel_ack_offset_ack": {
+ "type": "boolean"
+ },
+ "second_channel_data_rate_index_ack": {
+ "type": "boolean"
+ },
+ "second_channel_index_ack": {
+ "type": "boolean"
+ },
+ "default_channel_index_ack": {
+ "type": "boolean"
+ },
+ "cad_periodicity_ack": {
+ "type": "boolean"
+ }
+ }
+ },
+ "MACCommandRelayConfReq": {
+ "type": "object",
+ "properties": {
+ "configuration": {
+ "$ref": "#/definitions/MACCommandRelayConfReqConfiguration"
+ }
+ }
+ },
+ "MACCommandRelayConfReqConfiguration": {
+ "type": "object",
+ "properties": {
+ "second_channel": {
+ "$ref": "#/definitions/v3RelaySecondChannel"
+ },
+ "default_channel_index": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "cad_periodicity": {
+ "$ref": "#/definitions/v3RelayCADPeriodicity"
+ }
+ }
+ },
+ "MACCommandRelayConfigureFwdLimitAns": {
+ "type": "object"
+ },
+ "MACCommandRelayConfigureFwdLimitReq": {
+ "type": "object",
+ "properties": {
+ "reset_limit_counter": {
+ "$ref": "#/definitions/v3RelayResetLimitCounter"
+ },
+ "join_request_limits": {
+ "$ref": "#/definitions/v3RelayForwardLimits"
+ },
+ "notify_limits": {
+ "$ref": "#/definitions/v3RelayForwardLimits"
+ },
+ "global_uplink_limits": {
+ "$ref": "#/definitions/v3RelayForwardLimits"
+ },
+ "overall_limits": {
+ "$ref": "#/definitions/v3RelayForwardLimits"
+ }
+ }
+ },
+ "MACCommandRelayCtrlUplinkListAns": {
+ "type": "object",
+ "properties": {
+ "rule_index_ack": {
+ "type": "boolean"
+ },
+ "w_f_cnt": {
+ "type": "integer",
+ "format": "int64"
+ }
+ }
+ },
+ "MACCommandRelayCtrlUplinkListReq": {
+ "type": "object",
+ "properties": {
+ "rule_index": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "action": {
+ "$ref": "#/definitions/v3RelayCtrlUplinkListAction"
+ }
+ }
+ },
+ "MACCommandRelayEndDeviceConfAns": {
+ "type": "object",
+ "properties": {
+ "second_channel_frequency_ack": {
+ "type": "boolean"
+ },
+ "second_channel_data_rate_index_ack": {
+ "type": "boolean"
+ },
+ "second_channel_index_ack": {
+ "type": "boolean"
+ },
+ "backoff_ack": {
+ "type": "boolean"
+ }
+ }
+ },
+ "MACCommandRelayEndDeviceConfReq": {
+ "type": "object",
+ "properties": {
+ "configuration": {
+ "$ref": "#/definitions/MACCommandRelayEndDeviceConfReqConfiguration"
+ }
+ }
+ },
+ "MACCommandRelayEndDeviceConfReqConfiguration": {
+ "type": "object",
+ "properties": {
+ "always": {
+ "$ref": "#/definitions/v3RelayEndDeviceAlwaysMode"
+ },
+ "dynamic": {
+ "$ref": "#/definitions/v3RelayEndDeviceDynamicMode"
+ },
+ "end_device_controlled": {
+ "$ref": "#/definitions/v3RelayEndDeviceControlledMode"
+ },
+ "backoff": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "second_channel": {
+ "$ref": "#/definitions/v3RelaySecondChannel"
+ },
+ "serving_device_id": {
+ "type": "string"
+ }
+ }
+ },
+ "MACCommandRelayNotifyNewEndDeviceReq": {
+ "type": "object",
+ "properties": {
+ "dev_addr": {
+ "type": "string",
+ "format": "string",
+ "example": "2600ABCD"
+ },
+ "snr": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "rssi": {
+ "type": "integer",
+ "format": "int32"
+ }
+ }
+ },
+ "MACCommandRelayUpdateUplinkListAns": {
+ "type": "object"
+ },
+ "MACCommandRelayUpdateUplinkListReq": {
+ "type": "object",
+ "properties": {
+ "rule_index": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "forward_limits": {
+ "$ref": "#/definitions/v3RelayUplinkForwardLimits"
+ },
+ "dev_addr": {
+ "type": "string",
+ "format": "string",
+ "example": "2600ABCD"
+ },
+ "w_f_cnt": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "root_wor_s_key": {
+ "type": "string",
+ "format": "string",
+ "example": "0123456789ABCDEF0123456789ABCDEF"
+ },
+ "device_id": {
+ "type": "string"
+ },
+ "session_key_id": {
+ "type": "string",
+ "format": "byte"
+ }
+ }
+ },
"MACCommandResetConf": {
"type": "object",
"properties": {
@@ -19000,6 +19207,9 @@
},
"packet_broker": {
"$ref": "#/definitions/UplinkMessageRxMetadataPacketBrokerMetadata"
+ },
+ "relay": {
+ "$ref": "#/definitions/UplinkMessageRxMetadataRelayMetadata"
}
}
},
@@ -19113,22 +19323,6 @@
"default": "ENABLED",
"description": " - ENABLED: No restrictions are in place.\n - WARNING: Warnings are being emitted that the provider will be deprecated in the future.\n - DISABLED: New integrations cannot be set up, and old ones do not start."
},
- "RelayParametersRelayWORChannel": {
- "type": "object",
- "properties": {
- "frequency": {
- "type": "string",
- "format": "uint64"
- },
- "ack_frequency": {
- "type": "string",
- "format": "uint64"
- },
- "data_rate_index": {
- "$ref": "#/definitions/v3DataRateIndex"
- }
- }
- },
"TxAcknowledgmentResult": {
"type": "string",
"enum": [
@@ -19167,6 +19361,9 @@
"UplinkMessageRxMetadataPacketBrokerMetadata": {
"type": "object"
},
+ "UplinkMessageRxMetadataRelayMetadata": {
+ "type": "object"
+ },
"UserRegistrationAdminApproval": {
"type": "object",
"properties": {
@@ -19481,6 +19678,41 @@
}
}
},
+ "lorawanv3RelayMetadata": {
+ "type": "object",
+ "properties": {
+ "device_id": {
+ "type": "string",
+ "description": "End device identifiers of the relay."
+ },
+ "wor_channel": {
+ "$ref": "#/definitions/lorawanv3RelayWORChannel",
+ "description": "Wake on radio channel."
+ }
+ }
+ },
+ "lorawanv3RelayParameters": {
+ "type": "object",
+ "properties": {
+ "serving": {
+ "$ref": "#/definitions/v3ServingRelayParameters",
+ "description": "Parameters related to a relay which is serving end devices."
+ },
+ "served": {
+ "$ref": "#/definitions/v3ServedRelayParameters",
+ "description": "Parameters related to an end device served by a relay."
+ }
+ },
+ "description": "RelayParameters represent the parameters of a relay.\nThis is used internally by the Network Server."
+ },
+ "lorawanv3RelayWORChannel": {
+ "type": "string",
+ "enum": [
+ "RELAY_WOR_CHANNEL_DEFAULT",
+ "RELAY_WOR_CHANNEL_SECONDARY"
+ ],
+ "default": "RELAY_WOR_CHANNEL_DEFAULT"
+ },
"lorawanv3RxMetadata": {
"type": "object",
"properties": {
@@ -19490,6 +19722,9 @@
"packet_broker": {
"$ref": "#/definitions/lorawanv3PacketBrokerMetadata"
},
+ "relay": {
+ "$ref": "#/definitions/lorawanv3RelayMetadata"
+ },
"antenna_index": {
"type": "integer",
"format": "int64"
@@ -21078,7 +21313,7 @@
"$ref": "#/definitions/BandDescriptionDwellTime"
},
"relay": {
- "$ref": "#/definitions/BandDescriptionRelayParameters"
+ "$ref": "#/definitions/v3BandDescriptionRelayParameters"
}
}
},
@@ -21097,6 +21332,18 @@
}
}
},
+ "v3BandDescriptionRelayParameters": {
+ "type": "object",
+ "properties": {
+ "wor_channels": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "$ref": "#/definitions/BandDescriptionRelayParametersRelayWORChannel"
+ }
+ }
+ }
+ },
"v3BatchGetGatewayConnectionStatsRequest": {
"type": "object",
"properties": {
@@ -22581,6 +22828,9 @@
"type": "integer",
"format": "int64",
"title": "Base frequency in MHz for hardware support (433, 470, 868 or 915)"
+ },
+ "band_id": {
+ "type": "string"
}
}
},
@@ -23644,6 +23894,39 @@
},
"device_mode_conf": {
"$ref": "#/definitions/MACCommandDeviceModeConf"
+ },
+ "relay_conf_req": {
+ "$ref": "#/definitions/MACCommandRelayConfReq"
+ },
+ "relay_conf_ans": {
+ "$ref": "#/definitions/MACCommandRelayConfAns"
+ },
+ "relay_end_device_conf_req": {
+ "$ref": "#/definitions/MACCommandRelayEndDeviceConfReq"
+ },
+ "relay_end_device_conf_ans": {
+ "$ref": "#/definitions/MACCommandRelayEndDeviceConfAns"
+ },
+ "relay_update_uplink_list_req": {
+ "$ref": "#/definitions/MACCommandRelayUpdateUplinkListReq"
+ },
+ "relay_update_uplink_list_ans": {
+ "$ref": "#/definitions/MACCommandRelayUpdateUplinkListAns"
+ },
+ "relay_ctrl_uplink_list_req": {
+ "$ref": "#/definitions/MACCommandRelayCtrlUplinkListReq"
+ },
+ "relay_ctrl_uplink_list_ans": {
+ "$ref": "#/definitions/MACCommandRelayCtrlUplinkListAns"
+ },
+ "relay_configure_fwd_limit_req": {
+ "$ref": "#/definitions/MACCommandRelayConfigureFwdLimitReq"
+ },
+ "relay_configure_fwd_limit_ans": {
+ "$ref": "#/definitions/MACCommandRelayConfigureFwdLimitAns"
+ },
+ "relay_notify_new_end_device_req": {
+ "$ref": "#/definitions/MACCommandRelayNotifyNewEndDeviceReq"
}
}
},
@@ -23670,7 +23953,14 @@
"CID_PING_SLOT_CHANNEL",
"CID_BEACON_TIMING",
"CID_BEACON_FREQ",
- "CID_DEVICE_MODE"
+ "CID_DEVICE_MODE",
+ "CID_RELAY_CONF",
+ "CID_RELAY_END_DEVICE_CONF",
+ "CID_RELAY_FILTER_LIST",
+ "CID_RELAY_UPDATE_UPLINK_LIST",
+ "CID_RELAY_CTRL_UPLINK_LIST",
+ "CID_RELAY_CONFIGURE_FWD_LIMIT",
+ "CID_RELAY_NOTIFY_NEW_END_DEVICE"
],
"default": "CID_RFU_0",
"title": "- CID_BEACON_TIMING: Deprecated"
@@ -23760,11 +24050,11 @@
},
"uplink_dwell_time": {
"$ref": "#/definitions/lorawanv3BoolValue",
- "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)."
},
"downlink_dwell_time": {
"$ref": "#/definitions/lorawanv3BoolValue",
- "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)."
},
"adr_ack_limit_exponent": {
"$ref": "#/definitions/v3ADRAckLimitExponentValue",
@@ -23777,6 +24067,10 @@
"ping_slot_data_rate_index_value": {
"$ref": "#/definitions/v3DataRateIndexValue",
"description": "Data rate index of the class B ping slot."
+ },
+ "relay": {
+ "$ref": "#/definitions/lorawanv3RelayParameters",
+ "description": "Relay parameters."
}
},
"description": "MACParameters represent the parameters of the device's MAC layer (active or desired).\nThis is used internally by the Network Server."
@@ -23952,6 +24246,14 @@
"schedule_downlinks": {
"$ref": "#/definitions/lorawanv3BoolValue",
"description": "Whether or not downlink messages should be scheduled.\nThis option can be used in order to disable any downlink interaction with the end device. It will affect all types\nof downlink messages: data and MAC downlinks, and join accepts."
+ },
+ "relay": {
+ "$ref": "#/definitions/lorawanv3RelayParameters",
+ "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."
+ },
+ "desired_relay": {
+ "$ref": "#/definitions/lorawanv3RelayParameters",
+ "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."
}
}
},
@@ -24087,6 +24389,10 @@
"$ref": "#/definitions/v3MACCommandIdentifier"
},
"description": "MAC command identifiers sent by the end device in the last received uplink.\nThe Network Server may choose to store only certain types of MAC\ncommand identifiers in the underlying implementation."
+ },
+ "pending_relay_downlink": {
+ "$ref": "#/definitions/v3RelayForwardDownlinkReq",
+ "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."
}
},
"description": "MACState represents the state of MAC layer of the device.\nMACState is reset on each join for OTAA or ResetInd for ABP devices.\nThis is used internally by the Network Server."
@@ -25204,6 +25510,164 @@
"default": "REJOIN_TIME_0",
"description": " - REJOIN_TIME_0: Every ~17.1 minutes.\n - REJOIN_TIME_1: Every ~34.1 minutes.\n - REJOIN_TIME_2: Every ~1.1 hours.\n - REJOIN_TIME_3: Every ~2.3 hours.\n - REJOIN_TIME_4: Every ~4.6 hours.\n - REJOIN_TIME_5: Every ~9.1 hours.\n - REJOIN_TIME_6: Every ~18.2 hours.\n - REJOIN_TIME_7: Every ~1.5 days.\n - REJOIN_TIME_8: Every ~3.0 days.\n - REJOIN_TIME_9: Every ~6.1 days.\n - REJOIN_TIME_10: Every ~12.1 days.\n - REJOIN_TIME_11: Every ~3.5 weeks.\n - REJOIN_TIME_12: Every ~1.6 months.\n - REJOIN_TIME_13: Every ~3.2 months.\n - REJOIN_TIME_14: Every ~6.4 months.\n - REJOIN_TIME_15: Every ~1.1 year."
},
+ "v3RelayCADPeriodicity": {
+ "type": "string",
+ "enum": [
+ "RELAY_CAD_PERIODICITY_1_SECOND",
+ "RELAY_CAD_PERIODICITY_500_MILLISECONDS",
+ "RELAY_CAD_PERIODICITY_250_MILLISECONDS",
+ "RELAY_CAD_PERIODICITY_100_MILLISECONDS",
+ "RELAY_CAD_PERIODICITY_50_MILLISECONDS",
+ "RELAY_CAD_PERIODICITY_20_MILLISECONDS"
+ ],
+ "default": "RELAY_CAD_PERIODICITY_1_SECOND",
+ "title": "- RELAY_CAD_PERIODICITY_20_MILLISECONDS: sic"
+ },
+ "v3RelayCtrlUplinkListAction": {
+ "type": "string",
+ "enum": [
+ "RELAY_CTRL_UPLINK_LIST_ACTION_READ_W_F_CNT",
+ "RELAY_CTRL_UPLINK_LIST_ACTION_REMOVE_TRUSTED_END_DEVICE"
+ ],
+ "default": "RELAY_CTRL_UPLINK_LIST_ACTION_READ_W_F_CNT"
+ },
+ "v3RelayEndDeviceAlwaysMode": {
+ "type": "object"
+ },
+ "v3RelayEndDeviceControlledMode": {
+ "type": "object"
+ },
+ "v3RelayEndDeviceDynamicMode": {
+ "type": "object",
+ "properties": {
+ "smart_enable_level": {
+ "$ref": "#/definitions/v3RelaySmartEnableLevel",
+ "description": "The number of consecutive uplinks without a valid downlink before the end device attempts\nto use the relay mode to transmit messages."
+ }
+ }
+ },
+ "v3RelayForwardDownlinkReq": {
+ "type": "object",
+ "properties": {
+ "raw_payload": {
+ "type": "string",
+ "format": "byte"
+ }
+ }
+ },
+ "v3RelayForwardLimits": {
+ "type": "object",
+ "properties": {
+ "bucket_size": {
+ "$ref": "#/definitions/v3RelayLimitBucketSize",
+ "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."
+ },
+ "reload_rate": {
+ "type": "integer",
+ "format": "int64",
+ "description": "The number of tokens which are replenished in the bucket every hour."
+ }
+ }
+ },
+ "v3RelayLimitBucketSize": {
+ "type": "string",
+ "enum": [
+ "RELAY_LIMIT_BUCKET_SIZE_1",
+ "RELAY_LIMIT_BUCKET_SIZE_2",
+ "RELAY_LIMIT_BUCKET_SIZE_4",
+ "RELAY_LIMIT_BUCKET_SIZE_12"
+ ],
+ "default": "RELAY_LIMIT_BUCKET_SIZE_1",
+ "title": "- RELAY_LIMIT_BUCKET_SIZE_12: sic"
+ },
+ "v3RelayResetLimitCounter": {
+ "type": "string",
+ "enum": [
+ "RELAY_RESET_LIMIT_COUNTER_ZERO",
+ "RELAY_RESET_LIMIT_COUNTER_RELOAD_RATE",
+ "RELAY_RESET_LIMIT_COUNTER_MAX_VALUE",
+ "RELAY_RESET_LIMIT_COUNTER_NO_RESET"
+ ],
+ "default": "RELAY_RESET_LIMIT_COUNTER_ZERO"
+ },
+ "v3RelaySecondChAckOffset": {
+ "type": "string",
+ "enum": [
+ "RELAY_SECOND_CH_ACK_OFFSET_0",
+ "RELAY_SECOND_CH_ACK_OFFSET_200",
+ "RELAY_SECOND_CH_ACK_OFFSET_400",
+ "RELAY_SECOND_CH_ACK_OFFSET_800",
+ "RELAY_SECOND_CH_ACK_OFFSET_1600",
+ "RELAY_SECOND_CH_ACK_OFFSET_3200"
+ ],
+ "default": "RELAY_SECOND_CH_ACK_OFFSET_0",
+ "title": "- RELAY_SECOND_CH_ACK_OFFSET_0: 0 kHz\n - RELAY_SECOND_CH_ACK_OFFSET_200: 200 kHz\n - RELAY_SECOND_CH_ACK_OFFSET_400: 400 kHz\n - RELAY_SECOND_CH_ACK_OFFSET_800: 800 kHz\n - RELAY_SECOND_CH_ACK_OFFSET_1600: 1.6 MHz\n - RELAY_SECOND_CH_ACK_OFFSET_3200: 3.2 MHz"
+ },
+ "v3RelaySecondChannel": {
+ "type": "object",
+ "properties": {
+ "ack_offset": {
+ "$ref": "#/definitions/v3RelaySecondChAckOffset",
+ "description": "The frequency (Hz) offset used for the WOR acknowledgement."
+ },
+ "data_rate_index": {
+ "$ref": "#/definitions/v3DataRateIndex",
+ "description": "The data rate index used by the WOR and WOR acknowledgement."
+ },
+ "frequency": {
+ "type": "string",
+ "format": "uint64",
+ "description": "The frequency (Hz) used by the wake on radio message."
+ }
+ }
+ },
+ "v3RelaySmartEnableLevel": {
+ "type": "string",
+ "enum": [
+ "RELAY_SMART_ENABLE_LEVEL_8",
+ "RELAY_SMART_ENABLE_LEVEL_16",
+ "RELAY_SMART_ENABLE_LEVEL_32",
+ "RELAY_SMART_ENABLE_LEVEL_64"
+ ],
+ "default": "RELAY_SMART_ENABLE_LEVEL_8"
+ },
+ "v3RelayUplinkForwardLimits": {
+ "type": "object",
+ "properties": {
+ "bucket_size": {
+ "$ref": "#/definitions/v3RelayLimitBucketSize",
+ "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."
+ },
+ "reload_rate": {
+ "type": "integer",
+ "format": "int64",
+ "description": "The number of tokens which are replenished in the bucket every hour."
+ }
+ }
+ },
+ "v3RelayUplinkForwardingRule": {
+ "type": "object",
+ "properties": {
+ "limits": {
+ "$ref": "#/definitions/v3RelayUplinkForwardLimits",
+ "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."
+ },
+ "last_w_f_cnt": {
+ "type": "integer",
+ "format": "int64",
+ "description": "Last wake on radio frame counter used by the served end device."
+ },
+ "device_id": {
+ "type": "string",
+ "description": "End device identifier of the served end device."
+ },
+ "session_key_id": {
+ "type": "string",
+ "format": "byte",
+ "description": "Session key ID of the session keys used to derive the root relay session key."
+ }
+ }
+ },
"v3Right": {
"type": "string",
"enum": [
@@ -25390,6 +25854,91 @@
}
}
},
+ "v3ServedRelayParameters": {
+ "type": "object",
+ "properties": {
+ "always": {
+ "$ref": "#/definitions/v3RelayEndDeviceAlwaysMode",
+ "description": "The end device will always attempt to use the relay mode in order to send uplink messages."
+ },
+ "dynamic": {
+ "$ref": "#/definitions/v3RelayEndDeviceDynamicMode",
+ "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."
+ },
+ "end_device_controlled": {
+ "$ref": "#/definitions/v3RelayEndDeviceControlledMode",
+ "description": "The end device will control when it uses the relay mode. This is the default mode."
+ },
+ "backoff": {
+ "type": "integer",
+ "format": "int64",
+ "description": "Number of uplinks to be sent without a wake on radio frame."
+ },
+ "second_channel": {
+ "$ref": "#/definitions/v3RelaySecondChannel",
+ "description": "Second wake on radio channel configuration."
+ },
+ "serving_device_id": {
+ "type": "string",
+ "description": "End device identifier of the serving end device."
+ }
+ }
+ },
+ "v3ServingRelayForwardingLimits": {
+ "type": "object",
+ "properties": {
+ "reset_behavior": {
+ "$ref": "#/definitions/v3RelayResetLimitCounter",
+ "description": "Reset behavior of the buckets upon limit update."
+ },
+ "join_requests": {
+ "$ref": "#/definitions/v3RelayForwardLimits",
+ "description": "Bucket configuration for join requests.\nIf unset, no individual limits will apply to join requests, but the relay overall limitations will apply."
+ },
+ "notifications": {
+ "$ref": "#/definitions/v3RelayForwardLimits",
+ "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."
+ },
+ "uplink_messages": {
+ "$ref": "#/definitions/v3RelayForwardLimits",
+ "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."
+ },
+ "overall": {
+ "$ref": "#/definitions/v3RelayForwardLimits",
+ "description": "Bucket configuration for all relay messages.\nIf unset, no overall limits will apply to the relay, but individual limitations will still apply."
+ }
+ }
+ },
+ "v3ServingRelayParameters": {
+ "type": "object",
+ "properties": {
+ "second_channel": {
+ "$ref": "#/definitions/v3RelaySecondChannel",
+ "description": "Second wake on radio channel configuration."
+ },
+ "default_channel_index": {
+ "type": "integer",
+ "format": "int64",
+ "description": "Index of the default wake on radio channel."
+ },
+ "cad_periodicity": {
+ "$ref": "#/definitions/v3RelayCADPeriodicity",
+ "description": "Channel activity detection periodicity."
+ },
+ "uplink_forwarding_rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "$ref": "#/definitions/v3RelayUplinkForwardingRule"
+ },
+ "description": "Configured uplink forwarding rules."
+ },
+ "limits": {
+ "$ref": "#/definitions/v3ServingRelayForwardingLimits",
+ "description": "Configured forwarding limits.\nIf unset, the default value from Network Server configuration will be used."
+ }
+ }
+ },
"v3Session": {
"type": "object",
"properties": {
diff --git a/api/ttn/lorawan/v3/configuration_services.proto b/api/ttn/lorawan/v3/configuration_services.proto
index 3fc020ae19..a6423b8928 100644
--- a/api/ttn/lorawan/v3/configuration_services.proto
+++ b/api/ttn/lorawan/v3/configuration_services.proto
@@ -32,6 +32,8 @@ message ListFrequencyPlansRequest {
};
// Optional base frequency in MHz for hardware support (433, 470, 868 or 915)
uint32 base_frequency = 1;
+ // Optional Band ID to filter the results.
+ string band_id = 2;
}
message FrequencyPlanDescription {
@@ -41,6 +43,7 @@ message FrequencyPlanDescription {
string name = 3;
// Base frequency in MHz for hardware support (433, 470, 868 or 915)
uint32 base_frequency = 4;
+ string band_id = 5;
}
message ListFrequencyPlansResponse {
diff --git a/api/ttn/lorawan/v3/end_device.proto b/api/ttn/lorawan/v3/end_device.proto
index 0526c46b07..e762a67aeb 100644
--- a/api/ttn/lorawan/v3/end_device.proto
+++ b/api/ttn/lorawan/v3/end_device.proto
@@ -88,6 +88,120 @@ message BoolValue {
bool value = 1;
}
+message ServingRelayForwardingLimits {
+ option (thethings.flags.message) = {
+ select: true,
+ set: true
+ };
+
+ // Reset behavior of the buckets upon limit update.
+ RelayResetLimitCounter reset_behavior = 1;
+ // Bucket configuration for join requests.
+ // If unset, no individual limits will apply to join requests, but the relay overall limitations will apply.
+ RelayForwardLimits join_requests = 2;
+ // 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.
+ RelayForwardLimits notifications = 3;
+ // 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.
+ RelayForwardLimits uplink_messages = 4;
+ // Bucket configuration for all relay messages.
+ // If unset, no overall limits will apply to the relay, but individual limitations will still apply.
+ RelayForwardLimits overall = 5;
+}
+
+message RelayUplinkForwardingRule {
+ option (thethings.flags.message) = {
+ select: true,
+ set: true
+ };
+
+ // 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.
+ RelayUplinkForwardLimits limits = 1;
+ // Last wake on radio frame counter used by the served end device.
+ uint32 last_w_f_cnt = 2;
+
+ // End device identifier of the served end device.
+ string device_id = 3 [(validate.rules).string = {
+ pattern: "^[a-z0-9](?:[-]?[a-z0-9]){2,}$",
+ max_len: 36,
+ ignore_empty: true
+ }];
+ // Session key ID of the session keys used to derive the root relay session key.
+ bytes session_key_id = 4;
+}
+
+message ServingRelayParameters {
+ option (thethings.flags.message) = {
+ select: true,
+ set: true
+ };
+
+ // Second wake on radio channel configuration.
+ RelaySecondChannel second_channel = 1;
+ // Index of the default wake on radio channel.
+ uint32 default_channel_index = 2 [(validate.rules).uint32.lte = 255];
+ // Channel activity detection periodicity.
+ RelayCADPeriodicity cad_periodicity = 3 [(validate.rules).enum.defined_only = true];
+ // Configured uplink forwarding rules.
+ repeated RelayUplinkForwardingRule uplink_forwarding_rules = 4 [(validate.rules).repeated.max_items = 16];
+ // Configured forwarding limits.
+ // If unset, the default value from Network Server configuration will be used.
+ ServingRelayForwardingLimits limits = 5;
+}
+
+message ServedRelayParameters {
+ option (thethings.flags.message) = {
+ select: true,
+ set: true,
+ semantical: true
+ };
+
+ oneof mode {
+ option (validate.required) = true;
+
+ // The end device will always attempt to use the relay mode in order to send uplink messages.
+ RelayEndDeviceAlwaysMode always = 1;
+ // 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.
+ RelayEndDeviceDynamicMode dynamic = 2;
+ // The end device will control when it uses the relay mode. This is the default mode.
+ RelayEndDeviceControlledMode end_device_controlled = 3;
+ }
+ // Number of uplinks to be sent without a wake on radio frame.
+ uint32 backoff = 4 [(validate.rules).uint32.lte = 63];
+ // Second wake on radio channel configuration.
+ RelaySecondChannel second_channel = 5;
+
+ // End device identifier of the serving end device.
+ string serving_device_id = 6 [(validate.rules).string = {
+ pattern: "^[a-z0-9](?:[-]?[a-z0-9]){2,}$",
+ max_len: 36
+ }];
+}
+
+// RelayParameters represent the parameters of a relay.
+// This is used internally by the Network Server.
+message RelayParameters {
+ option (thethings.flags.message) = {
+ select: true,
+ set: true,
+ semantical: true
+ };
+
+ oneof mode {
+ option (validate.required) = true;
+
+ // Parameters related to a relay which is serving end devices.
+ ServingRelayParameters serving = 25;
+ // Parameters related to an end device served by a relay.
+ ServedRelayParameters served = 26;
+ }
+}
+
// MACParameters represent the parameters of the device's MAC layer (active or desired).
// This is used internally by the Network Server.
message MACParameters {
@@ -162,10 +276,10 @@ message MACParameters {
repeated Channel channels = 19 [(validate.rules).repeated.min_items = 1];
// 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).
BoolValue uplink_dwell_time = 20;
// 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).
BoolValue downlink_dwell_time = 21;
// ADR: number of messages to wait before setting ADRAckReq.
@@ -174,6 +288,9 @@ message MACParameters {
ADRAckDelayExponentValue adr_ack_delay_exponent = 23;
// Data rate index of the class B ping slot.
DataRateIndexValue ping_slot_data_rate_index_value = 24;
+
+ // Relay parameters.
+ RelayParameters relay = 25;
}
// Template for creating end devices.
@@ -443,6 +560,14 @@ message MACSettings {
// 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.
BoolValue schedule_downlinks = 35;
+
+ // The relay parameters the end device is using.
+ // If unset, the default value from Network Server configuration or regional parameters specification will be used.
+ RelayParameters relay = 36;
+
+ // 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.
+ RelayParameters desired_relay = 37;
}
// MACState represents the state of MAC layer of the device.
@@ -574,7 +699,11 @@ message MACState {
reserved 1 to 10;
}
PacketBrokerMetadata packet_broker = 18;
- reserved 2 to 8, 10, 12, 13, 16, 17, 19, 20, 99;
+ message RelayMetadata {
+ reserved 1 to 3;
+ }
+ RelayMetadata relay = 23;
+ reserved 2 to 8, 10, 12, 13, 16, 17, 19, 20, 21, 22, 99;
}
repeated RxMetadata rx_metadata = 5;
google.protobuf.Timestamp received_at = 6;
@@ -665,6 +794,11 @@ message MACState {
// The Network Server may choose to store only certain types of MAC
// command identifiers in the underlying implementation.
repeated MACCommandIdentifier recent_mac_command_identifiers = 23;
+
+ // 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.
+ RelayForwardDownlinkReq pending_relay_downlink = 24;
}
// Power state of the device.
diff --git a/api/ttn/lorawan/v3/gateway_services.proto b/api/ttn/lorawan/v3/gateway_services.proto
index dc2a082ed9..907bd30e79 100644
--- a/api/ttn/lorawan/v3/gateway_services.proto
+++ b/api/ttn/lorawan/v3/gateway_services.proto
@@ -181,7 +181,7 @@ service GatewayConfigurator {
message AssertGatewayRightsRequest {
repeated GatewayIdentifiers gateway_ids = 1 [
(validate.rules).repeated.min_items = 1,
- (validate.rules).repeated.max_items = 20
+ (validate.rules).repeated.max_items = 100
];
Rights required = 2 [(validate.rules).message.required = true];
}
diff --git a/api/ttn/lorawan/v3/lorawan.proto b/api/ttn/lorawan/v3/lorawan.proto
index 0f50e376cd..b5fd0824cd 100644
--- a/api/ttn/lorawan/v3/lorawan.proto
+++ b/api/ttn/lorawan/v3/lorawan.proto
@@ -720,6 +720,161 @@ enum MACCommandIdentifier {
CID_BEACON_TIMING = 18; // Deprecated
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;
+}
+
+enum RelayCADPeriodicity {
+ option (thethings.json.enum) = {
+ marshal_as_string: true,
+ prefix: "RELAY_CAD_PERIODICITY"
+ };
+
+ 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; // sic
+}
+
+enum RelaySecondChAckOffset {
+ option (thethings.json.enum) = {
+ marshal_as_string: true,
+ prefix: "RELAY_SECOND_CH_ACK_OFFSET"
+ };
+
+ RELAY_SECOND_CH_ACK_OFFSET_0 = 0; // 0 kHz
+ RELAY_SECOND_CH_ACK_OFFSET_200 = 1; // 200 kHz
+ RELAY_SECOND_CH_ACK_OFFSET_400 = 2; // 400 kHz
+ RELAY_SECOND_CH_ACK_OFFSET_800 = 3; // 800 kHz
+ RELAY_SECOND_CH_ACK_OFFSET_1600 = 4; // 1.6 MHz
+ RELAY_SECOND_CH_ACK_OFFSET_3200 = 5; // 3.2 MHz
+}
+
+enum RelayLimitBucketSize {
+ option (thethings.json.enum) = {
+ marshal_as_string: true,
+ prefix: "RELAY_LIMIT_BUCKET_SIZE"
+ };
+
+ RELAY_LIMIT_BUCKET_SIZE_1 = 0;
+ RELAY_LIMIT_BUCKET_SIZE_2 = 1;
+ RELAY_LIMIT_BUCKET_SIZE_4 = 2;
+ RELAY_LIMIT_BUCKET_SIZE_12 = 3; // sic
+}
+
+enum RelaySmartEnableLevel {
+ option (thethings.json.enum) = {
+ marshal_as_string: true,
+ prefix: "RELAY_SMART_ENABLE_LEVEL"
+ };
+
+ RELAY_SMART_ENABLE_LEVEL_8 = 0;
+ RELAY_SMART_ENABLE_LEVEL_16 = 1;
+ RELAY_SMART_ENABLE_LEVEL_32 = 2;
+ RELAY_SMART_ENABLE_LEVEL_64 = 3;
+}
+
+enum RelayWORChannel {
+ option (thethings.json.enum) = {
+ marshal_as_string: true,
+ prefix: "RELAY_WOR_CHANNEL"
+ };
+
+ RELAY_WOR_CHANNEL_DEFAULT = 0;
+ RELAY_WOR_CHANNEL_SECONDARY = 1;
+}
+
+enum RelayResetLimitCounter {
+ option (thethings.json.enum) = {
+ marshal_as_string: true,
+ prefix: "RELAY_RESET_LIMIT_COUNTER"
+ };
+
+ 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;
+}
+
+enum RelayCtrlUplinkListAction {
+ option (thethings.json.enum) = {
+ marshal_as_string: true,
+ prefix: "RELAY_CTRL_UPLINK_LIST_ACTION"
+ };
+
+ RELAY_CTRL_UPLINK_LIST_ACTION_READ_W_F_CNT = 0;
+ RELAY_CTRL_UPLINK_LIST_ACTION_REMOVE_TRUSTED_END_DEVICE = 1;
+}
+
+message RelaySecondChannel {
+ option (thethings.flags.message) = {
+ select: true,
+ set: true
+ };
+
+ // The frequency (Hz) offset used for the WOR acknowledgement.
+ RelaySecondChAckOffset ack_offset = 1 [(validate.rules).enum.defined_only = true];
+ // The data rate index used by the WOR and WOR acknowledgement.
+ DataRateIndex data_rate_index = 2 [(validate.rules).enum.defined_only = true];
+ // The frequency (Hz) used by the wake on radio message.
+ uint64 frequency = 3 [(validate.rules).uint64.gte = 100000];
+}
+
+message RelayUplinkForwardLimits {
+ option (thethings.flags.message) = {
+ select: true,
+ set: true
+ };
+
+ // 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.
+ RelayLimitBucketSize bucket_size = 1 [(validate.rules).enum.defined_only = true];
+ // The number of tokens which are replenished in the bucket every hour.
+ uint32 reload_rate = 2 [(validate.rules).uint32.lte = 62];
+}
+
+message RelayForwardLimits {
+ option (thethings.flags.message) = {
+ select: true,
+ set: true
+ };
+
+ // 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.
+ RelayLimitBucketSize bucket_size = 1 [(validate.rules).enum.defined_only = true];
+ // The number of tokens which are replenished in the bucket every hour.
+ uint32 reload_rate = 2 [(validate.rules).uint32.lte = 126];
+}
+
+message RelayEndDeviceAlwaysMode {
+ option (thethings.flags.message) = {
+ select: true,
+ set: true
+ };
+}
+message RelayEndDeviceDynamicMode {
+ option (thethings.flags.message) = {
+ select: true,
+ set: true
+ };
+
+ // The number of consecutive uplinks without a valid downlink before the end device attempts
+ // to use the relay mode to transmit messages.
+ RelaySmartEnableLevel smart_enable_level = 1 [(validate.rules).enum.defined_only = true];
+}
+message RelayEndDeviceControlledMode {
+ option (thethings.flags.message) = {
+ select: true,
+ set: true
+ };
}
message MACCommand {
@@ -760,8 +915,25 @@ message MACCommand {
BeaconFreqAns beacon_freq_ans = 30;
DeviceModeInd device_mode_ind = 31;
DeviceModeConf device_mode_conf = 32;
+
+ RelayConfReq relay_conf_req = 33;
+ RelayConfAns relay_conf_ans = 34;
+ RelayEndDeviceConfReq relay_end_device_conf_req = 35;
+ RelayEndDeviceConfAns relay_end_device_conf_ans = 36;
+ RelayUpdateUplinkListReq relay_update_uplink_list_req = 39;
+ RelayUpdateUplinkListAns relay_update_uplink_list_ans = 40;
+ RelayCtrlUplinkListReq relay_ctrl_uplink_list_req = 41;
+ RelayCtrlUplinkListAns relay_ctrl_uplink_list_ans = 42;
+ RelayConfigureFwdLimitReq relay_configure_fwd_limit_req = 43;
+ RelayConfigureFwdLimitAns relay_configure_fwd_limit_ans = 44;
+ RelayNotifyNewEndDeviceReq relay_notify_new_end_device_req = 45;
}
+ reserved 37;
+ reserved "relay_filter_list_req";
+ reserved 38;
+ reserved "relay_filter_list_ans";
+
message ResetInd {
Minor minor_version = 1 [(validate.rules).enum = {
defined_only: true,
@@ -912,6 +1084,145 @@ message MACCommand {
message DeviceModeConf {
Class class = 1 [(validate.rules).enum.defined_only = true];
}
+
+ message RelayConfReq {
+ message Configuration {
+ RelaySecondChannel second_channel = 1;
+ uint32 default_channel_index = 2 [(validate.rules).uint32.lte = 255];
+ RelayCADPeriodicity cad_periodicity = 3 [(validate.rules).enum.defined_only = true];
+ }
+ Configuration configuration = 1;
+ }
+ message RelayConfAns {
+ bool second_channel_frequency_ack = 1;
+ bool second_channel_ack_offset_ack = 2;
+ bool second_channel_data_rate_index_ack = 3;
+ bool second_channel_index_ack = 4;
+ bool default_channel_index_ack = 5;
+ bool cad_periodicity_ack = 6;
+ }
+ message RelayEndDeviceConfReq {
+ message Configuration {
+ oneof mode {
+ option (validate.required) = true;
+
+ RelayEndDeviceAlwaysMode always = 1;
+ RelayEndDeviceDynamicMode dynamic = 2;
+ RelayEndDeviceControlledMode end_device_controlled = 3;
+ }
+ uint32 backoff = 4 [(validate.rules).uint32.lte = 63];
+ RelaySecondChannel second_channel = 5;
+
+ string serving_device_id = 6 [(validate.rules).string = {
+ pattern: "^[a-z0-9](?:[-]?[a-z0-9]){2,}$",
+ max_len: 36
+ }];
+ }
+ Configuration configuration = 1;
+ }
+ message RelayEndDeviceConfAns {
+ bool second_channel_frequency_ack = 1;
+ reserved 2; // second_channel_ack_offset_ack does not exist in the relay specification.
+ reserved "second_channel_ack_offset_ack";
+ bool second_channel_data_rate_index_ack = 3;
+ bool second_channel_index_ack = 4;
+ bool backoff_ack = 5;
+ }
+ message RelayUpdateUplinkListReq {
+ uint32 rule_index = 1 [(validate.rules).uint32.lte = 15];
+ RelayUplinkForwardLimits forward_limits = 2;
+ bytes dev_addr = 3 [
+ (validate.rules).bytes = {
+ len: 4,
+ ignore_empty: true
+ },
+ (thethings.json.field) = {
+ marshaler_func: "go.thethings.network/lorawan-stack/v3/pkg/types.MarshalHEXBytes",
+ unmarshaler_func: "go.thethings.network/lorawan-stack/v3/pkg/types.Unmarshal4Bytes"
+ },
+ (thethings.flags.field) = {
+ set_flag_new_func: "go.thethings.network/lorawan-stack/v3/cmd/ttn-lw-cli/customflags.New4BytesFlag",
+ set_flag_getter_func: "go.thethings.network/lorawan-stack/v3/cmd/ttn-lw-cli/customflags.GetExactBytes"
+ },
+ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
+ type: STRING,
+ format: "string",
+ example: "\"2600ABCD\""
+ }
+ ];
+ uint32 w_f_cnt = 4;
+ bytes root_wor_s_key = 5 [
+ (validate.rules).bytes = {
+ len: 16,
+ ignore_empty: true
+ },
+ (thethings.json.field) = {
+ marshaler_func: "go.thethings.network/lorawan-stack/v3/pkg/types.MarshalHEXBytes",
+ unmarshaler_func: "go.thethings.network/lorawan-stack/v3/pkg/types.Unmarshal16Bytes"
+ },
+ (thethings.flags.field) = {
+ set_flag_new_func: "go.thethings.network/lorawan-stack/v3/cmd/ttn-lw-cli/customflags.New16BytesFlag",
+ set_flag_getter_func: "go.thethings.network/lorawan-stack/v3/cmd/ttn-lw-cli/customflags.GetExactBytes"
+ },
+ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
+ type: STRING,
+ format: "string",
+ example: "\"0123456789ABCDEF0123456789ABCDEF\""
+ }
+ ];
+
+ string device_id = 6 [(validate.rules).string = {
+ pattern: "^[a-z0-9](?:[-]?[a-z0-9]){2,}$",
+ max_len: 36
+ }];
+ bytes session_key_id = 7;
+ }
+ message RelayUpdateUplinkListAns {}
+ message RelayCtrlUplinkListReq {
+ uint32 rule_index = 1 [(validate.rules).uint32.lte = 15];
+ RelayCtrlUplinkListAction action = 2;
+ }
+ message RelayCtrlUplinkListAns {
+ bool rule_index_ack = 1;
+ uint32 w_f_cnt = 2;
+ }
+ message RelayConfigureFwdLimitReq {
+ RelayResetLimitCounter reset_limit_counter = 1;
+ RelayForwardLimits join_request_limits = 2;
+ RelayForwardLimits notify_limits = 3;
+ RelayForwardLimits global_uplink_limits = 4;
+ RelayForwardLimits overall_limits = 5;
+ }
+ message RelayConfigureFwdLimitAns {}
+ message RelayNotifyNewEndDeviceReq {
+ bytes dev_addr = 1 [
+ (validate.rules).bytes = {
+ len: 4,
+ ignore_empty: true
+ },
+ (thethings.json.field) = {
+ marshaler_func: "go.thethings.network/lorawan-stack/v3/pkg/types.MarshalHEXBytes",
+ unmarshaler_func: "go.thethings.network/lorawan-stack/v3/pkg/types.Unmarshal4Bytes"
+ },
+ (thethings.flags.field) = {
+ set_flag_new_func: "go.thethings.network/lorawan-stack/v3/cmd/ttn-lw-cli/customflags.New4BytesFlag",
+ set_flag_getter_func: "go.thethings.network/lorawan-stack/v3/cmd/ttn-lw-cli/customflags.GetExactBytes"
+ },
+ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
+ type: STRING,
+ format: "string",
+ example: "\"2600ABCD\""
+ }
+ ];
+ int32 snr = 2 [(validate.rules).int32 = {
+ lte: 11,
+ gte: -20
+ }];
+ int32 rssi = 3 [(validate.rules).int32 = {
+ lte: -15,
+ gte: -142
+ }];
+ }
}
message MACCommands {
@@ -1240,3 +1551,38 @@ message DeviceEIRPValue {
option (thethings.json.message) = {wrapper: true};
DeviceEIRP value = 1 [(validate.rules).enum.defined_only = true];
}
+
+message RelayForwardUplinkReq {
+ option (thethings.flags.message) = {
+ select: true,
+ set: true
+ };
+
+ DataRate data_rate = 1 [(validate.rules).message.required = true];
+ int32 snr = 2 [(validate.rules).int32 = {
+ lte: 11,
+ gte: -20
+ }];
+ int32 rssi = 3 [(validate.rules).int32 = {
+ lte: -15,
+ gte: -142
+ }];
+ RelayWORChannel wor_channel = 4 [(validate.rules).enum.defined_only = true];
+ uint64 frequency = 5 [(validate.rules).uint64.gte = 100000]; // Uplink channel frequency (Hz).
+ bytes raw_payload = 6;
+}
+
+message RelayForwardDownlinkReq {
+ option (thethings.flags.message) = {
+ select: true,
+ set: true
+ };
+
+ bytes raw_payload = 1;
+}
+
+message RelayUplinkToken {
+ EndDeviceIdentifiers ids = 1 [(validate.rules).message.required = true];
+ bytes session_key_id = 2;
+ uint32 full_f_cnt = 3;
+}
diff --git a/api/ttn/lorawan/v3/metadata.proto b/api/ttn/lorawan/v3/metadata.proto
index 141fab453a..fd9f16e9a8 100644
--- a/api/ttn/lorawan/v3/metadata.proto
+++ b/api/ttn/lorawan/v3/metadata.proto
@@ -24,6 +24,7 @@ import "thethings/flags/annotations.proto";
import "thethings/json/annotations.proto";
import "ttn/lorawan/v3/enums.proto";
import "ttn/lorawan/v3/identifiers.proto";
+import "ttn/lorawan/v3/lorawan.proto";
import "validate/validate.proto";
option go_package = "go.thethings.network/lorawan-stack/v3/pkg/ttnpb";
@@ -33,6 +34,7 @@ option go_package = "go.thethings.network/lorawan-stack/v3/pkg/ttnpb";
message RxMetadata {
GatewayIdentifiers gateway_ids = 1 [(validate.rules).message.required = true];
PacketBrokerMetadata packet_broker = 18;
+ RelayMetadata relay = 23;
uint32 antenna_index = 2;
// Timestamp at the end of the transmission, provided by the gateway. The accuracy is undefined.
@@ -79,7 +81,7 @@ message RxMetadata {
// - field names are written in snake_case
google.protobuf.Struct advanced = 99;
- // next: 23
+ // next: 24
}
message Location {
@@ -213,3 +215,13 @@ message PacketBrokerRouteHop {
// Receiver agent.
string receiver_agent = 5;
}
+
+message RelayMetadata {
+ // End device identifiers of the relay.
+ string device_id = 1 [(validate.rules).string = {
+ pattern: "^[a-z0-9](?:[-]?[a-z0-9]){2,}$",
+ max_len: 36
+ }];
+ // Wake on radio channel.
+ RelayWORChannel wor_channel = 2 [(validate.rules).enum.defined_only = true];
+}
diff --git a/config/messages.json b/config/messages.json
index 9f89f6d34a..7e578d2124 100644
--- a/config/messages.json
+++ b/config/messages.json
@@ -152,6 +152,69 @@
"file": "i18n.go"
}
},
+ "enum:CID_RELAY_CONF": {
+ "translations": {
+ "en": "relay configuration"
+ },
+ "description": {
+ "package": "pkg/ttnpb",
+ "file": "i18n.go"
+ }
+ },
+ "enum:CID_RELAY_CONFIGURE_FWD_LIMIT": {
+ "translations": {
+ "en": "manage uplink forwarding limits"
+ },
+ "description": {
+ "package": "pkg/ttnpb",
+ "file": "i18n.go"
+ }
+ },
+ "enum:CID_RELAY_CTRL_UPLINK_LIST": {
+ "translations": {
+ "en": "manage uplink forwarding rules"
+ },
+ "description": {
+ "package": "pkg/ttnpb",
+ "file": "i18n.go"
+ }
+ },
+ "enum:CID_RELAY_END_DEVICE_CONF": {
+ "translations": {
+ "en": "end device relay configuration"
+ },
+ "description": {
+ "package": "pkg/ttnpb",
+ "file": "i18n.go"
+ }
+ },
+ "enum:CID_RELAY_FILTER_LIST": {
+ "translations": {
+ "en": "manage join request forwarding rules"
+ },
+ "description": {
+ "package": "pkg/ttnpb",
+ "file": "i18n.go"
+ }
+ },
+ "enum:CID_RELAY_NOTIFY_NEW_END_DEVICE": {
+ "translations": {
+ "en": "new end device under relay"
+ },
+ "description": {
+ "package": "pkg/ttnpb",
+ "file": "i18n.go"
+ }
+ },
+ "enum:CID_RELAY_UPDATE_UPLINK_LIST": {
+ "translations": {
+ "en": "update uplink forwarding rules"
+ },
+ "description": {
+ "package": "pkg/ttnpb",
+ "file": "i18n.go"
+ }
+ },
"enum:CID_RESET": {
"translations": {
"en": "reset"
@@ -3509,6 +3572,60 @@
"file": "shared.go"
}
},
+ "error:pkg/console/internal/events/protocol:message_type": {
+ "translations": {
+ "en": "invalid message type `{type}`"
+ },
+ "description": {
+ "package": "pkg/console/internal/events/protocol",
+ "file": "protocol.go"
+ }
+ },
+ "error:pkg/console/internal/events/subscriptions:already_subscribed": {
+ "translations": {
+ "en": "already subscribed with ID `{id}`"
+ },
+ "description": {
+ "package": "pkg/console/internal/events/subscriptions",
+ "file": "subscriptions.go"
+ }
+ },
+ "error:pkg/console/internal/events/subscriptions:no_identifiers": {
+ "translations": {
+ "en": "no identifiers"
+ },
+ "description": {
+ "package": "pkg/console/internal/events/subscriptions",
+ "file": "subscriptions.go"
+ }
+ },
+ "error:pkg/console/internal/events/subscriptions:not_subscribed": {
+ "translations": {
+ "en": "not subscribed with ID `{id}`"
+ },
+ "description": {
+ "package": "pkg/console/internal/events/subscriptions",
+ "file": "subscriptions.go"
+ }
+ },
+ "error:pkg/console/internal/events:rate_exceeded": {
+ "translations": {
+ "en": "request rate exceeded"
+ },
+ "description": {
+ "package": "pkg/console/internal/events",
+ "file": "ratelimit.go"
+ }
+ },
+ "error:pkg/console/internal/events:unknown_caller": {
+ "translations": {
+ "en": "unknown caller type `{type}`"
+ },
+ "description": {
+ "package": "pkg/console/internal/events",
+ "file": "ratelimit.go"
+ }
+ },
"error:pkg/crypto/cryptoservices:no_app_key": {
"translations": {
"en": "no AppKey specified"
@@ -4382,67 +4499,67 @@
"file": "conversion.go"
}
},
- "error:pkg/events/grpc:invalid_regexp": {
+ "error:pkg/events/grpc:no_identifiers": {
"translations": {
- "en": "invalid regexp"
+ "en": "no identifiers"
},
"description": {
"package": "pkg/events/grpc",
"file": "grpc.go"
}
},
- "error:pkg/events/grpc:no_identifiers": {
+ "error:pkg/events/grpc:storage_disabled": {
"translations": {
- "en": "no identifiers"
+ "en": "events storage is not not enabled"
},
"description": {
"package": "pkg/events/grpc",
"file": "grpc.go"
}
},
- "error:pkg/events/grpc:no_matching_events": {
+ "error:pkg/events/redis:channel_closed": {
"translations": {
- "en": "no matching events for regexp `{regexp}`"
+ "en": "channel closed"
},
"description": {
- "package": "pkg/events/grpc",
- "file": "grpc.go"
+ "package": "pkg/events/redis",
+ "file": "redis.go"
}
},
- "error:pkg/events/grpc:storage_disabled": {
+ "error:pkg/events/redis:unknown_encoding": {
"translations": {
- "en": "events storage is not not enabled"
+ "en": "unknown encoding"
},
"description": {
- "package": "pkg/events/grpc",
- "file": "grpc.go"
+ "package": "pkg/events/redis",
+ "file": "codec.go"
}
},
- "error:pkg/events/grpc:unknown_event_name": {
+ "error:pkg/events:invalid_regexp": {
"translations": {
- "en": "unknown event `{name}`"
+ "en": "invalid regexp"
},
"description": {
- "package": "pkg/events/grpc",
- "file": "grpc.go"
+ "package": "pkg/events",
+ "file": "pattern.go"
}
},
- "error:pkg/events/redis:channel_closed": {
+ "error:pkg/events:no_matching_events": {
"translations": {
- "en": "channel closed"
+ "en": "no matching events for regexp `{regexp}`"
},
"description": {
- "package": "pkg/events/redis",
- "file": "redis.go"
+ "package": "pkg/events",
+ "file": "pattern.go"
}
},
- "error:pkg/events/redis:unknown_encoding": {
+ "error:pkg/events:unknown_event_name": {
"translations": {
- "en": "unknown encoding"
+ "en": "unknown event `{name}`"
},
"description": {
- "package": "pkg/events/redis",
- "file": "codec.go"
+ "package": "pkg/events",
+ "file": "pattern.go"
}
},
"error:pkg/fetch:fetch_file": {
@@ -7433,6 +7550,15 @@
"file": "registry.go"
}
},
+ "error:pkg/networkserver/redis:relay_served": {
+ "translations": {
+ "en": "`{served}` is already served by `{serving}`"
+ },
+ "description": {
+ "package": "pkg/networkserver/redis",
+ "file": "registry.go"
+ }
+ },
"error:pkg/networkserver:abp_join_request": {
"translations": {
"en": "received a join-request from ABP device"
@@ -7748,6 +7874,87 @@
"file": "grpc_gsns.go"
}
},
+ "error:pkg/networkserver:relay_full_f_cnt": {
+ "translations": {
+ "en": "invalid full FCnt"
+ },
+ "description": {
+ "package": "pkg/networkserver",
+ "file": "relay.go"
+ }
+ },
+ "error:pkg/networkserver:relay_m_type": {
+ "translations": {
+ "en": "invalid MType"
+ },
+ "description": {
+ "package": "pkg/networkserver",
+ "file": "relay.go"
+ }
+ },
+ "error:pkg/networkserver:relay_recent_uplinks": {
+ "translations": {
+ "en": "recent uplinks not found"
+ },
+ "description": {
+ "package": "pkg/networkserver",
+ "file": "relay.go"
+ }
+ },
+ "error:pkg/networkserver:relay_rx_windows_available": {
+ "translations": {
+ "en": "no RX windows available"
+ },
+ "description": {
+ "package": "pkg/networkserver",
+ "file": "relay.go"
+ }
+ },
+ "error:pkg/networkserver:relay_schedule": {
+ "translations": {
+ "en": "relay schedule"
+ },
+ "description": {
+ "package": "pkg/networkserver",
+ "file": "relay.go"
+ }
+ },
+ "error:pkg/networkserver:relay_serving": {
+ "translations": {
+ "en": "relay not serving"
+ },
+ "description": {
+ "package": "pkg/networkserver",
+ "file": "relay.go"
+ }
+ },
+ "error:pkg/networkserver:relay_session": {
+ "translations": {
+ "en": "relay session not found"
+ },
+ "description": {
+ "package": "pkg/networkserver",
+ "file": "relay.go"
+ }
+ },
+ "error:pkg/networkserver:relay_session_key_id": {
+ "translations": {
+ "en": "relay session key ID not found"
+ },
+ "description": {
+ "package": "pkg/networkserver",
+ "file": "relay.go"
+ }
+ },
+ "error:pkg/networkserver:relay_uplink_token": {
+ "translations": {
+ "en": "invalid relay uplink token"
+ },
+ "description": {
+ "package": "pkg/networkserver",
+ "file": "relay.go"
+ }
+ },
"error:pkg/networkserver:schedule": {
"translations": {
"en": "all downlink scheduling attempts failed"
@@ -10628,6 +10835,132 @@
"file": "rekey.go"
}
},
+ "event:ns.mac.relay_conf.answer.accept": {
+ "translations": {
+ "en": "relay configuration accept received"
+ },
+ "description": {
+ "package": "pkg/networkserver/mac",
+ "file": "relay_conf.go"
+ }
+ },
+ "event:ns.mac.relay_conf.answer.reject": {
+ "translations": {
+ "en": "relay configuration rejection received"
+ },
+ "description": {
+ "package": "pkg/networkserver/mac",
+ "file": "relay_conf.go"
+ }
+ },
+ "event:ns.mac.relay_conf.request": {
+ "translations": {
+ "en": "relay configuration request enqueued"
+ },
+ "description": {
+ "package": "pkg/networkserver/mac",
+ "file": "relay_conf.go"
+ }
+ },
+ "event:ns.mac.relay_configure_fwd_limit.answer": {
+ "translations": {
+ "en": "relay configure forward limit answer received"
+ },
+ "description": {
+ "package": "pkg/networkserver/mac",
+ "file": "relay_configure_fwd_limit.go"
+ }
+ },
+ "event:ns.mac.relay_configure_fwd_limit.request": {
+ "translations": {
+ "en": "relay configure forward limit request enqueued"
+ },
+ "description": {
+ "package": "pkg/networkserver/mac",
+ "file": "relay_configure_fwd_limit.go"
+ }
+ },
+ "event:ns.mac.relay_ctrl_uplink_list.answer.accept": {
+ "translations": {
+ "en": "relay control uplink list accept received"
+ },
+ "description": {
+ "package": "pkg/networkserver/mac",
+ "file": "relay_ctrl_uplink_list.go"
+ }
+ },
+ "event:ns.mac.relay_ctrl_uplink_list.answer.reject": {
+ "translations": {
+ "en": "relay control uplink list rejection received"
+ },
+ "description": {
+ "package": "pkg/networkserver/mac",
+ "file": "relay_ctrl_uplink_list.go"
+ }
+ },
+ "event:ns.mac.relay_ctrl_uplink_list.request": {
+ "translations": {
+ "en": "relay control uplink list request enqueued"
+ },
+ "description": {
+ "package": "pkg/networkserver/mac",
+ "file": "relay_ctrl_uplink_list.go"
+ }
+ },
+ "event:ns.mac.relay_end_device_conf.answer.accept": {
+ "translations": {
+ "en": "relay end device configuration accept received"
+ },
+ "description": {
+ "package": "pkg/networkserver/mac",
+ "file": "relay_end_device_conf.go"
+ }
+ },
+ "event:ns.mac.relay_end_device_conf.answer.reject": {
+ "translations": {
+ "en": "relay end device configuration rejection received"
+ },
+ "description": {
+ "package": "pkg/networkserver/mac",
+ "file": "relay_end_device_conf.go"
+ }
+ },
+ "event:ns.mac.relay_end_device_conf.request": {
+ "translations": {
+ "en": "relay end device configuration request enqueued"
+ },
+ "description": {
+ "package": "pkg/networkserver/mac",
+ "file": "relay_end_device_conf.go"
+ }
+ },
+ "event:ns.mac.relay_notify_new_end_device.indication": {
+ "translations": {
+ "en": "relay notify new end device indication received"
+ },
+ "description": {
+ "package": "pkg/networkserver/mac",
+ "file": "relay_notify_new_end_device.go"
+ }
+ },
+ "event:ns.mac.relay_update_uplink_list.answer": {
+ "translations": {
+ "en": "relay update uplink list answer received"
+ },
+ "description": {
+ "package": "pkg/networkserver/mac",
+ "file": "relay_update_uplink_list.go"
+ }
+ },
+ "event:ns.mac.relay_update_uplink_list.request": {
+ "translations": {
+ "en": "relay update uplink list request enqueued"
+ },
+ "description": {
+ "package": "pkg/networkserver/mac",
+ "file": "relay_update_uplink_list.go"
+ }
+ },
"event:ns.mac.reset.confirmation": {
"translations": {
"en": "device reset confirmation enqueued"
@@ -10835,6 +11168,24 @@
"file": "observability.go"
}
},
+ "event:ns.up.relay.drop": {
+ "translations": {
+ "en": "drop relay message"
+ },
+ "description": {
+ "package": "pkg/networkserver",
+ "file": "observability.go"
+ }
+ },
+ "event:ns.up.relay.process": {
+ "translations": {
+ "en": "successfully processed relay message"
+ },
+ "description": {
+ "package": "pkg/networkserver",
+ "file": "observability.go"
+ }
+ },
"event:oauth.authorize": {
"translations": {
"en": "authorize OAuth client"
diff --git a/config/storybook/preview.js b/config/storybook/preview.js
index 6233b087ed..4483cb7cff 100644
--- a/config/storybook/preview.js
+++ b/config/storybook/preview.js
@@ -23,27 +23,22 @@ import { createMemoryHistory } from 'history'
import messages from '@ttn-lw/locales/en.json'
import backendMessages from '@ttn-lw/locales/.backend/en.json'
-import { EnvProvider } from '@ttn-lw/lib/components/env'
-
import '../../pkg/webui/styles/main.styl'
import 'focus-visible/dist/focus-visible'
import createStore from './store'
import Center from './center'
-import env from './env'
const history = createMemoryHistory()
const store = createStore(history)
export const decorators = [
Story => (
-
-
-
-
- {Story()}
-
-
-
-
+
+
+
+ {Story()}
+
+
+
),
]
diff --git a/config/webpack.config.babel.js b/config/webpack.config.babel.js
index 2281c7e473..4530e40b95 100644
--- a/config/webpack.config.babel.js
+++ b/config/webpack.config.babel.js
@@ -175,6 +175,7 @@ export default {
target: WEBPACK_DEV_SERVER_USE_TLS ? 'https://localhost:8885' : 'http://localhost:1885',
changeOrigin: true,
secure: false,
+ ws: true,
},
],
historyApiFallback: true,
diff --git a/cypress/e2e/console/admin-panel/packet-broker/networks.spec.js b/cypress/e2e/console/admin-panel/packet-broker/networks.spec.js
index db702ac160..e3a83f2526 100644
--- a/cypress/e2e/console/admin-panel/packet-broker/networks.spec.js
+++ b/cypress/e2e/console/admin-panel/packet-broker/networks.spec.js
@@ -45,7 +45,12 @@ describe('Packet Broker networks', () => {
cy.intercept('/api/v3/pba/home-networks/policies*', {
fixture: 'console/packet-broker/policies-home-network.json',
})
- cy.visit(`${Cypress.config('consoleRootPath')}/admin-panel/packet-broker/networks`)
+ cy.visit(
+ `${Cypress.config(
+ 'consoleRootPath',
+ )}/admin-panel/packet-broker/routing-configuration/networks`,
+ )
+ cy.findByLabelText('Use custom routing policies').check()
const { networks } = this.networks
const networksFiltered = networks.filter(
@@ -73,7 +78,11 @@ describe('Packet Broker networks', () => {
n => n.forwarder_id.net_id === 19 && n.forwarder_id.tenant_id === 'johan',
)
- cy.visit(`${Cypress.config('consoleRootPath')}/admin-panel/packet-broker/networks/19/johan`)
+ cy.visit(
+ `${Cypress.config(
+ 'consoleRootPath',
+ )}/admin-panel/packet-broker/routing-configuration/networks/19/johan`,
+ )
cy.findAllByText(`${network.id.net_id.toString(16).padStart(6, '0')}/${network.id.tenant_id}`)
cy.findByText(
diff --git a/cypress/e2e/console/admin-panel/packet-broker/registration.spec.js b/cypress/e2e/console/admin-panel/packet-broker/registration.spec.js
index 5f4afc5366..4bfd68d939 100644
--- a/cypress/e2e/console/admin-panel/packet-broker/registration.spec.js
+++ b/cypress/e2e/console/admin-panel/packet-broker/registration.spec.js
@@ -61,15 +61,15 @@ describe('Packet Broker registration', () => {
cy.visit(`${Cypress.config('consoleRootPath')}/admin-panel/packet-broker`)
cy.findByText('Packet Broker', { selector: 'h1' }).should('be.visible')
- cy.findByText(/Packet Broker can be used to exchange traffic/).should('be.visible')
- cy.findByText('Packet Broker documentation', { selector: 'a' }).should('be.visible')
+ cy.findByText(/Packet Broker is a service by The Things Industries/).should('be.visible')
+ cy.findByText('Packet Broker', { selector: 'a' }).should('be.visible')
cy.findByText('Packet Broker website', { selector: 'a' }).should('be.visible')
- cy.findByText('Register network', { selector: 'span' }).should('be.visible')
+ cy.findByText('Enable Packet Broker', { selector: 'span' }).should('be.visible')
cy.findByTestId('switch')
.should('be.visible')
.and('not.be.checked')
.and('not.have.attr', 'disabled')
- cy.findByText(/To enable peering/).should('be.visible')
+ cy.findByText(/Enabling will allow/).should('be.visible')
cy.findByText('Default routing policy').should('not.exist')
cy.findByText('Networks').should('not.exist')
@@ -89,18 +89,20 @@ describe('Packet Broker registration', () => {
cy.loginConsole({ user_id: 'admin', password: 'admin' })
cy.visit(`${Cypress.config('consoleRootPath')}/admin-panel/packet-broker`)
- cy.findByText('Register network').click()
- cy.findByText('Register network').next().findByTestId('switch').should('be.checked')
- cy.findByText('List network publicly')
+ cy.findByText('Enable Packet Broker').click()
+ cy.findByText('Enable Packet Broker').next().findByTestId('switch').should('be.checked')
+ cy.findByText('List my network in Packet Broker publicly')
.should('be.visible')
.next()
.findByTestId('switch')
.should('be.checked')
- cy.findByTestId('feature-info-forwarder-enabled').should('be.visible')
- cy.findByTestId('feature-info-home-network-enabled').should('be.visible')
- cy.findByTestId('tabs').findByText('Default routing policy').should('be.visible')
- cy.findByTestId('tabs').findByText('Networks').should('be.visible')
- cy.findByLabelText('Do not use a default routing policy for this network').should('be.checked')
+ cy.findByLabelText('Forward traffic to all networks registered in Packet Broker').should(
+ 'exist',
+ )
+ cy.findByLabelText(
+ 'Forward traffic to The Things Stack Sandbox (community network) only',
+ ).should('exist')
+ cy.findByLabelText('Use custom routing policies').should('exist')
cy.findByTestId('error-notification').should('not.exist')
})
diff --git a/cypress/e2e/console/admin-panel/packet-broker/routing-policies.spec.js b/cypress/e2e/console/admin-panel/packet-broker/routing-policies.spec.js
index 9b9f519f12..be0fee18a5 100644
--- a/cypress/e2e/console/admin-panel/packet-broker/routing-policies.spec.js
+++ b/cypress/e2e/console/admin-panel/packet-broker/routing-policies.spec.js
@@ -32,12 +32,63 @@ describe('Packet Broker routing policies', () => {
cy.loginConsole({ user_id: 'admin', password: 'admin' })
})
- it('succeeds setting a default routing policy', () => {
+ it('succeeds setting a "traffic to all networks" routing configuration', () => {
cy.intercept('GET', '/api/v3/pba/home-networks/policies/default', { statusCode: 404 })
cy.intercept('PUT', '/api/v3/pba/home-networks/policies/default', {})
+ cy.intercept('DELETE', '/api/v3/pba/home-networks/policies/19', {})
+ cy.intercept('DELETE', '/api/v3/pba/home-networks/policies/19/johan', {})
+ cy.intercept('/api/v3/pba/networks*', { fixture: 'console/packet-broker/networks.json' })
+ cy.intercept('/api/v3/pba/home-networks/policies*', {
+ fixture: 'console/packet-broker/policies-home-network.json',
+ })
cy.visit(`${Cypress.config('consoleRootPath')}/admin-panel/packet-broker`)
- cy.findByLabelText('Use default routing policy for this network').check()
+ cy.findByLabelText('Forward traffic to all networks registered in Packet Broker').check()
+ cy.findByRole('button', { name: 'Save routing configuration' }).click()
+
+ cy.findByTestId('error-notification').should('not.exist')
+ cy.findByTestId('toast-notification')
+ .should('be.visible')
+ .findByText('Default routing configuration set')
+ .should('be.visible')
+ })
+
+ it('succeeds setting a "only ttn" routing configuration', () => {
+ cy.intercept('GET', '/api/v3/pba/home-networks/policies/default', { statusCode: 404 })
+ cy.intercept('/api/v3/pba/networks*', { fixture: 'console/packet-broker/networks.json' })
+ cy.intercept('/api/v3/pba/home-networks/policies*', {
+ fixture: 'console/packet-broker/policies-home-network.json',
+ })
+ cy.intercept('DELETE', '/api/v3/pba/home-networks/policies/default', {})
+ cy.intercept('DELETE', '/api/v3/pba/home-networks/policies/19', {})
+ cy.intercept('DELETE', '/api/v3/pba/home-networks/policies/19/johan', {})
+ cy.intercept('PUT', '/api/v3/pba/home-networks/policies/19/ttn', {})
+ cy.visit(`${Cypress.config('consoleRootPath')}/admin-panel/packet-broker`)
+
+ cy.findByLabelText(
+ 'Forward traffic to The Things Stack Sandbox (community network) only',
+ ).check()
+ cy.findByRole('button', { name: 'Save routing configuration' }).click()
+
+ cy.findByTestId('error-notification').should('not.exist')
+ cy.findByTestId('toast-notification')
+ .should('be.visible')
+ .findByText('Default routing configuration set')
+ .should('be.visible')
+ })
+
+ it('succeeds setting a custom routing configuration with a default routing policy', () => {
+ cy.intercept('GET', '/api/v3/pba/home-networks/policies/default', {
+ fixture: 'console/packet-broker/default-policy.json',
+ })
+ cy.intercept('PUT', '/api/v3/pba/home-networks/policies/default', {})
+ cy.intercept('/api/v3/pba/networks*', { fixture: 'console/packet-broker/networks.json' })
+ cy.intercept('/api/v3/pba/home-networks/policies*', {
+ fixture: 'console/packet-broker/policies-home-network.json',
+ })
+ cy.visit(`${Cypress.config('consoleRootPath')}/admin-panel/packet-broker`)
+
+ cy.findByLabelText('Use custom routing policies').check()
// Check routing policy form checkboxes.
cy.findByText('Uplink')
@@ -56,30 +107,35 @@ describe('Packet Broker routing policies', () => {
cy.findByLabelText('MAC data').check()
cy.findByLabelText('Application data').check()
})
- cy.findByRole('button', { name: 'Save default policy' }).click()
+ cy.findByRole('button', { name: 'Save routing configuration' }).click()
cy.findByTestId('error-notification').should('not.exist')
cy.findByTestId('toast-notification')
.should('be.visible')
- .findByText('Default routing policy set')
+ .findByText('Default routing configuration set')
.should('be.visible')
})
it('succeeds unsetting a default routing policy', () => {
+ cy.intercept('PUT', '/api/v3/pba/home-networks/policies/default', {})
+ cy.intercept('/api/v3/pba/networks*', { fixture: 'console/packet-broker/networks.json' })
+ cy.intercept('/api/v3/pba/home-networks/policies*', {
+ fixture: 'console/packet-broker/policies-home-network.json',
+ })
cy.intercept('GET', '/api/v3/pba/home-networks/policies/default', {
- fixture: 'console/packet-broker/default-policy.json',
+ fixture: 'console/packet-broker/default-custom-policy.json',
})
cy.intercept('DELETE', '/api/v3/pba/home-networks/policies/default', {})
cy.visit(`${Cypress.config('consoleRootPath')}/admin-panel/packet-broker`)
cy.findByLabelText('Do not use a default routing policy for this network').check()
- cy.findByRole('button', { name: 'Save default policy' }).click()
+ cy.findByRole('button', { name: 'Save routing configuration' }).click()
cy.findByTestId('error-notification').should('not.exist')
cy.findByTestId('toast-notification')
.should('be.visible')
- .findByText('Default routing policy set')
+ .findByText('Default routing configuration set')
.should('be.visible')
})
@@ -93,7 +149,11 @@ describe('Packet Broker routing policies', () => {
})
cy.intercept('PUT', '/api/v3/pba/home-networks/policies/19', {})
- cy.visit(`${Cypress.config('consoleRootPath')}/admin-panel/packet-broker/networks/19`)
+ cy.visit(
+ `${Cypress.config(
+ 'consoleRootPath',
+ )}/admin-panel/packet-broker/routing-configuration/networks/19`,
+ )
// Check routing policy form checkboxes.
cy.findByLabelText('Use network specific routing policy').check()
@@ -138,7 +198,11 @@ describe('Packet Broker routing policies', () => {
})
cy.intercept('DELETE', '/api/v3/pba/home-networks/policies/19', {})
- cy.visit(`${Cypress.config('consoleRootPath')}/admin-panel/packet-broker/networks/19`)
+ cy.visit(
+ `${Cypress.config(
+ 'consoleRootPath',
+ )}/admin-panel/packet-broker/routing-configuration/networks/19`,
+ )
cy.findByLabelText('Do not use a routing policy for this network').check()
cy.findByRole('button', { name: 'Save routing policy' }).click()
@@ -161,7 +225,11 @@ describe('Packet Broker routing policies', () => {
})
cy.intercept('DELETE', '/api/v3/pba/home-networks/policies/19', {})
- cy.visit(`${Cypress.config('consoleRootPath')}/admin-panel/packet-broker/networks/19`)
+ cy.visit(
+ `${Cypress.config(
+ 'consoleRootPath',
+ )}/admin-panel/packet-broker/routing-configuration/networks/19`,
+ )
cy.findByLabelText('Use default routing policy for this network').check()
cy.findByRole('button', { name: 'Save routing policy' }).click()
diff --git a/cypress/e2e/console/gateways/create.spec.js b/cypress/e2e/console/gateways/create.spec.js
index c532680428..bc9ca5843d 100644
--- a/cypress/e2e/console/gateways/create.spec.js
+++ b/cypress/e2e/console/gateways/create.spec.js
@@ -159,7 +159,12 @@ describe('Gateway create', () => {
.first()
.selectOption(gateway.frequency_plan)
cy.findByRole('button', { name: /Add frequency plan/ }).click()
- cy.findByText('Frequency plan').parent().parent().find('input').eq(2).selectOption('US_902_928')
+ cy.findByText('Frequency plan')
+ .parent()
+ .parent()
+ .find('input')
+ .eq(2)
+ .selectOption('EU_863_870_TTN')
cy.findByRole('button', { name: 'Register gateway' }).click()
cy.findByTestId('error-notification').should('not.exist')
@@ -169,7 +174,7 @@ describe('Gateway create', () => {
)
cy.findByRole('heading', { name: `eui-${gateway.eui}` })
cy.findByText('Frequency plan')
- cy.findByText('EU_863_870 , US_902_928_FSB_1').should('be.visible')
+ cy.findByText('EU_863_870 , EU_863_870_TTN').should('be.visible')
cy.findByTestId('error-notification').should('not.exist')
})
diff --git a/cypress/e2e/console/gateways/edit.spec.js b/cypress/e2e/console/gateways/edit.spec.js
index a7552e1128..4a6eba6a3e 100644
--- a/cypress/e2e/console/gateways/edit.spec.js
+++ b/cypress/e2e/console/gateways/edit.spec.js
@@ -294,7 +294,7 @@ describe('Gateway general settings', () => {
})
it('succeeds editing multiple frequency plans', () => {
- const newFrequencyPlan = 'Asia 920-923 MHz'
+ const newFrequencyPlan = 'Europe 863-870 MHz, 6 channels for roaming (Draft)'
cy.loginConsole({ user_id: user.ids.user_id, password: user.password })
cy.visit(
`${Cypress.config('consoleRootPath')}/gateways/${gateway2.ids.gateway_id}/general-settings`,
diff --git a/cypress/e2e/console/integrations/pub-subs/create.spec.js b/cypress/e2e/console/integrations/pub-subs/create.spec.js
index 3d8983ffb6..78f4616d4e 100644
--- a/cypress/e2e/console/integrations/pub-subs/create.spec.js
+++ b/cypress/e2e/console/integrations/pub-subs/create.spec.js
@@ -323,4 +323,85 @@ describe('Application Pub/Sub create', () => {
})
})
})
+
+ describe('Disabled Providers', () => {
+ const description = 'Changing the Pub/Sub provider has been disabled by an administrator'
+
+ describe('NATS disabled', () => {
+ const response = {
+ configuration: {
+ pubsub: {
+ providers: {
+ nats: 'DISABLED',
+ },
+ },
+ },
+ }
+
+ beforeEach(() => {
+ cy.loginConsole({ user_id: userId, password: user.password })
+ cy.visit(
+ `${Cypress.config('consoleRootPath')}/applications/${appId}/integrations/pubsubs/add`,
+ )
+
+ cy.intercept('GET', `/api/v3/as/configuration`, response)
+ })
+ it('succeeds setting MQTT as default provider', () => {
+ cy.findByLabelText('NATS').should('be.disabled')
+ cy.findByText(description).should('be.visible')
+ })
+ })
+
+ describe('MQTT disabled', () => {
+ const description = 'Changing the Pub/Sub provider has been disabled by an administrator'
+ const response = {
+ configuration: {
+ pubsub: {
+ providers: {
+ mqtt: 'DISABLED',
+ },
+ },
+ },
+ }
+
+ beforeEach(() => {
+ cy.loginConsole({ user_id: userId, password: user.password })
+ cy.visit(
+ `${Cypress.config('consoleRootPath')}/applications/${appId}/integrations/pubsubs/add`,
+ )
+ cy.intercept('GET', `/api/v3/as/configuration`, response)
+ })
+
+ it('succeeds setting NATS as default provider', () => {
+ cy.findByLabelText('MQTT').should('be.disabled')
+ cy.findByText(description).should('be.visible')
+ })
+ })
+
+ describe('MQTT and NATS disabled', () => {
+ const response = {
+ configuration: {
+ pubsub: {
+ providers: {
+ mqtt: 'DISABLED',
+ nats: 'DISABLED',
+ },
+ },
+ },
+ }
+
+ beforeEach(() => {
+ cy.loginConsole({ user_id: userId, password: user.password })
+ cy.on('uncaught:exception', () => false)
+ cy.visit(
+ `${Cypress.config('consoleRootPath')}/applications/${appId}/integrations/pubsubs/add`,
+ )
+ cy.intercept('GET', `/api/v3/as/configuration`, response)
+ })
+
+ it('succeeds showing not found page', () => {
+ cy.findByRole('heading', { name: /Not found/ }).should('be.visible')
+ })
+ })
+ })
})
diff --git a/cypress/fixtures/console/packet-broker/default-custom-policy.json b/cypress/fixtures/console/packet-broker/default-custom-policy.json
new file mode 100644
index 0000000000..edd8728179
--- /dev/null
+++ b/cypress/fixtures/console/packet-broker/default-custom-policy.json
@@ -0,0 +1,11 @@
+{
+ "updated_at": "2021-06-21T12:09:26.810087Z",
+ "uplink": {
+ "join_request": true,
+ "mac_data": false,
+ "application_data": true,
+ "signal_quality": false,
+ "localization": false
+ },
+ "downlink": { "join_accept": true, "mac_data": false, "application_data": true }
+}
diff --git a/data/lorawan-devices b/data/lorawan-devices
index 341ea4c310..4413bd8a98 160000
--- a/data/lorawan-devices
+++ b/data/lorawan-devices
@@ -1 +1 @@
-Subproject commit 341ea4c310c02b020cbf7262f18c182ff46d42dc
+Subproject commit 4413bd8a98e752dad4fd906e4c49387a79a09f61
diff --git a/data/lorawan-frequency-plans b/data/lorawan-frequency-plans
index 6d3428a337..54d10835c5 160000
--- a/data/lorawan-frequency-plans
+++ b/data/lorawan-frequency-plans
@@ -1 +1 @@
-Subproject commit 6d3428a33761b2b4a5c15143d817cbf204929d84
+Subproject commit 54d10835c50a893b34cadd992df752e9eba6061e
diff --git a/data/lorawan-webhook-templates b/data/lorawan-webhook-templates
index 2c03558427..1142a2a668 160000
--- a/data/lorawan-webhook-templates
+++ b/data/lorawan-webhook-templates
@@ -1 +1 @@
-Subproject commit 2c0355842769995e3f1d304d004303d9671febe0
+Subproject commit 1142a2a66863c477ee027b147c67a0ca923f485a
diff --git a/go.mod b/go.mod
index 20ab02d6a5..1b7361d68f 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
module go.thethings.network/lorawan-stack/v3
-go 1.20
+go 1.21
// Use our fork of throttled/throttled/v2.
replace github.com/throttled/throttled/v2 => github.com/TheThingsIndustries/throttled/v2 v2.7.1-noredis
@@ -16,24 +16,24 @@ require (
github.com/TheThingsIndustries/protoc-gen-go-flags v1.2.0
github.com/TheThingsIndustries/protoc-gen-go-json v1.6.0
github.com/TheThingsNetwork/go-cayenne-lib v1.2.0
- github.com/aws/aws-sdk-go v1.45.19
+ github.com/aws/aws-sdk-go v1.47.1
github.com/blang/semver v3.5.1+incompatible
github.com/blevesearch/bleve v1.0.14
github.com/bluele/gcache v0.0.2
github.com/disintegration/imaging v1.6.2
- github.com/dop251/goja v0.0.0-20230828202809-3dbe69dd2b8e
+ github.com/dop251/goja v0.0.0-20231027120936-b396bb4c349d
github.com/dustin/go-humanize v1.0.1
github.com/eclipse/paho.mqtt.golang v1.4.4-0.20230810210351-7b759f1d9ddf
github.com/emersion/go-smtp v0.18.1
github.com/envoyproxy/protoc-gen-validate v1.0.2
- github.com/felixge/httpsnoop v1.0.3
- github.com/getsentry/sentry-go v0.24.1
+ github.com/felixge/httpsnoop v1.0.4
+ github.com/getsentry/sentry-go v0.25.0
github.com/golang/gddo v0.0.0-20210115222349-20d68f94ee1f
- github.com/google/go-cmp v0.5.9
- github.com/google/uuid v1.3.1
+ github.com/google/go-cmp v0.6.0
+ github.com/google/uuid v1.4.0
github.com/gorilla/csrf v1.7.1
github.com/gorilla/handlers v1.5.1
- github.com/gorilla/mux v1.8.0
+ github.com/gorilla/mux v1.8.1
github.com/gorilla/schema v1.2.0
github.com/gorilla/securecookie v1.1.1
github.com/gorilla/websocket v1.5.0
@@ -41,8 +41,8 @@ require (
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0
- github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0
- github.com/hellofresh/health-go/v5 v5.3.0
+ github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.2-0.20231120080707-5e5867a3a4b0
+ github.com/hellofresh/health-go/v5 v5.5.0
github.com/howeyc/gopass v0.0.0-20210920133722-c8aef6fb66ef
github.com/iancoleman/strcase v0.3.0
github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa
@@ -52,18 +52,20 @@ require (
github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056
github.com/json-iterator/go v1.1.12
github.com/jtacoma/uritemplates v1.0.0
+ github.com/klauspost/compress v1.17.2
github.com/kr/pretty v0.3.1
github.com/lib/pq v1.10.9
+ github.com/mileusna/useragent v1.3.4
github.com/mitchellh/mapstructure v1.5.0
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
- github.com/nats-io/nats-server/v2 v2.10.2
- github.com/nats-io/nats.go v1.30.2
+ github.com/nats-io/nats-server/v2 v2.10.4
+ github.com/nats-io/nats.go v1.31.0
github.com/oklog/ulid/v2 v2.1.0
github.com/openshift/osin v1.0.2-0.20220317075346-0f4d38c6e53f
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.17.0
- github.com/redis/go-redis/v9 v9.2.1
+ github.com/redis/go-redis/v9 v9.3.0
github.com/satori/go.uuid v1.2.0
github.com/sendgrid/sendgrid-go v3.13.0+incompatible
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
@@ -71,53 +73,54 @@ require (
github.com/spf13/cast v1.5.1
github.com/spf13/cobra v1.7.0
github.com/spf13/pflag v1.0.5
- github.com/spf13/viper v1.16.0
+ github.com/spf13/viper v1.17.0
github.com/throttled/throttled v2.2.5+incompatible
github.com/throttled/throttled/v2 v2.12.0
github.com/uptrace/bun v1.1.16
github.com/uptrace/bun/dialect/pgdialect v1.1.16
github.com/uptrace/bun/driver/pgdriver v1.1.16
- github.com/vmihailenco/msgpack/v5 v5.4.0
+ github.com/vmihailenco/msgpack/v5 v5.4.1
go.opencensus.io v0.24.0
- go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux v0.45.0
- go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.45.0
- go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0
- go.opentelemetry.io/otel v1.19.0
- go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0
- go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.19.0
- go.opentelemetry.io/otel/sdk v1.19.0
- go.opentelemetry.io/otel/trace v1.19.0
- go.packetbroker.org/api/iam v1.7.0
- go.packetbroker.org/api/iam/v2 v2.7.13
- go.packetbroker.org/api/mapping/v2 v2.1.32
- go.packetbroker.org/api/routing v1.8.23
- go.packetbroker.org/api/v3 v3.15.2
+ go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux v0.46.0
+ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.0
+ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.0
+ go.opentelemetry.io/otel v1.20.0
+ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0
+ go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.20.0
+ go.opentelemetry.io/otel/sdk v1.20.0
+ go.opentelemetry.io/otel/trace v1.20.0
+ go.packetbroker.org/api/iam v1.8.1
+ go.packetbroker.org/api/iam/v2 v2.9.0
+ go.packetbroker.org/api/mapping/v2 v2.3.0
+ go.packetbroker.org/api/routing v1.9.1
+ go.packetbroker.org/api/v3 v3.17.0
go.thethings.network/lorawan-application-payload v0.0.0-20220125153912-1198ff1e403e
go.thethings.network/lorawan-stack-legacy/v2 v2.1.0
go.uber.org/automaxprocs v1.5.3
go.uber.org/zap v1.26.0
gocloud.dev v0.34.0
gocloud.dev/pubsub/natspubsub v0.34.0
- golang.org/x/crypto v0.14.0
- golang.org/x/exp v0.0.0-20230905200255-921286631fa9
- golang.org/x/net v0.17.0
- golang.org/x/oauth2 v0.12.0
- golang.org/x/sync v0.3.0
- google.golang.org/genproto v0.0.0-20230911183012-2d3300fd4832
- google.golang.org/genproto/googleapis/api v0.0.0-20230911183012-2d3300fd4832
- google.golang.org/genproto/googleapis/rpc v0.0.0-20230911183012-2d3300fd4832
- google.golang.org/grpc v1.58.2
+ golang.org/x/crypto v0.15.0
+ golang.org/x/exp v0.0.0-20231006140011-7918f672742d
+ golang.org/x/net v0.18.0
+ golang.org/x/oauth2 v0.14.0
+ golang.org/x/sync v0.4.0
+ google.golang.org/genproto v0.0.0-20231030173426-d783a09b4405
+ google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17
+ google.golang.org/grpc v1.59.0
google.golang.org/protobuf v1.31.0
gopkg.in/mail.v2 v2.3.1
gopkg.in/square/go-jose.v2 v2.6.0
gopkg.in/yaml.v2 v2.4.0
+ nhooyr.io/websocket v1.8.10
)
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
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0 // indirect
@@ -172,11 +175,11 @@ require (
github.com/dlclark/regexp2 v1.7.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21 // indirect
- github.com/fsnotify/fsnotify v1.6.0 // indirect
+ github.com/fsnotify/fsnotify v1.7.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
@@ -186,9 +189,9 @@ require (
github.com/golang/snappy v0.0.4 // indirect
github.com/gomodule/redigo v1.8.9 // indirect
github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect
- github.com/google/s2a-go v0.1.4 // indirect
+ github.com/google/s2a-go v0.1.7 // 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/gotnospirit/makeplural v0.0.0-20180622080156-a5f48d94d976 // indirect
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3 // indirect
@@ -205,12 +208,11 @@ require (
github.com/jacobsa/reqtrace v0.0.0-20150505043853-245c9e0234cb // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
- github.com/klauspost/compress v1.17.0 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/kylelemons/godebug v1.1.0 // 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/minio/highwayhash v1.0.2 // indirect
github.com/mitchellh/copystructure v1.0.0 // indirect
github.com/mitchellh/reflectwalk v1.0.0 // indirect
@@ -218,46 +220,48 @@ require (
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/mschoch/smat v0.2.0 // indirect
github.com/nats-io/jwt/v2 v2.5.2 // indirect
- github.com/nats-io/nkeys v0.4.5 // indirect
+ github.com/nats-io/nkeys v0.4.6 // indirect
github.com/nats-io/nuid v1.0.1 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 // 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/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/rivo/uniseg v0.4.3 // indirect
github.com/rogpeppe/go-internal v1.10.0 // 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/sendgrid/rest v2.6.9+incompatible // indirect
github.com/shopspring/decimal v1.2.0 // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
github.com/smartystreets/assertions v1.13.1 // indirect
- github.com/spf13/afero v1.9.5 // indirect
- github.com/spf13/jwalterweatherman v1.1.0 // indirect
+ github.com/sourcegraph/conc v0.3.0 // indirect
+ github.com/spf13/afero v1.10.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/tinylib/msgp v1.1.0 // indirect
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
github.com/willf/bitset v1.1.11 // indirect
go.etcd.io/bbolt v1.3.6 // indirect
- go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 // indirect
- go.opentelemetry.io/otel/metric v1.19.0 // indirect
+ go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0 // indirect
+ go.opentelemetry.io/otel/metric v1.20.0 // indirect
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
- golang.org/x/image v0.5.0 // indirect
- golang.org/x/sys v0.13.0 // indirect
- golang.org/x/term v0.13.0 // indirect
- golang.org/x/text v0.13.0 // indirect
+ golang.org/x/image v0.10.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/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/api v0.143.0 // indirect
+ google.golang.org/appengine v1.6.8 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
diff --git a/go.sum b/go.sum
index fde42d7502..3b61876c02 100644
--- a/go.sum
+++ b/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=
@@ -96,10 +97,9 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF
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=
@@ -196,11 +198,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
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=
@@ -221,8 +220,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=
@@ -232,11 +232,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=
@@ -253,7 +254,6 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
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=
@@ -261,22 +261,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=
@@ -293,8 +294,8 @@ github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KE
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
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=
@@ -312,7 +313,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=
@@ -366,16 +366,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=
@@ -389,18 +392,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=
@@ -413,8 +416,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=
@@ -434,9 +437,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=
@@ -445,8 +447,8 @@ 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=
@@ -511,8 +513,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=
@@ -542,9 +544,12 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
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/maxatome/go-testdeep v1.12.0 h1:Ql7Go8Tg0C1D/uMMX59LAoYK7LffeJQ6X2T04nTH68g=
+github.com/maxatome/go-testdeep v1.12.0/go.mod h1:lPZc/HAcJMP92l7yI6TRz1aZN5URwUBUAfUNvrclaNM=
+github.com/mileusna/useragent v1.3.4 h1:MiuRRuvGjEie1+yZHO88UBYg8YBC/ddF6T7F56i3PCk=
+github.com/mileusna/useragent v1.3.4/go.mod h1:3d8TOmwL/5I8pJjyVDteHtgDGcefrFUX4ccGOMKNYYc=
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=
@@ -568,12 +573,12 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW
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/jwt/v2 v2.5.2/go.mod h1:24BeQtRwxRV8ruvC4CojXlx/WQ/VjuwlYiH+vu/+ibI=
-github.com/nats-io/nats-server/v2 v2.10.2 h1:2o/OOyc/dxeMCQtrF1V/9er0SU0A3LKhDlv/+rqreBM=
-github.com/nats-io/nats-server/v2 v2.10.2/go.mod h1:lzrskZ/4gyMAh+/66cCd+q74c6v7muBypzfWhP/MAaM=
-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/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=
@@ -595,11 +600,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/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
@@ -608,9 +614,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=
@@ -632,8 +640,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=
@@ -645,13 +653,12 @@ 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.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
@@ -660,6 +667,10 @@ github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncj
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=
@@ -680,10 +691,12 @@ github.com/smarty/assertions v1.15.1/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+
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=
@@ -694,16 +707,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=
@@ -722,11 +733,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=
@@ -746,8 +757,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/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
@@ -771,39 +783,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=
@@ -812,7 +823,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=
@@ -832,11 +844,10 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
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.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
-golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
+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=
@@ -847,13 +858,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=
@@ -876,6 +887,7 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
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/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=
@@ -917,10 +929,10 @@ 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.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
-golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+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=
@@ -934,8 +946,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=
@@ -949,8 +961,9 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
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.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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+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=
@@ -1009,17 +1022,16 @@ 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.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
-golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.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-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.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
-golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+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=
@@ -1031,8 +1043,9 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
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.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=
@@ -1091,6 +1104,7 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
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/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=
@@ -1117,16 +1131,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=
@@ -1152,7 +1167,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=
@@ -1167,12 +1181,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=
@@ -1187,15 +1201,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=
@@ -1233,7 +1244,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=
@@ -1254,6 +1264,8 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
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/package.json b/package.json
index e4621069d3..96ea55b742 100644
--- a/package.json
+++ b/package.json
@@ -1,12 +1,12 @@
{
"name": "ttn-stack",
- "version": "3.28.0",
+ "version": "3.28.2",
"description": "The Things Stack",
"main": "index.js",
"repository": "https://github.com/TheThingsNetwork/lorawan-stack.git",
"license": "Apache-2.0",
"devDependencies": {
- "@babel/cli": "^7.22.9",
+ "@babel/cli": "^7.23.0",
"@babel/core": "^7.22.5",
"@babel/eslint-parser": "^7.22.9",
"@babel/plugin-proposal-class-properties": "^7.18.6",
@@ -15,10 +15,10 @@
"@babel/plugin-transform-runtime": "^7.22.10",
"@babel/plugin-transform-spread": "^7.22.5",
"@babel/plugin-transform-strict-mode": "^7.22.5",
- "@babel/preset-env": "^7.22.5",
- "@babel/preset-react": "^7.22.5",
- "@babel/register": "^7.22.5",
- "@babel/runtime-corejs2": "^7.22.5",
+ "@babel/preset-env": "^7.23.2",
+ "@babel/preset-react": "^7.22.15",
+ "@babel/register": "^7.22.15",
+ "@babel/runtime-corejs2": "^7.23.5",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.11",
"@storybook/addon-actions": "^7.0.24",
"@storybook/addon-info": "6.0.0-alpha.2",
@@ -38,12 +38,12 @@
"cypress-file-upload": "^5.0.8",
"cypress-log-to-output": "^1.1.2",
"eslint": "^8.44.0",
- "eslint-config-prettier": "^8.8.0",
+ "eslint-config-prettier": "^9.0.0",
"eslint-config-ttn": "git+https://github.com/TheThingsNetwork/eslint-config-ttn.git#v1.4.0",
- "eslint-import-resolver-webpack": "^0.13.7",
+ "eslint-import-resolver-webpack": "^0.13.8",
"eslint-plugin-babel": "^5.3.1",
"eslint-plugin-cypress": "^2.15.1",
- "eslint-plugin-import": "^2.27.5",
+ "eslint-plugin-import": "^2.29.0",
"eslint-plugin-jest": "^27.2.3",
"eslint-plugin-jsdoc": "^46.8.2",
"eslint-plugin-prefer-arrow": "^1.2.3",
@@ -66,7 +66,7 @@
"stylint": "^2.0.0",
"stylus": "^0.59.0",
"stylus-loader": "^7.1.3",
- "wait-on": "^7.0.1",
+ "wait-on": "^7.2.0",
"webpack": "^5.88.2",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.15.1",
@@ -76,12 +76,12 @@
"dependencies": {
"@formatjs/intl-datetimeformat": "^6.10.0",
"@formatjs/intl-displaynames": "^6.5.0",
- "@formatjs/intl-listformat": "^7.4.0",
+ "@formatjs/intl-listformat": "^7.5.3",
"@formatjs/intl-locale": "^3.3.2",
"@formatjs/intl-numberformat": "^8.7.0",
- "@formatjs/intl-pluralrules": "^5.2.4",
+ "@formatjs/intl-pluralrules": "^5.2.7",
"@formatjs/intl-relativetimeformat": "^11.2.4",
- "@sentry/browser": "^7.57.0",
+ "@sentry/browser": "^7.77.0",
"@sentry/integrations": "^7.61.0",
"@tippyjs/react": "^4.2.6",
"autobind-decorator": "^2.4.0",
diff --git a/pkg/applicationserver/io/mqtt/mqtt.go b/pkg/applicationserver/io/mqtt/mqtt.go
index 4482171125..7193cbbda8 100644
--- a/pkg/applicationserver/io/mqtt/mqtt.go
+++ b/pkg/applicationserver/io/mqtt/mqtt.go
@@ -283,6 +283,6 @@ func (c *connection) deliver(pkt *packet.PublishPacket) {
"count", len(items.Downlinks),
)).Debug("Handle downlink messages")
if err := op(c.server, c.io.Context(), ids, items.Downlinks); err != nil {
- logger.WithError(err).Warn("Failed to handle downlink messages")
+ logger.WithError(err).Info("Failed to handle downlink messages")
}
}
diff --git a/pkg/applicationserver/io/pubsub/pubsub.go b/pkg/applicationserver/io/pubsub/pubsub.go
index 784d38e8d1..5864dff704 100644
--- a/pkg/applicationserver/io/pubsub/pubsub.go
+++ b/pkg/applicationserver/io/pubsub/pubsub.go
@@ -214,7 +214,7 @@ func (i *integration) handleDown(
"count", len(operation.Downlinks),
)).Debug("Handle downlink messages")
if err := op(i.server, ctx, operation.EndDeviceIds, operation.Downlinks); err != nil {
- logger.WithError(err).Warn("Failed to handle downlink messages")
+ logger.WithError(err).Info("Failed to handle downlink messages")
}
}
}
diff --git a/pkg/auth/rights/auth_info.go b/pkg/auth/rights/auth_info.go
index f6b59c71ab..1a7158ffd3 100644
--- a/pkg/auth/rights/auth_info.go
+++ b/pkg/auth/rights/auth_info.go
@@ -51,16 +51,14 @@ func AuthInfo(ctx context.Context) (authInfo *ttnpb.AuthInfoResponse, err error)
var errUnauthenticated = errors.DefineUnauthenticated("unauthenticated", "unauthenticated")
-// RequireAuthentication confirms if the authentication information within a context contains any rights, if so,
+// RequireAuthenticated confirms if the authentication information within a context contains any rights, if so,
// the request is considered to be authenticated.
-func RequireAuthentication(ctx context.Context) error {
- log.FromContext(ctx).Debug("Authenticate request")
+func RequireAuthenticated(ctx context.Context) error {
authInfo, err := AuthInfo(ctx)
if err != nil {
log.FromContext(ctx).WithError(err).Debug("Failed to validate authentication information")
return errUnauthenticated.WithCause(err)
}
-
if authInfo.GetAccessMethod() == nil && len(authInfo.GetUniversalRights().GetRights()) == 0 {
return errUnauthenticated.New()
}
diff --git a/pkg/band/channel_mask.go b/pkg/band/channel_mask.go
index 557bb12ee5..466bf14af0 100644
--- a/pkg/band/channel_mask.go
+++ b/pkg/band/channel_mask.go
@@ -17,8 +17,7 @@ package band
import (
"fmt"
"math"
-
- "golang.org/x/exp/slices"
+ "slices"
)
// ChMaskCntlPair pairs a ChMaskCntl with a mask.
diff --git a/pkg/band/rpc.go b/pkg/band/rpc.go
index bea9836e43..6349468428 100644
--- a/pkg/band/rpc.go
+++ b/pkg/band/rpc.go
@@ -16,9 +16,9 @@ package band
import (
"context"
+ "maps"
"go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
- "golang.org/x/exp/maps"
"google.golang.org/protobuf/types/known/durationpb"
"google.golang.org/protobuf/types/known/wrapperspb"
)
diff --git a/pkg/band/shared.go b/pkg/band/shared.go
index f2e64859ba..b33f055513 100644
--- a/pkg/band/shared.go
+++ b/pkg/band/shared.go
@@ -50,6 +50,9 @@ type SharedParameters struct {
RelayForwardDelay time.Duration
// RelayReceiveDelay is the default RxR window timing in seconds.
RelayReceiveDelay time.Duration
+ // ServedRelayBackoff is the default number of wake on radio attempts before sending the uplink message directly
+ // by a served relay device.
+ ServedRelayBackoff uint32
}
var (
@@ -68,6 +71,7 @@ var (
parameters := universalSharedParameters
parameters.RelayForwardDelay = 50 * time.Millisecond
parameters.RelayReceiveDelay = 18 * time.Second
+ parameters.ServedRelayBackoff = 8
return parameters
}()
)
diff --git a/pkg/band/testdata/AS_923_2_RP002_V1_0_1.json b/pkg/band/testdata/AS_923_2_RP002_V1_0_1.json
index 148f93c521..a3a59ca60e 100644
--- a/pkg/band/testdata/AS_923_2_RP002_V1_0_1.json
+++ b/pkg/band/testdata/AS_923_2_RP002_V1_0_1.json
@@ -704,6 +704,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/AS_923_2_RP002_V1_0_2.json b/pkg/band/testdata/AS_923_2_RP002_V1_0_2.json
index 95871aa4fd..a9962ab97f 100644
--- a/pkg/band/testdata/AS_923_2_RP002_V1_0_2.json
+++ b/pkg/band/testdata/AS_923_2_RP002_V1_0_2.json
@@ -704,6 +704,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/AS_923_2_RP002_V1_0_3.json b/pkg/band/testdata/AS_923_2_RP002_V1_0_3.json
index 95871aa4fd..a9962ab97f 100644
--- a/pkg/band/testdata/AS_923_2_RP002_V1_0_3.json
+++ b/pkg/band/testdata/AS_923_2_RP002_V1_0_3.json
@@ -704,6 +704,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/AS_923_2_RP002_V1_0_4.json b/pkg/band/testdata/AS_923_2_RP002_V1_0_4.json
index 5a14aa9fba..941f3da47a 100644
--- a/pkg/band/testdata/AS_923_2_RP002_V1_0_4.json
+++ b/pkg/band/testdata/AS_923_2_RP002_V1_0_4.json
@@ -710,6 +710,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/AS_923_3_RP002_V1_0_1.json b/pkg/band/testdata/AS_923_3_RP002_V1_0_1.json
index 2225b47f38..79424d1fa7 100644
--- a/pkg/band/testdata/AS_923_3_RP002_V1_0_1.json
+++ b/pkg/band/testdata/AS_923_3_RP002_V1_0_1.json
@@ -704,6 +704,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/AS_923_3_RP002_V1_0_2.json b/pkg/band/testdata/AS_923_3_RP002_V1_0_2.json
index 216cba2bd3..d18d7aa61c 100644
--- a/pkg/band/testdata/AS_923_3_RP002_V1_0_2.json
+++ b/pkg/band/testdata/AS_923_3_RP002_V1_0_2.json
@@ -704,6 +704,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/AS_923_3_RP002_V1_0_3.json b/pkg/band/testdata/AS_923_3_RP002_V1_0_3.json
index 216cba2bd3..d18d7aa61c 100644
--- a/pkg/band/testdata/AS_923_3_RP002_V1_0_3.json
+++ b/pkg/band/testdata/AS_923_3_RP002_V1_0_3.json
@@ -704,6 +704,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/AS_923_3_RP002_V1_0_4.json b/pkg/band/testdata/AS_923_3_RP002_V1_0_4.json
index 7c807fc6c1..d8448f4bdc 100644
--- a/pkg/band/testdata/AS_923_3_RP002_V1_0_4.json
+++ b/pkg/band/testdata/AS_923_3_RP002_V1_0_4.json
@@ -710,6 +710,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/AS_923_4_RP002_V1_0_3.json b/pkg/band/testdata/AS_923_4_RP002_V1_0_3.json
index 34ebdccd6a..9624681bbd 100644
--- a/pkg/band/testdata/AS_923_4_RP002_V1_0_3.json
+++ b/pkg/band/testdata/AS_923_4_RP002_V1_0_3.json
@@ -704,6 +704,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/AS_923_4_RP002_V1_0_4.json b/pkg/band/testdata/AS_923_4_RP002_V1_0_4.json
index 81a73c316f..d3ee567912 100644
--- a/pkg/band/testdata/AS_923_4_RP002_V1_0_4.json
+++ b/pkg/band/testdata/AS_923_4_RP002_V1_0_4.json
@@ -710,6 +710,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/AS_923_PHY_V1_0_2_REV_A.json b/pkg/band/testdata/AS_923_PHY_V1_0_2_REV_A.json
index 6b1e7d3ab2..e82567b9ba 100644
--- a/pkg/band/testdata/AS_923_PHY_V1_0_2_REV_A.json
+++ b/pkg/band/testdata/AS_923_PHY_V1_0_2_REV_A.json
@@ -702,6 +702,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/AS_923_PHY_V1_0_2_REV_B.json b/pkg/band/testdata/AS_923_PHY_V1_0_2_REV_B.json
index 605ed7a850..fbca3c42f4 100644
--- a/pkg/band/testdata/AS_923_PHY_V1_0_2_REV_B.json
+++ b/pkg/band/testdata/AS_923_PHY_V1_0_2_REV_B.json
@@ -704,6 +704,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/AS_923_PHY_V1_0_3_REV_A.json b/pkg/band/testdata/AS_923_PHY_V1_0_3_REV_A.json
index b7a6ff28a4..1f9387e2e7 100644
--- a/pkg/band/testdata/AS_923_PHY_V1_0_3_REV_A.json
+++ b/pkg/band/testdata/AS_923_PHY_V1_0_3_REV_A.json
@@ -704,6 +704,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/AS_923_PHY_V1_1_REV_A.json b/pkg/band/testdata/AS_923_PHY_V1_1_REV_A.json
index ff9c341f44..b76cf6e26d 100644
--- a/pkg/band/testdata/AS_923_PHY_V1_1_REV_A.json
+++ b/pkg/band/testdata/AS_923_PHY_V1_1_REV_A.json
@@ -704,6 +704,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/AS_923_PHY_V1_1_REV_B.json b/pkg/band/testdata/AS_923_PHY_V1_1_REV_B.json
index ff9c341f44..b76cf6e26d 100644
--- a/pkg/band/testdata/AS_923_PHY_V1_1_REV_B.json
+++ b/pkg/band/testdata/AS_923_PHY_V1_1_REV_B.json
@@ -704,6 +704,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/AS_923_RP002_V1_0_0.json b/pkg/band/testdata/AS_923_RP002_V1_0_0.json
index 1438310426..a2a6279be9 100644
--- a/pkg/band/testdata/AS_923_RP002_V1_0_0.json
+++ b/pkg/band/testdata/AS_923_RP002_V1_0_0.json
@@ -704,6 +704,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/AS_923_RP002_V1_0_1.json b/pkg/band/testdata/AS_923_RP002_V1_0_1.json
index 06aa40f691..0d02d8ec54 100644
--- a/pkg/band/testdata/AS_923_RP002_V1_0_1.json
+++ b/pkg/band/testdata/AS_923_RP002_V1_0_1.json
@@ -704,6 +704,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/AS_923_RP002_V1_0_2.json b/pkg/band/testdata/AS_923_RP002_V1_0_2.json
index dbb9e721cc..296673a2cb 100644
--- a/pkg/band/testdata/AS_923_RP002_V1_0_2.json
+++ b/pkg/band/testdata/AS_923_RP002_V1_0_2.json
@@ -704,6 +704,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/AS_923_RP002_V1_0_3.json b/pkg/band/testdata/AS_923_RP002_V1_0_3.json
index dbb9e721cc..296673a2cb 100644
--- a/pkg/band/testdata/AS_923_RP002_V1_0_3.json
+++ b/pkg/band/testdata/AS_923_RP002_V1_0_3.json
@@ -704,6 +704,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/AS_923_RP002_V1_0_4.json b/pkg/band/testdata/AS_923_RP002_V1_0_4.json
index c4b1d0e88b..d467150f24 100644
--- a/pkg/band/testdata/AS_923_RP002_V1_0_4.json
+++ b/pkg/band/testdata/AS_923_RP002_V1_0_4.json
@@ -710,6 +710,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/AU_915_928_PHY_V1_0_1.json b/pkg/band/testdata/AU_915_928_PHY_V1_0_1.json
index 4ef3e12a72..458544cdf9 100644
--- a/pkg/band/testdata/AU_915_928_PHY_V1_0_1.json
+++ b/pkg/band/testdata/AU_915_928_PHY_V1_0_1.json
@@ -926,6 +926,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/AU_915_928_PHY_V1_0_2_REV_A.json b/pkg/band/testdata/AU_915_928_PHY_V1_0_2_REV_A.json
index 4ef3e12a72..458544cdf9 100644
--- a/pkg/band/testdata/AU_915_928_PHY_V1_0_2_REV_A.json
+++ b/pkg/band/testdata/AU_915_928_PHY_V1_0_2_REV_A.json
@@ -926,6 +926,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/AU_915_928_PHY_V1_0_2_REV_B.json b/pkg/band/testdata/AU_915_928_PHY_V1_0_2_REV_B.json
index 7cf26b684b..f014ff4ef6 100644
--- a/pkg/band/testdata/AU_915_928_PHY_V1_0_2_REV_B.json
+++ b/pkg/band/testdata/AU_915_928_PHY_V1_0_2_REV_B.json
@@ -996,6 +996,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/AU_915_928_PHY_V1_0_3_REV_A.json b/pkg/band/testdata/AU_915_928_PHY_V1_0_3_REV_A.json
index 1788de6c0c..1f7963c8d1 100644
--- a/pkg/band/testdata/AU_915_928_PHY_V1_0_3_REV_A.json
+++ b/pkg/band/testdata/AU_915_928_PHY_V1_0_3_REV_A.json
@@ -1001,6 +1001,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/AU_915_928_PHY_V1_1_REV_A.json b/pkg/band/testdata/AU_915_928_PHY_V1_1_REV_A.json
index e3b781c489..f28337549a 100644
--- a/pkg/band/testdata/AU_915_928_PHY_V1_1_REV_A.json
+++ b/pkg/band/testdata/AU_915_928_PHY_V1_1_REV_A.json
@@ -996,6 +996,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/AU_915_928_PHY_V1_1_REV_B.json b/pkg/band/testdata/AU_915_928_PHY_V1_1_REV_B.json
index 8002cd9bdf..7915097c01 100644
--- a/pkg/band/testdata/AU_915_928_PHY_V1_1_REV_B.json
+++ b/pkg/band/testdata/AU_915_928_PHY_V1_1_REV_B.json
@@ -1000,6 +1000,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/AU_915_928_RP002_V1_0_0.json b/pkg/band/testdata/AU_915_928_RP002_V1_0_0.json
index bdeb1bab4d..c55aaf1083 100644
--- a/pkg/band/testdata/AU_915_928_RP002_V1_0_0.json
+++ b/pkg/band/testdata/AU_915_928_RP002_V1_0_0.json
@@ -1000,6 +1000,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/AU_915_928_RP002_V1_0_1.json b/pkg/band/testdata/AU_915_928_RP002_V1_0_1.json
index bdeb1bab4d..c55aaf1083 100644
--- a/pkg/band/testdata/AU_915_928_RP002_V1_0_1.json
+++ b/pkg/band/testdata/AU_915_928_RP002_V1_0_1.json
@@ -1000,6 +1000,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/AU_915_928_RP002_V1_0_2.json b/pkg/band/testdata/AU_915_928_RP002_V1_0_2.json
index fadd6835c4..2e76cd6dbf 100644
--- a/pkg/band/testdata/AU_915_928_RP002_V1_0_2.json
+++ b/pkg/band/testdata/AU_915_928_RP002_V1_0_2.json
@@ -1024,6 +1024,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/AU_915_928_RP002_V1_0_3.json b/pkg/band/testdata/AU_915_928_RP002_V1_0_3.json
index fadd6835c4..2e76cd6dbf 100644
--- a/pkg/band/testdata/AU_915_928_RP002_V1_0_3.json
+++ b/pkg/band/testdata/AU_915_928_RP002_V1_0_3.json
@@ -1024,6 +1024,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/AU_915_928_RP002_V1_0_4.json b/pkg/band/testdata/AU_915_928_RP002_V1_0_4.json
index 1b667b7ff2..439dbbb64a 100644
--- a/pkg/band/testdata/AU_915_928_RP002_V1_0_4.json
+++ b/pkg/band/testdata/AU_915_928_RP002_V1_0_4.json
@@ -1035,6 +1035,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_470_510_20_A_RP002_V1_0_0.json b/pkg/band/testdata/CN_470_510_20_A_RP002_V1_0_0.json
index a567d79d4a..a5e04ad0a9 100644
--- a/pkg/band/testdata/CN_470_510_20_A_RP002_V1_0_0.json
+++ b/pkg/band/testdata/CN_470_510_20_A_RP002_V1_0_0.json
@@ -1112,6 +1112,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_470_510_20_A_RP002_V1_0_1.json b/pkg/band/testdata/CN_470_510_20_A_RP002_V1_0_1.json
index b83df34329..7cc8968f9f 100644
--- a/pkg/band/testdata/CN_470_510_20_A_RP002_V1_0_1.json
+++ b/pkg/band/testdata/CN_470_510_20_A_RP002_V1_0_1.json
@@ -1123,6 +1123,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_470_510_20_A_RP002_V1_0_2.json b/pkg/band/testdata/CN_470_510_20_A_RP002_V1_0_2.json
index b83df34329..7cc8968f9f 100644
--- a/pkg/band/testdata/CN_470_510_20_A_RP002_V1_0_2.json
+++ b/pkg/band/testdata/CN_470_510_20_A_RP002_V1_0_2.json
@@ -1123,6 +1123,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_470_510_20_A_RP002_V1_0_3.json b/pkg/band/testdata/CN_470_510_20_A_RP002_V1_0_3.json
index b83df34329..7cc8968f9f 100644
--- a/pkg/band/testdata/CN_470_510_20_A_RP002_V1_0_3.json
+++ b/pkg/band/testdata/CN_470_510_20_A_RP002_V1_0_3.json
@@ -1123,6 +1123,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_470_510_20_A_RP002_V1_0_4.json b/pkg/band/testdata/CN_470_510_20_A_RP002_V1_0_4.json
index d5cb59ec05..d21130bf3f 100644
--- a/pkg/band/testdata/CN_470_510_20_A_RP002_V1_0_4.json
+++ b/pkg/band/testdata/CN_470_510_20_A_RP002_V1_0_4.json
@@ -1134,6 +1134,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_470_510_20_B_RP002_V1_0_0.json b/pkg/band/testdata/CN_470_510_20_B_RP002_V1_0_0.json
index d936ca0894..83d3951c91 100644
--- a/pkg/band/testdata/CN_470_510_20_B_RP002_V1_0_0.json
+++ b/pkg/band/testdata/CN_470_510_20_B_RP002_V1_0_0.json
@@ -1112,6 +1112,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_470_510_20_B_RP002_V1_0_1.json b/pkg/band/testdata/CN_470_510_20_B_RP002_V1_0_1.json
index 072560ec75..eef8240003 100644
--- a/pkg/band/testdata/CN_470_510_20_B_RP002_V1_0_1.json
+++ b/pkg/band/testdata/CN_470_510_20_B_RP002_V1_0_1.json
@@ -1123,6 +1123,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_470_510_20_B_RP002_V1_0_2.json b/pkg/band/testdata/CN_470_510_20_B_RP002_V1_0_2.json
index 072560ec75..eef8240003 100644
--- a/pkg/band/testdata/CN_470_510_20_B_RP002_V1_0_2.json
+++ b/pkg/band/testdata/CN_470_510_20_B_RP002_V1_0_2.json
@@ -1123,6 +1123,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_470_510_20_B_RP002_V1_0_3.json b/pkg/band/testdata/CN_470_510_20_B_RP002_V1_0_3.json
index 072560ec75..eef8240003 100644
--- a/pkg/band/testdata/CN_470_510_20_B_RP002_V1_0_3.json
+++ b/pkg/band/testdata/CN_470_510_20_B_RP002_V1_0_3.json
@@ -1123,6 +1123,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_470_510_20_B_RP002_V1_0_4.json b/pkg/band/testdata/CN_470_510_20_B_RP002_V1_0_4.json
index d7a4520ad2..08331c33e3 100644
--- a/pkg/band/testdata/CN_470_510_20_B_RP002_V1_0_4.json
+++ b/pkg/band/testdata/CN_470_510_20_B_RP002_V1_0_4.json
@@ -1134,6 +1134,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_470_510_26_A_RP002_V1_0_0.json b/pkg/band/testdata/CN_470_510_26_A_RP002_V1_0_0.json
index f754cec1cc..bc0bdddfcd 100644
--- a/pkg/band/testdata/CN_470_510_26_A_RP002_V1_0_0.json
+++ b/pkg/band/testdata/CN_470_510_26_A_RP002_V1_0_0.json
@@ -836,6 +836,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_470_510_26_A_RP002_V1_0_1.json b/pkg/band/testdata/CN_470_510_26_A_RP002_V1_0_1.json
index a8bbdbf9c1..ed695b8a30 100644
--- a/pkg/band/testdata/CN_470_510_26_A_RP002_V1_0_1.json
+++ b/pkg/band/testdata/CN_470_510_26_A_RP002_V1_0_1.json
@@ -847,6 +847,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_470_510_26_A_RP002_V1_0_2.json b/pkg/band/testdata/CN_470_510_26_A_RP002_V1_0_2.json
index a8bbdbf9c1..ed695b8a30 100644
--- a/pkg/band/testdata/CN_470_510_26_A_RP002_V1_0_2.json
+++ b/pkg/band/testdata/CN_470_510_26_A_RP002_V1_0_2.json
@@ -847,6 +847,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_470_510_26_A_RP002_V1_0_3.json b/pkg/band/testdata/CN_470_510_26_A_RP002_V1_0_3.json
index a8bbdbf9c1..ed695b8a30 100644
--- a/pkg/band/testdata/CN_470_510_26_A_RP002_V1_0_3.json
+++ b/pkg/band/testdata/CN_470_510_26_A_RP002_V1_0_3.json
@@ -847,6 +847,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_470_510_26_A_RP002_V1_0_4.json b/pkg/band/testdata/CN_470_510_26_A_RP002_V1_0_4.json
index f50f983a68..aafd93e6ef 100644
--- a/pkg/band/testdata/CN_470_510_26_A_RP002_V1_0_4.json
+++ b/pkg/band/testdata/CN_470_510_26_A_RP002_V1_0_4.json
@@ -858,6 +858,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_470_510_26_B_RP002_V1_0_0.json b/pkg/band/testdata/CN_470_510_26_B_RP002_V1_0_0.json
index 27212743b2..fbf27ca32d 100644
--- a/pkg/band/testdata/CN_470_510_26_B_RP002_V1_0_0.json
+++ b/pkg/band/testdata/CN_470_510_26_B_RP002_V1_0_0.json
@@ -836,6 +836,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_470_510_26_B_RP002_V1_0_1.json b/pkg/band/testdata/CN_470_510_26_B_RP002_V1_0_1.json
index 0e8d37a666..b3bba73d5e 100644
--- a/pkg/band/testdata/CN_470_510_26_B_RP002_V1_0_1.json
+++ b/pkg/band/testdata/CN_470_510_26_B_RP002_V1_0_1.json
@@ -847,6 +847,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_470_510_26_B_RP002_V1_0_2.json b/pkg/band/testdata/CN_470_510_26_B_RP002_V1_0_2.json
index 0e8d37a666..b3bba73d5e 100644
--- a/pkg/band/testdata/CN_470_510_26_B_RP002_V1_0_2.json
+++ b/pkg/band/testdata/CN_470_510_26_B_RP002_V1_0_2.json
@@ -847,6 +847,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_470_510_26_B_RP002_V1_0_3.json b/pkg/band/testdata/CN_470_510_26_B_RP002_V1_0_3.json
index 0e8d37a666..b3bba73d5e 100644
--- a/pkg/band/testdata/CN_470_510_26_B_RP002_V1_0_3.json
+++ b/pkg/band/testdata/CN_470_510_26_B_RP002_V1_0_3.json
@@ -847,6 +847,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_470_510_26_B_RP002_V1_0_4.json b/pkg/band/testdata/CN_470_510_26_B_RP002_V1_0_4.json
index f414aab77c..935c11dcea 100644
--- a/pkg/band/testdata/CN_470_510_26_B_RP002_V1_0_4.json
+++ b/pkg/band/testdata/CN_470_510_26_B_RP002_V1_0_4.json
@@ -858,6 +858,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_470_510_PHY_V1_0_1.json b/pkg/band/testdata/CN_470_510_PHY_V1_0_1.json
index 2c9440151c..7b27e8d23b 100644
--- a/pkg/band/testdata/CN_470_510_PHY_V1_0_1.json
+++ b/pkg/band/testdata/CN_470_510_PHY_V1_0_1.json
@@ -1210,6 +1210,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_470_510_PHY_V1_0_2_REV_A.json b/pkg/band/testdata/CN_470_510_PHY_V1_0_2_REV_A.json
index 2c9440151c..7b27e8d23b 100644
--- a/pkg/band/testdata/CN_470_510_PHY_V1_0_2_REV_A.json
+++ b/pkg/band/testdata/CN_470_510_PHY_V1_0_2_REV_A.json
@@ -1210,6 +1210,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_470_510_PHY_V1_0_2_REV_B.json b/pkg/band/testdata/CN_470_510_PHY_V1_0_2_REV_B.json
index 274fe6f702..a56304658d 100644
--- a/pkg/band/testdata/CN_470_510_PHY_V1_0_2_REV_B.json
+++ b/pkg/band/testdata/CN_470_510_PHY_V1_0_2_REV_B.json
@@ -1210,6 +1210,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_470_510_PHY_V1_0_3_REV_A.json b/pkg/band/testdata/CN_470_510_PHY_V1_0_3_REV_A.json
index 35fece96b2..f76c0c1836 100644
--- a/pkg/band/testdata/CN_470_510_PHY_V1_0_3_REV_A.json
+++ b/pkg/band/testdata/CN_470_510_PHY_V1_0_3_REV_A.json
@@ -1210,6 +1210,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_470_510_PHY_V1_1_REV_A.json b/pkg/band/testdata/CN_470_510_PHY_V1_1_REV_A.json
index 35fece96b2..f76c0c1836 100644
--- a/pkg/band/testdata/CN_470_510_PHY_V1_1_REV_A.json
+++ b/pkg/band/testdata/CN_470_510_PHY_V1_1_REV_A.json
@@ -1210,6 +1210,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_470_510_PHY_V1_1_REV_B.json b/pkg/band/testdata/CN_470_510_PHY_V1_1_REV_B.json
index 35fece96b2..f76c0c1836 100644
--- a/pkg/band/testdata/CN_470_510_PHY_V1_1_REV_B.json
+++ b/pkg/band/testdata/CN_470_510_PHY_V1_1_REV_B.json
@@ -1210,6 +1210,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_779_787_PHY_V1_0.json b/pkg/band/testdata/CN_779_787_PHY_V1_0.json
index 38e39ebeef..a525332d45 100644
--- a/pkg/band/testdata/CN_779_787_PHY_V1_0.json
+++ b/pkg/band/testdata/CN_779_787_PHY_V1_0.json
@@ -582,6 +582,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_779_787_PHY_V1_0_1.json b/pkg/band/testdata/CN_779_787_PHY_V1_0_1.json
index 38e39ebeef..a525332d45 100644
--- a/pkg/band/testdata/CN_779_787_PHY_V1_0_1.json
+++ b/pkg/band/testdata/CN_779_787_PHY_V1_0_1.json
@@ -582,6 +582,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_779_787_PHY_V1_0_2_REV_A.json b/pkg/band/testdata/CN_779_787_PHY_V1_0_2_REV_A.json
index 38e39ebeef..a525332d45 100644
--- a/pkg/band/testdata/CN_779_787_PHY_V1_0_2_REV_A.json
+++ b/pkg/band/testdata/CN_779_787_PHY_V1_0_2_REV_A.json
@@ -582,6 +582,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_779_787_PHY_V1_0_2_REV_B.json b/pkg/band/testdata/CN_779_787_PHY_V1_0_2_REV_B.json
index 38e39ebeef..a525332d45 100644
--- a/pkg/band/testdata/CN_779_787_PHY_V1_0_2_REV_B.json
+++ b/pkg/band/testdata/CN_779_787_PHY_V1_0_2_REV_B.json
@@ -582,6 +582,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_779_787_PHY_V1_0_3_REV_A.json b/pkg/band/testdata/CN_779_787_PHY_V1_0_3_REV_A.json
index 38e39ebeef..a525332d45 100644
--- a/pkg/band/testdata/CN_779_787_PHY_V1_0_3_REV_A.json
+++ b/pkg/band/testdata/CN_779_787_PHY_V1_0_3_REV_A.json
@@ -582,6 +582,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_779_787_PHY_V1_1_REV_A.json b/pkg/band/testdata/CN_779_787_PHY_V1_1_REV_A.json
index 38e39ebeef..a525332d45 100644
--- a/pkg/band/testdata/CN_779_787_PHY_V1_1_REV_A.json
+++ b/pkg/band/testdata/CN_779_787_PHY_V1_1_REV_A.json
@@ -582,6 +582,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_779_787_PHY_V1_1_REV_B.json b/pkg/band/testdata/CN_779_787_PHY_V1_1_REV_B.json
index 38e39ebeef..a525332d45 100644
--- a/pkg/band/testdata/CN_779_787_PHY_V1_1_REV_B.json
+++ b/pkg/band/testdata/CN_779_787_PHY_V1_1_REV_B.json
@@ -582,6 +582,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_779_787_RP002_V1_0_0.json b/pkg/band/testdata/CN_779_787_RP002_V1_0_0.json
index 32688e5ad3..08044d9b99 100644
--- a/pkg/band/testdata/CN_779_787_RP002_V1_0_0.json
+++ b/pkg/band/testdata/CN_779_787_RP002_V1_0_0.json
@@ -582,6 +582,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_779_787_RP002_V1_0_1.json b/pkg/band/testdata/CN_779_787_RP002_V1_0_1.json
index 32688e5ad3..08044d9b99 100644
--- a/pkg/band/testdata/CN_779_787_RP002_V1_0_1.json
+++ b/pkg/band/testdata/CN_779_787_RP002_V1_0_1.json
@@ -582,6 +582,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_779_787_RP002_V1_0_2.json b/pkg/band/testdata/CN_779_787_RP002_V1_0_2.json
index 32688e5ad3..08044d9b99 100644
--- a/pkg/band/testdata/CN_779_787_RP002_V1_0_2.json
+++ b/pkg/band/testdata/CN_779_787_RP002_V1_0_2.json
@@ -582,6 +582,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/CN_779_787_RP002_V1_0_3.json b/pkg/band/testdata/CN_779_787_RP002_V1_0_3.json
index 32688e5ad3..08044d9b99 100644
--- a/pkg/band/testdata/CN_779_787_RP002_V1_0_3.json
+++ b/pkg/band/testdata/CN_779_787_RP002_V1_0_3.json
@@ -582,6 +582,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/EU_433_PHY_V1_0.json b/pkg/band/testdata/EU_433_PHY_V1_0.json
index 2cbdf6cc03..1ca9b1a390 100644
--- a/pkg/band/testdata/EU_433_PHY_V1_0.json
+++ b/pkg/band/testdata/EU_433_PHY_V1_0.json
@@ -552,6 +552,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/EU_433_PHY_V1_0_1.json b/pkg/band/testdata/EU_433_PHY_V1_0_1.json
index 2cbdf6cc03..1ca9b1a390 100644
--- a/pkg/band/testdata/EU_433_PHY_V1_0_1.json
+++ b/pkg/band/testdata/EU_433_PHY_V1_0_1.json
@@ -552,6 +552,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/EU_433_PHY_V1_0_2_REV_A.json b/pkg/band/testdata/EU_433_PHY_V1_0_2_REV_A.json
index 2cbdf6cc03..1ca9b1a390 100644
--- a/pkg/band/testdata/EU_433_PHY_V1_0_2_REV_A.json
+++ b/pkg/band/testdata/EU_433_PHY_V1_0_2_REV_A.json
@@ -552,6 +552,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/EU_433_PHY_V1_0_2_REV_B.json b/pkg/band/testdata/EU_433_PHY_V1_0_2_REV_B.json
index 2cbdf6cc03..1ca9b1a390 100644
--- a/pkg/band/testdata/EU_433_PHY_V1_0_2_REV_B.json
+++ b/pkg/band/testdata/EU_433_PHY_V1_0_2_REV_B.json
@@ -552,6 +552,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/EU_433_PHY_V1_0_3_REV_A.json b/pkg/band/testdata/EU_433_PHY_V1_0_3_REV_A.json
index 2cbdf6cc03..1ca9b1a390 100644
--- a/pkg/band/testdata/EU_433_PHY_V1_0_3_REV_A.json
+++ b/pkg/band/testdata/EU_433_PHY_V1_0_3_REV_A.json
@@ -552,6 +552,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/EU_433_PHY_V1_1_REV_A.json b/pkg/band/testdata/EU_433_PHY_V1_1_REV_A.json
index 2cbdf6cc03..1ca9b1a390 100644
--- a/pkg/band/testdata/EU_433_PHY_V1_1_REV_A.json
+++ b/pkg/band/testdata/EU_433_PHY_V1_1_REV_A.json
@@ -552,6 +552,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/EU_433_PHY_V1_1_REV_B.json b/pkg/band/testdata/EU_433_PHY_V1_1_REV_B.json
index 2cbdf6cc03..1ca9b1a390 100644
--- a/pkg/band/testdata/EU_433_PHY_V1_1_REV_B.json
+++ b/pkg/band/testdata/EU_433_PHY_V1_1_REV_B.json
@@ -552,6 +552,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/EU_433_RP002_V1_0_0.json b/pkg/band/testdata/EU_433_RP002_V1_0_0.json
index 031b141b75..70b7acb008 100644
--- a/pkg/band/testdata/EU_433_RP002_V1_0_0.json
+++ b/pkg/band/testdata/EU_433_RP002_V1_0_0.json
@@ -552,6 +552,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/EU_433_RP002_V1_0_1.json b/pkg/band/testdata/EU_433_RP002_V1_0_1.json
index 031b141b75..70b7acb008 100644
--- a/pkg/band/testdata/EU_433_RP002_V1_0_1.json
+++ b/pkg/band/testdata/EU_433_RP002_V1_0_1.json
@@ -552,6 +552,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/EU_433_RP002_V1_0_2.json b/pkg/band/testdata/EU_433_RP002_V1_0_2.json
index 031b141b75..70b7acb008 100644
--- a/pkg/band/testdata/EU_433_RP002_V1_0_2.json
+++ b/pkg/band/testdata/EU_433_RP002_V1_0_2.json
@@ -552,6 +552,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/EU_433_RP002_V1_0_3.json b/pkg/band/testdata/EU_433_RP002_V1_0_3.json
index 031b141b75..70b7acb008 100644
--- a/pkg/band/testdata/EU_433_RP002_V1_0_3.json
+++ b/pkg/band/testdata/EU_433_RP002_V1_0_3.json
@@ -552,6 +552,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/EU_433_RP002_V1_0_4.json b/pkg/band/testdata/EU_433_RP002_V1_0_4.json
index 9b78fb8302..1c4c056443 100644
--- a/pkg/band/testdata/EU_433_RP002_V1_0_4.json
+++ b/pkg/band/testdata/EU_433_RP002_V1_0_4.json
@@ -552,6 +552,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/EU_863_870_PHY_V1_0.json b/pkg/band/testdata/EU_863_870_PHY_V1_0.json
index 350faba32b..8c7c649215 100644
--- a/pkg/band/testdata/EU_863_870_PHY_V1_0.json
+++ b/pkg/band/testdata/EU_863_870_PHY_V1_0.json
@@ -582,6 +582,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/EU_863_870_PHY_V1_0_1.json b/pkg/band/testdata/EU_863_870_PHY_V1_0_1.json
index 350faba32b..8c7c649215 100644
--- a/pkg/band/testdata/EU_863_870_PHY_V1_0_1.json
+++ b/pkg/band/testdata/EU_863_870_PHY_V1_0_1.json
@@ -582,6 +582,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/EU_863_870_PHY_V1_0_2_REV_A.json b/pkg/band/testdata/EU_863_870_PHY_V1_0_2_REV_A.json
index 350faba32b..8c7c649215 100644
--- a/pkg/band/testdata/EU_863_870_PHY_V1_0_2_REV_A.json
+++ b/pkg/band/testdata/EU_863_870_PHY_V1_0_2_REV_A.json
@@ -582,6 +582,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/EU_863_870_PHY_V1_0_2_REV_B.json b/pkg/band/testdata/EU_863_870_PHY_V1_0_2_REV_B.json
index 55ff15db94..e676b699d2 100644
--- a/pkg/band/testdata/EU_863_870_PHY_V1_0_2_REV_B.json
+++ b/pkg/band/testdata/EU_863_870_PHY_V1_0_2_REV_B.json
@@ -584,6 +584,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/EU_863_870_PHY_V1_0_3_REV_A.json b/pkg/band/testdata/EU_863_870_PHY_V1_0_3_REV_A.json
index 55ff15db94..e676b699d2 100644
--- a/pkg/band/testdata/EU_863_870_PHY_V1_0_3_REV_A.json
+++ b/pkg/band/testdata/EU_863_870_PHY_V1_0_3_REV_A.json
@@ -584,6 +584,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/EU_863_870_PHY_V1_1_REV_A.json b/pkg/band/testdata/EU_863_870_PHY_V1_1_REV_A.json
index 55ff15db94..e676b699d2 100644
--- a/pkg/band/testdata/EU_863_870_PHY_V1_1_REV_A.json
+++ b/pkg/band/testdata/EU_863_870_PHY_V1_1_REV_A.json
@@ -584,6 +584,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/EU_863_870_PHY_V1_1_REV_B.json b/pkg/band/testdata/EU_863_870_PHY_V1_1_REV_B.json
index 55ff15db94..e676b699d2 100644
--- a/pkg/band/testdata/EU_863_870_PHY_V1_1_REV_B.json
+++ b/pkg/band/testdata/EU_863_870_PHY_V1_1_REV_B.json
@@ -584,6 +584,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/EU_863_870_RP002_V1_0_0.json b/pkg/band/testdata/EU_863_870_RP002_V1_0_0.json
index d0a2a3c98c..83ec7e3359 100644
--- a/pkg/band/testdata/EU_863_870_RP002_V1_0_0.json
+++ b/pkg/band/testdata/EU_863_870_RP002_V1_0_0.json
@@ -584,6 +584,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/EU_863_870_RP002_V1_0_1.json b/pkg/band/testdata/EU_863_870_RP002_V1_0_1.json
index d0a2a3c98c..83ec7e3359 100644
--- a/pkg/band/testdata/EU_863_870_RP002_V1_0_1.json
+++ b/pkg/band/testdata/EU_863_870_RP002_V1_0_1.json
@@ -584,6 +584,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/EU_863_870_RP002_V1_0_2.json b/pkg/band/testdata/EU_863_870_RP002_V1_0_2.json
index ea443cacb3..c086bc295d 100644
--- a/pkg/band/testdata/EU_863_870_RP002_V1_0_2.json
+++ b/pkg/band/testdata/EU_863_870_RP002_V1_0_2.json
@@ -680,6 +680,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/EU_863_870_RP002_V1_0_3.json b/pkg/band/testdata/EU_863_870_RP002_V1_0_3.json
index ea443cacb3..c086bc295d 100644
--- a/pkg/band/testdata/EU_863_870_RP002_V1_0_3.json
+++ b/pkg/band/testdata/EU_863_870_RP002_V1_0_3.json
@@ -680,6 +680,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/EU_863_870_RP002_V1_0_4.json b/pkg/band/testdata/EU_863_870_RP002_V1_0_4.json
index b9d727d82b..7137dd9cbb 100644
--- a/pkg/band/testdata/EU_863_870_RP002_V1_0_4.json
+++ b/pkg/band/testdata/EU_863_870_RP002_V1_0_4.json
@@ -691,6 +691,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/IN_865_867_PHY_V1_0_2_REV_B.json b/pkg/band/testdata/IN_865_867_PHY_V1_0_2_REV_B.json
index dd3e18b63f..e4072707e8 100644
--- a/pkg/band/testdata/IN_865_867_PHY_V1_0_2_REV_B.json
+++ b/pkg/band/testdata/IN_865_867_PHY_V1_0_2_REV_B.json
@@ -704,6 +704,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/IN_865_867_PHY_V1_0_3_REV_A.json b/pkg/band/testdata/IN_865_867_PHY_V1_0_3_REV_A.json
index dd3e18b63f..e4072707e8 100644
--- a/pkg/band/testdata/IN_865_867_PHY_V1_0_3_REV_A.json
+++ b/pkg/band/testdata/IN_865_867_PHY_V1_0_3_REV_A.json
@@ -704,6 +704,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/IN_865_867_PHY_V1_1_REV_A.json b/pkg/band/testdata/IN_865_867_PHY_V1_1_REV_A.json
index dd3e18b63f..e4072707e8 100644
--- a/pkg/band/testdata/IN_865_867_PHY_V1_1_REV_A.json
+++ b/pkg/band/testdata/IN_865_867_PHY_V1_1_REV_A.json
@@ -704,6 +704,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/IN_865_867_PHY_V1_1_REV_B.json b/pkg/band/testdata/IN_865_867_PHY_V1_1_REV_B.json
index dd3e18b63f..e4072707e8 100644
--- a/pkg/band/testdata/IN_865_867_PHY_V1_1_REV_B.json
+++ b/pkg/band/testdata/IN_865_867_PHY_V1_1_REV_B.json
@@ -704,6 +704,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/IN_865_867_RP002_V1_0_0.json b/pkg/band/testdata/IN_865_867_RP002_V1_0_0.json
index 8751207d8a..af7b408df9 100644
--- a/pkg/band/testdata/IN_865_867_RP002_V1_0_0.json
+++ b/pkg/band/testdata/IN_865_867_RP002_V1_0_0.json
@@ -704,6 +704,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/IN_865_867_RP002_V1_0_1.json b/pkg/band/testdata/IN_865_867_RP002_V1_0_1.json
index 8751207d8a..af7b408df9 100644
--- a/pkg/band/testdata/IN_865_867_RP002_V1_0_1.json
+++ b/pkg/band/testdata/IN_865_867_RP002_V1_0_1.json
@@ -704,6 +704,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/IN_865_867_RP002_V1_0_2.json b/pkg/band/testdata/IN_865_867_RP002_V1_0_2.json
index 8751207d8a..af7b408df9 100644
--- a/pkg/band/testdata/IN_865_867_RP002_V1_0_2.json
+++ b/pkg/band/testdata/IN_865_867_RP002_V1_0_2.json
@@ -704,6 +704,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/IN_865_867_RP002_V1_0_3.json b/pkg/band/testdata/IN_865_867_RP002_V1_0_3.json
index 8751207d8a..af7b408df9 100644
--- a/pkg/band/testdata/IN_865_867_RP002_V1_0_3.json
+++ b/pkg/band/testdata/IN_865_867_RP002_V1_0_3.json
@@ -704,6 +704,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/IN_865_867_RP002_V1_0_4.json b/pkg/band/testdata/IN_865_867_RP002_V1_0_4.json
index be342c42c4..973a6b9f14 100644
--- a/pkg/band/testdata/IN_865_867_RP002_V1_0_4.json
+++ b/pkg/band/testdata/IN_865_867_RP002_V1_0_4.json
@@ -715,6 +715,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/ISM_2400_PHY_V1_0.json b/pkg/band/testdata/ISM_2400_PHY_V1_0.json
index 484af58186..c8a1b0bbc5 100644
--- a/pkg/band/testdata/ISM_2400_PHY_V1_0.json
+++ b/pkg/band/testdata/ISM_2400_PHY_V1_0.json
@@ -556,6 +556,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/ISM_2400_PHY_V1_0_1.json b/pkg/band/testdata/ISM_2400_PHY_V1_0_1.json
index 484af58186..c8a1b0bbc5 100644
--- a/pkg/band/testdata/ISM_2400_PHY_V1_0_1.json
+++ b/pkg/band/testdata/ISM_2400_PHY_V1_0_1.json
@@ -556,6 +556,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/ISM_2400_PHY_V1_0_2_REV_A.json b/pkg/band/testdata/ISM_2400_PHY_V1_0_2_REV_A.json
index 484af58186..c8a1b0bbc5 100644
--- a/pkg/band/testdata/ISM_2400_PHY_V1_0_2_REV_A.json
+++ b/pkg/band/testdata/ISM_2400_PHY_V1_0_2_REV_A.json
@@ -556,6 +556,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/ISM_2400_PHY_V1_0_2_REV_B.json b/pkg/band/testdata/ISM_2400_PHY_V1_0_2_REV_B.json
index 484af58186..c8a1b0bbc5 100644
--- a/pkg/band/testdata/ISM_2400_PHY_V1_0_2_REV_B.json
+++ b/pkg/band/testdata/ISM_2400_PHY_V1_0_2_REV_B.json
@@ -556,6 +556,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/ISM_2400_PHY_V1_0_3_REV_A.json b/pkg/band/testdata/ISM_2400_PHY_V1_0_3_REV_A.json
index 484af58186..c8a1b0bbc5 100644
--- a/pkg/band/testdata/ISM_2400_PHY_V1_0_3_REV_A.json
+++ b/pkg/band/testdata/ISM_2400_PHY_V1_0_3_REV_A.json
@@ -556,6 +556,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/ISM_2400_PHY_V1_1_REV_A.json b/pkg/band/testdata/ISM_2400_PHY_V1_1_REV_A.json
index 484af58186..c8a1b0bbc5 100644
--- a/pkg/band/testdata/ISM_2400_PHY_V1_1_REV_A.json
+++ b/pkg/band/testdata/ISM_2400_PHY_V1_1_REV_A.json
@@ -556,6 +556,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/ISM_2400_PHY_V1_1_REV_B.json b/pkg/band/testdata/ISM_2400_PHY_V1_1_REV_B.json
index 484af58186..c8a1b0bbc5 100644
--- a/pkg/band/testdata/ISM_2400_PHY_V1_1_REV_B.json
+++ b/pkg/band/testdata/ISM_2400_PHY_V1_1_REV_B.json
@@ -556,6 +556,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/ISM_2400_RP002_V1_0_0.json b/pkg/band/testdata/ISM_2400_RP002_V1_0_0.json
index 484af58186..c8a1b0bbc5 100644
--- a/pkg/band/testdata/ISM_2400_RP002_V1_0_0.json
+++ b/pkg/band/testdata/ISM_2400_RP002_V1_0_0.json
@@ -556,6 +556,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/ISM_2400_RP002_V1_0_1.json b/pkg/band/testdata/ISM_2400_RP002_V1_0_1.json
index 484af58186..c8a1b0bbc5 100644
--- a/pkg/band/testdata/ISM_2400_RP002_V1_0_1.json
+++ b/pkg/band/testdata/ISM_2400_RP002_V1_0_1.json
@@ -556,6 +556,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/ISM_2400_RP002_V1_0_2.json b/pkg/band/testdata/ISM_2400_RP002_V1_0_2.json
index 484af58186..c8a1b0bbc5 100644
--- a/pkg/band/testdata/ISM_2400_RP002_V1_0_2.json
+++ b/pkg/band/testdata/ISM_2400_RP002_V1_0_2.json
@@ -556,6 +556,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/ISM_2400_RP002_V1_0_3.json b/pkg/band/testdata/ISM_2400_RP002_V1_0_3.json
index 484af58186..c8a1b0bbc5 100644
--- a/pkg/band/testdata/ISM_2400_RP002_V1_0_3.json
+++ b/pkg/band/testdata/ISM_2400_RP002_V1_0_3.json
@@ -556,6 +556,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/ISM_2400_RP002_V1_0_4.json b/pkg/band/testdata/ISM_2400_RP002_V1_0_4.json
index 484af58186..c8a1b0bbc5 100644
--- a/pkg/band/testdata/ISM_2400_RP002_V1_0_4.json
+++ b/pkg/band/testdata/ISM_2400_RP002_V1_0_4.json
@@ -556,6 +556,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/KR_920_923_PHY_V1_0_2_REV_A.json b/pkg/band/testdata/KR_920_923_PHY_V1_0_2_REV_A.json
index 15d5ccceb6..b4c39ae516 100644
--- a/pkg/band/testdata/KR_920_923_PHY_V1_0_2_REV_A.json
+++ b/pkg/band/testdata/KR_920_923_PHY_V1_0_2_REV_A.json
@@ -505,6 +505,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/KR_920_923_PHY_V1_0_2_REV_B.json b/pkg/band/testdata/KR_920_923_PHY_V1_0_2_REV_B.json
index e03c849aeb..df30406473 100644
--- a/pkg/band/testdata/KR_920_923_PHY_V1_0_2_REV_B.json
+++ b/pkg/band/testdata/KR_920_923_PHY_V1_0_2_REV_B.json
@@ -506,6 +506,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/KR_920_923_PHY_V1_0_3_REV_A.json b/pkg/band/testdata/KR_920_923_PHY_V1_0_3_REV_A.json
index e03c849aeb..df30406473 100644
--- a/pkg/band/testdata/KR_920_923_PHY_V1_0_3_REV_A.json
+++ b/pkg/band/testdata/KR_920_923_PHY_V1_0_3_REV_A.json
@@ -506,6 +506,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/KR_920_923_PHY_V1_1_REV_A.json b/pkg/band/testdata/KR_920_923_PHY_V1_1_REV_A.json
index e03c849aeb..df30406473 100644
--- a/pkg/band/testdata/KR_920_923_PHY_V1_1_REV_A.json
+++ b/pkg/band/testdata/KR_920_923_PHY_V1_1_REV_A.json
@@ -506,6 +506,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/KR_920_923_PHY_V1_1_REV_B.json b/pkg/band/testdata/KR_920_923_PHY_V1_1_REV_B.json
index e03c849aeb..df30406473 100644
--- a/pkg/band/testdata/KR_920_923_PHY_V1_1_REV_B.json
+++ b/pkg/band/testdata/KR_920_923_PHY_V1_1_REV_B.json
@@ -506,6 +506,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/KR_920_923_RP002_V1_0_0.json b/pkg/band/testdata/KR_920_923_RP002_V1_0_0.json
index 0595b6d390..a1d9767df8 100644
--- a/pkg/band/testdata/KR_920_923_RP002_V1_0_0.json
+++ b/pkg/band/testdata/KR_920_923_RP002_V1_0_0.json
@@ -506,6 +506,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/KR_920_923_RP002_V1_0_1.json b/pkg/band/testdata/KR_920_923_RP002_V1_0_1.json
index 0595b6d390..a1d9767df8 100644
--- a/pkg/band/testdata/KR_920_923_RP002_V1_0_1.json
+++ b/pkg/band/testdata/KR_920_923_RP002_V1_0_1.json
@@ -506,6 +506,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/KR_920_923_RP002_V1_0_2.json b/pkg/band/testdata/KR_920_923_RP002_V1_0_2.json
index 0595b6d390..a1d9767df8 100644
--- a/pkg/band/testdata/KR_920_923_RP002_V1_0_2.json
+++ b/pkg/band/testdata/KR_920_923_RP002_V1_0_2.json
@@ -506,6 +506,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/KR_920_923_RP002_V1_0_3.json b/pkg/band/testdata/KR_920_923_RP002_V1_0_3.json
index 0595b6d390..a1d9767df8 100644
--- a/pkg/band/testdata/KR_920_923_RP002_V1_0_3.json
+++ b/pkg/band/testdata/KR_920_923_RP002_V1_0_3.json
@@ -506,6 +506,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/KR_920_923_RP002_V1_0_4.json b/pkg/band/testdata/KR_920_923_RP002_V1_0_4.json
index 26a292c4af..b11482855f 100644
--- a/pkg/band/testdata/KR_920_923_RP002_V1_0_4.json
+++ b/pkg/band/testdata/KR_920_923_RP002_V1_0_4.json
@@ -517,6 +517,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/MA_869_870_DRAFT_PHY_V1_0.json b/pkg/band/testdata/MA_869_870_DRAFT_PHY_V1_0.json
index e25859d0e1..175a316a6a 100644
--- a/pkg/band/testdata/MA_869_870_DRAFT_PHY_V1_0.json
+++ b/pkg/band/testdata/MA_869_870_DRAFT_PHY_V1_0.json
@@ -614,6 +614,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/MA_869_870_DRAFT_PHY_V1_0_1.json b/pkg/band/testdata/MA_869_870_DRAFT_PHY_V1_0_1.json
index e25859d0e1..175a316a6a 100644
--- a/pkg/band/testdata/MA_869_870_DRAFT_PHY_V1_0_1.json
+++ b/pkg/band/testdata/MA_869_870_DRAFT_PHY_V1_0_1.json
@@ -614,6 +614,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/MA_869_870_DRAFT_PHY_V1_0_2_REV_A.json b/pkg/band/testdata/MA_869_870_DRAFT_PHY_V1_0_2_REV_A.json
index e25859d0e1..175a316a6a 100644
--- a/pkg/band/testdata/MA_869_870_DRAFT_PHY_V1_0_2_REV_A.json
+++ b/pkg/band/testdata/MA_869_870_DRAFT_PHY_V1_0_2_REV_A.json
@@ -614,6 +614,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/MA_869_870_DRAFT_PHY_V1_0_2_REV_B.json b/pkg/band/testdata/MA_869_870_DRAFT_PHY_V1_0_2_REV_B.json
index e25859d0e1..175a316a6a 100644
--- a/pkg/band/testdata/MA_869_870_DRAFT_PHY_V1_0_2_REV_B.json
+++ b/pkg/band/testdata/MA_869_870_DRAFT_PHY_V1_0_2_REV_B.json
@@ -614,6 +614,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/MA_869_870_DRAFT_PHY_V1_0_3_REV_A.json b/pkg/band/testdata/MA_869_870_DRAFT_PHY_V1_0_3_REV_A.json
index e25859d0e1..175a316a6a 100644
--- a/pkg/band/testdata/MA_869_870_DRAFT_PHY_V1_0_3_REV_A.json
+++ b/pkg/band/testdata/MA_869_870_DRAFT_PHY_V1_0_3_REV_A.json
@@ -614,6 +614,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/MA_869_870_DRAFT_PHY_V1_1_REV_A.json b/pkg/band/testdata/MA_869_870_DRAFT_PHY_V1_1_REV_A.json
index e25859d0e1..175a316a6a 100644
--- a/pkg/band/testdata/MA_869_870_DRAFT_PHY_V1_1_REV_A.json
+++ b/pkg/band/testdata/MA_869_870_DRAFT_PHY_V1_1_REV_A.json
@@ -614,6 +614,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/MA_869_870_DRAFT_PHY_V1_1_REV_B.json b/pkg/band/testdata/MA_869_870_DRAFT_PHY_V1_1_REV_B.json
index e25859d0e1..175a316a6a 100644
--- a/pkg/band/testdata/MA_869_870_DRAFT_PHY_V1_1_REV_B.json
+++ b/pkg/band/testdata/MA_869_870_DRAFT_PHY_V1_1_REV_B.json
@@ -614,6 +614,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/MA_869_870_DRAFT_RP002_V1_0_0.json b/pkg/band/testdata/MA_869_870_DRAFT_RP002_V1_0_0.json
index e25859d0e1..175a316a6a 100644
--- a/pkg/band/testdata/MA_869_870_DRAFT_RP002_V1_0_0.json
+++ b/pkg/band/testdata/MA_869_870_DRAFT_RP002_V1_0_0.json
@@ -614,6 +614,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/MA_869_870_DRAFT_RP002_V1_0_1.json b/pkg/band/testdata/MA_869_870_DRAFT_RP002_V1_0_1.json
index e25859d0e1..175a316a6a 100644
--- a/pkg/band/testdata/MA_869_870_DRAFT_RP002_V1_0_1.json
+++ b/pkg/band/testdata/MA_869_870_DRAFT_RP002_V1_0_1.json
@@ -614,6 +614,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/MA_869_870_DRAFT_RP002_V1_0_2.json b/pkg/band/testdata/MA_869_870_DRAFT_RP002_V1_0_2.json
index e25859d0e1..175a316a6a 100644
--- a/pkg/band/testdata/MA_869_870_DRAFT_RP002_V1_0_2.json
+++ b/pkg/band/testdata/MA_869_870_DRAFT_RP002_V1_0_2.json
@@ -614,6 +614,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/MA_869_870_DRAFT_RP002_V1_0_3.json b/pkg/band/testdata/MA_869_870_DRAFT_RP002_V1_0_3.json
index e25859d0e1..175a316a6a 100644
--- a/pkg/band/testdata/MA_869_870_DRAFT_RP002_V1_0_3.json
+++ b/pkg/band/testdata/MA_869_870_DRAFT_RP002_V1_0_3.json
@@ -614,6 +614,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/MA_869_870_DRAFT_RP002_V1_0_4.json b/pkg/band/testdata/MA_869_870_DRAFT_RP002_V1_0_4.json
index e25859d0e1..175a316a6a 100644
--- a/pkg/band/testdata/MA_869_870_DRAFT_RP002_V1_0_4.json
+++ b/pkg/band/testdata/MA_869_870_DRAFT_RP002_V1_0_4.json
@@ -614,6 +614,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/RU_864_870_PHY_V1_0_3_REV_A.json b/pkg/band/testdata/RU_864_870_PHY_V1_0_3_REV_A.json
index 1668bd2be3..c7c1e494d7 100644
--- a/pkg/band/testdata/RU_864_870_PHY_V1_0_3_REV_A.json
+++ b/pkg/band/testdata/RU_864_870_PHY_V1_0_3_REV_A.json
@@ -544,6 +544,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/RU_864_870_PHY_V1_1_REV_A.json b/pkg/band/testdata/RU_864_870_PHY_V1_1_REV_A.json
index 1668bd2be3..c7c1e494d7 100644
--- a/pkg/band/testdata/RU_864_870_PHY_V1_1_REV_A.json
+++ b/pkg/band/testdata/RU_864_870_PHY_V1_1_REV_A.json
@@ -544,6 +544,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/RU_864_870_PHY_V1_1_REV_B.json b/pkg/band/testdata/RU_864_870_PHY_V1_1_REV_B.json
index 1668bd2be3..c7c1e494d7 100644
--- a/pkg/band/testdata/RU_864_870_PHY_V1_1_REV_B.json
+++ b/pkg/band/testdata/RU_864_870_PHY_V1_1_REV_B.json
@@ -544,6 +544,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/RU_864_870_RP002_V1_0_0.json b/pkg/band/testdata/RU_864_870_RP002_V1_0_0.json
index 6bf4131fb4..7074a1f833 100644
--- a/pkg/band/testdata/RU_864_870_RP002_V1_0_0.json
+++ b/pkg/band/testdata/RU_864_870_RP002_V1_0_0.json
@@ -544,6 +544,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/RU_864_870_RP002_V1_0_1.json b/pkg/band/testdata/RU_864_870_RP002_V1_0_1.json
index 6bf4131fb4..7074a1f833 100644
--- a/pkg/band/testdata/RU_864_870_RP002_V1_0_1.json
+++ b/pkg/band/testdata/RU_864_870_RP002_V1_0_1.json
@@ -544,6 +544,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/RU_864_870_RP002_V1_0_2.json b/pkg/band/testdata/RU_864_870_RP002_V1_0_2.json
index 6bf4131fb4..7074a1f833 100644
--- a/pkg/band/testdata/RU_864_870_RP002_V1_0_2.json
+++ b/pkg/band/testdata/RU_864_870_RP002_V1_0_2.json
@@ -544,6 +544,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/RU_864_870_RP002_V1_0_3.json b/pkg/band/testdata/RU_864_870_RP002_V1_0_3.json
index 6bf4131fb4..7074a1f833 100644
--- a/pkg/band/testdata/RU_864_870_RP002_V1_0_3.json
+++ b/pkg/band/testdata/RU_864_870_RP002_V1_0_3.json
@@ -544,6 +544,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/RU_864_870_RP002_V1_0_4.json b/pkg/band/testdata/RU_864_870_RP002_V1_0_4.json
index 76d80f58cb..8fa2895cb1 100644
--- a/pkg/band/testdata/RU_864_870_RP002_V1_0_4.json
+++ b/pkg/band/testdata/RU_864_870_RP002_V1_0_4.json
@@ -555,6 +555,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/US_902_928_PHY_V1_0.json b/pkg/band/testdata/US_902_928_PHY_V1_0.json
index c3ba9170ff..9e46f149a1 100644
--- a/pkg/band/testdata/US_902_928_PHY_V1_0.json
+++ b/pkg/band/testdata/US_902_928_PHY_V1_0.json
@@ -932,6 +932,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/US_902_928_PHY_V1_0_1.json b/pkg/band/testdata/US_902_928_PHY_V1_0_1.json
index c3ba9170ff..9e46f149a1 100644
--- a/pkg/band/testdata/US_902_928_PHY_V1_0_1.json
+++ b/pkg/band/testdata/US_902_928_PHY_V1_0_1.json
@@ -932,6 +932,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/US_902_928_PHY_V1_0_2_REV_A.json b/pkg/band/testdata/US_902_928_PHY_V1_0_2_REV_A.json
index a95fa2c020..83a5fc9426 100644
--- a/pkg/band/testdata/US_902_928_PHY_V1_0_2_REV_A.json
+++ b/pkg/band/testdata/US_902_928_PHY_V1_0_2_REV_A.json
@@ -932,6 +932,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/US_902_928_PHY_V1_0_2_REV_B.json b/pkg/band/testdata/US_902_928_PHY_V1_0_2_REV_B.json
index f4a484afa9..7887e720ee 100644
--- a/pkg/band/testdata/US_902_928_PHY_V1_0_2_REV_B.json
+++ b/pkg/band/testdata/US_902_928_PHY_V1_0_2_REV_B.json
@@ -932,6 +932,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/US_902_928_PHY_V1_0_3_REV_A.json b/pkg/band/testdata/US_902_928_PHY_V1_0_3_REV_A.json
index 784f3435c6..22e367111d 100644
--- a/pkg/band/testdata/US_902_928_PHY_V1_0_3_REV_A.json
+++ b/pkg/band/testdata/US_902_928_PHY_V1_0_3_REV_A.json
@@ -937,6 +937,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/US_902_928_PHY_V1_1_REV_A.json b/pkg/band/testdata/US_902_928_PHY_V1_1_REV_A.json
index ef2583b372..663dfa8fea 100644
--- a/pkg/band/testdata/US_902_928_PHY_V1_1_REV_A.json
+++ b/pkg/band/testdata/US_902_928_PHY_V1_1_REV_A.json
@@ -936,6 +936,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/US_902_928_PHY_V1_1_REV_B.json b/pkg/band/testdata/US_902_928_PHY_V1_1_REV_B.json
index ef2583b372..663dfa8fea 100644
--- a/pkg/band/testdata/US_902_928_PHY_V1_1_REV_B.json
+++ b/pkg/band/testdata/US_902_928_PHY_V1_1_REV_B.json
@@ -936,6 +936,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/US_902_928_RP002_V1_0_0.json b/pkg/band/testdata/US_902_928_RP002_V1_0_0.json
index ef2583b372..663dfa8fea 100644
--- a/pkg/band/testdata/US_902_928_RP002_V1_0_0.json
+++ b/pkg/band/testdata/US_902_928_RP002_V1_0_0.json
@@ -936,6 +936,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/US_902_928_RP002_V1_0_1.json b/pkg/band/testdata/US_902_928_RP002_V1_0_1.json
index ef2583b372..663dfa8fea 100644
--- a/pkg/band/testdata/US_902_928_RP002_V1_0_1.json
+++ b/pkg/band/testdata/US_902_928_RP002_V1_0_1.json
@@ -936,6 +936,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/US_902_928_RP002_V1_0_2.json b/pkg/band/testdata/US_902_928_RP002_V1_0_2.json
index ec06d80670..1e6d5e62d9 100644
--- a/pkg/band/testdata/US_902_928_RP002_V1_0_2.json
+++ b/pkg/band/testdata/US_902_928_RP002_V1_0_2.json
@@ -976,6 +976,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/US_902_928_RP002_V1_0_3.json b/pkg/band/testdata/US_902_928_RP002_V1_0_3.json
index ec06d80670..1e6d5e62d9 100644
--- a/pkg/band/testdata/US_902_928_RP002_V1_0_3.json
+++ b/pkg/band/testdata/US_902_928_RP002_V1_0_3.json
@@ -976,6 +976,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 0,
- "RelayReceiveDelay": 0
+ "RelayReceiveDelay": 0,
+ "ServedRelayBackoff": 0
}
}
\ No newline at end of file
diff --git a/pkg/band/testdata/US_902_928_RP002_V1_0_4.json b/pkg/band/testdata/US_902_928_RP002_V1_0_4.json
index 456fe7bf44..318d1588d1 100644
--- a/pkg/band/testdata/US_902_928_RP002_V1_0_4.json
+++ b/pkg/band/testdata/US_902_928_RP002_V1_0_4.json
@@ -987,6 +987,7 @@
"MinRetransmitTimeout": 1000000000,
"MaxRetransmitTimeout": 3000000000,
"RelayForwardDelay": 50000000,
- "RelayReceiveDelay": 18000000000
+ "RelayReceiveDelay": 18000000000,
+ "ServedRelayBackoff": 8
}
}
\ No newline at end of file
diff --git a/pkg/basicstation/cups/server.go b/pkg/basicstation/cups/server.go
index 323ac8c91f..298fd3c9d5 100644
--- a/pkg/basicstation/cups/server.go
+++ b/pkg/basicstation/cups/server.go
@@ -33,7 +33,6 @@ import (
"go.thethings.network/lorawan-stack/v3/pkg/web"
"golang.org/x/sync/singleflight"
"google.golang.org/grpc"
- "google.golang.org/grpc/metadata"
)
// Server implements the Basic Station Configuration and Update Server.
@@ -184,17 +183,6 @@ func (s *Server) RegisterRoutes(web *web.Server) {
router.Path("/update-info").HandlerFunc(s.UpdateInfo).Methods(http.MethodPost)
}
-func getContext(r *http.Request) context.Context {
- ctx := r.Context()
- md := metadata.New(map[string]string{
- "authorization": r.Header.Get("Authorization"),
- })
- if ctxMd, ok := metadata.FromIncomingContext(ctx); ok {
- md = metadata.Join(ctxMd, md)
- }
- return metadata.NewIncomingContext(ctx, md)
-}
-
var errNoTrust = errors.DefineInternal("no_trust", "no trusted certificate found")
// parseAddress parses a CUPS or LNS address.
diff --git a/pkg/console/console.go b/pkg/console/console.go
index d012123d35..092e52a1bb 100644
--- a/pkg/console/console.go
+++ b/pkg/console/console.go
@@ -23,6 +23,7 @@ import (
"github.com/gorilla/csrf"
"github.com/gorilla/mux"
"go.thethings.network/lorawan-stack/v3/pkg/component"
+ "go.thethings.network/lorawan-stack/v3/pkg/console/internal/events"
"go.thethings.network/lorawan-stack/v3/pkg/web"
"go.thethings.network/lorawan-stack/v3/pkg/web/oauthclient"
"go.thethings.network/lorawan-stack/v3/pkg/webhandlers"
@@ -58,6 +59,7 @@ func New(c *component.Component, config Config) (*Console, error) {
}
c.RegisterWeb(console)
+ c.RegisterWeb(events.New(c))
return console, nil
}
@@ -88,22 +90,25 @@ func path(u string) (string, error) {
}
func generateConsoleCSPString(config *Config, nonce string, others ...webui.ContentSecurityPolicy) string {
+ baseURLs := webui.RewriteSchemes(
+ webui.WebsocketSchemeRewrites,
+ config.UI.StackConfig.GS.BaseURL,
+ config.UI.StackConfig.IS.BaseURL,
+ config.UI.StackConfig.JS.BaseURL,
+ config.UI.StackConfig.NS.BaseURL,
+ config.UI.StackConfig.AS.BaseURL,
+ config.UI.StackConfig.EDTC.BaseURL,
+ config.UI.StackConfig.QRG.BaseURL,
+ config.UI.StackConfig.GCS.BaseURL,
+ config.UI.StackConfig.DCS.BaseURL,
+ )
return webui.ContentSecurityPolicy{
- ConnectionSource: []string{
+ ConnectionSource: append([]string{
"'self'",
- config.UI.StackConfig.GS.BaseURL,
- config.UI.StackConfig.IS.BaseURL,
- config.UI.StackConfig.JS.BaseURL,
- config.UI.StackConfig.NS.BaseURL,
- config.UI.StackConfig.AS.BaseURL,
- config.UI.StackConfig.EDTC.BaseURL,
- config.UI.StackConfig.QRG.BaseURL,
- config.UI.StackConfig.GCS.BaseURL,
- config.UI.StackConfig.DCS.BaseURL,
config.UI.SentryDSN,
"gravatar.com",
"www.gravatar.com",
- },
+ }, baseURLs...),
StyleSource: []string{
"'self'",
config.UI.AssetsBaseURL,
diff --git a/pkg/console/internal/events/events.go b/pkg/console/internal/events/events.go
new file mode 100644
index 0000000000..3d8a106d8c
--- /dev/null
+++ b/pkg/console/internal/events/events.go
@@ -0,0 +1,168 @@
+// 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 contains the internal events APi for the Console.
+package events
+
+import (
+ "context"
+ "net/http"
+ "sync"
+ "time"
+
+ "github.com/gorilla/mux"
+ "github.com/mileusna/useragent"
+ "go.thethings.network/lorawan-stack/v3/pkg/auth/rights"
+ "go.thethings.network/lorawan-stack/v3/pkg/config"
+ "go.thethings.network/lorawan-stack/v3/pkg/console/internal/events/eventsmux"
+ "go.thethings.network/lorawan-stack/v3/pkg/console/internal/events/middleware"
+ "go.thethings.network/lorawan-stack/v3/pkg/console/internal/events/subscriptions"
+ "go.thethings.network/lorawan-stack/v3/pkg/errorcontext"
+ "go.thethings.network/lorawan-stack/v3/pkg/events"
+ "go.thethings.network/lorawan-stack/v3/pkg/log"
+ "go.thethings.network/lorawan-stack/v3/pkg/random"
+ "go.thethings.network/lorawan-stack/v3/pkg/ratelimit"
+ "go.thethings.network/lorawan-stack/v3/pkg/task"
+ "go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
+ "go.thethings.network/lorawan-stack/v3/pkg/web"
+ "go.thethings.network/lorawan-stack/v3/pkg/webhandlers"
+ "go.thethings.network/lorawan-stack/v3/pkg/webmiddleware"
+ "nhooyr.io/websocket"
+)
+
+const (
+ authorizationProtocolPrefix = "ttn.lorawan.v3.header.authorization.bearer."
+ protocolV1 = "ttn.lorawan.v3.console.internal.events.v1"
+
+ pingPeriod = time.Minute
+ pingJitter = 0.1
+)
+
+// Component is the interface of the component to the events API handler.
+type Component interface {
+ task.Starter
+ Context() context.Context
+ RateLimiter() ratelimit.Interface
+ GetBaseConfig(context.Context) config.ServiceBase
+}
+
+type eventsHandler struct {
+ component Component
+ subscriber events.Subscriber
+ definedNames map[string]struct{}
+}
+
+var _ web.Registerer = (*eventsHandler)(nil)
+
+func (h *eventsHandler) RegisterRoutes(server *web.Server) {
+ router := server.APIRouter().PathPrefix(ttnpb.HTTPAPIPrefix + "/console/internal/events/").Subrouter()
+ router.Use(
+ mux.MiddlewareFunc(webmiddleware.Namespace("console/internal/events")),
+ mux.MiddlewareFunc(middleware.ProtocolAuthentication(authorizationProtocolPrefix)),
+ mux.MiddlewareFunc(webmiddleware.Metadata("Authorization")),
+ ratelimit.HTTPMiddleware(h.component.RateLimiter(), "http:console:internal:events"),
+ )
+ router.Path("/").HandlerFunc(h.handleEvents).Methods(http.MethodGet)
+}
+
+func (h *eventsHandler) handleEvents(w http.ResponseWriter, r *http.Request) {
+ ctx := r.Context()
+ logger := log.FromContext(ctx)
+
+ if err := rights.RequireAuthenticated(ctx); err != nil {
+ webhandlers.Error(w, r, err)
+ return
+ }
+
+ rateLimit, err := makeRateLimiter(ctx, h.component.RateLimiter())
+ if err != nil {
+ webhandlers.Error(w, r, err)
+ return
+ }
+
+ // Safari versions above 15 cannot handle compression correctly when the
+ // `NSURLSession Websocket` experimental feature is enabled (it is enabled by default).
+ // Versions above 17 still show the same issues, but the experimental feature is baseline.
+ // As such, we disable compression for Safari for all versions in order to ensure the best
+ // user experience.
+ // https://github.com/TheThingsNetwork/lorawan-stack/issues/6782
+ compressionMode := websocket.CompressionContextTakeover
+ if ua := useragent.Parse(r.UserAgent()); ua.Name == useragent.Safari {
+ compressionMode = websocket.CompressionDisabled
+ }
+
+ conn, err := websocket.Accept(w, r, &websocket.AcceptOptions{
+ Subprotocols: []string{protocolV1},
+ InsecureSkipVerify: true, // CORS is not enabled for APIs.
+ CompressionMode: compressionMode,
+ })
+ if err != nil {
+ logger.WithError(err).Debug("Failed to accept WebSocket")
+ return
+ }
+ defer conn.Close(websocket.StatusNormalClosure, "main task closed")
+
+ ctx, cancel := errorcontext.New(ctx)
+ defer cancel(nil)
+
+ var wg sync.WaitGroup
+ defer wg.Wait()
+
+ m := eventsmux.New(func(ctx context.Context, cancel func(error)) subscriptions.Interface {
+ return subscriptions.New(ctx, cancel, h.subscriber, h.definedNames, h.component)
+ })
+ for name, f := range map[string]func(context.Context) error{
+ "console_events_mux": makeMuxTask(m, cancel),
+ "console_events_read": makeReadTask(conn, m, rateLimit, cancel),
+ "console_events_write": makeWriteTask(conn, m, cancel),
+ "console_events_ping": makePingTask(conn, cancel, random.Jitter(pingPeriod, pingJitter)),
+ } {
+ wg.Add(1)
+ h.component.StartTask(&task.Config{
+ Context: ctx,
+ ID: name,
+ Func: f,
+ Done: wg.Done,
+ Restart: task.RestartNever,
+ Backoff: task.DefaultBackoffConfig,
+ })
+ }
+}
+
+// Option configures the events API handler.
+type Option func(*eventsHandler)
+
+// WithSubscriber configures the Subscriber to use for events.
+func WithSubscriber(subscriber events.Subscriber) Option {
+ return func(h *eventsHandler) {
+ h.subscriber = subscriber
+ }
+}
+
+// New returns an events API handler for the Console.
+func New(c Component, opts ...Option) web.Registerer {
+ definedNames := make(map[string]struct{})
+ for _, def := range events.All().Definitions() {
+ definedNames[def.Name()] = struct{}{}
+ }
+ h := &eventsHandler{
+ component: c,
+ subscriber: events.DefaultPubSub(),
+ definedNames: definedNames,
+ }
+ for _, opt := range opts {
+ opt(h)
+ }
+ return h
+}
diff --git a/pkg/console/internal/events/eventsmux/mux.go b/pkg/console/internal/events/eventsmux/mux.go
new file mode 100644
index 0000000000..8c5c2af3ba
--- /dev/null
+++ b/pkg/console/internal/events/eventsmux/mux.go
@@ -0,0 +1,111 @@
+// 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 eventsmux implements the events mux.
+package eventsmux
+
+import (
+ "context"
+
+ "go.thethings.network/lorawan-stack/v3/pkg/auth/rights"
+ "go.thethings.network/lorawan-stack/v3/pkg/console/internal/events/protocol"
+ "go.thethings.network/lorawan-stack/v3/pkg/console/internal/events/subscriptions"
+ "go.thethings.network/lorawan-stack/v3/pkg/errorcontext"
+ "go.thethings.network/lorawan-stack/v3/pkg/events"
+ "go.thethings.network/lorawan-stack/v3/pkg/log"
+)
+
+// Interface is the interface for the events mux.
+type Interface interface {
+ // Requests returns the channel for requests.
+ Requests() chan<- protocol.Request
+ // Responses returns the channel for responses.
+ Responses() <-chan protocol.Response
+
+ // Run runs the events mux.
+ Run(context.Context) error
+}
+
+type mux struct {
+ createSubs func(context.Context, func(error)) subscriptions.Interface
+
+ requestCh chan protocol.Request
+ responseCh chan protocol.Response
+}
+
+// Requests implements Interface.
+func (m *mux) Requests() chan<- protocol.Request {
+ return m.requestCh
+}
+
+// Responses implements Interface.
+func (m *mux) Responses() <-chan protocol.Response {
+ return m.responseCh
+}
+
+// Run implements Interface.
+func (m *mux) Run(ctx context.Context) (err error) {
+ ctx, cancel := errorcontext.New(ctx)
+ defer func() { cancel(err) }()
+ subs := m.createSubs(ctx, cancel)
+ defer subs.Close()
+ for {
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ case req := <-m.requestCh:
+ if err := rights.RequireAuthenticated(ctx); err != nil {
+ return err
+ }
+ var resp protocol.Response
+ switch req := req.(type) {
+ case *protocol.SubscribeRequest:
+ resp = req.Response(subs.Subscribe(req.ID, req.Identifiers, req.After, req.Tail, req.Names))
+ case *protocol.UnsubscribeRequest:
+ resp = req.Response(subs.Unsubscribe(req.ID))
+ default:
+ panic("unreachable")
+ }
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ case m.responseCh <- resp:
+ }
+ case subEvt := <-subs.SubscriptionEvents():
+ evtPB, err := events.Proto(subEvt.Event)
+ if err != nil {
+ log.FromContext(ctx).WithError(err).Warn("Failed to convert event to proto")
+ continue
+ }
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ case m.responseCh <- &protocol.PublishResponse{
+ ID: subEvt.ID,
+ Event: evtPB,
+ }:
+ }
+ }
+ }
+}
+
+// New returns a new Interface.
+func New(createSubs func(context.Context, func(error)) subscriptions.Interface) Interface {
+ return &mux{
+ createSubs: createSubs,
+
+ requestCh: make(chan protocol.Request, 1),
+ responseCh: make(chan protocol.Response, 1),
+ }
+}
diff --git a/pkg/console/internal/events/eventsmux/mux_test.go b/pkg/console/internal/events/eventsmux/mux_test.go
new file mode 100644
index 0000000000..895da2db1d
--- /dev/null
+++ b/pkg/console/internal/events/eventsmux/mux_test.go
@@ -0,0 +1,319 @@
+// 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 eventsmux_test
+
+import (
+ "context"
+ "errors"
+ "testing"
+ "time"
+
+ "go.thethings.network/lorawan-stack/v3/pkg/auth/rights"
+ "go.thethings.network/lorawan-stack/v3/pkg/console/internal/events/eventsmux"
+ "go.thethings.network/lorawan-stack/v3/pkg/console/internal/events/protocol"
+ "go.thethings.network/lorawan-stack/v3/pkg/console/internal/events/subscriptions"
+ "go.thethings.network/lorawan-stack/v3/pkg/events"
+ "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"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/status"
+)
+
+type subscribeRequest struct {
+ ID uint64
+ Identifiers []*ttnpb.EntityIdentifiers
+ After *time.Time
+ Tail uint32
+ Names []string
+
+ Response chan<- error
+}
+
+type unsubscribeRequest struct {
+ ID uint64
+
+ Response chan<- error
+}
+
+type mockSubscriptions struct {
+ ctx context.Context
+ subReqs chan subscribeRequest
+ unsubReqs chan unsubscribeRequest
+ evsCh chan *subscriptions.SubscriptionEvent
+}
+
+// Subscribe implements subscriptions.Interface.
+func (m *mockSubscriptions) Subscribe(
+ id uint64, identifiers []*ttnpb.EntityIdentifiers, after *time.Time, tail uint32, names []string,
+) error {
+ ch := make(chan error, 1)
+ select {
+ case <-m.ctx.Done():
+ return m.ctx.Err()
+ case m.subReqs <- subscribeRequest{
+ ID: id,
+ Identifiers: identifiers,
+ After: after,
+ Tail: tail,
+ Names: names,
+
+ Response: ch,
+ }:
+ select {
+ case <-m.ctx.Done():
+ return m.ctx.Err()
+ case err := <-ch:
+ return err
+ }
+ }
+}
+
+// Unsubscribe implements subscriptions.Interface.
+func (m *mockSubscriptions) Unsubscribe(id uint64) error {
+ ch := make(chan error, 1)
+ select {
+ case <-m.ctx.Done():
+ return m.ctx.Err()
+ case m.unsubReqs <- unsubscribeRequest{
+ ID: id,
+
+ Response: ch,
+ }:
+ select {
+ case <-m.ctx.Done():
+ return m.ctx.Err()
+ case err := <-ch:
+ return err
+ }
+ }
+}
+
+// SubscriptionEvents implements subscriptions.Interface.
+func (m *mockSubscriptions) SubscriptionEvents() <-chan *subscriptions.SubscriptionEvent {
+ return m.evsCh
+}
+
+// Close implements subscriptions.Interface.
+func (*mockSubscriptions) Close() error { return nil }
+
+var _ subscriptions.Interface = (*mockSubscriptions)(nil)
+
+func TestMux(t *testing.T) { // nolint:gocyclo
+ t.Parallel()
+
+ a, ctx := test.New(t)
+
+ appIDs := &ttnpb.ApplicationIdentifiers{
+ ApplicationId: "foo",
+ }
+ ctx = rights.NewContext(ctx, &rights.Rights{
+ ApplicationRights: *rights.NewMap(map[string]*ttnpb.Rights{
+ unique.ID(ctx, appIDs): ttnpb.RightsFrom(ttnpb.Right_RIGHT_ALL),
+ }),
+ })
+ ctx = rights.NewContextWithAuthInfo(ctx, &ttnpb.AuthInfoResponse{
+ UniversalRights: ttnpb.RightsFrom(ttnpb.Right_RIGHT_ALL),
+ IsAdmin: true,
+ })
+
+ subs := &mockSubscriptions{
+ ctx: ctx,
+ subReqs: make(chan subscribeRequest, 1),
+ unsubReqs: make(chan unsubscribeRequest, 1),
+ evsCh: make(chan *subscriptions.SubscriptionEvent, 1),
+ }
+ m := eventsmux.New(func(context.Context, func(error)) subscriptions.Interface { return subs })
+
+ go m.Run(ctx) // nolint:errcheck
+
+ now := time.Now()
+ select {
+ case <-ctx.Done():
+ return
+ case m.Requests() <- &protocol.SubscribeRequest{
+ ID: 42,
+ Identifiers: []*ttnpb.EntityIdentifiers{
+ appIDs.GetEntityIdentifiers(),
+ },
+ After: &now,
+ Tail: 1,
+ Names: []string{"foo"},
+ }:
+ }
+ select {
+ case <-ctx.Done():
+ return
+ case req := <-subs.subReqs:
+ a.So(req, should.Resemble, subscribeRequest{
+ ID: 42,
+ Identifiers: []*ttnpb.EntityIdentifiers{
+ appIDs.GetEntityIdentifiers(),
+ },
+ After: &now,
+ Tail: 1,
+ Names: []string{"foo"},
+
+ Response: req.Response,
+ })
+ select {
+ case <-ctx.Done():
+ return
+ case req.Response <- nil:
+ }
+ }
+ select {
+ case <-ctx.Done():
+ return
+ case resp := <-m.Responses():
+ a.So(resp, should.Resemble, &protocol.SubscribeResponse{
+ ID: 42,
+ })
+ }
+
+ errAlreadySubscribed := errors.New("already subscribed")
+ select {
+ case <-ctx.Done():
+ return
+ case m.Requests() <- &protocol.SubscribeRequest{
+ ID: 42,
+ Identifiers: []*ttnpb.EntityIdentifiers{
+ appIDs.GetEntityIdentifiers(),
+ },
+ After: &now,
+ Tail: 1,
+ Names: []string{"foo"},
+ }:
+ }
+ select {
+ case <-ctx.Done():
+ return
+ case req := <-subs.subReqs:
+ a.So(req, should.Resemble, subscribeRequest{
+ ID: 42,
+ Identifiers: []*ttnpb.EntityIdentifiers{
+ appIDs.GetEntityIdentifiers(),
+ },
+ After: &now,
+ Tail: 1,
+ Names: []string{"foo"},
+
+ Response: req.Response,
+ })
+ select {
+ case <-ctx.Done():
+ return
+ case req.Response <- errAlreadySubscribed:
+ }
+ }
+ select {
+ case <-ctx.Done():
+ return
+ case resp := <-m.Responses():
+ a.So(resp, should.Resemble, &protocol.ErrorResponse{
+ ID: 42,
+ Error: status.New(codes.Unknown, "already subscribed"),
+ })
+ }
+
+ ev := events.New(
+ ctx,
+ "test.evt",
+ "test event",
+ events.WithIdentifiers(appIDs),
+ )
+ select {
+ case <-ctx.Done():
+ return
+ case subs.evsCh <- &subscriptions.SubscriptionEvent{
+ ID: 42,
+ Event: ev,
+ }:
+ }
+ select {
+ case <-ctx.Done():
+ return
+ case resp := <-m.Responses():
+ a.So(resp, should.Resemble, &protocol.PublishResponse{
+ ID: 42,
+ Event: test.Must(events.Proto(ev)),
+ })
+ }
+
+ select {
+ case <-ctx.Done():
+ return
+ case m.Requests() <- &protocol.UnsubscribeRequest{
+ ID: 42,
+ }:
+ }
+ select {
+ case <-ctx.Done():
+ return
+ case req := <-subs.unsubReqs:
+ a.So(req, should.Resemble, unsubscribeRequest{
+ ID: 42,
+
+ Response: req.Response,
+ })
+ select {
+ case <-ctx.Done():
+ return
+ case req.Response <- nil:
+ }
+ }
+ select {
+ case <-ctx.Done():
+ return
+ case resp := <-m.Responses():
+ a.So(resp, should.Resemble, &protocol.UnsubscribeResponse{
+ ID: 42,
+ })
+ }
+
+ errNotSubscribed := errors.New("not subscribed")
+ select {
+ case <-ctx.Done():
+ return
+ case m.Requests() <- &protocol.UnsubscribeRequest{
+ ID: 42,
+ }:
+ }
+ select {
+ case <-ctx.Done():
+ return
+ case req := <-subs.unsubReqs:
+ a.So(req, should.Resemble, unsubscribeRequest{
+ ID: 42,
+
+ Response: req.Response,
+ })
+ select {
+ case <-ctx.Done():
+ return
+ case req.Response <- errNotSubscribed:
+ }
+ }
+ select {
+ case <-ctx.Done():
+ return
+ case resp := <-m.Responses():
+ a.So(resp, should.Resemble, &protocol.ErrorResponse{
+ ID: 42,
+ Error: status.New(codes.Unknown, "not subscribed"),
+ })
+ }
+}
diff --git a/pkg/console/internal/events/middleware/auth.go b/pkg/console/internal/events/middleware/auth.go
new file mode 100644
index 0000000000..6f7f18409e
--- /dev/null
+++ b/pkg/console/internal/events/middleware/auth.go
@@ -0,0 +1,93 @@
+// 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 middleware
+
+import (
+ "fmt"
+ "net/http"
+ "net/textproto"
+ "strings"
+
+ "go.thethings.network/lorawan-stack/v3/pkg/auth"
+)
+
+var (
+ protocolHeader = textproto.CanonicalMIMEHeaderKey("Sec-WebSocket-Protocol")
+ authorizationHeader = textproto.CanonicalMIMEHeaderKey("Authorization")
+ connectionHeader = textproto.CanonicalMIMEHeaderKey("Connection")
+ upgradeHeader = textproto.CanonicalMIMEHeaderKey("Upgrade")
+)
+
+func headerTokens(h http.Header, key string) []string {
+ var tokens []string
+ for _, value := range h[key] {
+ value := strings.Split(strings.TrimSpace(value), ",")
+ for _, token := range value {
+ token := strings.TrimSpace(token)
+ tokens = append(tokens, token)
+ }
+ }
+ return tokens
+}
+
+func containsHeaderToken(h http.Header, key, token string) bool {
+ for _, t := range headerTokens(h, key) {
+ if strings.EqualFold(t, token) {
+ return true
+ }
+ }
+ return false
+}
+
+func isWebSocketRequest(r *http.Request) bool {
+ h := r.Header
+ return containsHeaderToken(h, connectionHeader, "upgrade") && containsHeaderToken(h, upgradeHeader, "websocket")
+}
+
+// ProtocolAuthentication returns a middleware that authenticates WebSocket requests using the subprotocol.
+// The subprotocol must be prefixed with the given prefix.
+// The token is extracted from the subprotocol and used to authenticate the request.
+// If the token is valid, the subprotocol is removed from the request, and the original authorization header is removed.
+// If the token is invalid, the request is unchanged.
+func ProtocolAuthentication(prefix string) func(http.Handler) http.Handler {
+ prefixLen := len(prefix)
+ return func(next http.Handler) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ if !isWebSocketRequest(r) {
+ next.ServeHTTP(w, r)
+ return
+ }
+ var protocols []string
+ token := ""
+ for _, protocol := range headerTokens(r.Header, protocolHeader) {
+ p := strings.TrimSpace(protocol)
+ if len(p) >= prefixLen && strings.EqualFold(prefix, p[:prefixLen]) {
+ token = p[prefixLen:]
+ continue
+ }
+ protocols = append(protocols, p)
+ }
+ if _, _, _, err := auth.SplitToken(token); err == nil {
+ if len(protocols) > 0 {
+ r.Header.Set(protocolHeader, strings.Join(protocols, ","))
+ } else {
+ r.Header.Del(protocolHeader)
+ }
+ r.Header.Set(authorizationHeader, fmt.Sprintf("Bearer %s", token))
+ }
+ next.ServeHTTP(w, r)
+ })
+ }
+}
diff --git a/pkg/webui/lib/components/scroll-to-top.js b/pkg/console/internal/events/middleware/middleware.go
similarity index 66%
rename from pkg/webui/lib/components/scroll-to-top.js
rename to pkg/console/internal/events/middleware/middleware.go
index fa731830d0..61a7321356 100644
--- a/pkg/webui/lib/components/scroll-to-top.js
+++ b/pkg/console/internal/events/middleware/middleware.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,5 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import { useEffect } from 'react'
-import { useLocation } from 'react-router-dom'
-
-export default () => {
- const { pathname } = useLocation()
-
- useEffect(() => {
- window.scrollTo(0, 0)
- }, [pathname])
-
- return null
-}
+// Package middleware implements the events middleware.
+package middleware
diff --git a/pkg/console/internal/events/protocol/PROTOCOL.md b/pkg/console/internal/events/protocol/PROTOCOL.md
new file mode 100644
index 0000000000..c29ddd5685
--- /dev/null
+++ b/pkg/console/internal/events/protocol/PROTOCOL.md
@@ -0,0 +1,196 @@
+### Internal Events API
+
+The Console internal events API is designed as an alternative to the `Events.Stream` gRPC API for event stream interactions. It allows multiple subscriptions to be multiplexed over a singular [WebSocket](https://en.wikipedia.org/wiki/WebSocket) connection.
+
+### Reasoning
+
+The `Events.Stream` gRPC API is available to HTTP clients via [grpc-gateway](https://github.com/grpc-ecosystem/grpc-gateway). While translated to HTTP, it is visible as a long-polling request whose response body will contain the events as a series of JSON objects.
+
+This approach is efficient in the context of [HTTP/2](https://en.wikipedia.org/wiki/HTTP/2) which supports multiplexing multiple requests over a singular TCP connection.
+
+Unfortunately the connection between a browser and The Things Stack is susceptible to proxies. Corporate environments are generally equipped with such proxies, and in their presence the connections are downgraded to HTTP/1.1 semantics.
+
+In HTTP/1.1 connections can be used for a singular request at a time - it is not possible to multiplex the requests over a singular connection, and only [keep-alive](https://en.wikipedia.org/wiki/HTTP_persistent_connection) connections are available.
+
+This is problematic as browsers have builtin limits for the number of concurrent connections that singular windows may use. This leads to hard to debug issues which are hardly reproducible.
+
+But, there is one silver lining - the connection limit _does not apply to WebSocket connections_. The internal events API is designed to deal with this limitation while providing an experience similar to the original `Events.Stream` gRPC API.
+
+### Endpoint
+
+The endpoint for the internal events API is `/api/v3/console/internal/events/`. Note that the trailing slash is not optional.
+
+### Semantics
+
+The protocol is [full-duplex](https://en.wikipedia.org/wiki/Duplex_(telecommunications)#Full_duplex) - the client side and server side may transmit messages at any time without waiting for a response from the other party.
+
+The protocol is centered around subscriptions. Subscriptions are identified by an unsigned numerical ID, which is selected by the client.
+
+A subscription is initiated by the client via a subscription request, which the server confirms either with a subscription response or an error response.
+
+Following a successful subscription, the server may send at any time publication responses containing the subscription identifier and an event. The subscription identifier can be used on the client side in order to route the event to the appropriate component or view.
+
+A subscription can be terminated via an unsubscribe request, which the server confirms either with an unsubscribe response or an error response.
+
+The client can expect that no publication responses will follow an unsubscribe response, but it is recommended that subscription identifiers are not recycled within the same session.
+
+Error responses can be expected when the request contents are invalid (lack of identifiers, or invalid identifiers), or the caller is not authorized to subscribe to the provided identifiers. It is also invalid to request a subscription with the same identifier as an existing subscription, or to unsubscribe using an identifier which is not subscribed.
+
+Error response are provided as a debugging facility, and the errors are generally not fixable by the Console user.
+
+A special case exists for situations in which the caller is no longer authorized to receive any events associated with the provided identifiers _after_ the subscription response has been sent. This can happen if the caller token has expired or the rights have been revoked while the stream is ongoing. In such situations the server will terminate the connection explicitly.
+
+### Authentication and Authorization
+
+The authentication for the internal API is similar to other APIs available in The Things Stack. Given a `Bearer` token `t`, the `Authorization` header should contain the value `Bearer t`.
+
+Upon connecting, no authorization will take place - the endpoint only will check that the provided token is valid (i.e. exists and it is not expired).
+
+The [standard WebSocket API](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) [does not support custom request headers](https://github.com/whatwg/websockets/issues/16). As a result of this limitation, the backend allows the Console to provide the token as a [protocol](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/WebSocket#parameters). Specifically, given a `Bearer` token `t`, the following protocols should be provided to the `WebSocket` constructor:
+
+- `ttn.lorawan.v3.console.internal.events.v1`
+- `ttn.lorawan.v3.header.authorization.bearer.t`
+
+### Message Format
+
+Both requests and responses sent over the WebSocket connection are JSON encoded. All messages are JSON objects and are required to contain at least the following two fields:
+
+- `type`: a string whose value must be either `subscribe`, `unsubscribe`, `publish` or `error`.
+- `id`: an unsigned integer which identifies the underlying subscription being served.
+
+Each of the following subsections describes an individual message and the message direction (client to server or server to client).
+
+#### `SubscribeRequest` [C -> S]
+
+- `type`: `subscribe`
+- `id`: the subscription identifier
+- `identifiers`, `tail`, `after`, `names`: semantically the same fields as those of the `StreamEventsRequest` Protobuf message.
+
+Example:
+
+```json
+{
+ "type": "subscribe",
+ "id": 1,
+ "tail": 10,
+ "identifiers": [
+ {
+ "application_ids": {
+ "application_id": "app1"
+ }
+ }
+ ]
+}
+```
+
+#### `SubscribeResponse` [S -> C]
+
+- `type`: `subscribe`
+- `id`: the subscription identifier
+
+Example:
+
+```json
+{
+ "type": "subscribe",
+ "id": 1
+}
+```
+
+#### `UnsubscribeRequest` [C -> S]
+
+- `type`: `unsubscribe`
+- `id`: the subscription identifier
+
+Example:
+
+```json
+{
+ "type": "unsubscribe",
+ "id": 1
+}
+```
+
+#### `UnsubscribeResponse` [S -> C]
+
+- `type`: `unsubscribe`
+- `id`: the subscription identifier
+
+Example:
+
+```json
+{
+ "type": "unsubscribe",
+ "id": 1
+}
+```
+
+#### `PublishResponse` [S -> C]
+
+- `type`: `publish`
+- `id`: the subscription identifier
+- `event`: an `Event` Protobuf message encoded as a JSON object
+
+Example:
+
+```json
+{
+ "type": "publish",
+ "id": 1,
+ "event": {
+ "name": "as.up.data.forward",
+ "time": "2023-10-26T16:27:14.103854Z",
+ "identifiers": [
+ {
+ "device_ids": {
+ "device_id": "eui-0000000000000003",
+ "application_ids": {
+ "application_id": "app1"
+ }
+ }
+ }
+ ],
+ "context": {
+ "tenant-id": "Cgl0aGV0aGluZ3M="
+ },
+ "visibility": {
+ "rights": [
+ "RIGHT_APPLICATION_TRAFFIC_READ"
+ ]
+ },
+ "unique_id": "01HDPCZDSQ358JMHD4SC2BQAB8"
+ }
+}
+```
+
+#### ErrorResponse [S -> C]
+
+- `type`: `error`
+- `id`: the subscription identifier
+- `error`: a `Status` Protobuf message encoded as a JSON object
+
+Example:
+
+```json
+{
+ "type": "error",
+ "id": 1,
+ "error": {
+ "code": 6,
+ "message": "error:pkg/console/internal/events/subscriptions:already_subscribed (already subscribed with ID `1`)",
+ "details": [
+ {
+ "@type": "type.googleapis.com/ttn.lorawan.v3.ErrorDetails",
+ "namespace": "pkg/console/internal/events/subscriptions",
+ "name": "already_subscribed",
+ "message_format": "already subscribed with ID `{id}`",
+ "attributes": {
+ "id": "1"
+ },
+ "correlation_id": "5da004b9f61f479aafe5bbcae4551e63",
+ "code": 6
+ }
+ ]
+ }
+}
+```
diff --git a/pkg/console/internal/events/protocol/protocol.go b/pkg/console/internal/events/protocol/protocol.go
new file mode 100644
index 0000000000..3348a8dc82
--- /dev/null
+++ b/pkg/console/internal/events/protocol/protocol.go
@@ -0,0 +1,331 @@
+// 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 protocol implements the protocol for the events package.
+package protocol
+
+import (
+ "encoding/json"
+ "time"
+
+ "go.thethings.network/lorawan-stack/v3/pkg/errors"
+ "go.thethings.network/lorawan-stack/v3/pkg/jsonpb"
+ "go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
+ statuspb "google.golang.org/genproto/googleapis/rpc/status"
+ "google.golang.org/grpc/status"
+)
+
+var (
+ errMessageType = errors.DefineInvalidArgument("message_type", "invalid message type `{type}`")
+
+ _ json.Marshaler = (*ttnpb.EntityIdentifiers)(nil)
+ _ json.Unmarshaler = (*ttnpb.EntityIdentifiers)(nil)
+
+ _ json.Marshaler = (*ttnpb.Event)(nil)
+ _ json.Unmarshaler = (*ttnpb.Event)(nil)
+)
+
+// MessageType is the type of a message.
+type MessageType int
+
+const (
+ // MessageTypeSubscribe is the type of a subscribe message.
+ MessageTypeSubscribe MessageType = iota
+ // MessageTypeUnsubscribe is the type of an unsubscribe message.
+ MessageTypeUnsubscribe
+ // MessageTypePublish is the type of a publish message.
+ MessageTypePublish
+ // MessageTypeError is the type of an error message.
+ MessageTypeError
+)
+
+// MarshalJSON implements json.Marshaler.
+func (m MessageType) MarshalJSON() ([]byte, error) {
+ switch m {
+ case MessageTypeSubscribe:
+ return []byte(`"subscribe"`), nil
+ case MessageTypeUnsubscribe:
+ return []byte(`"unsubscribe"`), nil
+ case MessageTypePublish:
+ return []byte(`"publish"`), nil
+ case MessageTypeError:
+ return []byte(`"error"`), nil
+ default:
+ return nil, errMessageType.WithAttributes("type", m)
+ }
+}
+
+// UnmarshalJSON implements json.Unmarshaler.
+func (m *MessageType) UnmarshalJSON(data []byte) error {
+ switch string(data) {
+ case `"subscribe"`:
+ *m = MessageTypeSubscribe
+ case `"unsubscribe"`:
+ *m = MessageTypeUnsubscribe
+ case `"publish"`:
+ *m = MessageTypePublish
+ case `"error"`:
+ *m = MessageTypeError
+ default:
+ return errMessageType.WithAttributes("type", string(data))
+ }
+ return nil
+}
+
+// Request is a request message.
+type Request interface {
+ _requestMessage()
+}
+
+// Response is a response message.
+type Response interface {
+ _responseMessage()
+}
+
+// SubscribeRequest is the request to subscribe to events.
+type SubscribeRequest struct {
+ ID uint64 `json:"id"`
+ Identifiers []*ttnpb.EntityIdentifiers `json:"identifiers"`
+ Tail uint32 `json:"tail"`
+ After *time.Time `json:"after"`
+ Names []string `json:"names"`
+}
+
+func (SubscribeRequest) _requestMessage() {}
+
+// Response builds a response to the request.
+func (m SubscribeRequest) Response(err error) Response {
+ if err != nil {
+ return newErrorResponse(m.ID, err)
+ }
+ return &SubscribeResponse{
+ ID: m.ID,
+ }
+}
+
+// MarshalJSON implements json.Marshaler.
+func (m SubscribeRequest) MarshalJSON() ([]byte, error) {
+ type alias SubscribeRequest
+ return jsonpb.TTN().Marshal(struct {
+ Type MessageType `json:"type"`
+ alias
+ }{
+ Type: MessageTypeSubscribe,
+ alias: alias(m),
+ })
+}
+
+// SubscribeResponse is the response to a subscribe request.
+type SubscribeResponse struct {
+ ID uint64 `json:"id"`
+}
+
+func (SubscribeResponse) _responseMessage() {}
+
+// MarshalJSON implements json.Marshaler.
+func (m SubscribeResponse) MarshalJSON() ([]byte, error) {
+ type alias SubscribeResponse
+ return jsonpb.TTN().Marshal(struct {
+ Type MessageType `json:"type"`
+ alias
+ }{
+ Type: MessageTypeSubscribe,
+ alias: alias(m),
+ })
+}
+
+// UnsubscribeRequest is the request to unsubscribe from events.
+type UnsubscribeRequest struct {
+ ID uint64 `json:"id"`
+}
+
+func (UnsubscribeRequest) _requestMessage() {}
+
+// MarshalJSON implements json.Marshaler.
+func (m UnsubscribeRequest) MarshalJSON() ([]byte, error) {
+ type alias UnsubscribeRequest
+ return jsonpb.TTN().Marshal(struct {
+ Type MessageType `json:"type"`
+ alias
+ }{
+ Type: MessageTypeUnsubscribe,
+ alias: alias(m),
+ })
+}
+
+// UnsubscribeResponse is the response to an unsubscribe request.
+type UnsubscribeResponse struct {
+ ID uint64 `json:"id"`
+}
+
+func (UnsubscribeResponse) _responseMessage() {}
+
+// Response builds a response to the request.
+func (m UnsubscribeRequest) Response(err error) Response {
+ if err != nil {
+ return newErrorResponse(m.ID, err)
+ }
+ return &UnsubscribeResponse{
+ ID: m.ID,
+ }
+}
+
+// MarshalJSON implements json.Marshaler.
+func (m UnsubscribeResponse) MarshalJSON() ([]byte, error) {
+ type alias UnsubscribeResponse
+ return jsonpb.TTN().Marshal(struct {
+ Type MessageType `json:"type"`
+ alias
+ }{
+ Type: MessageTypeUnsubscribe,
+ alias: alias(m),
+ })
+}
+
+// PublishResponse is the request to publish an event.
+type PublishResponse struct {
+ ID uint64 `json:"id"`
+ Event *ttnpb.Event `json:"event"`
+}
+
+func (PublishResponse) _responseMessage() {}
+
+// MarshalJSON implements json.Marshaler.
+func (m PublishResponse) MarshalJSON() ([]byte, error) {
+ type alias PublishResponse
+ return jsonpb.TTN().Marshal(struct {
+ Type MessageType `json:"type"`
+ alias
+ }{
+ Type: MessageTypePublish,
+ alias: alias(m),
+ })
+}
+
+// ErrorResponse is the response to an error.
+type ErrorResponse struct {
+ ID uint64
+ Error *status.Status
+}
+
+func (ErrorResponse) _responseMessage() {}
+
+// statusAlias is an alias of status.Status which supports JSON marshaling.
+type statusAlias statuspb.Status
+
+// MarshalJSON implements json.Marshaler.
+func (s *statusAlias) MarshalJSON() ([]byte, error) {
+ return jsonpb.TTN().Marshal((*statuspb.Status)(s))
+}
+
+// UnmarshalJSON implements json.Unmarshaler.
+func (s *statusAlias) UnmarshalJSON(data []byte) error {
+ return jsonpb.TTN().Unmarshal(data, (*statuspb.Status)(s))
+}
+
+// MarshalJSON implements json.Marshaler.
+func (m ErrorResponse) MarshalJSON() ([]byte, error) {
+ return jsonpb.TTN().Marshal(struct {
+ Type MessageType `json:"type"`
+ ID uint64 `json:"id"`
+ Error *statusAlias `json:"error"`
+ }{
+ Type: MessageTypeError,
+ ID: m.ID,
+ Error: (*statusAlias)(m.Error.Proto()),
+ })
+}
+
+func newErrorResponse(id uint64, err error) Response {
+ return &ErrorResponse{
+ ID: id,
+ Error: status.Convert(err),
+ }
+}
+
+// UnmarshalJSON implements json.Unmarshaler.
+func (m *ErrorResponse) UnmarshalJSON(data []byte) error {
+ var alias struct {
+ ID uint64 `json:"id"`
+ Error *statusAlias `json:"error"`
+ }
+ if err := jsonpb.TTN().Unmarshal(data, &alias); err != nil {
+ return err
+ }
+ m.ID = alias.ID
+ m.Error = status.FromProto((*statuspb.Status)(alias.Error))
+ return nil
+}
+
+// RequestWrapper wraps a request to be sent over the websocket.
+type RequestWrapper struct {
+ Contents Request
+}
+
+// UnmarshalJSON implements json.Unmarshaler.
+func (m *RequestWrapper) UnmarshalJSON(data []byte) error {
+ var contents struct {
+ Type MessageType `json:"type"`
+ }
+ if err := jsonpb.TTN().Unmarshal(data, &contents); err != nil {
+ return err
+ }
+ switch contents.Type {
+ case MessageTypeSubscribe:
+ m.Contents = &SubscribeRequest{}
+ case MessageTypeUnsubscribe:
+ m.Contents = &UnsubscribeRequest{}
+ default:
+ return errMessageType.WithAttributes("type", contents.Type)
+ }
+ return jsonpb.TTN().Unmarshal(data, m.Contents)
+}
+
+// MarshalJSON implements json.Marshaler.
+func (m RequestWrapper) MarshalJSON() ([]byte, error) {
+ return json.Marshal(m.Contents)
+}
+
+// ResponseWrapper wraps a response to be sent over the websocket.
+type ResponseWrapper struct {
+ Contents Response
+}
+
+// UnmarshalJSON implements json.Unmarshaler.
+func (m *ResponseWrapper) UnmarshalJSON(data []byte) error {
+ var contents struct {
+ Type MessageType `json:"type"`
+ }
+ if err := jsonpb.TTN().Unmarshal(data, &contents); err != nil {
+ return err
+ }
+ switch contents.Type {
+ case MessageTypeSubscribe:
+ m.Contents = &SubscribeResponse{}
+ case MessageTypeUnsubscribe:
+ m.Contents = &UnsubscribeResponse{}
+ case MessageTypePublish:
+ m.Contents = &PublishResponse{}
+ case MessageTypeError:
+ m.Contents = &ErrorResponse{}
+ default:
+ return errMessageType.WithAttributes("type", contents.Type)
+ }
+ return jsonpb.TTN().Unmarshal(data, m.Contents)
+}
+
+// MarshalJSON implements json.Marshaler.
+func (m ResponseWrapper) MarshalJSON() ([]byte, error) {
+ return json.Marshal(m.Contents)
+}
diff --git a/pkg/console/internal/events/protocol/protocol_test.go b/pkg/console/internal/events/protocol/protocol_test.go
new file mode 100644
index 0000000000..bec85bc950
--- /dev/null
+++ b/pkg/console/internal/events/protocol/protocol_test.go
@@ -0,0 +1,220 @@
+// 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 protocol_test
+
+import (
+ "encoding/json"
+ "fmt"
+ "testing"
+ "time"
+
+ "github.com/smarty/assertions"
+ "go.thethings.network/lorawan-stack/v3/pkg/console/internal/events/protocol"
+ "go.thethings.network/lorawan-stack/v3/pkg/errors"
+ "go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
+ "go.thethings.network/lorawan-stack/v3/pkg/util/test"
+ "go.thethings.network/lorawan-stack/v3/pkg/util/test/assertions/should"
+ "google.golang.org/grpc/status"
+ "google.golang.org/protobuf/types/known/anypb"
+ "google.golang.org/protobuf/types/known/timestamppb"
+)
+
+func TestMarshal(t *testing.T) {
+ t.Parallel()
+
+ a := assertions.New(t)
+
+ b, err := json.Marshal(protocol.MessageTypePublish)
+ if a.So(err, should.BeNil) {
+ a.So(b, should.Resemble, []byte(`"publish"`))
+ }
+ var tp protocol.MessageType
+ err = json.Unmarshal([]byte(`"publish"`), &tp)
+ if a.So(err, should.BeNil) {
+ a.So(tp, should.Equal, protocol.MessageTypePublish)
+ }
+
+ b, err = json.Marshal(&protocol.SubscribeRequest{
+ ID: 0x42,
+ Identifiers: []*ttnpb.EntityIdentifiers{
+ (&ttnpb.ApplicationIdentifiers{ApplicationId: "foo"}).GetEntityIdentifiers(),
+ (&ttnpb.ClientIdentifiers{ClientId: "bar"}).GetEntityIdentifiers(),
+ },
+ Tail: 10,
+ After: timePtr(time.UnixMilli(123456789012).UTC()),
+ Names: []string{"foo", "bar"},
+ })
+ if a.So(err, should.BeNil) {
+ a.So(
+ b,
+ should.Resemble,
+ []byte(`{"type":"subscribe","id":66,"identifiers":[{"application_ids":{"application_id":"foo"}},{"client_ids":{"client_id":"bar"}}],"tail":10,"after":"1973-11-29T21:33:09.012Z","names":["foo","bar"]}`), // nolint:lll
+ )
+ }
+ var subReq protocol.SubscribeRequest
+ err = json.Unmarshal(
+ []byte(`{"type":"subscribe","id":66,"identifiers":[{"application_ids":{"application_id":"foo"}},{"client_ids":{"client_id":"bar"}}],"tail":10,"after":"1973-11-29T21:33:09.012Z","names":["foo","bar"]}`), // nolint:lll
+ &subReq,
+ )
+ if a.So(err, should.BeNil) {
+ a.So(subReq, should.Resemble, protocol.SubscribeRequest{
+ ID: 0x42,
+ Identifiers: []*ttnpb.EntityIdentifiers{
+ (&ttnpb.ApplicationIdentifiers{ApplicationId: "foo"}).GetEntityIdentifiers(),
+ (&ttnpb.ClientIdentifiers{ClientId: "bar"}).GetEntityIdentifiers(),
+ },
+ Tail: 10,
+ After: timePtr(time.UnixMilli(123456789012).UTC()),
+ Names: []string{"foo", "bar"},
+ })
+ }
+
+ b, err = json.Marshal(&protocol.SubscribeResponse{
+ ID: 0x42,
+ })
+ if a.So(err, should.BeNil) {
+ a.So(b, should.Resemble, []byte(`{"type":"subscribe","id":66}`))
+ }
+ var subResp protocol.SubscribeResponse
+ err = json.Unmarshal([]byte(`{"type":"subscribe","id":66}`), &subResp)
+ if a.So(err, should.BeNil) {
+ a.So(subResp, should.Resemble, protocol.SubscribeResponse{ID: 0x42})
+ }
+
+ b, err = json.Marshal(&protocol.UnsubscribeRequest{
+ ID: 0x42,
+ })
+ if a.So(err, should.BeNil) {
+ a.So(b, should.Resemble, []byte(`{"type":"unsubscribe","id":66}`))
+ }
+ var unsubReq protocol.UnsubscribeRequest
+ err = json.Unmarshal([]byte(`{"type":"unsubscribe","id":66}`), &unsubReq)
+ if a.So(err, should.BeNil) {
+ a.So(unsubReq, should.Resemble, protocol.UnsubscribeRequest{ID: 0x42})
+ }
+
+ b, err = json.Marshal(&protocol.UnsubscribeResponse{
+ ID: 0x42,
+ })
+ if a.So(err, should.BeNil) {
+ a.So(b, should.Resemble, []byte(`{"type":"unsubscribe","id":66}`))
+ }
+ var unsubResp protocol.UnsubscribeResponse
+ err = json.Unmarshal([]byte(`{"type":"unsubscribe","id":66}`), &unsubResp)
+ if a.So(err, should.BeNil) {
+ a.So(unsubResp, should.Resemble, protocol.UnsubscribeResponse{ID: 0x42})
+ }
+
+ b, err = json.Marshal(&protocol.PublishResponse{
+ ID: 0x42,
+ Event: &ttnpb.Event{
+ Name: "foo",
+ Time: timestamppb.New(time.UnixMilli(123456789012).UTC()),
+ Identifiers: []*ttnpb.EntityIdentifiers{
+ (&ttnpb.ApplicationIdentifiers{ApplicationId: "foo"}).GetEntityIdentifiers(),
+ },
+ Data: test.Must(anypb.New(&ttnpb.ApplicationUp{
+ Up: &ttnpb.ApplicationUp_UplinkMessage{
+ UplinkMessage: &ttnpb.ApplicationUplink{},
+ },
+ })),
+ CorrelationIds: []string{"foo", "bar"},
+ },
+ })
+ if a.So(err, should.BeNil) {
+ a.So(
+ b,
+ should.Resemble,
+ []byte(`{"type":"publish","id":66,"event":{"name":"foo","time":"1973-11-29T21:33:09.012Z","identifiers":[{"application_ids":{"application_id":"foo"}}],"data":{"@type":"type.googleapis.com/ttn.lorawan.v3.ApplicationUp","uplink_message":{}},"correlation_ids":["foo","bar"]}}`), // nolint:lll
+ )
+ }
+ var pubResp protocol.PublishResponse
+ err = json.Unmarshal(
+ []byte(`{"type":"publish","id":66,"event":{"name":"foo","time":"1973-11-29T21:33:09.012Z","identifiers":[{"application_ids":{"application_id":"foo"}}],"data":{"@type":"type.googleapis.com/ttn.lorawan.v3.ApplicationUp","uplink_message":{}},"correlation_ids":["foo","bar"]}}`), // nolint:lll
+ &pubResp,
+ )
+ if a.So(err, should.BeNil) {
+ a.So(pubResp, should.Resemble, protocol.PublishResponse{
+ ID: 0x42,
+ Event: &ttnpb.Event{
+ Name: "foo",
+ Time: timestamppb.New(time.UnixMilli(123456789012).UTC()),
+ Identifiers: []*ttnpb.EntityIdentifiers{
+ (&ttnpb.ApplicationIdentifiers{ApplicationId: "foo"}).GetEntityIdentifiers(),
+ },
+ Data: test.Must(anypb.New(&ttnpb.ApplicationUp{
+ Up: &ttnpb.ApplicationUp_UplinkMessage{
+ UplinkMessage: &ttnpb.ApplicationUplink{},
+ },
+ })),
+ CorrelationIds: []string{"foo", "bar"},
+ },
+ })
+ }
+
+ errDefinition := errors.DefineInvalidArgument("bad_argument", "bad argument `{argument}`")
+ errInstance := errDefinition.WithAttributes("argument", "foo")
+ errStatus := status.Convert(errInstance)
+ errJSON := test.Must(json.Marshal(errInstance))
+ b, err = json.Marshal(&protocol.ErrorResponse{
+ ID: 0x42,
+ Error: errStatus,
+ })
+ if a.So(err, should.BeNil) {
+ a.So(b, should.Resemble, []byte(fmt.Sprintf(`{"type":"error","id":66,"error":%v}`, string(errJSON)))) // nolint:lll
+ }
+ var errResp protocol.ErrorResponse
+ err = json.Unmarshal([]byte(fmt.Sprintf(`{"type":"error","id":66,"error":%v}`, string(errJSON))), &errResp) // nolint:lll
+ if a.So(err, should.BeNil) {
+ a.So(errResp, should.Resemble, protocol.ErrorResponse{
+ ID: 0x42,
+ Error: errStatus,
+ })
+ }
+
+ var reqWrapper protocol.RequestWrapper
+ err = json.Unmarshal(
+ []byte(`{"type":"subscribe","id":66,"identifiers":[{"application_ids":{"application_id":"foo"}},{"client_ids":{"client_id":"bar"}}],"tail":10,"after":"1973-11-29T21:33:09.012Z","names":["foo","bar"]}`), // nolint:lll
+ &reqWrapper,
+ )
+ if a.So(err, should.BeNil) {
+ a.So(reqWrapper, should.Resemble, protocol.RequestWrapper{
+ Contents: &protocol.SubscribeRequest{
+ ID: 0x42,
+ Identifiers: []*ttnpb.EntityIdentifiers{
+ (&ttnpb.ApplicationIdentifiers{ApplicationId: "foo"}).GetEntityIdentifiers(),
+ (&ttnpb.ClientIdentifiers{ClientId: "bar"}).GetEntityIdentifiers(),
+ },
+ Tail: 10,
+ After: timePtr(time.UnixMilli(123456789012).UTC()),
+ Names: []string{"foo", "bar"},
+ },
+ })
+ }
+
+ var respWrapper protocol.ResponseWrapper
+ err = json.Unmarshal([]byte(`{"type":"subscribe","id":66}`), &respWrapper)
+ if a.So(err, should.BeNil) {
+ a.So(respWrapper, should.Resemble, protocol.ResponseWrapper{
+ Contents: &protocol.SubscribeResponse{
+ ID: 0x42,
+ },
+ })
+ }
+}
+
+func timePtr(t time.Time) *time.Time {
+ return &t
+}
diff --git a/pkg/console/internal/events/ratelimit.go b/pkg/console/internal/events/ratelimit.go
new file mode 100644
index 0000000000..4e8c0369dc
--- /dev/null
+++ b/pkg/console/internal/events/ratelimit.go
@@ -0,0 +1,56 @@
+// 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 (
+ "context"
+ "fmt"
+
+ "go.thethings.network/lorawan-stack/v3/pkg/auth/rights"
+ "go.thethings.network/lorawan-stack/v3/pkg/errors"
+ "go.thethings.network/lorawan-stack/v3/pkg/ratelimit"
+ "go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
+)
+
+var (
+ errUnknownCaller = errors.DefineInternal("unknown_caller", "unknown caller type `{type}`")
+ errRateExceeded = errors.DefineResourceExhausted("rate_exceeded", "request rate exceeded")
+)
+
+func makeRateLimiter(ctx context.Context, limiter ratelimit.Interface) (func() error, error) {
+ authInfo, err := rights.AuthInfo(ctx)
+ if err != nil {
+ return nil, err
+ }
+ resourceID := ""
+ switch method := authInfo.AccessMethod.(type) {
+ case *ttnpb.AuthInfoResponse_ApiKey:
+ resourceID = fmt.Sprintf("api-key:%s", method.ApiKey.ApiKey.Id)
+ case *ttnpb.AuthInfoResponse_OauthAccessToken:
+ resourceID = fmt.Sprintf("access-token:%s", method.OauthAccessToken.Id)
+ case *ttnpb.AuthInfoResponse_UserSession:
+ resourceID = fmt.Sprintf("session-id:%s", method.UserSession.SessionId)
+ // NOTE: *ttnpb.AuthInfoResponse_GatewayToken_ is intentionally left out.
+ default:
+ return nil, errUnknownCaller.WithAttributes("type", fmt.Sprintf("%T", authInfo.AccessMethod))
+ }
+ resource := ratelimit.ConsoleEventsRequestResource(resourceID)
+ return func() error {
+ if limit, _ := limiter.RateLimit(resource); limit {
+ return errRateExceeded.New()
+ }
+ return nil
+ }, nil
+}
diff --git a/pkg/console/internal/events/subscriptions/subscriptions.go b/pkg/console/internal/events/subscriptions/subscriptions.go
new file mode 100644
index 0000000000..faea7a4b73
--- /dev/null
+++ b/pkg/console/internal/events/subscriptions/subscriptions.go
@@ -0,0 +1,256 @@
+// 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 subscriptions implements the events mux subscriptions.
+package subscriptions
+
+import (
+ "context"
+ "sync"
+ "time"
+
+ "go.thethings.network/lorawan-stack/v3/pkg/auth/rights"
+ "go.thethings.network/lorawan-stack/v3/pkg/auth/rights/rightsutil"
+ "go.thethings.network/lorawan-stack/v3/pkg/errorcontext"
+ "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/task"
+ "go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
+)
+
+// SubscriptionEvent wraps an events.Event with a subscription ID.
+type SubscriptionEvent struct {
+ ID uint64
+ Event events.Event
+}
+
+// Interface is the interface for the events mux subscriptions.
+type Interface interface {
+ // Subscribe subscribes to events.
+ Subscribe(
+ id uint64, identifiers []*ttnpb.EntityIdentifiers, after *time.Time, tail uint32, names []string,
+ ) error
+ // Unsubscribe unsubscribe to events.
+ Unsubscribe(id uint64) error
+
+ // SubscriptionEvents provides the events for the underlying subscriptions.
+ SubscriptionEvents() <-chan *SubscriptionEvent
+
+ // Close closes all of the underlying subscriptions and waits for the background tasks to finish.
+ Close() error
+}
+
+type subscription struct {
+ id uint64
+ cancel func(error)
+ wg sync.WaitGroup
+ cancelParent func(error)
+ inputCh <-chan events.Event
+ outputCh chan<- *SubscriptionEvent
+}
+
+func (s *subscription) run(ctx context.Context) (err error) {
+ defer func() {
+ select {
+ case <-ctx.Done():
+ default:
+ s.cancelParent(err)
+ }
+ }()
+ for {
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ case evt := <-s.inputCh:
+ isVisible, err := rightsutil.EventIsVisible(ctx, evt)
+ if err != nil {
+ if err := rights.RequireAny(ctx, evt.Identifiers()...); err != nil {
+ return err
+ }
+ log.FromContext(ctx).WithError(err).Warn("Failed to check event visibility")
+ continue
+ }
+ if !isVisible {
+ continue
+ }
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ case s.outputCh <- &SubscriptionEvent{
+ ID: s.id,
+ Event: evt,
+ }:
+ }
+ }
+ }
+}
+
+type subscriptions struct {
+ ctx context.Context
+ cancel func(error)
+ subscriber events.Subscriber
+ definedNames map[string]struct{}
+ taskStarter task.Starter
+
+ wg sync.WaitGroup
+ ch chan *SubscriptionEvent
+ subs map[uint64]*subscription
+}
+
+var _ Interface = (*subscriptions)(nil)
+
+// Close implements Interface.
+func (s *subscriptions) Close() error {
+ for id, sub := range s.subs {
+ delete(s.subs, id)
+ sub.cancel(nil)
+ sub.wg.Wait()
+ }
+ s.wg.Wait()
+ return nil
+}
+
+// SubscriptionEvents implements Interface.
+func (s *subscriptions) SubscriptionEvents() <-chan *SubscriptionEvent { return s.ch }
+
+var (
+ errAlreadySubscribed = errors.DefineAlreadyExists("already_subscribed", "already subscribed with ID `{id}`")
+ errNoIdentifiers = errors.DefineInvalidArgument("no_identifiers", "no identifiers")
+)
+
+// Subscribe implements Interface.
+func (s *subscriptions) Subscribe(
+ id uint64, identifiers []*ttnpb.EntityIdentifiers, after *time.Time, tail uint32, names []string,
+) (err error) {
+ if err := s.validateSubscribe(id, identifiers); err != nil {
+ return err
+ }
+ names, err = events.NamesFromPatterns(s.definedNames, names)
+ if err != nil {
+ return err
+ }
+ ch := make(chan events.Event, channelSize(tail))
+ ctx, cancel := errorcontext.New(s.ctx)
+ defer func() {
+ if err != nil {
+ cancel(err)
+ }
+ }()
+ if store, hasStore := s.subscriber.(events.Store); hasStore {
+ if after == nil && tail == 0 {
+ now := time.Now()
+ after = &now
+ }
+ f := func(ctx context.Context) (err error) {
+ defer func() {
+ select {
+ case <-ctx.Done():
+ default:
+ s.cancel(err)
+ }
+ }()
+ return store.SubscribeWithHistory(ctx, names, identifiers, after, int(tail), events.Channel(ch))
+ }
+ s.wg.Add(1)
+ s.taskStarter.StartTask(&task.Config{
+ Context: ctx,
+ ID: "console_events_subscribe",
+ Func: f,
+ Done: s.wg.Done,
+ Restart: task.RestartNever,
+ Backoff: task.DefaultBackoffConfig,
+ })
+ } else {
+ if err := s.subscriber.Subscribe(ctx, names, identifiers, events.Channel(ch)); err != nil {
+ return err
+ }
+ }
+ sub := &subscription{
+ id: id,
+ cancel: cancel,
+ cancelParent: s.cancel,
+ inputCh: ch,
+ outputCh: s.ch,
+ }
+ sub.wg.Add(1)
+ s.taskStarter.StartTask(&task.Config{
+ Context: ctx,
+ ID: "console_events_filter",
+ Func: sub.run,
+ Done: sub.wg.Done,
+ Restart: task.RestartNever,
+ Backoff: task.DefaultBackoffConfig,
+ })
+ s.subs[id] = sub
+ return nil
+}
+
+var errNotSubscribed = errors.DefineNotFound("not_subscribed", "not subscribed with ID `{id}`")
+
+// Unsubscribe implements Interface.
+func (s *subscriptions) Unsubscribe(id uint64) error {
+ sub, ok := s.subs[id]
+ if !ok {
+ return errNotSubscribed.WithAttributes("id", id)
+ }
+ delete(s.subs, id)
+ sub.cancel(nil)
+ sub.wg.Wait()
+ return nil
+}
+
+// New returns a new Interface.
+func New(
+ ctx context.Context,
+ cancel func(error),
+ subscriber events.Subscriber,
+ definedNames map[string]struct{},
+ taskStarter task.Starter,
+) Interface {
+ return &subscriptions{
+ ctx: ctx,
+ cancel: cancel,
+ subscriber: subscriber,
+ definedNames: definedNames,
+ taskStarter: taskStarter,
+ ch: make(chan *SubscriptionEvent, 1),
+ subs: make(map[uint64]*subscription),
+ }
+}
+
+func (s *subscriptions) validateSubscribe(id uint64, identifiers []*ttnpb.EntityIdentifiers) error {
+ if _, ok := s.subs[id]; ok {
+ return errAlreadySubscribed.WithAttributes("id", id)
+ }
+ if len(identifiers) == 0 {
+ return errNoIdentifiers.New()
+ }
+ for _, ids := range identifiers {
+ if err := ids.ValidateFields(); err != nil {
+ return err
+ }
+ }
+ return rights.RequireAny(s.ctx, identifiers...)
+}
+
+func channelSize(n uint32) uint32 {
+ if n < 8 {
+ n = 8
+ }
+ if n > 1024 {
+ n = 1024
+ }
+ return n
+}
diff --git a/pkg/console/internal/events/subscriptions/subscriptions_test.go b/pkg/console/internal/events/subscriptions/subscriptions_test.go
new file mode 100644
index 0000000000..a397789e1c
--- /dev/null
+++ b/pkg/console/internal/events/subscriptions/subscriptions_test.go
@@ -0,0 +1,304 @@
+// 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 subscriptions_test
+
+import (
+ "context"
+ "sync"
+ "testing"
+ "time"
+
+ "go.thethings.network/lorawan-stack/v3/pkg/auth/rights"
+ "go.thethings.network/lorawan-stack/v3/pkg/console/internal/events/subscriptions"
+ "go.thethings.network/lorawan-stack/v3/pkg/errorcontext"
+ "go.thethings.network/lorawan-stack/v3/pkg/events"
+ "go.thethings.network/lorawan-stack/v3/pkg/task"
+ "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"
+)
+
+type subscribeRequest struct {
+ Context context.Context
+ Names []string
+ Identifiers []*ttnpb.EntityIdentifiers
+ After *time.Time
+ Tail int
+ Handler events.Handler
+
+ Response chan<- error
+}
+
+type mockSubscriber struct {
+ subReqs chan subscribeRequest
+}
+
+func (m *mockSubscriber) subscribeRequests() <-chan subscribeRequest { return m.subReqs }
+
+// Subscribe implements events.Subscriber.
+func (m *mockSubscriber) Subscribe(
+ ctx context.Context, names []string, identifiers []*ttnpb.EntityIdentifiers, hdl events.Handler,
+) error {
+ ch := make(chan error, 1)
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ case m.subReqs <- subscribeRequest{
+ Context: ctx,
+ Names: names,
+ Identifiers: identifiers,
+ Handler: hdl,
+
+ Response: ch,
+ }:
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ case err := <-ch:
+ return err
+ }
+ }
+}
+
+var _ events.Subscriber = (*mockSubscriber)(nil)
+
+type mockPubSubStore struct {
+ subReqs chan subscribeRequest
+}
+
+func (m *mockPubSubStore) subscribeRequests() <-chan subscribeRequest { return m.subReqs }
+
+func (*mockPubSubStore) historical() {}
+
+// Publish implements events.Store.
+func (*mockPubSubStore) Publish(...events.Event) { panic("not implemented") }
+
+// Subscribe implements events.Store.
+func (*mockPubSubStore) Subscribe(context.Context, []string, []*ttnpb.EntityIdentifiers, events.Handler) error {
+ panic("not implemented")
+}
+
+// FindRelated implements events.Store.
+func (*mockPubSubStore) FindRelated(context.Context, string) ([]events.Event, error) {
+ panic("not implemented")
+}
+
+// FetchHistory implements events.Store.
+func (*mockPubSubStore) FetchHistory(
+ context.Context, []string, []*ttnpb.EntityIdentifiers, *time.Time, int,
+) ([]events.Event, error) {
+ panic("not implemented")
+}
+
+// SubscribeWithHistory implements events.Store.
+func (m *mockPubSubStore) SubscribeWithHistory(
+ ctx context.Context, names []string, ids []*ttnpb.EntityIdentifiers, after *time.Time, tail int, hdl events.Handler,
+) error {
+ ch := make(chan error, 1)
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ case m.subReqs <- subscribeRequest{
+ Context: ctx,
+ Names: names,
+ Identifiers: ids,
+ After: after,
+ Tail: tail,
+ Handler: hdl,
+
+ Response: ch,
+ }:
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ case err := <-ch:
+ return err
+ }
+ }
+}
+
+var _ events.Store = (*mockPubSubStore)(nil)
+
+func runTestSubscriptions(
+ t *testing.T,
+ subscriber interface {
+ events.Subscriber
+ subscribeRequests() <-chan subscribeRequest
+ },
+) {
+ t.Helper()
+
+ _, historical := subscriber.(interface{ historical() })
+
+ a, ctx := test.New(t)
+ ctx, cancel := errorcontext.New(ctx)
+ defer cancel(nil)
+
+ timeout := test.Delay << 3
+ app1IDs, app2IDs := &ttnpb.ApplicationIdentifiers{
+ ApplicationId: "foo",
+ }, &ttnpb.ApplicationIdentifiers{
+ ApplicationId: "bar",
+ }
+ ctx = rights.NewContext(ctx, &rights.Rights{
+ ApplicationRights: *rights.NewMap(map[string]*ttnpb.Rights{
+ unique.ID(ctx, app1IDs): ttnpb.RightsFrom(ttnpb.Right_RIGHT_APPLICATION_ALL),
+ }),
+ })
+
+ sub := subscriptions.New(
+ ctx,
+ cancel,
+ subscriber,
+ map[string]struct{}{
+ "test": {},
+ },
+ task.StartTaskFunc(task.DefaultStartTask),
+ )
+ defer sub.Close()
+
+ select {
+ case <-ctx.Done():
+ return
+ case <-time.After(timeout):
+ case req := <-subscriber.subscribeRequests():
+ t.Fatal("Unexpected subscribe request", req)
+ }
+
+ now := time.Now()
+
+ var wg sync.WaitGroup
+ defer wg.Wait()
+
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ err := sub.Subscribe(
+ 1,
+ []*ttnpb.EntityIdentifiers{
+ app1IDs.GetEntityIdentifiers(),
+ },
+ &now,
+ 10,
+ []string{"test"},
+ )
+ a.So(err, should.BeNil)
+ }()
+ var handler events.Handler
+ select {
+ case <-ctx.Done():
+ return
+ case req := <-subscriber.subscribeRequests():
+ a.So(req.Context, should.HaveParentContextOrEqual, ctx)
+ a.So(req.Names, should.Resemble, []string{"test"})
+ a.So(req.Identifiers, should.Resemble, []*ttnpb.EntityIdentifiers{
+ app1IDs.GetEntityIdentifiers(),
+ })
+ if historical {
+ a.So(req.After, should.Resemble, &now)
+ a.So(req.Tail, should.Equal, 10)
+ }
+ a.So(req.Handler, should.NotBeNil)
+ if !historical {
+ select {
+ case <-ctx.Done():
+ return
+ case req.Response <- nil:
+ }
+ }
+ handler = req.Handler
+ }
+ wg.Wait()
+
+ err := sub.Subscribe(
+ 1,
+ []*ttnpb.EntityIdentifiers{
+ app1IDs.GetEntityIdentifiers(),
+ },
+ &now,
+ 10,
+ []string{"test"},
+ )
+ a.So(err, should.NotBeNil)
+
+ evt := events.New(
+ ctx,
+ "test",
+ "test",
+ events.WithIdentifiers(app2IDs),
+ events.WithVisibility(ttnpb.Right_RIGHT_APPLICATION_DEVICES_READ),
+ )
+ handler.Notify(evt)
+
+ select {
+ case <-ctx.Done():
+ return
+ case <-time.After(timeout):
+ case subEvt := <-sub.SubscriptionEvents():
+ t.Fatal("Unexpected subscription event", subEvt)
+ }
+
+ evt = events.New(
+ ctx,
+ "test",
+ "test",
+ events.WithIdentifiers(app1IDs),
+ events.WithVisibility(ttnpb.Right_RIGHT_APPLICATION_DEVICES_READ),
+ )
+ handler.Notify(evt)
+
+ select {
+ case <-ctx.Done():
+ return
+ case subEvt := <-sub.SubscriptionEvents():
+ a.So(subEvt.ID, should.Equal, 1)
+ a.So(subEvt.Event, should.ResembleEvent, evt)
+ }
+
+ err = sub.Unsubscribe(1)
+ a.So(err, should.BeNil)
+
+ err = sub.Unsubscribe(1)
+ a.So(err, should.NotBeNil)
+
+ select {
+ case <-ctx.Done():
+ return
+ case <-time.After(timeout):
+ case subEvt := <-sub.SubscriptionEvents():
+ t.Fatal("Unexpected subscription event", subEvt)
+ }
+}
+
+func TestSubscriptions(t *testing.T) {
+ t.Parallel()
+ runTestSubscriptions(
+ t,
+ &mockSubscriber{
+ subReqs: make(chan subscribeRequest, 1),
+ },
+ )
+}
+
+func TestStoreSubscriptions(t *testing.T) {
+ t.Parallel()
+ runTestSubscriptions(
+ t,
+ &mockPubSubStore{
+ subReqs: make(chan subscribeRequest, 1),
+ },
+ )
+}
diff --git a/pkg/console/internal/events/tasks.go b/pkg/console/internal/events/tasks.go
new file mode 100644
index 0000000000..298cb1f3f6
--- /dev/null
+++ b/pkg/console/internal/events/tasks.go
@@ -0,0 +1,100 @@
+// 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 (
+ "context"
+ "errors"
+ "io"
+ "time"
+
+ "go.thethings.network/lorawan-stack/v3/pkg/console/internal/events/eventsmux"
+ "go.thethings.network/lorawan-stack/v3/pkg/console/internal/events/protocol"
+ "go.thethings.network/lorawan-stack/v3/pkg/log"
+ "nhooyr.io/websocket"
+ "nhooyr.io/websocket/wsjson"
+)
+
+func makeMuxTask(m eventsmux.Interface, cancel func(error)) func(context.Context) error {
+ return func(ctx context.Context) (err error) {
+ defer func() { cancel(err) }()
+ return m.Run(ctx)
+ }
+}
+
+func makeReadTask(
+ conn *websocket.Conn, m eventsmux.Interface, rateLimit func() error, cancel func(error),
+) func(context.Context) error {
+ return func(ctx context.Context) (err error) {
+ defer func() { cancel(err) }()
+ defer func() {
+ if closeErr := (websocket.CloseError{}); errors.As(err, &closeErr) {
+ log.FromContext(ctx).WithFields(log.Fields(
+ "code", closeErr.Code,
+ "reason", closeErr.Reason,
+ )).Debug("WebSocket closed")
+ err = io.EOF
+ }
+ }()
+ for {
+ var request protocol.RequestWrapper
+ if err := wsjson.Read(ctx, conn, &request); err != nil {
+ return err
+ }
+ if err := rateLimit(); err != nil {
+ return err
+ }
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ case m.Requests() <- request.Contents:
+ }
+ }
+ }
+}
+
+func makeWriteTask(conn *websocket.Conn, m eventsmux.Interface, cancel func(error)) func(context.Context) error {
+ return func(ctx context.Context) (err error) {
+ defer func() { cancel(err) }()
+ for {
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ case response := <-m.Responses():
+ if err := wsjson.Write(ctx, conn, response); err != nil {
+ return err
+ }
+ }
+ }
+ }
+}
+
+func makePingTask(conn *websocket.Conn, cancel func(error), period time.Duration) func(context.Context) error {
+ return func(ctx context.Context) (err error) {
+ ticker := time.NewTicker(period)
+ defer ticker.Stop()
+ defer func() { cancel(err) }()
+ for {
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ case <-ticker.C:
+ if err := conn.Ping(ctx); err != nil {
+ return err
+ }
+ }
+ }
+ }
+}
diff --git a/pkg/crypto/join_messages_test.go b/pkg/crypto/join_messages_test.go
index 3866f32f50..37e3ad4230 100644
--- a/pkg/crypto/join_messages_test.go
+++ b/pkg/crypto/join_messages_test.go
@@ -16,6 +16,7 @@ package crypto_test
import (
"fmt"
+ "slices"
"testing"
"github.com/mohae/deepcopy"
@@ -23,7 +24,6 @@ import (
. "go.thethings.network/lorawan-stack/v3/pkg/crypto"
"go.thethings.network/lorawan-stack/v3/pkg/types"
"go.thethings.network/lorawan-stack/v3/pkg/util/test/assertions/should"
- "golang.org/x/exp/slices"
)
func TestJoinAcceptEncryption(t *testing.T) {
diff --git a/pkg/crypto/relay.go b/pkg/crypto/relay.go
new file mode 100644
index 0000000000..c64481809c
--- /dev/null
+++ b/pkg/crypto/relay.go
@@ -0,0 +1,31 @@
+// 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 crypto
+
+import (
+ "crypto/aes"
+
+ "go.thethings.network/lorawan-stack/v3/pkg/types"
+)
+
+// DeriveRootWorSKey derives the root relay session key.
+func DeriveRootWorSKey(nwkSEncKey types.AES128Key) types.AES128Key {
+ var key types.AES128Key
+ var plain [16]byte
+ plain[0] = 0x01
+ block, _ := aes.NewCipher(nwkSEncKey[:])
+ block.Encrypt(key[:], plain[:])
+ return key
+}
diff --git a/pkg/crypto/relay_test.go b/pkg/crypto/relay_test.go
new file mode 100644
index 0000000000..992267bbf4
--- /dev/null
+++ b/pkg/crypto/relay_test.go
@@ -0,0 +1,35 @@
+// 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 crypto_test
+
+import (
+ "testing"
+
+ "github.com/smarty/assertions"
+ "go.thethings.network/lorawan-stack/v3/pkg/crypto"
+ "go.thethings.network/lorawan-stack/v3/pkg/types"
+ "go.thethings.network/lorawan-stack/v3/pkg/util/test/assertions/should"
+)
+
+func TestDeriveRootWorSKey(t *testing.T) {
+ t.Parallel()
+ a := assertions.New(t)
+ nwkSEncKey := types.AES128Key{
+ 0xCE, 0x07, 0xA0, 0x09, 0xA3, 0x97, 0x0A, 0xC0, 0x51, 0x9A, 0x09, 0x9E, 0xD5, 0x3E, 0x55, 0x0B,
+ }
+ a.So(crypto.DeriveRootWorSKey(nwkSEncKey), should.Equal, types.AES128Key{
+ 0xEE, 0x91, 0xDC, 0x1A, 0x66, 0x66, 0xC0, 0x6E, 0x82, 0x77, 0xDE, 0x6D, 0xB4, 0xDB, 0x94, 0x5F,
+ })
+}
diff --git a/pkg/deviceclaimingserver/enddevices/ttjsv2/messages.go b/pkg/deviceclaimingserver/enddevices/ttjsv2/messages.go
index c000254e1d..a6c5e35f35 100644
--- a/pkg/deviceclaimingserver/enddevices/ttjsv2/messages.go
+++ b/pkg/deviceclaimingserver/enddevices/ttjsv2/messages.go
@@ -14,6 +14,10 @@
package ttjsv2
+import (
+ "context"
+)
+
// ClaimData contains information about the claim.
type ClaimData struct {
HomeNetID string `json:"homeNetID"`
@@ -38,6 +42,25 @@ type ClaimRequest struct {
KEK *KEK `json:"kek,omitempty"`
}
+// Apply applies the context to the request.
+func (req ClaimRequest) Apply(ctx context.Context, c Component) (ClaimRequest, error) {
+ deriv := req
+ if req.HomeNSID != nil {
+ deriv.HomeNSID = stringValue(*req.HomeNSID)
+ }
+ if req.RegenerateOwnerToken != nil {
+ deriv.RegenerateOwnerToken = boolValue(*req.RegenerateOwnerToken)
+ }
+ if req.Lock != nil {
+ deriv.Lock = boolValue(*req.Lock)
+ }
+ if req.KEK != nil {
+ kek := *req.KEK
+ deriv.KEK = &kek
+ }
+ return deriv, nil
+}
+
// ErrorResponse is a message that may be returned by The Things Join Server in case of an error.
type ErrorResponse struct {
Message string `json:"message"`
diff --git a/pkg/deviceclaimingserver/enddevices/ttjsv2/ttjs.go b/pkg/deviceclaimingserver/enddevices/ttjsv2/ttjs.go
index 2e15c46245..50e95e30a6 100644
--- a/pkg/deviceclaimingserver/enddevices/ttjsv2/ttjs.go
+++ b/pkg/deviceclaimingserver/enddevices/ttjsv2/ttjs.go
@@ -123,7 +123,7 @@ func (c *TTJS) Claim(ctx context.Context, joinEUI, devEUI types.EUI64, claimAuth
"url", reqURL,
))
- claimReq := &ClaimRequest{
+ claimReq := ClaimRequest{
OwnerToken: claimAuthenticationCode,
Lock: boolValue(true),
HomeNetID: c.config.NetID.String(),
@@ -132,6 +132,10 @@ func (c *TTJS) Claim(ctx context.Context, joinEUI, devEUI types.EUI64, claimAuth
if c.config.NSID != nil {
claimReq.HomeNSID = stringValue(c.config.NSID.String())
}
+ claimReq, err := claimReq.Apply(ctx, c)
+ if err != nil {
+ return err
+ }
buf, err := json.Marshal(claimReq)
if err != nil {
return err
diff --git a/pkg/deviceclaimingserver/enddevices/ttjsv2/ttjs_test.go b/pkg/deviceclaimingserver/enddevices/ttjsv2/ttjs_test.go
index 022420f7b3..08515ba517 100644
--- a/pkg/deviceclaimingserver/enddevices/ttjsv2/ttjs_test.go
+++ b/pkg/deviceclaimingserver/enddevices/ttjsv2/ttjs_test.go
@@ -99,7 +99,7 @@ func TestTTJS(t *testing.T) { //nolint:paralleltest
client1 := ttjsv2.NewClient(c, fetcher, ttjsv2.Config{
NetID: test.DefaultNetID,
NSID: &homeNSID,
- ASID: "localhost",
+ ASID: client1ASID,
JoinEUIPrefixes: []types.EUI64Prefix{
supportedJoinEUIPrefix,
},
@@ -176,7 +176,7 @@ func TestTTJS(t *testing.T) { //nolint:paralleltest
client2 := ttjsv2.NewClient(c, fetcher, ttjsv2.Config{
NetID: test.DefaultNetID,
NSID: &homeNSID,
- ASID: "localhost",
+ ASID: client2ASID,
JoinEUIPrefixes: []types.EUI64Prefix{
supportedJoinEUIPrefix,
},
diff --git a/pkg/devicerepository/grpc.go b/pkg/devicerepository/grpc.go
index c0d490b751..bad776016a 100644
--- a/pkg/devicerepository/grpc.go
+++ b/pkg/devicerepository/grpc.go
@@ -65,7 +65,7 @@ func (dr *DeviceRepository) ListBrands(
ctx context.Context,
req *ttnpb.ListEndDeviceBrandsRequest,
) (*ttnpb.ListEndDeviceBrandsResponse, error) {
- if err := rights.RequireAuthentication(ctx); err != nil {
+ if err := rights.RequireAuthenticated(ctx); err != nil {
return nil, err
}
if req.Limit > defaultLimit || req.Limit == 0 {
@@ -97,7 +97,7 @@ func (dr *DeviceRepository) GetBrand(
ctx context.Context,
req *ttnpb.GetEndDeviceBrandRequest,
) (*ttnpb.EndDeviceBrand, error) {
- if err := rights.RequireAuthentication(ctx); err != nil {
+ if err := rights.RequireAuthenticated(ctx); err != nil {
return nil, err
}
response, err := dr.store.GetBrands(store.GetBrandsRequest{
@@ -121,7 +121,7 @@ func (dr *DeviceRepository) ListModels(
ctx context.Context,
req *ttnpb.ListEndDeviceModelsRequest,
) (*ttnpb.ListEndDeviceModelsResponse, error) {
- if err := rights.RequireAuthentication(ctx); err != nil {
+ if err := rights.RequireAuthenticated(ctx); err != nil {
return nil, err
}
if req.Limit > defaultLimit || req.Limit == 0 {
@@ -152,7 +152,7 @@ func (dr *DeviceRepository) GetModel(
ctx context.Context,
req *ttnpb.GetEndDeviceModelRequest,
) (*ttnpb.EndDeviceModel, error) {
- if err := rights.RequireAuthentication(ctx); err != nil {
+ if err := rights.RequireAuthenticated(ctx); err != nil {
return nil, err
}
response, err := dr.store.GetModels(store.GetModelsRequest{
@@ -177,7 +177,7 @@ func (dr *DeviceRepository) GetTemplate(
ctx context.Context,
req *ttnpb.GetTemplateRequest,
) (*ttnpb.EndDeviceTemplate, error) {
- if err := rights.RequireAuthentication(ctx); err != nil {
+ if err := rights.RequireAuthenticated(ctx); err != nil {
return nil, err
}
return dr.store.GetTemplate(req, nil)
@@ -189,7 +189,7 @@ func getDecoder(
f func(store.GetCodecRequest) (*ttnpb.MessagePayloadDecoder, error),
) (*ttnpb.MessagePayloadDecoder, error) {
if clusterauth.Authorized(ctx) != nil {
- if err := rights.RequireAuthentication(ctx); err != nil {
+ if err := rights.RequireAuthenticated(ctx); err != nil {
return nil, err
}
}
@@ -218,7 +218,7 @@ func (dr *DeviceRepository) GetDownlinkEncoder(
req *ttnpb.GetPayloadFormatterRequest,
) (*ttnpb.MessagePayloadEncoder, error) {
if clusterauth.Authorized(ctx) != nil {
- if err := rights.RequireAuthentication(ctx); err != nil {
+ if err := rights.RequireAuthenticated(ctx); err != nil {
return nil, err
}
}
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/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 a53f083dd4..5333419bb0 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 ed581ff152..0a5558f21e 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
}
}
@@ -535,16 +542,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
@@ -869,7 +873,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 9e09957f68..def5b43d65 100644
--- a/pkg/gatewayserver/scheduling/scheduler.go
+++ b/pkg/gatewayserver/scheduling/scheduler.go
@@ -82,7 +82,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,
@@ -189,7 +189,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 111021e2ce..fa976b1d85 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,
@@ -330,7 +330,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{
{
@@ -418,7 +418,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,
@@ -532,7 +532,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,
@@ -732,7 +732,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,
@@ -823,14 +823,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,
@@ -840,7 +840,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,
@@ -855,8 +855,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,
@@ -875,7 +875,7 @@ func TestSchedulerWithMultipleFrequencyPlans(t *testing.T) {
},
},
},
- "EU_863_870_Custom": {
+ {
BandID: band.EU_863_870,
TimeOffAir: frequencyplans.TimeOffAir{
Duration: time.Second,
@@ -890,8 +890,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,
@@ -901,7 +901,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,
@@ -918,8 +918,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,
@@ -938,7 +938,7 @@ func TestSchedulerWithMultipleFrequencyPlans(t *testing.T) {
},
},
},
- "EU_863_870_Custom": {
+ {
BandID: band.EU_863_870,
TimeOffAir: frequencyplans.TimeOffAir{
Duration: time.Second,
@@ -955,8 +955,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{
@@ -967,7 +967,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,
@@ -1009,8 +1009,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,
@@ -1029,7 +1029,7 @@ func TestSchedulingWithMultipleFrequencyPlans(t *testing.T) {
},
},
},
- "EU_863_870_Custom": {
+ {
BandID: band.EU_863_870,
TimeOffAir: frequencyplans.TimeOffAir{
Duration: time.Second,
@@ -1120,7 +1120,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/networkserver/downlink.go b/pkg/networkserver/downlink.go
index f59113db52..26bd241ba7 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",
),
@@ -1550,14 +1611,16 @@ func (ns *NetworkServer) attemptClassADataDownlink(ctx context.Context, dev *ttn
} else {
logger = logger.WithError(err)
}
- logger.Warn("All Gateway Servers failed to schedule downlink, skip class A downlink slot")
+ logger.Info("All Gateway Servers failed to schedule downlink, skip class A downlink slot")
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",
@@ -1788,7 +1853,7 @@ func (ns *NetworkServer) attemptNetworkInitiatedDataDownlink(ctx context.Context
}
}
}
- logger.Warn("All Gateway Servers failed to schedule downlink, retry attempt")
+ logger.Info("All Gateway Servers failed to schedule downlink, retry attempt")
if genState.NeedsDownlinkQueueUpdate {
dev.Session.QueuedApplicationDownlinks = append([]*ttnpb.ApplicationDownlink{genState.ApplicationDownlink}, dev.Session.QueuedApplicationDownlinks...)
}
@@ -1981,6 +2046,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_deviceregistry.go b/pkg/networkserver/grpc_deviceregistry.go
index b89a10d032..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 {
@@ -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 e0f00e46e6..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,
@@ -887,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
}
@@ -1088,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{
@@ -1182,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
}
@@ -1344,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)
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/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/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 66cbdc0631..1526746693 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(
@@ -715,6 +715,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 {
@@ -737,6 +738,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_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/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 ba4cca23d7..43b00ca0ff 100644
--- a/pkg/networkserver/utils.go
+++ b/pkg/networkserver/utils.go
@@ -256,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
@@ -295,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
}
}
diff --git a/pkg/packetbrokeragent/agent.go b/pkg/packetbrokeragent/agent.go
index c8a99fced2..afcde1f3d6 100644
--- a/pkg/packetbrokeragent/agent.go
+++ b/pkg/packetbrokeragent/agent.go
@@ -75,7 +75,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) {
@@ -178,7 +178,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)
}
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/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 25da7c615c..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 {
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/rpcmiddleware/rpclog/client_interceptors.go b/pkg/rpcmiddleware/rpclog/client_interceptors.go
index 06024777fe..c0fe0de0c9 100644
--- a/pkg/rpcmiddleware/rpclog/client_interceptors.go
+++ b/pkg/rpcmiddleware/rpclog/client_interceptors.go
@@ -48,6 +48,11 @@ func UnaryClientInterceptor(ctx context.Context, opts ...Option) grpc.UnaryClien
}
level := o.levelFunc(o.codeFunc(err))
+
+ // suppress logs
+ if level > log.InfoLevel {
+ level = log.InfoLevel
+ }
entry := logger.WithFields(onceFields)
if err != nil {
entry = entry.WithError(err)
diff --git a/pkg/rpcmiddleware/rpclog/server_interceptors.go b/pkg/rpcmiddleware/rpclog/server_interceptors.go
index 8e094f3ed9..e645282c42 100644
--- a/pkg/rpcmiddleware/rpclog/server_interceptors.go
+++ b/pkg/rpcmiddleware/rpclog/server_interceptors.go
@@ -60,6 +60,10 @@ func UnaryServerInterceptor(ctx context.Context, opts ...Option) grpc.UnaryServe
if err == context.Canceled {
level = log.InfoLevel
}
+ // suppress logs
+ if level > log.InfoLevel {
+ level = log.InfoLevel
+ }
entry := logger.WithFields(onceFields)
if err != nil {
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 11653e4731..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
@@ -1272,313 +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, 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, 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,
+ 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,
- 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,
+ 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, 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, 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, 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,
+ 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, 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,
+ 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, 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, 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,
+ 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, 0x52, 0x04, 0x72, 0x61, 0x74, 0x65, 0x4a, 0x04,
- 0x08, 0x02, 0x10, 0x03, 0x1a, 0x6a, 0x0a, 0x0e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65,
- 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x42, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
- 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
- 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x73,
- 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x61, 0x74,
- 0x61, 0x52, 0x61, 0x74, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01,
- 0x1a, 0x74, 0x0a, 0x0d, 0x52, 0x78, 0x32, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72,
- 0x73, 0x12, 0x45, 0x0a, 0x0f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69,
- 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e,
- 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61,
- 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x0d, 0x64, 0x61, 0x74, 0x61, 0x52,
- 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x72, 0x65, 0x71,
- 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x66, 0x72, 0x65,
- 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x1a, 0x7b, 0x0a, 0x09, 0x44, 0x77, 0x65, 0x6c, 0x6c, 0x54,
- 0x69, 0x6d, 0x65, 0x12, 0x34, 0x0a, 0x07, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x01,
- 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
- 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65,
- 0x52, 0x07, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x12, 0x38, 0x0a, 0x09, 0x64, 0x6f, 0x77,
- 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67,
- 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42,
- 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69,
- 0x6e, 0x6b, 0x73, 0x1a, 0x93, 0x02, 0x0a, 0x0f, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x50, 0x61, 0x72,
- 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x62, 0x0a, 0x0c, 0x77, 0x6f, 0x72, 0x5f, 0x63,
- 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3f, 0x2e,
- 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x42,
- 0x61, 0x6e, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52,
- 0x65, 0x6c, 0x61, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x52,
- 0x65, 0x6c, 0x61, 0x79, 0x57, 0x4f, 0x52, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x0b,
- 0x77, 0x6f, 0x72, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x1a, 0x9b, 0x01, 0x0a, 0x0f,
- 0x52, 0x65, 0x6c, 0x61, 0x79, 0x57, 0x4f, 0x52, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12,
- 0x1c, 0x0a, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x04, 0x52, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x23, 0x0a,
- 0x0d, 0x61, 0x63, 0x6b, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02,
- 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x61, 0x63, 0x6b, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e,
- 0x63, 0x79, 0x12, 0x45, 0x0a, 0x0f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f,
- 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74,
- 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74,
- 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x0d, 0x64, 0x61, 0x74, 0x61,
- 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x4a,
- 0x04, 0x08, 0x1a, 0x10, 0x1b, 0x4a, 0x04, 0x08, 0x1b, 0x10, 0x1c, 0x4a, 0x04, 0x08, 0x1c, 0x10,
- 0x1d, 0x4a, 0x04, 0x08, 0x1d, 0x10, 0x1e, 0x22, 0xba, 0x03, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74,
- 0x42, 0x61, 0x6e, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a,
- 0x0c, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20,
- 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
- 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x6e, 0x64, 0x73, 0x52, 0x65,
- 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69,
- 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
- 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0xce, 0x01, 0x0a, 0x18, 0x56, 0x65, 0x72, 0x73, 0x69,
- 0x6f, 0x6e, 0x65, 0x64, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
- 0x69, 0x6f, 0x6e, 0x12, 0x58, 0x0a, 0x04, 0x62, 0x61, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28,
- 0x0b, 0x32, 0x44, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
- 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x6e, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70,
- 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x42, 0x61,
- 0x6e, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x42, 0x61,
- 0x6e, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x62, 0x61, 0x6e, 0x64, 0x1a, 0x58, 0x0a,
- 0x09, 0x42, 0x61, 0x6e, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65,
- 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x35, 0x0a, 0x05,
- 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x74,
- 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x42, 0x61, 0x6e,
- 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x76, 0x61,
- 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 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,
+ 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, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x65,
- 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
- 0x3a, 0x02, 0x38, 0x01, 0x32, 0xef, 0x03, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75,
- 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x93, 0x01, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x46,
- 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x50, 0x6c, 0x61, 0x6e, 0x73, 0x12, 0x29, 0x2e,
- 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c,
- 0x69, 0x73, 0x74, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x50, 0x6c, 0x61, 0x6e,
- 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c,
- 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x72,
- 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x50, 0x6c, 0x61, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70,
- 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x12, 0x1e, 0x2f, 0x63,
- 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x66, 0x72, 0x65,
- 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x2d, 0x70, 0x6c, 0x61, 0x6e, 0x73, 0x12, 0x84, 0x01, 0x0a,
- 0x0e, 0x47, 0x65, 0x74, 0x50, 0x68, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12,
- 0x25, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
- 0x2e, 0x47, 0x65, 0x74, 0x50, 0x68, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52,
- 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
- 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x68, 0x79, 0x56, 0x65,
- 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23,
- 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75,
- 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x70, 0x68, 0x79, 0x2d, 0x76, 0x65, 0x72, 0x73, 0x69,
- 0x6f, 0x6e, 0x73, 0x12, 0xc0, 0x01, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x6e, 0x64,
- 0x73, 0x12, 0x20, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
- 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x6e, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75,
- 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
- 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x6e, 0x64, 0x73, 0x52, 0x65,
- 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x68, 0x5a, 0x20,
- 0x12, 0x1e, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
- 0x2f, 0x62, 0x61, 0x6e, 0x64, 0x73, 0x2f, 0x7b, 0x62, 0x61, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x7d,
- 0x5a, 0x2e, 0x12, 0x2c, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69,
- 0x6f, 0x6e, 0x2f, 0x62, 0x61, 0x6e, 0x64, 0x73, 0x2f, 0x7b, 0x62, 0x61, 0x6e, 0x64, 0x5f, 0x69,
- 0x64, 0x7d, 0x2f, 0x7b, 0x70, 0x68, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x7d,
- 0x12, 0x14, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
- 0x2f, 0x62, 0x61, 0x6e, 0x64, 0x73, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65,
- 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c,
- 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f,
- 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74, 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
- 0x33,
+ 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, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x50, 0x6c, 0x61, 0x6e, 0x73, 0x52,
+ 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x12,
+ 0x1e, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f,
+ 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x2d, 0x70, 0x6c, 0x61, 0x6e, 0x73, 0x12,
+ 0x84, 0x01, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x50, 0x68, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
+ 0x6e, 0x73, 0x12, 0x25, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
+ 0x2e, 0x76, 0x33, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x68, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
+ 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
+ 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x68,
+ 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+ 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x63, 0x6f, 0x6e, 0x66,
+ 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x70, 0x68, 0x79, 0x2d, 0x76, 0x65,
+ 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0xc0, 0x01, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x42,
+ 0x61, 0x6e, 0x64, 0x73, 0x12, 0x20, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
+ 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x6e, 0x64, 0x73, 0x52,
+ 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
+ 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x6e, 0x64,
+ 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6e, 0x82, 0xd3, 0xe4, 0x93, 0x02,
+ 0x68, 0x5a, 0x20, 0x12, 0x1e, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x2f, 0x62, 0x61, 0x6e, 0x64, 0x73, 0x2f, 0x7b, 0x62, 0x61, 0x6e, 0x64, 0x5f,
+ 0x69, 0x64, 0x7d, 0x5a, 0x2e, 0x12, 0x2c, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x62, 0x61, 0x6e, 0x64, 0x73, 0x2f, 0x7b, 0x62, 0x61, 0x6e,
+ 0x64, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x7b, 0x70, 0x68, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69,
+ 0x6f, 0x6e, 0x7d, 0x12, 0x14, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x2f, 0x62, 0x61, 0x6e, 0x64, 0x73, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x6f, 0x2e,
+ 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72,
+ 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f,
+ 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74, 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x33,
}
var (
diff --git a/pkg/ttnpb/configuration_services.pb.paths.fm.go b/pkg/ttnpb/configuration_services.pb.paths.fm.go
index 3758203f16..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",
diff --git a/pkg/ttnpb/configuration_services.pb.setters.fm.go b/pkg/ttnpb/configuration_services.pb.setters.fm.go
index c04d0a841d..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)
diff --git a/pkg/ttnpb/configuration_services.pb.validate.go b/pkg/ttnpb/configuration_services.pb.validate.go
index 974a86731d..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,
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/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/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 6f8ebae936..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,
@@ -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 79d29f75fc..ab460b1687 100644
--- a/pkg/ttnpb/lorawan_flags.pb.go
+++ b/pkg/ttnpb/lorawan_flags.pb.go
@@ -907,6 +907,414 @@ func (m *TxSettings) SetFromFlags(flags *pflag.FlagSet, prefix string) (paths []
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)))
@@ -1248,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/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 8c7d64eca3..4bfb83bcb1 100644
--- a/pkg/version/ttn.go
+++ b/pkg/version/ttn.go
@@ -3,4 +3,4 @@
package version
// TTN Version
-var TTN = "3.28.0-dev"
+var TTN = "3.28.2-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/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/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/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/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 14f0fc625a..b509198db9 100644
--- a/pkg/webui/components/key-value-map/entry.js
+++ b/pkg/webui/components/key-value-map/entry.js
@@ -44,6 +44,7 @@ const Entry = ({
removeMessage,
distinctOptions,
atLeastOneEntry,
+ filterByTag,
}) => {
const [currentValue, setCurrentValue] = useState(value)
const [newOptions, setNewOptions] = useState(undefined)
@@ -98,8 +99,15 @@ const Entry = ({
} else {
newOptions = options.filter(v => !fieldValue.includes(v.value))
}
- setNewOptions(newOptions)
- }, [currentValue, options, fieldValue])
+
+ 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
@@ -157,6 +165,7 @@ Entry.propTypes = {
atLeastOneEntry: PropTypes.bool,
distinctOptions: PropTypes.bool,
fieldValue: PropTypes.any,
+ filterByTag: PropTypes.bool,
index: PropTypes.number.isRequired,
indexAsKey: PropTypes.bool.isRequired,
inputElement: PropTypes.elementType.isRequired,
@@ -184,6 +193,7 @@ Entry.defaultProps = {
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 0eb44e7a32..b908a8f6e9 100644
--- a/pkg/webui/components/key-value-map/index.js
+++ b/pkg/webui/components/key-value-map/index.js
@@ -46,6 +46,7 @@ const KeyValueMap = ({
valuePlaceholder,
distinctOptions,
atLeastOneEntry,
+ filterByTag,
}) => {
const handleEntryChange = useCallback(
(index, newValues) => {
@@ -98,6 +99,7 @@ const KeyValueMap = ({
removeMessage={removeMessage}
distinctOptions={distinctOptions}
atLeastOneEntry={atLeastOneEntry}
+ filterByTag={filterByTag}
/>
))}
@@ -122,6 +124,7 @@ KeyValueMap.propTypes = {
className: PropTypes.string,
disabled: PropTypes.bool,
distinctOptions: PropTypes.bool,
+ filterByTag: PropTypes.bool,
indexAsKey: PropTypes.bool,
inputElement: PropTypes.elementType,
isReadOnly: PropTypes.func,
@@ -157,6 +160,7 @@ KeyValueMap.defaultProps = {
removeMessage: undefined,
distinctOptions: false,
atLeastOneEntry: false,
+ filterByTag: false,
}
export default KeyValueMap
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/input/video/index.js b/pkg/webui/components/qr/input/video/index.js
index 43a4b808df..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,43 +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 [videoMode, setVideoMode] = useState({})
+ 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' }
-
- setVideoMode(videoMode)
+ }, [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)
@@ -74,51 +149,29 @@ const Video = props => {
}
}
}
- }, [devices, setCapture, setError, stream])
-
- const switchStream = useCallback(async () => {
- const ua = navigator.userAgent.toLowerCase()
- if (ua.indexOf('safari') !== -1 && ua.indexOf('chrome') === -1) {
- const userStream = await navigator.mediaDevices.getUserMedia({
- video: {
- facingMode: {
- exact: videoMode.facingMode.exact === 'environment' ? 'user' : 'environment',
- },
- },
- })
- setStream(userStream)
- } else if (videoMode.facingMode === 'environment') {
- const userStream = await navigator.mediaDevices.getUserMedia({
- video: { facingMode: 'user' },
- })
- setStream(userStream)
- } else if (videoMode.facingMode === 'user') {
- const userStream = await navigator.mediaDevices.getUserMedia({
- video: { facingMode: 'environment' },
- })
- setStream(userStream)
- } else if ('deviceId' in videoMode) {
- let indexOfCurrentDevice = cameras.findIndex(camera => camera.deviceId === videoMode.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[nextIndex]
- setVideoMode({ deviceId: device.deviceId })
- const userStream = await navigator.mediaDevices.getUserMedia({
- video: { deviceId: device.deviceId },
- })
- setStream(userStream)
- }
- }, [cameras, videoMode])
- 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 => {
@@ -137,19 +190,25 @@ const Video = props => {
)
useEffect(() => {
- if (devices.length && stream) {
+ if (stream) {
const video = videoRef.current
video.srcObject = stream
handleVideoFrame(video)
}
- }, [devices, handleVideoFrame, stream, videoRef])
+
+ 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 && (
-
- )}
- {devices.length && stream ? (
+ {stream ? (
{
Video.propTypes = {
onRead: PropTypes.func.isRequired,
- setCapture: PropTypes.func.isRequired,
- setError: PropTypes.func.isRequired,
stream: PropTypes.shape({
active: PropTypes.bool,
+ getTracks: PropTypes.func,
}),
}
@@ -179,4 +237,4 @@ Video.defaultProps = {
stream: undefined,
}
-export default Video
+export default Camera
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 5eb629adc0..3772341d16 100644
--- a/pkg/webui/console/components/device-import-form/index.js
+++ b/pkg/webui/console/components/device-import-form/index.js
@@ -116,7 +116,7 @@ const DeviceBulkCreateFormInner = props => {
className={style.info}
values={{
DocLink: msg => (
-
+
{msg}
),
diff --git a/pkg/webui/console/components/downlink-form/connect.js b/pkg/webui/console/components/downlink-form/connect.js
deleted file mode 100644
index a9c006373b..0000000000
--- a/pkg/webui/console/components/downlink-form/connect.js
+++ /dev/null
@@ -1,40 +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 tts from '@console/api/tts'
-
-import {
- selectSelectedApplicationId,
- selectApplicationLinkSkipPayloadCrypto,
-} from '@console/store/selectors/applications'
-import { selectSelectedDeviceId, selectSelectedDevice } from '@console/store/selectors/devices'
-
-const mapStateToProps = state => {
- 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 5c1d84b3ab..0000000000
--- a/pkg/webui/console/components/downlink-form/downlink-form.js
+++ /dev/null
@@ -1,210 +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)',
- 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/gateway-visibility-form/index.js b/pkg/webui/console/components/gateway-visibility-form/index.js
index 3a5372f6af..535477a7ac 100644
--- a/pkg/webui/console/components/gateway-visibility-form/index.js
+++ b/pkg/webui/console/components/gateway-visibility-form/index.js
@@ -74,19 +74,19 @@ 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/payload-formatters-form/index.js b/pkg/webui/console/components/payload-formatters-form/index.js
index 3aea48e963..ea7ec8d788 100644
--- a/pkg/webui/console/components/payload-formatters-form/index.js
+++ b/pkg/webui/console/components/payload-formatters-form/index.js
@@ -56,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',
@@ -419,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 && (
<>
@@ -287,7 +272,7 @@ export default class PubsubForm extends Component {
name="mqtt._use_credentials"
label={m.useCredentials}
component={Checkbox}
- onChange={this.handleUseCredentialsChangeMqtt}
+ onChange={handleUseCredentialsChangeMqtt}
/>
>
- )
- }
+ ),
+ [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 a817da0d22..81457da324 100644
--- a/pkg/webui/console/components/pubsub-form/messages.js
+++ b/pkg/webui/console/components/pubsub-form/messages.js
@@ -31,6 +31,7 @@ export default defineMessages({
mqttClientIdPlaceholder: 'my-client-id',
mqttServerUrlPlaceholder: 'mqtts://example.com',
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',
diff --git a/pkg/webui/console/components/routing-policy-form/index.js b/pkg/webui/console/components/routing-policy-form/index.js
index 17453e8319..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 2bb78718b8..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'
@@ -233,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,
}
@@ -355,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/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/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-importer/processor.js b/pkg/webui/console/containers/device-importer/processor.js
index ba9f090cab..2bdf280475 100644
--- a/pkg/webui/console/containers/device-importer/processor.js
+++ b/pkg/webui/console/containers/device-importer/processor.js
@@ -44,7 +44,7 @@ const statusMap = {
}
const docLinkValue = msg => (
-
+
{msg}
)
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 677a790406..0000000000
--- a/pkg/webui/console/containers/device-profile-section/device-selection/brand-select/brand-select.js
+++ /dev/null
@@ -1,87 +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',
- 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 d0d64d3607..0000000000
--- a/pkg/webui/console/containers/device-profile-section/device-selection/model-select/model-select.js
+++ /dev/null
@@ -1,101 +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({
- 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/freq-plans-select/gs-frequency-plan-select.js b/pkg/webui/console/containers/freq-plans-select/gs-frequency-plan-select.js
index f3eb89f04b..74b8a5f0ae 100644
--- 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
@@ -69,6 +69,7 @@ const GatewayFrequencyPlansSelect = () => {
additionalInputProps={{ options: freqPlanOptions }}
distinctOptions
atLeastOneEntry
+ filterByTag
required
/>
)
diff --git a/pkg/webui/console/containers/freq-plans-select/utils.js b/pkg/webui/console/containers/freq-plans-select/utils.js
index 2509bd20c7..0526a8fd1c 100644
--- a/pkg/webui/console/containers/freq-plans-select/utils.js
+++ b/pkg/webui/console/containers/freq-plans-select/utils.js
@@ -14,12 +14,13 @@
import { defineMessages } from 'react-intl'
-export const formatOptions = plans => plans.map(plan => ({ value: plan.id, label: plan.name }))
+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.',
+ '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/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/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 a46406c162..d404fd629e 100644
--- a/pkg/webui/console/lib/events/definitions.js
+++ b/pkg/webui/console/lib/events/definitions.js
@@ -43,15 +43,13 @@ export const eventMessages = {
'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.',
+ '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 by the stream provider',
-
+ 'synthetic.status.closed:preview': 'The connection was closed',
'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.',
+ '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',
diff --git a/pkg/webui/console/lib/events/utils.js b/pkg/webui/console/lib/events/utils.js
index fa1d34436b..57ed39e7d7 100644
--- a/pkg/webui/console/lib/events/utils.js
+++ b/pkg/webui/console/lib/events/utils.js
@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import { ingestError } from '@ttn-lw/lib/errors/utils'
+
import { createNetworkErrorEvent, createUnknownErrorEvent } from './definitions'
export const defineSyntheticEvent = name => data => ({
@@ -23,13 +25,30 @@ export const defineSyntheticEvent = name => data => ({
data,
})
-export const createSyntheticEventFromError = error => {
+const convertError = error => {
if (error instanceof Error) {
- const errorString = error.toString()
- if (error.message === 'network error' || error.message === 'Error in body stream') {
- return createNetworkErrorEvent({ error: errorString })
+ return {
+ ...error,
+ message: error.message,
+ name: error.name,
+ // The stack is omitted intentionally, as it is not relevant for a user.
}
+ }
+ return error
+}
- return createUnknownErrorEvent({ error: errorString })
+export const createSyntheticEventFromError = error => {
+ if (error instanceof Error) {
+ if (
+ error.name === 'ConnectionError' ||
+ error.name === 'ConnectionClosedError' ||
+ error.name === 'ConnectionTimeoutError'
+ ) {
+ return createNetworkErrorEvent({ error: convertError(error) })
+ } else if (error.name === 'ProtocolError') {
+ ingestError(error.error)
+ return createUnknownErrorEvent({ error: convertError(error) })
+ }
+ return createUnknownErrorEvent({ error: convertError(error) })
}
}
diff --git a/pkg/webui/console/lib/packet-broker/messages.js b/pkg/webui/console/lib/packet-broker/messages.js
index 5ab1c4f8db..764cdb47c6 100644
--- a/pkg/webui/console/lib/packet-broker/messages.js
+++ b/pkg/webui/console/lib/packet-broker/messages.js
@@ -22,7 +22,6 @@ export default defineMessages({
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',
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..635602bf77 100644
--- a/pkg/webui/console/store/middleware/logics/events.js
+++ b/pkg/webui/console/store/middleware/logics/events.js
@@ -19,7 +19,7 @@ import CONNECTION_STATUS from '@console/constants/connection-status'
import EVENT_TAIL from '@console/constants/event-tail'
import { getCombinedDeviceId } from '@ttn-lw/lib/selectors/id'
-import { isUnauthenticatedError, isNetworkError, isTimeoutError } from '@ttn-lw/lib/errors/utils'
+import { TokenError } from '@ttn-lw/lib/errors/custom-errors'
import { SET_CONNECTION_STATUS, setStatusChecking } from '@ttn-lw/lib/store/actions/status'
import { selectIsOnlineStatus } from '@ttn-lw/lib/store/selectors/status'
@@ -29,7 +29,6 @@ import {
createStartEventsStreamFailureActionType,
createStartEventsStreamSuccessActionType,
createEventStreamClosedActionType,
- createGetEventMessageFailureActionType,
createGetEventMessageSuccessActionType,
createSetEventsFilterActionType,
getEventMessageSuccess,
@@ -65,7 +64,6 @@ const createEventsConnectLogics = (reducerName, entityName, onEventsStart) => {
const START_EVENTS_FAILURE = createStartEventsStreamFailureActionType(reducerName)
const STOP_EVENTS = createStopEventsStreamActionType(reducerName)
const EVENT_STREAM_CLOSED = createEventStreamClosedActionType(reducerName)
- const GET_EVENT_MESSAGE_FAILURE = createGetEventMessageFailureActionType(reducerName)
const GET_EVENT_MESSAGE_SUCCESS = createGetEventMessageSuccessActionType(reducerName)
const SET_EVENT_FILTER = createSetEventsFilterActionType(reducerName)
const startEventsSuccess = startEventsStreamSuccess(reducerName)
@@ -93,8 +91,7 @@ const createEventsConnectLogics = (reducerName, entityName, onEventsStart) => {
},
validate: ({ getState, action = {} }, allow, reject) => {
if (!action.id) {
- reject()
- return
+ return reject()
}
const id = typeof action.id === 'object' ? getCombinedDeviceId(action.id) : action.id
@@ -106,11 +103,10 @@ const createEventsConnectLogics = (reducerName, entityName, onEventsStart) => {
const connected = status === CONNECTION_STATUS.CONNECTED
const connecting = status === CONNECTION_STATUS.CONNECTING
if (connected || connecting || !isOnline) {
- reject()
- return
+ return reject()
}
- allow(action)
+ return allow(action)
},
process: async ({ getState, action }, dispatch) => {
const { id, silent } = action
@@ -131,18 +127,16 @@ const createEventsConnectLogics = (reducerName, entityName, onEventsStart) => {
const filterRegExp = Boolean(filter) ? filter.filterRegExp : undefined
try {
- channel = await onEventsStart([id], filterRegExp, EVENT_TAIL, after)
-
- channel.on('start', () => dispatch(startEventsSuccess(id, { silent })))
- channel.on('chunk', message => dispatch(getEventSuccess(id, message)))
- channel.on('error', error => dispatch(getEventFailure(id, error)))
- channel.on('close', wasClientRequest =>
- dispatch(closeEvents(id, { silent: wasClientRequest })),
- )
-
+ const listeners = {
+ message: message => dispatch(getEventSuccess(id, message)),
+ error: error => dispatch(getEventFailure(id, error)),
+ close: wasClientRequest => dispatch(closeEvents(id, { silent: wasClientRequest })),
+ }
+ channel = await onEventsStart([id], filterRegExp, EVENT_TAIL, after, listeners)
+ dispatch(startEventsSuccess(id, { silent }))
channel.open()
} catch (error) {
- if (isUnauthenticatedError(error)) {
+ if (error instanceof TokenError) {
// The user is no longer authenticated; reinitiate the auth flow
// by refreshing the page.
window.location.reload()
@@ -156,8 +150,7 @@ const createEventsConnectLogics = (reducerName, entityName, onEventsStart) => {
type: [STOP_EVENTS, START_EVENTS_FAILURE],
validate: ({ getState, action = {} }, allow, reject) => {
if (!action.id) {
- reject()
- return
+ return reject()
}
const id = typeof action.id === 'object' ? getCombinedDeviceId(action.id) : action.id
@@ -167,41 +160,36 @@ const createEventsConnectLogics = (reducerName, entityName, onEventsStart) => {
const connected = status === CONNECTION_STATUS.CONNECTED
const connecting = status === CONNECTION_STATUS.CONNECTING
if (!connected && !connecting) {
- reject()
- return
+ return reject()
}
- allow(action)
+ return 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())
+ process: async ({ action }, dispatch, done) => {
+ if (action.type === START_EVENTS_FAILURE) {
+ // 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()
+ }
+ if (action.type === STOP_EVENTS && Boolean(channel)) {
+ // Close the connection if it wasn't closed already.
+ await channel.close()
}
- done()
+ return done()
},
}),
createLogic({
- type: [GET_EVENT_MESSAGE_FAILURE, EVENT_STREAM_CLOSED],
+ type: EVENT_STREAM_CLOSED,
cancelType: [START_EVENTS_SUCCESS, GET_EVENT_MESSAGE_SUCCESS, STOP_EVENTS],
warnTimeout: 0,
validate: ({ getState, action = {} }, allow, reject) => {
if (!action.id) {
- reject()
- return
+ return reject()
}
const id = typeof action.id === 'object' ? getCombinedDeviceId(action.id) : action.id
@@ -210,11 +198,11 @@ const createEventsConnectLogics = (reducerName, entityName, onEventsStart) => {
const status = selectEntityEventsStatus(getState(), id)
const connected = status === CONNECTION_STATUS.CONNECTED
const interrupted = selectEntityEventsInterrupted(getState(), id)
- if (!connected && interrupted) {
- reject()
+ if (!connected || interrupted) {
+ return reject()
}
- allow(action)
+ return allow(action)
},
process: ({ getState, action }, dispatch, done) => {
const isOnline = selectIsOnlineStatus(getState())
@@ -233,11 +221,11 @@ const createEventsConnectLogics = (reducerName, entityName, onEventsStart) => {
dispatch(startEvents(action.id))
} else {
clearInterval(reconnector)
- done()
+ return done()
}
}, 5000)
} else {
- done()
+ return done()
}
},
}),
@@ -245,6 +233,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,28 +257,22 @@ const createEventsConnectLogics = (reducerName, entityName, onEventsStart) => {
dispatch(dispatch(startEvents(ids)))
}
}
+ } else if (isOffline) {
+ // If the app went offline, close the event stream.
}
- done()
+ return done()
},
}),
createLogic({
type: SET_EVENT_FILTER,
+ debounce: 250,
process: async ({ action }, dispatch, done) => {
- if (channel) {
- try {
- await channel.close()
- } catch (error) {
- if (isNetworkError(error) || isTimeoutError(action.payload)) {
- dispatch(setStatusChecking())
- } else {
- throw error
- }
- } finally {
- dispatch(startEvents(action.id, { silent: true }))
- }
+ if (Boolean(channel)) {
+ await channel.close()
+ dispatch(startEvents(action.id, { silent: true }))
}
- done()
+ return done()
},
}),
]
diff --git a/pkg/webui/console/store/middleware/logics/gateways.js b/pkg/webui/console/store/middleware/logics/gateways.js
index 08b2c58c4e..b8665e391a 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 {
@@ -250,7 +252,7 @@ const updateGatewayStatisticsLogic = createRequestLogic({
const getGatewayEventLocationLogic = createLogic({
type: gateways.GET_GTW_EVENT_MESSAGE_SUCCESS,
validate: ({ action }, allow, reject) => {
- if (action.event.name !== 'gs.status.receive' || !action?.event?.data?.antenna_locations) {
+ if (action?.event?.name !== 'gs.status.receive' || !action?.event?.data?.antenna_locations) {
reject(action)
} else {
allow(action)
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/store/reducers/events.js b/pkg/webui/console/store/reducers/events.js
index e16d23bfc0..dc0e6b6022 100644
--- a/pkg/webui/console/store/reducers/events.js
+++ b/pkg/webui/console/store/reducers/events.js
@@ -150,13 +150,12 @@ const createNamedEventReducer = (reducerName = '') => {
: state.events),
error: action.error,
status: CONNECTION_STATUS.DISCONNECTED,
+ interrupted: true,
}
case GET_EVENT_FAILURE:
return {
...state,
...addEvent(state, createSyntheticEventFromError(action.error)),
- status: CONNECTION_STATUS.DISCONNECTED,
- interrupted: true,
}
case PAUSE_EVENTS:
return {
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,7 +41,7 @@ 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',
devAddressBlock: 'Device address block',
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/index.js b/pkg/webui/console/views/admin-panel/index.js
index cbb9450d6d..fd2d130793 100644
--- a/pkg/webui/console/views/admin-panel/index.js
+++ b/pkg/webui/console/views/admin-panel/index.js
@@ -40,21 +40,23 @@ import {
} from '@console/lib/feature-checks'
const m = defineMessages({
- adminPanel: 'Admin panel',
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 (
<>
-
+
{
)
}
-export default withBreadcrumb('apps.single.integrations.lora-cloud', props => {
- const { appId } = props
-
- return (
-
- )
-})(LoRaCloud)
+export default LoRaCloud
diff --git a/pkg/webui/console/views/applications/index.js b/pkg/webui/console/views/applications/index.js
index e6df665061..a22737072a 100644
--- a/pkg/webui/console/views/applications/index.js
+++ b/pkg/webui/console/views/applications/index.js
@@ -21,7 +21,7 @@ import { useBreadcrumbs } from '@ttn-lw/components/breadcrumbs/context'
import GenericNotFound from '@ttn-lw/lib/components/full-view-error/not-found'
import ValidateRouteParam from '@ttn-lw/lib/components/validate-route-param'
-import withFeatureRequirement from '@console/lib/components/with-feature-requirement'
+import Require from '@console/lib/components/require'
import Application from '@console/views/application'
import ApplicationsList from '@console/views/applications-list'
@@ -36,15 +36,17 @@ const Applications = () => {
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/network-server-form/index.js b/pkg/webui/console/views/device-general-settings/network-server-form/index.js
index 3c493260fe..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,
@@ -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 72878bd8a2..5cbc43ecf4 100644
--- a/pkg/webui/console/views/device-overview/index.js
+++ b/pkg/webui/console/views/device-overview/index.js
@@ -60,7 +60,7 @@ const m = defineMessages({
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:
@@ -265,7 +265,7 @@ const DeviceInfo = ({ frequencyPlans, device, onExport }) => {
},
}}
onApprove={onExport}
- message={m.macData}
+ message={m.downloadMacData}
type="button"
icon="file_download"
/>
@@ -307,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-location/index.js b/pkg/webui/console/views/gateway-location/index.js
index c67ac85263..5c24f4aeff 100644
--- a/pkg/webui/console/views/gateway-location/index.js
+++ b/pkg/webui/console/views/gateway-location/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.
@@ -14,35 +14,43 @@
import React from 'react'
import { Col, Row, Container } from 'react-grid-system'
+import { useParams } from 'react-router-dom'
import PageTitle from '@ttn-lw/components/page-title'
import Breadcrumb from '@ttn-lw/components/breadcrumbs/breadcrumb'
-import { withBreadcrumb } from '@ttn-lw/components/breadcrumbs/context'
+import { useBreadcrumbs } from '@ttn-lw/components/breadcrumbs/context'
import GatewayLocationForm from '@console/containers/gateway-location-form'
-import withFeatureRequirement from '@console/lib/components/with-feature-requirement'
+import Require from '@console/lib/components/require'
import sharedMessages from '@ttn-lw/lib/shared-messages'
import { mayViewOrEditGatewayLocation } from '@console/lib/feature-checks'
-const GatewayLocation = () => (
-
-
-
-
-
-
-
-
-)
-
-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/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}
>
-
+
{
+ 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/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/shared-messages.js b/pkg/webui/lib/shared-messages.js
index 7537d56f14..b8578d3e27 100644
--- a/pkg/webui/lib/shared-messages.js
+++ b/pkg/webui/lib/shared-messages.js
@@ -332,6 +332,7 @@ 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',
@@ -459,6 +460,7 @@ export default defineMessages({
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',
@@ -507,6 +509,7 @@ export default defineMessages({
uplinksReceived: 'Uplinks received',
uploadAnImage: 'Upload an image',
used: '{currentValue}/{maxValue} used',
+ useDefaultPolicy: 'Use default routing policy for this network',
user: 'User',
userAdd: 'Add user',
userDelete: 'Delete user',
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 b1d61a2403..334ecdaf14 100644
--- a/pkg/webui/locales/en.json
+++ b/pkg/webui/locales/en.json
@@ -191,6 +191,7 @@
"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",
@@ -204,16 +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.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.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",
@@ -304,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",
@@ -342,6 +342,7 @@
"console.components.pubsub-form.messages.mqttClientIdPlaceholder": "my-client-id",
"console.components.pubsub-form.messages.mqttServerUrlPlaceholder": "mqtts://example.com",
"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",
@@ -354,13 +355,11 @@
"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",
@@ -490,48 +489,48 @@
"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.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.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.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.",
- "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.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.validation-schema.validateEntry": "There must be at least one selected frequency plan ID.",
@@ -581,8 +580,8 @@
"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",
@@ -614,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.",
@@ -640,7 +639,6 @@
"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",
@@ -677,26 +675,24 @@
"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.devAddressBlock": "Device address block",
@@ -791,7 +787,7 @@
"console.views.device-overview.index.latestData": "Latest data",
"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.",
@@ -1269,6 +1265,7 @@
"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",
@@ -1390,6 +1387,7 @@
"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",
@@ -1438,6 +1436,7 @@
"lib.shared-messages.uplinksReceived": "Uplinks received",
"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",
diff --git a/pkg/webui/locales/ja.json b/pkg/webui/locales/ja.json
index bcac6340bf..2f9f10b27d 100644
--- a/pkg/webui/locales/ja.json
+++ b/pkg/webui/locales/ja.json
@@ -191,6 +191,7 @@
"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": "テンプレートファイルを選択してください",
@@ -204,16 +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.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.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",
@@ -246,13 +247,13 @@
"console.components.events.messages.eventUnavailable": "このイベントはもう利用できません。メモリを節約するために切り捨てられたのでしょう",
"console.components.events.messages.verboseStream": "冗長ストリーム",
"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": "場所入力を削除",
@@ -304,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": "アプリケーションフォーマッター貼り付け",
@@ -342,6 +342,7 @@
"console.components.pubsub-form.messages.mqttClientIdPlaceholder": "my-client-id",
"console.components.pubsub-form.messages.mqttServerUrlPlaceholder": "mqtts://example.com",
"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": "クライアント証明書",
@@ -353,14 +354,12 @@
"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の削除",
@@ -420,7 +419,7 @@
"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": "ゼロからやり直す",
@@ -477,61 +476,61 @@
"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.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.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.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.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.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.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.validation-schema.validateEntry": "",
@@ -564,36 +563,36 @@
"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.warning": "Pub/Subフォーマットが無効です",
"console.containers.pubsubs-table.index.host": "サーバーホスト",
- "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": "送信済み",
@@ -640,7 +639,6 @@
"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": "信号品質に関する情報",
@@ -672,51 +670,49 @@
"console.lib.packet-broker.messages.gatewayStatusDescription": "ゲートウェイがオンラインかオフラインかを表示します",
"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.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.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-integrations-lora-cloud.index.loraCloudInfoText": "LoRaWANネットワークやLoRaベースのデバイスに関連する一般的なタスクのシンプルなソリューションを可能にする付加価値の高いAPIをローラクラウドが提供します。以下からLoRaCloudのインテグレーションを設定することができます",
"console.views.application-integrations-lora-cloud.index.officialLoRaCloudDocumentation": "オフィシャル LoRa Cloud ドキュメンテーション",
@@ -746,40 +742,40 @@
"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.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": "エンドデバイスの位置設定の把握",
@@ -791,7 +787,7 @@
"console.views.device-overview.index.latestData": "最新データ",
"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データに含めることができませんでした",
@@ -799,17 +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.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 のダウンロードに失敗しました",
@@ -817,22 +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.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": "不十分な権利",
@@ -980,519 +976,522 @@
"lib.payload-formatter-messages.repository": "レポジトリー",
"lib.payload-formatter-messages.javascript": "Javascript",
"lib.payload-formatter-messages.cayennelpp": "CayenneLPP",
- "lib.shared-messages.16Bit": "",
- "lib.shared-messages.32Bit": "",
- "lib.shared-messages.abp": "",
+ "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.accessTokens": "アクティブ・アクセストークン",
"lib.shared-messages.accountDeleteConfirmation": "",
"lib.shared-messages.accountDeleted": "",
- "lib.shared-messages.accuracy": "",
- "lib.shared-messages.actions": "",
- "lib.shared-messages.activationMode": "",
- "lib.shared-messages.add": "",
- "lib.shared-messages.addApiKey": "",
- "lib.shared-messages.addAttributes": "",
- "lib.shared-messages.addCollaborator": "",
- "lib.shared-messages.addDeviceBulk": "",
+ "lib.shared-messages.accuracy": "精度",
+ "lib.shared-messages.actions": "アクション",
+ "lib.shared-messages.activationMode": "アクティベーションモード",
+ "lib.shared-messages.add": "追加",
+ "lib.shared-messages.addApiKey": "APIキーの追加",
+ "lib.shared-messages.addAttributes": "属性の追加",
+ "lib.shared-messages.addCollaborator": "コラボレータ―の追加",
+ "lib.shared-messages.addDeviceBulk": "エンドデバイス一括作成",
"lib.shared-messages.addHeaderEntry": "",
"lib.shared-messages.addOAuthClient": "",
- "lib.shared-messages.addPubsub": "",
- "lib.shared-messages.addWebhook": "",
- "lib.shared-messages.address": "",
- "lib.shared-messages.addressPlaceholder": "",
- "lib.shared-messages.admin": "",
- "lib.shared-messages.adminContact": "",
+ "lib.shared-messages.addPubsub": "Pub/Subの追加",
+ "lib.shared-messages.addWebhook": "webhookの追加",
+ "lib.shared-messages.address": "住所",
+ "lib.shared-messages.addressPlaceholder": "ホスト",
+ "lib.shared-messages.admin": "管理者",
+ "lib.shared-messages.adminContact": "管理連絡先",
"lib.shared-messages.adminDescription": "",
- "lib.shared-messages.adminPanel": "",
- "lib.shared-messages.all": "",
- "lib.shared-messages.allAdmin": "",
- "lib.shared-messages.altitude": "",
- "lib.shared-messages.altitudeDesc": "",
- "lib.shared-messages.antennas": "",
- "lib.shared-messages.apiKey": "",
- "lib.shared-messages.apiKeyCounted": "",
- "lib.shared-messages.apiKeyNamePlaceholder": "",
- "lib.shared-messages.apiKeys": "",
+ "lib.shared-messages.adminPanel": "管理パネル",
+ "lib.shared-messages.all": "すべて",
+ "lib.shared-messages.allAdmin": "すべて(管理者)",
+ "lib.shared-messages.altitude": "高度",
+ "lib.shared-messages.altitudeDesc": "メートル単位の高度で、0は海抜を意味します",
+ "lib.shared-messages.antennas": "アンテナ",
+ "lib.shared-messages.apiKey": "APIキー",
+ "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": "",
- "lib.shared-messages.appEUIDescription": "",
- "lib.shared-messages.appEUIJoinEUI": "",
- "lib.shared-messages.appId": "",
- "lib.shared-messages.appKey": "",
+ "lib.shared-messages.appEUI": "AppEUI",
+ "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": "",
- "lib.shared-messages.application": "",
- "lib.shared-messages.applicationServerAddress": "",
- "lib.shared-messages.applications": "",
- "lib.shared-messages.approve": "",
- "lib.shared-messages.asServerID": "",
- "lib.shared-messages.asServerIDDescription": "",
- "lib.shared-messages.asServerKekLabel": "",
- "lib.shared-messages.asServerKekLabelDescription": "",
- "lib.shared-messages.attributeDescription": "",
- "lib.shared-messages.attributeKeyValidateTooLong": "",
- "lib.shared-messages.attributeKeyValidateTooShort": "",
- "lib.shared-messages.attributeValueValidateTooLong": "",
- "lib.shared-messages.attributes": "",
- "lib.shared-messages.attributesValidateRequired": "",
- "lib.shared-messages.attributesValidateTooMany": "",
- "lib.shared-messages.authorization": "",
- "lib.shared-messages.authorizationCode": "",
- "lib.shared-messages.authorizations": "",
- "lib.shared-messages.autoUpdateDescription": "",
- "lib.shared-messages.automaticUpdates": "",
+ "lib.shared-messages.appSKey": "AppSKey",
+ "lib.shared-messages.application": "アプリケーション",
+ "lib.shared-messages.applicationServerAddress": "アプリケーションサーバのアドレス",
+ "lib.shared-messages.applications": "アプリケーション",
+ "lib.shared-messages.approve": "承認",
+ "lib.shared-messages.asServerID": "アプリケーションサーバID",
+ "lib.shared-messages.asServerIDDescription": "使用するアプリケーションサーバのAS-ID",
+ "lib.shared-messages.asServerKekLabel": "アプリケーションサーバKEKラベル",
+ "lib.shared-messages.asServerKekLabelDescription": "アプリケーションセッションキーのラッピングに使用するアプリケーションサーバのKEKラベル",
+ "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.authorization": "オーソライズ",
+ "lib.shared-messages.authorizationCode": "オーソライズコード",
+ "lib.shared-messages.authorizations": "オーソライズ",
+ "lib.shared-messages.autoUpdateDescription": "ゲートウェイは自動更新可能",
+ "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": "",
- "lib.shared-messages.changePassword": "",
- "lib.shared-messages.channel": "",
- "lib.shared-messages.claimAuthCode": "",
- "lib.shared-messages.claiming": "",
- "lib.shared-messages.classBTimeout": "",
- "lib.shared-messages.classCTimeout": "",
- "lib.shared-messages.clear": "",
- "lib.shared-messages.client": "",
+ "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": "場所の設定を変更",
+ "lib.shared-messages.changePassword": "パスワードの変更",
+ "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": "",
- "lib.shared-messages.collaboratorDeleteSuccess": "",
- "lib.shared-messages.collaboratorEdit": "",
- "lib.shared-messages.collaboratorEditRights": "",
- "lib.shared-messages.collaboratorId": "",
- "lib.shared-messages.collaboratorIdPlaceholder": "",
- "lib.shared-messages.collaboratorModalWarning": "",
- "lib.shared-messages.collaboratorModalWarningSelf": "",
- "lib.shared-messages.collaboratorRemove": "",
- "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": "",
- "lib.shared-messages.componentNs": "",
- "lib.shared-messages.componentQrg": "",
- "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.contactFieldPlaceholder": "",
- "lib.shared-messages.contactInformation": "",
- "lib.shared-messages.convertMacToEui": "",
- "lib.shared-messages.copiedToClipboard": "",
- "lib.shared-messages.copyToClipboard": "",
- "lib.shared-messages.createApiKey": "",
- "lib.shared-messages.createApplication": "",
- "lib.shared-messages.createOrganization": "",
- "lib.shared-messages.created": "",
- "lib.shared-messages.createdAt": "",
- "lib.shared-messages.currentCollaborators": "",
- "lib.shared-messages.currentUserIndicator": "",
- "lib.shared-messages.data": "",
- "lib.shared-messages.defineRights": "",
- "lib.shared-messages.delayWarning": "",
- "lib.shared-messages.deleteModalConfirmDeletion": "",
- "lib.shared-messages.deleteModalConfirmMessage": "",
- "lib.shared-messages.deleteModalDefaultMessage": "",
- "lib.shared-messages.deleteModalPurgeMessage": "",
- "lib.shared-messages.deleteModalPurgeWarning": "",
- "lib.shared-messages.deleteModalReleaseIdLabel": "",
- "lib.shared-messages.deleteModalReleaseIdTitle": "",
- "lib.shared-messages.deleteModalTitle": "",
- "lib.shared-messages.deleted": "",
- "lib.shared-messages.description": "",
- "lib.shared-messages.devAddr": "",
- "lib.shared-messages.devDesc": "",
- "lib.shared-messages.devEUI": "",
- "lib.shared-messages.devEUIBlockLimitReached": "",
- "lib.shared-messages.devID": "",
- "lib.shared-messages.devName": "",
- "lib.shared-messages.device": "",
- "lib.shared-messages.deviceCounted": "",
- "lib.shared-messages.deviceDescDescription": "",
- "lib.shared-messages.deviceDescPlaceholder": "",
+ "lib.shared-messages.collaborator": "コラボレーター",
+ "lib.shared-messages.collaboratorCounted": "{count, plural, one {コラボレーター} other {コラボレータース}}",
+ "lib.shared-messages.collaboratorDeleteSuccess": "コラボレーターの削除",
+ "lib.shared-messages.collaboratorEdit": "{collaboratorId}の編集",
+ "lib.shared-messages.collaboratorEditRights": "{collaboratorId}の編集権限",
+ "lib.shared-messages.collaboratorId": "コラボレーターID",
+ "lib.shared-messages.collaboratorIdPlaceholder": "collaborator-id",
+ "lib.shared-messages.collaboratorModalWarning": "コラボレータとして{collaboratorId}を削除してもよろしいでしょうか?",
+ "lib.shared-messages.collaboratorModalWarningSelf": "本当にコラボレーターを削除しますか?このエンティティへのアクセスは、他の誰かがあなたを再びコラボレーターとして追加するまで失われます",
+ "lib.shared-messages.collaboratorRemove": "コラボレーターの削除",
+ "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.confirm": "確認",
+ "lib.shared-messages.confirmPassword": "パスワードの確認",
+ "lib.shared-messages.confirmedDownlink": "確認済みダウンリンク",
+ "lib.shared-messages.connected": "接続済",
+ "lib.shared-messages.connecting": "接続中",
+ "lib.shared-messages.connectionIssues": "接続の問題",
+ "lib.shared-messages.contactFieldPlaceholder": "コラボレーターを入力または選択",
+ "lib.shared-messages.contactInformation": "連絡先",
+ "lib.shared-messages.convertMacToEui": "MACをEUIに変換",
+ "lib.shared-messages.copiedToClipboard": "クリップボードにコピーされます!",
+ "lib.shared-messages.copyToClipboard": "クリップボードにコピー",
+ "lib.shared-messages.createApiKey": "APIキーの作成",
+ "lib.shared-messages.createApplication": "アプリケーションの作成",
+ "lib.shared-messages.createOrganization": "組織をつくる",
+ "lib.shared-messages.created": "作成済",
+ "lib.shared-messages.createdAt": "で作成しました。",
+ "lib.shared-messages.currentCollaborators": "現在のコラボレーター",
+ "lib.shared-messages.currentUserIndicator": "(これはあなたです)",
+ "lib.shared-messages.data": "データ",
+ "lib.shared-messages.defineRights": "権利の定義",
+ "lib.shared-messages.delayWarning": "遅延が短すぎます。ゲートウェイサーバーは下限値 ({minimumValue}ms) を使用します",
+ "lib.shared-messages.deleteModalConfirmDeletion": "削除の確認",
+ "lib.shared-messages.deleteModalConfirmMessage": "削除を確認するため、{entityId} を入力してください",
+ "lib.shared-messages.deleteModalDefaultMessage": "これにより、ENTITY自身と、共同研究者の関連付けを含むすべての関連するENTITYが永久に削除されます。また、ENTITY IDを再利用することもできなくなります",
+ "lib.shared-messages.deleteModalPurgeMessage": "これにより、そのエンティティ自身と、共同作業者の関連付けを含むすべての関連付けが永久に削除されます",
+ "lib.shared-messages.deleteModalPurgeWarning": "エンティティIDを公開すると、同じIDで新しいエンティティを登録することができるようになります。ただし、これは不可逆的であり、同じIDのエンティティを登録した場合、他のユーザーがそのエンティティの履歴データにアクセスできるようになる可能性があります。こちら に記載されているパージの意味合いをよく理解してください。",
+ "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": "",
- "lib.shared-messages.deviceNamePlaceholder": "",
- "lib.shared-messages.deviceSimulationDisabledWarning": "",
- "lib.shared-messages.devices": "",
- "lib.shared-messages.disabled": "",
- "lib.shared-messages.disconnected": "",
- "lib.shared-messages.documentation": "",
- "lib.shared-messages.downlink": "",
- "lib.shared-messages.downlinkAck": "",
- "lib.shared-messages.downlinkFailed": "",
- "lib.shared-messages.downlinkFrameCount": "",
- "lib.shared-messages.downlinkNack": "",
- "lib.shared-messages.downlinkPush": "",
- "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": "",
- "lib.shared-messages.email": "",
- "lib.shared-messages.emailAddress": "",
+ "lib.shared-messages.deviceIdPlaceholder": "my-new-device",
+ "lib.shared-messages.deviceNamePlaceholder": "私の新しいエンドデバイス",
+ "lib.shared-messages.deviceSimulationDisabledWarning": "ペイロード暗号をスキップする機器では、シミュレーションは無効になります",
+ "lib.shared-messages.devices": "エンドデバイス",
+ "lib.shared-messages.disabled": "無効化",
+ "lib.shared-messages.disconnected": "切断されます",
+ "lib.shared-messages.documentation": "ドキュメンテーション",
+ "lib.shared-messages.downlink": "ダウンリンク",
+ "lib.shared-messages.downlinkAck": "ダウンリンク ACK",
+ "lib.shared-messages.downlinkFailed": "ダウンリンクに失敗しました。",
+ "lib.shared-messages.downlinkFrameCount": "ダウンリンクのフレームカウント",
+ "lib.shared-messages.downlinkNack": "裸のダウンリンク",
+ "lib.shared-messages.downlinkPush": "ダウンリンクプッシュ",
+ "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.endDeviceModelsUnavailable": "",
- "lib.shared-messages.enforceDutyCycle": "",
- "lib.shared-messages.enforceDutyCycleDescription": "",
- "lib.shared-messages.entityId": "",
- "lib.shared-messages.eventDownlinkAckDesc": "",
- "lib.shared-messages.eventDownlinkFailedDesc": "",
- "lib.shared-messages.eventDownlinkNackDesc": "",
- "lib.shared-messages.eventDownlinkPushDesc": "",
- "lib.shared-messages.eventDownlinkQueueInvalidatedDesc": "",
- "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": "",
- "lib.shared-messages.eventUplinkMessageDesc": "",
- "lib.shared-messages.eventUplinkNormalizedDesc": "",
- "lib.shared-messages.eventsCannotShow": "",
- "lib.shared-messages.expiry": "",
- "lib.shared-messages.exportJson": "",
- "lib.shared-messages.external": "",
- "lib.shared-messages.externalJoinServer": "",
+ "lib.shared-messages.empty": "空の状態",
+ "lib.shared-messages.enabled": "有効化",
+ "lib.shared-messages.endDeviceModelsUnavailable": "エンドデバイスモデルが利用できません",
+ "lib.shared-messages.enforceDutyCycle": "デューティサイクルの強制",
+ "lib.shared-messages.enforceDutyCycleDescription": "スペクトラム規制を尊重するため、すべてのゲートウェイに推奨されています",
+ "lib.shared-messages.entityId": "エンティティID",
+ "lib.shared-messages.eventDownlinkAckDesc": "確認されたダウンリンクは、エンドデバイスによって確認されます",
+ "lib.shared-messages.eventDownlinkFailedDesc": "ダウンリンクは送信できません",
+ "lib.shared-messages.eventDownlinkNackDesc": "送信された確認済みダウンリンクが、エンドデバイスの確認に失敗した場合",
+ "lib.shared-messages.eventDownlinkPushDesc": "ダウンリンクがダウンリンクキューにプッシュされます",
+ "lib.shared-messages.eventDownlinkQueueInvalidatedDesc": "フレームカウンターの不一致によりダウンリンクキューがリセットされます",
+ "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": "インテグレーションがイベントを発信します",
+ "lib.shared-messages.eventUplinkMessageDesc": "アップリンクメッセージをアプリケーションで受信した場合",
+ "lib.shared-messages.eventUplinkNormalizedDesc": "正規化されたアップリンクペイロード",
+ "lib.shared-messages.eventsCannotShow": "イベントを表示できません",
+ "lib.shared-messages.expiry": "期限切れ",
+ "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.format": "",
- "lib.shared-messages.fpNotFoundError": "",
- "lib.shared-messages.frameCounterWidth": "",
- "lib.shared-messages.freqAdd": "",
- "lib.shared-messages.frequencyPlaceholder": "",
- "lib.shared-messages.frequencyPlan": "",
- "lib.shared-messages.frequencyPlanWarning": "",
- "lib.shared-messages.furtherResources": "",
- "lib.shared-messages.gateway": "",
- "lib.shared-messages.gatewayDescDescription": "",
- "lib.shared-messages.gatewayDescPlaceholder": "",
- "lib.shared-messages.gatewayDescription": "",
- "lib.shared-messages.gatewayEUI": "",
- "lib.shared-messages.gatewayID": "",
- "lib.shared-messages.gatewayIdPlaceholder": "",
- "lib.shared-messages.gatewayLocation": "",
- "lib.shared-messages.gatewayLocationPublic": "",
- "lib.shared-messages.gatewayName": "",
- "lib.shared-messages.gatewayNamePlaceholder": "",
- "lib.shared-messages.gatewayScheduleDownlinkLate": "",
- "lib.shared-messages.gatewayServerAddress": "",
- "lib.shared-messages.gatewayStatus": "",
- "lib.shared-messages.gatewayStatusPublic": "",
- "lib.shared-messages.gatewayUpdateOptions": "",
- "lib.shared-messages.gateways": "",
- "lib.shared-messages.general": "",
- "lib.shared-messages.generalInformation": "",
- "lib.shared-messages.generalSettings": "",
- "lib.shared-messages.generateAPIKeyCups": "",
- "lib.shared-messages.generateAPIKeyLNS": "",
- "lib.shared-messages.getSupport": "",
- "lib.shared-messages.grantAdminStatus": "",
- "lib.shared-messages.grpcService": "",
- "lib.shared-messages.gsServerAddressDescription": "",
- "lib.shared-messages.hardware": "",
- "lib.shared-messages.hardwareVersion": "",
- "lib.shared-messages.homeNetID": "",
- "lib.shared-messages.homeNetIDDescription": "",
- "lib.shared-messages.hours": "",
- "lib.shared-messages.id": "",
- "lib.shared-messages.idAlreadyExists": "",
- "lib.shared-messages.import": "",
- "lib.shared-messages.importDevices": "",
- "lib.shared-messages.inputMethod": "",
- "lib.shared-messages.insufficientAppKeyRights": "",
- "lib.shared-messages.insufficientNwkKeyRights": "",
- "lib.shared-messages.integrations": "",
- "lib.shared-messages.invite": "",
- "lib.shared-messages.joinAccept": "",
- "lib.shared-messages.joinEUI": "",
- "lib.shared-messages.joinServerAddress": "",
- "lib.shared-messages.key": "",
- "lib.shared-messages.keyEdit": "",
- "lib.shared-messages.keyId": "",
- "lib.shared-messages.lastSeen": "",
- "lib.shared-messages.latitude": "",
- "lib.shared-messages.latitudeDesc": "",
- "lib.shared-messages.lbsLNSSecret": "",
- "lib.shared-messages.lbsLNSSecretDescription": "",
- "lib.shared-messages.link": "",
- "lib.shared-messages.linked": "",
- "lib.shared-messages.liveData": "",
- "lib.shared-messages.location": "",
- "lib.shared-messages.locationDescription": "",
- "lib.shared-messages.locationMarkerDescriptionNonUser": "",
- "lib.shared-messages.locationMarkerDescriptionUntrusted": "",
- "lib.shared-messages.locationMarkerDescriptionUser": "",
- "lib.shared-messages.locationSolved": "",
- "lib.shared-messages.locationSourceBtRssi": "",
- "lib.shared-messages.locationSourceCombined": "",
- "lib.shared-messages.locationSourceGps": "",
- "lib.shared-messages.locationSourceIpGeolocation": "",
- "lib.shared-messages.locationSourceLoraRssi": "",
- "lib.shared-messages.locationSourceLoraTdoa": "",
- "lib.shared-messages.locationSourceRegistry": "",
- "lib.shared-messages.locationSourceWifiRssi": "",
- "lib.shared-messages.login": "",
- "lib.shared-messages.loginFailed": "",
- "lib.shared-messages.logout": "",
- "lib.shared-messages.longitude": "",
- "lib.shared-messages.longitudeDesc": "",
- "lib.shared-messages.loraCloud": "",
- "lib.shared-messages.loraCloudServerUrlDescription": "",
- "lib.shared-messages.lorawanClassCapabilities": "",
- "lib.shared-messages.lorawanInformation": "",
- "lib.shared-messages.lorawanOptions": "",
- "lib.shared-messages.lorawanPhyVersionDescription": "",
- "lib.shared-messages.macSettingsError": "",
- "lib.shared-messages.macVersion": "",
- "lib.shared-messages.messageTypes": "",
- "lib.shared-messages.messages": "",
- "lib.shared-messages.messaging": "",
- "lib.shared-messages.milliseconds": "",
- "lib.shared-messages.minutes": "",
- "lib.shared-messages.model": "",
- "lib.shared-messages.moreInformation": "",
- "lib.shared-messages.mqtt": "",
- "lib.shared-messages.multicast": "",
- "lib.shared-messages.name": "",
- "lib.shared-messages.netId": "",
+ "lib.shared-messages.fetching": "データの取得...",
+ "lib.shared-messages.firmwareVersion": "ファームウェアバージョン",
+ "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": "その他のリソース",
+ "lib.shared-messages.gateway": "ゲートウェイ",
+ "lib.shared-messages.gatewayDescDescription": "オプションのゲートウェイの説明;ゲートウェイについてのメモを保存するために使用することもできます",
+ "lib.shared-messages.gatewayDescPlaceholder": "新しいゲートウェイの説明",
+ "lib.shared-messages.gatewayDescription": "ゲートウェイの説明",
+ "lib.shared-messages.gatewayEUI": "ゲートウェイEUI",
+ "lib.shared-messages.gatewayID": "ゲートウェイID",
+ "lib.shared-messages.gatewayIdPlaceholder": "my-new-gateway",
+ "lib.shared-messages.gatewayLocation": "ゲートウェイの場所",
+ "lib.shared-messages.gatewayLocationPublic": "ネットワーク内での位置情報の共有",
+ "lib.shared-messages.gatewayName": "ゲートウェイ名",
+ "lib.shared-messages.gatewayNamePlaceholder": "私の新しいゲートウェイ",
+ "lib.shared-messages.gatewayScheduleDownlinkLate": "スケジュールダウンリンクの遅延",
+ "lib.shared-messages.gatewayServerAddress": "ゲートウェイサーバのアドレス",
+ "lib.shared-messages.gatewayStatus": "ゲートウェイの状態",
+ "lib.shared-messages.gatewayStatusPublic": "ネットワーク内でステータスを共有",
+ "lib.shared-messages.gatewayUpdateOptions": "ゲートウェイの更新",
+ "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": "ハードウェアバージョン",
+ "lib.shared-messages.homeNetID": "ホーム NetID",
+ "lib.shared-messages.homeNetIDDescription": "LoRaWANネットワークを識別するためのID",
+ "lib.shared-messages.hours": "時間",
+ "lib.shared-messages.id": "ID",
+ "lib.shared-messages.idAlreadyExists": "IDはすでに存在しています。",
+ "lib.shared-messages.import": "インポート",
+ "lib.shared-messages.importDevices": "エンドデバイスのインポート",
+ "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": "キー",
+ "lib.shared-messages.keyEdit": "APIキーの編集",
+ "lib.shared-messages.keyId": "キーID",
+ "lib.shared-messages.lastSeen": "最後に閲覧",
+ "lib.shared-messages.latitude": "緯度",
+ "lib.shared-messages.latitudeDesc": "南北の位置を度数で表したもので、0は赤道です",
+ "lib.shared-messages.lbsLNSSecret": "LoRa Basics Station LNS 認証キー",
+ "lib.shared-messages.lbsLNSSecretDescription": "LoRa Basics Station LNS 接続のための認証キーです。このフィールドは、他のゲートウェイでは無視されます",
+ "lib.shared-messages.link": "リンク",
+ "lib.shared-messages.linked": "リンク済",
+ "lib.shared-messages.liveData": "ライブデータ",
+ "lib.shared-messages.location": "場所",
+ "lib.shared-messages.locationDescription": "公開に設定すると、ゲートウェイの位置がネットワークの他のユーザーから見えることがあります",
+ "lib.shared-messages.locationMarkerDescriptionNonUser": "この位置は、このデバイスの受信メッセージから自動的に設定されました",
+ "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.locationSourceIpGeolocation": "IPに基づくジオロケーション",
+ "lib.shared-messages.locationSourceLoraRssi": "LoRa RSSIジオロケーション",
+ "lib.shared-messages.locationSourceLoraTdoa": "LoRa TDOAジオロケーション",
+ "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は主子午線(グリニッジ)です",
+ "lib.shared-messages.loraCloud": "LoRa Cloud",
+ "lib.shared-messages.loraCloudServerUrlDescription": "LoRa Cloud モデム・ジオロケーションサービスサーバーURL",
+ "lib.shared-messages.lorawanClassCapabilities": "LoRaWANのクラス機能",
+ "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.milliseconds": "ミリ秒",
+ "lib.shared-messages.minutes": "分",
+ "lib.shared-messages.model": "モデル",
+ "lib.shared-messages.moreInformation": "詳細情報",
+ "lib.shared-messages.mqtt": "MQTT",
+ "lib.shared-messages.multicast": "マルチキャスト",
+ "lib.shared-messages.name": "名前",
+ "lib.shared-messages.netId": "Net ID",
"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.noDesc": "",
- "lib.shared-messages.noEvents": "",
- "lib.shared-messages.noLocation": "",
- "lib.shared-messages.noMatch": "",
+ "lib.shared-messages.networkServerAddress": "ネットワークサーバーアドレス",
+ "lib.shared-messages.networks": "ネットワーク",
+ "lib.shared-messages.never": "ネバー",
+ "lib.shared-messages.next": "次へ",
+ "lib.shared-messages.noActivityYet": "まだ活動はしていません",
+ "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.normalizedPayloadAir": "",
- "lib.shared-messages.normalizedPayloadSoil": "",
- "lib.shared-messages.normalizedPayloadWind": "",
- "lib.shared-messages.notAvailable": "",
- "lib.shared-messages.notLinked": "",
- "lib.shared-messages.notSet": "",
- "lib.shared-messages.nsEmptyDefault": "",
- "lib.shared-messages.nsServerKekLabel": "",
- "lib.shared-messages.nsServerKekLabelDescription": "",
- "lib.shared-messages.nwkKey": "",
- "lib.shared-messages.nwkSEncKey": "",
- "lib.shared-messages.nwkSEncKeyDescription": "",
- "lib.shared-messages.nwkSKey": "",
- "lib.shared-messages.oauthClientAuthorizations": "",
- "lib.shared-messages.oauthClientId": "",
- "lib.shared-messages.oauthClients": "",
- "lib.shared-messages.offline": "",
- "lib.shared-messages.ok": "",
- "lib.shared-messages.online": "",
- "lib.shared-messages.options": "",
- "lib.shared-messages.organization": "",
- "lib.shared-messages.organizationId": "",
- "lib.shared-messages.organizations": "",
- "lib.shared-messages.otaa": "",
- "lib.shared-messages.otherCluster": "",
- "lib.shared-messages.otherOption": "",
- "lib.shared-messages.overview": "",
- "lib.shared-messages.packetBroker": "",
- "lib.shared-messages.password": "",
- "lib.shared-messages.passwordChanged": "",
- "lib.shared-messages.pause": "",
- "lib.shared-messages.payload": "",
- "lib.shared-messages.payloadFormatters": "",
- "lib.shared-messages.payloadFormattersDownlink": "",
- "lib.shared-messages.payloadFormattersUpdateFailure": "",
- "lib.shared-messages.payloadFormattersUpdateSuccess": "",
- "lib.shared-messages.payloadFormattersUplink": "",
- "lib.shared-messages.personalApiKeys": "",
- "lib.shared-messages.phyVersion": "",
- "lib.shared-messages.phyVersionDescription": "",
+ "lib.shared-messages.noRecentActivity": "最近の活動はありません",
+ "lib.shared-messages.none": "なし",
+ "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.nsEmptyDefault": "同じクラスタ内のネットワークサーバーにリンクするには空のままにします",
+ "lib.shared-messages.nsServerKekLabel": "ネットワークサーバーKEKラベル",
+ "lib.shared-messages.nsServerKekLabelDescription": "ネットワーク・セッション・キーのラッピングに使用するネットワーク・サーバの KEK ラベル",
+ "lib.shared-messages.nwkKey": "NwkKey",
+ "lib.shared-messages.nwkSEncKey": "NwkSEncKey",
+ "lib.shared-messages.nwkSEncKeyDescription": "ネットワークセッション暗号化キー",
+ "lib.shared-messages.nwkSKey": "NwkSKey",
+ "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": "オンライン",
+ "lib.shared-messages.options": "オプション",
+ "lib.shared-messages.organization": "組織",
+ "lib.shared-messages.organizationId": "組織ID",
+ "lib.shared-messages.organizations": "組織",
+ "lib.shared-messages.otaa": "Over the air activation (OTAA)",
+ "lib.shared-messages.otherCluster": "他のクラスター",
+ "lib.shared-messages.otherOption": "その他…",
+ "lib.shared-messages.overview": "概要",
+ "lib.shared-messages.packetBroker": "Packet Broker",
+ "lib.shared-messages.password": "パスワード",
+ "lib.shared-messages.passwordChanged": "パスワード変更",
+ "lib.shared-messages.pause": "一時停止",
+ "lib.shared-messages.payload": "ペイロード",
+ "lib.shared-messages.payloadFormatters": "ペイロードフォーマッター",
+ "lib.shared-messages.payloadFormattersDownlink": "ダウンリンクペイロードフォーマッター",
+ "lib.shared-messages.payloadFormattersUpdateFailure": "ペイロードフォーマッターの更新にエラーがありました",
+ "lib.shared-messages.payloadFormattersUpdateSuccess": "ペイロードフォーマッターの更新",
+ "lib.shared-messages.payloadFormattersUplink": "アップリンクペイロードフォーマッター",
+ "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": "",
- "lib.shared-messages.provider": "",
- "lib.shared-messages.provisionedOnExternalJoinServer": "",
- "lib.shared-messages.pubsubBaseTopic": "",
- "lib.shared-messages.pubsubFormat": "",
- "lib.shared-messages.pubsubId": "",
- "lib.shared-messages.pubsubs": "",
- "lib.shared-messages.purge": "",
- "lib.shared-messages.redirecting": "",
- "lib.shared-messages.refresh": "",
- "lib.shared-messages.registerEndDevice": "",
- "lib.shared-messages.registerGateway": "",
+ "lib.shared-messages.port": "ポート",
+ "lib.shared-messages.privacyPolicy": "個人情報保護方針",
+ "lib.shared-messages.profileSettings": "プロファイル設定",
+ "lib.shared-messages.provider": "プロバイダー",
+ "lib.shared-messages.provisionedOnExternalJoinServer": "外部のJoinサーバーでプロビジョニング",
+ "lib.shared-messages.pubsubBaseTopic": "基本トピック",
+ "lib.shared-messages.pubsubFormat": "Pub/Subフォーマット",
+ "lib.shared-messages.pubsubId": "Pub/Sub ID",
+ "lib.shared-messages.pubsubs": "Pub/Subs",
+ "lib.shared-messages.purge": "パージ(消去)",
+ "lib.shared-messages.redirecting": "リダイレクト中...",
+ "lib.shared-messages.refresh": "リフレッシュ",
+ "lib.shared-messages.registerEndDevice": "エンドデバイスの登録",
+ "lib.shared-messages.registerGateway": "ゲートウェイの登録",
"lib.shared-messages.remove": "",
- "lib.shared-messages.removeCollaborator": "",
- "lib.shared-messages.removeCollaboratorLast": "",
- "lib.shared-messages.removeCollaboratorSelf": "",
- "lib.shared-messages.replaceWebhook": "",
- "lib.shared-messages.requireAuthenticatedConnection": "",
- "lib.shared-messages.requireAuthenticatedConnectionDescription": "",
- "lib.shared-messages.reset": "",
- "lib.shared-messages.resetWarning": "",
- "lib.shared-messages.resetsFCnt": "",
- "lib.shared-messages.resetsJoinNonces": "",
- "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.removeCollaborator": "コラボレーターの削除",
+ "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.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": "",
- "lib.shared-messages.sNwkSIKeyDescription": "",
- "lib.shared-messages.saveChanges": "",
+ "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": "",
- "lib.shared-messages.scheduleDownlinkLateDescription": "",
- "lib.shared-messages.search": "",
+ "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": "",
- "lib.shared-messages.secret": "",
- "lib.shared-messages.secure": "",
- "lib.shared-messages.sendInvitation": "",
- "lib.shared-messages.serverUrl": "",
- "lib.shared-messages.serviceData": "",
- "lib.shared-messages.sessions": "",
+ "lib.shared-messages.seconds": "秒",
+ "lib.shared-messages.secondsAbbreviated": "sec",
+ "lib.shared-messages.secret": "秘密",
+ "lib.shared-messages.secure": "セキュア",
+ "lib.shared-messages.sendInvitation": "招待状送付",
+ "lib.shared-messages.serverUrl": "サーバーURL",
+ "lib.shared-messages.serviceData": "サービスデータ",
+ "lib.shared-messages.sessions": "セッション",
"lib.shared-messages.setLoRaCloudToken": "",
- "lib.shared-messages.settings": "",
- "lib.shared-messages.shareGatewayInfo": "",
- "lib.shared-messages.skipCryptoDescription": "",
- "lib.shared-messages.skipCryptoPlaceholder": "",
- "lib.shared-messages.skipCryptoTitle": "",
- "lib.shared-messages.source": "",
- "lib.shared-messages.stable": "",
- "lib.shared-messages.state": "",
- "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.statusPage": "",
- "lib.shared-messages.statusUnknown": "",
- "lib.shared-messages.success": "",
+ "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.source": "ソース",
+ "lib.shared-messages.stable": "安定した",
+ "lib.shared-messages.state": "状態",
+ "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.statusPage": "ステータスページ",
+ "lib.shared-messages.statusUnknown": "ステータス不明",
+ "lib.shared-messages.success": "成功",
"lib.shared-messages.suggestions": "",
- "lib.shared-messages.supportsClassB": "",
- "lib.shared-messages.supportsClassC": "",
- "lib.shared-messages.takeMeBack": "",
- "lib.shared-messages.technicalContact": "",
- "lib.shared-messages.tenantId": "",
- "lib.shared-messages.termsAndCondition": "",
- "lib.shared-messages.time": "",
- "lib.shared-messages.token": "",
- "lib.shared-messages.tokenDelete": "",
- "lib.shared-messages.tokenDeleted": "",
- "lib.shared-messages.tokenSet": "",
- "lib.shared-messages.tokenUpdated": "",
- "lib.shared-messages.traffic": "",
- "lib.shared-messages.troubleshooting": "",
- "lib.shared-messages.type": "",
- "lib.shared-messages.typeToSearch": "",
- "lib.shared-messages.unexposed": "",
- "lib.shared-messages.unknown": "",
- "lib.shared-messages.unknownError": "",
- "lib.shared-messages.unknownHwOption": "",
- "lib.shared-messages.updateChannelDescription": "",
- "lib.shared-messages.updatedAt": "",
- "lib.shared-messages.uplink": "",
- "lib.shared-messages.uplinkFrameCount": "",
- "lib.shared-messages.uplinkMessage": "",
- "lib.shared-messages.uplinkNormalized": "",
- "lib.shared-messages.uplinksReceived": "",
+ "lib.shared-messages.supportsClassB": "クラスBをサポート",
+ "lib.shared-messages.supportsClassC": "クラスCをサポート",
+ "lib.shared-messages.takeMeBack": "私を連れ戻して",
+ "lib.shared-messages.technicalContact": "技術連絡先",
+ "lib.shared-messages.tenantId": "テナントID",
+ "lib.shared-messages.termsAndCondition": "ご利用規約",
+ "lib.shared-messages.time": "時間",
+ "lib.shared-messages.token": "トークン",
+ "lib.shared-messages.tokenDelete": "トークン削除",
+ "lib.shared-messages.tokenDeleted": "削除されたトークン",
+ "lib.shared-messages.tokenSet": "トークンの設定",
+ "lib.shared-messages.tokenUpdated": "トークンの更新",
+ "lib.shared-messages.traffic": "トラフィック",
+ "lib.shared-messages.troubleshooting": "トラブルシューティング",
+ "lib.shared-messages.type": "タイプ",
+ "lib.shared-messages.typeToSearch": "検索に入力する…",
+ "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": "アップリンク",
+ "lib.shared-messages.uplinkFrameCount": "アップリンクフレーム数",
+ "lib.shared-messages.uplinkMessage": "アップリンクメッセージ",
+ "lib.shared-messages.uplinkNormalized": "正規化されたアップリンク",
+ "lib.shared-messages.uplinksReceived": "アップリンクを受信",
"lib.shared-messages.uploadAnImage": "",
- "lib.shared-messages.used": "",
- "lib.shared-messages.user": "",
- "lib.shared-messages.userAdd": "",
- "lib.shared-messages.userDelete": "",
+ "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": "",
+ "lib.shared-messages.userEdit": "ユーザーを編集",
+ "lib.shared-messages.userId": "ユーザーID",
"lib.shared-messages.userIdPlaceholder": "",
- "lib.shared-messages.userInvitations": "",
- "lib.shared-messages.userManagement": "",
+ "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": "",
- "lib.shared-messages.validateApiKey": "",
- "lib.shared-messages.validateDateInPast": "",
- "lib.shared-messages.validateDelayFormat": "",
- "lib.shared-messages.validateDigit": "",
- "lib.shared-messages.validateEmail": "",
- "lib.shared-messages.validateFreqDynamic": "",
- "lib.shared-messages.validateFreqNumeric": "",
- "lib.shared-messages.validateFreqRequired": "",
- "lib.shared-messages.validateHexLength": "",
- "lib.shared-messages.validateIdFormat": "",
- "lib.shared-messages.validateInt32": "",
- "lib.shared-messages.validateJson": "",
- "lib.shared-messages.validateLatitude": "",
- "lib.shared-messages.validateLength": "",
- "lib.shared-messages.validateLongitude": "",
- "lib.shared-messages.validateMacAddressEntered": "",
- "lib.shared-messages.validateMqttPassword": "",
- "lib.shared-messages.validateMqttUrl": "",
- "lib.shared-messages.validateNoSpaces": "",
- "lib.shared-messages.validateNumberGte": "",
- "lib.shared-messages.validateNumberLte": "",
- "lib.shared-messages.validatePasswordMatch": "",
- "lib.shared-messages.validateRequired": "",
- "lib.shared-messages.validateRights": "",
- "lib.shared-messages.validateSpecial": "",
- "lib.shared-messages.validateTooLong": "",
- "lib.shared-messages.validateTooShort": "",
- "lib.shared-messages.validateUppercase": "",
- "lib.shared-messages.validateUrl": "",
- "lib.shared-messages.value": "",
- "lib.shared-messages.webhookActivated": "",
- "lib.shared-messages.webhookAlreadyExistsModalMessage": "",
- "lib.shared-messages.webhookBaseUrl": "",
- "lib.shared-messages.webhookDeleted": "",
- "lib.shared-messages.webhookFormat": "",
- "lib.shared-messages.webhookId": "",
+ "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.validateHexLength": "{field} は完全な16進数の値でなければなりません",
+ "lib.shared-messages.validateIdFormat": "{field} には小文字、数字、ダッシュ(-)のみを含める必要があります",
+ "lib.shared-messages.validateInt32": "{field}は整数、負または正でなければなりません",
+ "lib.shared-messages.validateJson": "{field}は有効なJSONオブジェクトでなければなりません",
+ "lib.shared-messages.validateLatitude": "緯度は-90から90までの整数または10進数でなければなりません",
+ "lib.shared-messages.validateLength": "{field} は正確に{length}文字の長さでなければなりません",
+ "lib.shared-messages.validateLongitude": "経度は-180から180までの整数または小数でなければなりません",
+ "lib.shared-messages.validateMacAddressEntered": "MACアドレスを入力してください",
+ "lib.shared-messages.validateMqttPassword": "{field}は空か、少なくとも2文字以上でなければなりません",
+ "lib.shared-messages.validateMqttUrl": "MQTTのURLは \"mqtt[s]://[username][:password]@host.domain[:port]\"という形式でなければなりません",
+ "lib.shared-messages.validateNoSpaces": "{field} にはスペースを入れてはいけません",
+ "lib.shared-messages.validateNumberGte": "{field} は少なくとも{min}以上でなければなりません",
+ "lib.shared-messages.validateNumberLte": "{field} は{max}以下でなければなりません",
+ "lib.shared-messages.validatePasswordMatch": "パスワードは一致している必要があります",
+ "lib.shared-messages.validateRequired": "{field}が必要です",
+ "lib.shared-messages.validateRights": "少なくとも1つの権利を選択する必要があります。",
+ "lib.shared-messages.validateSpecial": "{field} は少なくとも{special}special{special,plural, one {character} other {characters}}を持っている必要があります",
+ "lib.shared-messages.validateTooLong": "{field}の文字数は{max}以下でなければなりません",
+ "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.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": "",
+ "lib.shared-messages.webhooks": "Webhooks",
"enum:CHANNEL_MASKS": "チャネルマスク",
"enum:CID_ADR_PARAM_SETUP": "ADRパラメータ",
"enum:CID_BEACON_FREQ": "ビーコン周波数",
@@ -1510,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": "受信パラメータ",
@@ -1883,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がありません",
@@ -1980,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": "ファイル名が特定されません",
@@ -2319,6 +2331,7 @@
"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}' を超えています",
@@ -2354,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状態",
@@ -2674,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": "受信パラメータ設定許可を受信",
@@ -2697,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 4d2fb73c13..f23650871f 100644
--- a/sdk/js/generated/api.json
+++ b/sdk/js/generated/api.json
@@ -9881,6 +9881,18 @@
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
+ },
+ {
+ "name": "band_id",
+ "description": "",
+ "label": "",
+ "type": "string",
+ "longType": "string",
+ "fullType": "string",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
}
]
},
@@ -10153,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": ""
}
]
},
@@ -17284,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",
@@ -17296,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",
@@ -17341,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": ""
}
]
},
@@ -17883,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": ""
}
]
},
@@ -18235,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": ""
}
]
},
@@ -18935,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": ""
}
]
},
@@ -18949,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",
@@ -18981,6 +19076,114 @@
}
]
},
+ {
+ "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": true,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "serving",
+ "description": "Parameters related to a relay which is serving end devices.",
+ "label": "",
+ "type": "ServingRelayParameters",
+ "longType": "ServingRelayParameters",
+ "fullType": "ttn.lorawan.v3.ServingRelayParameters",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "mode",
+ "defaultValue": ""
+ },
+ {
+ "name": "served",
+ "description": "Parameters related to an end device served by a relay.",
+ "label": "",
+ "type": "ServedRelayParameters",
+ "longType": "ServedRelayParameters",
+ "fullType": "ttn.lorawan.v3.ServedRelayParameters",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "mode",
+ "defaultValue": ""
+ }
+ ]
+ },
+ {
+ "name": "RelayUplinkForwardingRule",
+ "longName": "RelayUplinkForwardingRule",
+ "fullName": "ttn.lorawan.v3.RelayUplinkForwardingRule",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "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": "RelayUplinkForwardLimits",
+ "longType": "RelayUplinkForwardLimits",
+ "fullType": "ttn.lorawan.v3.RelayUplinkForwardLimits",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "last_w_f_cnt",
+ "description": "Last wake on radio frame counter used by the served end device.",
+ "label": "",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "device_id",
+ "description": "End device identifier of the served 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,}$"
+ }
+ ]
+ }
+ },
+ {
+ "name": "session_key_id",
+ "description": "Session key ID of the session keys used to derive the root relay session key.",
+ "label": "",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ }
+ ]
+ },
{
"name": "ResetAndGetEndDeviceRequest",
"longName": "ResetAndGetEndDeviceRequest",
@@ -19026,22 +19229,58 @@
]
},
{
- "name": "Session",
- "longName": "Session",
- "fullName": "ttn.lorawan.v3.Session",
+ "name": "ServedRelayParameters",
+ "longName": "ServedRelayParameters",
+ "fullName": "ttn.lorawan.v3.ServedRelayParameters",
"description": "",
"hasExtensions": false,
"hasFields": true,
- "hasOneofs": false,
+ "hasOneofs": true,
"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.",
+ "name": "always",
+ "description": "The end device will always attempt to use the relay mode in order to send uplink messages.",
"label": "",
- "type": "bytes",
- "longType": "bytes",
- "fullType": "bytes",
+ "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": "",
@@ -19049,19 +19288,31 @@
"options": {
"validate.rules": [
{
- "name": "bytes.len",
- "value": 4
+ "name": "uint32.lte",
+ "value": 63
}
]
}
},
{
- "name": "keys",
- "description": "",
+ "name": "second_channel",
+ "description": "Second wake on radio channel configuration.",
"label": "",
- "type": "SessionKeys",
- "longType": "SessionKeys",
- "fullType": "ttn.lorawan.v3.SessionKeys",
+ "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": "",
@@ -19069,72 +19320,296 @@
"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": "ServingRelayForwardingLimits",
+ "longName": "ServingRelayForwardingLimits",
+ "fullName": "ttn.lorawan.v3.ServingRelayForwardingLimits",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "last_f_cnt_up",
- "description": "Last uplink frame counter value used. Network Server only. Application Server assumes the Network Server checked it.",
+ "name": "reset_behavior",
+ "description": "Reset behavior of the buckets upon limit update.",
"label": "",
- "type": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
+ "type": "RelayResetLimitCounter",
+ "longType": "RelayResetLimitCounter",
+ "fullType": "ttn.lorawan.v3.RelayResetLimitCounter",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "last_n_f_cnt_down",
- "description": "Last network downlink frame counter value used. Network Server only.",
+ "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": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
+ "type": "RelayForwardLimits",
+ "longType": "RelayForwardLimits",
+ "fullType": "ttn.lorawan.v3.RelayForwardLimits",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "last_a_f_cnt_down",
- "description": "Last application downlink frame counter value used. Application Server only.",
+ "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": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
+ "type": "RelayForwardLimits",
+ "longType": "RelayForwardLimits",
+ "fullType": "ttn.lorawan.v3.RelayForwardLimits",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "last_conf_f_cnt_down",
- "description": "Frame counter of the last confirmed downlink message sent. Network Server only.",
+ "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": "uint32",
- "longType": "uint32",
- "fullType": "uint32",
+ "type": "RelayForwardLimits",
+ "longType": "RelayForwardLimits",
+ "fullType": "ttn.lorawan.v3.RelayForwardLimits",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "started_at",
- "description": "Time when the session started. Network Server only.",
+ "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": "Timestamp",
- "longType": "google.protobuf.Timestamp",
- "fullType": "google.protobuf.Timestamp",
+ "type": "RelayForwardLimits",
+ "longType": "RelayForwardLimits",
+ "fullType": "ttn.lorawan.v3.RelayForwardLimits",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
- },
+ }
+ ]
+ },
+ {
+ "name": "ServingRelayParameters",
+ "longName": "ServingRelayParameters",
+ "fullName": "ttn.lorawan.v3.ServingRelayParameters",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "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": "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": {
+ "validate.rules": [
+ {
+ "name": "uint32.lte",
+ "value": 255
+ }
+ ]
+ }
+ },
+ {
+ "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": "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": {
+ "validate.rules": [
+ {
+ "name": "repeated.max_items",
+ "value": 16
+ }
+ ]
+ }
+ },
+ {
+ "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": "Session",
+ "longName": "Session",
+ "fullName": "ttn.lorawan.v3.Session",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "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.",
+ "label": "",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "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": "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": "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": "queued_application_downlinks",
"description": "Queued Application downlink messages. Stored in Application Server and Network Server.",
@@ -23020,7 +23495,7 @@
},
{
"name": "repeated.max_items",
- "value": 20
+ "value": 100
}
]
}
@@ -28502,6 +28977,41 @@
"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": "CID_RELAY_CONFIGURE_FWD_LIMIT",
+ "number": "69",
+ "description": ""
+ },
+ {
+ "name": "CID_RELAY_NOTIFY_NEW_END_DEVICE",
+ "number": "70",
+ "description": ""
}
]
},
@@ -29101,55 +29611,251 @@
]
},
{
- "name": "RxDelay",
- "longName": "RxDelay",
- "fullName": "ttn.lorawan.v3.RxDelay",
+ "name": "RelayCADPeriodicity",
+ "longName": "RelayCADPeriodicity",
+ "fullName": "ttn.lorawan.v3.RelayCADPeriodicity",
"description": "",
"values": [
{
- "name": "RX_DELAY_0",
+ "name": "RELAY_CAD_PERIODICITY_1_SECOND",
"number": "0",
- "description": "1 second."
+ "description": ""
},
{
- "name": "RX_DELAY_1",
+ "name": "RELAY_CAD_PERIODICITY_500_MILLISECONDS",
"number": "1",
- "description": "1 second."
+ "description": ""
},
{
- "name": "RX_DELAY_2",
+ "name": "RELAY_CAD_PERIODICITY_250_MILLISECONDS",
"number": "2",
- "description": "2 seconds."
+ "description": ""
},
{
- "name": "RX_DELAY_3",
+ "name": "RELAY_CAD_PERIODICITY_100_MILLISECONDS",
"number": "3",
- "description": "3 seconds."
+ "description": ""
},
{
- "name": "RX_DELAY_4",
+ "name": "RELAY_CAD_PERIODICITY_50_MILLISECONDS",
"number": "4",
- "description": "4 seconds."
+ "description": ""
},
{
- "name": "RX_DELAY_5",
+ "name": "RELAY_CAD_PERIODICITY_20_MILLISECONDS",
"number": "5",
- "description": "5 seconds."
- },
+ "description": "sic"
+ }
+ ]
+ },
+ {
+ "name": "RelayCtrlUplinkListAction",
+ "longName": "RelayCtrlUplinkListAction",
+ "fullName": "ttn.lorawan.v3.RelayCtrlUplinkListAction",
+ "description": "",
+ "values": [
{
- "name": "RX_DELAY_6",
- "number": "6",
- "description": "6 seconds."
+ "name": "RELAY_CTRL_UPLINK_LIST_ACTION_READ_W_F_CNT",
+ "number": "0",
+ "description": ""
},
{
- "name": "RX_DELAY_7",
- "number": "7",
- "description": "7 seconds."
- },
+ "name": "RELAY_CTRL_UPLINK_LIST_ACTION_REMOVE_TRUSTED_END_DEVICE",
+ "number": "1",
+ "description": ""
+ }
+ ]
+ },
+ {
+ "name": "RelayLimitBucketSize",
+ "longName": "RelayLimitBucketSize",
+ "fullName": "ttn.lorawan.v3.RelayLimitBucketSize",
+ "description": "",
+ "values": [
{
- "name": "RX_DELAY_8",
- "number": "8",
- "description": "8 seconds."
+ "name": "RELAY_LIMIT_BUCKET_SIZE_1",
+ "number": "0",
+ "description": ""
+ },
+ {
+ "name": "RELAY_LIMIT_BUCKET_SIZE_2",
+ "number": "1",
+ "description": ""
+ },
+ {
+ "name": "RELAY_LIMIT_BUCKET_SIZE_4",
+ "number": "2",
+ "description": ""
+ },
+ {
+ "name": "RELAY_LIMIT_BUCKET_SIZE_12",
+ "number": "3",
+ "description": "sic"
+ }
+ ]
+ },
+ {
+ "name": "RelayResetLimitCounter",
+ "longName": "RelayResetLimitCounter",
+ "fullName": "ttn.lorawan.v3.RelayResetLimitCounter",
+ "description": "",
+ "values": [
+ {
+ "name": "RELAY_RESET_LIMIT_COUNTER_ZERO",
+ "number": "0",
+ "description": ""
+ },
+ {
+ "name": "RELAY_RESET_LIMIT_COUNTER_RELOAD_RATE",
+ "number": "1",
+ "description": ""
+ },
+ {
+ "name": "RELAY_RESET_LIMIT_COUNTER_MAX_VALUE",
+ "number": "2",
+ "description": ""
+ },
+ {
+ "name": "RELAY_RESET_LIMIT_COUNTER_NO_RESET",
+ "number": "3",
+ "description": ""
+ }
+ ]
+ },
+ {
+ "name": "RelaySecondChAckOffset",
+ "longName": "RelaySecondChAckOffset",
+ "fullName": "ttn.lorawan.v3.RelaySecondChAckOffset",
+ "description": "",
+ "values": [
+ {
+ "name": "RELAY_SECOND_CH_ACK_OFFSET_0",
+ "number": "0",
+ "description": "0 kHz"
+ },
+ {
+ "name": "RELAY_SECOND_CH_ACK_OFFSET_200",
+ "number": "1",
+ "description": "200 kHz"
+ },
+ {
+ "name": "RELAY_SECOND_CH_ACK_OFFSET_400",
+ "number": "2",
+ "description": "400 kHz"
+ },
+ {
+ "name": "RELAY_SECOND_CH_ACK_OFFSET_800",
+ "number": "3",
+ "description": "800 kHz"
+ },
+ {
+ "name": "RELAY_SECOND_CH_ACK_OFFSET_1600",
+ "number": "4",
+ "description": "1.6 MHz"
+ },
+ {
+ "name": "RELAY_SECOND_CH_ACK_OFFSET_3200",
+ "number": "5",
+ "description": "3.2 MHz"
+ }
+ ]
+ },
+ {
+ "name": "RelaySmartEnableLevel",
+ "longName": "RelaySmartEnableLevel",
+ "fullName": "ttn.lorawan.v3.RelaySmartEnableLevel",
+ "description": "",
+ "values": [
+ {
+ "name": "RELAY_SMART_ENABLE_LEVEL_8",
+ "number": "0",
+ "description": ""
+ },
+ {
+ "name": "RELAY_SMART_ENABLE_LEVEL_16",
+ "number": "1",
+ "description": ""
+ },
+ {
+ "name": "RELAY_SMART_ENABLE_LEVEL_32",
+ "number": "2",
+ "description": ""
+ },
+ {
+ "name": "RELAY_SMART_ENABLE_LEVEL_64",
+ "number": "3",
+ "description": ""
+ }
+ ]
+ },
+ {
+ "name": "RelayWORChannel",
+ "longName": "RelayWORChannel",
+ "fullName": "ttn.lorawan.v3.RelayWORChannel",
+ "description": "",
+ "values": [
+ {
+ "name": "RELAY_WOR_CHANNEL_DEFAULT",
+ "number": "0",
+ "description": ""
+ },
+ {
+ "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": "RX_DELAY_1",
+ "number": "1",
+ "description": "1 second."
+ },
+ {
+ "name": "RX_DELAY_2",
+ "number": "2",
+ "description": "2 seconds."
+ },
+ {
+ "name": "RX_DELAY_3",
+ "number": "3",
+ "description": "3 seconds."
+ },
+ {
+ "name": "RX_DELAY_4",
+ "number": "4",
+ "description": "4 seconds."
+ },
+ {
+ "name": "RX_DELAY_5",
+ "number": "5",
+ "description": "5 seconds."
+ },
+ {
+ "name": "RX_DELAY_6",
+ "number": "6",
+ "description": "6 seconds."
+ },
+ {
+ "name": "RX_DELAY_7",
+ "number": "7",
+ "description": "7 seconds."
+ },
+ {
+ "name": "RX_DELAY_8",
+ "number": "8",
+ "description": "8 seconds."
},
{
"name": "RX_DELAY_9",
@@ -30661,6 +31367,138 @@
"isoneof": true,
"oneofdecl": "payload",
"defaultValue": ""
+ },
+ {
+ "name": "relay_conf_req",
+ "description": "",
+ "label": "",
+ "type": "RelayConfReq",
+ "longType": "MACCommand.RelayConfReq",
+ "fullType": "ttn.lorawan.v3.MACCommand.RelayConfReq",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
+ },
+ {
+ "name": "relay_conf_ans",
+ "description": "",
+ "label": "",
+ "type": "RelayConfAns",
+ "longType": "MACCommand.RelayConfAns",
+ "fullType": "ttn.lorawan.v3.MACCommand.RelayConfAns",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
+ },
+ {
+ "name": "relay_end_device_conf_req",
+ "description": "",
+ "label": "",
+ "type": "RelayEndDeviceConfReq",
+ "longType": "MACCommand.RelayEndDeviceConfReq",
+ "fullType": "ttn.lorawan.v3.MACCommand.RelayEndDeviceConfReq",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
+ },
+ {
+ "name": "relay_end_device_conf_ans",
+ "description": "",
+ "label": "",
+ "type": "RelayEndDeviceConfAns",
+ "longType": "MACCommand.RelayEndDeviceConfAns",
+ "fullType": "ttn.lorawan.v3.MACCommand.RelayEndDeviceConfAns",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
+ },
+ {
+ "name": "relay_update_uplink_list_req",
+ "description": "",
+ "label": "",
+ "type": "RelayUpdateUplinkListReq",
+ "longType": "MACCommand.RelayUpdateUplinkListReq",
+ "fullType": "ttn.lorawan.v3.MACCommand.RelayUpdateUplinkListReq",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
+ },
+ {
+ "name": "relay_update_uplink_list_ans",
+ "description": "",
+ "label": "",
+ "type": "RelayUpdateUplinkListAns",
+ "longType": "MACCommand.RelayUpdateUplinkListAns",
+ "fullType": "ttn.lorawan.v3.MACCommand.RelayUpdateUplinkListAns",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
+ },
+ {
+ "name": "relay_ctrl_uplink_list_req",
+ "description": "",
+ "label": "",
+ "type": "RelayCtrlUplinkListReq",
+ "longType": "MACCommand.RelayCtrlUplinkListReq",
+ "fullType": "ttn.lorawan.v3.MACCommand.RelayCtrlUplinkListReq",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
+ },
+ {
+ "name": "relay_ctrl_uplink_list_ans",
+ "description": "",
+ "label": "",
+ "type": "RelayCtrlUplinkListAns",
+ "longType": "MACCommand.RelayCtrlUplinkListAns",
+ "fullType": "ttn.lorawan.v3.MACCommand.RelayCtrlUplinkListAns",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
+ },
+ {
+ "name": "relay_configure_fwd_limit_req",
+ "description": "",
+ "label": "",
+ "type": "RelayConfigureFwdLimitReq",
+ "longType": "MACCommand.RelayConfigureFwdLimitReq",
+ "fullType": "ttn.lorawan.v3.MACCommand.RelayConfigureFwdLimitReq",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
+ },
+ {
+ "name": "relay_configure_fwd_limit_ans",
+ "description": "",
+ "label": "",
+ "type": "RelayConfigureFwdLimitAns",
+ "longType": "MACCommand.RelayConfigureFwdLimitAns",
+ "fullType": "ttn.lorawan.v3.MACCommand.RelayConfigureFwdLimitAns",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
+ },
+ {
+ "name": "relay_notify_new_end_device_req",
+ "description": "",
+ "label": "",
+ "type": "RelayNotifyNewEndDeviceReq",
+ "longType": "MACCommand.RelayNotifyNewEndDeviceReq",
+ "fullType": "ttn.lorawan.v3.MACCommand.RelayNotifyNewEndDeviceReq",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "payload",
+ "defaultValue": ""
}
]
},
@@ -31801,9 +32639,9 @@
]
},
{
- "name": "ResetConf",
- "longName": "MACCommand.ResetConf",
- "fullName": "ttn.lorawan.v3.MACCommand.ResetConf",
+ "name": "RelayConfAns",
+ "longName": "MACCommand.RelayConfAns",
+ "fullName": "ttn.lorawan.v3.MACCommand.RelayConfAns",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -31811,83 +32649,31 @@
"extensions": [],
"fields": [
{
- "name": "minor_version",
+ "name": "second_channel_frequency_ack",
"description": "",
"label": "",
- "type": "Minor",
- "longType": "Minor",
- "fullType": "ttn.lorawan.v3.Minor",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "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": [
+ "defaultValue": ""
+ },
{
- "name": "minor_version",
+ "name": "second_channel_ack_offset_ack",
"description": "",
"label": "",
- "type": "Minor",
- "longType": "Minor",
- "fullType": "ttn.lorawan.v3.Minor",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "enum.defined_only",
- "value": true
- },
- {
- "name": "enum.in",
- "value": [
- 1
- ]
- }
- ]
- }
- }
- ]
- },
- {
- "name": "RxParamSetupAns",
- "longName": "MACCommand.RxParamSetupAns",
- "fullName": "ttn.lorawan.v3.MACCommand.RxParamSetupAns",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ "defaultValue": ""
+ },
{
- "name": "rx2_data_rate_index_ack",
+ "name": "second_channel_data_rate_index_ack",
"description": "",
"label": "",
"type": "bool",
@@ -31899,7 +32685,7 @@
"defaultValue": ""
},
{
- "name": "rx1_data_rate_offset_ack",
+ "name": "second_channel_index_ack",
"description": "",
"label": "",
"type": "bool",
@@ -31911,7 +32697,19 @@
"defaultValue": ""
},
{
- "name": "rx2_frequency_ack",
+ "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",
@@ -31925,9 +32723,9 @@
]
},
{
- "name": "RxParamSetupReq",
- "longName": "MACCommand.RxParamSetupReq",
- "fullName": "ttn.lorawan.v3.MACCommand.RxParamSetupReq",
+ "name": "RelayConfReq",
+ "longName": "MACCommand.RelayConfReq",
+ "fullName": "ttn.lorawan.v3.MACCommand.RelayConfReq",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -31935,52 +32733,48 @@
"extensions": [],
"fields": [
{
- "name": "rx2_data_rate_index",
+ "name": "configuration",
"description": "",
"label": "",
- "type": "DataRateIndex",
- "longType": "DataRateIndex",
- "fullType": "ttn.lorawan.v3.DataRateIndex",
+ "type": "Configuration",
+ "longType": "MACCommand.RelayConfReq.Configuration",
+ "fullType": "ttn.lorawan.v3.MACCommand.RelayConfReq.Configuration",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "enum.defined_only",
- "value": true
- }
- ]
- }
- },
+ "defaultValue": ""
+ }
+ ]
+ },
+ {
+ "name": "Configuration",
+ "longName": "MACCommand.RelayConfReq.Configuration",
+ "fullName": "ttn.lorawan.v3.MACCommand.RelayConfReq.Configuration",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "rx1_data_rate_offset",
+ "name": "second_channel",
"description": "",
"label": "",
- "type": "DataRateOffset",
- "longType": "DataRateOffset",
- "fullType": "ttn.lorawan.v3.DataRateOffset",
+ "type": "RelaySecondChannel",
+ "longType": "RelaySecondChannel",
+ "fullType": "ttn.lorawan.v3.RelaySecondChannel",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "enum.defined_only",
- "value": true
- }
- ]
- }
+ "defaultValue": ""
},
{
- "name": "rx2_frequency",
- "description": "Rx2 frequency (Hz).",
+ "name": "default_channel_index",
+ "description": "",
"label": "",
- "type": "uint64",
- "longType": "uint64",
- "fullType": "uint64",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -31988,31 +32782,19 @@
"options": {
"validate.rules": [
{
- "name": "uint64.gte",
- "value": 100000
+ "name": "uint32.lte",
+ "value": 255
}
]
}
- }
- ]
- },
- {
- "name": "RxTimingSetupReq",
- "longName": "MACCommand.RxTimingSetupReq",
- "fullName": "ttn.lorawan.v3.MACCommand.RxTimingSetupReq",
- "description": "",
- "hasExtensions": false,
- "hasFields": true,
- "hasOneofs": false,
- "extensions": [],
- "fields": [
+ },
{
- "name": "delay",
+ "name": "cad_periodicity",
"description": "",
"label": "",
- "type": "RxDelay",
- "longType": "RxDelay",
- "fullType": "ttn.lorawan.v3.RxDelay",
+ "type": "RelayCADPeriodicity",
+ "longType": "RelayCADPeriodicity",
+ "fullType": "ttn.lorawan.v3.RelayCADPeriodicity",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -32029,9 +32811,20 @@
]
},
{
- "name": "TxParamSetupReq",
- "longName": "MACCommand.TxParamSetupReq",
- "fullName": "ttn.lorawan.v3.MACCommand.TxParamSetupReq",
+ "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,
@@ -32039,44 +32832,60 @@
"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": "reset_limit_counter",
+ "description": "",
"label": "",
- "type": "DeviceEIRP",
- "longType": "DeviceEIRP",
- "fullType": "ttn.lorawan.v3.DeviceEIRP",
+ "type": "RelayResetLimitCounter",
+ "longType": "RelayResetLimitCounter",
+ "fullType": "ttn.lorawan.v3.RelayResetLimitCounter",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "enum.defined_only",
- "value": true
- }
- ]
- }
+ "defaultValue": ""
},
{
- "name": "uplink_dwell_time",
+ "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": "downlink_dwell_time",
+ "name": "notify_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": "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": "",
@@ -32085,9 +32894,9 @@
]
},
{
- "name": "MACCommands",
- "longName": "MACCommands",
- "fullName": "ttn.lorawan.v3.MACCommands",
+ "name": "RelayCtrlUplinkListAns",
+ "longName": "MACCommand.RelayCtrlUplinkListAns",
+ "fullName": "ttn.lorawan.v3.MACCommand.RelayCtrlUplinkListAns",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -32095,12 +32904,24 @@
"extensions": [],
"fields": [
{
- "name": "commands",
+ "name": "rule_index_ack",
"description": "",
- "label": "repeated",
- "type": "MACCommand",
- "longType": "MACCommand",
- "fullType": "ttn.lorawan.v3.MACCommand",
+ "label": "",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "name": "w_f_cnt",
+ "description": "",
+ "label": "",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
@@ -32109,9 +32930,9 @@
]
},
{
- "name": "MACPayload",
- "longName": "MACPayload",
- "fullName": "ttn.lorawan.v3.MACPayload",
+ "name": "RelayCtrlUplinkListReq",
+ "longName": "MACCommand.RelayCtrlUplinkListReq",
+ "fullName": "ttn.lorawan.v3.MACCommand.RelayCtrlUplinkListReq",
"description": "",
"hasExtensions": false,
"hasFields": true,
@@ -32119,27 +32940,7 @@
"extensions": [],
"fields": [
{
- "name": "f_hdr",
- "description": "",
- "label": "",
- "type": "FHDR",
- "longType": "FHDR",
- "fullType": "ttn.lorawan.v3.FHDR",
- "ismap": false,
- "isoneof": false,
- "oneofdecl": "",
- "defaultValue": "",
- "options": {
- "validate.rules": [
- {
- "name": "message.required",
- "value": true
- }
- ]
- }
- },
- {
- "name": "f_port",
+ "name": "rule_index",
"description": "",
"label": "",
"type": "uint32",
@@ -32153,38 +32954,158 @@
"validate.rules": [
{
"name": "uint32.lte",
- "value": 255
+ "value": 15
}
]
}
},
{
- "name": "frm_payload",
+ "name": "action",
"description": "",
"label": "",
- "type": "bytes",
- "longType": "bytes",
- "fullType": "bytes",
+ "type": "RelayCtrlUplinkListAction",
+ "longType": "RelayCtrlUplinkListAction",
+ "fullType": "ttn.lorawan.v3.RelayCtrlUplinkListAction",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
- },
+ }
+ ]
+ },
+ {
+ "name": "RelayEndDeviceConfAns",
+ "longName": "MACCommand.RelayEndDeviceConfAns",
+ "fullName": "ttn.lorawan.v3.MACCommand.RelayEndDeviceConfAns",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
{
- "name": "decoded_payload",
+ "name": "second_channel_frequency_ack",
"description": "",
"label": "",
- "type": "Struct",
- "longType": "google.protobuf.Struct",
- "fullType": "google.protobuf.Struct",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
"ismap": false,
"isoneof": false,
"oneofdecl": "",
"defaultValue": ""
},
{
- "name": "full_f_cnt",
- "description": "Full 32-bit FCnt value. Used internally by Network Server.",
+ "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": "backoff_ack",
+ "description": "",
+ "label": "",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ }
+ ]
+ },
+ {
+ "name": "RelayEndDeviceConfReq",
+ "longName": "MACCommand.RelayEndDeviceConfReq",
+ "fullName": "ttn.lorawan.v3.MACCommand.RelayEndDeviceConfReq",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "configuration",
+ "description": "",
+ "label": "",
+ "type": "Configuration",
+ "longType": "MACCommand.RelayEndDeviceConfReq.Configuration",
+ "fullType": "ttn.lorawan.v3.MACCommand.RelayEndDeviceConfReq.Configuration",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ }
+ ]
+ },
+ {
+ "name": "Configuration",
+ "longName": "MACCommand.RelayEndDeviceConfReq.Configuration",
+ "fullName": "ttn.lorawan.v3.MACCommand.RelayEndDeviceConfReq.Configuration",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": true,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "always",
+ "description": "",
+ "label": "",
+ "type": "RelayEndDeviceAlwaysMode",
+ "longType": "RelayEndDeviceAlwaysMode",
+ "fullType": "ttn.lorawan.v3.RelayEndDeviceAlwaysMode",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "mode",
+ "defaultValue": ""
+ },
+ {
+ "name": "dynamic",
+ "description": "",
+ "label": "",
+ "type": "RelayEndDeviceDynamicMode",
+ "longType": "RelayEndDeviceDynamicMode",
+ "fullType": "ttn.lorawan.v3.RelayEndDeviceDynamicMode",
+ "ismap": false,
+ "isoneof": true,
+ "oneofdecl": "mode",
+ "defaultValue": ""
+ },
+ {
+ "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",
"longType": "uint32",
@@ -32192,14 +33113,149 @@
"ismap": false,
"isoneof": false,
"oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "uint32.lte",
+ "value": 63
+ }
+ ]
+ }
+ },
+ {
+ "name": "second_channel",
+ "description": "",
+ "label": "",
+ "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": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "string.max_len",
+ "value": 36
+ },
+ {
+ "name": "string.pattern",
+ "value": "^[a-z0-9](?:[-]?[a-z0-9]){2,}$"
+ }
+ ]
+ }
}
]
},
{
- "name": "MHDR",
- "longName": "MHDR",
- "fullName": "ttn.lorawan.v3.MHDR",
+ "name": "RelayNotifyNewEndDeviceReq",
+ "longName": "MACCommand.RelayNotifyNewEndDeviceReq",
+ "fullName": "ttn.lorawan.v3.MACCommand.RelayNotifyNewEndDeviceReq",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "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": "snr",
+ "description": "",
+ "label": "",
+ "type": "int32",
+ "longType": "int32",
+ "fullType": "int32",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "int32.lte",
+ "value": 11
+ },
+ {
+ "name": "int32.gte",
+ "value": -20
+ }
+ ]
+ }
+ },
+ {
+ "name": "rssi",
+ "description": "",
+ "label": "",
+ "type": "int32",
+ "longType": "int32",
+ "fullType": "int32",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "int32.lte",
+ "value": -15
+ },
+ {
+ "name": "int32.gte",
+ "value": -142
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "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,
@@ -32207,12 +33263,1030 @@
"extensions": [],
"fields": [
{
- "name": "m_type",
+ "name": "rule_index",
+ "description": "",
+ "label": "",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "uint32.lte",
+ "value": 15
+ }
+ ]
+ }
+ },
+ {
+ "name": "forward_limits",
+ "description": "",
+ "label": "",
+ "type": "RelayUplinkForwardLimits",
+ "longType": "RelayUplinkForwardLimits",
+ "fullType": "ttn.lorawan.v3.RelayUplinkForwardLimits",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "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": "w_f_cnt",
+ "description": "",
+ "label": "",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
+ "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": "bytes.len",
+ "value": 16
+ }
+ ]
+ }
+ },
+ {
+ "name": "device_id",
+ "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": "session_key_id",
+ "description": "",
+ "label": "",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ }
+ ]
+ },
+ {
+ "name": "ResetConf",
+ "longName": "MACCommand.ResetConf",
+ "fullName": "ttn.lorawan.v3.MACCommand.ResetConf",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "minor_version",
+ "description": "",
+ "label": "",
+ "type": "Minor",
+ "longType": "Minor",
+ "fullType": "ttn.lorawan.v3.Minor",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "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": "minor_version",
+ "description": "",
+ "label": "",
+ "type": "Minor",
+ "longType": "Minor",
+ "fullType": "ttn.lorawan.v3.Minor",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "enum.defined_only",
+ "value": true
+ },
+ {
+ "name": "enum.in",
+ "value": [
+ 1
+ ]
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "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",
+ "description": "",
+ "label": "",
+ "type": "bool",
+ "longType": "bool",
+ "fullType": "bool",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ },
+ {
+ "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",
+ "longType": "bool",
+ "fullType": "bool",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ }
+ ]
+ },
+ {
+ "name": "RxParamSetupReq",
+ "longName": "MACCommand.RxParamSetupReq",
+ "fullName": "ttn.lorawan.v3.MACCommand.RxParamSetupReq",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "rx2_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": "rx1_data_rate_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": "rx2_frequency",
+ "description": "Rx2 frequency (Hz).",
+ "label": "",
+ "type": "uint64",
+ "longType": "uint64",
+ "fullType": "uint64",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "uint64.gte",
+ "value": 100000
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "RxTimingSetupReq",
+ "longName": "MACCommand.RxTimingSetupReq",
+ "fullName": "ttn.lorawan.v3.MACCommand.RxTimingSetupReq",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "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": "TxParamSetupReq",
+ "longName": "MACCommand.TxParamSetupReq",
+ "fullName": "ttn.lorawan.v3.MACCommand.TxParamSetupReq",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "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 ]",
+ "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": "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",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "commands",
+ "description": "",
+ "label": "repeated",
+ "type": "MACCommand",
+ "longType": "MACCommand",
+ "fullType": "ttn.lorawan.v3.MACCommand",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ }
+ ]
+ },
+ {
+ "name": "MACPayload",
+ "longName": "MACPayload",
+ "fullName": "ttn.lorawan.v3.MACPayload",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "f_hdr",
+ "description": "",
+ "label": "",
+ "type": "FHDR",
+ "longType": "FHDR",
+ "fullType": "ttn.lorawan.v3.FHDR",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "message.required",
+ "value": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "f_port",
+ "description": "",
+ "label": "",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "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": "MHDR",
+ "longName": "MHDR",
+ "fullName": "ttn.lorawan.v3.MHDR",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "m_type",
+ "description": "",
+ "label": "",
+ "type": "MType",
+ "longType": "MType",
+ "fullType": "ttn.lorawan.v3.MType",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "enum.defined_only",
+ "value": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "major",
+ "description": "",
+ "label": "",
+ "type": "Major",
+ "longType": "Major",
+ "fullType": "ttn.lorawan.v3.Major",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "enum.defined_only",
+ "value": true
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "Message",
+ "longName": "Message",
+ "fullName": "ttn.lorawan.v3.Message",
+ "description": "Message represents a LoRaWAN message",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": true,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "m_hdr",
+ "description": "",
+ "label": "",
+ "type": "MHDR",
+ "longType": "MHDR",
+ "fullType": "ttn.lorawan.v3.MHDR",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "message.required",
+ "value": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "mic",
+ "description": "",
+ "label": "",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "bytes.min_len",
+ "value": 0
+ },
+ {
+ "name": "bytes.max_len",
+ "value": 4
+ }
+ ]
+ }
+ },
+ {
+ "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": "",
+ "label": "",
+ "type": "PingSlotPeriod",
+ "longType": "PingSlotPeriod",
+ "fullType": "ttn.lorawan.v3.PingSlotPeriod",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "enum.defined_only",
+ "value": true
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "RejoinRequestPayload",
+ "longName": "RejoinRequestPayload",
+ "fullName": "ttn.lorawan.v3.RejoinRequestPayload",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "rejoin_type",
+ "description": "",
+ "label": "",
+ "type": "RejoinRequestType",
+ "longType": "RejoinRequestType",
+ "fullType": "ttn.lorawan.v3.RejoinRequestType",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "enum.defined_only",
+ "value": true
+ }
+ ]
+ }
+ },
+ {
+ "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": "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": "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": "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": "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,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "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": "RelaySmartEnableLevel",
+ "longType": "RelaySmartEnableLevel",
+ "fullType": "ttn.lorawan.v3.RelaySmartEnableLevel",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "enum.defined_only",
+ "value": true
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "RelayForwardDownlinkReq",
+ "longName": "RelayForwardDownlinkReq",
+ "fullName": "ttn.lorawan.v3.RelayForwardDownlinkReq",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "raw_payload",
+ "description": "",
+ "label": "",
+ "type": "bytes",
+ "longType": "bytes",
+ "fullType": "bytes",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": ""
+ }
+ ]
+ },
+ {
+ "name": "RelayForwardLimits",
+ "longName": "RelayForwardLimits",
+ "fullName": "ttn.lorawan.v3.RelayForwardLimits",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "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": "RelayLimitBucketSize",
+ "longType": "RelayLimitBucketSize",
+ "fullType": "ttn.lorawan.v3.RelayLimitBucketSize",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "enum.defined_only",
+ "value": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "reload_rate",
+ "description": "The number of tokens which are replenished in the bucket every hour.",
+ "label": "",
+ "type": "uint32",
+ "longType": "uint32",
+ "fullType": "uint32",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "uint32.lte",
+ "value": 126
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "RelayForwardUplinkReq",
+ "longName": "RelayForwardUplinkReq",
+ "fullName": "ttn.lorawan.v3.RelayForwardUplinkReq",
+ "description": "",
+ "hasExtensions": false,
+ "hasFields": true,
+ "hasOneofs": false,
+ "extensions": [],
+ "fields": [
+ {
+ "name": "data_rate",
+ "description": "",
+ "label": "",
+ "type": "DataRate",
+ "longType": "DataRate",
+ "fullType": "ttn.lorawan.v3.DataRate",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "message.required",
+ "value": true
+ }
+ ]
+ }
+ },
+ {
+ "name": "snr",
+ "description": "",
+ "label": "",
+ "type": "int32",
+ "longType": "int32",
+ "fullType": "int32",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "int32.lte",
+ "value": 11
+ },
+ {
+ "name": "int32.gte",
+ "value": -20
+ }
+ ]
+ }
+ },
+ {
+ "name": "rssi",
+ "description": "",
+ "label": "",
+ "type": "int32",
+ "longType": "int32",
+ "fullType": "int32",
+ "ismap": false,
+ "isoneof": false,
+ "oneofdecl": "",
+ "defaultValue": "",
+ "options": {
+ "validate.rules": [
+ {
+ "name": "int32.lte",
+ "value": -15
+ },
+ {
+ "name": "int32.gte",
+ "value": -142
+ }
+ ]
+ }
+ },
+ {
+ "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": "",
@@ -32227,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": "",
@@ -32240,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": "",
@@ -32272,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": "",
@@ -32292,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": "",
@@ -32376,8 +34398,8 @@
"options": {
"validate.rules": [
{
- "name": "enum.defined_only",
- "value": true
+ "name": "uint64.gte",
+ "value": 100000
}
]
}
@@ -32385,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,
@@ -32395,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": "",
@@ -32415,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": "",
@@ -32428,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": "",
@@ -32448,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",
@@ -32464,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",
@@ -35527,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",
@@ -35569,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 1db9aea484..e6c63fa752 100644
--- a/sdk/js/package.json
+++ b/sdk/js/package.json
@@ -1,6 +1,6 @@
{
"name": "ttn-lw",
- "version": "3.28.0",
+ "version": "3.28.2",
"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..e5765f20f3 100644
--- a/sdk/js/src/api/stream/shared.js
+++ b/sdk/js/src/api/stream/shared.js
@@ -19,8 +19,46 @@ export const notify = (listener, ...args) => {
}
export const EVENTS = Object.freeze({
- START: 'start',
- CHUNK: 'chunk',
+ MESSAGE: 'message',
ERROR: 'error',
CLOSE: 'close',
})
+
+export const MESSAGE_TYPES = Object.freeze({
+ SUBSCRIBE: 'subscribe',
+ UNSUBSCRIBE: 'unsubscribe',
+ PUBLISH: 'publish',
+ ERROR: 'error',
+})
+
+export const INITIAL_LISTENERS = Object.freeze(
+ Object.values(EVENTS).reduce((acc, curr) => ({ ...acc, [curr]: {} }), {}),
+)
+
+export const newQueuedListeners = listeners => {
+ const queue = []
+ let open = false
+ const queuedListeners = Object.values(EVENTS).reduce(
+ (acc, curr) => ({
+ ...acc,
+ [curr]: (...args) => {
+ if (open) {
+ notify(listeners[curr], ...args)
+ } else {
+ queue.push([curr, args])
+ }
+ },
+ }),
+ {},
+ )
+ return [
+ () => {
+ open = true
+ for (const [event, args] of queue) {
+ notify(listeners[event], ...args)
+ }
+ queue.splice(0, queue.length)
+ },
+ queuedListeners,
+ ]
+}
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..bca8a83b18
--- /dev/null
+++ b/sdk/js/src/api/stream/subscribeToWebSocketStream.js
@@ -0,0 +1,319 @@
+// 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 traverse from 'traverse'
+
+import Token from '../../util/token'
+
+import { notify, newQueuedListeners, EVENTS, MESSAGE_TYPES, INITIAL_LISTENERS } from './shared'
+
+export class ConnectionError extends Error {
+ constructor(message) {
+ super(message)
+ this.name = 'ConnectionError'
+ }
+}
+
+export class ConnectionClosedError extends ConnectionError {
+ constructor(message, code) {
+ super(message)
+ this.name = 'ConnectionClosedError'
+ this.code = code
+ }
+}
+
+export class ConnectionTimeoutError extends ConnectionError {
+ constructor(message) {
+ super(message)
+ this.name = 'ConnectionTimeoutError'
+ }
+}
+
+export class ProtocolError extends Error {
+ constructor(error) {
+ super(error.message)
+ this.name = 'ProtocolError'
+ this.error = error
+ }
+}
+
+const newSubscription = (
+ unsubscribe,
+ originalListeners,
+ resolveSubscribe,
+ rejectSubscribe,
+ resolveClose,
+) => {
+ let closeRequested = false
+ const [open, listeners] = newQueuedListeners(originalListeners)
+ const externalSubscription = {
+ open,
+ close: () => {
+ closeRequested = true
+ return unsubscribe()
+ },
+ }
+ return {
+ onError: err => {
+ notify(listeners[EVENTS.ERROR], err)
+
+ rejectSubscribe(err)
+ },
+ onClose: closeEvent => {
+ notify(listeners[EVENTS.CLOSE], closeRequested)
+
+ rejectSubscribe(new ConnectionClosedError('WebSocket connection closed', closeEvent.code))
+ resolveClose()
+ },
+ onMessage: dataParsed => {
+ if (dataParsed.type === MESSAGE_TYPES.SUBSCRIBE) {
+ resolveSubscribe(externalSubscription)
+ }
+
+ if (dataParsed.type === MESSAGE_TYPES.ERROR) {
+ const err = new ProtocolError(dataParsed.error)
+ notify(listeners[EVENTS.ERROR], err)
+
+ rejectSubscribe(err)
+ }
+
+ if (dataParsed.type === MESSAGE_TYPES.PUBLISH) {
+ notify(listeners[EVENTS.MESSAGE], dataParsed.event)
+ }
+
+ if (dataParsed.type === MESSAGE_TYPES.UNSUBSCRIBE) {
+ notify(listeners[EVENTS.CLOSE], closeRequested)
+
+ resolveClose()
+ }
+ },
+ }
+}
+
+const newInstance = (wsInstance, onClose) => {
+ const subscriptions = {}
+
+ // Broadcast connection errors to all subscriptions.
+ wsInstance.addEventListener('error', () => {
+ const err = new ConnectionError('WebSocket connection error')
+ for (const subscription of Object.values(subscriptions)) {
+ subscription.onError(err)
+ }
+ })
+
+ // Broadcast connection closure to all subscriptions.
+ wsInstance.addEventListener('close', closeEvent => {
+ // TODO: Handle close event codes.
+ // https://github.com/TheThingsNetwork/lorawan-stack/issues/6752
+ for (const subscription of Object.values(subscriptions)) {
+ subscription.onClose(closeEvent)
+ }
+ onClose()
+ })
+
+ // Broadcast messages to the correct subscription.
+ wsInstance.addEventListener('message', ({ data }) => {
+ const dataParsed = JSON.parse(data)
+ const sid = dataParsed.id
+ const subscription = traverse(subscriptions).get([sid]) || null
+
+ if (!subscription) {
+ return
+ }
+
+ subscription.onMessage(dataParsed)
+
+ if (dataParsed.type === MESSAGE_TYPES.UNSUBSCRIBE) {
+ delete subscriptions[sid]
+ }
+ })
+
+ return {
+ subscribe: (sid, subscribePayload, unsubscribePayload, listeners, resolve, reject) => {
+ if (sid in subscriptions) {
+ throw new Error(`Subscription with ID ${sid} already exists`)
+ }
+
+ // The `unsubscribed` promise is used in order to guarantee that calls to the `close` method
+ // of the subscription finish _after_ the closure events have been emitted. Callers can expect
+ // that after `close` resolves, no further events will be emitted.
+ let resolveClose = null
+ const unsubscribed = new Promise(resolve => {
+ resolveClose = resolve
+ })
+ let unsubscribeCalled = false
+ const unsubscribe = () => {
+ if (!unsubscribeCalled) {
+ unsubscribeCalled = true
+
+ if (wsInstance.state === WebSocket.open) {
+ wsInstance.send(unsubscribePayload)
+ }
+ }
+ return unsubscribed
+ }
+
+ const subscription = newSubscription(unsubscribe, listeners, resolve, reject, resolveClose)
+ subscriptions[sid] = subscription
+
+ if (wsInstance.readyState === WebSocket.OPEN) {
+ // If the WebSocket connection is already open, only add the subscription.
+ wsInstance.send(subscribePayload)
+ } else if (wsInstance.readyState === WebSocket.CONNECTING) {
+ // Otherwise wait for the connection to open and then add the subscription.
+ const onOpen = () => {
+ wsInstance.send(subscribePayload)
+ wsInstance.removeEventListener('open', onOpen)
+ }
+ wsInstance.addEventListener('open', onOpen)
+ } else {
+ delete subscriptions[sid]
+ throw new Error('WebSocket connection is closed')
+ }
+ },
+ }
+}
+
+const newStore = () => {
+ const connections = {}
+ return {
+ getInstance: url => traverse(connections).get([url]),
+ setInstance: (url, wsInstance) =>
+ traverse(connections).set(
+ [url],
+ newInstance(wsInstance, () => delete connections[url]),
+ ),
+ }
+}
+
+const state = newStore()
+
+/**
+ * Opens a new stream.
+ *
+ * Implementation guarantees:
+ * - No events will be sent to the listeners before the `open` function is called.
+ * - No events will be sent to the listeners after the `close` function is called.
+ * - The `close` function will resolve after all events have been sent to the listeners.
+ * - The `close` function does not throw any errors.
+ * - The `close` function can be called multiple times.
+ * - The `open` function can be called multiple times.
+ * - The `open` function does not throw any errors, as long as the event listeners do not throw.
+ * - No `message` event will follow an `error` event.
+ * - No `message` event will follow a `close` event.
+ * - No `error` event will follow a `close` event.
+ * - No `error` event will follow another `error` event.
+ * - No `close` event will follow another `close` event.
+ *
+ * @async
+ * @param {object} payload - - The body of the initial request.
+ * @param {string} baseUrl - The stream baseUrl.
+ * @param {object} listeners - The listeners object.
+ * @param {string} endpoint - The stream endpoint.
+ * @param {number} timeout - The connection timeout for the stream.
+ *
+ * @example
+ * (async () => {
+ * const stream = await stream(
+ * { identifiers: [{ application_ids: { application_id: 'my-app' }}]},
+ * 'http://localhost:8080',
+ * {
+ * message: ({ data }) => console.log('received data', JSON.parse(data)),
+ * error: error => console.log(error),
+ * close: wasClientRequest => console.log(wasClientRequest ? 'conn closed by client' : 'conn closed by server'),
+ * },
+ * )
+ *
+ * // Start the stream in order to start dispatching events.
+ * stream.open()
+ *
+ * // Close the stream after 20 s.
+ * setTimeout(() => stream.close(), 20000)
+ * })()
+ *
+ * @returns {object} The stream subscription object the `open` function to start sending events to the listeners and
+ * the `close` function to close the stream.
+ */
+export default async (
+ payload,
+ baseUrl,
+ listeners,
+ endpoint = '/console/internal/events/',
+ timeout = 10000,
+) => {
+ for (const eventName of Object.keys(listeners)) {
+ if (!Object.values(EVENTS).includes(eventName)) {
+ throw new Error(
+ `${eventName} event is not supported. Should be one of: message, error or close`,
+ )
+ }
+ }
+ const filledListeners = { ...INITIAL_LISTENERS, ...listeners }
+
+ const subscriptionId = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER)
+ const subscriptionPayload = JSON.stringify({
+ type: MESSAGE_TYPES.SUBSCRIBE,
+ id: subscriptionId,
+ ...payload,
+ })
+ const unsubscribePayload = JSON.stringify({
+ type: MESSAGE_TYPES.UNSUBSCRIBE,
+ id: subscriptionId,
+ })
+ const url = baseUrl + endpoint
+ const token = new Token().get()
+ const tokenParsed = typeof token === 'function' ? `${(await token()).access_token}` : token
+ const baseUrlParsed = baseUrl.replace('http', 'ws')
+
+ const subscribe = new Promise((resolve, reject) => {
+ let instance = state.getInstance(url)
+ // Open up the WebSocket connection if it doesn't exist.
+ if (!instance) {
+ instance = state.setInstance(
+ url,
+ new WebSocket(`${baseUrlParsed}${endpoint}`, [
+ 'ttn.lorawan.v3.console.internal.events.v1',
+ `ttn.lorawan.v3.header.authorization.bearer.${tokenParsed}`,
+ ]),
+ )
+ }
+
+ // Add the new subscription to the subscriptions object.
+ // Also add the resolver functions to the subscription object to be able
+ // to resolve the promise after the subscription confirmation message.
+ instance.subscribe(
+ subscriptionId,
+ subscriptionPayload,
+ unsubscribePayload,
+ filledListeners,
+ resolve,
+ reject,
+ )
+ })
+
+ try {
+ return await Promise.race([
+ subscribe,
+ new Promise((_resolve, reject) =>
+ setTimeout(() => reject(new ConnectionTimeoutError('Timed out')), timeout),
+ ),
+ ])
+ } catch (err) {
+ subscribe.then(
+ subscription => subscription.close(),
+ () => {},
+ )
+ throw err
+ }
+}
diff --git a/sdk/js/src/api/stream/subscribeToWebSocketStreams.js b/sdk/js/src/api/stream/subscribeToWebSocketStreams.js
new file mode 100644
index 0000000000..87a73dd53f
--- /dev/null
+++ b/sdk/js/src/api/stream/subscribeToWebSocketStreams.js
@@ -0,0 +1,105 @@
+// 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 { EVENTS, INITIAL_LISTENERS, notify } from './shared'
+import subscribeToWebSocketStream from './subscribeToWebSocketStream'
+
+/*
+ * Subscribe to an event stream with multiple base URLs.
+ * Semantically equivalent to subscribeToWebSocketStream, but guarantees uniform stream closure and unaffected
+ * event emission in case of failure of one or more streams.
+ */
+export default async (
+ payload,
+ baseUrls,
+ listeners,
+ endpoint = '/console/internal/events/',
+ timeout = 10000,
+) => {
+ if (!(baseUrls instanceof Array) || baseUrls.length === 0) {
+ throw new Error('Cannot subscribe to events without base URLs')
+ }
+ if (baseUrls.length === 1) {
+ return subscribeToWebSocketStream(payload, baseUrls[0], listeners, endpoint, timeout)
+ }
+
+ for (const eventName of Object.keys(listeners)) {
+ if (!Object.values(EVENTS).includes(eventName)) {
+ throw new Error(
+ `${eventName} event is not supported. Should be one of: message, error or close`,
+ )
+ }
+ }
+ const filledListeners = { ...INITIAL_LISTENERS, ...listeners }
+
+ // Interweaving multiple streams has the side effect of making the standard event listener
+ // state machine look erratic externally - only certain streams may fail, while others may continue
+ // to work. Upper layers which use the stream must not be exposed to this detail - once one
+ // stream fails, we need to ensure that all streams are closed and no stray events are emitted.
+ //
+ // The standard state machine guarantees that once an error or close event is emitted, no further
+ // message events will be emitted. It is also guaranteed that once an error event is emitted, a close
+ // event will follow.
+ let [closeAll, hadError, hadClose] = [() => {}, false, false]
+ const uniformListeners = {
+ [EVENTS.MESSAGE]: (...params) => {
+ if (hadClose || hadError) {
+ return
+ }
+ notify(filledListeners[EVENTS.MESSAGE], ...params)
+ },
+ [EVENTS.ERROR]: (...params) => {
+ if (hadClose || hadError) {
+ return
+ }
+ hadError = true
+ notify(filledListeners[EVENTS.ERROR], ...params)
+ },
+ [EVENTS.CLOSE]: (...params) => {
+ if (hadClose) {
+ return
+ }
+ hadClose = true
+ notify(filledListeners[EVENTS.CLOSE], ...params)
+ closeAll()
+ },
+ }
+
+ const pendingStreams = baseUrls.map(baseUrl =>
+ subscribeToWebSocketStream(payload, baseUrl, uniformListeners, endpoint, timeout),
+ )
+ try {
+ const streams = await Promise.all(pendingStreams)
+ closeAll = () => Promise.all(streams.map(stream => stream.close()))
+ return {
+ open: () => streams.forEach(stream => stream.open()),
+ close: closeAll,
+ }
+ } catch (error) {
+ // Ensure that if only some streams fail, the successful ones are closed.
+ await Promise.all(
+ pendingStreams.map(async pendingStream => {
+ try {
+ const stream = await pendingStream
+ await stream.close()
+ } catch {
+ // Only the pending stream promise may throw, as `close` does not throw.
+ // Although multiple streams may fail, we will rethrow only the first error
+ // and ignore the rest, as they are not really actionable.
+ }
+ }),
+ )
+ throw error
+ }
+}
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..7ad00cfc22 100644
--- a/sdk/js/src/service/applications.js
+++ b/sdk/js/src/service/applications.js
@@ -15,7 +15,7 @@
import autoBind from 'auto-bind'
import Marshaler from '../util/marshaler'
-import combineStreams from '../util/combine-streams'
+import subscribeToWebSocketStreams from '../api/stream/subscribeToWebSocketStreams'
import { STACK_COMPONENTS_MAP } from '../util/constants'
import Devices from './devices'
@@ -26,8 +26,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
@@ -217,7 +216,7 @@ class Applications {
// Events Stream
- async openStream(identifiers, names, tail, after) {
+ async openStream(identifiers, names, tail, after, listeners) {
const payload = {
identifiers: identifiers.map(id => ({
application_ids: { application_id: id },
@@ -230,20 +229,13 @@ 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)),
+ )
// Combine all stream sources to one subscription generator.
- return combineStreams(streams)
+ return subscribeToWebSocketStreams(payload, [...baseUrls], listeners)
}
}
diff --git a/sdk/js/src/service/devices/index.js b/sdk/js/src/service/devices/index.js
index f075d58849..a3a975a1d2 100644
--- a/sdk/js/src/service/devices/index.js
+++ b/sdk/js/src/service/devices/index.js
@@ -19,7 +19,7 @@ import traverse from 'traverse'
import { notify, EVENTS } from '../../api/stream/shared'
import Marshaler from '../../util/marshaler'
-import combineStreams from '../../util/combine-streams'
+import subscribeToWebSocketStreams from '../../api/stream/subscribeToWebSocketStreams'
import deviceEntityMap from '../../../generated/device-entity-map.json'
import DownlinkQueue from '../downlink-queue'
import { STACK_COMPONENTS_MAP } from '../../util/constants'
@@ -29,8 +29,7 @@ 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 +644,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 +663,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`,
)
}
@@ -680,7 +679,7 @@ class Devices {
// Events Stream
- async openStream(identifiers, names, tail, after) {
+ async openStream(identifiers, names, tail, after, listeners) {
const payload = {
identifiers: identifiers.map(ids => ({
device_ids: ids,
@@ -693,20 +692,13 @@ 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)),
+ )
// Combine all stream sources to one subscription generator.
- return combineStreams(streams)
+ return subscribeToWebSocketStreams(payload, [...baseUrls], listeners)
}
async simulateUplink(applicationId, deviceId, uplink) {
diff --git a/sdk/js/src/service/gateways.js b/sdk/js/src/service/gateways.js
index 2a566e5c58..2f16e0fd03 100644
--- a/sdk/js/src/service/gateways.js
+++ b/sdk/js/src/service/gateways.js
@@ -15,7 +15,7 @@
import autoBind from 'auto-bind'
import Marshaler from '../util/marshaler'
-import combineStreams from '../util/combine-streams'
+import subscribeToWebSocketStreams from '../api/stream/subscribeToWebSocketStreams'
import { STACK_COMPONENTS_MAP } from '../util/constants'
import ApiKeys from './api-keys'
@@ -221,6 +221,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 },
@@ -231,7 +239,7 @@ class Gateways {
// Events Stream
- async openStream(identifiers, names, tail, after) {
+ async openStream(identifiers, names, tail, after, listeners) {
const payload = {
identifiers: identifiers.map(id => ({
gateway_ids: { gateway_id: id },
@@ -249,12 +257,11 @@ 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)),
)
-
// Combine all stream sources to one subscription generator.
- return combineStreams(streams)
+ return subscribeToWebSocketStreams(payload, [...baseUrls], listeners)
}
// Gateway Configuration Server.
@@ -265,7 +272,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..e63022185e 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: {
@@ -153,7 +156,7 @@ class Organizations {
// Events stream.
- async openStream(identifiers, names, tail, after) {
+ async openStream(identifiers, names, tail, after, listeners) {
const payload = {
identifiers: identifiers.map(id => ({
organization_ids: { organization_id: id },
@@ -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, listeners)
}
}
diff --git a/sdk/js/src/util/combine-streams.js b/sdk/js/src/util/combine-streams.js
deleted file mode 100644
index 92ab832595..0000000000
--- a/sdk/js/src/util/combine-streams.js
+++ /dev/null
@@ -1,50 +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.
-
-/**
- * Combines multiple streams into a single subscription provider.
- *
- * @param {Array} streams - An array of (async) stream functions.
- * @returns {object} The stream subscription object with the `on` function for
- * attaching listeners and the `close` function to close the stream.
- */
-const combinedStream = async streams => {
- if (!(streams instanceof Array) || streams.length === 0) {
- throw new Error('Cannot combine streams with invalid stream array.')
- } else if (streams.length === 1) {
- return streams[0]
- }
-
- 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)
- }
- },
- close: () => {
- for (const subscriber of subscribers) {
- subscriber.close()
- }
- },
- }
-}
-
-export default combinedStream
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 b06d50ec53..b615441896 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
@@ -42,7 +42,7 @@ require (
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.2.0 // indirect
- github.com/aws/aws-sdk-go v1.45.19 // 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,56 @@ 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/mileusna/useragent v1.3.4 // 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 +201,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 +209,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 +232,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.14.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.17.0 // indirect
- golang.org/x/oauth2 v0.12.0 // indirect
- golang.org/x/sync v0.3.0 // indirect
- golang.org/x/sys v0.13.0 // indirect
- golang.org/x/term v0.13.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 +259,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 f621452ef8..187d51fe46 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=
@@ -96,10 +97,9 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF
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,12 @@ 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/mileusna/useragent v1.3.4 h1:MiuRRuvGjEie1+yZHO88UBYg8YBC/ddF6T7F56i3PCk=
+github.com/mileusna/useragent v1.3.4/go.mod h1:3d8TOmwL/5I8pJjyVDteHtgDGcefrFUX4ccGOMKNYYc=
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 +584,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 +592,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 +621,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 +634,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 +660,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 +673,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 +708,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 +728,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 +754,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 +778,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 +814,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 +854,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 +876,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.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
-golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
+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 +890,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 +921,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 +964,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.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
-golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
+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 +982,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 +998,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 +1059,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.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
-golang.org/x/sys v0.13.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.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
-golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
+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 +1084,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 +1147,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 +1175,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 +1211,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 +1225,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 +1245,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 +1288,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 +1310,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/yarn.lock b/yarn.lock
index 4d0fcf83e6..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"
@@ -80,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"
@@ -246,13 +226,6 @@
"@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==
- dependencies:
- "@babel/types" "^7.16.7"
-
"@babel/helper-annotate-as-pure@^7.18.6":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz#eaa49f6f80d5a33f9a5dd2276e6d6e451be0a6bb"
@@ -274,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==
@@ -342,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"
@@ -368,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"
@@ -443,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"
@@ -499,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"
@@ -506,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"
@@ -572,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"
@@ -612,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"
@@ -744,21 +678,21 @@
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"
@@ -784,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"
@@ -961,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":
@@ -987,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"
@@ -1002,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":
@@ -1034,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"
@@ -1049,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"
@@ -1064,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"
@@ -1080,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"
@@ -1104,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"
@@ -1119,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"
@@ -1134,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"
@@ -1184,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"
@@ -1219,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"
@@ -1251,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"
@@ -1282,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"
@@ -1301,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"
@@ -1371,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"
@@ -1410,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"
@@ -1441,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"
@@ -1535,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"
@@ -1616,41 +1532,7 @@
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.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.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.15", "@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==
@@ -1659,15 +1541,6 @@
"@babel/helper-validator-identifier" "^7.22.20"
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"
-
"@base2/pretty-print-object@1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@base2/pretty-print-object/-/pretty-print-object-1.0.1.tgz#371ba8be66d556812dc7fb169ebc3c08378f69d4"
@@ -2115,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"
@@ -2171,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==
@@ -2180,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"
@@ -2204,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"
@@ -2213,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":
@@ -2652,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"
@@ -2693,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"
@@ -2728,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"
@@ -4102,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:
@@ -4141,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==
@@ -4151,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:
@@ -4291,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"
@@ -4407,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"
@@ -4585,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==
@@ -4595,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"
@@ -4704,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"
@@ -5145,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==
@@ -5179,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"
@@ -5429,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==
@@ -5822,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"
@@ -5944,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==
@@ -6165,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"
@@ -6181,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==
@@ -6243,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==
- 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==
+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.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"
@@ -6864,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==
@@ -6989,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"
@@ -7359,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"
@@ -7838,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"
@@ -8546,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"
@@ -8669,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==
@@ -9213,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==
@@ -9807,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"
@@ -9841,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==
+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.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==
- 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"
@@ -11092,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"
@@ -11147,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"
@@ -11171,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"
@@ -11270,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"
@@ -11339,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==
@@ -12368,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"
@@ -12396,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"
@@ -12551,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"
@@ -12620,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"
@@ -12752,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"