From 3f1a47e1e2e4064e0f82165f43c4fab943c653d6 Mon Sep 17 00:00:00 2001 From: Orne Brocaar Date: Tue, 25 Jun 2024 11:37:57 +0100 Subject: [PATCH] Integrate Gateway Mesh feature. This adds a Gateway Mesh section to the web-interface (+ API endpoints) to see the status op each Relay Gateway within the Gateway Mesh. The Gateway Mesh (https://github.com/chirpstack/chirpstack-gateway-mesh) is an experimental feature to extend LoRaWAN coverage throug Relay Gateways. --- Cargo.lock | 10 +- api/go/api/application.pb.go | 21 +- api/go/api/device.pb.go | 19 +- api/go/api/device_profile.pb.go | 21 +- api/go/api/device_profile_template.pb.go | 21 +- api/go/api/gateway.pb.go | 1074 +++++++++++++++-- api/go/api/gateway_grpc.pb.go | 156 +++ api/go/api/internal.pb.go | 19 +- api/go/api/multicast_group.pb.go | 21 +- api/go/api/relay.pb.go | 21 +- api/go/api/tenant.pb.go | 20 +- api/go/api/user.pb.go | 21 +- api/go/common/common.pb.go | 21 +- api/go/gw/gw.pb.go | 374 ++++-- api/go/integration/integration.pb.go | 12 +- api/go/stream/api_request.pb.go | 23 +- api/go/stream/backend_interfaces.pb.go | 25 +- api/go/stream/frame.pb.go | 23 +- api/go/stream/meta.pb.go | 21 +- api/grpc-web/package.json | 2 +- api/java/build.gradle.kts | 2 +- api/js/package.json | 2 +- api/kotlin/build.gradle.kts | 2 +- api/proto/api/gateway.proto | 145 ++- api/proto/gw/gw.proto | 26 + api/python/src/setup.py | 2 +- api/rust/Cargo.toml | 2 +- .../proto/chirpstack/api/application.proto | 2 + api/rust/proto/chirpstack/api/device.proto | 2 + .../proto/chirpstack/api/device_profile.proto | 2 + .../api/device_profile_template.proto | 2 + api/rust/proto/chirpstack/api/gateway.proto | 147 ++- api/rust/proto/chirpstack/api/internal.proto | 2 + .../chirpstack/api/multicast_group.proto | 2 + api/rust/proto/chirpstack/api/relay.proto | 2 + api/rust/proto/chirpstack/api/tenant.proto | 2 + api/rust/proto/chirpstack/api/user.proto | 2 + api/rust/proto/chirpstack/common/common.proto | 2 + api/rust/proto/chirpstack/gw/gw.proto | 28 + .../chirpstack/integration/integration.proto | 2 + .../proto/chirpstack/stream/api_request.proto | 2 + .../stream/backend_interfaces.proto | 2 + api/rust/proto/chirpstack/stream/frame.proto | 2 + api/rust/proto/chirpstack/stream/meta.proto | 2 + backend/Cargo.toml | 2 +- chirpstack-integration/Cargo.toml | 2 +- chirpstack/Cargo.toml | 2 +- .../down.sql | 1 + .../up.sql | 13 + chirpstack/src/api/gateway.rs | 292 ++++- chirpstack/src/gateway/backend/mqtt.rs | 12 + chirpstack/src/storage/gateway.rs | 270 ++++- chirpstack/src/storage/schema.rs | 18 + chirpstack/src/uplink/mesh.rs | 119 ++ chirpstack/src/uplink/mod.rs | 1 + lrwn-filters/Cargo.toml | 2 +- lrwn/Cargo.toml | 2 +- ui/package.json | 2 +- ui/src/components/Menu.tsx | 11 + ui/src/components/RelayIdInput.tsx | 202 ++++ ui/src/stores/GatewayStore.ts | 60 + .../views/gateways/mesh/EditRelayGateway.tsx | 34 + .../views/gateways/mesh/ListRelayGateways.tsx | 119 ++ .../views/gateways/mesh/RelayGatewayForm.tsx | 76 ++ .../gateways/mesh/RelayGatewayLayout.tsx | 108 ++ ui/src/views/tenants/TenantLoader.tsx | 4 + 66 files changed, 3275 insertions(+), 388 deletions(-) create mode 100644 chirpstack/migrations/2024-06-13-122655_add_relay_gateway/down.sql create mode 100644 chirpstack/migrations/2024-06-13-122655_add_relay_gateway/up.sql create mode 100644 chirpstack/src/uplink/mesh.rs create mode 100644 ui/src/components/RelayIdInput.tsx create mode 100644 ui/src/views/gateways/mesh/EditRelayGateway.tsx create mode 100644 ui/src/views/gateways/mesh/ListRelayGateways.tsx create mode 100644 ui/src/views/gateways/mesh/RelayGatewayForm.tsx create mode 100644 ui/src/views/gateways/mesh/RelayGatewayLayout.tsx diff --git a/Cargo.lock b/Cargo.lock index 46882418..6f5ec7b5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -570,7 +570,7 @@ dependencies = [ [[package]] name = "backend" -version = "4.8.1" +version = "4.9.0-test.1" dependencies = [ "aes-kw", "anyhow", @@ -800,7 +800,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chirpstack" -version = "4.8.1" +version = "4.9.0-test.1" dependencies = [ "aes", "anyhow", @@ -891,7 +891,7 @@ dependencies = [ [[package]] name = "chirpstack_api" -version = "4.8.1" +version = "4.9.0-test.1" dependencies = [ "diesel", "hex", @@ -2582,7 +2582,7 @@ dependencies = [ [[package]] name = "lrwn" -version = "4.8.1" +version = "4.9.0-test.1" dependencies = [ "aes", "anyhow", @@ -2596,7 +2596,7 @@ dependencies = [ [[package]] name = "lrwn_filters" -version = "4.8.1" +version = "4.9.0-test.1" dependencies = [ "hex", "lrwn", diff --git a/api/go/api/application.pb.go b/api/go/api/application.pb.go index 2feed6fc..3ed25fa5 100644 --- a/api/go/api/application.pb.go +++ b/api/go/api/application.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.34.1 // protoc v4.24.4 // source: api/application.proto @@ -5622,14 +5622,17 @@ var file_api_application_proto_rawDesc = []byte{ 0x73, 0x2f, 0x7b, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x6d, 0x71, 0x74, 0x74, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, - 0x42, 0x68, 0x0a, 0x11, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, - 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x10, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, - 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2f, - 0x67, 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x61, 0x70, 0x69, 0xaa, 0x02, 0x0e, 0x43, 0x68, 0x69, 0x72, - 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x41, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x42, 0x96, 0x01, 0x0a, 0x11, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, + 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x10, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, + 0x6b, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x61, 0x70, 0x69, 0xaa, 0x02, 0x0e, 0x43, 0x68, 0x69, + 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x41, 0x70, 0x69, 0xca, 0x02, 0x0e, 0x43, 0x68, + 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5c, 0x41, 0x70, 0x69, 0xe2, 0x02, 0x1a, 0x47, + 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5c, 0x43, 0x68, 0x69, 0x72, 0x70, + 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5c, 0x41, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( diff --git a/api/go/api/device.pb.go b/api/go/api/device.pb.go index 8c1a90c4..e38c488b 100644 --- a/api/go/api/device.pb.go +++ b/api/go/api/device.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.34.1 // protoc v4.24.4 // source: api/device.proto @@ -2888,13 +2888,16 @@ var file_api_device_proto_rawDesc = []byte{ 0xe4, 0x93, 0x02, 0x2f, 0x3a, 0x01, 0x2a, 0x22, 0x2a, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x64, 0x65, 0x76, 0x5f, 0x65, 0x75, 0x69, 0x7d, 0x2f, 0x67, 0x65, 0x74, 0x2d, 0x6e, 0x65, 0x78, 0x74, 0x2d, 0x66, 0x2d, 0x63, 0x6e, 0x74, 0x2d, 0x64, - 0x6f, 0x77, 0x6e, 0x42, 0x63, 0x0a, 0x11, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, - 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x0b, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x63, - 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, - 0x2f, 0x76, 0x34, 0x2f, 0x61, 0x70, 0x69, 0xaa, 0x02, 0x0e, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, - 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x41, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x77, 0x6e, 0x42, 0x91, 0x01, 0x0a, 0x11, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72, 0x70, + 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x0b, 0x44, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, + 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, + 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x61, 0x70, 0x69, 0xaa, 0x02, 0x0e, 0x43, 0x68, 0x69, 0x72, 0x70, + 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x41, 0x70, 0x69, 0xca, 0x02, 0x0e, 0x43, 0x68, 0x69, 0x72, + 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5c, 0x41, 0x70, 0x69, 0xe2, 0x02, 0x1a, 0x47, 0x50, 0x42, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5c, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, + 0x61, 0x63, 0x6b, 0x5c, 0x41, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/go/api/device_profile.pb.go b/api/go/api/device_profile.pb.go index 01793372..5f85863b 100644 --- a/api/go/api/device_profile.pb.go +++ b/api/go/api/device_profile.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.34.1 // protoc v4.24.4 // source: api/device_profile.proto @@ -2054,14 +2054,17 @@ var file_api_device_profile_proto_rawDesc = []byte{ 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x25, 0x12, 0x23, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2d, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x61, 0x64, 0x72, 0x2d, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, - 0x6d, 0x73, 0x42, 0x6a, 0x0a, 0x11, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, - 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x12, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x50, - 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2e, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, - 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, - 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x61, 0x70, 0x69, 0xaa, 0x02, 0x0e, - 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x41, 0x70, 0x69, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6d, 0x73, 0x42, 0x98, 0x01, 0x0a, 0x11, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, + 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x12, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2e, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, + 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x61, 0x70, 0x69, 0xaa, 0x02, + 0x0e, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x41, 0x70, 0x69, 0xca, + 0x02, 0x0e, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5c, 0x41, 0x70, 0x69, + 0xe2, 0x02, 0x1a, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5c, 0x43, + 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5c, 0x41, 0x70, 0x69, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/go/api/device_profile_template.pb.go b/api/go/api/device_profile_template.pb.go index 980fc4e8..258bcdda 100644 --- a/api/go/api/device_profile_template.pb.go +++ b/api/go/api/device_profile_template.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.34.1 // protoc v4.24.4 // source: api/device_profile_template.proto @@ -1088,14 +1088,17 @@ var file_api_device_profile_template_proto_rawDesc = []byte{ 0x6c, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x12, 0x1d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2d, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x74, 0x65, 0x6d, 0x70, 0x6c, - 0x61, 0x74, 0x65, 0x73, 0x42, 0x72, 0x0a, 0x11, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72, 0x70, - 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x1a, 0x44, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x63, - 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, - 0x2f, 0x76, 0x34, 0x2f, 0x61, 0x70, 0x69, 0xaa, 0x02, 0x0e, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, - 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x41, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x61, 0x74, 0x65, 0x73, 0x42, 0xa0, 0x01, 0x0a, 0x11, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72, + 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x1a, 0x44, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, + 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, + 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, + 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x61, 0x70, 0x69, 0xaa, 0x02, 0x0e, 0x43, 0x68, 0x69, 0x72, 0x70, + 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x41, 0x70, 0x69, 0xca, 0x02, 0x0e, 0x43, 0x68, 0x69, 0x72, + 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5c, 0x41, 0x70, 0x69, 0xe2, 0x02, 0x1a, 0x47, 0x50, 0x42, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5c, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, + 0x61, 0x63, 0x6b, 0x5c, 0x41, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/go/api/gateway.pb.go b/api/go/api/gateway.pb.go index 557fd9bc..0b5c0cfa 100644 --- a/api/go/api/gateway.pb.go +++ b/api/go/api/gateway.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.34.1 // protoc v4.24.4 // source: api/gateway.proto @@ -1152,6 +1152,584 @@ func (x *GetGatewayDutyCycleMetricsResponse) GetWindowPercentage() *common.Metri return nil } +type GetRelayGatewayRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Tenant ID (UUID). + TenantId string `protobuf:"bytes,1,opt,name=tenant_id,json=tenantId,proto3" json:"tenant_id,omitempty"` + // Relay ID (4 byte HEX). + RelayId string `protobuf:"bytes,2,opt,name=relay_id,json=relayId,proto3" json:"relay_id,omitempty"` +} + +func (x *GetRelayGatewayRequest) Reset() { + *x = GetRelayGatewayRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_gateway_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetRelayGatewayRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetRelayGatewayRequest) ProtoMessage() {} + +func (x *GetRelayGatewayRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_gateway_proto_msgTypes[15] + 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 GetRelayGatewayRequest.ProtoReflect.Descriptor instead. +func (*GetRelayGatewayRequest) Descriptor() ([]byte, []int) { + return file_api_gateway_proto_rawDescGZIP(), []int{15} +} + +func (x *GetRelayGatewayRequest) GetTenantId() string { + if x != nil { + return x.TenantId + } + return "" +} + +func (x *GetRelayGatewayRequest) GetRelayId() string { + if x != nil { + return x.RelayId + } + return "" +} + +type GetRelayGatewayResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Relay Gateway object. + RelayGateway *RelayGateway `protobuf:"bytes,1,opt,name=relay_gateway,json=relayGateway,proto3" json:"relay_gateway,omitempty"` + // Created at timestamp. + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + // Last update timestamp. + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` + // Last seen at timestamp. + LastSeenAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=last_seen_at,json=lastSeenAt,proto3" json:"last_seen_at,omitempty"` +} + +func (x *GetRelayGatewayResponse) Reset() { + *x = GetRelayGatewayResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_gateway_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetRelayGatewayResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetRelayGatewayResponse) ProtoMessage() {} + +func (x *GetRelayGatewayResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_gateway_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetRelayGatewayResponse.ProtoReflect.Descriptor instead. +func (*GetRelayGatewayResponse) Descriptor() ([]byte, []int) { + return file_api_gateway_proto_rawDescGZIP(), []int{16} +} + +func (x *GetRelayGatewayResponse) GetRelayGateway() *RelayGateway { + if x != nil { + return x.RelayGateway + } + return nil +} + +func (x *GetRelayGatewayResponse) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *GetRelayGatewayResponse) GetUpdatedAt() *timestamppb.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + +func (x *GetRelayGatewayResponse) GetLastSeenAt() *timestamppb.Timestamp { + if x != nil { + return x.LastSeenAt + } + return nil +} + +type ListRelayGatewaysRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Max number of relay-gateways to return in the result-set. + Limit uint32 `protobuf:"varint,1,opt,name=limit,proto3" json:"limit,omitempty"` + // Offset in the result-set (for pagination). + Offset uint32 `protobuf:"varint,2,opt,name=offset,proto3" json:"offset,omitempty"` + // Tenant ID (UUID) to filter relay-gateways on. + // To list all relay-gateways as a global admin user, this field can be left blank. + TenantId string `protobuf:"bytes,3,opt,name=tenant_id,json=tenantId,proto3" json:"tenant_id,omitempty"` +} + +func (x *ListRelayGatewaysRequest) Reset() { + *x = ListRelayGatewaysRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_gateway_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListRelayGatewaysRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListRelayGatewaysRequest) ProtoMessage() {} + +func (x *ListRelayGatewaysRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_gateway_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListRelayGatewaysRequest.ProtoReflect.Descriptor instead. +func (*ListRelayGatewaysRequest) Descriptor() ([]byte, []int) { + return file_api_gateway_proto_rawDescGZIP(), []int{17} +} + +func (x *ListRelayGatewaysRequest) GetLimit() uint32 { + if x != nil { + return x.Limit + } + return 0 +} + +func (x *ListRelayGatewaysRequest) GetOffset() uint32 { + if x != nil { + return x.Offset + } + return 0 +} + +func (x *ListRelayGatewaysRequest) GetTenantId() string { + if x != nil { + return x.TenantId + } + return "" +} + +type ListRelayGatewaysResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Total number of relay-gateways. + TotalCount uint32 `protobuf:"varint,1,opt,name=total_count,json=totalCount,proto3" json:"total_count,omitempty"` + // Result-set. + Result []*RelayGatewayListItem `protobuf:"bytes,2,rep,name=result,proto3" json:"result,omitempty"` +} + +func (x *ListRelayGatewaysResponse) Reset() { + *x = ListRelayGatewaysResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_gateway_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListRelayGatewaysResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListRelayGatewaysResponse) ProtoMessage() {} + +func (x *ListRelayGatewaysResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_gateway_proto_msgTypes[18] + 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 ListRelayGatewaysResponse.ProtoReflect.Descriptor instead. +func (*ListRelayGatewaysResponse) Descriptor() ([]byte, []int) { + return file_api_gateway_proto_rawDescGZIP(), []int{18} +} + +func (x *ListRelayGatewaysResponse) GetTotalCount() uint32 { + if x != nil { + return x.TotalCount + } + return 0 +} + +func (x *ListRelayGatewaysResponse) GetResult() []*RelayGatewayListItem { + if x != nil { + return x.Result + } + return nil +} + +type RelayGatewayListItem struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Tenant ID. + TenantId string `protobuf:"bytes,1,opt,name=tenant_id,json=tenantId,proto3" json:"tenant_id,omitempty"` + // Relay ID (4 byte HEX). + RelayId string `protobuf:"bytes,2,opt,name=relay_id,json=relayId,proto3" json:"relay_id,omitempty"` + // Name. + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + // Description. + Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty"` + // Created at timestamp. + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + // Last update timestamp. + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` + // Last seen at timestamp. + LastSeenAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=last_seen_at,json=lastSeenAt,proto3" json:"last_seen_at,omitempty"` + // Gateway state. + // Please note that the state of the relay is driven by the last + // received stats packet sent by the relay-gateway. + State GatewayState `protobuf:"varint,10,opt,name=state,proto3,enum=api.GatewayState" json:"state,omitempty"` + // Region configuration ID. + RegionConfigId string `protobuf:"bytes,11,opt,name=region_config_id,json=regionConfigId,proto3" json:"region_config_id,omitempty"` +} + +func (x *RelayGatewayListItem) Reset() { + *x = RelayGatewayListItem{} + if protoimpl.UnsafeEnabled { + mi := &file_api_gateway_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RelayGatewayListItem) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RelayGatewayListItem) ProtoMessage() {} + +func (x *RelayGatewayListItem) ProtoReflect() protoreflect.Message { + mi := &file_api_gateway_proto_msgTypes[19] + 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 RelayGatewayListItem.ProtoReflect.Descriptor instead. +func (*RelayGatewayListItem) Descriptor() ([]byte, []int) { + return file_api_gateway_proto_rawDescGZIP(), []int{19} +} + +func (x *RelayGatewayListItem) GetTenantId() string { + if x != nil { + return x.TenantId + } + return "" +} + +func (x *RelayGatewayListItem) GetRelayId() string { + if x != nil { + return x.RelayId + } + return "" +} + +func (x *RelayGatewayListItem) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *RelayGatewayListItem) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *RelayGatewayListItem) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *RelayGatewayListItem) GetUpdatedAt() *timestamppb.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + +func (x *RelayGatewayListItem) GetLastSeenAt() *timestamppb.Timestamp { + if x != nil { + return x.LastSeenAt + } + return nil +} + +func (x *RelayGatewayListItem) GetState() GatewayState { + if x != nil { + return x.State + } + return GatewayState_NEVER_SEEN +} + +func (x *RelayGatewayListItem) GetRegionConfigId() string { + if x != nil { + return x.RegionConfigId + } + return "" +} + +type UpdateRelayGatewayRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Relay Gateway object. + RelayGateway *RelayGateway `protobuf:"bytes,1,opt,name=relay_gateway,json=relayGateway,proto3" json:"relay_gateway,omitempty"` +} + +func (x *UpdateRelayGatewayRequest) Reset() { + *x = UpdateRelayGatewayRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_gateway_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateRelayGatewayRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateRelayGatewayRequest) ProtoMessage() {} + +func (x *UpdateRelayGatewayRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_gateway_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 UpdateRelayGatewayRequest.ProtoReflect.Descriptor instead. +func (*UpdateRelayGatewayRequest) Descriptor() ([]byte, []int) { + return file_api_gateway_proto_rawDescGZIP(), []int{20} +} + +func (x *UpdateRelayGatewayRequest) GetRelayGateway() *RelayGateway { + if x != nil { + return x.RelayGateway + } + return nil +} + +type DeleteRelayGatewayRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Tenant ID. + TenantId string `protobuf:"bytes,1,opt,name=tenant_id,json=tenantId,proto3" json:"tenant_id,omitempty"` + // Relay ID (4 byte HEX). + RelayId string `protobuf:"bytes,2,opt,name=relay_id,json=relayId,proto3" json:"relay_id,omitempty"` +} + +func (x *DeleteRelayGatewayRequest) Reset() { + *x = DeleteRelayGatewayRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_gateway_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteRelayGatewayRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteRelayGatewayRequest) ProtoMessage() {} + +func (x *DeleteRelayGatewayRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_gateway_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 DeleteRelayGatewayRequest.ProtoReflect.Descriptor instead. +func (*DeleteRelayGatewayRequest) Descriptor() ([]byte, []int) { + return file_api_gateway_proto_rawDescGZIP(), []int{21} +} + +func (x *DeleteRelayGatewayRequest) GetTenantId() string { + if x != nil { + return x.TenantId + } + return "" +} + +func (x *DeleteRelayGatewayRequest) GetRelayId() string { + if x != nil { + return x.RelayId + } + return "" +} + +type RelayGateway struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Tenant ID. + TenantId string `protobuf:"bytes,1,opt,name=tenant_id,json=tenantId,proto3" json:"tenant_id,omitempty"` + // Relay ID (4 byte HEX). + RelayId string `protobuf:"bytes,2,opt,name=relay_id,json=relayId,proto3" json:"relay_id,omitempty"` + // Name. + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + // Description. + Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty"` + // Stats interval (seconds). + // This defines the expected interval in which the gateway sends its + // statistics. + StatsInterval uint32 `protobuf:"varint,5,opt,name=stats_interval,json=statsInterval,proto3" json:"stats_interval,omitempty"` + // Region configuration ID. + RegionConfigId string `protobuf:"bytes,6,opt,name=region_config_id,json=regionConfigId,proto3" json:"region_config_id,omitempty"` +} + +func (x *RelayGateway) Reset() { + *x = RelayGateway{} + if protoimpl.UnsafeEnabled { + mi := &file_api_gateway_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RelayGateway) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RelayGateway) ProtoMessage() {} + +func (x *RelayGateway) ProtoReflect() protoreflect.Message { + mi := &file_api_gateway_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 RelayGateway.ProtoReflect.Descriptor instead. +func (*RelayGateway) Descriptor() ([]byte, []int) { + return file_api_gateway_proto_rawDescGZIP(), []int{22} +} + +func (x *RelayGateway) GetTenantId() string { + if x != nil { + return x.TenantId + } + return "" +} + +func (x *RelayGateway) GetRelayId() string { + if x != nil { + return x.RelayId + } + return "" +} + +func (x *RelayGateway) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *RelayGateway) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *RelayGateway) GetStatsInterval() uint32 { + if x != nil { + return x.StatsInterval + } + return 0 +} + +func (x *RelayGateway) GetRegionConfigId() string { + if x != nil { + return x.RegionConfigId + } + return "" +} + var File_api_gateway_proto protoreflect.FileDescriptor var file_api_gateway_proto_rawDesc = []byte{ @@ -1347,77 +1925,199 @@ var file_api_gateway_proto_rawDesc = []byte{ 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x10, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x50, 0x65, - 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x2a, 0x37, 0x0a, 0x0c, 0x47, 0x61, 0x74, 0x65, - 0x77, 0x61, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x0a, 0x4e, 0x45, 0x56, 0x45, - 0x52, 0x5f, 0x53, 0x45, 0x45, 0x4e, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x4f, 0x4e, 0x4c, 0x49, - 0x4e, 0x45, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x4f, 0x46, 0x46, 0x4c, 0x49, 0x4e, 0x45, 0x10, - 0x02, 0x32, 0xb1, 0x07, 0x0a, 0x0e, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x12, 0x55, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x19, - 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, - 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x3a, 0x01, 0x2a, 0x22, 0x0d, 0x2f, 0x61, - 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x12, 0x5a, 0x0a, 0x03, 0x47, - 0x65, 0x74, 0x12, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65, - 0x77, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x61, 0x70, 0x69, - 0x2e, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x61, 0x70, + 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x22, 0x50, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x52, + 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x12, + 0x19, 0x0a, 0x08, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x49, 0x64, 0x22, 0x85, 0x02, 0x0a, 0x17, 0x47, + 0x65, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x0d, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, + 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, + 0x52, 0x0c, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x12, 0x39, + 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, 0x52, 0x09, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 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, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x64, 0x41, 0x74, 0x12, 0x3c, 0x0a, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, + 0x6e, 0x5f, 0x61, 0x74, 0x18, 0x04, 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, 0x65, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, + 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, + 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6c, + 0x69, 0x6d, 0x69, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x1b, 0x0a, 0x09, + 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x22, 0x6f, 0x0a, 0x19, 0x4c, 0x69, 0x73, + 0x74, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x74, 0x6f, 0x74, + 0x61, 0x6c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x31, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, + 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x74, + 0x65, 0x6d, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x8b, 0x03, 0x0a, 0x14, 0x52, + 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x49, + 0x74, 0x65, 0x6d, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, + 0x12, 0x19, 0x0a, 0x08, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 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, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, + 0x75, 0x70, 0x64, 0x61, 0x74, 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, 0x09, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x3c, 0x0a, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x5f, + 0x73, 0x65, 0x65, 0x6e, 0x5f, 0x61, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x53, + 0x65, 0x65, 0x6e, 0x41, 0x74, 0x12, 0x27, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x61, 0x74, 0x65, 0x77, + 0x61, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x28, + 0x0a, 0x10, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, + 0x69, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x64, 0x22, 0x53, 0x0a, 0x19, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x36, 0x0a, 0x0d, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x67, + 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, + 0x0c, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x22, 0x53, 0x0a, + 0x19, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, + 0x77, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x65, + 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, + 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x65, 0x6c, 0x61, 0x79, + 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x6c, 0x61, 0x79, + 0x49, 0x64, 0x22, 0xcd, 0x01, 0x0a, 0x0c, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, + 0x77, 0x61, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, + 0x12, 0x19, 0x0a, 0x08, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x76, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x74, 0x73, + 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x28, 0x0a, 0x10, 0x72, 0x65, 0x67, 0x69, + 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0e, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x49, 0x64, 0x2a, 0x37, 0x0a, 0x0c, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x0a, 0x4e, 0x45, 0x56, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x45, 0x4e, + 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x4f, 0x4e, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x01, 0x12, 0x0b, + 0x0a, 0x07, 0x4f, 0x46, 0x46, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x02, 0x32, 0xee, 0x0b, 0x0a, 0x0e, + 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x55, + 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x18, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x12, 0x3a, 0x01, 0x2a, 0x22, 0x0d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, + 0x65, 0x77, 0x61, 0x79, 0x73, 0x12, 0x5a, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x16, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x61, + 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, + 0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, + 0x7d, 0x12, 0x6a, 0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x19, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x2d, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x3a, 0x01, 0x2a, 0x1a, 0x22, 0x2f, 0x61, 0x70, 0x69, 0x2f, + 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, + 0x79, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x5f, 0x0a, + 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x1c, 0x2a, 0x1a, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, + 0x73, 0x2f, 0x7b, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x52, + 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, + 0x61, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x15, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x0f, 0x12, 0x0d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, + 0x79, 0x73, 0x12, 0xb1, 0x01, 0x0a, 0x19, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x43, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, + 0x12, 0x2c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x47, + 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x47, 0x61, 0x74, + 0x65, 0x77, 0x61, 0x79, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x37, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x31, 0x22, 0x2f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, + 0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, + 0x7d, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x2d, 0x63, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x77, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, + 0x72, 0x69, 0x63, 0x73, 0x12, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x61, + 0x74, 0x65, 0x77, 0x61, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, + 0x65, 0x77, 0x61, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x12, 0x22, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b, 0x67, 0x61, 0x74, 0x65, - 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x6a, 0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x47, 0x61, + 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, + 0x9d, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x44, 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, + 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x26, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, + 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x44, 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, + 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x27, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, + 0x44, 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x35, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2f, + 0x12, 0x2d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, + 0x7b, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x64, 0x75, 0x74, + 0x79, 0x2d, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x2d, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, + 0x89, 0x01, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, + 0x77, 0x61, 0x79, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x6c, + 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, + 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3b, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x35, 0x12, 0x33, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, + 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x2d, 0x67, 0x61, 0x74, 0x65, + 0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, + 0x2f, 0x7b, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x78, 0x0a, 0x11, 0x4c, + 0x69, 0x73, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, + 0x12, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x79, + 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, + 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x12, 0x1c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, + 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x2d, 0x67, 0x61, 0x74, + 0x65, 0x77, 0x61, 0x79, 0x73, 0x12, 0xa8, 0x01, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x12, 0x1e, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x22, 0x2d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x3a, 0x01, 0x2a, 0x1a, - 0x22, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b, - 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, - 0x69, 0x64, 0x7d, 0x12, 0x5f, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x19, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, - 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x2a, 0x1a, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, - 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, - 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x52, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x18, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x15, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f, 0x12, 0x0d, 0x2f, 0x61, 0x70, 0x69, 0x2f, - 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x12, 0xb1, 0x01, 0x0a, 0x19, 0x47, 0x65, 0x6e, - 0x65, 0x72, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x2c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x6e, - 0x65, 0x72, 0x61, 0x74, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x43, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, - 0x61, 0x74, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x37, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x31, 0x22, 0x2f, 0x2f, 0x61, 0x70, - 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b, 0x67, 0x61, 0x74, 0x65, - 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, - 0x2d, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x77, 0x0a, 0x0a, - 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x1d, 0x2e, 0x61, 0x70, 0x69, - 0x2e, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, - 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x24, 0x12, 0x22, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, - 0x2f, 0x7b, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x6d, 0x65, - 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x9d, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x44, 0x75, 0x74, - 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x26, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x44, 0x75, - 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x47, - 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x44, 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x4d, - 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x35, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2f, 0x12, 0x2d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, - 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, - 0x64, 0x7d, 0x2f, 0x64, 0x75, 0x74, 0x79, 0x2d, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x2d, 0x6d, 0x65, - 0x74, 0x72, 0x69, 0x63, 0x73, 0x42, 0x64, 0x0a, 0x11, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72, - 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x0c, 0x47, 0x61, 0x74, 0x65, - 0x77, 0x61, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, - 0x6b, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, 0x69, - 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x61, 0x70, 0x69, 0xaa, 0x02, 0x0e, 0x43, 0x68, 0x69, - 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x41, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x6d, 0x70, 0x74, 0x79, 0x22, 0x5a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x54, 0x3a, 0x01, 0x2a, 0x1a, + 0x4f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x72, + 0x65, 0x6c, 0x61, 0x79, 0x2d, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b, 0x72, + 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x74, 0x65, 0x6e, + 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x7b, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x67, + 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d, + 0x12, 0x89, 0x01, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x6c, 0x61, 0x79, + 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x12, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, + 0x3b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x35, 0x2a, 0x33, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, + 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x2d, 0x67, 0x61, 0x74, + 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, + 0x7d, 0x2f, 0x7b, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x42, 0x92, 0x01, 0x0a, + 0x11, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, + 0x70, 0x69, 0x42, 0x0c, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, + 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, + 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x61, + 0x70, 0x69, 0xaa, 0x02, 0x0e, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, + 0x41, 0x70, 0x69, 0xca, 0x02, 0x0e, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x5c, 0x41, 0x70, 0x69, 0xe2, 0x02, 0x1a, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x5c, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5c, 0x41, 0x70, + 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1433,7 +2133,7 @@ func file_api_gateway_proto_rawDescGZIP() []byte { } var file_api_gateway_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_api_gateway_proto_msgTypes = make([]protoimpl.MessageInfo, 18) +var file_api_gateway_proto_msgTypes = make([]protoimpl.MessageInfo, 26) var file_api_gateway_proto_goTypes = []interface{}{ (GatewayState)(0), // 0: api.GatewayState (*Gateway)(nil), // 1: api.Gateway @@ -1451,68 +2151,94 @@ var file_api_gateway_proto_goTypes = []interface{}{ (*GetGatewayMetricsResponse)(nil), // 13: api.GetGatewayMetricsResponse (*GetGatewayDutyCycleMetricsRequest)(nil), // 14: api.GetGatewayDutyCycleMetricsRequest (*GetGatewayDutyCycleMetricsResponse)(nil), // 15: api.GetGatewayDutyCycleMetricsResponse - nil, // 16: api.Gateway.TagsEntry - nil, // 17: api.Gateway.MetadataEntry - nil, // 18: api.GatewayListItem.PropertiesEntry - (*common.Location)(nil), // 19: common.Location - (*timestamppb.Timestamp)(nil), // 20: google.protobuf.Timestamp - (common.Aggregation)(0), // 21: common.Aggregation - (*common.Metric)(nil), // 22: common.Metric - (*emptypb.Empty)(nil), // 23: google.protobuf.Empty + (*GetRelayGatewayRequest)(nil), // 16: api.GetRelayGatewayRequest + (*GetRelayGatewayResponse)(nil), // 17: api.GetRelayGatewayResponse + (*ListRelayGatewaysRequest)(nil), // 18: api.ListRelayGatewaysRequest + (*ListRelayGatewaysResponse)(nil), // 19: api.ListRelayGatewaysResponse + (*RelayGatewayListItem)(nil), // 20: api.RelayGatewayListItem + (*UpdateRelayGatewayRequest)(nil), // 21: api.UpdateRelayGatewayRequest + (*DeleteRelayGatewayRequest)(nil), // 22: api.DeleteRelayGatewayRequest + (*RelayGateway)(nil), // 23: api.RelayGateway + nil, // 24: api.Gateway.TagsEntry + nil, // 25: api.Gateway.MetadataEntry + nil, // 26: api.GatewayListItem.PropertiesEntry + (*common.Location)(nil), // 27: common.Location + (*timestamppb.Timestamp)(nil), // 28: google.protobuf.Timestamp + (common.Aggregation)(0), // 29: common.Aggregation + (*common.Metric)(nil), // 30: common.Metric + (*emptypb.Empty)(nil), // 31: google.protobuf.Empty } var file_api_gateway_proto_depIdxs = []int32{ - 19, // 0: api.Gateway.location:type_name -> common.Location - 16, // 1: api.Gateway.tags:type_name -> api.Gateway.TagsEntry - 17, // 2: api.Gateway.metadata:type_name -> api.Gateway.MetadataEntry - 19, // 3: api.GatewayListItem.location:type_name -> common.Location - 18, // 4: api.GatewayListItem.properties:type_name -> api.GatewayListItem.PropertiesEntry - 20, // 5: api.GatewayListItem.created_at:type_name -> google.protobuf.Timestamp - 20, // 6: api.GatewayListItem.updated_at:type_name -> google.protobuf.Timestamp - 20, // 7: api.GatewayListItem.last_seen_at:type_name -> google.protobuf.Timestamp + 27, // 0: api.Gateway.location:type_name -> common.Location + 24, // 1: api.Gateway.tags:type_name -> api.Gateway.TagsEntry + 25, // 2: api.Gateway.metadata:type_name -> api.Gateway.MetadataEntry + 27, // 3: api.GatewayListItem.location:type_name -> common.Location + 26, // 4: api.GatewayListItem.properties:type_name -> api.GatewayListItem.PropertiesEntry + 28, // 5: api.GatewayListItem.created_at:type_name -> google.protobuf.Timestamp + 28, // 6: api.GatewayListItem.updated_at:type_name -> google.protobuf.Timestamp + 28, // 7: api.GatewayListItem.last_seen_at:type_name -> google.protobuf.Timestamp 0, // 8: api.GatewayListItem.state:type_name -> api.GatewayState 1, // 9: api.CreateGatewayRequest.gateway:type_name -> api.Gateway 1, // 10: api.GetGatewayResponse.gateway:type_name -> api.Gateway - 20, // 11: api.GetGatewayResponse.created_at:type_name -> google.protobuf.Timestamp - 20, // 12: api.GetGatewayResponse.updated_at:type_name -> google.protobuf.Timestamp - 20, // 13: api.GetGatewayResponse.last_seen_at:type_name -> google.protobuf.Timestamp + 28, // 11: api.GetGatewayResponse.created_at:type_name -> google.protobuf.Timestamp + 28, // 12: api.GetGatewayResponse.updated_at:type_name -> google.protobuf.Timestamp + 28, // 13: api.GetGatewayResponse.last_seen_at:type_name -> google.protobuf.Timestamp 1, // 14: api.UpdateGatewayRequest.gateway:type_name -> api.Gateway 2, // 15: api.ListGatewaysResponse.result:type_name -> api.GatewayListItem - 20, // 16: api.GenerateGatewayClientCertificateResponse.expires_at:type_name -> google.protobuf.Timestamp - 20, // 17: api.GetGatewayMetricsRequest.start:type_name -> google.protobuf.Timestamp - 20, // 18: api.GetGatewayMetricsRequest.end:type_name -> google.protobuf.Timestamp - 21, // 19: api.GetGatewayMetricsRequest.aggregation:type_name -> common.Aggregation - 22, // 20: api.GetGatewayMetricsResponse.rx_packets:type_name -> common.Metric - 22, // 21: api.GetGatewayMetricsResponse.tx_packets:type_name -> common.Metric - 22, // 22: api.GetGatewayMetricsResponse.tx_packets_per_freq:type_name -> common.Metric - 22, // 23: api.GetGatewayMetricsResponse.rx_packets_per_freq:type_name -> common.Metric - 22, // 24: api.GetGatewayMetricsResponse.tx_packets_per_dr:type_name -> common.Metric - 22, // 25: api.GetGatewayMetricsResponse.rx_packets_per_dr:type_name -> common.Metric - 22, // 26: api.GetGatewayMetricsResponse.tx_packets_per_status:type_name -> common.Metric - 20, // 27: api.GetGatewayDutyCycleMetricsRequest.start:type_name -> google.protobuf.Timestamp - 20, // 28: api.GetGatewayDutyCycleMetricsRequest.end:type_name -> google.protobuf.Timestamp - 22, // 29: api.GetGatewayDutyCycleMetricsResponse.max_load_percentage:type_name -> common.Metric - 22, // 30: api.GetGatewayDutyCycleMetricsResponse.window_percentage:type_name -> common.Metric - 3, // 31: api.GatewayService.Create:input_type -> api.CreateGatewayRequest - 4, // 32: api.GatewayService.Get:input_type -> api.GetGatewayRequest - 6, // 33: api.GatewayService.Update:input_type -> api.UpdateGatewayRequest - 7, // 34: api.GatewayService.Delete:input_type -> api.DeleteGatewayRequest - 8, // 35: api.GatewayService.List:input_type -> api.ListGatewaysRequest - 10, // 36: api.GatewayService.GenerateClientCertificate:input_type -> api.GenerateGatewayClientCertificateRequest - 12, // 37: api.GatewayService.GetMetrics:input_type -> api.GetGatewayMetricsRequest - 14, // 38: api.GatewayService.GetDutyCycleMetrics:input_type -> api.GetGatewayDutyCycleMetricsRequest - 23, // 39: api.GatewayService.Create:output_type -> google.protobuf.Empty - 5, // 40: api.GatewayService.Get:output_type -> api.GetGatewayResponse - 23, // 41: api.GatewayService.Update:output_type -> google.protobuf.Empty - 23, // 42: api.GatewayService.Delete:output_type -> google.protobuf.Empty - 9, // 43: api.GatewayService.List:output_type -> api.ListGatewaysResponse - 11, // 44: api.GatewayService.GenerateClientCertificate:output_type -> api.GenerateGatewayClientCertificateResponse - 13, // 45: api.GatewayService.GetMetrics:output_type -> api.GetGatewayMetricsResponse - 15, // 46: api.GatewayService.GetDutyCycleMetrics:output_type -> api.GetGatewayDutyCycleMetricsResponse - 39, // [39:47] is the sub-list for method output_type - 31, // [31:39] is the sub-list for method input_type - 31, // [31:31] is the sub-list for extension type_name - 31, // [31:31] is the sub-list for extension extendee - 0, // [0:31] is the sub-list for field type_name + 28, // 16: api.GenerateGatewayClientCertificateResponse.expires_at:type_name -> google.protobuf.Timestamp + 28, // 17: api.GetGatewayMetricsRequest.start:type_name -> google.protobuf.Timestamp + 28, // 18: api.GetGatewayMetricsRequest.end:type_name -> google.protobuf.Timestamp + 29, // 19: api.GetGatewayMetricsRequest.aggregation:type_name -> common.Aggregation + 30, // 20: api.GetGatewayMetricsResponse.rx_packets:type_name -> common.Metric + 30, // 21: api.GetGatewayMetricsResponse.tx_packets:type_name -> common.Metric + 30, // 22: api.GetGatewayMetricsResponse.tx_packets_per_freq:type_name -> common.Metric + 30, // 23: api.GetGatewayMetricsResponse.rx_packets_per_freq:type_name -> common.Metric + 30, // 24: api.GetGatewayMetricsResponse.tx_packets_per_dr:type_name -> common.Metric + 30, // 25: api.GetGatewayMetricsResponse.rx_packets_per_dr:type_name -> common.Metric + 30, // 26: api.GetGatewayMetricsResponse.tx_packets_per_status:type_name -> common.Metric + 28, // 27: api.GetGatewayDutyCycleMetricsRequest.start:type_name -> google.protobuf.Timestamp + 28, // 28: api.GetGatewayDutyCycleMetricsRequest.end:type_name -> google.protobuf.Timestamp + 30, // 29: api.GetGatewayDutyCycleMetricsResponse.max_load_percentage:type_name -> common.Metric + 30, // 30: api.GetGatewayDutyCycleMetricsResponse.window_percentage:type_name -> common.Metric + 23, // 31: api.GetRelayGatewayResponse.relay_gateway:type_name -> api.RelayGateway + 28, // 32: api.GetRelayGatewayResponse.created_at:type_name -> google.protobuf.Timestamp + 28, // 33: api.GetRelayGatewayResponse.updated_at:type_name -> google.protobuf.Timestamp + 28, // 34: api.GetRelayGatewayResponse.last_seen_at:type_name -> google.protobuf.Timestamp + 20, // 35: api.ListRelayGatewaysResponse.result:type_name -> api.RelayGatewayListItem + 28, // 36: api.RelayGatewayListItem.created_at:type_name -> google.protobuf.Timestamp + 28, // 37: api.RelayGatewayListItem.updated_at:type_name -> google.protobuf.Timestamp + 28, // 38: api.RelayGatewayListItem.last_seen_at:type_name -> google.protobuf.Timestamp + 0, // 39: api.RelayGatewayListItem.state:type_name -> api.GatewayState + 23, // 40: api.UpdateRelayGatewayRequest.relay_gateway:type_name -> api.RelayGateway + 3, // 41: api.GatewayService.Create:input_type -> api.CreateGatewayRequest + 4, // 42: api.GatewayService.Get:input_type -> api.GetGatewayRequest + 6, // 43: api.GatewayService.Update:input_type -> api.UpdateGatewayRequest + 7, // 44: api.GatewayService.Delete:input_type -> api.DeleteGatewayRequest + 8, // 45: api.GatewayService.List:input_type -> api.ListGatewaysRequest + 10, // 46: api.GatewayService.GenerateClientCertificate:input_type -> api.GenerateGatewayClientCertificateRequest + 12, // 47: api.GatewayService.GetMetrics:input_type -> api.GetGatewayMetricsRequest + 14, // 48: api.GatewayService.GetDutyCycleMetrics:input_type -> api.GetGatewayDutyCycleMetricsRequest + 16, // 49: api.GatewayService.GetRelayGateway:input_type -> api.GetRelayGatewayRequest + 18, // 50: api.GatewayService.ListRelayGateways:input_type -> api.ListRelayGatewaysRequest + 21, // 51: api.GatewayService.UpdateRelayGateway:input_type -> api.UpdateRelayGatewayRequest + 22, // 52: api.GatewayService.DeleteRelayGateway:input_type -> api.DeleteRelayGatewayRequest + 31, // 53: api.GatewayService.Create:output_type -> google.protobuf.Empty + 5, // 54: api.GatewayService.Get:output_type -> api.GetGatewayResponse + 31, // 55: api.GatewayService.Update:output_type -> google.protobuf.Empty + 31, // 56: api.GatewayService.Delete:output_type -> google.protobuf.Empty + 9, // 57: api.GatewayService.List:output_type -> api.ListGatewaysResponse + 11, // 58: api.GatewayService.GenerateClientCertificate:output_type -> api.GenerateGatewayClientCertificateResponse + 13, // 59: api.GatewayService.GetMetrics:output_type -> api.GetGatewayMetricsResponse + 15, // 60: api.GatewayService.GetDutyCycleMetrics:output_type -> api.GetGatewayDutyCycleMetricsResponse + 17, // 61: api.GatewayService.GetRelayGateway:output_type -> api.GetRelayGatewayResponse + 19, // 62: api.GatewayService.ListRelayGateways:output_type -> api.ListRelayGatewaysResponse + 31, // 63: api.GatewayService.UpdateRelayGateway:output_type -> google.protobuf.Empty + 31, // 64: api.GatewayService.DeleteRelayGateway:output_type -> google.protobuf.Empty + 53, // [53:65] is the sub-list for method output_type + 41, // [41:53] is the sub-list for method input_type + 41, // [41:41] is the sub-list for extension type_name + 41, // [41:41] is the sub-list for extension extendee + 0, // [0:41] is the sub-list for field type_name } func init() { file_api_gateway_proto_init() } @@ -1701,6 +2427,102 @@ func file_api_gateway_proto_init() { return nil } } + file_api_gateway_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetRelayGatewayRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_gateway_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetRelayGatewayResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_gateway_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListRelayGatewaysRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_gateway_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListRelayGatewaysResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_gateway_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RelayGatewayListItem); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_gateway_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateRelayGatewayRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_gateway_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteRelayGatewayRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_gateway_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RelayGateway); 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{ @@ -1708,7 +2530,7 @@ func file_api_gateway_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_api_gateway_proto_rawDesc, NumEnums: 1, - NumMessages: 18, + NumMessages: 26, NumExtensions: 0, NumServices: 1, }, diff --git a/api/go/api/gateway_grpc.pb.go b/api/go/api/gateway_grpc.pb.go index 3f3d7d4e..aeec35a4 100644 --- a/api/go/api/gateway_grpc.pb.go +++ b/api/go/api/gateway_grpc.pb.go @@ -28,6 +28,10 @@ const ( GatewayService_GenerateClientCertificate_FullMethodName = "/api.GatewayService/GenerateClientCertificate" GatewayService_GetMetrics_FullMethodName = "/api.GatewayService/GetMetrics" GatewayService_GetDutyCycleMetrics_FullMethodName = "/api.GatewayService/GetDutyCycleMetrics" + GatewayService_GetRelayGateway_FullMethodName = "/api.GatewayService/GetRelayGateway" + GatewayService_ListRelayGateways_FullMethodName = "/api.GatewayService/ListRelayGateways" + GatewayService_UpdateRelayGateway_FullMethodName = "/api.GatewayService/UpdateRelayGateway" + GatewayService_DeleteRelayGateway_FullMethodName = "/api.GatewayService/DeleteRelayGateway" ) // GatewayServiceClient is the client API for GatewayService service. @@ -51,6 +55,14 @@ type GatewayServiceClient interface { // GetDutyCycleMetrics returns the duty-cycle metrics. // Note that only the last 2 hours of data are stored. Currently only per minute aggregation is available. GetDutyCycleMetrics(ctx context.Context, in *GetGatewayDutyCycleMetricsRequest, opts ...grpc.CallOption) (*GetGatewayDutyCycleMetricsResponse, error) + // Get the given Relay Gateway. + GetRelayGateway(ctx context.Context, in *GetRelayGatewayRequest, opts ...grpc.CallOption) (*GetRelayGatewayResponse, error) + // List the detected Relay Gateways. + ListRelayGateways(ctx context.Context, in *ListRelayGatewaysRequest, opts ...grpc.CallOption) (*ListRelayGatewaysResponse, error) + // Update the given Relay Gateway. + UpdateRelayGateway(ctx context.Context, in *UpdateRelayGatewayRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + // Delete the given Relay Gateway. + DeleteRelayGateway(ctx context.Context, in *DeleteRelayGatewayRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) } type gatewayServiceClient struct { @@ -133,6 +145,42 @@ func (c *gatewayServiceClient) GetDutyCycleMetrics(ctx context.Context, in *GetG return out, nil } +func (c *gatewayServiceClient) GetRelayGateway(ctx context.Context, in *GetRelayGatewayRequest, opts ...grpc.CallOption) (*GetRelayGatewayResponse, error) { + out := new(GetRelayGatewayResponse) + err := c.cc.Invoke(ctx, GatewayService_GetRelayGateway_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *gatewayServiceClient) ListRelayGateways(ctx context.Context, in *ListRelayGatewaysRequest, opts ...grpc.CallOption) (*ListRelayGatewaysResponse, error) { + out := new(ListRelayGatewaysResponse) + err := c.cc.Invoke(ctx, GatewayService_ListRelayGateways_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *gatewayServiceClient) UpdateRelayGateway(ctx context.Context, in *UpdateRelayGatewayRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, GatewayService_UpdateRelayGateway_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *gatewayServiceClient) DeleteRelayGateway(ctx context.Context, in *DeleteRelayGatewayRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, GatewayService_DeleteRelayGateway_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // GatewayServiceServer is the server API for GatewayService service. // All implementations must embed UnimplementedGatewayServiceServer // for forward compatibility @@ -154,6 +202,14 @@ type GatewayServiceServer interface { // GetDutyCycleMetrics returns the duty-cycle metrics. // Note that only the last 2 hours of data are stored. Currently only per minute aggregation is available. GetDutyCycleMetrics(context.Context, *GetGatewayDutyCycleMetricsRequest) (*GetGatewayDutyCycleMetricsResponse, error) + // Get the given Relay Gateway. + GetRelayGateway(context.Context, *GetRelayGatewayRequest) (*GetRelayGatewayResponse, error) + // List the detected Relay Gateways. + ListRelayGateways(context.Context, *ListRelayGatewaysRequest) (*ListRelayGatewaysResponse, error) + // Update the given Relay Gateway. + UpdateRelayGateway(context.Context, *UpdateRelayGatewayRequest) (*emptypb.Empty, error) + // Delete the given Relay Gateway. + DeleteRelayGateway(context.Context, *DeleteRelayGatewayRequest) (*emptypb.Empty, error) mustEmbedUnimplementedGatewayServiceServer() } @@ -185,6 +241,18 @@ func (UnimplementedGatewayServiceServer) GetMetrics(context.Context, *GetGateway func (UnimplementedGatewayServiceServer) GetDutyCycleMetrics(context.Context, *GetGatewayDutyCycleMetricsRequest) (*GetGatewayDutyCycleMetricsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetDutyCycleMetrics not implemented") } +func (UnimplementedGatewayServiceServer) GetRelayGateway(context.Context, *GetRelayGatewayRequest) (*GetRelayGatewayResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetRelayGateway not implemented") +} +func (UnimplementedGatewayServiceServer) ListRelayGateways(context.Context, *ListRelayGatewaysRequest) (*ListRelayGatewaysResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListRelayGateways not implemented") +} +func (UnimplementedGatewayServiceServer) UpdateRelayGateway(context.Context, *UpdateRelayGatewayRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateRelayGateway not implemented") +} +func (UnimplementedGatewayServiceServer) DeleteRelayGateway(context.Context, *DeleteRelayGatewayRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteRelayGateway not implemented") +} func (UnimplementedGatewayServiceServer) mustEmbedUnimplementedGatewayServiceServer() {} // UnsafeGatewayServiceServer may be embedded to opt out of forward compatibility for this service. @@ -342,6 +410,78 @@ func _GatewayService_GetDutyCycleMetrics_Handler(srv interface{}, ctx context.Co return interceptor(ctx, in, info, handler) } +func _GatewayService_GetRelayGateway_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetRelayGatewayRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(GatewayServiceServer).GetRelayGateway(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: GatewayService_GetRelayGateway_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(GatewayServiceServer).GetRelayGateway(ctx, req.(*GetRelayGatewayRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _GatewayService_ListRelayGateways_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListRelayGatewaysRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(GatewayServiceServer).ListRelayGateways(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: GatewayService_ListRelayGateways_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(GatewayServiceServer).ListRelayGateways(ctx, req.(*ListRelayGatewaysRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _GatewayService_UpdateRelayGateway_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateRelayGatewayRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(GatewayServiceServer).UpdateRelayGateway(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: GatewayService_UpdateRelayGateway_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(GatewayServiceServer).UpdateRelayGateway(ctx, req.(*UpdateRelayGatewayRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _GatewayService_DeleteRelayGateway_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteRelayGatewayRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(GatewayServiceServer).DeleteRelayGateway(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: GatewayService_DeleteRelayGateway_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(GatewayServiceServer).DeleteRelayGateway(ctx, req.(*DeleteRelayGatewayRequest)) + } + return interceptor(ctx, in, info, handler) +} + // GatewayService_ServiceDesc is the grpc.ServiceDesc for GatewayService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -381,6 +521,22 @@ var GatewayService_ServiceDesc = grpc.ServiceDesc{ MethodName: "GetDutyCycleMetrics", Handler: _GatewayService_GetDutyCycleMetrics_Handler, }, + { + MethodName: "GetRelayGateway", + Handler: _GatewayService_GetRelayGateway_Handler, + }, + { + MethodName: "ListRelayGateways", + Handler: _GatewayService_ListRelayGateways_Handler, + }, + { + MethodName: "UpdateRelayGateway", + Handler: _GatewayService_UpdateRelayGateway_Handler, + }, + { + MethodName: "DeleteRelayGateway", + Handler: _GatewayService_DeleteRelayGateway_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "api/gateway.proto", diff --git a/api/go/api/internal.pb.go b/api/go/api/internal.pb.go index b0cea84a..211c7337 100644 --- a/api/go/api/internal.pb.go +++ b/api/go/api/internal.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.34.1 // protoc v4.24.4 // source: api/internal.proto @@ -2530,13 +2530,16 @@ var file_api_internal_proto_rawDesc = []byte{ 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x42, 0x65, 0x0a, 0x11, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, - 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x0d, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x63, - 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, - 0x2f, 0x76, 0x34, 0x2f, 0x61, 0x70, 0x69, 0xaa, 0x02, 0x0e, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, - 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x41, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x00, 0x42, 0x93, 0x01, 0x0a, 0x11, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, + 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x0d, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, + 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, + 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x61, 0x70, 0x69, 0xaa, 0x02, 0x0e, 0x43, 0x68, 0x69, 0x72, 0x70, + 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x41, 0x70, 0x69, 0xca, 0x02, 0x0e, 0x43, 0x68, 0x69, 0x72, + 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5c, 0x41, 0x70, 0x69, 0xe2, 0x02, 0x1a, 0x47, 0x50, 0x42, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5c, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, + 0x61, 0x63, 0x6b, 0x5c, 0x41, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/go/api/multicast_group.pb.go b/api/go/api/multicast_group.pb.go index 695fdc5d..d37cb3cb 100644 --- a/api/go/api/multicast_group.pb.go +++ b/api/go/api/multicast_group.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.34.1 // protoc v4.24.4 // source: api/multicast_group.proto @@ -1654,14 +1654,17 @@ var file_api_multicast_group_proto_rawDesc = []byte{ 0x32, 0x12, 0x30, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61, 0x73, 0x74, 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2f, 0x7b, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61, 0x73, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71, 0x75, - 0x65, 0x75, 0x65, 0x42, 0x6b, 0x0a, 0x11, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, - 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x13, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, - 0x61, 0x73, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, - 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, - 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, - 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x61, 0x70, 0x69, 0xaa, - 0x02, 0x0e, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x41, 0x70, 0x69, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x75, 0x65, 0x42, 0x99, 0x01, 0x0a, 0x11, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72, 0x70, + 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x13, 0x4d, 0x75, 0x6c, 0x74, 0x69, + 0x63, 0x61, 0x73, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, + 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, + 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, + 0x63, 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x61, 0x70, 0x69, + 0xaa, 0x02, 0x0e, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x41, 0x70, + 0x69, 0xca, 0x02, 0x0e, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5c, 0x41, + 0x70, 0x69, 0xe2, 0x02, 0x1a, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x5c, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5c, 0x41, 0x70, 0x69, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/go/api/relay.pb.go b/api/go/api/relay.pb.go index d233ec14..d5d4101f 100644 --- a/api/go/api/relay.pb.go +++ b/api/go/api/relay.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.34.1 // protoc v4.24.4 // source: api/relay.proto @@ -595,14 +595,17 @@ var file_api_relay_proto_rawDesc = []byte{ 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x25, 0x12, 0x23, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x73, 0x2f, 0x7b, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x64, 0x65, 0x76, 0x5f, 0x65, 0x75, 0x69, 0x7d, - 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x42, 0x62, 0x0a, 0x11, 0x69, 0x6f, 0x2e, 0x63, - 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x0a, 0x52, - 0x65, 0x6c, 0x61, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, - 0x63, 0x6b, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, - 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x61, 0x70, 0x69, 0xaa, 0x02, 0x0e, 0x43, 0x68, - 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x41, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x42, 0x90, 0x01, 0x0a, 0x11, 0x69, 0x6f, 0x2e, + 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x0a, + 0x52, 0x65, 0x6c, 0x61, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, + 0x61, 0x63, 0x6b, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x61, 0x70, 0x69, 0xaa, 0x02, 0x0e, 0x43, + 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x41, 0x70, 0x69, 0xca, 0x02, 0x0e, + 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5c, 0x41, 0x70, 0x69, 0xe2, 0x02, + 0x1a, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5c, 0x43, 0x68, 0x69, + 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5c, 0x41, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( diff --git a/api/go/api/tenant.pb.go b/api/go/api/tenant.pb.go index 5b3ccb93..f44a829e 100644 --- a/api/go/api/tenant.pb.go +++ b/api/go/api/tenant.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.34.1 // protoc v4.24.4 // source: api/tenant.proto @@ -1565,14 +1565,16 @@ var file_api_tenant_proto_rawDesc = []byte{ 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x12, 0x1e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x75, - 0x73, 0x65, 0x72, 0x73, 0x42, 0x63, 0x0a, 0x11, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72, 0x70, - 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x0b, 0x54, 0x65, 0x6e, 0x61, 0x6e, - 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, - 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, - 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x61, 0x70, 0x69, 0xaa, 0x02, 0x0e, 0x43, 0x68, 0x69, 0x72, 0x70, - 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x41, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x73, 0x65, 0x72, 0x73, 0x42, 0x91, 0x01, 0x0a, 0x11, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72, + 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x0b, 0x54, 0x65, 0x6e, 0x61, + 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2f, + 0x67, 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x61, 0x70, 0x69, 0xaa, 0x02, 0x0e, 0x43, 0x68, 0x69, 0x72, + 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x41, 0x70, 0x69, 0xca, 0x02, 0x0e, 0x43, 0x68, 0x69, + 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5c, 0x41, 0x70, 0x69, 0xe2, 0x02, 0x1a, 0x47, 0x50, + 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5c, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, + 0x74, 0x61, 0x63, 0x6b, 0x5c, 0x41, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/go/api/user.pb.go b/api/go/api/user.pb.go index 115d0c72..45f7e8b5 100644 --- a/api/go/api/user.pb.go +++ b/api/go/api/user.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.34.1 // protoc v4.24.4 // source: api/user.proto @@ -891,14 +891,17 @@ var file_api_user_proto_rawDesc = []byte{ 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x28, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x3a, 0x01, 0x2a, 0x22, 0x1d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x75, 0x73, 0x65, 0x72, - 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x42, 0x61, 0x0a, - 0x11, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, - 0x70, 0x69, 0x42, 0x09, 0x55, 0x73, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, - 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, - 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, - 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x61, 0x70, 0x69, 0xaa, - 0x02, 0x0e, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x41, 0x70, 0x69, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x42, 0x8f, 0x01, + 0x0a, 0x11, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, + 0x61, 0x70, 0x69, 0x42, 0x09, 0x55, 0x73, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, + 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, + 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, + 0x63, 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x61, 0x70, 0x69, + 0xaa, 0x02, 0x0e, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x41, 0x70, + 0x69, 0xca, 0x02, 0x0e, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5c, 0x41, + 0x70, 0x69, 0xe2, 0x02, 0x1a, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x5c, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5c, 0x41, 0x70, 0x69, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/go/common/common.pb.go b/api/go/common/common.pb.go index 60de84f7..6bda9fe9 100644 --- a/api/go/common/common.pb.go +++ b/api/go/common/common.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.34.1 // protoc v4.24.4 // source: common/common.proto @@ -1076,14 +1076,17 @@ var file_common_common_proto_rawDesc = []byte{ 0x01, 0x2a, 0x34, 0x0a, 0x0b, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 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, 0x42, 0x69, 0x0a, 0x11, 0x69, 0x6f, 0x2e, 0x63, 0x68, - 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x0b, 0x43, 0x6f, - 0x6d, 0x6d, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x31, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, - 0x63, 0x6b, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, - 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0xaa, 0x02, - 0x11, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, - 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x41, 0x53, 0x53, 0x5f, 0x43, 0x10, 0x02, 0x42, 0x9d, 0x01, 0x0a, 0x11, 0x69, 0x6f, 0x2e, 0x63, + 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x0b, 0x43, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x31, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, + 0x61, 0x63, 0x6b, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0xaa, + 0x02, 0x11, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x43, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0xca, 0x02, 0x11, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x5c, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0xe2, 0x02, 0x1d, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x5c, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x5c, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/go/gw/gw.pb.go b/api/go/gw/gw.pb.go index 5eaf3d30..f05d0a6e 100644 --- a/api/go/gw/gw.pb.go +++ b/api/go/gw/gw.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.34.1 // protoc v4.24.4 // source: gw/gw.proto @@ -3548,6 +3548,148 @@ func (x *ConnState) GetState() ConnState_State { return ConnState_OFFLINE } +// Gateway Mesh heartbeat (sent periodically by the Relay Gateways). +type MeshHeartbeat struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Gateway ID (of the Border Gateway). + GatewayId string `protobuf:"bytes,1,opt,name=gateway_id,json=gatewayId,proto3" json:"gateway_id,omitempty"` + // Relay ID. + RelayId string `protobuf:"bytes,2,opt,name=relay_id,json=relayId,proto3" json:"relay_id,omitempty"` + // Timestamp (second precision). + Time *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=time,proto3" json:"time,omitempty"` + // Relay path. + RelayPath []*MeshHeartbeatRelayPath `protobuf:"bytes,4,rep,name=relay_path,json=relayPath,proto3" json:"relay_path,omitempty"` +} + +func (x *MeshHeartbeat) Reset() { + *x = MeshHeartbeat{} + if protoimpl.UnsafeEnabled { + mi := &file_gw_gw_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MeshHeartbeat) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MeshHeartbeat) ProtoMessage() {} + +func (x *MeshHeartbeat) ProtoReflect() protoreflect.Message { + mi := &file_gw_gw_proto_msgTypes[35] + 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 MeshHeartbeat.ProtoReflect.Descriptor instead. +func (*MeshHeartbeat) Descriptor() ([]byte, []int) { + return file_gw_gw_proto_rawDescGZIP(), []int{35} +} + +func (x *MeshHeartbeat) GetGatewayId() string { + if x != nil { + return x.GatewayId + } + return "" +} + +func (x *MeshHeartbeat) GetRelayId() string { + if x != nil { + return x.RelayId + } + return "" +} + +func (x *MeshHeartbeat) GetTime() *timestamppb.Timestamp { + if x != nil { + return x.Time + } + return nil +} + +func (x *MeshHeartbeat) GetRelayPath() []*MeshHeartbeatRelayPath { + if x != nil { + return x.RelayPath + } + return nil +} + +type MeshHeartbeatRelayPath struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Relay ID. + RelayId string `protobuf:"bytes,1,opt,name=relay_id,json=relayId,proto3" json:"relay_id,omitempty"` + // RSSI. + Rssi int32 `protobuf:"varint,2,opt,name=rssi,proto3" json:"rssi,omitempty"` + // SNR. + Snr int32 `protobuf:"varint,3,opt,name=snr,proto3" json:"snr,omitempty"` +} + +func (x *MeshHeartbeatRelayPath) Reset() { + *x = MeshHeartbeatRelayPath{} + if protoimpl.UnsafeEnabled { + mi := &file_gw_gw_proto_msgTypes[36] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MeshHeartbeatRelayPath) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MeshHeartbeatRelayPath) ProtoMessage() {} + +func (x *MeshHeartbeatRelayPath) ProtoReflect() protoreflect.Message { + mi := &file_gw_gw_proto_msgTypes[36] + 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 MeshHeartbeatRelayPath.ProtoReflect.Descriptor instead. +func (*MeshHeartbeatRelayPath) Descriptor() ([]byte, []int) { + return file_gw_gw_proto_rawDescGZIP(), []int{36} +} + +func (x *MeshHeartbeatRelayPath) GetRelayId() string { + if x != nil { + return x.RelayId + } + return "" +} + +func (x *MeshHeartbeatRelayPath) GetRssi() int32 { + if x != nil { + return x.Rssi + } + return 0 +} + +func (x *MeshHeartbeatRelayPath) GetSnr() int32 { + if x != nil { + return x.Snr + } + return 0 +} + var File_gw_gw_proto protoreflect.FileDescriptor var file_gw_gw_proto_rawDesc = []byte{ @@ -4116,50 +4258,70 @@ var file_gw_gw_proto_rawDesc = []byte{ 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x20, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x4f, 0x46, 0x46, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x4f, 0x4e, 0x4c, - 0x49, 0x4e, 0x45, 0x10, 0x01, 0x2a, 0xb5, 0x01, 0x0a, 0x08, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x61, - 0x74, 0x65, 0x12, 0x10, 0x0a, 0x0c, 0x43, 0x52, 0x5f, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x49, 0x4e, - 0x45, 0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x52, 0x5f, 0x34, 0x5f, 0x35, 0x10, 0x01, - 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x52, 0x5f, 0x34, 0x5f, 0x36, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, - 0x43, 0x52, 0x5f, 0x34, 0x5f, 0x37, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x52, 0x5f, 0x34, - 0x5f, 0x38, 0x10, 0x04, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x52, 0x5f, 0x33, 0x5f, 0x38, 0x10, 0x05, - 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x52, 0x5f, 0x32, 0x5f, 0x36, 0x10, 0x06, 0x12, 0x0a, 0x0a, 0x06, - 0x43, 0x52, 0x5f, 0x31, 0x5f, 0x34, 0x10, 0x07, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x52, 0x5f, 0x31, - 0x5f, 0x36, 0x10, 0x08, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x52, 0x5f, 0x35, 0x5f, 0x36, 0x10, 0x09, - 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x52, 0x5f, 0x4c, 0x49, 0x5f, 0x34, 0x5f, 0x35, 0x10, 0x0a, 0x12, - 0x0d, 0x0a, 0x09, 0x43, 0x52, 0x5f, 0x4c, 0x49, 0x5f, 0x34, 0x5f, 0x36, 0x10, 0x0b, 0x12, 0x0d, - 0x0a, 0x09, 0x43, 0x52, 0x5f, 0x4c, 0x49, 0x5f, 0x34, 0x5f, 0x38, 0x10, 0x0c, 0x2a, 0x3b, 0x0a, - 0x0e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x12, - 0x0f, 0x0a, 0x0b, 0x49, 0x4d, 0x4d, 0x45, 0x44, 0x49, 0x41, 0x54, 0x45, 0x4c, 0x59, 0x10, 0x00, - 0x12, 0x09, 0x0a, 0x05, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x47, - 0x50, 0x53, 0x5f, 0x45, 0x50, 0x4f, 0x43, 0x48, 0x10, 0x02, 0x2a, 0x37, 0x0a, 0x11, 0x46, 0x69, - 0x6e, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x45, 0x4e, 0x43, - 0x52, 0x59, 0x50, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x50, 0x4c, 0x41, 0x49, - 0x4e, 0x10, 0x02, 0x2a, 0x30, 0x0a, 0x09, 0x43, 0x52, 0x43, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x0a, 0x0a, 0x06, 0x4e, 0x4f, 0x5f, 0x43, 0x52, 0x43, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, - 0x42, 0x41, 0x44, 0x5f, 0x43, 0x52, 0x43, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x52, 0x43, - 0x5f, 0x4f, 0x4b, 0x10, 0x02, 0x2a, 0xd5, 0x01, 0x0a, 0x0b, 0x54, 0x78, 0x41, 0x63, 0x6b, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x47, 0x4e, 0x4f, 0x52, 0x45, 0x44, - 0x10, 0x00, 0x12, 0x06, 0x0a, 0x02, 0x4f, 0x4b, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x54, 0x4f, - 0x4f, 0x5f, 0x4c, 0x41, 0x54, 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x4f, 0x4f, 0x5f, - 0x45, 0x41, 0x52, 0x4c, 0x59, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x43, 0x4f, 0x4c, 0x4c, 0x49, - 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x10, 0x04, 0x12, 0x14, 0x0a, - 0x10, 0x43, 0x4f, 0x4c, 0x4c, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x42, 0x45, 0x41, 0x43, 0x4f, - 0x4e, 0x10, 0x05, 0x12, 0x0b, 0x0a, 0x07, 0x54, 0x58, 0x5f, 0x46, 0x52, 0x45, 0x51, 0x10, 0x06, - 0x12, 0x0c, 0x0a, 0x08, 0x54, 0x58, 0x5f, 0x50, 0x4f, 0x57, 0x45, 0x52, 0x10, 0x07, 0x12, 0x10, - 0x0a, 0x0c, 0x47, 0x50, 0x53, 0x5f, 0x55, 0x4e, 0x4c, 0x4f, 0x43, 0x4b, 0x45, 0x44, 0x10, 0x08, - 0x12, 0x0e, 0x0a, 0x0a, 0x51, 0x55, 0x45, 0x55, 0x45, 0x5f, 0x46, 0x55, 0x4c, 0x4c, 0x10, 0x09, - 0x12, 0x12, 0x0a, 0x0e, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x10, 0x0a, 0x12, 0x17, 0x0a, 0x13, 0x44, 0x55, 0x54, 0x59, 0x5f, 0x43, 0x59, 0x43, - 0x4c, 0x45, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x10, 0x0b, 0x42, 0x6a, 0x0a, - 0x14, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x67, 0x77, 0x42, 0x0c, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x63, 0x68, 0x69, - 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x76, - 0x34, 0x2f, 0x67, 0x77, 0xaa, 0x02, 0x12, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, - 0x6b, 0x2e, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x49, 0x4e, 0x45, 0x10, 0x01, 0x22, 0xb4, 0x01, 0x0a, 0x0d, 0x4d, 0x65, 0x73, 0x68, 0x48, 0x65, + 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x61, 0x74, 0x65, 0x77, + 0x61, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x61, 0x74, + 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, + 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x49, + 0x64, 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, 0x39, 0x0a, 0x0a, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x77, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x48, + 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x50, 0x61, 0x74, + 0x68, 0x52, 0x09, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x50, 0x61, 0x74, 0x68, 0x22, 0x59, 0x0a, 0x16, + 0x4d, 0x65, 0x73, 0x68, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x52, 0x65, 0x6c, + 0x61, 0x79, 0x50, 0x61, 0x74, 0x68, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x49, + 0x64, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x73, 0x73, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x04, 0x72, 0x73, 0x73, 0x69, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x6e, 0x72, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x03, 0x73, 0x6e, 0x72, 0x2a, 0xb5, 0x01, 0x0a, 0x08, 0x43, 0x6f, 0x64, 0x65, + 0x52, 0x61, 0x74, 0x65, 0x12, 0x10, 0x0a, 0x0c, 0x43, 0x52, 0x5f, 0x55, 0x4e, 0x44, 0x45, 0x46, + 0x49, 0x4e, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x52, 0x5f, 0x34, 0x5f, 0x35, + 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x52, 0x5f, 0x34, 0x5f, 0x36, 0x10, 0x02, 0x12, 0x0a, + 0x0a, 0x06, 0x43, 0x52, 0x5f, 0x34, 0x5f, 0x37, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x52, + 0x5f, 0x34, 0x5f, 0x38, 0x10, 0x04, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x52, 0x5f, 0x33, 0x5f, 0x38, + 0x10, 0x05, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x52, 0x5f, 0x32, 0x5f, 0x36, 0x10, 0x06, 0x12, 0x0a, + 0x0a, 0x06, 0x43, 0x52, 0x5f, 0x31, 0x5f, 0x34, 0x10, 0x07, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x52, + 0x5f, 0x31, 0x5f, 0x36, 0x10, 0x08, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x52, 0x5f, 0x35, 0x5f, 0x36, + 0x10, 0x09, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x52, 0x5f, 0x4c, 0x49, 0x5f, 0x34, 0x5f, 0x35, 0x10, + 0x0a, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x52, 0x5f, 0x4c, 0x49, 0x5f, 0x34, 0x5f, 0x36, 0x10, 0x0b, + 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x52, 0x5f, 0x4c, 0x49, 0x5f, 0x34, 0x5f, 0x38, 0x10, 0x0c, 0x2a, + 0x3b, 0x0a, 0x0e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x54, 0x69, 0x6d, 0x69, 0x6e, + 0x67, 0x12, 0x0f, 0x0a, 0x0b, 0x49, 0x4d, 0x4d, 0x45, 0x44, 0x49, 0x41, 0x54, 0x45, 0x4c, 0x59, + 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x44, 0x45, 0x4c, 0x41, 0x59, 0x10, 0x01, 0x12, 0x0d, 0x0a, + 0x09, 0x47, 0x50, 0x53, 0x5f, 0x45, 0x50, 0x4f, 0x43, 0x48, 0x10, 0x02, 0x2a, 0x37, 0x0a, 0x11, + 0x46, 0x69, 0x6e, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x45, + 0x4e, 0x43, 0x52, 0x59, 0x50, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x50, 0x4c, + 0x41, 0x49, 0x4e, 0x10, 0x02, 0x2a, 0x30, 0x0a, 0x09, 0x43, 0x52, 0x43, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x0a, 0x0a, 0x06, 0x4e, 0x4f, 0x5f, 0x43, 0x52, 0x43, 0x10, 0x00, 0x12, 0x0b, + 0x0a, 0x07, 0x42, 0x41, 0x44, 0x5f, 0x43, 0x52, 0x43, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x43, + 0x52, 0x43, 0x5f, 0x4f, 0x4b, 0x10, 0x02, 0x2a, 0xd5, 0x01, 0x0a, 0x0b, 0x54, 0x78, 0x41, 0x63, + 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x47, 0x4e, 0x4f, 0x52, + 0x45, 0x44, 0x10, 0x00, 0x12, 0x06, 0x0a, 0x02, 0x4f, 0x4b, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, + 0x54, 0x4f, 0x4f, 0x5f, 0x4c, 0x41, 0x54, 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x4f, + 0x4f, 0x5f, 0x45, 0x41, 0x52, 0x4c, 0x59, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x43, 0x4f, 0x4c, + 0x4c, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x10, 0x04, 0x12, + 0x14, 0x0a, 0x10, 0x43, 0x4f, 0x4c, 0x4c, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x42, 0x45, 0x41, + 0x43, 0x4f, 0x4e, 0x10, 0x05, 0x12, 0x0b, 0x0a, 0x07, 0x54, 0x58, 0x5f, 0x46, 0x52, 0x45, 0x51, + 0x10, 0x06, 0x12, 0x0c, 0x0a, 0x08, 0x54, 0x58, 0x5f, 0x50, 0x4f, 0x57, 0x45, 0x52, 0x10, 0x07, + 0x12, 0x10, 0x0a, 0x0c, 0x47, 0x50, 0x53, 0x5f, 0x55, 0x4e, 0x4c, 0x4f, 0x43, 0x4b, 0x45, 0x44, + 0x10, 0x08, 0x12, 0x0e, 0x0a, 0x0a, 0x51, 0x55, 0x45, 0x55, 0x45, 0x5f, 0x46, 0x55, 0x4c, 0x4c, + 0x10, 0x09, 0x12, 0x12, 0x0a, 0x0e, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x5f, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x10, 0x0a, 0x12, 0x17, 0x0a, 0x13, 0x44, 0x55, 0x54, 0x59, 0x5f, 0x43, + 0x59, 0x43, 0x4c, 0x45, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x10, 0x0b, 0x42, + 0xa0, 0x01, 0x0a, 0x14, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, + 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x67, 0x77, 0x42, 0x0c, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, + 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, + 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, + 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x67, 0x77, 0xaa, 0x02, 0x12, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, + 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0xca, 0x02, 0x12, 0x43, + 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5c, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, + 0x79, 0xe2, 0x02, 0x1e, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5c, + 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5c, 0x47, 0x61, 0x74, 0x65, 0x77, + 0x61, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -4175,7 +4337,7 @@ func file_gw_gw_proto_rawDescGZIP() []byte { } var file_gw_gw_proto_enumTypes = make([]protoimpl.EnumInfo, 6) -var file_gw_gw_proto_msgTypes = make([]protoimpl.MessageInfo, 42) +var file_gw_gw_proto_msgTypes = make([]protoimpl.MessageInfo, 44) var file_gw_gw_proto_goTypes = []interface{}{ (CodeRate)(0), // 0: gw.CodeRate (DownlinkTiming)(0), // 1: gw.DownlinkTiming @@ -4218,62 +4380,64 @@ var file_gw_gw_proto_goTypes = []interface{}{ (*RawPacketForwarderEvent)(nil), // 38: gw.RawPacketForwarderEvent (*RawPacketForwarderCommand)(nil), // 39: gw.RawPacketForwarderCommand (*ConnState)(nil), // 40: gw.ConnState - nil, // 41: gw.GatewayStats.MetadataEntry - nil, // 42: gw.GatewayStats.TxPacketsPerFrequencyEntry - nil, // 43: gw.GatewayStats.RxPacketsPerFrequencyEntry - nil, // 44: gw.GatewayStats.TxPacketsPerStatusEntry - nil, // 45: gw.UplinkRxInfoLegacy.MetadataEntry - nil, // 46: gw.UplinkRxInfo.MetadataEntry - nil, // 47: gw.GatewayCommandExecRequest.EnvironmentEntry - (common.Modulation)(0), // 48: common.Modulation - (*timestamppb.Timestamp)(nil), // 49: google.protobuf.Timestamp - (*common.Location)(nil), // 50: common.Location - (common.Regulation)(0), // 51: common.Regulation - (*durationpb.Duration)(nil), // 52: google.protobuf.Duration + (*MeshHeartbeat)(nil), // 41: gw.MeshHeartbeat + (*MeshHeartbeatRelayPath)(nil), // 42: gw.MeshHeartbeatRelayPath + nil, // 43: gw.GatewayStats.MetadataEntry + nil, // 44: gw.GatewayStats.TxPacketsPerFrequencyEntry + nil, // 45: gw.GatewayStats.RxPacketsPerFrequencyEntry + nil, // 46: gw.GatewayStats.TxPacketsPerStatusEntry + nil, // 47: gw.UplinkRxInfoLegacy.MetadataEntry + nil, // 48: gw.UplinkRxInfo.MetadataEntry + nil, // 49: gw.GatewayCommandExecRequest.EnvironmentEntry + (common.Modulation)(0), // 50: common.Modulation + (*timestamppb.Timestamp)(nil), // 51: google.protobuf.Timestamp + (*common.Location)(nil), // 52: common.Location + (common.Regulation)(0), // 53: common.Regulation + (*durationpb.Duration)(nil), // 54: google.protobuf.Duration } var file_gw_gw_proto_depIdxs = []int32{ 9, // 0: gw.Modulation.lora:type_name -> gw.LoraModulationInfo 10, // 1: gw.Modulation.fsk:type_name -> gw.FskModulationInfo 11, // 2: gw.Modulation.lr_fhss:type_name -> gw.LrFhssModulationInfo - 48, // 3: gw.UplinkTxInfoLegacy.modulation:type_name -> common.Modulation + 50, // 3: gw.UplinkTxInfoLegacy.modulation:type_name -> common.Modulation 9, // 4: gw.UplinkTxInfoLegacy.lora_modulation_info:type_name -> gw.LoraModulationInfo 10, // 5: gw.UplinkTxInfoLegacy.fsk_modulation_info:type_name -> gw.FskModulationInfo 11, // 6: gw.UplinkTxInfoLegacy.lr_fhss_modulation_info:type_name -> gw.LrFhssModulationInfo 6, // 7: gw.UplinkTxInfo.modulation:type_name -> gw.Modulation 0, // 8: gw.LoraModulationInfo.code_rate:type_name -> gw.CodeRate 0, // 9: gw.LrFhssModulationInfo.code_rate:type_name -> gw.CodeRate - 49, // 10: gw.PlainFineTimestamp.time:type_name -> google.protobuf.Timestamp - 49, // 11: gw.GatewayStats.time:type_name -> google.protobuf.Timestamp - 50, // 12: gw.GatewayStats.location:type_name -> common.Location - 41, // 13: gw.GatewayStats.metadata:type_name -> gw.GatewayStats.MetadataEntry - 42, // 14: gw.GatewayStats.tx_packets_per_frequency:type_name -> gw.GatewayStats.TxPacketsPerFrequencyEntry - 43, // 15: gw.GatewayStats.rx_packets_per_frequency:type_name -> gw.GatewayStats.RxPacketsPerFrequencyEntry + 51, // 10: gw.PlainFineTimestamp.time:type_name -> google.protobuf.Timestamp + 51, // 11: gw.GatewayStats.time:type_name -> google.protobuf.Timestamp + 52, // 12: gw.GatewayStats.location:type_name -> common.Location + 43, // 13: gw.GatewayStats.metadata:type_name -> gw.GatewayStats.MetadataEntry + 44, // 14: gw.GatewayStats.tx_packets_per_frequency:type_name -> gw.GatewayStats.TxPacketsPerFrequencyEntry + 45, // 15: gw.GatewayStats.rx_packets_per_frequency:type_name -> gw.GatewayStats.RxPacketsPerFrequencyEntry 15, // 16: gw.GatewayStats.tx_packets_per_modulation:type_name -> gw.PerModulationCount 15, // 17: gw.GatewayStats.rx_packets_per_modulation:type_name -> gw.PerModulationCount - 44, // 18: gw.GatewayStats.tx_packets_per_status:type_name -> gw.GatewayStats.TxPacketsPerStatusEntry + 46, // 18: gw.GatewayStats.tx_packets_per_status:type_name -> gw.GatewayStats.TxPacketsPerStatusEntry 16, // 19: gw.GatewayStats.duty_cycle_stats:type_name -> gw.DutyCycleStats 6, // 20: gw.PerModulationCount.modulation:type_name -> gw.Modulation - 51, // 21: gw.DutyCycleStats.regulation:type_name -> common.Regulation - 52, // 22: gw.DutyCycleStats.window:type_name -> google.protobuf.Duration + 53, // 21: gw.DutyCycleStats.regulation:type_name -> common.Regulation + 54, // 22: gw.DutyCycleStats.window:type_name -> google.protobuf.Duration 17, // 23: gw.DutyCycleStats.bands:type_name -> gw.DutyCycleBand - 52, // 24: gw.DutyCycleBand.load_max:type_name -> google.protobuf.Duration - 52, // 25: gw.DutyCycleBand.load_tracked:type_name -> google.protobuf.Duration - 49, // 26: gw.UplinkRxInfoLegacy.time:type_name -> google.protobuf.Timestamp - 52, // 27: gw.UplinkRxInfoLegacy.time_since_gps_epoch:type_name -> google.protobuf.Duration - 50, // 28: gw.UplinkRxInfoLegacy.location:type_name -> common.Location + 54, // 24: gw.DutyCycleBand.load_max:type_name -> google.protobuf.Duration + 54, // 25: gw.DutyCycleBand.load_tracked:type_name -> google.protobuf.Duration + 51, // 26: gw.UplinkRxInfoLegacy.time:type_name -> google.protobuf.Timestamp + 54, // 27: gw.UplinkRxInfoLegacy.time_since_gps_epoch:type_name -> google.protobuf.Duration + 52, // 28: gw.UplinkRxInfoLegacy.location:type_name -> common.Location 2, // 29: gw.UplinkRxInfoLegacy.fine_timestamp_type:type_name -> gw.FineTimestampType 12, // 30: gw.UplinkRxInfoLegacy.encrypted_fine_timestamp:type_name -> gw.EncryptedFineTimestamp 13, // 31: gw.UplinkRxInfoLegacy.plain_fine_timestamp:type_name -> gw.PlainFineTimestamp 3, // 32: gw.UplinkRxInfoLegacy.crc_status:type_name -> gw.CRCStatus - 45, // 33: gw.UplinkRxInfoLegacy.metadata:type_name -> gw.UplinkRxInfoLegacy.MetadataEntry - 49, // 34: gw.UplinkRxInfo.gw_time:type_name -> google.protobuf.Timestamp - 49, // 35: gw.UplinkRxInfo.ns_time:type_name -> google.protobuf.Timestamp - 52, // 36: gw.UplinkRxInfo.time_since_gps_epoch:type_name -> google.protobuf.Duration - 52, // 37: gw.UplinkRxInfo.fine_time_since_gps_epoch:type_name -> google.protobuf.Duration - 50, // 38: gw.UplinkRxInfo.location:type_name -> common.Location - 46, // 39: gw.UplinkRxInfo.metadata:type_name -> gw.UplinkRxInfo.MetadataEntry + 47, // 33: gw.UplinkRxInfoLegacy.metadata:type_name -> gw.UplinkRxInfoLegacy.MetadataEntry + 51, // 34: gw.UplinkRxInfo.gw_time:type_name -> google.protobuf.Timestamp + 51, // 35: gw.UplinkRxInfo.ns_time:type_name -> google.protobuf.Timestamp + 54, // 36: gw.UplinkRxInfo.time_since_gps_epoch:type_name -> google.protobuf.Duration + 54, // 37: gw.UplinkRxInfo.fine_time_since_gps_epoch:type_name -> google.protobuf.Duration + 52, // 38: gw.UplinkRxInfo.location:type_name -> common.Location + 48, // 39: gw.UplinkRxInfo.metadata:type_name -> gw.UplinkRxInfo.MetadataEntry 3, // 40: gw.UplinkRxInfo.crc_status:type_name -> gw.CRCStatus - 48, // 41: gw.DownlinkTxInfoLegacy.modulation:type_name -> common.Modulation + 50, // 41: gw.DownlinkTxInfoLegacy.modulation:type_name -> common.Modulation 9, // 42: gw.DownlinkTxInfoLegacy.lora_modulation_info:type_name -> gw.LoraModulationInfo 10, // 43: gw.DownlinkTxInfoLegacy.fsk_modulation_info:type_name -> gw.FskModulationInfo 1, // 44: gw.DownlinkTxInfoLegacy.timing:type_name -> gw.DownlinkTiming @@ -4285,8 +4449,8 @@ var file_gw_gw_proto_depIdxs = []int32{ 23, // 50: gw.Timing.immediately:type_name -> gw.ImmediatelyTimingInfo 24, // 51: gw.Timing.delay:type_name -> gw.DelayTimingInfo 25, // 52: gw.Timing.gps_epoch:type_name -> gw.GPSEpochTimingInfo - 52, // 53: gw.DelayTimingInfo.delay:type_name -> google.protobuf.Duration - 52, // 54: gw.GPSEpochTimingInfo.time_since_gps_epoch:type_name -> google.protobuf.Duration + 54, // 53: gw.DelayTimingInfo.delay:type_name -> google.protobuf.Duration + 54, // 54: gw.GPSEpochTimingInfo.time_since_gps_epoch:type_name -> google.protobuf.Duration 7, // 55: gw.UplinkFrame.tx_info_legacy:type_name -> gw.UplinkTxInfoLegacy 18, // 56: gw.UplinkFrame.rx_info_legacy:type_name -> gw.UplinkRxInfoLegacy 8, // 57: gw.UplinkFrame.tx_info:type_name -> gw.UplinkTxInfo @@ -4299,17 +4463,19 @@ var file_gw_gw_proto_depIdxs = []int32{ 31, // 64: gw.DownlinkTxAck.items:type_name -> gw.DownlinkTxAckItem 4, // 65: gw.DownlinkTxAckItem.status:type_name -> gw.TxAckStatus 33, // 66: gw.GatewayConfiguration.channels:type_name -> gw.ChannelConfiguration - 52, // 67: gw.GatewayConfiguration.stats_interval:type_name -> google.protobuf.Duration - 48, // 68: gw.ChannelConfiguration.modulation_legacy:type_name -> common.Modulation + 54, // 67: gw.GatewayConfiguration.stats_interval:type_name -> google.protobuf.Duration + 50, // 68: gw.ChannelConfiguration.modulation_legacy:type_name -> common.Modulation 34, // 69: gw.ChannelConfiguration.lora_modulation_config:type_name -> gw.LoraModulationConfig 35, // 70: gw.ChannelConfiguration.fsk_modulation_config:type_name -> gw.FskModulationConfig - 47, // 71: gw.GatewayCommandExecRequest.environment:type_name -> gw.GatewayCommandExecRequest.EnvironmentEntry + 49, // 71: gw.GatewayCommandExecRequest.environment:type_name -> gw.GatewayCommandExecRequest.EnvironmentEntry 5, // 72: gw.ConnState.state:type_name -> gw.ConnState.State - 73, // [73:73] is the sub-list for method output_type - 73, // [73:73] is the sub-list for method input_type - 73, // [73:73] is the sub-list for extension type_name - 73, // [73:73] is the sub-list for extension extendee - 0, // [0:73] is the sub-list for field type_name + 51, // 73: gw.MeshHeartbeat.time:type_name -> google.protobuf.Timestamp + 42, // 74: gw.MeshHeartbeat.relay_path:type_name -> gw.MeshHeartbeatRelayPath + 75, // [75:75] is the sub-list for method output_type + 75, // [75:75] is the sub-list for method input_type + 75, // [75:75] is the sub-list for extension type_name + 75, // [75:75] is the sub-list for extension extendee + 0, // [0:75] is the sub-list for field type_name } func init() { file_gw_gw_proto_init() } @@ -4738,6 +4904,30 @@ func file_gw_gw_proto_init() { return nil } } + file_gw_gw_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MeshHeartbeat); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gw_gw_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MeshHeartbeatRelayPath); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } file_gw_gw_proto_msgTypes[0].OneofWrappers = []interface{}{ (*Modulation_Lora)(nil), @@ -4775,7 +4965,7 @@ func file_gw_gw_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_gw_gw_proto_rawDesc, NumEnums: 6, - NumMessages: 42, + NumMessages: 44, NumExtensions: 0, NumServices: 0, }, diff --git a/api/go/integration/integration.pb.go b/api/go/integration/integration.pb.go index d019355a..5d6ae9be 100644 --- a/api/go/integration/integration.pb.go +++ b/api/go/integration/integration.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.34.1 // protoc v4.24.4 // source: integration/integration.proto @@ -1581,7 +1581,7 @@ var file_integration_integration_proto_rawDesc = []byte{ 0x4c, 0x49, 0x4e, 0x4b, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x10, 0x08, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x45, 0x4c, 0x41, 0x59, 0x5f, 0x4e, 0x45, 0x57, 0x5f, 0x45, 0x4e, 0x44, 0x5f, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x10, 0x09, 0x12, 0x0e, 0x0a, 0x0a, 0x46, 0x5f, 0x43, 0x4e, - 0x54, 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x0a, 0x42, 0x81, 0x01, 0x0a, 0x1d, 0x69, 0x6f, 0x2e, + 0x54, 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x0a, 0x42, 0xbf, 0x01, 0x0a, 0x1d, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x10, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x33, @@ -1589,8 +1589,12 @@ var file_integration_integration_proto_rawDesc = []byte{ 0x61, 0x72, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0xaa, 0x02, 0x16, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, - 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0xca, 0x02, 0x16, 0x43, + 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5c, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0xe2, 0x02, 0x22, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x5c, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5c, 0x49, + 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( diff --git a/api/go/stream/api_request.pb.go b/api/go/stream/api_request.pb.go index 5b6700a4..c4977bf8 100644 --- a/api/go/stream/api_request.pb.go +++ b/api/go/stream/api_request.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.34.1 // protoc v4.24.4 // source: stream/api_request.proto @@ -110,15 +110,18 @@ var file_stream_api_request_proto_rawDesc = []byte{ 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 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, 0x42, 0x74, 0x0a, 0x18, 0x69, 0x6f, 0x2e, 0x63, 0x68, - 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x42, 0x0f, 0x41, 0x70, 0x69, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x63, 0x68, - 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, 0x2f, - 0x76, 0x34, 0x2f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xaa, 0x02, 0x11, 0x43, 0x68, 0x69, 0x72, - 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0xa8, 0x01, 0x0a, 0x18, 0x69, 0x6f, 0x2e, 0x63, + 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x42, 0x0f, 0x41, 0x70, 0x69, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x63, + 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, + 0x2f, 0x76, 0x34, 0x2f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xaa, 0x02, 0x11, 0x43, 0x68, 0x69, + 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xca, 0x02, + 0x11, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5c, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0xe2, 0x02, 0x1d, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x5c, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5c, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/go/stream/backend_interfaces.pb.go b/api/go/stream/backend_interfaces.pb.go index 0b7513ea..89d17ae2 100644 --- a/api/go/stream/backend_interfaces.pb.go +++ b/api/go/stream/backend_interfaces.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.34.1 // protoc v4.24.4 // source: stream/backend_interfaces.proto @@ -170,16 +170,19 @@ var file_stream_backend_interfaces_proto_rawDesc = []byte{ 0x72, 0x72, 0x6f, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0c, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x6f, 0x64, 0x79, 0x42, 0x7b, 0x0a, - 0x18, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x42, 0x16, 0x42, 0x61, 0x63, 0x6b, 0x65, - 0x6e, 0x64, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x50, 0x01, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, - 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x34, 0x2f, - 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xaa, 0x02, 0x11, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, - 0x61, 0x63, 0x6b, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x0c, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x6f, 0x64, 0x79, 0x42, 0xaf, 0x01, + 0x0a, 0x18, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x42, 0x16, 0x42, 0x61, 0x63, 0x6b, + 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x63, 0x68, 0x69, 0x72, + 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x34, + 0x2f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xaa, 0x02, 0x11, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, + 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xca, 0x02, 0x11, 0x43, 0x68, + 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5c, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xe2, + 0x02, 0x1d, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5c, 0x43, 0x68, + 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5c, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/go/stream/frame.pb.go b/api/go/stream/frame.pb.go index d04c2f89..7964f3d8 100644 --- a/api/go/stream/frame.pb.go +++ b/api/go/stream/frame.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.34.1 // protoc v4.24.4 // source: stream/frame.proto @@ -328,15 +328,18 @@ var file_stream_frame_proto_rawDesc = []byte{ 0x65, 0x78, 0x74, 0x46, 0x4f, 0x70, 0x74, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x66, 0x72, 0x6d, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x65, - 0x78, 0x74, 0x46, 0x72, 0x6d, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x6f, 0x0a, 0x18, - 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70, - 0x69, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x42, 0x0a, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x63, 0x68, - 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, 0x2f, - 0x76, 0x34, 0x2f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xaa, 0x02, 0x11, 0x43, 0x68, 0x69, 0x72, - 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x78, 0x74, 0x46, 0x72, 0x6d, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0xa3, 0x01, 0x0a, + 0x18, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x42, 0x0a, 0x46, 0x72, 0x61, 0x6d, 0x65, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x63, + 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, + 0x2f, 0x76, 0x34, 0x2f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xaa, 0x02, 0x11, 0x43, 0x68, 0x69, + 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xca, 0x02, + 0x11, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5c, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0xe2, 0x02, 0x1d, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x5c, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5c, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/go/stream/meta.pb.go b/api/go/stream/meta.pb.go index 63d458e2..7ccc4ec8 100644 --- a/api/go/stream/meta.pb.go +++ b/api/go/stream/meta.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.34.1 // protoc v4.24.4 // source: stream/meta.proto @@ -288,14 +288,17 @@ var file_stream_meta_proto_rawDesc = []byte{ 0x4d, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, - 0x64, 0x42, 0x6e, 0x0a, 0x18, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, - 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x42, 0x09, 0x4d, - 0x65, 0x74, 0x61, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, - 0x6b, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, 0x69, - 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xaa, 0x02, 0x11, - 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x64, 0x42, 0xa2, 0x01, 0x0a, 0x18, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, + 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x42, 0x09, + 0x4d, 0x65, 0x74, 0x61, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x31, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, + 0x63, 0x6b, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xaa, 0x02, + 0x11, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0xca, 0x02, 0x11, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5c, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xe2, 0x02, 0x1d, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x5c, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5c, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/grpc-web/package.json b/api/grpc-web/package.json index 662997de..bee25f39 100644 --- a/api/grpc-web/package.json +++ b/api/grpc-web/package.json @@ -1,6 +1,6 @@ { "name": "@chirpstack/chirpstack-api-grpc-web", - "version": "4.8.1", + "version": "4.9.0-test.1", "description": "Chirpstack gRPC-web API", "license": "MIT", "devDependencies": { diff --git a/api/java/build.gradle.kts b/api/java/build.gradle.kts index 10bb1376..7c4ab507 100644 --- a/api/java/build.gradle.kts +++ b/api/java/build.gradle.kts @@ -8,7 +8,7 @@ plugins { } group = "io.chirpstack" -version = "4.8.1" +version = "4.9.0-test.1" repositories { mavenCentral() diff --git a/api/js/package.json b/api/js/package.json index 08a18b5b..c629064c 100644 --- a/api/js/package.json +++ b/api/js/package.json @@ -1,6 +1,6 @@ { "name": "@chirpstack/chirpstack-api", - "version": "4.8.1", + "version": "4.9.0-test.1", "description": "Chirpstack JS and TS API", "license": "MIT", "devDependencies": { diff --git a/api/kotlin/build.gradle.kts b/api/kotlin/build.gradle.kts index c4925f02..7756a4f4 100644 --- a/api/kotlin/build.gradle.kts +++ b/api/kotlin/build.gradle.kts @@ -9,7 +9,7 @@ plugins { } group = "io.chirpstack" -version = "4.8.1" +version = "4.9.0-test.1" repositories { mavenCentral() diff --git a/api/proto/api/gateway.proto b/api/proto/api/gateway.proto index 024d5f3e..480391cc 100644 --- a/api/proto/api/gateway.proto +++ b/api/proto/api/gateway.proto @@ -75,6 +75,35 @@ service GatewayService { get: "/api/gateways/{gateway_id}/duty-cycle-metrics" }; } + + // Get the given Relay Gateway. + rpc GetRelayGateway(GetRelayGatewayRequest) returns (GetRelayGatewayResponse) { + option(google.api.http) = { + get: "/api/gateways/relay-gateways/{tenant_id}/{relay_id}" + }; + } + + // List the detected Relay Gateways. + rpc ListRelayGateways(ListRelayGatewaysRequest) returns (ListRelayGatewaysResponse) { + option(google.api.http) = { + get: "/api/gateways/relay-gateways" + }; + } + + // Update the given Relay Gateway. + rpc UpdateRelayGateway(UpdateRelayGatewayRequest) returns (google.protobuf.Empty) { + option(google.api.http) = { + put: "/api/gateways/relay-gateways/{relay_gateway.tenant_id}/{relay_gateway.relay_id}" + body: "*" + }; + } + + // Delete the given Relay Gateway. + rpc DeleteRelayGateway(DeleteRelayGatewayRequest) returns (google.protobuf.Empty) { + option(google.api.http) = { + delete: "/api/gateways/relay-gateways/{tenant_id}/{relay_id}" + }; + } } enum GatewayState { @@ -135,11 +164,11 @@ message GatewayListItem { // Gateway properties. map properties = 6; - // Created at timestamp. - google.protobuf.Timestamp created_at = 7; + // Created at timestamp. + google.protobuf.Timestamp created_at = 7; - // Last update timestamp. - google.protobuf.Timestamp updated_at = 8; + // Last update timestamp. + google.protobuf.Timestamp updated_at = 8; // Last seen at timestamp. google.protobuf.Timestamp last_seen_at = 9; @@ -284,3 +313,111 @@ message GetGatewayDutyCycleMetricsResponse { // Percentage relative to tracking window. common.Metric window_percentage = 2; } + +message GetRelayGatewayRequest { + // Tenant ID (UUID). + string tenant_id = 1; + + // Relay ID (4 byte HEX). + string relay_id = 2; +} + +message GetRelayGatewayResponse { + // Relay Gateway object. + RelayGateway relay_gateway = 1; + + // Created at timestamp. + google.protobuf.Timestamp created_at = 2; + + // Last update timestamp. + google.protobuf.Timestamp updated_at = 3; + + // Last seen at timestamp. + google.protobuf.Timestamp last_seen_at = 4; +} + +message ListRelayGatewaysRequest { + // Max number of relay-gateways to return in the result-set. + uint32 limit = 1; + + // Offset in the result-set (for pagination). + uint32 offset = 2; + + // Tenant ID (UUID) to filter relay-gateways on. + // To list all relay-gateways as a global admin user, this field can be left blank. + string tenant_id = 3; +} + +message ListRelayGatewaysResponse { + // Total number of relay-gateways. + uint32 total_count = 1; + + // Result-set. + repeated RelayGatewayListItem result = 2; +} + +message RelayGatewayListItem { + // Tenant ID. + string tenant_id = 1; + + // Relay ID (4 byte HEX). + string relay_id = 2; + + // Name. + string name = 3; + + // Description. + string description = 4; + + // Created at timestamp. + google.protobuf.Timestamp created_at = 5; + + // Last update timestamp. + google.protobuf.Timestamp updated_at = 6; + + // Last seen at timestamp. + google.protobuf.Timestamp last_seen_at = 7; + + // Gateway state. + // Please note that the state of the relay is driven by the last + // received stats packet sent by the relay-gateway. + GatewayState state = 10; + + // Region configuration ID. + string region_config_id = 11; +} + +message UpdateRelayGatewayRequest { + // Relay Gateway object. + RelayGateway relay_gateway = 1; +} + +message DeleteRelayGatewayRequest { + // Tenant ID. + string tenant_id = 1; + + // Relay ID (4 byte HEX). + string relay_id = 2; +} + +message RelayGateway { + // Tenant ID. + string tenant_id = 1; + + // Relay ID (4 byte HEX). + string relay_id = 2; + + // Name. + string name = 3; + + // Description. + string description = 4; + + // Stats interval (seconds). + // This defines the expected interval in which the gateway sends its + // statistics. + uint32 stats_interval = 5; + + // Region configuration ID. + string region_config_id = 6; +} diff --git a/api/proto/gw/gw.proto b/api/proto/gw/gw.proto index 03e8f7f9..490b77a5 100644 --- a/api/proto/gw/gw.proto +++ b/api/proto/gw/gw.proto @@ -749,3 +749,29 @@ message ConnState { State state = 2; } + +// Gateway Mesh heartbeat (sent periodically by the Relay Gateways). +message MeshHeartbeat { + // Gateway ID (of the Border Gateway). + string gateway_id = 1; + + // Relay ID. + string relay_id = 2; + + // Timestamp (second precision). + google.protobuf.Timestamp time = 3; + + // Relay path. + repeated MeshHeartbeatRelayPath relay_path = 4; +} + +message MeshHeartbeatRelayPath { + // Relay ID. + string relay_id = 1; + + // RSSI. + int32 rssi = 2; + + // SNR. + int32 snr = 3; +} diff --git a/api/python/src/setup.py b/api/python/src/setup.py index 2ef83509..460db6b8 100644 --- a/api/python/src/setup.py +++ b/api/python/src/setup.py @@ -18,7 +18,7 @@ CLASSIFIERS = [ setup( name='chirpstack-api', - version = "4.8.1.post1", + version = "4.9.0-test.1", url='https://github.com/brocaar/chirpstack-api', author='Orne Brocaar', author_email='info@brocaar.com', diff --git a/api/rust/Cargo.toml b/api/rust/Cargo.toml index e249b4af..5192c4c3 100644 --- a/api/rust/Cargo.toml +++ b/api/rust/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "chirpstack_api" description = "ChirpStack Protobuf / gRPC API definitions." -version = "4.8.1" +version = "4.9.0-test.1" authors = ["Orne Brocaar "] license = "MIT" homepage = "https://www.chirpstack.io" diff --git a/api/rust/proto/chirpstack/api/application.proto b/api/rust/proto/chirpstack/api/application.proto index ca09c6a1..24397d79 100644 --- a/api/rust/proto/chirpstack/api/application.proto +++ b/api/rust/proto/chirpstack/api/application.proto @@ -7,6 +7,8 @@ option java_package = "io.chirpstack.api"; option java_multiple_files = true; option java_outer_classname = "ApplicationProto"; option csharp_namespace = "Chirpstack.Api"; +option php_namespace = "Chirpstack\\Api"; +option php_metadata_namespace = "GPBMetadata\\Chirpstack\\Api"; import "google/api/annotations.proto"; import "google/protobuf/timestamp.proto"; diff --git a/api/rust/proto/chirpstack/api/device.proto b/api/rust/proto/chirpstack/api/device.proto index ad1bafb7..f80a2f15 100644 --- a/api/rust/proto/chirpstack/api/device.proto +++ b/api/rust/proto/chirpstack/api/device.proto @@ -7,6 +7,8 @@ option java_package = "io.chirpstack.api"; option java_multiple_files = true; option java_outer_classname = "DeviceProto"; option csharp_namespace = "Chirpstack.Api"; +option php_namespace = "Chirpstack\\Api"; +option php_metadata_namespace = "GPBMetadata\\Chirpstack\\Api"; import "common/common.proto"; import "google/api/annotations.proto"; diff --git a/api/rust/proto/chirpstack/api/device_profile.proto b/api/rust/proto/chirpstack/api/device_profile.proto index 0d6b3823..102dcc2c 100644 --- a/api/rust/proto/chirpstack/api/device_profile.proto +++ b/api/rust/proto/chirpstack/api/device_profile.proto @@ -7,6 +7,8 @@ option java_package = "io.chirpstack.api"; option java_multiple_files = true; option java_outer_classname = "DeviceProfileProto"; option csharp_namespace = "Chirpstack.Api"; +option php_namespace = "Chirpstack\\Api"; +option php_metadata_namespace = "GPBMetadata\\Chirpstack\\Api"; import "google/api/annotations.proto"; import "google/protobuf/timestamp.proto"; diff --git a/api/rust/proto/chirpstack/api/device_profile_template.proto b/api/rust/proto/chirpstack/api/device_profile_template.proto index 1f28a5d7..c302dd02 100644 --- a/api/rust/proto/chirpstack/api/device_profile_template.proto +++ b/api/rust/proto/chirpstack/api/device_profile_template.proto @@ -7,6 +7,8 @@ option java_package = "io.chirpstack.api"; option java_multiple_files = true; option java_outer_classname = "DeviceProfileTemplateProto"; option csharp_namespace = "Chirpstack.Api"; +option php_namespace = "Chirpstack\\Api"; +option php_metadata_namespace = "GPBMetadata\\Chirpstack\\Api"; import "google/api/annotations.proto"; import "google/protobuf/timestamp.proto"; diff --git a/api/rust/proto/chirpstack/api/gateway.proto b/api/rust/proto/chirpstack/api/gateway.proto index 1d007144..480391cc 100644 --- a/api/rust/proto/chirpstack/api/gateway.proto +++ b/api/rust/proto/chirpstack/api/gateway.proto @@ -7,6 +7,8 @@ option java_package = "io.chirpstack.api"; option java_multiple_files = true; option java_outer_classname = "GatewayProto"; option csharp_namespace = "Chirpstack.Api"; +option php_namespace = "Chirpstack\\Api"; +option php_metadata_namespace = "GPBMetadata\\Chirpstack\\Api"; import "google/api/annotations.proto"; import "google/protobuf/timestamp.proto"; @@ -73,6 +75,35 @@ service GatewayService { get: "/api/gateways/{gateway_id}/duty-cycle-metrics" }; } + + // Get the given Relay Gateway. + rpc GetRelayGateway(GetRelayGatewayRequest) returns (GetRelayGatewayResponse) { + option(google.api.http) = { + get: "/api/gateways/relay-gateways/{tenant_id}/{relay_id}" + }; + } + + // List the detected Relay Gateways. + rpc ListRelayGateways(ListRelayGatewaysRequest) returns (ListRelayGatewaysResponse) { + option(google.api.http) = { + get: "/api/gateways/relay-gateways" + }; + } + + // Update the given Relay Gateway. + rpc UpdateRelayGateway(UpdateRelayGatewayRequest) returns (google.protobuf.Empty) { + option(google.api.http) = { + put: "/api/gateways/relay-gateways/{relay_gateway.tenant_id}/{relay_gateway.relay_id}" + body: "*" + }; + } + + // Delete the given Relay Gateway. + rpc DeleteRelayGateway(DeleteRelayGatewayRequest) returns (google.protobuf.Empty) { + option(google.api.http) = { + delete: "/api/gateways/relay-gateways/{tenant_id}/{relay_id}" + }; + } } enum GatewayState { @@ -133,11 +164,11 @@ message GatewayListItem { // Gateway properties. map properties = 6; - // Created at timestamp. - google.protobuf.Timestamp created_at = 7; + // Created at timestamp. + google.protobuf.Timestamp created_at = 7; - // Last update timestamp. - google.protobuf.Timestamp updated_at = 8; + // Last update timestamp. + google.protobuf.Timestamp updated_at = 8; // Last seen at timestamp. google.protobuf.Timestamp last_seen_at = 9; @@ -282,3 +313,111 @@ message GetGatewayDutyCycleMetricsResponse { // Percentage relative to tracking window. common.Metric window_percentage = 2; } + +message GetRelayGatewayRequest { + // Tenant ID (UUID). + string tenant_id = 1; + + // Relay ID (4 byte HEX). + string relay_id = 2; +} + +message GetRelayGatewayResponse { + // Relay Gateway object. + RelayGateway relay_gateway = 1; + + // Created at timestamp. + google.protobuf.Timestamp created_at = 2; + + // Last update timestamp. + google.protobuf.Timestamp updated_at = 3; + + // Last seen at timestamp. + google.protobuf.Timestamp last_seen_at = 4; +} + +message ListRelayGatewaysRequest { + // Max number of relay-gateways to return in the result-set. + uint32 limit = 1; + + // Offset in the result-set (for pagination). + uint32 offset = 2; + + // Tenant ID (UUID) to filter relay-gateways on. + // To list all relay-gateways as a global admin user, this field can be left blank. + string tenant_id = 3; +} + +message ListRelayGatewaysResponse { + // Total number of relay-gateways. + uint32 total_count = 1; + + // Result-set. + repeated RelayGatewayListItem result = 2; +} + +message RelayGatewayListItem { + // Tenant ID. + string tenant_id = 1; + + // Relay ID (4 byte HEX). + string relay_id = 2; + + // Name. + string name = 3; + + // Description. + string description = 4; + + // Created at timestamp. + google.protobuf.Timestamp created_at = 5; + + // Last update timestamp. + google.protobuf.Timestamp updated_at = 6; + + // Last seen at timestamp. + google.protobuf.Timestamp last_seen_at = 7; + + // Gateway state. + // Please note that the state of the relay is driven by the last + // received stats packet sent by the relay-gateway. + GatewayState state = 10; + + // Region configuration ID. + string region_config_id = 11; +} + +message UpdateRelayGatewayRequest { + // Relay Gateway object. + RelayGateway relay_gateway = 1; +} + +message DeleteRelayGatewayRequest { + // Tenant ID. + string tenant_id = 1; + + // Relay ID (4 byte HEX). + string relay_id = 2; +} + +message RelayGateway { + // Tenant ID. + string tenant_id = 1; + + // Relay ID (4 byte HEX). + string relay_id = 2; + + // Name. + string name = 3; + + // Description. + string description = 4; + + // Stats interval (seconds). + // This defines the expected interval in which the gateway sends its + // statistics. + uint32 stats_interval = 5; + + // Region configuration ID. + string region_config_id = 6; +} diff --git a/api/rust/proto/chirpstack/api/internal.proto b/api/rust/proto/chirpstack/api/internal.proto index d033e252..49f68f11 100644 --- a/api/rust/proto/chirpstack/api/internal.proto +++ b/api/rust/proto/chirpstack/api/internal.proto @@ -7,6 +7,8 @@ option java_package = "io.chirpstack.api"; option java_multiple_files = true; option java_outer_classname = "InternalProto"; option csharp_namespace = "Chirpstack.Api"; +option php_namespace = "Chirpstack\\Api"; +option php_metadata_namespace = "GPBMetadata\\Chirpstack\\Api"; import "google/protobuf/timestamp.proto"; import "google/protobuf/empty.proto"; diff --git a/api/rust/proto/chirpstack/api/multicast_group.proto b/api/rust/proto/chirpstack/api/multicast_group.proto index 7548e046..92104e0f 100644 --- a/api/rust/proto/chirpstack/api/multicast_group.proto +++ b/api/rust/proto/chirpstack/api/multicast_group.proto @@ -7,6 +7,8 @@ option java_package = "io.chirpstack.api"; option java_multiple_files = true; option java_outer_classname = "MulticastGroupProto"; option csharp_namespace = "Chirpstack.Api"; +option php_namespace = "Chirpstack\\Api"; +option php_metadata_namespace = "GPBMetadata\\Chirpstack\\Api"; import "google/api/annotations.proto"; import "google/protobuf/timestamp.proto"; diff --git a/api/rust/proto/chirpstack/api/relay.proto b/api/rust/proto/chirpstack/api/relay.proto index 2a29073f..fa12800b 100644 --- a/api/rust/proto/chirpstack/api/relay.proto +++ b/api/rust/proto/chirpstack/api/relay.proto @@ -7,6 +7,8 @@ option java_package = "io.chirpstack.api"; option java_multiple_files = true; option java_outer_classname = "RelayProto"; option csharp_namespace = "Chirpstack.Api"; +option php_namespace = "Chirpstack\\Api"; +option php_metadata_namespace = "GPBMetadata\\Chirpstack\\Api"; import "google/api/annotations.proto"; import "google/protobuf/timestamp.proto"; diff --git a/api/rust/proto/chirpstack/api/tenant.proto b/api/rust/proto/chirpstack/api/tenant.proto index e1a20f30..b3f48983 100644 --- a/api/rust/proto/chirpstack/api/tenant.proto +++ b/api/rust/proto/chirpstack/api/tenant.proto @@ -7,6 +7,8 @@ option java_package = "io.chirpstack.api"; option java_multiple_files = true; option java_outer_classname = "TenantProto"; option csharp_namespace = "Chirpstack.Api"; +option php_namespace = "Chirpstack\\Api"; +option php_metadata_namespace = "GPBMetadata\\Chirpstack\\Api"; import "google/api/annotations.proto"; import "google/protobuf/timestamp.proto"; diff --git a/api/rust/proto/chirpstack/api/user.proto b/api/rust/proto/chirpstack/api/user.proto index 68a51a5a..4b92f663 100644 --- a/api/rust/proto/chirpstack/api/user.proto +++ b/api/rust/proto/chirpstack/api/user.proto @@ -7,6 +7,8 @@ option java_package = "io.chirpstack.api"; option java_multiple_files = true; option java_outer_classname = "UserProto"; option csharp_namespace = "Chirpstack.Api"; +option php_namespace = "Chirpstack\\Api"; +option php_metadata_namespace = "GPBMetadata\\Chirpstack\\Api"; import "google/api/annotations.proto"; import "google/protobuf/timestamp.proto"; diff --git a/api/rust/proto/chirpstack/common/common.proto b/api/rust/proto/chirpstack/common/common.proto index 1a9a290e..ceb08aed 100644 --- a/api/rust/proto/chirpstack/common/common.proto +++ b/api/rust/proto/chirpstack/common/common.proto @@ -7,6 +7,8 @@ option java_package = "io.chirpstack.api"; option java_multiple_files = true; option java_outer_classname = "CommonProto"; option csharp_namespace = "Chirpstack.Common"; +option php_namespace = "Chirpstack\\Common"; +option php_metadata_namespace = "GPBMetadata\\Chirpstack\\Common"; import "google/protobuf/timestamp.proto"; diff --git a/api/rust/proto/chirpstack/gw/gw.proto b/api/rust/proto/chirpstack/gw/gw.proto index 9acf6128..490b77a5 100644 --- a/api/rust/proto/chirpstack/gw/gw.proto +++ b/api/rust/proto/chirpstack/gw/gw.proto @@ -7,6 +7,8 @@ option java_package = "io.chirpstack.api.gw"; option java_multiple_files = true; option java_outer_classname = "GatewayProto"; option csharp_namespace = "Chirpstack.Gateway"; +option php_namespace = "Chirpstack\\Gateway"; +option php_metadata_namespace = "GPBMetadata\\Chirpstack\\Gateway"; import "common/common.proto"; import "google/protobuf/timestamp.proto"; @@ -747,3 +749,29 @@ message ConnState { State state = 2; } + +// Gateway Mesh heartbeat (sent periodically by the Relay Gateways). +message MeshHeartbeat { + // Gateway ID (of the Border Gateway). + string gateway_id = 1; + + // Relay ID. + string relay_id = 2; + + // Timestamp (second precision). + google.protobuf.Timestamp time = 3; + + // Relay path. + repeated MeshHeartbeatRelayPath relay_path = 4; +} + +message MeshHeartbeatRelayPath { + // Relay ID. + string relay_id = 1; + + // RSSI. + int32 rssi = 2; + + // SNR. + int32 snr = 3; +} diff --git a/api/rust/proto/chirpstack/integration/integration.proto b/api/rust/proto/chirpstack/integration/integration.proto index 77e3b8e0..c96d32d9 100644 --- a/api/rust/proto/chirpstack/integration/integration.proto +++ b/api/rust/proto/chirpstack/integration/integration.proto @@ -7,6 +7,8 @@ option java_package = "io.chirpstack.api.integration"; option java_multiple_files = true; option java_outer_classname = "IntegrationProto"; option csharp_namespace = "Chirpstack.Integration"; +option php_namespace = "Chirpstack\\Integration"; +option php_metadata_namespace = "GPBMetadata\\Chirpstack\\Integration"; import "common/common.proto"; import "gw/gw.proto"; diff --git a/api/rust/proto/chirpstack/stream/api_request.proto b/api/rust/proto/chirpstack/stream/api_request.proto index dd2d80e3..765da729 100644 --- a/api/rust/proto/chirpstack/stream/api_request.proto +++ b/api/rust/proto/chirpstack/stream/api_request.proto @@ -7,6 +7,8 @@ option java_package = "io.chirpstack.api.stream"; option java_multiple_files = true; option java_outer_classname = "ApiRequestProto"; option csharp_namespace = "Chirpstack.Stream"; +option php_namespace = "Chirpstack\\Stream"; +option php_metadata_namespace = "GPBMetadata\\Chirpstack\\Stream"; import "google/protobuf/timestamp.proto"; import "common/common.proto"; diff --git a/api/rust/proto/chirpstack/stream/backend_interfaces.proto b/api/rust/proto/chirpstack/stream/backend_interfaces.proto index ca0957b4..cb59d510 100644 --- a/api/rust/proto/chirpstack/stream/backend_interfaces.proto +++ b/api/rust/proto/chirpstack/stream/backend_interfaces.proto @@ -7,6 +7,8 @@ option java_package = "io.chirpstack.api.stream"; option java_multiple_files = true; option java_outer_classname = "BackendInterfacesProto"; option csharp_namespace = "Chirpstack.Stream"; +option php_namespace = "Chirpstack\\Stream"; +option php_metadata_namespace = "GPBMetadata\\Chirpstack\\Stream"; import "google/protobuf/timestamp.proto"; diff --git a/api/rust/proto/chirpstack/stream/frame.proto b/api/rust/proto/chirpstack/stream/frame.proto index 509e1e8b..75ebe20c 100644 --- a/api/rust/proto/chirpstack/stream/frame.proto +++ b/api/rust/proto/chirpstack/stream/frame.proto @@ -7,6 +7,8 @@ option java_package = "io.chirpstack.api.stream"; option java_multiple_files = true; option java_outer_classname = "FrameProto"; option csharp_namespace = "Chirpstack.Stream"; +option php_namespace = "Chirpstack\\Stream"; +option php_metadata_namespace = "GPBMetadata\\Chirpstack\\Stream"; import "google/protobuf/timestamp.proto"; import "common/common.proto"; diff --git a/api/rust/proto/chirpstack/stream/meta.proto b/api/rust/proto/chirpstack/stream/meta.proto index 83a6b227..511aae7e 100644 --- a/api/rust/proto/chirpstack/stream/meta.proto +++ b/api/rust/proto/chirpstack/stream/meta.proto @@ -7,6 +7,8 @@ option java_package = "io.chirpstack.api.stream"; option java_multiple_files = true; option java_outer_classname = "MetaProto"; option csharp_namespace = "Chirpstack.Stream"; +option php_namespace = "Chirpstack\\Stream"; +option php_metadata_namespace = "GPBMetadata\\Chirpstack\\Stream"; import "common/common.proto"; import "gw/gw.proto"; diff --git a/backend/Cargo.toml b/backend/Cargo.toml index 51129ad4..46a181dc 100644 --- a/backend/Cargo.toml +++ b/backend/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "backend" -version = "4.8.1" +version = "4.9.0-test.1" authors = ["Orne Brocaar "] edition = "2018" publish = false diff --git a/chirpstack-integration/Cargo.toml b/chirpstack-integration/Cargo.toml index 378feee0..7f2689b5 100644 --- a/chirpstack-integration/Cargo.toml +++ b/chirpstack-integration/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/chirpstack/chirpstack" [dependencies] - chirpstack_api = { path = "../api/rust", version = "4.8.0" } + chirpstack_api = { path = "../api/rust", version = "4.9.0-test.1" } redis = { version = "0.25", features = [ "cluster-async", "tokio-rustls-comp", diff --git a/chirpstack/Cargo.toml b/chirpstack/Cargo.toml index 0487d0a1..5e67ff74 100644 --- a/chirpstack/Cargo.toml +++ b/chirpstack/Cargo.toml @@ -3,7 +3,7 @@ description = "ChirpStack is an open-source LoRaWAN(TM) Network Server" repository = "https://github.com/chirpstack/chirpstack" homepage = "https://www.chirpstack.io/" - version = "4.8.1" + version = "4.9.0-test.1" authors = ["Orne Brocaar "] edition = "2021" publish = false diff --git a/chirpstack/migrations/2024-06-13-122655_add_relay_gateway/down.sql b/chirpstack/migrations/2024-06-13-122655_add_relay_gateway/down.sql new file mode 100644 index 00000000..6e499c91 --- /dev/null +++ b/chirpstack/migrations/2024-06-13-122655_add_relay_gateway/down.sql @@ -0,0 +1 @@ +drop table relay_gateway; diff --git a/chirpstack/migrations/2024-06-13-122655_add_relay_gateway/up.sql b/chirpstack/migrations/2024-06-13-122655_add_relay_gateway/up.sql new file mode 100644 index 00000000..bae05e4f --- /dev/null +++ b/chirpstack/migrations/2024-06-13-122655_add_relay_gateway/up.sql @@ -0,0 +1,13 @@ +create table relay_gateway ( + tenant_id uuid not null references tenant on delete cascade, + relay_id bytea not null, + created_at timestamp with time zone not null, + updated_at timestamp with time zone not null, + last_seen_at timestamp with time zone, + name varchar(100) not null, + description text not null, + stats_interval_secs integer not null, + region_config_id varchar(100) not null, + + primary key (tenant_id, relay_id) +); diff --git a/chirpstack/src/api/gateway.rs b/chirpstack/src/api/gateway.rs index deaa20b2..9a6bd365 100644 --- a/chirpstack/src/api/gateway.rs +++ b/chirpstack/src/api/gateway.rs @@ -14,7 +14,11 @@ use super::auth::validator; use super::error::ToStatus; use super::helpers::{self, FromProto}; use crate::certificate; -use crate::storage::{fields, gateway, metrics}; +use crate::storage::{ + fields, + gateway::{self, RelayId}, + metrics, +}; pub struct Gateway { validator: validator::RequestValidator, @@ -783,6 +787,194 @@ impl GatewayService for Gateway { Ok(resp) } + + async fn get_relay_gateway( + &self, + request: Request, + ) -> Result, Status> { + let req = request.get_ref(); + let tenant_id = Uuid::from_str(&req.tenant_id).map_err(|e| e.status())?; + let relay_id = RelayId::from_str(&req.relay_id).map_err(|e| e.status())?; + + // The tenant_id is part of the relay PK. + self.validator + .validate( + request.extensions(), + validator::ValidateGatewaysAccess::new(validator::Flag::List, tenant_id), + ) + .await?; + + let relay = gateway::get_relay_gateway(tenant_id, relay_id) + .await + .map_err(|e| e.status())?; + + let mut resp = Response::new(api::GetRelayGatewayResponse { + relay_gateway: Some(api::RelayGateway { + tenant_id: relay.tenant_id.to_string(), + relay_id: relay.relay_id.to_string(), + name: relay.name, + description: relay.description, + stats_interval: relay.stats_interval_secs as u32, + region_config_id: relay.region_config_id.to_string(), + }), + created_at: Some(helpers::datetime_to_prost_timestamp(&relay.created_at)), + updated_at: Some(helpers::datetime_to_prost_timestamp(&relay.updated_at)), + last_seen_at: relay + .last_seen_at + .as_ref() + .map(helpers::datetime_to_prost_timestamp), + }); + + resp.metadata_mut() + .insert("x-log-tenant_id", req.tenant_id.parse().unwrap()); + resp.metadata_mut() + .insert("x-log-relay_id", req.relay_id.parse().unwrap()); + + Ok(resp) + } + + async fn update_relay_gateway( + &self, + request: Request, + ) -> Result, Status> { + let req_relay = match &request.get_ref().relay_gateway { + Some(v) => v, + None => { + return Err(Status::invalid_argument("relay_gateway is missing")); + } + }; + let tenant_id = Uuid::from_str(&req_relay.tenant_id).map_err(|e| e.status())?; + let relay_id = RelayId::from_str(&req_relay.relay_id).map_err(|e| e.status())?; + + // The tenant_id is part of the relay PK. + self.validator + .validate( + request.extensions(), + validator::ValidateGatewaysAccess::new(validator::Flag::List, tenant_id), + ) + .await?; + + let _ = gateway::update_relay_gateway(gateway::RelayGateway { + tenant_id, + relay_id, + name: req_relay.name.clone(), + description: req_relay.description.clone(), + stats_interval_secs: req_relay.stats_interval as i32, + region_config_id: req_relay.region_config_id.clone(), + ..Default::default() + }) + .await + .map_err(|e| e.status())?; + + let mut resp = Response::new(()); + resp.metadata_mut() + .insert("x-log-tenant_id", req_relay.tenant_id.parse().unwrap()); + resp.metadata_mut() + .insert("x-log-relay_id", req_relay.relay_id.parse().unwrap()); + + Ok(resp) + } + + async fn delete_relay_gateway( + &self, + request: Request, + ) -> Result, Status> { + let req = request.get_ref(); + let tenant_id = Uuid::from_str(&req.tenant_id).map_err(|e| e.status())?; + let relay_id = RelayId::from_str(&req.relay_id).map_err(|e| e.status())?; + + // The tenant_id is part of the relay PK. + self.validator + .validate( + request.extensions(), + validator::ValidateGatewaysAccess::new(validator::Flag::List, tenant_id), + ) + .await?; + + gateway::delete_relay_gateway(tenant_id, relay_id) + .await + .map_err(|e| e.status())?; + + let mut resp = Response::new(()); + resp.metadata_mut() + .insert("x-log-tenant_id", req.tenant_id.parse().unwrap()); + resp.metadata_mut() + .insert("x-log-relay_id", req.relay_id.parse().unwrap()); + + Ok(resp) + } + + async fn list_relay_gateways( + &self, + request: Request, + ) -> Result, Status> { + let req = request.get_ref(); + let tenant_id = if req.tenant_id.is_empty() { + None + } else { + Some(Uuid::from_str(&req.tenant_id).map_err(|e| e.status())?) + }; + + self.validator + .validate( + request.extensions(), + validator::ValidateGatewaysAccess::new( + validator::Flag::List, + tenant_id.unwrap_or(Uuid::nil()), + ), + ) + .await?; + + let filters = gateway::RelayGatewayFilters { tenant_id }; + + let count = gateway::get_relay_gateway_count(&filters) + .await + .map_err(|e| e.status())?; + let result = gateway::list_relay_gateways(req.limit as i64, req.offset as i64, &filters) + .await + .map_err(|e| e.status())?; + + let mut resp = Response::new(api::ListRelayGatewaysResponse { + total_count: count as u32, + result: result + .iter() + .map(|r| api::RelayGatewayListItem { + tenant_id: r.tenant_id.to_string(), + relay_id: r.relay_id.to_string(), + name: r.name.clone(), + description: r.description.clone(), + created_at: Some(helpers::datetime_to_prost_timestamp(&r.created_at)), + updated_at: Some(helpers::datetime_to_prost_timestamp(&r.updated_at)), + last_seen_at: r + .last_seen_at + .as_ref() + .map(helpers::datetime_to_prost_timestamp), + state: { + if let Some(ts) = r.last_seen_at { + if (Utc::now() - ts) + > Duration::try_seconds((r.stats_interval_secs * 2).into()) + .unwrap_or_default() + { + api::GatewayState::Offline + } else { + api::GatewayState::Online + } + } else { + api::GatewayState::NeverSeen + } + } + .into(), + region_config_id: r.region_config_id.to_string(), + }) + .collect(), + }); + if !req.tenant_id.is_empty() { + resp.metadata_mut() + .insert("x-log-tenant_id", req.tenant_id.parse().unwrap()); + } + + Ok(resp) + } } #[cfg(test)] @@ -1162,5 +1354,103 @@ pub mod test { }), stats_resp.window_percentage ); + + // create relay gateway + let _ = gateway::create_relay_gateway(gateway::RelayGateway { + tenant_id: t.id, + relay_id: gateway::RelayId::from_be_bytes([1, 2, 3, 4]), + name: "test-relay".into(), + description: "test relay".into(), + region_config_id: "eu868".into(), + ..Default::default() + }) + .await + .unwrap(); + + // get relay gateway + let get_relay_req = api::GetRelayGatewayRequest { + tenant_id: t.id.to_string(), + relay_id: "01020304".into(), + }; + let mut get_relay_req = Request::new(get_relay_req); + get_relay_req.extensions_mut().insert(AuthID::User(u.id)); + let get_relay_resp = service.get_relay_gateway(get_relay_req).await.unwrap(); + assert_eq!( + Some(api::RelayGateway { + tenant_id: t.id.to_string(), + relay_id: "01020304".into(), + name: "test-relay".into(), + description: "test relay".into(), + stats_interval: 900, + region_config_id: "eu868".into(), + }), + get_relay_resp.get_ref().relay_gateway + ); + + // update + let up_relay_req = api::UpdateRelayGatewayRequest { + relay_gateway: Some(api::RelayGateway { + tenant_id: t.id.to_string(), + relay_id: "01020304".into(), + name: "updated-relay".into(), + description: "updated relay".into(), + stats_interval: 600, + region_config_id: "us915_0".into(), + }), + }; + let mut up_relay_req = Request::new(up_relay_req); + up_relay_req.extensions_mut().insert(AuthID::User(u.id)); + let _ = service.update_relay_gateway(up_relay_req).await.unwrap(); + + // get relay gateway + let get_relay_req = api::GetRelayGatewayRequest { + tenant_id: t.id.to_string(), + relay_id: "01020304".into(), + }; + let mut get_relay_req = Request::new(get_relay_req); + get_relay_req.extensions_mut().insert(AuthID::User(u.id)); + let get_relay_resp = service.get_relay_gateway(get_relay_req).await.unwrap(); + assert_eq!( + Some(api::RelayGateway { + tenant_id: t.id.to_string(), + relay_id: "01020304".into(), + name: "updated-relay".into(), + description: "updated relay".into(), + stats_interval: 600, + region_config_id: "us915_0".into(), + }), + get_relay_resp.get_ref().relay_gateway + ); + + // list + let list_relay_req = api::ListRelayGatewaysRequest { + tenant_id: t.id.to_string(), + limit: 10, + offset: 0, + }; + let mut list_relay_req = Request::new(list_relay_req); + list_relay_req.extensions_mut().insert(AuthID::User(u.id)); + let list_relay_resp = service.list_relay_gateways(list_relay_req).await.unwrap(); + assert_eq!(1, list_relay_resp.get_ref().total_count); + assert_eq!(1, list_relay_resp.get_ref().result.len()); + + // delete + let del_relay_req = api::DeleteRelayGatewayRequest { + tenant_id: t.id.to_string(), + relay_id: "01020304".into(), + }; + let mut del_relay_req = Request::new(del_relay_req); + del_relay_req.extensions_mut().insert(AuthID::User(u.id)); + let del_relay_resp = service.delete_relay_gateway(del_relay_req).await; + assert!(del_relay_resp.is_ok()); + + let del_relay_req = api::DeleteRelayGatewayRequest { + tenant_id: t.id.to_string(), + relay_id: "01020304".into(), + }; + let mut del_relay_req = Request::new(del_relay_req); + del_relay_req.extensions_mut().insert(AuthID::User(u.id)); + let del_relay_resp = service.delete_relay_gateway(del_relay_req).await; + assert!(del_relay_resp.is_err()); } } diff --git a/chirpstack/src/gateway/backend/mqtt.rs b/chirpstack/src/gateway/backend/mqtt.rs index 9fe7b7ff..b6d6c376 100644 --- a/chirpstack/src/gateway/backend/mqtt.rs +++ b/chirpstack/src/gateway/backend/mqtt.rs @@ -414,6 +414,18 @@ async fn message_callback( set_gateway_json(&event.gateway_id, json); tokio::spawn(downlink::tx_ack::TxAck::handle(event)); + } else if topic.ends_with("/mesh-stats") { + EVENT_COUNTER + .get_or_create(&EventLabels { + event: "mesh-stats".to_string(), + }) + .inc(); + let event = match json { + true => serde_json::from_slice(&p.payload)?, + false => chirpstack_api::gw::MeshHeartbeat::decode(&mut Cursor::new(&p.payload))?, + }; + + tokio::spawn(uplink::mesh::MeshHeartbeat::handle(event)); } else { return Err(anyhow!("Unknown event type")); } diff --git a/chirpstack/src/storage/gateway.rs b/chirpstack/src/storage/gateway.rs index 6404fddb..5f78987d 100644 --- a/chirpstack/src/storage/gateway.rs +++ b/chirpstack/src/storage/gateway.rs @@ -7,11 +7,13 @@ use diesel_async::RunQueryDsl; use tracing::info; use uuid::Uuid; -use lrwn::EUI64; +use lrwn::{DevAddr, EUI64}; -use super::schema::{gateway, multicast_group_gateway, tenant}; +use super::schema::{gateway, multicast_group_gateway, relay_gateway, tenant}; use super::{error::Error, fields, get_async_db_conn}; +pub type RelayId = DevAddr; + #[derive(Queryable, Insertable, PartialEq, Debug)] #[diesel(table_name = gateway)] pub struct Gateway { @@ -40,6 +42,29 @@ impl Gateway { } } +impl Default for Gateway { + fn default() -> Self { + let now = Utc::now(); + + Gateway { + gateway_id: EUI64::from_be_bytes([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), + tenant_id: Uuid::nil(), + created_at: now, + updated_at: now, + last_seen_at: None, + name: "".into(), + description: "".into(), + latitude: 0.0, + longitude: 0.0, + altitude: 0.0, + tls_certificate: None, + stats_interval_secs: 30, + tags: fields::KeyValue::new(HashMap::new()), + properties: fields::KeyValue::new(HashMap::new()), + } + } +} + #[derive(AsChangeset, Debug, Clone, Default)] #[diesel(table_name = gateway)] pub struct GatewayChangeset { @@ -95,29 +120,56 @@ pub struct GatewayCountsByState { pub offline_count: i64, } -impl Default for Gateway { +#[derive(Queryable, Insertable, PartialEq, Debug)] +#[diesel(table_name = relay_gateway)] +pub struct RelayGateway { + pub tenant_id: Uuid, + pub relay_id: RelayId, + pub created_at: DateTime, + pub updated_at: DateTime, + pub last_seen_at: Option>, + pub name: String, + pub description: String, + pub stats_interval_secs: i32, + pub region_config_id: String, +} + +impl Default for RelayGateway { fn default() -> Self { let now = Utc::now(); - Gateway { - gateway_id: EUI64::from_be_bytes([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), + RelayGateway { + relay_id: RelayId::from_be_bytes([1, 2, 3, 4]), tenant_id: Uuid::nil(), created_at: now, updated_at: now, last_seen_at: None, name: "".into(), description: "".into(), - latitude: 0.0, - longitude: 0.0, - altitude: 0.0, - tls_certificate: None, - stats_interval_secs: 30, - tags: fields::KeyValue::new(HashMap::new()), - properties: fields::KeyValue::new(HashMap::new()), + stats_interval_secs: 900, + region_config_id: "".into(), } } } +#[derive(Default, Clone)] +pub struct RelayGatewayFilters { + pub tenant_id: Option, +} + +#[derive(Queryable, PartialEq, Debug)] +pub struct RelayGatewayListItem { + pub relay_id: RelayId, + pub tenant_id: Uuid, + pub created_at: DateTime, + pub updated_at: DateTime, + pub last_seen_at: Option>, + pub name: String, + pub description: String, + pub stats_interval_secs: i32, + pub region_config_id: String, +} + pub async fn create(gw: Gateway) -> Result { gw.validate()?; let mut c = get_async_db_conn().await?; @@ -322,6 +374,103 @@ pub async fn get_counts_by_state(tenant_id: &Option) -> Result Result { + let relay: RelayGateway = diesel::insert_into(relay_gateway::table) + .values(&relay) + .get_result(&mut get_async_db_conn().await?) + .await + .map_err(|e| Error::from_diesel(e, relay.relay_id.to_string()))?; + + info!(relay_id = %relay.relay_id, "Relay Gateway created"); + + Ok(relay) +} + +pub async fn get_relay_gateway(tenant_id: Uuid, relay_id: RelayId) -> Result { + let relay = relay_gateway::dsl::relay_gateway + .find((&tenant_id, &relay_id)) + .first(&mut get_async_db_conn().await?) + .await + .map_err(|e| Error::from_diesel(e, relay_id.to_string()))?; + Ok(relay) +} + +pub async fn update_relay_gateway(relay: RelayGateway) -> Result { + let relay: RelayGateway = + diesel::update(relay_gateway::dsl::relay_gateway.find((&relay.tenant_id, &relay.relay_id))) + .set(( + relay_gateway::updated_at.eq(&relay.updated_at), + relay_gateway::name.eq(&relay.name), + relay_gateway::description.eq(&relay.description), + relay_gateway::stats_interval_secs.eq(&relay.stats_interval_secs), + relay_gateway::region_config_id.eq(&relay.region_config_id), + )) + .get_result(&mut get_async_db_conn().await?) + .await + .map_err(|e| Error::from_diesel(e, relay.relay_id.to_string()))?; + + info!(relay_id = %relay.relay_id, "Relay Gateway updated"); + + Ok(relay) +} + +pub async fn get_relay_gateway_count(filters: &RelayGatewayFilters) -> Result { + let mut q = relay_gateway::dsl::relay_gateway + .select(dsl::count_star()) + .into_boxed(); + + if let Some(tenant_id) = &filters.tenant_id { + q = q.filter(relay_gateway::dsl::tenant_id.eq(tenant_id)); + } + + Ok(q.first(&mut get_async_db_conn().await?).await?) +} + +pub async fn delete_relay_gateway(tenant_id: Uuid, relay_id: RelayId) -> Result<(), Error> { + let ra = diesel::delete(relay_gateway::dsl::relay_gateway.find((&tenant_id, &relay_id))) + .execute(&mut get_async_db_conn().await?) + .await?; + if ra == 0 { + return Err(Error::NotFound(relay_id.to_string())); + } + + info!(relay_id = %relay_id, "Relay Gateway deleted"); + + Ok(()) +} + +pub async fn list_relay_gateways( + limit: i64, + offset: i64, + filters: &RelayGatewayFilters, +) -> Result, Error> { + let mut q = relay_gateway::dsl::relay_gateway + .select(( + relay_gateway::relay_id, + relay_gateway::tenant_id, + relay_gateway::created_at, + relay_gateway::updated_at, + relay_gateway::last_seen_at, + relay_gateway::name, + relay_gateway::description, + relay_gateway::stats_interval_secs, + relay_gateway::region_config_id, + )) + .into_boxed(); + + if let Some(tenant_id) = &filters.tenant_id { + q = q.filter(relay_gateway::dsl::tenant_id.eq(tenant_id)); + } + + let items = q + .order_by(relay_gateway::dsl::name) + .limit(limit) + .offset(offset) + .load(&mut get_async_db_conn().await?) + .await?; + Ok(items) +} + #[cfg(test)] pub mod test { use super::*; @@ -337,6 +486,14 @@ pub mod test { offset: i64, } + struct RelayGatewayFilterTest<'a> { + filters: RelayGatewayFilters, + relay_gateways: Vec<&'a RelayGateway>, + count: usize, + limit: i64, + offset: i64, + } + pub async fn create_gateway(id: EUI64) -> Gateway { let tenant_id = { let t = storage::tenant::test::create_tenant().await; @@ -498,4 +655,93 @@ pub mod test { delete(&gw.gateway_id).await.unwrap(); assert_eq!(true, delete(&gw.gateway_id).await.is_err()); } + + #[tokio::test] + async fn test_relay_gateway() { + let _guard = test::prepare().await; + let gw = create_gateway(EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8])).await; + + // create + let mut relay = create_relay_gateway(RelayGateway { + relay_id: RelayId::from_be_bytes([1, 2, 3, 4]), + tenant_id: gw.tenant_id, + name: "test-relay".into(), + description: "test relay".into(), + region_config_id: "eu868".into(), + ..Default::default() + }) + .await + .unwrap(); + + // get + let relay_get = get_relay_gateway(relay.tenant_id, relay.relay_id) + .await + .unwrap(); + assert_eq!(relay, relay_get); + + // update + relay.name = "updated-relay".into(); + relay.region_config_id = "us915_0".into(); + relay = update_relay_gateway(relay).await.unwrap(); + let relay_get = get_relay_gateway(relay.tenant_id, relay.relay_id) + .await + .unwrap(); + assert_eq!(relay, relay_get); + + // test count and list + let tests = vec![ + RelayGatewayFilterTest { + filters: RelayGatewayFilters { tenant_id: None }, + relay_gateways: vec![&relay], + count: 1, + limit: 10, + offset: 0, + }, + RelayGatewayFilterTest { + filters: RelayGatewayFilters { + tenant_id: Some(gw.tenant_id), + }, + relay_gateways: vec![&relay], + count: 1, + limit: 10, + offset: 0, + }, + RelayGatewayFilterTest { + filters: RelayGatewayFilters { + tenant_id: Some(gw.tenant_id), + }, + relay_gateways: vec![&relay], + count: 1, + limit: 10, + offset: 0, + }, + ]; + + for tst in tests { + let count = get_relay_gateway_count(&tst.filters).await.unwrap() as usize; + assert_eq!(tst.count, count); + + let items = list_relay_gateways(tst.limit, tst.offset, &tst.filters) + .await + .unwrap(); + assert_eq!( + tst.relay_gateways + .iter() + .map(|r| r.relay_id.to_string()) + .collect::(), + items + .iter() + .map(|r| r.relay_id.to_string()) + .collect::(), + ); + } + + // delete + delete_relay_gateway(relay.tenant_id, relay.relay_id) + .await + .unwrap(); + assert!(delete_relay_gateway(relay.tenant_id, relay.relay_id) + .await + .is_err()); + } } diff --git a/chirpstack/src/storage/schema.rs b/chirpstack/src/storage/schema.rs index 40fc733d..22c514dd 100644 --- a/chirpstack/src/storage/schema.rs +++ b/chirpstack/src/storage/schema.rs @@ -288,6 +288,22 @@ diesel::table! { } } +diesel::table! { + relay_gateway (tenant_id, relay_id) { + tenant_id -> Uuid, + relay_id -> Bytea, + created_at -> Timestamptz, + updated_at -> Timestamptz, + last_seen_at -> Nullable, + #[max_length = 100] + name -> Varchar, + description -> Text, + stats_interval_secs -> Int4, + #[max_length = 100] + region_config_id -> Varchar, + } +} + diesel::table! { tenant (id) { id -> Uuid, @@ -349,6 +365,7 @@ diesel::joinable!(multicast_group_gateway -> gateway (gateway_id)); diesel::joinable!(multicast_group_gateway -> multicast_group (multicast_group_id)); diesel::joinable!(multicast_group_queue_item -> gateway (gateway_id)); diesel::joinable!(multicast_group_queue_item -> multicast_group (multicast_group_id)); +diesel::joinable!(relay_gateway -> tenant (tenant_id)); diesel::joinable!(tenant_user -> tenant (tenant_id)); diesel::joinable!(tenant_user -> user (user_id)); @@ -367,6 +384,7 @@ diesel::allow_tables_to_appear_in_same_query!( multicast_group_gateway, multicast_group_queue_item, relay_device, + relay_gateway, tenant, tenant_user, user, diff --git a/chirpstack/src/uplink/mesh.rs b/chirpstack/src/uplink/mesh.rs new file mode 100644 index 00000000..db5098cd --- /dev/null +++ b/chirpstack/src/uplink/mesh.rs @@ -0,0 +1,119 @@ +use std::str::FromStr; + +use anyhow::Result; +use chrono::{DateTime, Utc}; +use tracing::{error, span, trace, warn, Instrument, Level}; + +use chirpstack_api::gw; + +use crate::config; +use crate::helpers::errors::PrintFullError; +use crate::storage::{ + error::Error, + gateway::{self, RelayId}, +}; +use lrwn::EUI64; + +pub struct MeshHeartbeat { + gateway_id: EUI64, + relay_id: RelayId, + mesh_stats: gw::MeshHeartbeat, +} + +impl MeshHeartbeat { + pub async fn handle(s: gw::MeshHeartbeat) { + let gateway_id = match EUI64::from_str(&s.gateway_id) { + Ok(v) => v, + Err(e) => { + warn!(error = %e.full(), "Decode gateway_id error"); + return; + } + }; + + let relay_id = match RelayId::from_str(&s.relay_id) { + Ok(v) => v, + Err(e) => { + warn!(error = %e.full(), "Decode relay_id error"); + return; + } + }; + + let span = span!(Level::INFO, "mesh_stats", gateway_id = %gateway_id, relay_id = %relay_id); + + if let Err(e) = MeshHeartbeat::_handle(gateway_id, relay_id, s) + .instrument(span) + .await + { + match e.downcast_ref::() { + Some(Error::NotFound(_)) => { + let conf = config::get(); + if !conf.gateway.allow_unknown_gateways { + error!(error = %e.full(), "Handle mesh-stats error"); + } + } + Some(_) | None => { + error!(error = %e.full(), "Handle mesh-stats error"); + } + } + } + } + + async fn _handle(gateway_id: EUI64, relay_id: RelayId, s: gw::MeshHeartbeat) -> Result<()> { + let mut ctx = MeshHeartbeat { + gateway_id, + relay_id, + mesh_stats: s, + }; + + ctx.update_or_create_relay_gateway().await?; + + Ok(()) + } + + async fn update_or_create_relay_gateway(&mut self) -> Result<()> { + trace!("Getting Border Gateway"); + let border_gw = gateway::get(&self.gateway_id).await?; + + let ts: DateTime = match &self.mesh_stats.time { + Some(v) => v + .clone() + .try_into() + .map_err(|e| anyhow!("Convert time error: {}", e))?, + None => { + warn!("Stats message does not have time field set"); + return Ok(()); + } + }; + + match gateway::get_relay_gateway(border_gw.tenant_id, self.relay_id).await { + Ok(mut v) => { + if let Some(last_seen_at) = v.last_seen_at { + if last_seen_at > ts { + warn!("Time is less than last seen timestamp, ignoring stats"); + return Ok(()); + } + } + + v.last_seen_at = Some(ts); + v.region_config_id = border_gw + .properties + .get("region_config_id") + .cloned() + .unwrap_or_default(); + gateway::update_relay_gateway(v).await?; + } + Err(_) => { + let _ = gateway::create_relay_gateway(gateway::RelayGateway { + tenant_id: border_gw.tenant_id, + relay_id: self.relay_id, + name: self.relay_id.to_string(), + last_seen_at: Some(ts), + ..Default::default() + }) + .await?; + } + } + + Ok(()) + } +} diff --git a/chirpstack/src/uplink/mod.rs b/chirpstack/src/uplink/mod.rs index 590cabdd..5621285b 100644 --- a/chirpstack/src/uplink/mod.rs +++ b/chirpstack/src/uplink/mod.rs @@ -33,6 +33,7 @@ pub mod helpers; pub mod join; pub mod join_fns; pub mod join_sns; +pub mod mesh; pub mod stats; #[derive(Clone, Hash, PartialEq, Eq, EncodeLabelSet, Debug)] diff --git a/lrwn-filters/Cargo.toml b/lrwn-filters/Cargo.toml index e5d8f9fa..d80df51b 100644 --- a/lrwn-filters/Cargo.toml +++ b/lrwn-filters/Cargo.toml @@ -3,7 +3,7 @@ name = "lrwn_filters" description = "Library for filtering LoRaWAN payloads on DevAddr and JoinEUIs prefixes" homepage = "https://www.chirpstack.io/" license = "MIT" -version = "4.8.1" +version = "4.9.0-test.1" authors = ["Orne Brocaar "] edition = "2021" repository = "https://github.com/chirpstack/chirpstack" diff --git a/lrwn/Cargo.toml b/lrwn/Cargo.toml index e92b122d..6b534f8f 100644 --- a/lrwn/Cargo.toml +++ b/lrwn/Cargo.toml @@ -3,7 +3,7 @@ name = "lrwn" description = "Library for encoding / decoding LoRaWAN frames." homepage = "https://www.chirpstack.io" license = "MIT" -version = "4.8.1" +version = "4.9.0-test.1" authors = ["Orne Brocaar "] edition = "2018" repository = "https://github.com/chirpstack/chirpstack" diff --git a/ui/package.json b/ui/package.json index fcf1610f..172788c0 100644 --- a/ui/package.json +++ b/ui/package.json @@ -1,6 +1,6 @@ { "name": "chirpstack-ui", - "version": "4.8.1", + "version": "4.9.0-test.1", "private": true, "dependencies": { "@ant-design/colors": "^7.0.0", diff --git a/ui/src/components/Menu.tsx b/ui/src/components/Menu.tsx index 9d4fcf17..2ab77120 100644 --- a/ui/src/components/Menu.tsx +++ b/ui/src/components/Menu.tsx @@ -12,6 +12,7 @@ import { ControlOutlined, AppstoreOutlined, CompassOutlined, + RadarChartOutlined, } from "@ant-design/icons"; import { @@ -130,6 +131,11 @@ function SideMenu() { setSelectedKey("tenant-gateways"); } + // tenant gateway-mesh + if (/\/tenants\/[\w-]{36}\/gateways\/mesh.*/g.exec(path)) { + setSelectedKey("tenant-gateways-mesh"); + } + // tenant applications if (/\/tenants\/[\w-]{36}\/applications.*/g.exec(path)) { setSelectedKey("tenant-applications"); @@ -242,6 +248,11 @@ function SideMenu() { icon: , label: Gateways, }, + { + key: "tenant-gateways-mesh", + icon: , + label: Gateway Mesh, + }, { key: "tenant-applications", icon: , diff --git a/ui/src/components/RelayIdInput.tsx b/ui/src/components/RelayIdInput.tsx new file mode 100644 index 00000000..0b26147e --- /dev/null +++ b/ui/src/components/RelayIdInput.tsx @@ -0,0 +1,202 @@ + +import React, { useState, useEffect } from "react"; + +import { notification, Input, Select, Button, Space, Form, Dropdown, Menu } from "antd"; +import { ReloadOutlined, CopyOutlined } from "@ant-design/icons"; +import { Buffer } from "buffer"; + +interface IProps { + label: string; + name: string; + required?: boolean; + value?: string; + disabled?: boolean; + tooltip?: string; +} + +function RelayIdInput(props: IProps) { + const form = Form.useFormInstance(); + const [byteOrder, setByteOrder] = useState("msb"); + const [value, setValue] = useState(""); + + useEffect(() => { + if (props.value) { + setValue(props.value); + } + }, [props]); + + const updateField = (v: string) => { + if (byteOrder === "lsb") { + const bytes = v.match(/[A-Fa-f0-9]{2}/g) || []; + v = bytes.reverse().join(""); + } + + form.setFieldsValue({ + [props.name]: v, + }); + }; + + const onChange = (e: React.ChangeEvent) => { + let v = e.target.value; + const match = v.match(/[A-Fa-f0-9]/g); + + let value = ""; + if (match) { + if (match.length > 8) { + value = match.slice(0, 8).join(""); + } else { + value = match.join(""); + } + } + + setValue(value); + updateField(value); + }; + + const onByteOrderSelect = (v: string) => { + if (v === byteOrder) { + return; + } + + setByteOrder(v); + + const current = value; + const bytes = current.match(/[A-Fa-f0-9]{2}/g) || []; + const vv = bytes.reverse().join(""); + + setValue(vv); + updateField(vv); + }; + + const generateRandom = () => { + let cryptoObj = window.crypto || window.Crypto; + let b = new Uint8Array(4); + cryptoObj.getRandomValues(b); + + let key = Buffer.from(b).toString("hex"); + setValue(key); + updateField(key); + }; + + const copyToClipboard = () => { + const bytes = value.match(/[A-Fa-f0-9]{2}/g); + + if (bytes !== null && navigator.clipboard !== undefined) { + navigator.clipboard + .writeText(bytes.join("").toUpperCase()) + .then(() => { + notification.success({ + message: "Copied to clipboard", + duration: 3, + }); + }) + .catch(e => { + notification.error({ + message: "Error", + description: e, + duration: 3, + }); + }); + } else { + notification.error({ + message: "Error", + description: "Clipboard functionality is not available.", + duration: 3, + }); + } + }; + + const copyToClipboardHexArray = () => { + const bytes = value.match(/[A-Fa-f0-9]{2}/g); + + if (bytes !== null && navigator.clipboard !== undefined) { + navigator.clipboard + .writeText( + bytes + .join(", ") + .toUpperCase() + .replace(/[A-Fa-f0-9]{2}/g, "0x$&"), + ) + .then(() => { + notification.success({ + message: "Copied to clipboard", + duration: 3, + }); + }) + .catch(e => { + notification.error({ + message: "Error", + description: e, + duration: 3, + }); + }); + } + }; + + const copyMenu = ( + + HEX string + + ), + }, + { + key: "2", + label: ( + + ), + }, + ]} + /> + ); + + const addon = ( + + + + + + + + ); + + return ( + + + + + ); +} + +export default RelayIdInput; diff --git a/ui/src/stores/GatewayStore.ts b/ui/src/stores/GatewayStore.ts index 1f41d298..e2745112 100644 --- a/ui/src/stores/GatewayStore.ts +++ b/ui/src/stores/GatewayStore.ts @@ -15,6 +15,12 @@ import { GetGatewayDutyCycleMetricsResponse, GenerateGatewayClientCertificateRequest, GenerateGatewayClientCertificateResponse, + GetRelayGatewayRequest, + GetRelayGatewayResponse, + ListRelayGatewaysRequest, + ListRelayGatewaysResponse, + UpdateRelayGatewayRequest, + DeleteRelayGatewayRequest, } from "@chirpstack/chirpstack-api-grpc-web/api/gateway_pb"; import SessionStore from "./SessionStore"; @@ -136,6 +142,60 @@ class GatewayStore extends EventEmitter { callbackFunc(resp); }); }; + + getRelayGateway = (req: GetRelayGatewayRequest, callbackFunc: (resp: GetRelayGatewayResponse) => void) => { + this.client.getRelayGateway(req, SessionStore.getMetadata(), (err, resp) => { + if (err !== null) { + HandleError(err); + return; + } + + callbackFunc(resp); + }) + } + + listRelayGateways = (req: ListRelayGatewaysRequest, callbackFunc: (resp: ListRelayGatewaysResponse) => void) => { + this.client.listRelayGateways(req, SessionStore.getMetadata(), (err, resp) => { + if (err !== null) { + HandleError(err); + return; + } + + callbackFunc(resp); + }) + } + + updateRelayGateway = (req: UpdateRelayGatewayRequest, callbackFunc: () => void) => { + this.client.updateRelayGateway(req, SessionStore.getMetadata(), (err) => { + if (err !== null) { + HandleError(err); + return; + } + + notification.success({ + message: "Relay Gateway updated", + duration: 3, + }); + + callbackFunc(); + }) + } + + deleteRelayGateway = (req: DeleteRelayGatewayRequest, callbackFunc: () => void) => { + this.client.deleteRelayGateway(req, SessionStore.getMetadata(), (err) => { + if (err !== null) { + HandleError(err); + return; + } + + notification.success({ + message: "Relay Gateway deleted", + duration: 3, + }); + + callbackFunc(); + }) + } } const gatewayStore = new GatewayStore(); diff --git a/ui/src/views/gateways/mesh/EditRelayGateway.tsx b/ui/src/views/gateways/mesh/EditRelayGateway.tsx new file mode 100644 index 00000000..7332ed78 --- /dev/null +++ b/ui/src/views/gateways/mesh/EditRelayGateway.tsx @@ -0,0 +1,34 @@ +import { useNavigate } from "react-router-dom"; + +import { RelayGateway, UpdateRelayGatewayRequest } from "@chirpstack/chirpstack-api-grpc-web/api/gateway_pb"; + +import RelayGatewayForm from "./RelayGatewayForm"; +import GatewayStore from "../../../stores/GatewayStore"; +import SessionStore from "../../../stores/SessionStore"; + +interface IProps { + relayGateway: RelayGateway; +} + +function EditRelayGateway(props: IProps) { + const navigate = useNavigate(); + + const onFinish = (obj: RelayGateway) => { + let req = new UpdateRelayGatewayRequest(); + req.setRelayGateway(obj); + + GatewayStore.updateRelayGateway(req, () => { + navigate(`/tenants/${obj.getTenantId()}/gateways/mesh/relays`); + }); + }; + + const disabled = !( + SessionStore.isAdmin() || + SessionStore.isTenantAdmin(props.relayGateway.getTenantId()) || + SessionStore.isTenantGatewayAdmin(props.relayGateway.getTenantId()) + ); + + return ; +} + +export default EditRelayGateway; diff --git a/ui/src/views/gateways/mesh/ListRelayGateways.tsx b/ui/src/views/gateways/mesh/ListRelayGateways.tsx new file mode 100644 index 00000000..4c9aeafe --- /dev/null +++ b/ui/src/views/gateways/mesh/ListRelayGateways.tsx @@ -0,0 +1,119 @@ +import React from "react"; +import { Link } from "react-router-dom"; + +import moment from "moment"; +import { Space, Breadcrumb, Badge } from "antd"; +import { ColumnsType } from "antd/es/table"; +import { PageHeader } from "@ant-design/pro-layout"; + +import { + ListRelayGatewaysRequest, + ListRelayGatewaysResponse, + RelayGatewayListItem, + GatewayState, +} from "@chirpstack/chirpstack-api-grpc-web/api/gateway_pb"; +import { Tenant } from "@chirpstack/chirpstack-api-grpc-web/api/tenant_pb"; + +import DataTable, { GetPageCallbackFunc } from "../../../components/DataTable"; +import GatewayStore from "../../../stores/GatewayStore"; + +interface IProps { + tenant: Tenant; +} + +function ListRelayGateways(props: IProps) { + const columns: ColumnsType = [ + { + title: "", + dataIndex: "state", + key: "state", + width: 150, + render: (text, record) => { + if (record.state === GatewayState.NEVER_SEEN) { + return ; + } else if (record.state === GatewayState.OFFLINE) { + return ; + } else if (record.state === GatewayState.ONLINE) { + return ; + } + }, + }, + { + title: "Last seen", + dataIndex: "lastSeenAt", + key: "lastSeenAt", + width: 250, + render: (text, record) => { + if (record.lastSeenAt !== undefined) { + let ts = new Date(0); + ts.setUTCSeconds(record.lastSeenAt.seconds); + return moment(ts).format("YYYY-MM-DD HH:mm:ss"); + } + }, + }, + { + title: "Relay ID", + dataIndex: "relayId", + key: "relayId", + width: 250, + render: (text, record) => ( + {text} + ), + }, + { + title: "Name", + dataIndex: "name", + key: "name", + }, + { + title: "Region ID", + dataIndex: "regionConfigId", + key: "regionConfigId", + width: 150, + render: (text) => { + return {text}; + } + }, + ]; + + const getPage = (limit: number, offset: number, callbackFunc: GetPageCallbackFunc) => { + let req = new ListRelayGatewaysRequest(); + req.setTenantId(props.tenant.getId()); + req.setLimit(limit); + req.setOffset(offset); + + GatewayStore.listRelayGateways(req, (resp: ListRelayGatewaysResponse) => { + const obj = resp.toObject(); + callbackFunc(obj.totalCount, obj.resultList); + }); + }; + + return ( + + ( + + + Tenants + + + + {props.tenant.getName()} + + + + Gateway Mesh + + + Relay Gateways + + + )} + /> + + + ); +} + +export default ListRelayGateways; diff --git a/ui/src/views/gateways/mesh/RelayGatewayForm.tsx b/ui/src/views/gateways/mesh/RelayGatewayForm.tsx new file mode 100644 index 00000000..09383bbd --- /dev/null +++ b/ui/src/views/gateways/mesh/RelayGatewayForm.tsx @@ -0,0 +1,76 @@ + +import React from "react"; + +import { Form, Input, InputNumber, Row, Col, Button } from "antd"; + +import { RelayGateway } from "@chirpstack/chirpstack-api-grpc-web/api/gateway_pb"; + +import { onFinishFailed } from "../../helpers"; +import RelayIdInput from "../../../components/RelayIdInput"; + +interface IProps { + initialValues: RelayGateway; + onFinish: (obj: RelayGateway) => void; + update?: boolean; + disabled?: boolean; +} + +function RelayGatewayForm(props: IProps) { + const onFinish = (values: RelayGateway.AsObject) => { + const v = Object.assign(props.initialValues.toObject(), values); + let relay = new RelayGateway(); + + relay.setTenantId(v.tenantId); + relay.setRelayId(v.relayId); + relay.setName(v.name); + relay.setDescription(v.description); + relay.setStatsInterval(v.statsInterval); + relay.setRegionConfigId(v.regionConfigId); + + props.onFinish(relay); + }; + + return ( +
+ + + + + + + + + + + + + + + + + + + +
+ ); +} + +export default RelayGatewayForm; diff --git a/ui/src/views/gateways/mesh/RelayGatewayLayout.tsx b/ui/src/views/gateways/mesh/RelayGatewayLayout.tsx new file mode 100644 index 00000000..1dd9389e --- /dev/null +++ b/ui/src/views/gateways/mesh/RelayGatewayLayout.tsx @@ -0,0 +1,108 @@ +import React, { useState, useEffect } from "react"; + +import { Route, Routes, Link, useParams, useNavigate } from "react-router-dom"; + +import { Space, Breadcrumb, Card, Button } from "antd"; +import { PageHeader } from "@ant-design/pro-layout"; + +import { Tenant } from "@chirpstack/chirpstack-api-grpc-web/api/tenant_pb"; +import { + RelayGateway, + GetRelayGatewayRequest, + GetRelayGatewayResponse, + DeleteRelayGatewayRequest, +} from "@chirpstack/chirpstack-api-grpc-web/api/gateway_pb"; + +import Admin from "../../../components/Admin"; +import SessionStore from "../../../stores/SessionStore"; +import GatewayStore from "../../../stores/GatewayStore"; +import DeleteConfirm from "../../../components/DeleteConfirm"; + +import EditRelayGateway from "./EditRelayGateway"; + +interface IProps { + tenant: Tenant; +} + +function RelayGatewayLayout(props: IProps) { + const { relayId } = useParams(); + const navigate = useNavigate(); + const [relayGateway, setRelayGateway] = useState(undefined); + + useEffect(() => { + let req = new GetRelayGatewayRequest(); + req.setTenantId(props.tenant.getId()); + req.setRelayId(relayId!); + + GatewayStore.getRelayGateway(req, (resp: GetRelayGatewayResponse) => { + setRelayGateway(resp.getRelayGateway()); + }); + }, [props, relayId]); + + const deleteRelayGateway = () => { + let req = new DeleteRelayGatewayRequest(); + req.setTenantId(props.tenant.getId()); + req.setRelayId(relayId!); + + GatewayStore.deleteRelayGateway(req, () => { + navigate(`/tenants/${props.tenant.getId()}/gateways/mesh/relays`); + }); + } + + if (!relayGateway) { + return null; + } + + let isGatewayAdmin = + SessionStore.isAdmin() || + SessionStore.isTenantAdmin(props.tenant.getId()) || + SessionStore.isTenantGatewayAdmin(props.tenant.getId()); + + return ( + + ( + + + Tenants + + + + {props.tenant.getName()} + + + + Gateway Mesh + + + + Relay Gateways + + + + {relayGateway.getName()} + + + )} + title={relayGateway.getName()} + subTitle={`relay id: ${relayGateway.getRelayId()}`} + extra={[ + + + + + , + ]} + /> + + + } /> + + + + ); +} + +export default RelayGatewayLayout; diff --git a/ui/src/views/tenants/TenantLoader.tsx b/ui/src/views/tenants/TenantLoader.tsx index 19a816a1..2a5b9e37 100644 --- a/ui/src/views/tenants/TenantLoader.tsx +++ b/ui/src/views/tenants/TenantLoader.tsx @@ -19,8 +19,10 @@ import CreateDeviceProfile from "../device-profiles/CreateDeviceProfile"; import EditDeviceProfile from "../device-profiles/EditDeviceProfile"; import ListGateways from "../gateways/ListGateways"; +import ListRelayGateways from "../gateways/mesh/ListRelayGateways"; import CreateGateway from "../gateways/CreateGateway"; import GatewayLayout from "../gateways/GatewayLayout"; +import RelayGatewayLayout from "../gateways/mesh/RelayGatewayLayout"; import ListApplications from "../applications/ListApplications"; import CreateApplication from "../applications/CreateApplication"; @@ -65,6 +67,8 @@ function TenantLoader() { } /> } /> + } /> + } /> } /> } />