Compare commits

...

41 Commits

Author SHA1 Message Date
cba8da2d05 Bump version to 4.0.0-rc.4 2022-09-05 22:47:47 +01:00
97a235cc80 Remove duplicate code.
This is already handled by the filter_mac_commands function.
2022-09-05 22:38:48 +01:00
8a4b537645 Fix filtering on mac-command conflict and error count. 2022-09-05 14:07:16 +01:00
32889d7052 Make UI proxy work within Compose for development. 2022-09-01 14:50:46 +01:00
4dd441e85d Cleanup DevEUI from DevAddr > DevEUI set, if DS does not exist. 2022-08-31 11:13:51 +01:00
0fa40717e8 Add missing CN470 configuration.
Closes #36.
2022-08-31 09:48:55 +01:00
7e6552df5e Fix missing Kafka key. 2022-08-31 08:49:53 +01:00
4f08f7ddcb Add user_id filter when listing tenants with global API key. (#34) 2022-08-31 08:48:11 +01:00
0a5c38d322 Also log txack errors for mac-only downlinks. 2022-08-30 14:02:21 +01:00
3cf05e8fb9 Fix passive-roaming tx ack and save device-session order.
We first need to save the device-session and then handle the tx ack, as
else we are overwriting the frame-counter increment.
2022-08-26 12:54:46 +01:00
46bc4d6038 Use rf_region_encode module for rf_region in ULMetaData. 2022-08-25 10:43:36 +01:00
75f67f8c5c Use default for Description and do not serialize if empty. 2022-08-25 09:52:54 +01:00
ca2961c7b6 Bump version to 4.0.0-rc.3 2022-08-23 08:59:05 +01:00
63b0af6cf3 Remove owning_ref indirect dep by updating prometheus-client.
The owning_ref crate has a vulnerable. The updated prometheus-client no
longer uses owning_ref as a dependency.
2022-08-22 10:54:33 +01:00
d97da8ed50 Fix c > 64 to c >= 64 typo in channel-mask calculation.
Depending the channel-configuration, this would send three LinkADRReq
mac-commands while the same configuration could be send to the device in
two LinkADRReq mac-commands.
2022-08-21 21:48:27 +01:00
3b297ef221 Replace env. variables in config by localhost for .deb and .rpm
The env. variables are used such that the same configuration can be used
for Docker images, .deb and .rpm packages. However, if installing .deb
or .rpm packages, this can be confusing as executing 'chirpstack -c
/etc/chirpstack' will fail because these environment variables are only
available when using systemctl to start the ChirpStack process
(configured in the .service configuration file).
2022-08-21 21:44:36 +01:00
e917f8ea49 Remove default CA and MQTT cert gen. on install.
In case of mult-server deployments, this can be confusing as each VM
generates different certificate files by default, where all instances
must share the same certificate (or at least CA certificate + key).
The other issue is that the MQTT broker certificate must contain the
correct hostname, which can (most of the times) not automatically be
retrieved. Documentation to generate these certificates can be found
here:

https://www.chirpstack.io/docs/guides/mosquitto-tls-configuration.html
2022-08-21 19:56:49 +01:00
424306ab41 Update cpufeatures crate. This fixes an incorrect avx2 check.
In some scenarios, this check returned true while the avx2 extension was
not available (e.g. QEMU emulated CPU).

See for more details: https://github.com/RustCrypto/hashes/pull/386.
2022-08-18 11:37:03 +01:00
613f4562a2 Add config option to allow unknown gateways. 2022-08-18 10:27:55 +01:00
bf6df9c845 Fix shadowing of rx_info and setting location.
The rx_info value was shadowed, and because of this the location was set
on the cloned value, not the original value, making the location set
useless.
2022-08-14 13:49:00 +01:00
d4337b10ab Bump version to 4.0.0-rc.2 2022-08-11 12:04:21 +01:00
77dc247f66 Fix mac_version -> mac_version().
The first returns the Protobuf integer, the second the generated enum
type. The big difference is that the first .to_string() would convert
the Protobuf integer to the same but then as String type, where the
latter returns something like '1.0.3' which is provided by the
fmt::Display trait implementation by ChirpStack.
2022-08-11 11:38:43 +01:00
ca567ca562 Bump version to 4.0.0-rc.1 2022-08-10 12:36:43 +01:00
1a68080ac0 Fix configfile template. 2022-08-10 11:34:52 +01:00
ba7fc75ee6 Fix clippy warnings. 2022-08-10 11:34:33 +01:00
7868629533 Fix LoRaWAN 1.1 downlink fopts encryption. 2022-08-09 16:33:58 +01:00
2b1bf3b96f Only decode mac-commands for logging if in plaintext.
Please note that for LoRaWAN 1.1.x, mac-commands in the f_opts field are
encrypted. Within the context of the device we can decrypt these, but
within the context of a gateway we can only show these as raw bytes.
2022-08-09 15:29:22 +01:00
fd62076e02 Add plaintext_mac_commands field to up/down frame-log. 2022-08-09 15:28:37 +01:00
cfb4290334 Add missing isDisabled and setSkipFcntCheck switches (UI). 2022-08-09 11:07:32 +01:00
6d62cdb27c Fix generating gRPC documentation (md). 2022-08-08 15:56:01 +01:00
92a710fd1e Fix NewChannelReq for LoRaWAN 2.4GHz freqs. 2022-08-08 11:49:47 +01:00
d31113d61c Include cargo-bitbake in Dockerfile-devel. 2022-08-07 13:39:36 +01:00
e680db3be0 Bump version to 4.0.0-test.18 2022-08-04 17:11:45 +01:00
620ff1a8f9 Add missing channel and rf_chain fields.
This is not used by ChirpStack, but the chirpstack-udp-bridge expects to
receive this information from the ChirpStack Concentratord.
2022-08-04 16:52:01 +01:00
a14adfe20b Bump version to 4.0.0-test.17 2022-08-04 10:27:03 +01:00
672511c696 Implement support for JSON for GW<>NS.
This auto-detects the encoding used by the gateway and stores this
setting such that the commands will be encoded using the same setting.

Closes #2.
2022-08-03 15:19:51 +01:00
3348ccf67d Fix async receiver for passive-roaming HomeNSReq + add debug logs. 2022-08-03 15:18:31 +01:00
7890dc7539 Also match 1.0 and 1.1 strings for MacVersion. 2022-08-01 14:45:43 +01:00
341ac828b0 Bump version to 4.0.0-test.16 2022-08-01 12:59:57 +01:00
d7a4334b77 Fix missing GatewayStats v4_migrate.
This is needed as the gateway_id field has changed from bytes to string
(as the Protobuf JSON mapping encodes bytes to base64).
2022-08-01 12:08:08 +01:00
54d582504f Fix clippy warnings. 2022-08-01 10:24:15 +01:00
87 changed files with 4736 additions and 1485 deletions

6
.gitignore vendored
View File

@ -13,11 +13,7 @@
**/target
# Certificates
/chirpstack/configuration/certs/*.crt
/chirpstack/configuration/certs/*.key
/chirpstack/configuration/certs/*.trust
/chirpstack/configuration/certs/*.pem
/chirpstack/configuration/certs/*.csr
/chirpstack/configuration/certs/*
/chirpstack/configuration/private_*.toml
# UI

37
Cargo.lock generated
View File

@ -635,7 +635,7 @@ dependencies = [
[[package]]
name = "backend"
version = "4.0.0-test.15"
version = "4.0.0-rc.4"
dependencies = [
"aes-kw",
"anyhow",
@ -879,7 +879,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chirpstack"
version = "4.0.0-test.15"
version = "4.0.0-rc.4"
dependencies = [
"aes 0.7.5",
"anyhow",
@ -958,7 +958,7 @@ dependencies = [
[[package]]
name = "chirpstack_api"
version = "4.0.0-test.15"
version = "4.0.0-rc.4"
dependencies = [
"hex",
"pbjson",
@ -1118,9 +1118,9 @@ checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
[[package]]
name = "cpufeatures"
version = "0.2.2"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b"
checksum = "1079fb8528d9f9c888b1e8aa651e6e079ade467323d58f75faf1d30b1808f540"
dependencies = [
"libc",
]
@ -2222,7 +2222,7 @@ dependencies = [
[[package]]
name = "lrwn"
version = "4.0.0-test.15"
version = "4.0.0-rc.4"
dependencies = [
"aes 0.7.5",
"anyhow",
@ -2582,15 +2582,6 @@ version = "6.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "648001efe5d5c0102d8cea768e348da85d90af8ba91f0bea908f157951493cd4"
[[package]]
name = "owning_ref"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ff55baddef9e4ad00f88b6c743a2a8062d4c6ade126c2a528644b8e444d52ce"
dependencies = [
"stable_deref_trait",
]
[[package]]
name = "p12"
version = "0.6.3"
@ -2953,21 +2944,21 @@ dependencies = [
[[package]]
name = "prometheus-client"
version = "0.16.0"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac1abe0255c04d15f571427a2d1e00099016506cf3297b53853acd2b7eb87825"
checksum = "3c473049631c233933d6286c88bbb7be30e62ec534cf99a9ae0079211f7fa603"
dependencies = [
"dtoa 1.0.2",
"itoa 1.0.2",
"owning_ref",
"parking_lot",
"prometheus-client-derive-text-encode",
]
[[package]]
name = "prometheus-client-derive-text-encode"
version = "0.2.0"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8e12d01b9d66ad9eb4529c57666b6263fc1993cb30261d83ead658fdd932652"
checksum = "66a455fbcb954c1a7decf3c586e860fd7889cddf4b8e164be736dbac95a953cd"
dependencies = [
"proc-macro2",
"quote",
@ -3803,12 +3794,6 @@ dependencies = [
"lock_api",
]
[[package]]
name = "stable_deref_trait"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "string_cache"
version = "0.8.4"

View File

@ -36,5 +36,6 @@ RUN rustup target add aarch64-unknown-linux-gnu
RUN cargo install diesel_cli --version 2.0.0-rc.1 --no-default-features --features postgres
RUN cargo install cargo-deb
RUN cargo install cargo-rpm
RUN cargo install cargo-bitbake
WORKDIR $PROJECT_PATH/chirpstack

View File

@ -30,11 +30,11 @@ build-ui:
# Enters the devshell for ChirpStack development.
devshell:
docker-compose run --rm --service-ports chirpstack bash
docker-compose run --rm --service-ports --name chirpstack chirpstack bash
# Enters the devshell for ChirpStack UI development.
devshell-ui:
docker-compose run --rm --service-ports chirpstack-ui bash
docker-compose run --rm --service-ports --name chirpstack-ui chirpstack-ui bash
# Runs the tests
test:

2
api/Makefile vendored
View File

@ -1,4 +1,4 @@
.PHONY: rust grpc-web go js python
.PHONY: rust grpc-web go js python md
all:
docker-compose up

View File

@ -42,6 +42,8 @@ type UplinkFrameLog struct {
DevEui string `protobuf:"bytes,6,opt,name=dev_eui,json=devEui,proto3" json:"dev_eui,omitempty"`
// Time.
Time *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=time,proto3" json:"time,omitempty"`
// Plaintext mac-commands.
PlaintextMacCommands bool `protobuf:"varint,8,opt,name=plaintext_mac_commands,json=plaintextMacCommands,proto3" json:"plaintext_mac_commands,omitempty"`
}
func (x *UplinkFrameLog) Reset() {
@ -125,6 +127,13 @@ func (x *UplinkFrameLog) GetTime() *timestamppb.Timestamp {
return nil
}
func (x *UplinkFrameLog) GetPlaintextMacCommands() bool {
if x != nil {
return x.PlaintextMacCommands
}
return false
}
type DownlinkFrameLog struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@ -146,6 +155,8 @@ type DownlinkFrameLog struct {
DevAddr string `protobuf:"bytes,7,opt,name=dev_addr,json=devAddr,proto3" json:"dev_addr,omitempty"`
// Device EUI (optional).
DevEui string `protobuf:"bytes,8,opt,name=dev_eui,json=devEui,proto3" json:"dev_eui,omitempty"`
// Plaintext mac-commands.
PlaintextMacCommands bool `protobuf:"varint,9,opt,name=plaintext_mac_commands,json=plaintextMacCommands,proto3" json:"plaintext_mac_commands,omitempty"`
}
func (x *DownlinkFrameLog) Reset() {
@ -236,6 +247,13 @@ func (x *DownlinkFrameLog) GetDevEui() string {
return ""
}
func (x *DownlinkFrameLog) GetPlaintextMacCommands() bool {
if x != nil {
return x.PlaintextMacCommands
}
return false
}
var File_api_frame_log_proto protoreflect.FileDescriptor
var file_api_frame_log_proto_rawDesc = []byte{
@ -244,7 +262,7 @@ var file_api_frame_log_proto_rawDesc = []byte{
0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65,
0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x13, 0x63, 0x6f, 0x6d,
0x6d, 0x6f, 0x6e, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x1a, 0x0b, 0x67, 0x77, 0x2f, 0x67, 0x77, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x91, 0x02,
0x1a, 0x0b, 0x67, 0x77, 0x2f, 0x67, 0x77, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc7, 0x02,
0x0a, 0x0e, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x4c, 0x6f, 0x67,
0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x68, 0x79, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x68, 0x79, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61,
@ -262,31 +280,38 @@ var file_api_frame_log_proto_rawDesc = []byte{
0x69, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, 0x6d,
0x65, 0x22, 0xaa, 0x02, 0x0a, 0x10, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x46, 0x72,
0x61, 0x6d, 0x65, 0x4c, 0x6f, 0x67, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x68, 0x79, 0x5f, 0x70, 0x61,
0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x68, 0x79,
0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x2b, 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x69, 0x6e,
0x66, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x77, 0x2e, 0x44, 0x6f,
0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x54, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x74, 0x78,
0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b,
0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x64, 0x6f, 0x77, 0x6e, 0x6c,
0x69, 0x6e, 0x6b, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x61, 0x74, 0x65, 0x77,
0x61, 0x79, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x06, 0x6d, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06,
0x20, 0x01, 0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x54,
0x79, 0x70, 0x65, 0x52, 0x05, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x64, 0x65,
0x76, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65,
0x76, 0x41, 0x64, 0x64, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x65, 0x76, 0x5f, 0x65, 0x75, 0x69,
0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x65, 0x76, 0x45, 0x75, 0x69, 0x42, 0x54,
0x0a, 0x11, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e,
0x61, 0x70, 0x69, 0x42, 0x0d, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x4c, 0x6f, 0x67, 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, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x65, 0x12, 0x34, 0x0a, 0x16, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x6d,
0x61, 0x63, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28,
0x08, 0x52, 0x14, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x4d, 0x61, 0x63, 0x43,
0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x22, 0xe0, 0x02, 0x0a, 0x10, 0x44, 0x6f, 0x77, 0x6e,
0x6c, 0x69, 0x6e, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x4c, 0x6f, 0x67, 0x12, 0x2e, 0x0a, 0x04,
0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f,
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d,
0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b,
0x70, 0x68, 0x79, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
0x0c, 0x52, 0x0a, 0x70, 0x68, 0x79, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x2b, 0x0a,
0x07, 0x74, 0x78, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12,
0x2e, 0x67, 0x77, 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x54, 0x78, 0x49, 0x6e,
0x66, 0x6f, 0x52, 0x06, 0x74, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x6f,
0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52,
0x0a, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x67,
0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52,
0x09, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x06, 0x6d, 0x5f,
0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x63, 0x6f, 0x6d,
0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x54, 0x79, 0x70, 0x65, 0x52, 0x05, 0x6d, 0x54, 0x79, 0x70, 0x65,
0x12, 0x19, 0x0a, 0x08, 0x64, 0x65, 0x76, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x07, 0x20, 0x01,
0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x76, 0x41, 0x64, 0x64, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x64,
0x65, 0x76, 0x5f, 0x65, 0x75, 0x69, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x65,
0x76, 0x45, 0x75, 0x69, 0x12, 0x34, 0x0a, 0x16, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x78,
0x74, 0x5f, 0x6d, 0x61, 0x63, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x09,
0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x4d,
0x61, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x42, 0x54, 0x0a, 0x11, 0x69, 0x6f,
0x2e, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x42,
0x0d, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x4c, 0x6f, 0x67, 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,
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (

641
api/go/gw/gw.pb.go vendored
View File

@ -1463,17 +1463,21 @@ type UplinkRxInfo struct {
// SNR.
// Note: only available for LoRa modulation.
Snr float32 `protobuf:"fixed32,7,opt,name=snr,proto3" json:"snr,omitempty"`
// Channel.
Channel uint32 `protobuf:"varint,8,opt,name=channel,proto3" json:"channel,omitempty"`
// RF chain.
RfChain uint32 `protobuf:"varint,9,opt,name=rf_chain,json=rfChain,proto3" json:"rf_chain,omitempty"`
// Board.
Board uint32 `protobuf:"varint,8,opt,name=board,proto3" json:"board,omitempty"`
Board uint32 `protobuf:"varint,10,opt,name=board,proto3" json:"board,omitempty"`
// Antenna.
Antenna uint32 `protobuf:"varint,9,opt,name=antenna,proto3" json:"antenna,omitempty"`
Antenna uint32 `protobuf:"varint,11,opt,name=antenna,proto3" json:"antenna,omitempty"`
// Location.
Location *common.Location `protobuf:"bytes,10,opt,name=location,proto3" json:"location,omitempty"`
Location *common.Location `protobuf:"bytes,12,opt,name=location,proto3" json:"location,omitempty"`
// Gateway specific context.
// This value must be returned to the gateway on (Class-A) downlink.
Context []byte `protobuf:"bytes,11,opt,name=context,proto3" json:"context,omitempty"`
Context []byte `protobuf:"bytes,13,opt,name=context,proto3" json:"context,omitempty"`
// Properties.
Metadata *structpb.Struct `protobuf:"bytes,12,opt,name=metadata,proto3" json:"metadata,omitempty"`
Metadata *structpb.Struct `protobuf:"bytes,14,opt,name=metadata,proto3" json:"metadata,omitempty"`
}
func (x *UplinkRxInfo) Reset() {
@ -1557,6 +1561,20 @@ func (x *UplinkRxInfo) GetSnr() float32 {
return 0
}
func (x *UplinkRxInfo) GetChannel() uint32 {
if x != nil {
return x.Channel
}
return 0
}
func (x *UplinkRxInfo) GetRfChain() uint32 {
if x != nil {
return x.RfChain
}
return 0
}
func (x *UplinkRxInfo) GetBoard() uint32 {
if x != nil {
return x.Board
@ -3547,8 +3565,8 @@ var file_gw_gw_proto_rawDesc = []byte{
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, 0x10, 0x0a, 0x0e,
0x66, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0xee,
0x03, 0x0a, 0x0c, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x52, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x12,
0x66, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0xa3,
0x04, 0x0a, 0x0c, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x52, 0x78, 0x49, 0x6e, 0x66, 0x6f, 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, 0x1b,
0x0a, 0x09, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
@ -3568,318 +3586,321 @@ var file_gw_gw_proto_rawDesc = []byte{
0x69, 0x6e, 0x63, 0x65, 0x47, 0x70, 0x73, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x12, 0x0a, 0x04,
0x72, 0x73, 0x73, 0x69, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x72, 0x73, 0x73, 0x69,
0x12, 0x10, 0x0a, 0x03, 0x73, 0x6e, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x02, 0x52, 0x03, 0x73,
0x6e, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28,
0x0d, 0x52, 0x05, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x6e, 0x74, 0x65,
0x6e, 0x6e, 0x61, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x61, 0x6e, 0x74, 0x65, 0x6e,
0x6e, 0x61, 0x12, 0x2c, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x6f,
0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28,
0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65,
0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67,
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53,
0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22,
0xaf, 0x05, 0x0a, 0x14, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x54, 0x78, 0x49, 0x6e,
0x66, 0x6f, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x61, 0x74, 0x65,
0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x67, 0x61,
0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75,
0x65, 0x6e, 0x63, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x66, 0x72, 0x65, 0x71,
0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x18, 0x06,
0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x12, 0x32, 0x0a, 0x0a, 0x6d,
0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32,
0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12,
0x4a, 0x0a, 0x14, 0x6c, 0x6f, 0x72, 0x61, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e,
0x67, 0x77, 0x2e, 0x4c, 0x6f, 0x72, 0x61, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x48, 0x00, 0x52, 0x12, 0x6c, 0x6f, 0x72, 0x61, 0x4d, 0x6f, 0x64,
0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x47, 0x0a, 0x13, 0x66,
0x73, 0x6b, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e,
0x66, 0x6f, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x67, 0x77, 0x2e, 0x46, 0x73,
0x6b, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x48,
0x00, 0x52, 0x11, 0x66, 0x73, 0x6b, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x49, 0x6e, 0x66, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x18, 0x0a, 0x20,
0x01, 0x28, 0x0d, 0x52, 0x05, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x6e,
0x74, 0x65, 0x6e, 0x6e, 0x61, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x61, 0x6e, 0x74,
0x65, 0x6e, 0x6e, 0x61, 0x12, 0x2a, 0x0a, 0x06, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x18, 0x0c,
0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x67, 0x77, 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69,
0x6e, 0x6b, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x52, 0x06, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67,
0x12, 0x53, 0x0a, 0x17, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x6c, 0x79, 0x5f,
0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x0d, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x19, 0x2e, 0x67, 0x77, 0x2e, 0x49, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65,
0x6c, 0x79, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x48, 0x01, 0x52, 0x15,
0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x6c, 0x79, 0x54, 0x69, 0x6d, 0x69, 0x6e,
0x67, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x41, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x74,
0x69, 0x6d, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x13, 0x2e, 0x67, 0x77, 0x2e, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x54, 0x69, 0x6d, 0x69, 0x6e,
0x67, 0x49, 0x6e, 0x66, 0x6f, 0x48, 0x01, 0x52, 0x0f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x54, 0x69,
0x6d, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x4b, 0x0a, 0x15, 0x67, 0x70, 0x73, 0x5f,
0x65, 0x70, 0x6f, 0x63, 0x68, 0x5f, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x6e, 0x66,
0x6f, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x77, 0x2e, 0x47, 0x50, 0x53,
0x45, 0x70, 0x6f, 0x63, 0x68, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x48,
0x01, 0x52, 0x12, 0x67, 0x70, 0x73, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x54, 0x69, 0x6d, 0x69, 0x6e,
0x67, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74,
0x18, 0x10, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x42,
0x11, 0x0a, 0x0f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e,
0x66, 0x6f, 0x42, 0x0d, 0x0a, 0x0b, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x6e, 0x66,
0x6f, 0x22, 0xe2, 0x01, 0x0a, 0x0e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x54, 0x78,
0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63,
0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e,
0x63, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28,
0x05, 0x52, 0x05, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x12, 0x2e, 0x0a, 0x0a, 0x6d, 0x6f, 0x64, 0x75,
0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x67,
0x77, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x6d, 0x6f,
0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x6f, 0x61, 0x72,
0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x12, 0x18,
0x0a, 0x07, 0x61, 0x6e, 0x74, 0x65, 0x6e, 0x6e, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52,
0x07, 0x61, 0x6e, 0x74, 0x65, 0x6e, 0x6e, 0x61, 0x12, 0x22, 0x0a, 0x06, 0x74, 0x69, 0x6d, 0x69,
0x6e, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x67, 0x77, 0x2e, 0x54, 0x69,
0x6d, 0x69, 0x6e, 0x67, 0x52, 0x06, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x12, 0x18, 0x0a, 0x07,
0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63,
0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0xb9, 0x01, 0x0a, 0x06, 0x54, 0x69, 0x6d, 0x69, 0x6e,
0x67, 0x12, 0x3d, 0x0a, 0x0b, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x6c, 0x79,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x77, 0x2e, 0x49, 0x6d, 0x6d, 0x65,
0x6e, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x18, 0x08, 0x20,
0x01, 0x28, 0x0d, 0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x19, 0x0a, 0x08,
0x72, 0x66, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07,
0x72, 0x66, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x6f, 0x61, 0x72, 0x64,
0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x12, 0x18, 0x0a,
0x07, 0x61, 0x6e, 0x74, 0x65, 0x6e, 0x6e, 0x61, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07,
0x61, 0x6e, 0x74, 0x65, 0x6e, 0x6e, 0x61, 0x12, 0x2c, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x63, 0x6f, 0x6d, 0x6d,
0x6f, 0x6e, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x6c, 0x6f, 0x63,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74,
0x18, 0x0d, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12,
0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x0e, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61,
0x64, 0x61, 0x74, 0x61, 0x22, 0xaf, 0x05, 0x0a, 0x14, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e,
0x6b, 0x54, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x12, 0x1d, 0x0a,
0x0a, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
0x0c, 0x52, 0x09, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09,
0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52,
0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x6f,
0x77, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x70, 0x6f, 0x77, 0x65, 0x72,
0x12, 0x32, 0x0a, 0x0a, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07,
0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x6f,
0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x12, 0x4a, 0x0a, 0x14, 0x6c, 0x6f, 0x72, 0x61, 0x5f, 0x6d, 0x6f, 0x64,
0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x08, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x77, 0x2e, 0x4c, 0x6f, 0x72, 0x61, 0x4d, 0x6f, 0x64, 0x75,
0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x48, 0x00, 0x52, 0x12, 0x6c, 0x6f,
0x72, 0x61, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f,
0x12, 0x47, 0x0a, 0x13, 0x66, 0x73, 0x6b, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e,
0x67, 0x77, 0x2e, 0x46, 0x73, 0x6b, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x49, 0x6e, 0x66, 0x6f, 0x48, 0x00, 0x52, 0x11, 0x66, 0x73, 0x6b, 0x4d, 0x6f, 0x64, 0x75, 0x6c,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x6f, 0x61,
0x72, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x12,
0x18, 0x0a, 0x07, 0x61, 0x6e, 0x74, 0x65, 0x6e, 0x6e, 0x61, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d,
0x52, 0x07, 0x61, 0x6e, 0x74, 0x65, 0x6e, 0x6e, 0x61, 0x12, 0x2a, 0x0a, 0x06, 0x74, 0x69, 0x6d,
0x69, 0x6e, 0x67, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x67, 0x77, 0x2e, 0x44,
0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x52, 0x06, 0x74,
0x69, 0x6d, 0x69, 0x6e, 0x67, 0x12, 0x53, 0x0a, 0x17, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61,
0x74, 0x65, 0x6c, 0x79, 0x5f, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x6e, 0x66, 0x6f,
0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x77, 0x2e, 0x49, 0x6d, 0x6d, 0x65,
0x64, 0x69, 0x61, 0x74, 0x65, 0x6c, 0x79, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66,
0x6f, 0x48, 0x00, 0x52, 0x0b, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x6c, 0x79,
0x12, 0x2b, 0x0a, 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x13, 0x2e, 0x67, 0x77, 0x2e, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67,
0x49, 0x6e, 0x66, 0x6f, 0x48, 0x00, 0x52, 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x35, 0x0a,
0x09, 0x67, 0x70, 0x73, 0x5f, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x16, 0x2e, 0x67, 0x77, 0x2e, 0x47, 0x50, 0x53, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x54, 0x69,
0x6d, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x48, 0x00, 0x52, 0x08, 0x67, 0x70, 0x73, 0x45,
0x70, 0x6f, 0x63, 0x68, 0x42, 0x0c, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65,
0x72, 0x73, 0x22, 0x17, 0x0a, 0x15, 0x49, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x6c,
0x79, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x42, 0x0a, 0x0f, 0x44,
0x65, 0x6c, 0x61, 0x79, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2f,
0x0a, 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e,
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x22,
0x60, 0x0a, 0x12, 0x47, 0x50, 0x53, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x54, 0x69, 0x6d, 0x69, 0x6e,
0x67, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x4a, 0x0a, 0x14, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x73, 0x69,
0x6e, 0x63, 0x65, 0x5f, 0x67, 0x70, 0x73, 0x5f, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x11,
0x74, 0x69, 0x6d, 0x65, 0x53, 0x69, 0x6e, 0x63, 0x65, 0x47, 0x70, 0x73, 0x45, 0x70, 0x6f, 0x63,
0x68, 0x22, 0x80, 0x02, 0x0a, 0x0b, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x46, 0x72, 0x61, 0x6d,
0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x68, 0x79, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x68, 0x79, 0x50, 0x61, 0x79, 0x6c, 0x6f,
0x61, 0x64, 0x12, 0x3c, 0x0a, 0x0e, 0x74, 0x78, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x6c, 0x65,
0x67, 0x61, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x77, 0x2e,
0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x54, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x4c, 0x65, 0x67, 0x61,
0x63, 0x79, 0x52, 0x0c, 0x74, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79,
0x12, 0x3c, 0x0a, 0x0e, 0x72, 0x78, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x6c, 0x65, 0x67, 0x61,
0x63, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x77, 0x2e, 0x55, 0x70,
0x6c, 0x69, 0x6e, 0x6b, 0x52, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79,
0x52, 0x0c, 0x72, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x12, 0x29,
0x0a, 0x07, 0x74, 0x78, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x10, 0x2e, 0x67, 0x77, 0x2e, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x54, 0x78, 0x49, 0x6e, 0x66,
0x6f, 0x52, 0x06, 0x74, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x29, 0x0a, 0x07, 0x72, 0x78, 0x5f,
0x69, 0x6e, 0x66, 0x6f, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x67, 0x77, 0x2e,
0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x52, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x72, 0x78,
0x49, 0x6e, 0x66, 0x6f, 0x22, 0x87, 0x01, 0x0a, 0x0e, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x46,
0x72, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x68, 0x79, 0x5f, 0x70,
0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x68,
0x79, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x29, 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x69,
0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x67, 0x77, 0x2e, 0x55,
0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x54, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x74, 0x78, 0x49,
0x6e, 0x66, 0x6f, 0x12, 0x29, 0x0a, 0x07, 0x72, 0x78, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x03,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x67, 0x77, 0x2e, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b,
0x52, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x72, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0xd6,
0x01, 0x0a, 0x0d, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65,
0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x69, 0x64, 0x18,
0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x49,
0x64, 0x12, 0x2c, 0x0a, 0x12, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x69, 0x64,
0x5f, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x64,
0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x49, 0x64, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x12,
0x2b, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15,
0x2e, 0x67, 0x77, 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x46, 0x72, 0x61, 0x6d,
0x65, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x2a, 0x0a, 0x11,
0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x5f, 0x6c, 0x65, 0x67, 0x61, 0x63,
0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
0x49, 0x64, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x61, 0x74, 0x65,
0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x61,
0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x22, 0xa1, 0x01, 0x0a, 0x11, 0x44, 0x6f, 0x77, 0x6e,
0x6c, 0x69, 0x6e, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x1f, 0x0a,
0x0b, 0x70, 0x68, 0x79, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0c, 0x52, 0x0a, 0x70, 0x68, 0x79, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x3e,
0x0a, 0x0e, 0x74, 0x78, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79,
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x67, 0x77, 0x2e, 0x44, 0x6f, 0x77, 0x6e,
0x6c, 0x69, 0x6e, 0x6b, 0x54, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79,
0x52, 0x0c, 0x74, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x12, 0x2b,
0x0a, 0x07, 0x74, 0x78, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x12, 0x2e, 0x67, 0x77, 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x54, 0x78, 0x49,
0x6e, 0x66, 0x6f, 0x52, 0x06, 0x74, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0xd6, 0x01, 0x0a, 0x0d,
0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x54, 0x78, 0x41, 0x63, 0x6b, 0x12, 0x2a, 0x0a,
0x11, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x5f, 0x6c, 0x65, 0x67, 0x61,
0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61,
0x79, 0x49, 0x64, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x61, 0x74,
0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67,
0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x6f, 0x77, 0x6e,
0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x64,
0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x64, 0x6f, 0x77,
0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x69, 0x64, 0x5f, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x18,
0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x49,
0x64, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x12, 0x2b, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73,
0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x67, 0x77, 0x2e, 0x44, 0x6f, 0x77, 0x6e,
0x6c, 0x69, 0x6e, 0x6b, 0x54, 0x78, 0x41, 0x63, 0x6b, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69,
0x74, 0x65, 0x6d, 0x73, 0x22, 0x3c, 0x0a, 0x11, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b,
0x54, 0x78, 0x41, 0x63, 0x6b, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x27, 0x0a, 0x06, 0x73, 0x74, 0x61,
0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x67, 0x77, 0x2e, 0x54,
0x78, 0x41, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74,
0x75, 0x73, 0x22, 0xf3, 0x01, 0x0a, 0x14, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x43, 0x6f,
0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x11, 0x67,
0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x5f, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49,
0x64, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x61, 0x74, 0x65, 0x77,
0x61, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x61, 0x74,
0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
0x12, 0x34, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03,
0x28, 0x0b, 0x32, 0x18, 0x2e, 0x67, 0x77, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x43,
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x63, 0x68,
0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x12, 0x40, 0x0a, 0x0e, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f,
0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19,
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x74, 0x73,
0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x22, 0xe3, 0x02, 0x0a, 0x14, 0x43, 0x68, 0x61,
0x6f, 0x48, 0x01, 0x52, 0x15, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x6c, 0x79,
0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x41, 0x0a, 0x11, 0x64, 0x65,
0x6c, 0x61, 0x79, 0x5f, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18,
0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x67, 0x77, 0x2e, 0x44, 0x65, 0x6c, 0x61, 0x79,
0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x48, 0x01, 0x52, 0x0f, 0x64, 0x65,
0x6c, 0x61, 0x79, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x4b, 0x0a,
0x15, 0x67, 0x70, 0x73, 0x5f, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x5f, 0x74, 0x69, 0x6d, 0x69, 0x6e,
0x67, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67,
0x77, 0x2e, 0x47, 0x50, 0x53, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67,
0x49, 0x6e, 0x66, 0x6f, 0x48, 0x01, 0x52, 0x12, 0x67, 0x70, 0x73, 0x45, 0x70, 0x6f, 0x63, 0x68,
0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f,
0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e,
0x74, 0x65, 0x78, 0x74, 0x42, 0x11, 0x0a, 0x0f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x42, 0x0d, 0x0a, 0x0b, 0x74, 0x69, 0x6d, 0x69, 0x6e,
0x67, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x22, 0xe2, 0x01, 0x0a, 0x0e, 0x44, 0x6f, 0x77, 0x6e, 0x6c,
0x69, 0x6e, 0x6b, 0x54, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x72, 0x65,
0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x66, 0x72,
0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x6f, 0x77, 0x65, 0x72,
0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x12, 0x2e, 0x0a,
0x0a, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x0e, 0x2e, 0x67, 0x77, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x52, 0x0a, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a,
0x05, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x62, 0x6f,
0x61, 0x72, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x6e, 0x74, 0x65, 0x6e, 0x6e, 0x61, 0x18, 0x05,
0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x61, 0x6e, 0x74, 0x65, 0x6e, 0x6e, 0x61, 0x12, 0x22, 0x0a,
0x06, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e,
0x67, 0x77, 0x2e, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x52, 0x06, 0x74, 0x69, 0x6d, 0x69, 0x6e,
0x67, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x07, 0x20, 0x01,
0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0xb9, 0x01, 0x0a, 0x06,
0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x12, 0x3d, 0x0a, 0x0b, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69,
0x61, 0x74, 0x65, 0x6c, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x77,
0x2e, 0x49, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x6c, 0x79, 0x54, 0x69, 0x6d, 0x69,
0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x48, 0x00, 0x52, 0x0b, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69,
0x61, 0x74, 0x65, 0x6c, 0x79, 0x12, 0x2b, 0x0a, 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x02,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x67, 0x77, 0x2e, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x54,
0x69, 0x6d, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x48, 0x00, 0x52, 0x05, 0x64, 0x65, 0x6c,
0x61, 0x79, 0x12, 0x35, 0x0a, 0x09, 0x67, 0x70, 0x73, 0x5f, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18,
0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x77, 0x2e, 0x47, 0x50, 0x53, 0x45, 0x70,
0x6f, 0x63, 0x68, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x48, 0x00, 0x52,
0x08, 0x67, 0x70, 0x73, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x42, 0x0c, 0x0a, 0x0a, 0x70, 0x61, 0x72,
0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x22, 0x17, 0x0a, 0x15, 0x49, 0x6d, 0x6d, 0x65, 0x64,
0x69, 0x61, 0x74, 0x65, 0x6c, 0x79, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f,
0x22, 0x42, 0x0a, 0x0f, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x49,
0x6e, 0x66, 0x6f, 0x12, 0x2f, 0x0a, 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x64,
0x65, 0x6c, 0x61, 0x79, 0x22, 0x60, 0x0a, 0x12, 0x47, 0x50, 0x53, 0x45, 0x70, 0x6f, 0x63, 0x68,
0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x4a, 0x0a, 0x14, 0x74, 0x69,
0x6d, 0x65, 0x5f, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x5f, 0x67, 0x70, 0x73, 0x5f, 0x65, 0x70, 0x6f,
0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x52, 0x11, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x69, 0x6e, 0x63, 0x65, 0x47, 0x70,
0x73, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x22, 0x80, 0x02, 0x0a, 0x0b, 0x55, 0x70, 0x6c, 0x69, 0x6e,
0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x68, 0x79, 0x5f, 0x70, 0x61,
0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x68, 0x79,
0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x3c, 0x0a, 0x0e, 0x74, 0x78, 0x5f, 0x69, 0x6e,
0x66, 0x6f, 0x5f, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x16, 0x2e, 0x67, 0x77, 0x2e, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x54, 0x78, 0x49, 0x6e, 0x66,
0x6f, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x52, 0x0c, 0x74, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x4c,
0x65, 0x67, 0x61, 0x63, 0x79, 0x12, 0x3c, 0x0a, 0x0e, 0x72, 0x78, 0x5f, 0x69, 0x6e, 0x66, 0x6f,
0x5f, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e,
0x67, 0x77, 0x2e, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x52, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x4c,
0x65, 0x67, 0x61, 0x63, 0x79, 0x52, 0x0c, 0x72, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x4c, 0x65, 0x67,
0x61, 0x63, 0x79, 0x12, 0x29, 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x04,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x67, 0x77, 0x2e, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b,
0x54, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x74, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x29,
0x0a, 0x07, 0x72, 0x78, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x10, 0x2e, 0x67, 0x77, 0x2e, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x52, 0x78, 0x49, 0x6e, 0x66,
0x6f, 0x52, 0x06, 0x72, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x87, 0x01, 0x0a, 0x0e, 0x55, 0x70,
0x6c, 0x69, 0x6e, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x74, 0x12, 0x1f, 0x0a, 0x0b,
0x70, 0x68, 0x79, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
0x0c, 0x52, 0x0a, 0x70, 0x68, 0x79, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x29, 0x0a,
0x07, 0x74, 0x78, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10,
0x2e, 0x67, 0x77, 0x2e, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x54, 0x78, 0x49, 0x6e, 0x66, 0x6f,
0x52, 0x06, 0x74, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x29, 0x0a, 0x07, 0x72, 0x78, 0x5f, 0x69,
0x6e, 0x66, 0x6f, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x67, 0x77, 0x2e, 0x55,
0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x52, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x72, 0x78, 0x49,
0x6e, 0x66, 0x6f, 0x22, 0xd6, 0x01, 0x0a, 0x0d, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b,
0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e,
0x6b, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x64, 0x6f, 0x77, 0x6e,
0x6c, 0x69, 0x6e, 0x6b, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69,
0x6e, 0x6b, 0x5f, 0x69, 0x64, 0x5f, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x18, 0x04, 0x20, 0x01,
0x28, 0x0c, 0x52, 0x10, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x49, 0x64, 0x4c, 0x65,
0x67, 0x61, 0x63, 0x79, 0x12, 0x2b, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x05, 0x20,
0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x67, 0x77, 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e,
0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d,
0x73, 0x12, 0x2a, 0x0a, 0x11, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x5f,
0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x67, 0x61,
0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x12, 0x1d, 0x0a,
0x0a, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28,
0x09, 0x52, 0x09, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x22, 0xa1, 0x01, 0x0a,
0x11, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x49, 0x74,
0x65, 0x6d, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x68, 0x79, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61,
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x68, 0x79, 0x50, 0x61, 0x79, 0x6c,
0x6f, 0x61, 0x64, 0x12, 0x3e, 0x0a, 0x0e, 0x74, 0x78, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x6c,
0x65, 0x67, 0x61, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x67, 0x77,
0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x54, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x4c,
0x65, 0x67, 0x61, 0x63, 0x79, 0x52, 0x0c, 0x74, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x4c, 0x65, 0x67,
0x61, 0x63, 0x79, 0x12, 0x2b, 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x03,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x77, 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69,
0x6e, 0x6b, 0x54, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x74, 0x78, 0x49, 0x6e, 0x66, 0x6f,
0x22, 0xd6, 0x01, 0x0a, 0x0d, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x54, 0x78, 0x41,
0x63, 0x6b, 0x12, 0x2a, 0x0a, 0x11, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64,
0x5f, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x67,
0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x12, 0x1d,
0x0a, 0x0a, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01,
0x28, 0x09, 0x52, 0x09, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x12, 0x1f, 0x0a,
0x0b, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01,
0x28, 0x0d, 0x52, 0x0a, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x49, 0x64, 0x12, 0x2c,
0x0a, 0x12, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x69, 0x64, 0x5f, 0x6c, 0x65,
0x67, 0x61, 0x63, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x64, 0x6f, 0x77, 0x6e,
0x6c, 0x69, 0x6e, 0x6b, 0x49, 0x64, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x12, 0x2b, 0x0a, 0x05,
0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x67, 0x77,
0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x54, 0x78, 0x41, 0x63, 0x6b, 0x49, 0x74,
0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x3c, 0x0a, 0x11, 0x44, 0x6f, 0x77,
0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x54, 0x78, 0x41, 0x63, 0x6b, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x27,
0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f,
0x2e, 0x67, 0x77, 0x2e, 0x54, 0x78, 0x41, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52,
0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0xf3, 0x01, 0x0a, 0x14, 0x47, 0x61, 0x74, 0x65,
0x77, 0x61, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x12, 0x2a, 0x0a, 0x11, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x5f, 0x6c,
0x65, 0x67, 0x61, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x67, 0x61, 0x74,
0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x12, 0x1d, 0x0a, 0x0a,
0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09,
0x52, 0x09, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76,
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65,
0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x34, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c,
0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x67, 0x77, 0x2e, 0x43, 0x68, 0x61,
0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x01,
0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12,
0x3f, 0x0a, 0x11, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x65,
0x67, 0x61, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x63, 0x6f, 0x6d,
0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x10,
0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79,
0x12, 0x50, 0x0a, 0x16, 0x6c, 0x6f, 0x72, 0x61, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x18, 0x2e, 0x67, 0x77, 0x2e, 0x4c, 0x6f, 0x72, 0x61, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x14, 0x6c, 0x6f,
0x72, 0x61, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66,
0x69, 0x67, 0x12, 0x4d, 0x0a, 0x15, 0x66, 0x73, 0x6b, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x17, 0x2e, 0x67, 0x77, 0x2e, 0x46, 0x73, 0x6b, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x13, 0x66, 0x73,
0x6b, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69,
0x67, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d,
0x52, 0x05, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x6d, 0x6f, 0x64,
0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x64, 0x65,
0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x42, 0x13, 0x0a, 0x11, 0x6d, 0x6f, 0x64,
0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x8c,
0x01, 0x0a, 0x14, 0x4c, 0x6f, 0x72, 0x61, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x29, 0x0a, 0x10, 0x62, 0x61, 0x6e, 0x64, 0x77,
0x69, 0x64, 0x74, 0x68, 0x5f, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
0x0d, 0x52, 0x0f, 0x62, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64, 0x74, 0x68, 0x4c, 0x65, 0x67, 0x61,
0x63, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x62, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64, 0x74, 0x68, 0x18,
0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x62, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64, 0x74, 0x68,
0x12, 0x2b, 0x0a, 0x11, 0x73, 0x70, 0x72, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x66, 0x61,
0x63, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x10, 0x73, 0x70, 0x72,
0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x46, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x22, 0x78, 0x0a,
0x13, 0x46, 0x73, 0x6b, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f,
0x6e, 0x66, 0x69, 0x67, 0x12, 0x29, 0x0a, 0x10, 0x62, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64, 0x74,
0x68, 0x5f, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f,
0x62, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64, 0x74, 0x68, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x12,
0x1c, 0x0a, 0x09, 0x62, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01,
0x28, 0x0d, 0x52, 0x09, 0x62, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64, 0x74, 0x68, 0x12, 0x18, 0x0a,
0x07, 0x62, 0x69, 0x74, 0x72, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07,
0x62, 0x69, 0x74, 0x72, 0x61, 0x74, 0x65, 0x22, 0xc1, 0x02, 0x0a, 0x19, 0x47, 0x61, 0x74, 0x65,
0x77, 0x61, 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
0x5f, 0x69, 0x64, 0x5f, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c,
0x52, 0x0f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x4c, 0x65, 0x67, 0x61, 0x63,
0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x18,
0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64,
0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x65, 0x78,
0x65, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x65, 0x78, 0x65,
0x63, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x64, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01,
0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x64, 0x69, 0x6e, 0x12, 0x50, 0x0a, 0x0b, 0x65, 0x6e, 0x76,
0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e,
0x2e, 0x67, 0x77, 0x2e, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x61,
0x6e, 0x64, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x45, 0x6e,
0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b,
0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x1a, 0x3e, 0x0a, 0x10, 0x45,
0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 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, 0x22, 0xc6, 0x01, 0x0a, 0x1a,
0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x78,
0x65, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x67, 0x61,
0x6e, 0x52, 0x08, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x12, 0x40, 0x0a, 0x0e, 0x73,
0x74, 0x61, 0x74, 0x73, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x04, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d,
0x73, 0x74, 0x61, 0x74, 0x73, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x22, 0xe3, 0x02,
0x0a, 0x14, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75,
0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65,
0x6e, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75,
0x65, 0x6e, 0x63, 0x79, 0x12, 0x3f, 0x0a, 0x11, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x5f, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32,
0x12, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x52, 0x10, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c,
0x65, 0x67, 0x61, 0x63, 0x79, 0x12, 0x50, 0x0a, 0x16, 0x6c, 0x6f, 0x72, 0x61, 0x5f, 0x6d, 0x6f,
0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18,
0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x67, 0x77, 0x2e, 0x4c, 0x6f, 0x72, 0x61, 0x4d,
0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48,
0x00, 0x52, 0x14, 0x6c, 0x6f, 0x72, 0x61, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4d, 0x0a, 0x15, 0x66, 0x73, 0x6b, 0x5f, 0x6d,
0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x77, 0x2e, 0x46, 0x73, 0x6b, 0x4d,
0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48,
0x00, 0x52, 0x13, 0x66, 0x73, 0x6b, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x18,
0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x12, 0x20, 0x0a, 0x0b,
0x64, 0x65, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28,
0x0d, 0x52, 0x0b, 0x64, 0x65, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x42, 0x13,
0x0a, 0x11, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e,
0x66, 0x69, 0x67, 0x22, 0x8c, 0x01, 0x0a, 0x14, 0x4c, 0x6f, 0x72, 0x61, 0x4d, 0x6f, 0x64, 0x75,
0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x29, 0x0a, 0x10,
0x62, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64, 0x74, 0x68, 0x5f, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x62, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64, 0x74,
0x68, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x62, 0x61, 0x6e, 0x64, 0x77,
0x69, 0x64, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x62, 0x61, 0x6e, 0x64,
0x77, 0x69, 0x64, 0x74, 0x68, 0x12, 0x2b, 0x0a, 0x11, 0x73, 0x70, 0x72, 0x65, 0x61, 0x64, 0x69,
0x6e, 0x67, 0x5f, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0d,
0x52, 0x10, 0x73, 0x70, 0x72, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x46, 0x61, 0x63, 0x74, 0x6f,
0x72, 0x73, 0x22, 0x78, 0x0a, 0x13, 0x46, 0x73, 0x6b, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x29, 0x0a, 0x10, 0x62, 0x61, 0x6e,
0x64, 0x77, 0x69, 0x64, 0x74, 0x68, 0x5f, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0d, 0x52, 0x0f, 0x62, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64, 0x74, 0x68, 0x4c, 0x65,
0x67, 0x61, 0x63, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x62, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64, 0x74,
0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x62, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64,
0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x69, 0x74, 0x72, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20,
0x01, 0x28, 0x0d, 0x52, 0x07, 0x62, 0x69, 0x74, 0x72, 0x61, 0x74, 0x65, 0x22, 0xc1, 0x02, 0x0a,
0x19, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45,
0x78, 0x65, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x67, 0x61,
0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x5f, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x18,
0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64,
0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61,
0x79, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x61, 0x74, 0x65,
0x77, 0x61, 0x79, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x65, 0x78, 0x65, 0x63, 0x5f, 0x69, 0x64,
0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x65, 0x78, 0x65, 0x63, 0x49, 0x64, 0x12, 0x16,
0x0a, 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06,
0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x64, 0x65, 0x72, 0x72,
0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x74, 0x64, 0x65, 0x72, 0x72, 0x12, 0x14,
0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65,
0x72, 0x72, 0x6f, 0x72, 0x22, 0x7e, 0x0a, 0x17, 0x52, 0x61, 0x77, 0x50, 0x61, 0x63, 0x6b, 0x65,
0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12,
0x77, 0x61, 0x79, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64,
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12,
0x17, 0x0a, 0x07, 0x65, 0x78, 0x65, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d,
0x52, 0x06, 0x65, 0x78, 0x65, 0x63, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x64, 0x69,
0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x64, 0x69, 0x6e, 0x12, 0x50,
0x0a, 0x0b, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20,
0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x67, 0x77, 0x2e, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x2e, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x45, 0x6e,
0x74, 0x72, 0x79, 0x52, 0x0b, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74,
0x1a, 0x3e, 0x0a, 0x10, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 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,
0x22, 0xc6, 0x01, 0x0a, 0x1a, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x43, 0x6f, 0x6d, 0x6d,
0x61, 0x6e, 0x64, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x2a, 0x0a, 0x11, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x5f, 0x6c, 0x65,
0x67, 0x61, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x67, 0x61, 0x74, 0x65,
0x77, 0x61, 0x79, 0x49, 0x64, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x67,
0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
0x09, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61,
0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, 0x79,
0x6c, 0x6f, 0x61, 0x64, 0x22, 0x80, 0x01, 0x0a, 0x19, 0x52, 0x61, 0x77, 0x50, 0x61, 0x63, 0x6b,
0x65, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x61,
0x6e, 0x64, 0x12, 0x2a, 0x0a, 0x11, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64,
0x5f, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x67,
0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x12, 0x1d,
0x0a, 0x0a, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01,
0x28, 0x09, 0x52, 0x09, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x12, 0x18, 0x0a,
0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07,
0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xa3, 0x01, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x6e,
0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
0x5f, 0x69, 0x64, 0x5f, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c,
0x52, 0x0f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x4c, 0x65, 0x67, 0x61, 0x63,
0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x18,
0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64,
0x12, 0x29, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32,
0x13, 0x2e, 0x67, 0x77, 0x2e, 0x43, 0x6f, 0x6e, 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, 0xbc, 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, 0x42, 0x55, 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, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52,
0x09, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x65, 0x78,
0x65, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x65, 0x78, 0x65,
0x63, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x18, 0x03, 0x20,
0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73,
0x74, 0x64, 0x65, 0x72, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x74, 0x64,
0x65, 0x72, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01,
0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x7e, 0x0a, 0x17, 0x52, 0x61, 0x77,
0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x45,
0x76, 0x65, 0x6e, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f,
0x69, 0x64, 0x5f, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52,
0x0f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79,
0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x04,
0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x12,
0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c,
0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x80, 0x01, 0x0a, 0x19, 0x52, 0x61,
0x77, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72,
0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x2a, 0x0a, 0x11, 0x67, 0x61, 0x74, 0x65, 0x77,
0x61, 0x79, 0x5f, 0x69, 0x64, 0x5f, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0c, 0x52, 0x0f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x4c, 0x65, 0x67,
0x61, 0x63, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69,
0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20,
0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xa3, 0x01, 0x0a,
0x09, 0x43, 0x6f, 0x6e, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x67, 0x61,
0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x5f, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x18,
0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64,
0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61,
0x79, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x61, 0x74, 0x65,
0x77, 0x61, 0x79, 0x49, 0x64, 0x12, 0x29, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02,
0x20, 0x01, 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x67, 0x77, 0x2e, 0x43, 0x6f, 0x6e, 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, 0xbc, 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, 0x42, 0x55, 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, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (

View File

@ -35,6 +35,9 @@ export class UplinkFrameLog extends jspb.Message {
hasTime(): boolean;
clearTime(): UplinkFrameLog;
getPlaintextMacCommands(): boolean;
setPlaintextMacCommands(value: boolean): UplinkFrameLog;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): UplinkFrameLog.AsObject;
static toObject(includeInstance: boolean, msg: UplinkFrameLog): UplinkFrameLog.AsObject;
@ -52,6 +55,7 @@ export namespace UplinkFrameLog {
devAddr: string,
devEui: string,
time?: google_protobuf_timestamp_pb.Timestamp.AsObject,
plaintextMacCommands: boolean,
}
}
@ -86,6 +90,9 @@ export class DownlinkFrameLog extends jspb.Message {
getDevEui(): string;
setDevEui(value: string): DownlinkFrameLog;
getPlaintextMacCommands(): boolean;
setPlaintextMacCommands(value: boolean): DownlinkFrameLog;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): DownlinkFrameLog.AsObject;
static toObject(includeInstance: boolean, msg: DownlinkFrameLog): DownlinkFrameLog.AsObject;
@ -104,6 +111,7 @@ export namespace DownlinkFrameLog {
mType: common_common_pb.MType,
devAddr: string,
devEui: string,
plaintextMacCommands: boolean,
}
}

View File

@ -111,7 +111,8 @@ proto.api.UplinkFrameLog.toObject = function(includeInstance, msg) {
mType: jspb.Message.getFieldWithDefault(msg, 4, 0),
devAddr: jspb.Message.getFieldWithDefault(msg, 5, ""),
devEui: jspb.Message.getFieldWithDefault(msg, 6, ""),
time: (f = msg.getTime()) && google_protobuf_timestamp_pb.Timestamp.toObject(includeInstance, f)
time: (f = msg.getTime()) && google_protobuf_timestamp_pb.Timestamp.toObject(includeInstance, f),
plaintextMacCommands: jspb.Message.getBooleanFieldWithDefault(msg, 8, false)
};
if (includeInstance) {
@ -179,6 +180,10 @@ proto.api.UplinkFrameLog.deserializeBinaryFromReader = function(msg, reader) {
reader.readMessage(value,google_protobuf_timestamp_pb.Timestamp.deserializeBinaryFromReader);
msg.setTime(value);
break;
case 8:
var value = /** @type {boolean} */ (reader.readBool());
msg.setPlaintextMacCommands(value);
break;
default:
reader.skipField();
break;
@ -260,6 +265,13 @@ proto.api.UplinkFrameLog.serializeBinaryToWriter = function(message, writer) {
google_protobuf_timestamp_pb.Timestamp.serializeBinaryToWriter
);
}
f = message.getPlaintextMacCommands();
if (f) {
writer.writeBool(
8,
f
);
}
};
@ -471,6 +483,24 @@ proto.api.UplinkFrameLog.prototype.hasTime = function() {
};
/**
* optional bool plaintext_mac_commands = 8;
* @return {boolean}
*/
proto.api.UplinkFrameLog.prototype.getPlaintextMacCommands = function() {
return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 8, false));
};
/**
* @param {boolean} value
* @return {!proto.api.UplinkFrameLog} returns this
*/
proto.api.UplinkFrameLog.prototype.setPlaintextMacCommands = function(value) {
return jspb.Message.setProto3BooleanField(this, 8, value);
};
@ -510,7 +540,8 @@ proto.api.DownlinkFrameLog.toObject = function(includeInstance, msg) {
gatewayId: jspb.Message.getFieldWithDefault(msg, 5, ""),
mType: jspb.Message.getFieldWithDefault(msg, 6, 0),
devAddr: jspb.Message.getFieldWithDefault(msg, 7, ""),
devEui: jspb.Message.getFieldWithDefault(msg, 8, "")
devEui: jspb.Message.getFieldWithDefault(msg, 8, ""),
plaintextMacCommands: jspb.Message.getBooleanFieldWithDefault(msg, 9, false)
};
if (includeInstance) {
@ -581,6 +612,10 @@ proto.api.DownlinkFrameLog.deserializeBinaryFromReader = function(msg, reader) {
var value = /** @type {string} */ (reader.readString());
msg.setDevEui(value);
break;
case 9:
var value = /** @type {boolean} */ (reader.readBool());
msg.setPlaintextMacCommands(value);
break;
default:
reader.skipField();
break;
@ -668,6 +703,13 @@ proto.api.DownlinkFrameLog.serializeBinaryToWriter = function(message, writer) {
f
);
}
f = message.getPlaintextMacCommands();
if (f) {
writer.writeBool(
9,
f
);
}
};
@ -877,4 +919,22 @@ proto.api.DownlinkFrameLog.prototype.setDevEui = function(value) {
};
/**
* optional bool plaintext_mac_commands = 9;
* @return {boolean}
*/
proto.api.DownlinkFrameLog.prototype.getPlaintextMacCommands = function() {
return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 9, false));
};
/**
* @param {boolean} value
* @return {!proto.api.DownlinkFrameLog} returns this
*/
proto.api.DownlinkFrameLog.prototype.setPlaintextMacCommands = function(value) {
return jspb.Message.setProto3BooleanField(this, 9, value);
};
goog.object.extend(exports, proto.api);

View File

@ -1,6 +1,6 @@
{
"name": "@chirpstack/chirpstack-api-grpc-web",
"version": "4.0.0-test.15",
"version": "4.0.0-rc.4",
"description": "Chirpstack gRPC-web API",
"license": "MIT",
"devDependencies": {

View File

@ -36,6 +36,9 @@ export class UplinkFrameLog extends jspb.Message {
getTime(): google_protobuf_timestamp_pb.Timestamp | undefined;
setTime(value?: google_protobuf_timestamp_pb.Timestamp): void;
getPlaintextMacCommands(): boolean;
setPlaintextMacCommands(value: boolean): void;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): UplinkFrameLog.AsObject;
static toObject(includeInstance: boolean, msg: UplinkFrameLog): UplinkFrameLog.AsObject;
@ -55,6 +58,7 @@ export namespace UplinkFrameLog {
devAddr: string,
devEui: string,
time?: google_protobuf_timestamp_pb.Timestamp.AsObject,
plaintextMacCommands: boolean,
}
}
@ -89,6 +93,9 @@ export class DownlinkFrameLog extends jspb.Message {
getDevEui(): string;
setDevEui(value: string): void;
getPlaintextMacCommands(): boolean;
setPlaintextMacCommands(value: boolean): void;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): DownlinkFrameLog.AsObject;
static toObject(includeInstance: boolean, msg: DownlinkFrameLog): DownlinkFrameLog.AsObject;
@ -109,6 +116,7 @@ export namespace DownlinkFrameLog {
mType: common_common_pb.MTypeMap[keyof common_common_pb.MTypeMap],
devAddr: string,
devEui: string,
plaintextMacCommands: boolean,
}
}

View File

@ -74,7 +74,8 @@ proto.api.UplinkFrameLog.toObject = function(includeInstance, msg) {
mType: msg.getMType(),
devAddr: msg.getDevAddr(),
devEui: msg.getDevEui(),
time: (f = msg.getTime()) && google_protobuf_timestamp_pb.Timestamp.toObject(includeInstance, f)
time: (f = msg.getTime()) && google_protobuf_timestamp_pb.Timestamp.toObject(includeInstance, f),
plaintextMacCommands: msg.getPlaintextMacCommands()
};
if (includeInstance) {
@ -143,6 +144,10 @@ proto.api.UplinkFrameLog.deserializeBinaryFromReader = function(msg, reader) {
reader.readMessage(value,google_protobuf_timestamp_pb.Timestamp.deserializeBinaryFromReader);
msg.setTime(value);
break;
case 8:
var value = /** @type {boolean} */ (reader.readBool());
msg.setPlaintextMacCommands(value);
break;
default:
reader.skipField();
break;
@ -233,6 +238,13 @@ proto.api.UplinkFrameLog.prototype.serializeBinaryToWriter = function (writer) {
google_protobuf_timestamp_pb.Timestamp.serializeBinaryToWriter
);
}
f = this.getPlaintextMacCommands();
if (f) {
writer.writeBool(
8,
f
);
}
};
@ -412,6 +424,23 @@ proto.api.UplinkFrameLog.prototype.hasTime = function() {
};
/**
* optional bool plaintext_mac_commands = 8;
* Note that Boolean fields may be set to 0/1 when serialized from a Java server.
* You should avoid comparisons like {@code val === true/false} in those cases.
* @return {boolean}
*/
proto.api.UplinkFrameLog.prototype.getPlaintextMacCommands = function() {
return /** @type {boolean} */ (jspb.Message.getFieldProto3(this, 8, false));
};
/** @param {boolean} value */
proto.api.UplinkFrameLog.prototype.setPlaintextMacCommands = function(value) {
jspb.Message.setField(this, 8, value);
};
/**
* Generated by JsPbCodeGenerator.
@ -465,7 +494,8 @@ proto.api.DownlinkFrameLog.toObject = function(includeInstance, msg) {
gatewayId: msg.getGatewayId(),
mType: msg.getMType(),
devAddr: msg.getDevAddr(),
devEui: msg.getDevEui()
devEui: msg.getDevEui(),
plaintextMacCommands: msg.getPlaintextMacCommands()
};
if (includeInstance) {
@ -536,6 +566,10 @@ proto.api.DownlinkFrameLog.deserializeBinaryFromReader = function(msg, reader) {
var value = /** @type {string} */ (reader.readString());
msg.setDevEui(value);
break;
case 9:
var value = /** @type {boolean} */ (reader.readBool());
msg.setPlaintextMacCommands(value);
break;
default:
reader.skipField();
break;
@ -632,6 +666,13 @@ proto.api.DownlinkFrameLog.prototype.serializeBinaryToWriter = function (writer)
f
);
}
f = this.getPlaintextMacCommands();
if (f) {
writer.writeBool(
9,
f
);
}
};
@ -818,4 +859,21 @@ proto.api.DownlinkFrameLog.prototype.setDevEui = function(value) {
};
/**
* optional bool plaintext_mac_commands = 9;
* Note that Boolean fields may be set to 0/1 when serialized from a Java server.
* You should avoid comparisons like {@code val === true/false} in those cases.
* @return {boolean}
*/
proto.api.DownlinkFrameLog.prototype.getPlaintextMacCommands = function() {
return /** @type {boolean} */ (jspb.Message.getFieldProto3(this, 9, false));
};
/** @param {boolean} value */
proto.api.DownlinkFrameLog.prototype.setPlaintextMacCommands = function(value) {
jspb.Message.setField(this, 9, value);
};
goog.object.extend(exports, proto.api);

View File

@ -513,6 +513,12 @@ export class UplinkRxInfo extends jspb.Message {
getSnr(): number;
setSnr(value: number): void;
getChannel(): number;
setChannel(value: number): void;
getRfChain(): number;
setRfChain(value: number): void;
getBoard(): number;
setBoard(value: number): void;
@ -553,6 +559,8 @@ export namespace UplinkRxInfo {
fineTimeSinceGpsEpoch?: google_protobuf_duration_pb.Duration.AsObject,
rssi: number,
snr: number,
channel: number,
rfChain: number,
board: number,
antenna: number,
location?: common_common_pb.Location.AsObject,

110
api/js/gw/gw_pb.js vendored
View File

@ -3664,6 +3664,8 @@ proto.gw.UplinkRxInfo.toObject = function(includeInstance, msg) {
fineTimeSinceGpsEpoch: (f = msg.getFineTimeSinceGpsEpoch()) && google_protobuf_duration_pb.Duration.toObject(includeInstance, f),
rssi: msg.getRssi(),
snr: msg.getSnr(),
channel: msg.getChannel(),
rfChain: msg.getRfChain(),
board: msg.getBoard(),
antenna: msg.getAntenna(),
location: (f = msg.getLocation()) && common_common_pb.Location.toObject(includeInstance, f),
@ -3738,22 +3740,30 @@ proto.gw.UplinkRxInfo.deserializeBinaryFromReader = function(msg, reader) {
break;
case 8:
var value = /** @type {number} */ (reader.readUint32());
msg.setBoard(value);
msg.setChannel(value);
break;
case 9:
var value = /** @type {number} */ (reader.readUint32());
msg.setAntenna(value);
msg.setRfChain(value);
break;
case 10:
var value = /** @type {number} */ (reader.readUint32());
msg.setBoard(value);
break;
case 11:
var value = /** @type {number} */ (reader.readUint32());
msg.setAntenna(value);
break;
case 12:
var value = new common_common_pb.Location;
reader.readMessage(value,common_common_pb.Location.deserializeBinaryFromReader);
msg.setLocation(value);
break;
case 11:
case 13:
var value = /** @type {!Uint8Array} */ (reader.readBytes());
msg.setContext(value);
break;
case 12:
case 14:
var value = new google_protobuf_struct_pb.Struct;
reader.readMessage(value,google_protobuf_struct_pb.Struct.deserializeBinaryFromReader);
msg.setMetadata(value);
@ -3848,24 +3858,38 @@ proto.gw.UplinkRxInfo.prototype.serializeBinaryToWriter = function (writer) {
f
);
}
f = this.getBoard();
f = this.getChannel();
if (f !== 0) {
writer.writeUint32(
8,
f
);
}
f = this.getAntenna();
f = this.getRfChain();
if (f !== 0) {
writer.writeUint32(
9,
f
);
}
f = this.getBoard();
if (f !== 0) {
writer.writeUint32(
10,
f
);
}
f = this.getAntenna();
if (f !== 0) {
writer.writeUint32(
11,
f
);
}
f = this.getLocation();
if (f != null) {
writer.writeMessage(
10,
12,
f,
common_common_pb.Location.serializeBinaryToWriter
);
@ -3873,14 +3897,14 @@ proto.gw.UplinkRxInfo.prototype.serializeBinaryToWriter = function (writer) {
f = this.getContext_asU8();
if (f.length > 0) {
writer.writeBytes(
11,
13,
f
);
}
f = this.getMetadata();
if (f != null) {
writer.writeMessage(
12,
14,
f,
google_protobuf_struct_pb.Struct.serializeBinaryToWriter
);
@ -4048,48 +4072,78 @@ proto.gw.UplinkRxInfo.prototype.setSnr = function(value) {
/**
* optional uint32 board = 8;
* optional uint32 channel = 8;
* @return {number}
*/
proto.gw.UplinkRxInfo.prototype.getBoard = function() {
proto.gw.UplinkRxInfo.prototype.getChannel = function() {
return /** @type {number} */ (jspb.Message.getFieldProto3(this, 8, 0));
};
/** @param {number} value */
proto.gw.UplinkRxInfo.prototype.setBoard = function(value) {
proto.gw.UplinkRxInfo.prototype.setChannel = function(value) {
jspb.Message.setField(this, 8, value);
};
/**
* optional uint32 antenna = 9;
* optional uint32 rf_chain = 9;
* @return {number}
*/
proto.gw.UplinkRxInfo.prototype.getAntenna = function() {
proto.gw.UplinkRxInfo.prototype.getRfChain = function() {
return /** @type {number} */ (jspb.Message.getFieldProto3(this, 9, 0));
};
/** @param {number} value */
proto.gw.UplinkRxInfo.prototype.setAntenna = function(value) {
proto.gw.UplinkRxInfo.prototype.setRfChain = function(value) {
jspb.Message.setField(this, 9, value);
};
/**
* optional common.Location location = 10;
* optional uint32 board = 10;
* @return {number}
*/
proto.gw.UplinkRxInfo.prototype.getBoard = function() {
return /** @type {number} */ (jspb.Message.getFieldProto3(this, 10, 0));
};
/** @param {number} value */
proto.gw.UplinkRxInfo.prototype.setBoard = function(value) {
jspb.Message.setField(this, 10, value);
};
/**
* optional uint32 antenna = 11;
* @return {number}
*/
proto.gw.UplinkRxInfo.prototype.getAntenna = function() {
return /** @type {number} */ (jspb.Message.getFieldProto3(this, 11, 0));
};
/** @param {number} value */
proto.gw.UplinkRxInfo.prototype.setAntenna = function(value) {
jspb.Message.setField(this, 11, value);
};
/**
* optional common.Location location = 12;
* @return {proto.common.Location}
*/
proto.gw.UplinkRxInfo.prototype.getLocation = function() {
return /** @type{proto.common.Location} */ (
jspb.Message.getWrapperField(this, common_common_pb.Location, 10));
jspb.Message.getWrapperField(this, common_common_pb.Location, 12));
};
/** @param {proto.common.Location|undefined} value */
proto.gw.UplinkRxInfo.prototype.setLocation = function(value) {
jspb.Message.setWrapperField(this, 10, value);
jspb.Message.setWrapperField(this, 12, value);
};
@ -4103,21 +4157,21 @@ proto.gw.UplinkRxInfo.prototype.clearLocation = function() {
* @return{!boolean}
*/
proto.gw.UplinkRxInfo.prototype.hasLocation = function() {
return jspb.Message.getField(this, 10) != null;
return jspb.Message.getField(this, 12) != null;
};
/**
* optional bytes context = 11;
* optional bytes context = 13;
* @return {!(string|Uint8Array)}
*/
proto.gw.UplinkRxInfo.prototype.getContext = function() {
return /** @type {!(string|Uint8Array)} */ (jspb.Message.getFieldProto3(this, 11, ""));
return /** @type {!(string|Uint8Array)} */ (jspb.Message.getFieldProto3(this, 13, ""));
};
/**
* optional bytes context = 11;
* optional bytes context = 13;
* This is a type-conversion wrapper around `getContext()`
* @return {string}
*/
@ -4128,7 +4182,7 @@ proto.gw.UplinkRxInfo.prototype.getContext_asB64 = function() {
/**
* optional bytes context = 11;
* optional bytes context = 13;
* Note that Uint8Array is not supported on all browsers.
* @see http://caniuse.com/Uint8Array
* This is a type-conversion wrapper around `getContext()`
@ -4142,23 +4196,23 @@ proto.gw.UplinkRxInfo.prototype.getContext_asU8 = function() {
/** @param {!(string|Uint8Array)} value */
proto.gw.UplinkRxInfo.prototype.setContext = function(value) {
jspb.Message.setField(this, 11, value);
jspb.Message.setField(this, 13, value);
};
/**
* optional google.protobuf.Struct metadata = 12;
* optional google.protobuf.Struct metadata = 14;
* @return {proto.google.protobuf.Struct}
*/
proto.gw.UplinkRxInfo.prototype.getMetadata = function() {
return /** @type{proto.google.protobuf.Struct} */ (
jspb.Message.getWrapperField(this, google_protobuf_struct_pb.Struct, 12));
jspb.Message.getWrapperField(this, google_protobuf_struct_pb.Struct, 14));
};
/** @param {proto.google.protobuf.Struct|undefined} value */
proto.gw.UplinkRxInfo.prototype.setMetadata = function(value) {
jspb.Message.setWrapperField(this, 12, value);
jspb.Message.setWrapperField(this, 14, value);
};
@ -4172,7 +4226,7 @@ proto.gw.UplinkRxInfo.prototype.clearMetadata = function() {
* @return{!boolean}
*/
proto.gw.UplinkRxInfo.prototype.hasMetadata = function() {
return jspb.Message.getField(this, 12) != null;
return jspb.Message.getField(this, 14) != null;
};

2
api/js/package.json vendored
View File

@ -1,6 +1,6 @@
{
"name": "@chirpstack/chirpstack-api",
"version": "4.0.0-test.15",
"version": "4.0.0-rc.4",
"description": "Chirpstack JS and TS API",
"license": "MIT",
"devDependencies": {

2
api/md/Makefile vendored
View File

@ -1,6 +1,6 @@
.PHONY: requirements api
all: requirements
all: requirements api
requirements:
go install github.com/pseudomuto/protoc-gen-doc/cmd/protoc-gen-doc@v1.5.1

562
api/md/api/api.md vendored
View File

@ -14,6 +14,7 @@
- [CreateAzureServiceBusIntegrationRequest](#api-CreateAzureServiceBusIntegrationRequest)
- [CreateGcpPubSubIntegrationRequest](#api-CreateGcpPubSubIntegrationRequest)
- [CreateHttpIntegrationRequest](#api-CreateHttpIntegrationRequest)
- [CreateIftttIntegrationRequest](#api-CreateIftttIntegrationRequest)
- [CreateInfluxDbIntegrationRequest](#api-CreateInfluxDbIntegrationRequest)
- [CreateLoraCloudIntegrationRequest](#api-CreateLoraCloudIntegrationRequest)
- [CreateMyDevicesIntegrationRequest](#api-CreateMyDevicesIntegrationRequest)
@ -24,6 +25,7 @@
- [DeleteAzureServiceBusIntegrationRequest](#api-DeleteAzureServiceBusIntegrationRequest)
- [DeleteGcpPubSubIntegrationRequest](#api-DeleteGcpPubSubIntegrationRequest)
- [DeleteHttpIntegrationRequest](#api-DeleteHttpIntegrationRequest)
- [DeleteIftttIntegrationRequest](#api-DeleteIftttIntegrationRequest)
- [DeleteInfluxDbIntegrationRequest](#api-DeleteInfluxDbIntegrationRequest)
- [DeleteLoraCloudIntegrationRequest](#api-DeleteLoraCloudIntegrationRequest)
- [DeleteMyDevicesIntegrationRequest](#api-DeleteMyDevicesIntegrationRequest)
@ -42,6 +44,8 @@
- [GetGcpPubSubIntegrationResponse](#api-GetGcpPubSubIntegrationResponse)
- [GetHttpIntegrationRequest](#api-GetHttpIntegrationRequest)
- [GetHttpIntegrationResponse](#api-GetHttpIntegrationResponse)
- [GetIftttIntegrationRequest](#api-GetIftttIntegrationRequest)
- [GetIftttIntegrationResponse](#api-GetIftttIntegrationResponse)
- [GetInfluxDbIntegrationRequest](#api-GetInfluxDbIntegrationRequest)
- [GetInfluxDbIntegrationResponse](#api-GetInfluxDbIntegrationResponse)
- [GetLoraCloudIntegrationRequest](#api-GetLoraCloudIntegrationRequest)
@ -54,6 +58,7 @@
- [GetThingsBoardIntegrationResponse](#api-GetThingsBoardIntegrationResponse)
- [HttpIntegration](#api-HttpIntegration)
- [HttpIntegration.HeadersEntry](#api-HttpIntegration-HeadersEntry)
- [IftttIntegration](#api-IftttIntegration)
- [InfluxDbIntegration](#api-InfluxDbIntegration)
- [IntegrationListItem](#api-IntegrationListItem)
- [ListApplicationsRequest](#api-ListApplicationsRequest)
@ -70,6 +75,7 @@
- [UpdateAzureServiceBusIntegrationRequest](#api-UpdateAzureServiceBusIntegrationRequest)
- [UpdateGcpPubSubIntegrationRequest](#api-UpdateGcpPubSubIntegrationRequest)
- [UpdateHttpIntegrationRequest](#api-UpdateHttpIntegrationRequest)
- [UpdateIftttIntegrationRequest](#api-UpdateIftttIntegrationRequest)
- [UpdateInfluxDbIntegrationRequest](#api-UpdateInfluxDbIntegrationRequest)
- [UpdateLoraCloudIntegrationRequest](#api-UpdateLoraCloudIntegrationRequest)
- [UpdateMyDevicesIntegrationRequest](#api-UpdateMyDevicesIntegrationRequest)
@ -97,10 +103,7 @@
- [DeviceKeys](#api-DeviceKeys)
- [DeviceListItem](#api-DeviceListItem)
- [DeviceQueueItem](#api-DeviceQueueItem)
- [DeviceStats](#api-DeviceStats)
- [DeviceStats.ErrorsEntry](#api-DeviceStats-ErrorsEntry)
- [DeviceStats.RxPacketsPerDrEntry](#api-DeviceStats-RxPacketsPerDrEntry)
- [DeviceStats.RxPacketsPerFrequencyEntry](#api-DeviceStats-RxPacketsPerFrequencyEntry)
- [DeviceState](#api-DeviceState)
- [DeviceStatus](#api-DeviceStatus)
- [EnqueueDeviceQueueItemRequest](#api-EnqueueDeviceQueueItemRequest)
- [EnqueueDeviceQueueItemResponse](#api-EnqueueDeviceQueueItemResponse)
@ -110,12 +113,16 @@
- [GetDeviceActivationResponse](#api-GetDeviceActivationResponse)
- [GetDeviceKeysRequest](#api-GetDeviceKeysRequest)
- [GetDeviceKeysResponse](#api-GetDeviceKeysResponse)
- [GetDeviceLinkMetricsRequest](#api-GetDeviceLinkMetricsRequest)
- [GetDeviceLinkMetricsResponse](#api-GetDeviceLinkMetricsResponse)
- [GetDeviceMetricsRequest](#api-GetDeviceMetricsRequest)
- [GetDeviceMetricsResponse](#api-GetDeviceMetricsResponse)
- [GetDeviceMetricsResponse.MetricsEntry](#api-GetDeviceMetricsResponse-MetricsEntry)
- [GetDeviceMetricsResponse.StatesEntry](#api-GetDeviceMetricsResponse-StatesEntry)
- [GetDeviceQueueItemsRequest](#api-GetDeviceQueueItemsRequest)
- [GetDeviceQueueItemsResponse](#api-GetDeviceQueueItemsResponse)
- [GetDeviceRequest](#api-GetDeviceRequest)
- [GetDeviceResponse](#api-GetDeviceResponse)
- [GetDeviceStatsRequest](#api-GetDeviceStatsRequest)
- [GetDeviceStatsResponse](#api-GetDeviceStatsResponse)
- [GetRandomDevAddrRequest](#api-GetRandomDevAddrRequest)
- [GetRandomDevAddrResponse](#api-GetRandomDevAddrResponse)
- [ListDevicesRequest](#api-ListDevicesRequest)
@ -131,6 +138,7 @@
- [CreateDeviceProfileResponse](#api-CreateDeviceProfileResponse)
- [DeleteDeviceProfileRequest](#api-DeleteDeviceProfileRequest)
- [DeviceProfile](#api-DeviceProfile)
- [DeviceProfile.MeasurementsEntry](#api-DeviceProfile-MeasurementsEntry)
- [DeviceProfile.TagsEntry](#api-DeviceProfile-TagsEntry)
- [DeviceProfileListItem](#api-DeviceProfileListItem)
- [GetDeviceProfileRequest](#api-GetDeviceProfileRequest)
@ -138,9 +146,11 @@
- [ListDeviceProfileAdrAlgorithmsResponse](#api-ListDeviceProfileAdrAlgorithmsResponse)
- [ListDeviceProfilesRequest](#api-ListDeviceProfilesRequest)
- [ListDeviceProfilesResponse](#api-ListDeviceProfilesResponse)
- [Measurement](#api-Measurement)
- [UpdateDeviceProfileRequest](#api-UpdateDeviceProfileRequest)
- [CodecRuntime](#api-CodecRuntime)
- [MeasurementKind](#api-MeasurementKind)
- [DeviceProfileService](#api-DeviceProfileService)
@ -156,18 +166,12 @@
- [Gateway.TagsEntry](#api-Gateway-TagsEntry)
- [GatewayListItem](#api-GatewayListItem)
- [GatewayListItem.PropertiesEntry](#api-GatewayListItem-PropertiesEntry)
- [GatewayStats](#api-GatewayStats)
- [GatewayStats.RxPacketsPerDrEntry](#api-GatewayStats-RxPacketsPerDrEntry)
- [GatewayStats.RxPacketsPerFrequencyEntry](#api-GatewayStats-RxPacketsPerFrequencyEntry)
- [GatewayStats.TxPacketsPerDrEntry](#api-GatewayStats-TxPacketsPerDrEntry)
- [GatewayStats.TxPacketsPerFrequencyEntry](#api-GatewayStats-TxPacketsPerFrequencyEntry)
- [GatewayStats.TxPacketsPerStatusEntry](#api-GatewayStats-TxPacketsPerStatusEntry)
- [GenerateGatewayClientCertificateRequest](#api-GenerateGatewayClientCertificateRequest)
- [GenerateGatewayClientCertificateResponse](#api-GenerateGatewayClientCertificateResponse)
- [GetGatewayMetricsRequest](#api-GetGatewayMetricsRequest)
- [GetGatewayMetricsResponse](#api-GetGatewayMetricsResponse)
- [GetGatewayRequest](#api-GetGatewayRequest)
- [GetGatewayResponse](#api-GetGatewayResponse)
- [GetGatewayStatsRequest](#api-GetGatewayStatsRequest)
- [GetGatewayStatsResponse](#api-GetGatewayStatsResponse)
- [ListGatewaysRequest](#api-ListGatewaysRequest)
- [ListGatewaysResponse](#api-ListGatewaysResponse)
- [UpdateGatewayRequest](#api-UpdateGatewayRequest)
@ -413,6 +417,21 @@
<a name="api-CreateIftttIntegrationRequest"></a>
### CreateIftttIntegrationRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| integration | [IftttIntegration](#api-IftttIntegration) | | Integration object. |
<a name="api-CreateInfluxDbIntegrationRequest"></a>
### CreateInfluxDbIntegrationRequest
@ -563,6 +582,21 @@
<a name="api-DeleteIftttIntegrationRequest"></a>
### DeleteIftttIntegrationRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| application_id | [string](#string) | | Application ID (UUID). |
<a name="api-DeleteInfluxDbIntegrationRequest"></a>
### DeleteInfluxDbIntegrationRequest
@ -716,6 +750,7 @@
| application | [Application](#api-Application) | | Application object. |
| created_at | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | Created at timestamp. |
| updated_at | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | Last update timestamp. |
| measurement_keys | [string](#string) | repeated | Measurement keys. This contains the measurement keys from all the device-profiles that are used by the devices under this application. |
@ -842,6 +877,36 @@
<a name="api-GetIftttIntegrationRequest"></a>
### GetIftttIntegrationRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| application_id | [string](#string) | | Application ID (UUID). |
<a name="api-GetIftttIntegrationResponse"></a>
### GetIftttIntegrationResponse
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| integration | [IftttIntegration](#api-IftttIntegration) | | Integration object. |
<a name="api-GetInfluxDbIntegrationRequest"></a>
### GetInfluxDbIntegrationRequest
@ -1026,6 +1091,25 @@
<a name="api-IftttIntegration"></a>
### IftttIntegration
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| application_id | [string](#string) | | Application ID (UUID). |
| key | [string](#string) | | Key. This key can be obtained from the IFTTT Webhooks documentation page. |
| uplink_values | [string](#string) | repeated | Values. Up to 2 values can be forwarded to IFTTT. These values must map to the decoded payload keys. For example: { &#34;batteryLevel&#34;: 75.3, &#34;buttons&#34;: [{&#34;pressed&#34;: false}, {&#34;pressed&#34;: true}] } You would specify the following fields: uplink_values = [&#34;batteryLevel&#34;, &#34;buttons_0_pressed&#34;]
Note: The first value is always used for the DevEUI. |
<a name="api-InfluxDbIntegration"></a>
### InfluxDbIntegration
@ -1300,6 +1384,21 @@
<a name="api-UpdateIftttIntegrationRequest"></a>
### UpdateIftttIntegrationRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| integration | [IftttIntegration](#api-IftttIntegration) | | Integration object to update. |
<a name="api-UpdateInfluxDbIntegrationRequest"></a>
### UpdateInfluxDbIntegrationRequest
@ -1434,6 +1533,7 @@
| AZURE_SERVICE_BUS | 7 | |
| PILOT_THINGS | 8 | |
| MQTT_GLOBAL | 9 | |
| IFTTT | 10 | |
@ -1490,6 +1590,10 @@ ApplicationService is the service providing API methods for managing application
| GetPilotThingsIntegration | [GetPilotThingsIntegrationRequest](#api-GetPilotThingsIntegrationRequest) | [GetPilotThingsIntegrationResponse](#api-GetPilotThingsIntegrationResponse) | Get Pilot Things integration. |
| UpdatePilotThingsIntegration | [UpdatePilotThingsIntegrationRequest](#api-UpdatePilotThingsIntegrationRequest) | [.google.protobuf.Empty](#google-protobuf-Empty) | Update Pilot Things integration. |
| DeletePilotThingsIntegration | [DeletePilotThingsIntegrationRequest](#api-DeletePilotThingsIntegrationRequest) | [.google.protobuf.Empty](#google-protobuf-Empty) | Delete Pilot Things integration. |
| CreateIftttIntegration | [CreateIftttIntegrationRequest](#api-CreateIftttIntegrationRequest) | [.google.protobuf.Empty](#google-protobuf-Empty) | Create IFTTT integration. |
| GetIftttIntegration | [GetIftttIntegrationRequest](#api-GetIftttIntegrationRequest) | [GetIftttIntegrationResponse](#api-GetIftttIntegrationResponse) | Get IFTTT integration. |
| UpdateIftttIntegration | [UpdateIftttIntegrationRequest](#api-UpdateIftttIntegrationRequest) | [.google.protobuf.Empty](#google-protobuf-Empty) | Update IFTTT integration. |
| DeleteIftttIntegration | [DeleteIftttIntegrationRequest](#api-DeleteIftttIntegrationRequest) | [.google.protobuf.Empty](#google-protobuf-Empty) | Delete IFTTT integration. |
| GenerateMqttIntegrationClientCertificate | [GenerateMqttIntegrationClientCertificateRequest](#api-GenerateMqttIntegrationClientCertificateRequest) | [GenerateMqttIntegrationClientCertificateResponse](#api-GenerateMqttIntegrationClientCertificateResponse) | Generates application ID specific client-certificate. |
@ -1733,69 +1837,16 @@ ApplicationService is the service providing API methods for managing application
<a name="api-DeviceStats"></a>
<a name="api-DeviceState"></a>
### DeviceStats
### DeviceState
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| time | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | Timestamp of the (aggregated) measurement. |
| rx_packets | [uint32](#uint32) | | Packets received from the device. |
| gw_rssi | [float](#float) | | Average RSSI (as reported by the gateway(s)). |
| gw_snr | [float](#float) | | Average SNR (as reported by the gateway(s)). |
| rx_packets_per_frequency | [DeviceStats.RxPacketsPerFrequencyEntry](#api-DeviceStats-RxPacketsPerFrequencyEntry) | repeated | Packets received by frequency. |
| rx_packets_per_dr | [DeviceStats.RxPacketsPerDrEntry](#api-DeviceStats-RxPacketsPerDrEntry) | repeated | Packets received by DR. |
| errors | [DeviceStats.ErrorsEntry](#api-DeviceStats-ErrorsEntry) | repeated | Error count. |
<a name="api-DeviceStats-ErrorsEntry"></a>
### DeviceStats.ErrorsEntry
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| key | [string](#string) | | |
| value | [uint32](#uint32) | | |
<a name="api-DeviceStats-RxPacketsPerDrEntry"></a>
### DeviceStats.RxPacketsPerDrEntry
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| key | [uint32](#uint32) | | |
| value | [uint32](#uint32) | | |
<a name="api-DeviceStats-RxPacketsPerFrequencyEntry"></a>
### DeviceStats.RxPacketsPerFrequencyEntry
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| key | [uint32](#uint32) | | |
| value | [uint32](#uint32) | | |
| name | [string](#string) | | Name. |
| value | [string](#string) | | Value. |
@ -1827,7 +1878,7 @@ ApplicationService is the service providing API methods for managing application
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| item | [DeviceQueueItem](#api-DeviceQueueItem) | | |
| queue_item | [DeviceQueueItem](#api-DeviceQueueItem) | | |
@ -1941,6 +1992,110 @@ ApplicationService is the service providing API methods for managing application
<a name="api-GetDeviceLinkMetricsRequest"></a>
### GetDeviceLinkMetricsRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| dev_eui | [string](#string) | | DevEUI (EUI64). |
| start | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | Interval start timestamp. |
| end | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | Interval end timestamp. |
| aggregation | [common.Aggregation](#common-Aggregation) | | Aggregation. |
<a name="api-GetDeviceLinkMetricsResponse"></a>
### GetDeviceLinkMetricsResponse
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| rx_packets | [common.Metric](#common-Metric) | | Packets received from the device. |
| gw_rssi | [common.Metric](#common-Metric) | | RSSI (as reported by the gateway(s)). |
| gw_snr | [common.Metric](#common-Metric) | | SNR (as reported by the gateway(s)). |
| rx_packets_per_freq | [common.Metric](#common-Metric) | | Packets received by frequency. |
| rx_packets_per_dr | [common.Metric](#common-Metric) | | Packets received by DR. |
| errors | [common.Metric](#common-Metric) | | Errors. |
<a name="api-GetDeviceMetricsRequest"></a>
### GetDeviceMetricsRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| dev_eui | [string](#string) | | DevEUI (EUI64). |
| start | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | Interval start timestamp. |
| end | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | Interval end timestamp. |
| aggregation | [common.Aggregation](#common-Aggregation) | | Aggregation. |
<a name="api-GetDeviceMetricsResponse"></a>
### GetDeviceMetricsResponse
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| metrics | [GetDeviceMetricsResponse.MetricsEntry](#api-GetDeviceMetricsResponse-MetricsEntry) | repeated | |
| states | [GetDeviceMetricsResponse.StatesEntry](#api-GetDeviceMetricsResponse-StatesEntry) | repeated | |
<a name="api-GetDeviceMetricsResponse-MetricsEntry"></a>
### GetDeviceMetricsResponse.MetricsEntry
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| key | [string](#string) | | |
| value | [common.Metric](#common-Metric) | | |
<a name="api-GetDeviceMetricsResponse-StatesEntry"></a>
### GetDeviceMetricsResponse.StatesEntry
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| key | [string](#string) | | |
| value | [DeviceState](#api-DeviceState) | | |
<a name="api-GetDeviceQueueItemsRequest"></a>
### GetDeviceQueueItemsRequest
@ -2007,38 +2162,6 @@ ApplicationService is the service providing API methods for managing application
<a name="api-GetDeviceStatsRequest"></a>
### GetDeviceStatsRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| dev_eui | [string](#string) | | DevEUI (EUI64). |
| start | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | Interval start timestamp. |
| end | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | Interval end timestamp. |
<a name="api-GetDeviceStatsResponse"></a>
### GetDeviceStatsResponse
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| result | [DeviceStats](#api-DeviceStats) | repeated | |
<a name="api-GetRandomDevAddrRequest"></a>
### GetRandomDevAddrRequest
@ -2161,7 +2284,8 @@ DeviceService is the service providing API methods for managing devices.
| Deactivate | [DeactivateDeviceRequest](#api-DeactivateDeviceRequest) | [.google.protobuf.Empty](#google-protobuf-Empty) | Deactivate de-activates the device. |
| GetActivation | [GetDeviceActivationRequest](#api-GetDeviceActivationRequest) | [GetDeviceActivationResponse](#api-GetDeviceActivationResponse) | GetActivation returns the current activation details of the device (OTAA or ABP). |
| GetRandomDevAddr | [GetRandomDevAddrRequest](#api-GetRandomDevAddrRequest) | [GetRandomDevAddrResponse](#api-GetRandomDevAddrResponse) | GetRandomDevAddr returns a random DevAddr taking the NwkID prefix into account. |
| GetStats | [GetDeviceStatsRequest](#api-GetDeviceStatsRequest) | [GetDeviceStatsResponse](#api-GetDeviceStatsResponse) | GetStats returns the device stats. |
| GetMetrics | [GetDeviceMetricsRequest](#api-GetDeviceMetricsRequest) | [GetDeviceMetricsResponse](#api-GetDeviceMetricsResponse) | GetMetrics returns the device metrics. Note that this requires a device-profile with codec and measurements configured. |
| GetLinkMetrics | [GetDeviceLinkMetricsRequest](#api-GetDeviceLinkMetricsRequest) | [GetDeviceLinkMetricsResponse](#api-GetDeviceLinkMetricsResponse) | GetLinkMetrics returns the device link metrics. This includes uplinks, downlinks, RSSI, SNR, etc... |
| Enqueue | [EnqueueDeviceQueueItemRequest](#api-EnqueueDeviceQueueItemRequest) | [EnqueueDeviceQueueItemResponse](#api-EnqueueDeviceQueueItemResponse) | Enqueue adds the given item to the downlink queue. |
| FlushQueue | [FlushDeviceQueueRequest](#api-FlushDeviceQueueRequest) | [.google.protobuf.Empty](#google-protobuf-Empty) | FlushQueue flushes the downlink device-queue. |
| GetQueue | [GetDeviceQueueItemsRequest](#api-GetDeviceQueueItemsRequest) | [GetDeviceQueueItemsResponse](#api-GetDeviceQueueItemsResponse) | GetQueue returns the downlink device-queue. |
@ -2249,6 +2373,7 @@ DeviceService is the service providing API methods for managing devices.
| id | [string](#string) | | Device-profile ID (UUID). Note: on create this will be automatically generated. |
| tenant_id | [string](#string) | | Tenant ID (UUID). |
| name | [string](#string) | | Name. |
| description | [string](#string) | | Description. |
| region | [common.Region](#common-Region) | | Region. |
| mac_version | [common.MacVersion](#common-MacVersion) | | LoRaWAN mac-version. |
| reg_params_revision | [common.RegParamsRevision](#common-RegParamsRevision) | | Regional parameters revision. |
@ -2271,6 +2396,23 @@ DeviceService is the service providing API methods for managing devices.
| abp_rx2_dr | [uint32](#uint32) | | RX2 DR (for ABP). |
| abp_rx2_freq | [uint32](#uint32) | | RX2 frequency (for ABP, Hz). |
| tags | [DeviceProfile.TagsEntry](#api-DeviceProfile-TagsEntry) | repeated | User defined tags. |
| measurements | [DeviceProfile.MeasurementsEntry](#api-DeviceProfile-MeasurementsEntry) | repeated | Measurements. If defined, ChirpStack will visualize these metrics in the web-interface. |
<a name="api-DeviceProfile-MeasurementsEntry"></a>
### DeviceProfile.MeasurementsEntry
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| key | [string](#string) | | |
| value | [Measurement](#api-Measurement) | | |
@ -2399,6 +2541,22 @@ DeviceService is the service providing API methods for managing devices.
<a name="api-Measurement"></a>
### Measurement
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| name | [string](#string) | | Name (user defined). |
| kind | [MeasurementKind](#api-MeasurementKind) | | Kind. |
<a name="api-UpdateDeviceProfileRequest"></a>
### UpdateDeviceProfileRequest
@ -2428,6 +2586,21 @@ DeviceService is the service providing API methods for managing devices.
| JS | 2 | JavaScript. |
<a name="api-MeasurementKind"></a>
### MeasurementKind
| Name | Number | Description |
| ---- | ------ | ----------- |
| UNKNOWN | 0 | Unknown (in which case it is not tracked). |
| COUNTER | 1 | Incrementing counters that never decrease (these are not reset on each reading). |
| ABSOLUTE | 2 | Counters that do get reset upon reading. |
| GAUGE | 3 | E.g. a temperature value. |
| STRING | 4 | E.g. a firmware version, true / false value. |
@ -2474,6 +2647,7 @@ DeviceProfileService is the service providing API methods for managing device-pr
| m_type | [common.MType](#common-MType) | | Message type. |
| dev_addr | [string](#string) | | Device address (optional). |
| dev_eui | [string](#string) | | Device EUI (optional). |
| plaintext_mac_commands | [bool](#bool) | | Plaintext mac-commands. |
@ -2495,6 +2669,7 @@ DeviceProfileService is the service providing API methods for managing device-pr
| dev_addr | [string](#string) | | Device address (optional). |
| dev_eui | [string](#string) | | Device EUI (optional). |
| time | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | Time. |
| plaintext_mac_commands | [bool](#bool) | | Plaintext mac-commands. |
@ -2639,108 +2814,6 @@ DeviceProfileService is the service providing API methods for managing device-pr
<a name="api-GatewayStats"></a>
### GatewayStats
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| time | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | Timestamp of the (aggregated) measurement. |
| rx_packets | [uint32](#uint32) | | Packets received. |
| tx_packets | [uint32](#uint32) | | Packets emitted. |
| tx_packets_per_frequency | [GatewayStats.TxPacketsPerFrequencyEntry](#api-GatewayStats-TxPacketsPerFrequencyEntry) | repeated | Tx packets per frequency. |
| rx_packets_per_frequency | [GatewayStats.RxPacketsPerFrequencyEntry](#api-GatewayStats-RxPacketsPerFrequencyEntry) | repeated | Rx packets per frequency. |
| tx_packets_per_dr | [GatewayStats.TxPacketsPerDrEntry](#api-GatewayStats-TxPacketsPerDrEntry) | repeated | Tx packets per DR. |
| rx_packets_per_dr | [GatewayStats.RxPacketsPerDrEntry](#api-GatewayStats-RxPacketsPerDrEntry) | repeated | Rx packets per DR. |
| tx_packets_per_status | [GatewayStats.TxPacketsPerStatusEntry](#api-GatewayStats-TxPacketsPerStatusEntry) | repeated | Tx packets per status. |
<a name="api-GatewayStats-RxPacketsPerDrEntry"></a>
### GatewayStats.RxPacketsPerDrEntry
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| key | [uint32](#uint32) | | |
| value | [uint32](#uint32) | | |
<a name="api-GatewayStats-RxPacketsPerFrequencyEntry"></a>
### GatewayStats.RxPacketsPerFrequencyEntry
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| key | [uint32](#uint32) | | |
| value | [uint32](#uint32) | | |
<a name="api-GatewayStats-TxPacketsPerDrEntry"></a>
### GatewayStats.TxPacketsPerDrEntry
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| key | [uint32](#uint32) | | |
| value | [uint32](#uint32) | | |
<a name="api-GatewayStats-TxPacketsPerFrequencyEntry"></a>
### GatewayStats.TxPacketsPerFrequencyEntry
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| key | [uint32](#uint32) | | |
| value | [uint32](#uint32) | | |
<a name="api-GatewayStats-TxPacketsPerStatusEntry"></a>
### GatewayStats.TxPacketsPerStatusEntry
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| key | [string](#string) | | |
| value | [uint32](#uint32) | | |
<a name="api-GenerateGatewayClientCertificateRequest"></a>
### GenerateGatewayClientCertificateRequest
@ -2774,6 +2847,45 @@ DeviceProfileService is the service providing API methods for managing device-pr
<a name="api-GetGatewayMetricsRequest"></a>
### GetGatewayMetricsRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| gateway_id | [string](#string) | | Gateway ID (EUI64). |
| start | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | Interval start timestamp. |
| end | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | Interval end timestamp. |
| aggregation | [common.Aggregation](#common-Aggregation) | | Aggregation. |
<a name="api-GetGatewayMetricsResponse"></a>
### GetGatewayMetricsResponse
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| rx_packets | [common.Metric](#common-Metric) | | RX packets. |
| tx_packets | [common.Metric](#common-Metric) | | TX packets. |
| tx_packets_per_freq | [common.Metric](#common-Metric) | | TX packets / frequency. |
| rx_packets_per_freq | [common.Metric](#common-Metric) | | RX packets / frequency. |
| tx_packets_per_dr | [common.Metric](#common-Metric) | | TX packets / DR. |
| rx_packets_per_dr | [common.Metric](#common-Metric) | | RX packets / DR. |
| tx_packets_per_status | [common.Metric](#common-Metric) | | TX packets per status. |
<a name="api-GetGatewayRequest"></a>
### GetGatewayRequest
@ -2807,38 +2919,6 @@ DeviceProfileService is the service providing API methods for managing device-pr
<a name="api-GetGatewayStatsRequest"></a>
### GetGatewayStatsRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| gateway_id | [string](#string) | | Gateway ID (EUI64). |
| start | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | Interval start timestamp. |
| end | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | Interval end timestamp. |
<a name="api-GetGatewayStatsResponse"></a>
### GetGatewayStatsResponse
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| result | [GatewayStats](#api-GatewayStats) | repeated | |
<a name="api-ListGatewaysRequest"></a>
### ListGatewaysRequest
@ -2907,7 +2987,7 @@ GatewayService is the service providing API methods for managing gateways.
| Delete | [DeleteGatewayRequest](#api-DeleteGatewayRequest) | [.google.protobuf.Empty](#google-protobuf-Empty) | Delete deletes the gateway matching the given Gateway ID. |
| List | [ListGatewaysRequest](#api-ListGatewaysRequest) | [ListGatewaysResponse](#api-ListGatewaysResponse) | Get the list of gateways. |
| GenerateClientCertificate | [GenerateGatewayClientCertificateRequest](#api-GenerateGatewayClientCertificateRequest) | [GenerateGatewayClientCertificateResponse](#api-GenerateGatewayClientCertificateResponse) | Generate client-certificate for the gateway. |
| GetStats | [GetGatewayStatsRequest](#api-GetGatewayStatsRequest) | [GetGatewayStatsResponse](#api-GetGatewayStatsResponse) | GetStats returns the gateway stats. |
| GetMetrics | [GetGatewayMetricsRequest](#api-GetGatewayMetricsRequest) | [GetGatewayMetricsResponse](#api-GetGatewayMetricsResponse) | GetMetrics returns the gateway metrics. |
@ -2989,7 +3069,7 @@ GatewayService is the service providing API methods for managing gateways.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| multicast_group_queue_item | [MulticastGroupQueueItem](#api-MulticastGroupQueueItem) | | Multicast queue-item to enqueue. |
| queue_item | [MulticastGroupQueueItem](#api-MulticastGroupQueueItem) | | Multicast queue-item to enqueue. |

544
api/md/api/internal.md vendored
View File

@ -1,544 +0,0 @@
# Protocol Documentation
<a name="top"></a>
## Table of Contents
- [api/internal.proto](#api_internal-proto)
- [ApiKey](#api-ApiKey)
- [CreateApiKeyRequest](#api-CreateApiKeyRequest)
- [CreateApiKeyResponse](#api-CreateApiKeyResponse)
- [DeleteApiKeyRequest](#api-DeleteApiKeyRequest)
- [GetDevicesSummaryRequest](#api-GetDevicesSummaryRequest)
- [GetDevicesSummaryResponse](#api-GetDevicesSummaryResponse)
- [GetDevicesSummaryResponse.DrCountEntry](#api-GetDevicesSummaryResponse-DrCountEntry)
- [GetGatewaysSummaryRequest](#api-GetGatewaysSummaryRequest)
- [GetGatewaysSummaryResponse](#api-GetGatewaysSummaryResponse)
- [GlobalSearchRequest](#api-GlobalSearchRequest)
- [GlobalSearchResponse](#api-GlobalSearchResponse)
- [GlobalSearchResult](#api-GlobalSearchResult)
- [ListApiKeysRequest](#api-ListApiKeysRequest)
- [ListApiKeysResponse](#api-ListApiKeysResponse)
- [LogItem](#api-LogItem)
- [LogItem.PropertiesEntry](#api-LogItem-PropertiesEntry)
- [LoginRequest](#api-LoginRequest)
- [LoginResponse](#api-LoginResponse)
- [OpenIdConnect](#api-OpenIdConnect)
- [OpenIdConnectLoginRequest](#api-OpenIdConnectLoginRequest)
- [OpenIdConnectLoginResponse](#api-OpenIdConnectLoginResponse)
- [ProfileResponse](#api-ProfileResponse)
- [SettingsResponse](#api-SettingsResponse)
- [StreamDeviceEventsRequest](#api-StreamDeviceEventsRequest)
- [StreamDeviceFramesRequest](#api-StreamDeviceFramesRequest)
- [StreamGatewayFramesRequest](#api-StreamGatewayFramesRequest)
- [UserTenantLink](#api-UserTenantLink)
- [InternalService](#api-InternalService)
- [Scalar Value Types](#scalar-value-types)
<a name="api_internal-proto"></a>
<p align="right"><a href="#top">Top</a></p>
## api/internal.proto
<a name="api-ApiKey"></a>
### ApiKey
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| id | [string](#string) | | API key ID. This value will be automatically generated on create. |
| name | [string](#string) | | Name. |
| is_admin | [bool](#bool) | | Is global admin key. |
| tenant_id | [string](#string) | | Tenant ID. In case the API key is intended to manage resources under a single tenant. |
<a name="api-CreateApiKeyRequest"></a>
### CreateApiKeyRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| api_key | [ApiKey](#api-ApiKey) | | The API key to create. |
<a name="api-CreateApiKeyResponse"></a>
### CreateApiKeyResponse
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| id | [string](#string) | | API key ID. |
| token | [string](#string) | | API token for authentication API requests. |
<a name="api-DeleteApiKeyRequest"></a>
### DeleteApiKeyRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| id | [string](#string) | | API key ID. |
<a name="api-GetDevicesSummaryRequest"></a>
### GetDevicesSummaryRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| tenant_id | [string](#string) | | Tenant ID (UUID). |
<a name="api-GetDevicesSummaryResponse"></a>
### GetDevicesSummaryResponse
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| active_count | [uint32](#uint32) | | Active count. |
| inactive_count | [uint32](#uint32) | | Inactive count. |
| dr_count | [GetDevicesSummaryResponse.DrCountEntry](#api-GetDevicesSummaryResponse-DrCountEntry) | repeated | per data-rate count. Devices that have never been seen are excluded. |
| never_seen_count | [uint32](#uint32) | | Never seen count. |
<a name="api-GetDevicesSummaryResponse-DrCountEntry"></a>
### GetDevicesSummaryResponse.DrCountEntry
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| key | [uint32](#uint32) | | |
| value | [uint32](#uint32) | | |
<a name="api-GetGatewaysSummaryRequest"></a>
### GetGatewaysSummaryRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| tenant_id | [string](#string) | | Tenant ID (UUID). |
<a name="api-GetGatewaysSummaryResponse"></a>
### GetGatewaysSummaryResponse
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| active_count | [uint32](#uint32) | | Active count. |
| inactive_count | [uint32](#uint32) | | Inactive count. |
| never_seen_count | [uint32](#uint32) | | Never seen count. |
<a name="api-GlobalSearchRequest"></a>
### GlobalSearchRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| search | [string](#string) | | Search query. |
| limit | [int64](#int64) | | Max number of results to return. |
| offset | [int64](#int64) | | Offset offset of the result-set (for pagination). |
<a name="api-GlobalSearchResponse"></a>
### GlobalSearchResponse
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| result | [GlobalSearchResult](#api-GlobalSearchResult) | repeated | |
<a name="api-GlobalSearchResult"></a>
### GlobalSearchResult
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| kind | [string](#string) | | Record kind. |
| score | [float](#float) | | Search score. |
| tenant_id | [string](#string) | | Organization id. |
| tenant_name | [string](#string) | | Organization name. |
| application_id | [string](#string) | | Application id. |
| application_name | [string](#string) | | Application name. |
| device_dev_eui | [string](#string) | | Device DevEUI (hex encoded). |
| device_name | [string](#string) | | Device name. |
| gateway_id | [string](#string) | | Gateway MAC (hex encoded). |
| gateway_name | [string](#string) | | Gateway name. |
<a name="api-ListApiKeysRequest"></a>
### ListApiKeysRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| limit | [uint32](#uint32) | | Max number of items to return. |
| offset | [uint32](#uint32) | | Offset in the result-set (for pagination). |
| is_admin | [bool](#bool) | | Return only admin keys. |
| tenant_id | [string](#string) | | Filter on tenant ID. |
<a name="api-ListApiKeysResponse"></a>
### ListApiKeysResponse
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| total_count | [uint32](#uint32) | | Total number of API keys. |
| result | [ApiKey](#api-ApiKey) | repeated | |
<a name="api-LogItem"></a>
### LogItem
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| id | [string](#string) | | ID. |
| time | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | Timestamp. |
| description | [string](#string) | | Message. |
| body | [string](#string) | | Body. |
| properties | [LogItem.PropertiesEntry](#api-LogItem-PropertiesEntry) | repeated | Properties. |
<a name="api-LogItem-PropertiesEntry"></a>
### LogItem.PropertiesEntry
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| key | [string](#string) | | |
| value | [string](#string) | | |
<a name="api-LoginRequest"></a>
### LoginRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| email | [string](#string) | | Email of the user. |
| password | [string](#string) | | Password of the user. |
<a name="api-LoginResponse"></a>
### LoginResponse
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| jwt | [string](#string) | | The JWT tag to be used to access chirpstack-application-server interfaces. |
<a name="api-OpenIdConnect"></a>
### OpenIdConnect
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| enabled | [bool](#bool) | | Enable OpenId Connect authentication. |
| login_url | [string](#string) | | Login url. |
| login_label | [string](#string) | | Login label. |
| logout_url | [string](#string) | | Logout url. |
<a name="api-OpenIdConnectLoginRequest"></a>
### OpenIdConnectLoginRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| code | [string](#string) | | OpenId Connect callback code. |
| state | [string](#string) | | OpenId Connect callback state. |
<a name="api-OpenIdConnectLoginResponse"></a>
### OpenIdConnectLoginResponse
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| token | [string](#string) | | Token to use for authentication. |
<a name="api-ProfileResponse"></a>
### ProfileResponse
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| user | [User](#api-User) | | User object. |
| tenants | [UserTenantLink](#api-UserTenantLink) | repeated | Tenants to which the user is associated. |
<a name="api-SettingsResponse"></a>
### SettingsResponse
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| openid_connect | [OpenIdConnect](#api-OpenIdConnect) | | OpenId Connect settings. |
<a name="api-StreamDeviceEventsRequest"></a>
### StreamDeviceEventsRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| dev_eui | [string](#string) | | Device EUI. |
<a name="api-StreamDeviceFramesRequest"></a>
### StreamDeviceFramesRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| dev_eui | [string](#string) | | Device EUI. |
<a name="api-StreamGatewayFramesRequest"></a>
### StreamGatewayFramesRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| gateway_id | [string](#string) | | Gateway ID (EUI64). |
<a name="api-UserTenantLink"></a>
### UserTenantLink
Defines a tenant to which the user is associated.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| created_at | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | Created at timestamp. |
| updated_at | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | Last update timestamp. |
| tenant_id | [string](#string) | | Tenant ID. |
| is_admin | [bool](#bool) | | User is admin within the context of this tenant. There is no need to set the is_device_admin and is_gateway_admin flags. |
| is_device_admin | [bool](#bool) | | User is able to modify device related resources (applications, device-profiles, devices, multicast-groups). |
| is_gateway_admin | [bool](#bool) | | User is able to modify gateways. |
<a name="api-InternalService"></a>
### InternalService
InternalService is the service providing API endpoints for internal usage.
| Method Name | Request Type | Response Type | Description |
| ----------- | ------------ | ------------- | ------------|
| Login | [LoginRequest](#api-LoginRequest) | [LoginResponse](#api-LoginResponse) | Log in a user |
| Profile | [.google.protobuf.Empty](#google-protobuf-Empty) | [ProfileResponse](#api-ProfileResponse) | Get the current user&#39;s profile |
| GlobalSearch | [GlobalSearchRequest](#api-GlobalSearchRequest) | [GlobalSearchResponse](#api-GlobalSearchResponse) | Perform a global search. |
| CreateApiKey | [CreateApiKeyRequest](#api-CreateApiKeyRequest) | [CreateApiKeyResponse](#api-CreateApiKeyResponse) | CreateApiKey creates the given API key. |
| DeleteApiKey | [DeleteApiKeyRequest](#api-DeleteApiKeyRequest) | [.google.protobuf.Empty](#google-protobuf-Empty) | DeleteApiKey deletes the API key. |
| ListApiKeys | [ListApiKeysRequest](#api-ListApiKeysRequest) | [ListApiKeysResponse](#api-ListApiKeysResponse) | ListApiKeys lists the available API keys. |
| Settings | [.google.protobuf.Empty](#google-protobuf-Empty) | [SettingsResponse](#api-SettingsResponse) | Get the global settings. |
| OpenIdConnectLogin | [OpenIdConnectLoginRequest](#api-OpenIdConnectLoginRequest) | [OpenIdConnectLoginResponse](#api-OpenIdConnectLoginResponse) | OpenId Connect login. |
| GetDevicesSummary | [GetDevicesSummaryRequest](#api-GetDevicesSummaryRequest) | [GetDevicesSummaryResponse](#api-GetDevicesSummaryResponse) | GetDevicesSummary returns an aggregated summary of the devices. |
| GetGatewaysSummary | [GetGatewaysSummaryRequest](#api-GetGatewaysSummaryRequest) | [GetGatewaysSummaryResponse](#api-GetGatewaysSummaryResponse) | GetGatewaysSummary returns an aggregated summary of the gateways. |
| StreamGatewayFrames | [StreamGatewayFramesRequest](#api-StreamGatewayFramesRequest) | [LogItem](#api-LogItem) stream | Stream frame for the given Gateway ID. |
| StreamDeviceFrames | [StreamDeviceFramesRequest](#api-StreamDeviceFramesRequest) | [LogItem](#api-LogItem) stream | Stream frames for the given Device EUI. |
| StreamDeviceEvents | [StreamDeviceEventsRequest](#api-StreamDeviceEventsRequest) | [LogItem](#api-LogItem) stream | Stream events for the given Device EUI. |
## Scalar Value Types
| .proto Type | Notes | C++ | Java | Python | Go | C# | PHP | Ruby |
| ----------- | ----- | --- | ---- | ------ | -- | -- | --- | ---- |
| <a name="double" /> double | | double | double | float | float64 | double | float | Float |
| <a name="float" /> float | | float | float | float | float32 | float | float | Float |
| <a name="int32" /> int32 | Uses variable-length encoding. Inefficient for encoding negative numbers if your field is likely to have negative values, use sint32 instead. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
| <a name="int64" /> int64 | Uses variable-length encoding. Inefficient for encoding negative numbers if your field is likely to have negative values, use sint64 instead. | int64 | long | int/long | int64 | long | integer/string | Bignum |
| <a name="uint32" /> uint32 | Uses variable-length encoding. | uint32 | int | int/long | uint32 | uint | integer | Bignum or Fixnum (as required) |
| <a name="uint64" /> uint64 | Uses variable-length encoding. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum or Fixnum (as required) |
| <a name="sint32" /> sint32 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
| <a name="sint64" /> sint64 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s. | int64 | long | int/long | int64 | long | integer/string | Bignum |
| <a name="fixed32" /> fixed32 | Always four bytes. More efficient than uint32 if values are often greater than 2^28. | uint32 | int | int | uint32 | uint | integer | Bignum or Fixnum (as required) |
| <a name="fixed64" /> fixed64 | Always eight bytes. More efficient than uint64 if values are often greater than 2^56. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum |
| <a name="sfixed32" /> sfixed32 | Always four bytes. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
| <a name="sfixed64" /> sfixed64 | Always eight bytes. | int64 | long | int/long | int64 | long | integer/string | Bignum |
| <a name="bool" /> bool | | bool | boolean | boolean | bool | bool | boolean | TrueClass/FalseClass |
| <a name="string" /> string | A string must always contain UTF-8 encoded or 7-bit ASCII text. | string | String | str/unicode | string | string | string | String (UTF-8) |
| <a name="bytes" /> bytes | May contain any arbitrary sequence of bytes. | string | ByteString | str | []byte | ByteString | string | String (ASCII-8BIT) |

View File

@ -32,6 +32,9 @@ message UplinkFrameLog {
// Time.
google.protobuf.Timestamp time = 7;
// Plaintext mac-commands.
bool plaintext_mac_commands = 8;
}
message DownlinkFrameLog {
@ -58,4 +61,7 @@ message DownlinkFrameLog {
// Device EUI (optional).
string dev_eui = 8;
// Plaintext mac-commands.
bool plaintext_mac_commands = 9;
}

View File

@ -189,6 +189,10 @@ message ListTenantsRequest {
// If set, the given string will be used to search on name.
string search = 3;
// If set, filters the result set to the tenants of the user.
// Only global API keys are able to filter by this field.
string user_id = 4;
}
message ListTenantsResponse {

16
api/proto/gw/gw.proto vendored
View File

@ -331,21 +331,27 @@ message UplinkRxInfo {
// Note: only available for LoRa modulation.
float snr = 7;
// Channel.
uint32 channel = 8;
// RF chain.
uint32 rf_chain = 9;
// Board.
uint32 board = 8;
uint32 board = 10;
// Antenna.
uint32 antenna = 9;
uint32 antenna = 11;
// Location.
common.Location location = 10;
common.Location location = 12;
// Gateway specific context.
// This value must be returned to the gateway on (Class-A) downlink.
bytes context = 11;
bytes context = 13;
// Properties.
google.protobuf.Struct metadata = 12;
google.protobuf.Struct metadata = 14;
}
message DownlinkTxInfoLegacy {

View File

@ -32,6 +32,9 @@ message UplinkFrameLog {
// Time.
google.protobuf.Timestamp time = 7;
// Plaintext mac-commands.
bool plaintext_mac_commands = 8;
}
message DownlinkFrameLog {
@ -58,4 +61,7 @@ message DownlinkFrameLog {
// Device EUI (optional).
string dev_eui = 8;
// Plaintext mac-commands.
bool plaintext_mac_commands = 9;
}

View File

@ -189,6 +189,10 @@ message ListTenantsRequest {
// If set, the given string will be used to search on name.
string search = 3;
// If set, filters the result set to the tenants of the user.
// Only global API keys are able to filter by this field.
string user_id = 4;
}
message ListTenantsResponse {

View File

@ -331,21 +331,27 @@ message UplinkRxInfo {
// Note: only available for LoRa modulation.
float snr = 7;
// Channel.
uint32 channel = 8;
// RF chain.
uint32 rf_chain = 9;
// Board.
uint32 board = 8;
uint32 board = 10;
// Antenna.
uint32 antenna = 9;
uint32 antenna = 11;
// Location.
common.Location location = 10;
common.Location location = 12;
// Gateway specific context.
// This value must be returned to the gateway on (Class-A) downlink.
bytes context = 11;
bytes context = 13;
// Properties.
google.protobuf.Struct metadata = 12;
google.protobuf.Struct metadata = 14;
}
message DownlinkTxInfoLegacy {

View File

@ -17,7 +17,7 @@ from chirpstack_api.common import common_pb2 as chirpstack__api_dot_common_dot_c
from chirpstack_api.gw import gw_pb2 as chirpstack__api_dot_gw_dot_gw__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\"chirpstack-api/api/frame_log.proto\x12\x03\x61pi\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\"chirpstack-api/common/common.proto\x1a\x1a\x63hirpstack-api/gw/gw.proto\"\xd7\x01\n\x0eUplinkFrameLog\x12\x13\n\x0bphy_payload\x18\x01 \x01(\x0c\x12!\n\x07tx_info\x18\x02 \x01(\x0b\x32\x10.gw.UplinkTxInfo\x12!\n\x07rx_info\x18\x03 \x03(\x0b\x32\x10.gw.UplinkRxInfo\x12\x1d\n\x06m_type\x18\x04 \x01(\x0e\x32\r.common.MType\x12\x10\n\x08\x64\x65v_addr\x18\x05 \x01(\t\x12\x0f\n\x07\x64\x65v_eui\x18\x06 \x01(\t\x12(\n\x04time\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\xe1\x01\n\x10\x44ownlinkFrameLog\x12(\n\x04time\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x13\n\x0bphy_payload\x18\x02 \x01(\x0c\x12#\n\x07tx_info\x18\x03 \x01(\x0b\x32\x12.gw.DownlinkTxInfo\x12\x13\n\x0b\x64ownlink_id\x18\x04 \x01(\r\x12\x12\n\ngateway_id\x18\x05 \x01(\t\x12\x1d\n\x06m_type\x18\x06 \x01(\x0e\x32\r.common.MType\x12\x10\n\x08\x64\x65v_addr\x18\x07 \x01(\t\x12\x0f\n\x07\x64\x65v_eui\x18\x08 \x01(\tBT\n\x11io.chirpstack.apiB\rFrameLogProtoP\x01Z.github.com/chirpstack/chirpstack/api/go/v4/apib\x06proto3')
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\"chirpstack-api/api/frame_log.proto\x12\x03\x61pi\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\"chirpstack-api/common/common.proto\x1a\x1a\x63hirpstack-api/gw/gw.proto\"\xf7\x01\n\x0eUplinkFrameLog\x12\x13\n\x0bphy_payload\x18\x01 \x01(\x0c\x12!\n\x07tx_info\x18\x02 \x01(\x0b\x32\x10.gw.UplinkTxInfo\x12!\n\x07rx_info\x18\x03 \x03(\x0b\x32\x10.gw.UplinkRxInfo\x12\x1d\n\x06m_type\x18\x04 \x01(\x0e\x32\r.common.MType\x12\x10\n\x08\x64\x65v_addr\x18\x05 \x01(\t\x12\x0f\n\x07\x64\x65v_eui\x18\x06 \x01(\t\x12(\n\x04time\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x1e\n\x16plaintext_mac_commands\x18\x08 \x01(\x08\"\x81\x02\n\x10\x44ownlinkFrameLog\x12(\n\x04time\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x13\n\x0bphy_payload\x18\x02 \x01(\x0c\x12#\n\x07tx_info\x18\x03 \x01(\x0b\x32\x12.gw.DownlinkTxInfo\x12\x13\n\x0b\x64ownlink_id\x18\x04 \x01(\r\x12\x12\n\ngateway_id\x18\x05 \x01(\t\x12\x1d\n\x06m_type\x18\x06 \x01(\x0e\x32\r.common.MType\x12\x10\n\x08\x64\x65v_addr\x18\x07 \x01(\t\x12\x0f\n\x07\x64\x65v_eui\x18\x08 \x01(\t\x12\x1e\n\x16plaintext_mac_commands\x18\t \x01(\x08\x42T\n\x11io.chirpstack.apiB\rFrameLogProtoP\x01Z.github.com/chirpstack/chirpstack/api/go/v4/apib\x06proto3')
@ -42,7 +42,7 @@ if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\021io.chirpstack.apiB\rFrameLogProtoP\001Z.github.com/chirpstack/chirpstack/api/go/v4/api'
_UPLINKFRAMELOG._serialized_start=141
_UPLINKFRAMELOG._serialized_end=356
_DOWNLINKFRAMELOG._serialized_start=359
_DOWNLINKFRAMELOG._serialized_end=584
_UPLINKFRAMELOG._serialized_end=388
_DOWNLINKFRAMELOG._serialized_start=391
_DOWNLINKFRAMELOG._serialized_end=648
# @@protoc_insertion_point(module_scope)

File diff suppressed because one or more lines are too long

View File

@ -18,7 +18,7 @@ CLASSIFIERS = [
setup(
name='chirpstack-api',
version = "4.0.0-test.15",
version = "4.0.0-rc.4",
url='https://github.com/brocaar/chirpstack-api',
author='Orne Brocaar',
author_email='info@brocaar.com',

2
api/rust/Cargo.lock generated vendored
View File

@ -121,7 +121,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chirpstack_api"
version = "4.0.0-test.14"
version = "4.0.0-rc.2"
dependencies = [
"hex",
"pbjson",

2
api/rust/Cargo.toml vendored
View File

@ -1,7 +1,7 @@
[package]
name = "chirpstack_api"
description = "ChirpStack Protobuf / gRPC API definitions."
version = "4.0.0-test.15"
version = "4.0.0-rc.4"
authors = ["Orne Brocaar <info@brocaar.com>"]
license = "MIT"
homepage = "https://www.chirpstack.io"

View File

@ -32,6 +32,9 @@ message UplinkFrameLog {
// Time.
google.protobuf.Timestamp time = 7;
// Plaintext mac-commands.
bool plaintext_mac_commands = 8;
}
message DownlinkFrameLog {
@ -58,4 +61,7 @@ message DownlinkFrameLog {
// Device EUI (optional).
string dev_eui = 8;
// Plaintext mac-commands.
bool plaintext_mac_commands = 9;
}

View File

@ -189,6 +189,10 @@ message ListTenantsRequest {
// If set, the given string will be used to search on name.
string search = 3;
// If set, filters the result set to the tenants of the user.
// Only global API keys are able to filter by this field.
string user_id = 4;
}
message ListTenantsResponse {

View File

@ -331,21 +331,27 @@ message UplinkRxInfo {
// Note: only available for LoRa modulation.
float snr = 7;
// Channel.
uint32 channel = 8;
// RF chain.
uint32 rf_chain = 9;
// Board.
uint32 board = 8;
uint32 board = 10;
// Antenna.
uint32 antenna = 9;
uint32 antenna = 11;
// Location.
common.Location location = 10;
common.Location location = 12;
// Gateway specific context.
// This value must be returned to the gateway on (Class-A) downlink.
bytes context = 11;
bytes context = 13;
// Properties.
google.protobuf.Struct metadata = 12;
google.protobuf.Struct metadata = 14;
}
message DownlinkTxInfoLegacy {

10
api/rust/src/gw.rs vendored
View File

@ -121,6 +121,8 @@ impl UplinkFrame {
fine_time_since_gps_epoch: None,
rssi: rx_info.rssi,
snr: rx_info.lora_snr as f32,
channel: rx_info.channel,
rf_chain: rx_info.rf_chain,
board: rx_info.board,
antenna: rx_info.antenna,
location: rx_info.location.clone(),
@ -277,3 +279,11 @@ impl DownlinkTxAck {
}
}
}
impl GatewayStats {
pub fn v4_migrate(&mut self) {
if self.gateway_id.is_empty() {
self.gateway_id = hex::encode(&self.gateway_id_legacy);
}
}
}

View File

@ -1,6 +1,6 @@
[package]
name = "backend"
version = "4.0.0-test.15"
version = "4.0.0-rc.4"
authors = ["Orne Brocaar <info@brocaar.com>"]
edition = "2018"
publish = false

View File

@ -12,7 +12,7 @@ use reqwest::header::{HeaderMap, AUTHORIZATION, CONTENT_TYPE};
use reqwest::{Certificate, Identity};
use serde::{Deserialize, Serialize};
use tokio::sync::oneshot::Receiver;
use tracing::{error, info, trace};
use tracing::{debug, error, info, trace};
const PROTOCOL_VERSION: &str = "1.0";
@ -279,13 +279,15 @@ impl Client {
};
let bp = pl.base_payload();
let body = serde_json::to_string(&pl)?;
info!(receiver_id = %hex::encode(&bp.base.receiver_id), transaction_id = bp.base.transaction_id, message_type = ?bp.base.message_type, server = %server, "Making request");
debug!("JSON: {}", body);
self.client
.post(&server)
.headers(self.headers.clone())
.json(pl)
.body(body)
.send()
.await?
.error_for_status()?;
@ -315,14 +317,16 @@ impl Client {
};
let bp = pl.base_payload().clone();
let body = serde_json::to_string(&pl)?;
info!(receiver_id = %hex::encode(&bp.receiver_id), transaction_id = bp.transaction_id, message_type = ?bp.message_type, server = %server, async_interface = %async_resp.is_some(), "Making request");
debug!("JSON: {}", body);
let res = self
.client
.post(&server)
.headers(self.headers.clone())
.json(pl)
.body(body)
.send()
.await?
.error_for_status()?;
@ -344,6 +348,7 @@ impl Client {
None => res.text().await?,
};
debug!("JSON: {}", resp_json);
let base: BasePayloadResult = serde_json::from_str(&resp_json)?;
if base.result.result_code != ResultCode::Success {
error!(result_code = ?base.result.result_code, description = %base.result.description, receiver_id = %hex::encode(&bp.receiver_id), transaction_id = bp.transaction_id, message_type = ?bp.message_type, "Response error");
@ -523,7 +528,11 @@ pub struct BasePayloadResult {
pub struct ResultPayload {
#[serde(rename = "ResultCode")]
pub result_code: ResultCode,
#[serde(rename = "Description")]
#[serde(
default,
rename = "Description",
skip_serializing_if = "String::is_empty"
)]
pub description: String,
}
@ -933,7 +942,12 @@ pub struct ULMetaData {
pub f_ns_ul_token: Vec<u8>,
#[serde(rename = "RecvTime")]
pub recv_time: DateTime<Utc>,
#[serde(default, rename = "RFRegion", skip_serializing_if = "String::is_empty")]
#[serde(
default,
rename = "RFRegion",
with = "rf_region_encode",
skip_serializing_if = "String::is_empty"
)]
pub rf_region: String,
#[serde(rename = "GWCnt")]
pub gw_cnt: Option<usize>,
@ -974,7 +988,12 @@ pub struct GWInfoElement {
pub id: Vec<u8>,
#[serde(rename = "FineRecvTime")]
pub fine_recv_time: Option<usize>,
#[serde(default, rename = "RFRegion", skip_serializing_if = "String::is_empty")]
#[serde(
default,
rename = "RFRegion",
with = "rf_region_encode",
skip_serializing_if = "String::is_empty"
)]
pub rf_region: String,
#[serde(rename = "RSSI")]
pub rssi: Option<isize>,
@ -1079,6 +1098,27 @@ pub struct DLMetaData {
pub hi_priority_flag: bool,
}
mod rf_region_encode {
use serde::{Deserializer, Serializer};
pub fn serialize<S>(s: &str, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&s.replace('_', "-"))
}
pub fn deserialize<'a, D>(deserializer: D) -> Result<String, D::Error>
where
D: Deserializer<'a>,
{
let s: &str = serde::de::Deserialize::deserialize(deserializer)?;
// Some implementations use lowercase.
Ok(s.to_uppercase())
}
}
mod hex_encode {
use serde::{Deserializer, Serializer};

View File

@ -1,4 +0,0 @@
[Service]
Environment="MQTT_BROKER_HOST=localhost"
Environment="POSTGRESQL_HOST=localhost"
Environment="REDIS_HOST=localhost"

View File

@ -23,6 +23,9 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
rm -rf %{buildroot}
mkdir -p %{buildroot}
cp -a * %{buildroot}
sed -i "s/\$MQTT_BROKER_HOST/localhost/" %{buildroot}/etc/chirpstack/*.toml
sed -i "s/\$POSTGRESQL_HOST/localhost/" %{buildroot}/etc/chirpstack/*.toml
sed -i "s/\$REDIS_HOST/localhost/" %{buildroot}/etc/chirpstack/*.toml
%clean
rm -rf %{buildroot}
@ -32,4 +35,3 @@ rm -rf %{buildroot}
%{_bindir}/*
/lib/systemd/system/chirpstack.service
%config /etc/chirpstack/*
%config /etc/systemd/system/chirpstack.service.d/*

View File

@ -3,7 +3,7 @@ name = "chirpstack"
description = "ChirpStack is an open-source LoRaWAN(TM) Network Server"
repository = "https://github.com/chirpstack/chirpstack"
homepage="https://www.chirpstack.io/"
version = "4.0.0-test.15"
version = "4.0.0-rc.4"
authors = ["Orne Brocaar <info@brocaar.com>"]
edition = "2021"
publish = false
@ -107,7 +107,7 @@ base64 = "0.13"
async-recursion = "1.0"
regex = "1"
petgraph = "0.6"
prometheus-client = "0.16"
prometheus-client = "0.18"
pin-project = "1.0"
# Development and testing
@ -120,13 +120,8 @@ bytes = "1.1"
assets = [
["target/release/chirpstack", "usr/bin/", "755"],
["configuration/*.toml", "etc/chirpstack/", "640"],
["configuration/certs/*.json", "etc/chirpstack/certs", "640"],
["debian/environment.conf", "etc/systemd/system/chirpstack.service.d/environment.conf", "640"],
]
conf-files = [
"/etc/chirpstack/certs/ca-config.json",
"/etc/chirpstack/certs/ca-csr.json",
"/etc/chirpstack/certs/mqtt-server.json",
"/etc/chirpstack/chirpstack.toml",
"/etc/chirpstack/region_as923.toml",
"/etc/chirpstack/region_as923_2.toml",
@ -156,7 +151,6 @@ conf-files = [
"/etc/chirpstack/region_us915_6.toml",
"/etc/chirpstack/region_us915_7.toml",
]
depends = "$auto, golang-cfssl"
suggests = "postgresql, mosquitto, redis"
maintainer-scripts = "debian/"
systemd-units = { enable = true }
@ -167,7 +161,6 @@ package = "chirpstack"
[package.metadata.rpm.files]
"configuration/" = { path = "/etc/chirpstack/" }
"chirpstack.service" = { path = "/lib/systemd/system/chirpstack.service" }
"chirpstack.env" = { path = "/etc/systemd/system/chirpstack.service.d/environment" }
[package.metadata.rpm.cargo]
buildflags = ["--release"]

View File

@ -111,14 +111,8 @@ test:
test-lrwn:
cd ../lrwn && make test
test-server: debug-amd64 configuration/certs/ca.pem
test-server: debug-amd64
../target/debug/chirpstack -c ./configuration
dbshell:
psql -h postgres -U chirpstack chirpstack
configuration/certs/ca.pem:
cfssl gencert -initca configuration/certs/ca-csr.json | cfssljson -bare configuration/certs/ca
configuration/certs/mqtt-server.pem: configuration/certs/ca.pem
cfssl gencert -ca configuration/certs/ca.pem -ca-key configuration/certs/ca-key.pem -config configuration/certs/ca-config.json -profile server configuration/certs/mqtt-server.json | cfssljson -bare configuration/certs/mqtt-server

View File

@ -1,17 +0,0 @@
{
"signing": {
"default": {
"expiry": "8760h"
},
"profiles": {
"server": {
"expiry": "8760h",
"usages": [
"signing",
"key encipherment",
"server auth"
]
}
}
}
}

View File

@ -1,7 +0,0 @@
{
"CN": "ChirpStack CA",
"key": {
"algo": "rsa",
"size": 4096
}
}

View File

@ -1,10 +0,0 @@
{
"CN": "mqtt-broker",
"hosts": [
"*"
],
"key": {
"algo": "rsa",
"size": 4096
}
}

View File

@ -70,6 +70,7 @@
"as923_3",
"as923_4",
"au915_0",
"cn470_10",
"cn779",
"eu433",
"eu868",
@ -97,19 +98,9 @@
secret="you-must-replace-this"
[gateway]
client_cert_lifetime="365days"
ca_cert="configuration/certs/ca.pem"
ca_key="configuration/certs/ca-key.pem"
[integration]
enabled=["mqtt"]
[integration.mqtt]
server="tcp://$MQTT_BROKER_HOST:1883/"
json=true
[integration.mqtt.client]
client_cert_lifetime="365days"
ca_cert="configuration/certs/ca.pem"
ca_key="configuration/certs/ca-key.pem"

View File

@ -0,0 +1,237 @@
# This file contains an example CN470 example (channels 0-7).
[[regions]]
# Name is an use-defined identifier for this region.
name="cn470_0"
# Common-name refers to the common-name of this region as defined by
# the LoRa Alliance.
common_name="CN470"
# Gateway configuration.
[regions.gateway]
# Force gateways as private.
#
# If enabled, gateways can only be used by devices under the same tenant.
force_gws_private=false
# Gateway backend configuration.
[regions.gateway.backend]
# The enabled backend type.
enabled="mqtt"
# MQTT configuration.
[regions.gateway.backend.mqtt]
# Event topic template.
event_topic="cn470_0/gateway/+/event/+"
# Command topic template.
command_topic="cn470_0/gateway/{{ gateway_id }}/command/{{ command }}"
# MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws)
server="tcp://$MQTT_BROKER_HOST:1883"
# Connect with the given username (optional)
username=""
# Connect with the given password (optional)
password=""
# Quality of service level
#
# 0: at most once
# 1: at least once
# 2: exactly once
#
# Note: an increase of this value will decrease the performance.
# For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels
qos=0
# Clean session
#
# Set the "clean session" flag in the connect message when this client
# connects to an MQTT broker. By setting this flag you are indicating
# that no messages saved by the broker for this client should be delivered.
clean_session=false
# Client ID
#
# Set the client id to be used by this client when connecting to the MQTT
# broker. A client id must be no longer than 23 characters. If left blank,
# a random id will be generated by ChirpStack.
client_id=""
# CA certificate file (optional)
#
# Use this when setting up a secure connection (when server uses ssl://...)
# but the certificate used by the server is not trusted by any CA certificate
# on the server (e.g. when self generated).
ca_cert=""
# TLS certificate file (optional)
tls_cert=""
# TLS key file (optional)
tls_key=""
# Gateway channel configuration.
#
# Note: this configuration is only used in case the gateway is using the
# ChirpStack Concentratord daemon. In any other case, this configuration
# is ignored.
[[regions.gateway.channels]]
frequency=470300000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=470500000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=470700000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=470900000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=471100000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=471300000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=471500000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=471700000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
# Region specific network configuration.
[regions.network]
# Installation margin (dB) used by the ADR engine.
#
# A higher number means that the network-server will keep more margin,
# resulting in a lower data-rate but decreasing the chance that the
# device gets disconnected because it is unable to reach one of the
# surrounded gateways.
installation_margin=10
# RX window (Class-A).
#
# Set this to:
# 0: RX1 / RX2
# 1: RX1 only
# 2: RX2 only
rx_window=0
# RX1 delay (1 - 15 seconds).
rx1_delay=1
# RX1 data-rate offset
rx1_dr_offset=0
# RX2 data-rate
rx2_dr=0
# RX2 frequency (Hz)
rx2_frequency=505300000
# Prefer RX2 on RX1 data-rate less than.
#
# Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate
# is smaller than the configured value, then the Network Server will
# first try to schedule the downlink for RX2, failing that (e.g. the gateway
# has already a payload scheduled at the RX2 timing) it will try RX1.
rx2_prefer_on_rx1_dr_lt=0
# Prefer RX2 on link budget.
#
# When the link-budget is better for RX2 than for RX1, the Network Server will first
# try to schedule the downlink in RX2, failing that it will try RX1.
rx2_prefer_on_link_budget=false
# Downlink TX Power (dBm)
#
# When set to -1, the downlink TX Power from the configured band will
# be used.
#
# Please consult the LoRaWAN Regional Parameters and local regulations
# for valid and legal options. Note that the configured TX Power must be
# supported by your gateway(s).
downlink_tx_power=-1
# ADR is disabled.
adr_disabled=false
# Minimum data-rate.
min_dr=0
# Maximum data-rate.
max_dr=5
# Enabled uplink channels.
#
# Use this when ony a sub-set of the by default enabled channels are being
# used. For example when only using the first 8 channels of the US band.
# Note: when left blank / empty array, all channels will be enabled.
enabled_uplink_channels=[0, 1, 2, 3, 4, 5, 6, 7]
# Rejoin-request configuration (LoRaWAN 1.1)
[regions.network.rejoin_request]
# Request devices to periodically send rejoin-requests.
enabled=false
# The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4)
# uplink messages. Valid values are 0 to 15.
max_count_n=0
# The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10)
# seconds. Valid values are 0 to 15.
#
# 0 = roughly 17 minutes
# 15 = about 1 year
max_time_n=0
# Class-B configuration.
[regions.network.class_b]
# Ping-slot data-rate.
ping_slot_dr=0
# Ping-slot frequency (Hz)
#
# set this to 0 to use the default frequency plan for the configured region
# (which could be frequency hopping).
ping_slot_frequency=0

View File

@ -0,0 +1,237 @@
# This file contains an example CN470 example (channels 8-15).
[[regions]]
# Name is an use-defined identifier for this region.
name="cn470_1"
# Common-name refers to the common-name of this region as defined by
# the LoRa Alliance.
common_name="CN470"
# Gateway configuration.
[regions.gateway]
# Force gateways as private.
#
# If enabled, gateways can only be used by devices under the same tenant.
force_gws_private=false
# Gateway backend configuration.
[regions.gateway.backend]
# The enabled backend type.
enabled="mqtt"
# MQTT configuration.
[regions.gateway.backend.mqtt]
# Event topic template.
event_topic="cn470_1/gateway/+/event/+"
# Command topic template.
command_topic="cn470_1/gateway/{{ gateway_id }}/command/{{ command }}"
# MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws)
server="tcp://$MQTT_BROKER_HOST:1883"
# Connect with the given username (optional)
username=""
# Connect with the given password (optional)
password=""
# Quality of service level
#
# 0: at most once
# 1: at least once
# 2: exactly once
#
# Note: an increase of this value will decrease the performance.
# For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels
qos=0
# Clean session
#
# Set the "clean session" flag in the connect message when this client
# connects to an MQTT broker. By setting this flag you are indicating
# that no messages saved by the broker for this client should be delivered.
clean_session=false
# Client ID
#
# Set the client id to be used by this client when connecting to the MQTT
# broker. A client id must be no longer than 23 characters. If left blank,
# a random id will be generated by ChirpStack.
client_id=""
# CA certificate file (optional)
#
# Use this when setting up a secure connection (when server uses ssl://...)
# but the certificate used by the server is not trusted by any CA certificate
# on the server (e.g. when self generated).
ca_cert=""
# TLS certificate file (optional)
tls_cert=""
# TLS key file (optional)
tls_key=""
# Gateway channel configuration.
#
# Note: this configuration is only used in case the gateway is using the
# ChirpStack Concentratord daemon. In any other case, this configuration
# is ignored.
[[regions.gateway.channels]]
frequency=471900000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=472100000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=472300000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=472500000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=472700000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=472900000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=473100000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=473300000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
# Region specific network configuration.
[regions.network]
# Installation margin (dB) used by the ADR engine.
#
# A higher number means that the network-server will keep more margin,
# resulting in a lower data-rate but decreasing the chance that the
# device gets disconnected because it is unable to reach one of the
# surrounded gateways.
installation_margin=10
# RX window (Class-A).
#
# Set this to:
# 0: RX1 / RX2
# 1: RX1 only
# 2: RX2 only
rx_window=0
# RX1 delay (1 - 15 seconds).
rx1_delay=1
# RX1 data-rate offset
rx1_dr_offset=0
# RX2 data-rate
rx2_dr=0
# RX2 frequency (Hz)
rx2_frequency=505300000
# Prefer RX2 on RX1 data-rate less than.
#
# Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate
# is smaller than the configured value, then the Network Server will
# first try to schedule the downlink for RX2, failing that (e.g. the gateway
# has already a payload scheduled at the RX2 timing) it will try RX1.
rx2_prefer_on_rx1_dr_lt=0
# Prefer RX2 on link budget.
#
# When the link-budget is better for RX2 than for RX1, the Network Server will first
# try to schedule the downlink in RX2, failing that it will try RX1.
rx2_prefer_on_link_budget=false
# Downlink TX Power (dBm)
#
# When set to -1, the downlink TX Power from the configured band will
# be used.
#
# Please consult the LoRaWAN Regional Parameters and local regulations
# for valid and legal options. Note that the configured TX Power must be
# supported by your gateway(s).
downlink_tx_power=-1
# ADR is disabled.
adr_disabled=false
# Minimum data-rate.
min_dr=0
# Maximum data-rate.
max_dr=5
# Enabled uplink channels.
#
# Use this when ony a sub-set of the by default enabled channels are being
# used. For example when only using the first 8 channels of the US band.
# Note: when left blank / empty array, all channels will be enabled.
enabled_uplink_channels=[8, 9, 10, 11, 12, 13, 14, 15]
# Rejoin-request configuration (LoRaWAN 1.1)
[regions.network.rejoin_request]
# Request devices to periodically send rejoin-requests.
enabled=false
# The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4)
# uplink messages. Valid values are 0 to 15.
max_count_n=0
# The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10)
# seconds. Valid values are 0 to 15.
#
# 0 = roughly 17 minutes
# 15 = about 1 year
max_time_n=0
# Class-B configuration.
[regions.network.class_b]
# Ping-slot data-rate.
ping_slot_dr=0
# Ping-slot frequency (Hz)
#
# set this to 0 to use the default frequency plan for the configured region
# (which could be frequency hopping).
ping_slot_frequency=0

View File

@ -0,0 +1,237 @@
# This file contains an example CN470 example (channels 80-87).
[[regions]]
# Name is an use-defined identifier for this region.
name="cn470_10"
# Common-name refers to the common-name of this region as defined by
# the LoRa Alliance.
common_name="CN470"
# Gateway configuration.
[regions.gateway]
# Force gateways as private.
#
# If enabled, gateways can only be used by devices under the same tenant.
force_gws_private=false
# Gateway backend configuration.
[regions.gateway.backend]
# The enabled backend type.
enabled="mqtt"
# MQTT configuration.
[regions.gateway.backend.mqtt]
# Event topic template.
event_topic="cn470_10/gateway/+/event/+"
# Command topic template.
command_topic="cn470_10/gateway/{{ gateway_id }}/command/{{ command }}"
# MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws)
server="tcp://$MQTT_BROKER_HOST:1883"
# Connect with the given username (optional)
username=""
# Connect with the given password (optional)
password=""
# Quality of service level
#
# 0: at most once
# 1: at least once
# 2: exactly once
#
# Note: an increase of this value will decrease the performance.
# For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels
qos=0
# Clean session
#
# Set the "clean session" flag in the connect message when this client
# connects to an MQTT broker. By setting this flag you are indicating
# that no messages saved by the broker for this client should be delivered.
clean_session=false
# Client ID
#
# Set the client id to be used by this client when connecting to the MQTT
# broker. A client id must be no longer than 23 characters. If left blank,
# a random id will be generated by ChirpStack.
client_id=""
# CA certificate file (optional)
#
# Use this when setting up a secure connection (when server uses ssl://...)
# but the certificate used by the server is not trusted by any CA certificate
# on the server (e.g. when self generated).
ca_cert=""
# TLS certificate file (optional)
tls_cert=""
# TLS key file (optional)
tls_key=""
# Gateway channel configuration.
#
# Note: this configuration is only used in case the gateway is using the
# ChirpStack Concentratord daemon. In any other case, this configuration
# is ignored.
[[regions.gateway.channels]]
frequency=486300000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=486500000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=486700000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=486900000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=487100000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=487300000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=487500000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=487700000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
# Region specific network configuration.
[regions.network]
# Installation margin (dB) used by the ADR engine.
#
# A higher number means that the network-server will keep more margin,
# resulting in a lower data-rate but decreasing the chance that the
# device gets disconnected because it is unable to reach one of the
# surrounded gateways.
installation_margin=10
# RX window (Class-A).
#
# Set this to:
# 0: RX1 / RX2
# 1: RX1 only
# 2: RX2 only
rx_window=0
# RX1 delay (1 - 15 seconds).
rx1_delay=1
# RX1 data-rate offset
rx1_dr_offset=0
# RX2 data-rate
rx2_dr=0
# RX2 frequency (Hz)
rx2_frequency=505300000
# Prefer RX2 on RX1 data-rate less than.
#
# Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate
# is smaller than the configured value, then the Network Server will
# first try to schedule the downlink for RX2, failing that (e.g. the gateway
# has already a payload scheduled at the RX2 timing) it will try RX1.
rx2_prefer_on_rx1_dr_lt=0
# Prefer RX2 on link budget.
#
# When the link-budget is better for RX2 than for RX1, the Network Server will first
# try to schedule the downlink in RX2, failing that it will try RX1.
rx2_prefer_on_link_budget=false
# Downlink TX Power (dBm)
#
# When set to -1, the downlink TX Power from the configured band will
# be used.
#
# Please consult the LoRaWAN Regional Parameters and local regulations
# for valid and legal options. Note that the configured TX Power must be
# supported by your gateway(s).
downlink_tx_power=-1
# ADR is disabled.
adr_disabled=false
# Minimum data-rate.
min_dr=0
# Maximum data-rate.
max_dr=5
# Enabled uplink channels.
#
# Use this when ony a sub-set of the by default enabled channels are being
# used. For example when only using the first 8 channels of the US band.
# Note: when left blank / empty array, all channels will be enabled.
enabled_uplink_channels=[80, 81, 82, 83, 84, 85, 86, 87]
# Rejoin-request configuration (LoRaWAN 1.1)
[regions.network.rejoin_request]
# Request devices to periodically send rejoin-requests.
enabled=false
# The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4)
# uplink messages. Valid values are 0 to 15.
max_count_n=0
# The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10)
# seconds. Valid values are 0 to 15.
#
# 0 = roughly 17 minutes
# 15 = about 1 year
max_time_n=0
# Class-B configuration.
[regions.network.class_b]
# Ping-slot data-rate.
ping_slot_dr=0
# Ping-slot frequency (Hz)
#
# set this to 0 to use the default frequency plan for the configured region
# (which could be frequency hopping).
ping_slot_frequency=0

View File

@ -0,0 +1,237 @@
# This file contains an example CN470 example (channels 88-95).
[[regions]]
# Name is an use-defined identifier for this region.
name="cn470_11"
# Common-name refers to the common-name of this region as defined by
# the LoRa Alliance.
common_name="CN470"
# Gateway configuration.
[regions.gateway]
# Force gateways as private.
#
# If enabled, gateways can only be used by devices under the same tenant.
force_gws_private=false
# Gateway backend configuration.
[regions.gateway.backend]
# The enabled backend type.
enabled="mqtt"
# MQTT configuration.
[regions.gateway.backend.mqtt]
# Event topic template.
event_topic="cn470_11/gateway/+/event/+"
# Command topic template.
command_topic="cn470_11/gateway/{{ gateway_id }}/command/{{ command }}"
# MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws)
server="tcp://$MQTT_BROKER_HOST:1883"
# Connect with the given username (optional)
username=""
# Connect with the given password (optional)
password=""
# Quality of service level
#
# 0: at most once
# 1: at least once
# 2: exactly once
#
# Note: an increase of this value will decrease the performance.
# For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels
qos=0
# Clean session
#
# Set the "clean session" flag in the connect message when this client
# connects to an MQTT broker. By setting this flag you are indicating
# that no messages saved by the broker for this client should be delivered.
clean_session=false
# Client ID
#
# Set the client id to be used by this client when connecting to the MQTT
# broker. A client id must be no longer than 23 characters. If left blank,
# a random id will be generated by ChirpStack.
client_id=""
# CA certificate file (optional)
#
# Use this when setting up a secure connection (when server uses ssl://...)
# but the certificate used by the server is not trusted by any CA certificate
# on the server (e.g. when self generated).
ca_cert=""
# TLS certificate file (optional)
tls_cert=""
# TLS key file (optional)
tls_key=""
# Gateway channel configuration.
#
# Note: this configuration is only used in case the gateway is using the
# ChirpStack Concentratord daemon. In any other case, this configuration
# is ignored.
[[regions.gateway.channels]]
frequency=487900000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=488100000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=488300000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=488500000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=488700000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=488900000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=489100000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=489300000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
# Region specific network configuration.
[regions.network]
# Installation margin (dB) used by the ADR engine.
#
# A higher number means that the network-server will keep more margin,
# resulting in a lower data-rate but decreasing the chance that the
# device gets disconnected because it is unable to reach one of the
# surrounded gateways.
installation_margin=10
# RX window (Class-A).
#
# Set this to:
# 0: RX1 / RX2
# 1: RX1 only
# 2: RX2 only
rx_window=0
# RX1 delay (1 - 15 seconds).
rx1_delay=1
# RX1 data-rate offset
rx1_dr_offset=0
# RX2 data-rate
rx2_dr=0
# RX2 frequency (Hz)
rx2_frequency=505300000
# Prefer RX2 on RX1 data-rate less than.
#
# Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate
# is smaller than the configured value, then the Network Server will
# first try to schedule the downlink for RX2, failing that (e.g. the gateway
# has already a payload scheduled at the RX2 timing) it will try RX1.
rx2_prefer_on_rx1_dr_lt=0
# Prefer RX2 on link budget.
#
# When the link-budget is better for RX2 than for RX1, the Network Server will first
# try to schedule the downlink in RX2, failing that it will try RX1.
rx2_prefer_on_link_budget=false
# Downlink TX Power (dBm)
#
# When set to -1, the downlink TX Power from the configured band will
# be used.
#
# Please consult the LoRaWAN Regional Parameters and local regulations
# for valid and legal options. Note that the configured TX Power must be
# supported by your gateway(s).
downlink_tx_power=-1
# ADR is disabled.
adr_disabled=false
# Minimum data-rate.
min_dr=0
# Maximum data-rate.
max_dr=5
# Enabled uplink channels.
#
# Use this when ony a sub-set of the by default enabled channels are being
# used. For example when only using the first 8 channels of the US band.
# Note: when left blank / empty array, all channels will be enabled.
enabled_uplink_channels=[88, 89, 90, 91, 92, 93, 94, 95]
# Rejoin-request configuration (LoRaWAN 1.1)
[regions.network.rejoin_request]
# Request devices to periodically send rejoin-requests.
enabled=false
# The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4)
# uplink messages. Valid values are 0 to 15.
max_count_n=0
# The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10)
# seconds. Valid values are 0 to 15.
#
# 0 = roughly 17 minutes
# 15 = about 1 year
max_time_n=0
# Class-B configuration.
[regions.network.class_b]
# Ping-slot data-rate.
ping_slot_dr=0
# Ping-slot frequency (Hz)
#
# set this to 0 to use the default frequency plan for the configured region
# (which could be frequency hopping).
ping_slot_frequency=0

View File

@ -0,0 +1,237 @@
# This file contains an example CN470 example (channels 16-23).
[[regions]]
# Name is an use-defined identifier for this region.
name="cn470_2"
# Common-name refers to the common-name of this region as defined by
# the LoRa Alliance.
common_name="CN470"
# Gateway configuration.
[regions.gateway]
# Force gateways as private.
#
# If enabled, gateways can only be used by devices under the same tenant.
force_gws_private=false
# Gateway backend configuration.
[regions.gateway.backend]
# The enabled backend type.
enabled="mqtt"
# MQTT configuration.
[regions.gateway.backend.mqtt]
# Event topic template.
event_topic="cn470_2/gateway/+/event/+"
# Command topic template.
command_topic="cn470_2/gateway/{{ gateway_id }}/command/{{ command }}"
# MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws)
server="tcp://$MQTT_BROKER_HOST:1883"
# Connect with the given username (optional)
username=""
# Connect with the given password (optional)
password=""
# Quality of service level
#
# 0: at most once
# 1: at least once
# 2: exactly once
#
# Note: an increase of this value will decrease the performance.
# For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels
qos=0
# Clean session
#
# Set the "clean session" flag in the connect message when this client
# connects to an MQTT broker. By setting this flag you are indicating
# that no messages saved by the broker for this client should be delivered.
clean_session=false
# Client ID
#
# Set the client id to be used by this client when connecting to the MQTT
# broker. A client id must be no longer than 23 characters. If left blank,
# a random id will be generated by ChirpStack.
client_id=""
# CA certificate file (optional)
#
# Use this when setting up a secure connection (when server uses ssl://...)
# but the certificate used by the server is not trusted by any CA certificate
# on the server (e.g. when self generated).
ca_cert=""
# TLS certificate file (optional)
tls_cert=""
# TLS key file (optional)
tls_key=""
# Gateway channel configuration.
#
# Note: this configuration is only used in case the gateway is using the
# ChirpStack Concentratord daemon. In any other case, this configuration
# is ignored.
[[regions.gateway.channels]]
frequency=473500000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=473700000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=473900000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=474100000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=474300000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=474500000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=474700000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=474900000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
# Region specific network configuration.
[regions.network]
# Installation margin (dB) used by the ADR engine.
#
# A higher number means that the network-server will keep more margin,
# resulting in a lower data-rate but decreasing the chance that the
# device gets disconnected because it is unable to reach one of the
# surrounded gateways.
installation_margin=10
# RX window (Class-A).
#
# Set this to:
# 0: RX1 / RX2
# 1: RX1 only
# 2: RX2 only
rx_window=0
# RX1 delay (1 - 15 seconds).
rx1_delay=1
# RX1 data-rate offset
rx1_dr_offset=0
# RX2 data-rate
rx2_dr=0
# RX2 frequency (Hz)
rx2_frequency=505300000
# Prefer RX2 on RX1 data-rate less than.
#
# Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate
# is smaller than the configured value, then the Network Server will
# first try to schedule the downlink for RX2, failing that (e.g. the gateway
# has already a payload scheduled at the RX2 timing) it will try RX1.
rx2_prefer_on_rx1_dr_lt=0
# Prefer RX2 on link budget.
#
# When the link-budget is better for RX2 than for RX1, the Network Server will first
# try to schedule the downlink in RX2, failing that it will try RX1.
rx2_prefer_on_link_budget=false
# Downlink TX Power (dBm)
#
# When set to -1, the downlink TX Power from the configured band will
# be used.
#
# Please consult the LoRaWAN Regional Parameters and local regulations
# for valid and legal options. Note that the configured TX Power must be
# supported by your gateway(s).
downlink_tx_power=-1
# ADR is disabled.
adr_disabled=false
# Minimum data-rate.
min_dr=0
# Maximum data-rate.
max_dr=5
# Enabled uplink channels.
#
# Use this when ony a sub-set of the by default enabled channels are being
# used. For example when only using the first 8 channels of the US band.
# Note: when left blank / empty array, all channels will be enabled.
enabled_uplink_channels=[16, 17, 18, 19, 20, 21, 22, 23]
# Rejoin-request configuration (LoRaWAN 1.1)
[regions.network.rejoin_request]
# Request devices to periodically send rejoin-requests.
enabled=false
# The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4)
# uplink messages. Valid values are 0 to 15.
max_count_n=0
# The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10)
# seconds. Valid values are 0 to 15.
#
# 0 = roughly 17 minutes
# 15 = about 1 year
max_time_n=0
# Class-B configuration.
[regions.network.class_b]
# Ping-slot data-rate.
ping_slot_dr=0
# Ping-slot frequency (Hz)
#
# set this to 0 to use the default frequency plan for the configured region
# (which could be frequency hopping).
ping_slot_frequency=0

View File

@ -0,0 +1,237 @@
# This file contains an example CN470 example (channels 24-31).
[[regions]]
# Name is an use-defined identifier for this region.
name="cn470_3"
# Common-name refers to the common-name of this region as defined by
# the LoRa Alliance.
common_name="CN470"
# Gateway configuration.
[regions.gateway]
# Force gateways as private.
#
# If enabled, gateways can only be used by devices under the same tenant.
force_gws_private=false
# Gateway backend configuration.
[regions.gateway.backend]
# The enabled backend type.
enabled="mqtt"
# MQTT configuration.
[regions.gateway.backend.mqtt]
# Event topic template.
event_topic="cn470_3/gateway/+/event/+"
# Command topic template.
command_topic="cn470_3/gateway/{{ gateway_id }}/command/{{ command }}"
# MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws)
server="tcp://$MQTT_BROKER_HOST:1883"
# Connect with the given username (optional)
username=""
# Connect with the given password (optional)
password=""
# Quality of service level
#
# 0: at most once
# 1: at least once
# 2: exactly once
#
# Note: an increase of this value will decrease the performance.
# For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels
qos=0
# Clean session
#
# Set the "clean session" flag in the connect message when this client
# connects to an MQTT broker. By setting this flag you are indicating
# that no messages saved by the broker for this client should be delivered.
clean_session=false
# Client ID
#
# Set the client id to be used by this client when connecting to the MQTT
# broker. A client id must be no longer than 23 characters. If left blank,
# a random id will be generated by ChirpStack.
client_id=""
# CA certificate file (optional)
#
# Use this when setting up a secure connection (when server uses ssl://...)
# but the certificate used by the server is not trusted by any CA certificate
# on the server (e.g. when self generated).
ca_cert=""
# TLS certificate file (optional)
tls_cert=""
# TLS key file (optional)
tls_key=""
# Gateway channel configuration.
#
# Note: this configuration is only used in case the gateway is using the
# ChirpStack Concentratord daemon. In any other case, this configuration
# is ignored.
[[regions.gateway.channels]]
frequency=475100000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=475300000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=475500000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=475700000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=475900000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=476100000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=476300000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=476500000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
# Region specific network configuration.
[regions.network]
# Installation margin (dB) used by the ADR engine.
#
# A higher number means that the network-server will keep more margin,
# resulting in a lower data-rate but decreasing the chance that the
# device gets disconnected because it is unable to reach one of the
# surrounded gateways.
installation_margin=10
# RX window (Class-A).
#
# Set this to:
# 0: RX1 / RX2
# 1: RX1 only
# 2: RX2 only
rx_window=0
# RX1 delay (1 - 15 seconds).
rx1_delay=1
# RX1 data-rate offset
rx1_dr_offset=0
# RX2 data-rate
rx2_dr=0
# RX2 frequency (Hz)
rx2_frequency=505300000
# Prefer RX2 on RX1 data-rate less than.
#
# Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate
# is smaller than the configured value, then the Network Server will
# first try to schedule the downlink for RX2, failing that (e.g. the gateway
# has already a payload scheduled at the RX2 timing) it will try RX1.
rx2_prefer_on_rx1_dr_lt=0
# Prefer RX2 on link budget.
#
# When the link-budget is better for RX2 than for RX1, the Network Server will first
# try to schedule the downlink in RX2, failing that it will try RX1.
rx2_prefer_on_link_budget=false
# Downlink TX Power (dBm)
#
# When set to -1, the downlink TX Power from the configured band will
# be used.
#
# Please consult the LoRaWAN Regional Parameters and local regulations
# for valid and legal options. Note that the configured TX Power must be
# supported by your gateway(s).
downlink_tx_power=-1
# ADR is disabled.
adr_disabled=false
# Minimum data-rate.
min_dr=0
# Maximum data-rate.
max_dr=5
# Enabled uplink channels.
#
# Use this when ony a sub-set of the by default enabled channels are being
# used. For example when only using the first 8 channels of the US band.
# Note: when left blank / empty array, all channels will be enabled.
enabled_uplink_channels=[24, 25, 26, 27, 28, 29, 30, 31]
# Rejoin-request configuration (LoRaWAN 1.1)
[regions.network.rejoin_request]
# Request devices to periodically send rejoin-requests.
enabled=false
# The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4)
# uplink messages. Valid values are 0 to 15.
max_count_n=0
# The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10)
# seconds. Valid values are 0 to 15.
#
# 0 = roughly 17 minutes
# 15 = about 1 year
max_time_n=0
# Class-B configuration.
[regions.network.class_b]
# Ping-slot data-rate.
ping_slot_dr=0
# Ping-slot frequency (Hz)
#
# set this to 0 to use the default frequency plan for the configured region
# (which could be frequency hopping).
ping_slot_frequency=0

View File

@ -0,0 +1,237 @@
# This file contains an example CN470 example (channels 32-39).
[[regions]]
# Name is an use-defined identifier for this region.
name="cn470_4"
# Common-name refers to the common-name of this region as defined by
# the LoRa Alliance.
common_name="CN470"
# Gateway configuration.
[regions.gateway]
# Force gateways as private.
#
# If enabled, gateways can only be used by devices under the same tenant.
force_gws_private=false
# Gateway backend configuration.
[regions.gateway.backend]
# The enabled backend type.
enabled="mqtt"
# MQTT configuration.
[regions.gateway.backend.mqtt]
# Event topic template.
event_topic="cn470_4/gateway/+/event/+"
# Command topic template.
command_topic="cn470_4/gateway/{{ gateway_id }}/command/{{ command }}"
# MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws)
server="tcp://$MQTT_BROKER_HOST:1883"
# Connect with the given username (optional)
username=""
# Connect with the given password (optional)
password=""
# Quality of service level
#
# 0: at most once
# 1: at least once
# 2: exactly once
#
# Note: an increase of this value will decrease the performance.
# For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels
qos=0
# Clean session
#
# Set the "clean session" flag in the connect message when this client
# connects to an MQTT broker. By setting this flag you are indicating
# that no messages saved by the broker for this client should be delivered.
clean_session=false
# Client ID
#
# Set the client id to be used by this client when connecting to the MQTT
# broker. A client id must be no longer than 23 characters. If left blank,
# a random id will be generated by ChirpStack.
client_id=""
# CA certificate file (optional)
#
# Use this when setting up a secure connection (when server uses ssl://...)
# but the certificate used by the server is not trusted by any CA certificate
# on the server (e.g. when self generated).
ca_cert=""
# TLS certificate file (optional)
tls_cert=""
# TLS key file (optional)
tls_key=""
# Gateway channel configuration.
#
# Note: this configuration is only used in case the gateway is using the
# ChirpStack Concentratord daemon. In any other case, this configuration
# is ignored.
[[regions.gateway.channels]]
frequency=476700000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=476900000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=477100000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=477300000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=477500000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=477700000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=477900000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=478100000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
# Region specific network configuration.
[regions.network]
# Installation margin (dB) used by the ADR engine.
#
# A higher number means that the network-server will keep more margin,
# resulting in a lower data-rate but decreasing the chance that the
# device gets disconnected because it is unable to reach one of the
# surrounded gateways.
installation_margin=10
# RX window (Class-A).
#
# Set this to:
# 0: RX1 / RX2
# 1: RX1 only
# 2: RX2 only
rx_window=0
# RX1 delay (1 - 15 seconds).
rx1_delay=1
# RX1 data-rate offset
rx1_dr_offset=0
# RX2 data-rate
rx2_dr=0
# RX2 frequency (Hz)
rx2_frequency=505300000
# Prefer RX2 on RX1 data-rate less than.
#
# Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate
# is smaller than the configured value, then the Network Server will
# first try to schedule the downlink for RX2, failing that (e.g. the gateway
# has already a payload scheduled at the RX2 timing) it will try RX1.
rx2_prefer_on_rx1_dr_lt=0
# Prefer RX2 on link budget.
#
# When the link-budget is better for RX2 than for RX1, the Network Server will first
# try to schedule the downlink in RX2, failing that it will try RX1.
rx2_prefer_on_link_budget=false
# Downlink TX Power (dBm)
#
# When set to -1, the downlink TX Power from the configured band will
# be used.
#
# Please consult the LoRaWAN Regional Parameters and local regulations
# for valid and legal options. Note that the configured TX Power must be
# supported by your gateway(s).
downlink_tx_power=-1
# ADR is disabled.
adr_disabled=false
# Minimum data-rate.
min_dr=0
# Maximum data-rate.
max_dr=5
# Enabled uplink channels.
#
# Use this when ony a sub-set of the by default enabled channels are being
# used. For example when only using the first 8 channels of the US band.
# Note: when left blank / empty array, all channels will be enabled.
enabled_uplink_channels=[32, 33, 34, 35, 36, 37, 38, 39]
# Rejoin-request configuration (LoRaWAN 1.1)
[regions.network.rejoin_request]
# Request devices to periodically send rejoin-requests.
enabled=false
# The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4)
# uplink messages. Valid values are 0 to 15.
max_count_n=0
# The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10)
# seconds. Valid values are 0 to 15.
#
# 0 = roughly 17 minutes
# 15 = about 1 year
max_time_n=0
# Class-B configuration.
[regions.network.class_b]
# Ping-slot data-rate.
ping_slot_dr=0
# Ping-slot frequency (Hz)
#
# set this to 0 to use the default frequency plan for the configured region
# (which could be frequency hopping).
ping_slot_frequency=0

View File

@ -0,0 +1,237 @@
# This file contains an example CN470 example (channels 40-47).
[[regions]]
# Name is an use-defined identifier for this region.
name="cn470_5"
# Common-name refers to the common-name of this region as defined by
# the LoRa Alliance.
common_name="CN470"
# Gateway configuration.
[regions.gateway]
# Force gateways as private.
#
# If enabled, gateways can only be used by devices under the same tenant.
force_gws_private=false
# Gateway backend configuration.
[regions.gateway.backend]
# The enabled backend type.
enabled="mqtt"
# MQTT configuration.
[regions.gateway.backend.mqtt]
# Event topic template.
event_topic="cn470_5/gateway/+/event/+"
# Command topic template.
command_topic="cn470_5/gateway/{{ gateway_id }}/command/{{ command }}"
# MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws)
server="tcp://$MQTT_BROKER_HOST:1883"
# Connect with the given username (optional)
username=""
# Connect with the given password (optional)
password=""
# Quality of service level
#
# 0: at most once
# 1: at least once
# 2: exactly once
#
# Note: an increase of this value will decrease the performance.
# For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels
qos=0
# Clean session
#
# Set the "clean session" flag in the connect message when this client
# connects to an MQTT broker. By setting this flag you are indicating
# that no messages saved by the broker for this client should be delivered.
clean_session=false
# Client ID
#
# Set the client id to be used by this client when connecting to the MQTT
# broker. A client id must be no longer than 23 characters. If left blank,
# a random id will be generated by ChirpStack.
client_id=""
# CA certificate file (optional)
#
# Use this when setting up a secure connection (when server uses ssl://...)
# but the certificate used by the server is not trusted by any CA certificate
# on the server (e.g. when self generated).
ca_cert=""
# TLS certificate file (optional)
tls_cert=""
# TLS key file (optional)
tls_key=""
# Gateway channel configuration.
#
# Note: this configuration is only used in case the gateway is using the
# ChirpStack Concentratord daemon. In any other case, this configuration
# is ignored.
[[regions.gateway.channels]]
frequency=478300000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=478500000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=478700000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=478900000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=479100000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=479300000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=479500000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=479700000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
# Region specific network configuration.
[regions.network]
# Installation margin (dB) used by the ADR engine.
#
# A higher number means that the network-server will keep more margin,
# resulting in a lower data-rate but decreasing the chance that the
# device gets disconnected because it is unable to reach one of the
# surrounded gateways.
installation_margin=10
# RX window (Class-A).
#
# Set this to:
# 0: RX1 / RX2
# 1: RX1 only
# 2: RX2 only
rx_window=0
# RX1 delay (1 - 15 seconds).
rx1_delay=1
# RX1 data-rate offset
rx1_dr_offset=0
# RX2 data-rate
rx2_dr=0
# RX2 frequency (Hz)
rx2_frequency=505300000
# Prefer RX2 on RX1 data-rate less than.
#
# Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate
# is smaller than the configured value, then the Network Server will
# first try to schedule the downlink for RX2, failing that (e.g. the gateway
# has already a payload scheduled at the RX2 timing) it will try RX1.
rx2_prefer_on_rx1_dr_lt=0
# Prefer RX2 on link budget.
#
# When the link-budget is better for RX2 than for RX1, the Network Server will first
# try to schedule the downlink in RX2, failing that it will try RX1.
rx2_prefer_on_link_budget=false
# Downlink TX Power (dBm)
#
# When set to -1, the downlink TX Power from the configured band will
# be used.
#
# Please consult the LoRaWAN Regional Parameters and local regulations
# for valid and legal options. Note that the configured TX Power must be
# supported by your gateway(s).
downlink_tx_power=-1
# ADR is disabled.
adr_disabled=false
# Minimum data-rate.
min_dr=0
# Maximum data-rate.
max_dr=5
# Enabled uplink channels.
#
# Use this when ony a sub-set of the by default enabled channels are being
# used. For example when only using the first 8 channels of the US band.
# Note: when left blank / empty array, all channels will be enabled.
enabled_uplink_channels=[40, 41, 42, 43, 44, 45, 46, 47]
# Rejoin-request configuration (LoRaWAN 1.1)
[regions.network.rejoin_request]
# Request devices to periodically send rejoin-requests.
enabled=false
# The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4)
# uplink messages. Valid values are 0 to 15.
max_count_n=0
# The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10)
# seconds. Valid values are 0 to 15.
#
# 0 = roughly 17 minutes
# 15 = about 1 year
max_time_n=0
# Class-B configuration.
[regions.network.class_b]
# Ping-slot data-rate.
ping_slot_dr=0
# Ping-slot frequency (Hz)
#
# set this to 0 to use the default frequency plan for the configured region
# (which could be frequency hopping).
ping_slot_frequency=0

View File

@ -0,0 +1,237 @@
# This file contains an example CN470 example (channels 48-55).
[[regions]]
# Name is an use-defined identifier for this region.
name="cn470_6"
# Common-name refers to the common-name of this region as defined by
# the LoRa Alliance.
common_name="CN470"
# Gateway configuration.
[regions.gateway]
# Force gateways as private.
#
# If enabled, gateways can only be used by devices under the same tenant.
force_gws_private=false
# Gateway backend configuration.
[regions.gateway.backend]
# The enabled backend type.
enabled="mqtt"
# MQTT configuration.
[regions.gateway.backend.mqtt]
# Event topic template.
event_topic="cn470_6/gateway/+/event/+"
# Command topic template.
command_topic="cn470_6/gateway/{{ gateway_id }}/command/{{ command }}"
# MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws)
server="tcp://$MQTT_BROKER_HOST:1883"
# Connect with the given username (optional)
username=""
# Connect with the given password (optional)
password=""
# Quality of service level
#
# 0: at most once
# 1: at least once
# 2: exactly once
#
# Note: an increase of this value will decrease the performance.
# For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels
qos=0
# Clean session
#
# Set the "clean session" flag in the connect message when this client
# connects to an MQTT broker. By setting this flag you are indicating
# that no messages saved by the broker for this client should be delivered.
clean_session=false
# Client ID
#
# Set the client id to be used by this client when connecting to the MQTT
# broker. A client id must be no longer than 23 characters. If left blank,
# a random id will be generated by ChirpStack.
client_id=""
# CA certificate file (optional)
#
# Use this when setting up a secure connection (when server uses ssl://...)
# but the certificate used by the server is not trusted by any CA certificate
# on the server (e.g. when self generated).
ca_cert=""
# TLS certificate file (optional)
tls_cert=""
# TLS key file (optional)
tls_key=""
# Gateway channel configuration.
#
# Note: this configuration is only used in case the gateway is using the
# ChirpStack Concentratord daemon. In any other case, this configuration
# is ignored.
[[regions.gateway.channels]]
frequency=479900000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=480100000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=480300000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=480500000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=480700000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=480900000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=481100000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=481300000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
# Region specific network configuration.
[regions.network]
# Installation margin (dB) used by the ADR engine.
#
# A higher number means that the network-server will keep more margin,
# resulting in a lower data-rate but decreasing the chance that the
# device gets disconnected because it is unable to reach one of the
# surrounded gateways.
installation_margin=10
# RX window (Class-A).
#
# Set this to:
# 0: RX1 / RX2
# 1: RX1 only
# 2: RX2 only
rx_window=0
# RX1 delay (1 - 15 seconds).
rx1_delay=1
# RX1 data-rate offset
rx1_dr_offset=0
# RX2 data-rate
rx2_dr=0
# RX2 frequency (Hz)
rx2_frequency=505300000
# Prefer RX2 on RX1 data-rate less than.
#
# Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate
# is smaller than the configured value, then the Network Server will
# first try to schedule the downlink for RX2, failing that (e.g. the gateway
# has already a payload scheduled at the RX2 timing) it will try RX1.
rx2_prefer_on_rx1_dr_lt=0
# Prefer RX2 on link budget.
#
# When the link-budget is better for RX2 than for RX1, the Network Server will first
# try to schedule the downlink in RX2, failing that it will try RX1.
rx2_prefer_on_link_budget=false
# Downlink TX Power (dBm)
#
# When set to -1, the downlink TX Power from the configured band will
# be used.
#
# Please consult the LoRaWAN Regional Parameters and local regulations
# for valid and legal options. Note that the configured TX Power must be
# supported by your gateway(s).
downlink_tx_power=-1
# ADR is disabled.
adr_disabled=false
# Minimum data-rate.
min_dr=0
# Maximum data-rate.
max_dr=5
# Enabled uplink channels.
#
# Use this when ony a sub-set of the by default enabled channels are being
# used. For example when only using the first 8 channels of the US band.
# Note: when left blank / empty array, all channels will be enabled.
enabled_uplink_channels=[48, 49, 50, 51, 52, 53, 54, 55]
# Rejoin-request configuration (LoRaWAN 1.1)
[regions.network.rejoin_request]
# Request devices to periodically send rejoin-requests.
enabled=false
# The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4)
# uplink messages. Valid values are 0 to 15.
max_count_n=0
# The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10)
# seconds. Valid values are 0 to 15.
#
# 0 = roughly 17 minutes
# 15 = about 1 year
max_time_n=0
# Class-B configuration.
[regions.network.class_b]
# Ping-slot data-rate.
ping_slot_dr=0
# Ping-slot frequency (Hz)
#
# set this to 0 to use the default frequency plan for the configured region
# (which could be frequency hopping).
ping_slot_frequency=0

View File

@ -0,0 +1,237 @@
# This file contains an example CN470 example (channels 56-63).
[[regions]]
# Name is an use-defined identifier for this region.
name="cn470_7"
# Common-name refers to the common-name of this region as defined by
# the LoRa Alliance.
common_name="CN470"
# Gateway configuration.
[regions.gateway]
# Force gateways as private.
#
# If enabled, gateways can only be used by devices under the same tenant.
force_gws_private=false
# Gateway backend configuration.
[regions.gateway.backend]
# The enabled backend type.
enabled="mqtt"
# MQTT configuration.
[regions.gateway.backend.mqtt]
# Event topic template.
event_topic="cn470_7/gateway/+/event/+"
# Command topic template.
command_topic="cn470_7/gateway/{{ gateway_id }}/command/{{ command }}"
# MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws)
server="tcp://$MQTT_BROKER_HOST:1883"
# Connect with the given username (optional)
username=""
# Connect with the given password (optional)
password=""
# Quality of service level
#
# 0: at most once
# 1: at least once
# 2: exactly once
#
# Note: an increase of this value will decrease the performance.
# For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels
qos=0
# Clean session
#
# Set the "clean session" flag in the connect message when this client
# connects to an MQTT broker. By setting this flag you are indicating
# that no messages saved by the broker for this client should be delivered.
clean_session=false
# Client ID
#
# Set the client id to be used by this client when connecting to the MQTT
# broker. A client id must be no longer than 23 characters. If left blank,
# a random id will be generated by ChirpStack.
client_id=""
# CA certificate file (optional)
#
# Use this when setting up a secure connection (when server uses ssl://...)
# but the certificate used by the server is not trusted by any CA certificate
# on the server (e.g. when self generated).
ca_cert=""
# TLS certificate file (optional)
tls_cert=""
# TLS key file (optional)
tls_key=""
# Gateway channel configuration.
#
# Note: this configuration is only used in case the gateway is using the
# ChirpStack Concentratord daemon. In any other case, this configuration
# is ignored.
[[regions.gateway.channels]]
frequency=481500000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=481700000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=481900000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=482100000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=482300000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=482500000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=482700000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=482900000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
# Region specific network configuration.
[regions.network]
# Installation margin (dB) used by the ADR engine.
#
# A higher number means that the network-server will keep more margin,
# resulting in a lower data-rate but decreasing the chance that the
# device gets disconnected because it is unable to reach one of the
# surrounded gateways.
installation_margin=10
# RX window (Class-A).
#
# Set this to:
# 0: RX1 / RX2
# 1: RX1 only
# 2: RX2 only
rx_window=0
# RX1 delay (1 - 15 seconds).
rx1_delay=1
# RX1 data-rate offset
rx1_dr_offset=0
# RX2 data-rate
rx2_dr=0
# RX2 frequency (Hz)
rx2_frequency=505300000
# Prefer RX2 on RX1 data-rate less than.
#
# Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate
# is smaller than the configured value, then the Network Server will
# first try to schedule the downlink for RX2, failing that (e.g. the gateway
# has already a payload scheduled at the RX2 timing) it will try RX1.
rx2_prefer_on_rx1_dr_lt=0
# Prefer RX2 on link budget.
#
# When the link-budget is better for RX2 than for RX1, the Network Server will first
# try to schedule the downlink in RX2, failing that it will try RX1.
rx2_prefer_on_link_budget=false
# Downlink TX Power (dBm)
#
# When set to -1, the downlink TX Power from the configured band will
# be used.
#
# Please consult the LoRaWAN Regional Parameters and local regulations
# for valid and legal options. Note that the configured TX Power must be
# supported by your gateway(s).
downlink_tx_power=-1
# ADR is disabled.
adr_disabled=false
# Minimum data-rate.
min_dr=0
# Maximum data-rate.
max_dr=5
# Enabled uplink channels.
#
# Use this when ony a sub-set of the by default enabled channels are being
# used. For example when only using the first 8 channels of the US band.
# Note: when left blank / empty array, all channels will be enabled.
enabled_uplink_channels=[56, 57, 58, 59, 60, 61, 62, 63]
# Rejoin-request configuration (LoRaWAN 1.1)
[regions.network.rejoin_request]
# Request devices to periodically send rejoin-requests.
enabled=false
# The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4)
# uplink messages. Valid values are 0 to 15.
max_count_n=0
# The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10)
# seconds. Valid values are 0 to 15.
#
# 0 = roughly 17 minutes
# 15 = about 1 year
max_time_n=0
# Class-B configuration.
[regions.network.class_b]
# Ping-slot data-rate.
ping_slot_dr=0
# Ping-slot frequency (Hz)
#
# set this to 0 to use the default frequency plan for the configured region
# (which could be frequency hopping).
ping_slot_frequency=0

View File

@ -0,0 +1,237 @@
# This file contains an example CN470 example (channels 64-71).
[[regions]]
# Name is an use-defined identifier for this region.
name="cn470_8"
# Common-name refers to the common-name of this region as defined by
# the LoRa Alliance.
common_name="CN470"
# Gateway configuration.
[regions.gateway]
# Force gateways as private.
#
# If enabled, gateways can only be used by devices under the same tenant.
force_gws_private=false
# Gateway backend configuration.
[regions.gateway.backend]
# The enabled backend type.
enabled="mqtt"
# MQTT configuration.
[regions.gateway.backend.mqtt]
# Event topic template.
event_topic="cn470_8/gateway/+/event/+"
# Command topic template.
command_topic="cn470_8/gateway/{{ gateway_id }}/command/{{ command }}"
# MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws)
server="tcp://$MQTT_BROKER_HOST:1883"
# Connect with the given username (optional)
username=""
# Connect with the given password (optional)
password=""
# Quality of service level
#
# 0: at most once
# 1: at least once
# 2: exactly once
#
# Note: an increase of this value will decrease the performance.
# For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels
qos=0
# Clean session
#
# Set the "clean session" flag in the connect message when this client
# connects to an MQTT broker. By setting this flag you are indicating
# that no messages saved by the broker for this client should be delivered.
clean_session=false
# Client ID
#
# Set the client id to be used by this client when connecting to the MQTT
# broker. A client id must be no longer than 23 characters. If left blank,
# a random id will be generated by ChirpStack.
client_id=""
# CA certificate file (optional)
#
# Use this when setting up a secure connection (when server uses ssl://...)
# but the certificate used by the server is not trusted by any CA certificate
# on the server (e.g. when self generated).
ca_cert=""
# TLS certificate file (optional)
tls_cert=""
# TLS key file (optional)
tls_key=""
# Gateway channel configuration.
#
# Note: this configuration is only used in case the gateway is using the
# ChirpStack Concentratord daemon. In any other case, this configuration
# is ignored.
[[regions.gateway.channels]]
frequency=483100000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=483300000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=483500000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=483700000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=483900000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=484100000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=484300000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=484500000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
# Region specific network configuration.
[regions.network]
# Installation margin (dB) used by the ADR engine.
#
# A higher number means that the network-server will keep more margin,
# resulting in a lower data-rate but decreasing the chance that the
# device gets disconnected because it is unable to reach one of the
# surrounded gateways.
installation_margin=10
# RX window (Class-A).
#
# Set this to:
# 0: RX1 / RX2
# 1: RX1 only
# 2: RX2 only
rx_window=0
# RX1 delay (1 - 15 seconds).
rx1_delay=1
# RX1 data-rate offset
rx1_dr_offset=0
# RX2 data-rate
rx2_dr=0
# RX2 frequency (Hz)
rx2_frequency=505300000
# Prefer RX2 on RX1 data-rate less than.
#
# Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate
# is smaller than the configured value, then the Network Server will
# first try to schedule the downlink for RX2, failing that (e.g. the gateway
# has already a payload scheduled at the RX2 timing) it will try RX1.
rx2_prefer_on_rx1_dr_lt=0
# Prefer RX2 on link budget.
#
# When the link-budget is better for RX2 than for RX1, the Network Server will first
# try to schedule the downlink in RX2, failing that it will try RX1.
rx2_prefer_on_link_budget=false
# Downlink TX Power (dBm)
#
# When set to -1, the downlink TX Power from the configured band will
# be used.
#
# Please consult the LoRaWAN Regional Parameters and local regulations
# for valid and legal options. Note that the configured TX Power must be
# supported by your gateway(s).
downlink_tx_power=-1
# ADR is disabled.
adr_disabled=false
# Minimum data-rate.
min_dr=0
# Maximum data-rate.
max_dr=5
# Enabled uplink channels.
#
# Use this when ony a sub-set of the by default enabled channels are being
# used. For example when only using the first 8 channels of the US band.
# Note: when left blank / empty array, all channels will be enabled.
enabled_uplink_channels=[64, 65, 66, 67, 68, 69, 70, 71]
# Rejoin-request configuration (LoRaWAN 1.1)
[regions.network.rejoin_request]
# Request devices to periodically send rejoin-requests.
enabled=false
# The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4)
# uplink messages. Valid values are 0 to 15.
max_count_n=0
# The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10)
# seconds. Valid values are 0 to 15.
#
# 0 = roughly 17 minutes
# 15 = about 1 year
max_time_n=0
# Class-B configuration.
[regions.network.class_b]
# Ping-slot data-rate.
ping_slot_dr=0
# Ping-slot frequency (Hz)
#
# set this to 0 to use the default frequency plan for the configured region
# (which could be frequency hopping).
ping_slot_frequency=0

View File

@ -0,0 +1,237 @@
# This file contains an example CN470 example (channels 72-79).
[[regions]]
# Name is an use-defined identifier for this region.
name="cn470_9"
# Common-name refers to the common-name of this region as defined by
# the LoRa Alliance.
common_name="CN470"
# Gateway configuration.
[regions.gateway]
# Force gateways as private.
#
# If enabled, gateways can only be used by devices under the same tenant.
force_gws_private=false
# Gateway backend configuration.
[regions.gateway.backend]
# The enabled backend type.
enabled="mqtt"
# MQTT configuration.
[regions.gateway.backend.mqtt]
# Event topic template.
event_topic="cn470_9/gateway/+/event/+"
# Command topic template.
command_topic="cn470_9/gateway/{{ gateway_id }}/command/{{ command }}"
# MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws)
server="tcp://$MQTT_BROKER_HOST:1883"
# Connect with the given username (optional)
username=""
# Connect with the given password (optional)
password=""
# Quality of service level
#
# 0: at most once
# 1: at least once
# 2: exactly once
#
# Note: an increase of this value will decrease the performance.
# For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels
qos=0
# Clean session
#
# Set the "clean session" flag in the connect message when this client
# connects to an MQTT broker. By setting this flag you are indicating
# that no messages saved by the broker for this client should be delivered.
clean_session=false
# Client ID
#
# Set the client id to be used by this client when connecting to the MQTT
# broker. A client id must be no longer than 23 characters. If left blank,
# a random id will be generated by ChirpStack.
client_id=""
# CA certificate file (optional)
#
# Use this when setting up a secure connection (when server uses ssl://...)
# but the certificate used by the server is not trusted by any CA certificate
# on the server (e.g. when self generated).
ca_cert=""
# TLS certificate file (optional)
tls_cert=""
# TLS key file (optional)
tls_key=""
# Gateway channel configuration.
#
# Note: this configuration is only used in case the gateway is using the
# ChirpStack Concentratord daemon. In any other case, this configuration
# is ignored.
[[regions.gateway.channels]]
frequency=484700000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=484900000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=485100000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=485300000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=485500000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=485700000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=485900000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
[[regions.gateway.channels]]
frequency=486100000
bandwidth=125000
modulation="LORA"
spreading_factors=[7, 8, 9, 10, 11, 12]
# Region specific network configuration.
[regions.network]
# Installation margin (dB) used by the ADR engine.
#
# A higher number means that the network-server will keep more margin,
# resulting in a lower data-rate but decreasing the chance that the
# device gets disconnected because it is unable to reach one of the
# surrounded gateways.
installation_margin=10
# RX window (Class-A).
#
# Set this to:
# 0: RX1 / RX2
# 1: RX1 only
# 2: RX2 only
rx_window=0
# RX1 delay (1 - 15 seconds).
rx1_delay=1
# RX1 data-rate offset
rx1_dr_offset=0
# RX2 data-rate
rx2_dr=0
# RX2 frequency (Hz)
rx2_frequency=505300000
# Prefer RX2 on RX1 data-rate less than.
#
# Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate
# is smaller than the configured value, then the Network Server will
# first try to schedule the downlink for RX2, failing that (e.g. the gateway
# has already a payload scheduled at the RX2 timing) it will try RX1.
rx2_prefer_on_rx1_dr_lt=0
# Prefer RX2 on link budget.
#
# When the link-budget is better for RX2 than for RX1, the Network Server will first
# try to schedule the downlink in RX2, failing that it will try RX1.
rx2_prefer_on_link_budget=false
# Downlink TX Power (dBm)
#
# When set to -1, the downlink TX Power from the configured band will
# be used.
#
# Please consult the LoRaWAN Regional Parameters and local regulations
# for valid and legal options. Note that the configured TX Power must be
# supported by your gateway(s).
downlink_tx_power=-1
# ADR is disabled.
adr_disabled=false
# Minimum data-rate.
min_dr=0
# Maximum data-rate.
max_dr=5
# Enabled uplink channels.
#
# Use this when ony a sub-set of the by default enabled channels are being
# used. For example when only using the first 8 channels of the US band.
# Note: when left blank / empty array, all channels will be enabled.
enabled_uplink_channels=[72, 73, 74, 75, 76, 77, 78, 79]
# Rejoin-request configuration (LoRaWAN 1.1)
[regions.network.rejoin_request]
# Request devices to periodically send rejoin-requests.
enabled=false
# The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4)
# uplink messages. Valid values are 0 to 15.
max_count_n=0
# The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10)
# seconds. Valid values are 0 to 15.
#
# 0 = roughly 17 minutes
# 15 = about 1 year
max_time_n=0
# Class-B configuration.
[regions.network.class_b]
# Ping-slot data-rate.
ping_slot_dr=0
# Ping-slot frequency (Hz)
#
# set this to 0 to use the default frequency plan for the configured region
# (which could be frequency hopping).
ping_slot_frequency=0

View File

@ -1,4 +0,0 @@
[Service]
Environment="MQTT_BROKER_HOST=localhost"
Environment="POSTGRESQL_HOST=localhost"
Environment="REDIS_HOST=localhost"

View File

@ -3,18 +3,11 @@
# Set config-file permissions
chown -R chirpstack:chirpstack /etc/chirpstack
chmod 750 /etc/chirpstack
chmod 750 /etc/chirpstack/certs
chmod 640 /etc/chirpstack/*.toml
# Generate certificates
CERTROOT=/etc/chirpstack/certs
if [ ! -f $CERTROOT/ca.pem ]; then
cfssl gencert -initca $CERTROOT/ca-csr.json | cfssljson -bare $CERTROOT/ca
fi
if [ ! -f $CERTROOT/mqtt-server.pem ]; then
cfssl gencert -ca $CERTROOT/ca.pem -ca-key $CERTROOT/ca-key.pem -config $CERTROOT/ca-config.json -profile server $CERTROOT/mqtt-server.json | cfssljson -bare $CERTROOT/mqtt-server
fi
# Set environment variables to localhost
sed -i "s/\$MQTT_BROKER_HOST/localhost/" /etc/chirpstack/*.toml
sed -i "s/\$POSTGRESQL_HOST/localhost/" /etc/chirpstack/*.toml
sed -i "s/\$REDIS_HOST/localhost/" /etc/chirpstack/*.toml
#DEBHELPER#

View File

@ -8,7 +8,7 @@ use anyhow::Result;
use redis::streams::StreamReadReply;
use tokio::sync::oneshot;
use tokio::task;
use tracing::{error, info, warn};
use tracing::{debug, error, info, warn};
use uuid::Uuid;
use warp::{http::StatusCode, Filter, Reply};
@ -69,6 +69,8 @@ pub async fn handle_request(mut body: impl warp::Buf) -> http::Response<hyper::B
body.advance(cnt);
}
debug!("JSON: {}", String::from_utf8(b.clone()).unwrap_or_default());
let bp: BasePayload = match serde_json::from_slice(&b) {
Ok(v) => v,
Err(e) => {

View File

@ -667,7 +667,8 @@ impl DeviceService for Device {
kind: match v.kind {
fields::MeasurementKind::COUNTER => common::MetricKind::Counter,
fields::MeasurementKind::ABSOLUTE => common::MetricKind::Absolute,
fields::MeasurementKind::GAUGE | _ => common::MetricKind::Gauge,
fields::MeasurementKind::GAUGE => common::MetricKind::Gauge,
_ => common::MetricKind::Gauge,
}
.into(),
},

View File

@ -172,8 +172,13 @@ impl TenantService for Tenant {
}
}
AuthID::Key(_) => {
// Nothing to do as the validator function already validated that the
// Nothing else to do as the validator function already validated that the
// API key must be a global admin key.
if !req.user_id.is_empty() {
let user_id = Uuid::from_str(&req.user_id).map_err(|e| e.status())?;
filters.user_id = Some(user_id);
}
}
_ => {
// this should never happen
@ -492,6 +497,7 @@ pub mod test {
search: "update".into(),
offset: 0,
limit: 10,
user_id: "".into(),
};
let mut list_req = Request::new(list_req);
list_req.extensions_mut().insert(AuthID::User(u.id.clone()));

View File

@ -96,13 +96,19 @@ pub fn run() {
# will generate client certificates which can be used by the gateway for
# authentication and authorization. The Common Name of the certificate will
# be set to the Gateway ID.
client_cert_lifetime="{{ gateway.client_cert_lifetime }}"
ca_key="{{ gateway.ca_key }}"
ca_cert="{{ gateway.ca_cert }}"
# Certificate lifetime.
#
# This defines how long (after generating) the certificate remains valid.
ca_key="{{ gateway.ca_key }}"
client_cert_lifetime="{{ gateway.client_cert_lifetime }}"
# Allow unknown gateways.
#
# If set to true, then uplinks received from gateways not configured in
# ChirpStack will be allowed.
allow_unknown_gateways={{ gateway.allow_unknown_gateways }}
# Network related configuration.
@ -334,6 +340,24 @@ pub fn run() {
tls_key="{{ integration.mqtt.tls_key }}"
# Configuration for MQTT clients.
[integration.mqtt.client]
# CA certificate and key file (optional).
#
# If setting the CA certificate and key file options, ChirpStack
# will generate client certificates which can be used by the MQTT clients for
# authentication and authorization. The Common Name of the certificate will
# be set to the ID of the application.
ca_key="{{ integration.mqtt.ca_key }}"
ca_cert="{{ integration.mqtt.ca_cert }}"
# Certificate lifetime.
#
# This defines how long (after generating) the certificate remains valid.
client_cert_lifetime="{{ integration.mqtt.client_cert_lifetime }}"
# PostgreSQL integration configuration.
[integration.postgresql]

View File

@ -132,6 +132,7 @@ pub struct Gateway {
pub client_cert_lifetime: Duration,
pub ca_cert: String,
pub ca_key: String,
pub allow_unknown_gateways: bool,
}
impl Default for Gateway {
@ -140,6 +141,7 @@ impl Default for Gateway {
client_cert_lifetime: Duration::from_secs(60 * 60 * 24 * 365),
ca_cert: "".to_string(),
ca_key: "".to_string(),
allow_unknown_gateways: false,
}
}
}

View File

@ -142,16 +142,16 @@ impl Data {
ctx.update_device_queue_item().await?;
ctx.save_downlink_frame().await?;
if ctx._is_roaming() {
ctx.save_device_session().await?;
ctx.send_downlink_frame_passive_roaming().await?;
ctx.handle_passive_roaming_tx_ack().await?;
} else {
// Some mac-commands set their state (e.g. last requested) to the device-session.
ctx.save_device_session().await?;
ctx.send_downlink_frame().await?;
}
}
// Some mac-commands set their state (e.g. last requested) to the device-session.
ctx.save_device_session().await?;
Ok(())
}
@ -389,6 +389,8 @@ impl Data {
self._set_rx_parameters().await?;
self._set_tx_parameters().await?;
self.mac_commands = filter_mac_commands(&self.device_session, &self.mac_commands);
Ok(())
}
@ -557,6 +559,19 @@ impl Data {
}
}
// Encrypt f_opts mac-commands (LoRaWAN 1.1)
if !self
.device_session
.mac_version()
.to_string()
.starts_with("1.0")
{
phy.encrypt_f_opts(&lrwn::AES128Key::from_slice(
&self.device_session.nwk_s_enc_key,
)?)
.context("Encrypt f_opts")?;
}
// Set MIC.
// If this is an ACK, then FCntUp has already been incremented by one. If
// this is not an ACK, then DownlinkDataMIC will zero out ConfFCnt.
@ -807,6 +822,7 @@ impl Data {
// Note: this must come before ADR!
async fn _request_channel_mask_reconfiguration(&mut self) -> Result<()> {
trace!("Requesting channel-mask reconfiguration");
let enabled_uplink_channel_indices: Vec<usize> = self
.device_session
.enabled_uplink_channel_indices
@ -1408,3 +1424,233 @@ impl Data {
Ok(false)
}
}
fn filter_mac_commands(
device_session: &internal::DeviceSession,
mac_commands: &[lrwn::MACCommandSet],
) -> Vec<lrwn::MACCommandSet> {
let incompatible_macs: HashMap<lrwn::CID, Vec<lrwn::CID>> = [
(lrwn::CID::NewChannelReq, vec![lrwn::CID::LinkADRReq]),
(lrwn::CID::LinkADRReq, vec![lrwn::CID::NewChannelReq]),
]
.iter()
.cloned()
.collect();
let mut filtered_mac_commands: Vec<lrwn::MACCommandSet> = Vec::new();
'outer: for mac_command_set in mac_commands {
for mac_command in &**mac_command_set {
// Check if it doesn't exceed the max error error count.
if device_session
.mac_command_error_count
.get(&(mac_command.cid().byte() as u32))
.cloned()
.unwrap_or_default()
> 1
{
continue 'outer;
}
// Check if there aren't any conflicting mac-commands.
if let Some(incompatible_cids) = incompatible_macs.get(&mac_command.cid()) {
for mac_command_set in &filtered_mac_commands {
for mac_command in &**mac_command_set {
if incompatible_cids.contains(&mac_command.cid()) {
continue 'outer;
}
}
}
}
}
filtered_mac_commands.push(mac_command_set.clone());
}
filtered_mac_commands
}
#[cfg(test)]
mod test {
use super::*;
struct Test {
device_session: internal::DeviceSession,
mac_commands: Vec<lrwn::MACCommandSet>,
expected_mac_commands: Vec<lrwn::MACCommandSet>,
}
#[test]
fn test_filter_mac_commands() {
let tests = vec![
// No mac-commands set.
Test {
device_session: internal::DeviceSession {
..Default::default()
},
mac_commands: Vec::new(),
expected_mac_commands: Vec::new(),
},
// One LinkADRReq, no errors.
Test {
device_session: internal::DeviceSession {
mac_command_error_count: [(lrwn::CID::LinkADRReq.byte() as u32, 0)]
.iter()
.cloned()
.collect(),
..Default::default()
},
mac_commands: vec![lrwn::MACCommandSet::new(vec![
lrwn::MACCommand::LinkADRReq(lrwn::LinkADRReqPayload {
dr: 0,
tx_power: 0,
ch_mask: lrwn::ChMask::new([false; 16]),
redundancy: lrwn::Redundancy {
ch_mask_cntl: 0,
nb_rep: 0,
},
}),
])],
expected_mac_commands: vec![lrwn::MACCommandSet::new(vec![
lrwn::MACCommand::LinkADRReq(lrwn::LinkADRReqPayload {
dr: 0,
tx_power: 0,
ch_mask: lrwn::ChMask::new([false; 16]),
redundancy: lrwn::Redundancy {
ch_mask_cntl: 0,
nb_rep: 0,
},
}),
])],
},
// One LinkADRReq, 0 errors (HashMap contains the CID, but count = 0).
Test {
device_session: internal::DeviceSession {
mac_command_error_count: [(lrwn::CID::LinkADRReq.byte() as u32, 0)]
.iter()
.cloned()
.collect(),
..Default::default()
},
mac_commands: vec![lrwn::MACCommandSet::new(vec![
lrwn::MACCommand::LinkADRReq(lrwn::LinkADRReqPayload {
dr: 0,
tx_power: 0,
ch_mask: lrwn::ChMask::new([false; 16]),
redundancy: lrwn::Redundancy {
ch_mask_cntl: 0,
nb_rep: 0,
},
}),
])],
expected_mac_commands: vec![lrwn::MACCommandSet::new(vec![
lrwn::MACCommand::LinkADRReq(lrwn::LinkADRReqPayload {
dr: 0,
tx_power: 0,
ch_mask: lrwn::ChMask::new([false; 16]),
redundancy: lrwn::Redundancy {
ch_mask_cntl: 0,
nb_rep: 0,
},
}),
])],
},
// One LinkADRReq, exceeding error count.
Test {
device_session: internal::DeviceSession {
mac_command_error_count: [(lrwn::CID::LinkADRReq.byte() as u32, 2)]
.iter()
.cloned()
.collect(),
..Default::default()
},
mac_commands: vec![lrwn::MACCommandSet::new(vec![
lrwn::MACCommand::LinkADRReq(lrwn::LinkADRReqPayload {
dr: 0,
tx_power: 0,
ch_mask: lrwn::ChMask::new([false; 16]),
redundancy: lrwn::Redundancy {
ch_mask_cntl: 0,
nb_rep: 0,
},
}),
])],
expected_mac_commands: Vec::new(),
},
// NewChannelReq + LinkADRReq
Test {
device_session: Default::default(),
mac_commands: vec![
lrwn::MACCommandSet::new(vec![lrwn::MACCommand::NewChannelReq(
lrwn::NewChannelReqPayload {
ch_index: 3,
freq: 867100000,
min_dr: 0,
max_dr: 5,
},
)]),
lrwn::MACCommandSet::new(vec![lrwn::MACCommand::LinkADRReq(
lrwn::LinkADRReqPayload {
dr: 0,
tx_power: 0,
ch_mask: lrwn::ChMask::new([false; 16]),
redundancy: lrwn::Redundancy {
ch_mask_cntl: 0,
nb_rep: 0,
},
},
)]),
],
expected_mac_commands: vec![lrwn::MACCommandSet::new(vec![
lrwn::MACCommand::NewChannelReq(lrwn::NewChannelReqPayload {
ch_index: 3,
freq: 867100000,
min_dr: 0,
max_dr: 5,
}),
])],
},
// LinkADRReq + NewChannelReq (this order should never happen)
Test {
device_session: Default::default(),
mac_commands: vec![
lrwn::MACCommandSet::new(vec![lrwn::MACCommand::LinkADRReq(
lrwn::LinkADRReqPayload {
dr: 0,
tx_power: 0,
ch_mask: lrwn::ChMask::new([false; 16]),
redundancy: lrwn::Redundancy {
ch_mask_cntl: 0,
nb_rep: 0,
},
},
)]),
lrwn::MACCommandSet::new(vec![lrwn::MACCommand::NewChannelReq(
lrwn::NewChannelReqPayload {
ch_index: 3,
freq: 867100000,
min_dr: 0,
max_dr: 5,
},
)]),
],
expected_mac_commands: vec![lrwn::MACCommandSet::new(vec![
lrwn::MACCommand::LinkADRReq(lrwn::LinkADRReqPayload {
dr: 0,
tx_power: 0,
ch_mask: lrwn::ChMask::new([false; 16]),
redundancy: lrwn::Redundancy {
ch_mask_cntl: 0,
nb_rep: 0,
},
}),
])],
},
];
for test in &tests {
let out = filter_mac_commands(&test.device_session, &test.mac_commands);
assert_eq!(test.expected_mac_commands, out);
}
}
}

View File

@ -70,7 +70,7 @@ impl TxAck {
ctx.decode_phy_payload()?;
if ctx.is_error() {
if ctx.is_application_payload() {
if ctx.is_application_payload() || ctx.is_mac_only_downlink() {
ctx.get_device().await?;
ctx.get_device_profile().await?;
ctx.get_application().await?;
@ -262,7 +262,7 @@ impl TxAck {
let mut ds = self.device_session.as_mut().unwrap();
if ds.mac_version.to_string().starts_with("1.0") {
if ds.mac_version().to_string().starts_with("1.0") {
ds.n_f_cnt_down += 1;
} else {
ds.a_f_cnt_down += 1;
@ -415,6 +415,7 @@ impl TxAck {
"".to_string()
}
},
plaintext_mac_commands: false,
};
// Log for gateway (with potentially encrypted mac-commands).
@ -451,6 +452,7 @@ impl TxAck {
m_type: dfl.m_type,
dev_addr: dfl.dev_addr.clone(),
dev_eui: dfl.dev_eui.clone(),
plaintext_mac_commands: true,
};
// Log for device.

View File

@ -40,6 +40,7 @@ pub async fn log_uplink_for_gateways(ufl: &api::UplinkFrameLog) -> Result<()> {
dev_addr: ufl.dev_addr.clone(),
dev_eui: ufl.dev_eui.clone(),
time: ufl.time.clone(),
plaintext_mac_commands: ufl.plaintext_mac_commands,
};
let b = ufl_copy.encode_to_vec();
@ -268,71 +269,90 @@ pub async fn get_frame_logs(
for stream_id in &stream_key.ids {
last_id = stream_id.id.clone();
for (k, v) in &stream_id.map {
match k.as_ref() {
"up" => {
trace!(key = %k, id = %last_id, "Frame-log received from stream");
if let redis::Value::Data(b) = v {
let pl = api::UplinkFrameLog::decode(&mut Cursor::new(b))?;
let mut phy = lrwn::PhyPayload::from_slice(&pl.phy_payload)?;
phy.decode_f_opts_to_mac_commands()?;
let res = || -> Result<()> {
match k.as_ref() {
"up" => {
trace!(key = %k, id = %last_id, "Frame-log received from stream");
if let redis::Value::Data(b) = v {
let pl = api::UplinkFrameLog::decode(&mut Cursor::new(b))?;
let mut phy = lrwn::PhyPayload::from_slice(&pl.phy_payload)?;
if pl.plaintext_mac_commands {
phy.decode_f_opts_to_mac_commands()?;
}
let pl = api::LogItem {
id: stream_id.id.clone(),
time: pl.time.clone(),
description: pl.m_type().into(),
body: json!({
"phy_payload": phy,
"tx_info": pl.tx_info,
"rx_info": pl.rx_info,
})
.to_string(),
properties: [
("DevAddr".to_string(), pl.dev_addr),
("DevEUI".to_string(), pl.dev_eui),
]
.iter()
.cloned()
.collect(),
};
if channel.blocking_send(pl).is_err() {
return Err(anyhow!("Channel send error"));
let pl = api::LogItem {
id: stream_id.id.clone(),
time: pl.time.clone(),
description: pl.m_type().into(),
body: json!({
"phy_payload": phy,
"tx_info": pl.tx_info,
"rx_info": pl.rx_info,
})
.to_string(),
properties: [
("DevAddr".to_string(), pl.dev_addr),
("DevEUI".to_string(), pl.dev_eui),
]
.iter()
.cloned()
.collect(),
};
if let Err(e) = channel.blocking_send(pl) {
return Err(anyhow::Error::new(e));
}
}
}
}
"down" => {
trace!(key = %k, id = %last_id, "frame-log received from stream");
if let redis::Value::Data(b) = v {
let pl = api::DownlinkFrameLog::decode(&mut Cursor::new(b))?;
let mut phy = lrwn::PhyPayload::from_slice(&pl.phy_payload)?;
phy.decode_f_opts_to_mac_commands()?;
"down" => {
trace!(key = %k, id = %last_id, "frame-log received from stream");
if let redis::Value::Data(b) = v {
let pl = api::DownlinkFrameLog::decode(&mut Cursor::new(b))?;
let mut phy = lrwn::PhyPayload::from_slice(&pl.phy_payload)?;
if pl.plaintext_mac_commands {
phy.decode_f_opts_to_mac_commands()?;
}
let pl = api::LogItem {
id: stream_id.id.clone(),
time: pl.time.clone(),
description: pl.m_type().into(),
body: json!({
"phy_payload": phy,
"tx_info": pl.tx_info,
})
.to_string(),
properties: [
("DevAddr".to_string(), pl.dev_addr),
("DevEUI".to_string(), pl.dev_eui),
("Gateway ID".to_string(), pl.gateway_id),
]
.iter()
.cloned()
.collect(),
};
let pl = api::LogItem {
id: stream_id.id.clone(),
time: pl.time.clone(),
description: pl.m_type().into(),
body: json!({
"phy_payload": phy,
"tx_info": pl.tx_info,
})
.to_string(),
properties: [
("DevAddr".to_string(), pl.dev_addr),
("DevEUI".to_string(), pl.dev_eui),
("Gateway ID".to_string(), pl.gateway_id),
]
.iter()
.cloned()
.collect(),
};
if channel.blocking_send(pl).is_err() {
return Err(anyhow!("Channel send error"));
if let Err(e) = channel.blocking_send(pl) {
return Err(anyhow::Error::new(e));
}
}
}
_ => {
error!(key = %k, "Unexpected key in frame-log stream");
}
}
_ => {
error!(key = %k, "Unexpected key in frame-log stream");
Ok(())
}();
if let Err(e) = res {
// Return in case of channel error, in any other case we just log
// the error.
if e.downcast_ref::<mpsc::error::SendError<api::LogItem>>().is_some() {
return Err(e);
}
error!(key = %k, error = %e, "Parsing frame-log error");
}
}
}

View File

@ -1,7 +1,9 @@
use std::collections::hash_map::DefaultHasher;
use std::collections::HashMap;
use std::env::temp_dir;
use std::hash::Hasher;
use std::io::Cursor;
use std::sync::RwLock;
use std::time::Duration;
use anyhow::{Context, Result};
@ -55,6 +57,7 @@ lazy_static! {
);
counter
};
static ref GATEWAY_JSON: RwLock<HashMap<String, bool>> = RwLock::new(HashMap::new());
}
struct MqttContext {
@ -247,9 +250,14 @@ impl GatewayBackend for MqttBackend<'_> {
let topic = self.get_command_topic(&df.gateway_id, "down")?;
let mut df = df.clone();
df.v4_migrate();
let b = df.encode_to_vec();
info!(gateway_id = %df.gateway_id, topic = %topic, "Sending downlink frame");
let json = gateway_is_json(&df.gateway_id);
let b = match json {
true => serde_json::to_vec(&df)?,
false => df.encode_to_vec(),
};
info!(gateway_id = %df.gateway_id, topic = %topic, json = json, "Sending downlink frame");
let msg = mqtt::Message::new(topic, b, self.qos as i32);
self.client.publish(msg).await?;
trace!("Message sent");
@ -267,9 +275,13 @@ impl GatewayBackend for MqttBackend<'_> {
})
.inc();
let topic = self.get_command_topic(&gw_conf.gateway_id, "config")?;
let b = gw_conf.encode_to_vec();
let json = gateway_is_json(&gw_conf.gateway_id);
let b = match json {
true => serde_json::to_vec(&gw_conf)?,
false => gw_conf.encode_to_vec(),
};
info!(gateway_id = %gw_conf.gateway_id, topic = %topic, "Sending gateway configuration");
info!(gateway_id = %gw_conf.gateway_id, topic = %topic, json = json, "Sending gateway configuration");
let msg = mqtt::Message::new(topic, b, self.qos as i32);
self.client.publish(msg).await?;
trace!("Message sent");
@ -299,10 +311,13 @@ async fn message_callback(region_name: &str, region_common_name: CommonName, msg
return Ok(());
}
let json = payload_is_json(b);
info!(
region_name = region_name,
topic = topic,
qos = qos,
json = json,
"Message received from gateway"
);
@ -312,10 +327,14 @@ async fn message_callback(region_name: &str, region_common_name: CommonName, msg
event: "up".to_string(),
})
.inc();
let mut event = chirpstack_api::gw::UplinkFrame::decode(&mut Cursor::new(b))?;
let mut event = match json {
true => serde_json::from_slice(b)?,
false => chirpstack_api::gw::UplinkFrame::decode(&mut Cursor::new(b))?,
};
event.v4_migrate();
if let Some(rx_info) = &mut event.rx_info {
set_gateway_json(&rx_info.gateway_id, json);
rx_info.set_metadata_string("region_name", region_name);
rx_info.set_metadata_string("region_common_name", &region_common_name.to_string());
}
@ -327,7 +346,11 @@ async fn message_callback(region_name: &str, region_common_name: CommonName, msg
event: "stats".to_string(),
})
.inc();
let mut event = chirpstack_api::gw::GatewayStats::decode(&mut Cursor::new(b))?;
let mut event = match json {
true => serde_json::from_slice(b)?,
false => chirpstack_api::gw::GatewayStats::decode(&mut Cursor::new(b))?,
};
event.v4_migrate();
event
.meta_data
.insert("region_name".to_string(), region_name.to_string());
@ -335,6 +358,7 @@ async fn message_callback(region_name: &str, region_common_name: CommonName, msg
"region_common_name".to_string(),
region_common_name.to_string(),
);
set_gateway_json(&event.gateway_id, json);
tokio::spawn(uplink::stats::Stats::handle(event));
} else if topic.ends_with("/ack") {
EVENT_COUNTER
@ -342,8 +366,12 @@ async fn message_callback(region_name: &str, region_common_name: CommonName, msg
event: "ack".to_string(),
})
.inc();
let mut event = chirpstack_api::gw::DownlinkTxAck::decode(&mut Cursor::new(b))?;
let mut event = match json {
true => serde_json::from_slice(b)?,
false => chirpstack_api::gw::DownlinkTxAck::decode(&mut Cursor::new(b))?,
};
event.v4_migrate();
set_gateway_json(&event.gateway_id, json);
tokio::spawn(downlink::tx_ack::TxAck::handle(event));
} else {
return Err(anyhow!("Unknown event type"));
@ -381,3 +409,17 @@ async fn is_locked(key: String) -> Result<bool> {
})
.await?
}
fn gateway_is_json(gateway_id: &str) -> bool {
let gw_json_r = GATEWAY_JSON.read().unwrap();
gw_json_r.get(gateway_id).cloned().unwrap_or(false)
}
fn set_gateway_json(gateway_id: &str, is_json: bool) {
let mut gw_json_w = GATEWAY_JSON.write().unwrap();
gw_json_w.insert(gateway_id.to_string(), is_json);
}
fn payload_is_json(b: &[u8]) -> bool {
String::from_utf8_lossy(b).contains("gatewayId")
}

View File

@ -62,6 +62,10 @@ pub async fn setup() -> Result<()> {
.await
.context("Setup AMQP integration")?,
)),
"kafka" => integrations.push(Box::new(
kafka::Integration::new(&conf.integration.kafka)
.context("Setup Kafka integration")?,
)),
_ => {
return Err(anyhow!("Unexpected integration: {}", name));
}

View File

@ -4,7 +4,7 @@ use std::io::Cursor;
use anyhow::{Context, Result};
use prost::Message;
use tokio::task;
use tracing::{info, trace, warn};
use tracing::{error, info, trace};
use super::error::Error;
use super::{get_redis_conn, redis_key};
@ -324,16 +324,40 @@ async fn get_dev_euis_for_dev_addr(dev_addr: DevAddr) -> Result<Vec<EUI64>> {
.await?
}
async fn remove_dev_eui_from_dev_addr_set(dev_addr: DevAddr, dev_eui: EUI64) -> Result<()> {
task::spawn_blocking({
let dev_addr = dev_addr;
let dev_eui = dev_eui;
move || -> Result<()> {
let key = redis_key(format!("devaddr:{{{}}}", dev_addr));
let mut c = get_redis_conn()?;
redis::cmd("SREM")
.arg(key)
.arg(&dev_eui.to_be_bytes())
.query(&mut *c)?;
Ok(())
}
})
.await?
}
async fn get_for_dev_addr(dev_addr: DevAddr) -> Result<Vec<internal::DeviceSession>> {
trace!(dev_addr = %dev_addr, "Getting device-session for DevAddr");
let dev_euis = get_dev_euis_for_dev_addr(dev_addr).await?;
let mut out = Vec::new();
for dev_eui in &dev_euis {
let ds = match get(dev_eui).await {
for dev_eui in dev_euis {
let ds = match get(&dev_eui).await {
Ok(v) => v,
Err(e) => {
warn!(dev_addr = %dev_addr, dev_eui = %dev_eui, error = %e, "Get device-session for DevAddr error");
if let Error::NotFound(_) = e {
if let Err(e) = remove_dev_eui_from_dev_addr_set(dev_addr, dev_eui).await {
error!(dev_addr = %dev_addr, dev_eui = %dev_eui, error = %e, "Remove DevEUI from DevAddr->DevEUI set error");
}
} else {
error!(dev_addr = %dev_addr, dev_eui = %dev_eui, error = %e, "Get device-session for DevEUI error");
}
continue;
}
};
@ -667,4 +691,49 @@ pub mod test {
}
}
}
#[tokio::test]
async fn test_get_for_dev_addr() {
let _guard = test::prepare().await;
let dev_eui_1 = EUI64::from_be_bytes([1, 1, 1, 1, 1, 1, 1, 1]);
let dev_eui_2 = EUI64::from_be_bytes([2, 2, 2, 2, 2, 2, 2, 2]);
let dev_addr = DevAddr::from_be_bytes([1, 2, 3, 4]);
let ds_1 = internal::DeviceSession {
dev_addr: dev_addr.to_vec(),
dev_eui: dev_eui_1.to_vec(),
..Default::default()
};
let ds_2 = internal::DeviceSession {
dev_addr: dev_addr.to_vec(),
dev_eui: dev_eui_2.to_vec(),
..Default::default()
};
save(&ds_1).await.unwrap();
save(&ds_2).await.unwrap();
let dss = get_for_dev_addr(dev_addr).await.unwrap();
assert_eq!(2, dss.len());
let dev_euis = get_dev_euis_for_dev_addr(dev_addr).await.unwrap();
assert_eq!(2, dev_euis.len());
// At this point there is still a 'dangling' pointer from DevAddr->DevEUI.
delete(&dev_eui_2).await.unwrap();
let dev_euis = get_dev_euis_for_dev_addr(dev_addr).await.unwrap();
assert_eq!(2, dev_euis.len());
// This should only return one device-session.
let dss = get_for_dev_addr(dev_addr).await.unwrap();
assert_eq!(1, dss.len());
assert_eq!(dev_eui_1.to_vec(), dss[0].dev_eui);
// 'dangling' DevAddr->DevEUI pointers have been cleaned up.
let dev_euis = get_dev_euis_for_dev_addr(dev_addr).await.unwrap();
assert_eq!(1, dev_euis.len());
assert_eq!(dev_eui_1, dev_euis[0]);
}
}

View File

@ -429,6 +429,18 @@ pub mod test {
let t_get = get(&t.id).await.unwrap();
assert_eq!(t, t_get);
// add tenant user for filter by user_id test
let user = create_user().await;
let tu = TenantUser {
tenant_id: t.id,
user_id: user.id,
is_admin: true,
..Default::default()
};
add_user(tu).await.unwrap();
// get_count and list
let tests = vec![
FilterTest {
@ -481,6 +493,16 @@ pub mod test {
limit: 10,
offset: 10,
},
FilterTest {
filter: Filters {
user_id: Some(user.id),
search: None,
},
ts: vec![&t],
count: 1,
limit: 10,
offset: 0,
},
];
for tst in tests {
let count = get_count(&tst.filter).await.unwrap() as usize;

View File

@ -60,6 +60,12 @@ async fn test_fns_uplink() {
let mut rx_info = gw::UplinkRxInfo {
gateway_id: gw.gateway_id.to_string(),
time: Some(recv_time.into()),
location: Some(common::Location {
latitude: 0.0,
longitude: 0.0,
altitude: 0.0,
..Default::default()
}),
..Default::default()
};
rx_info.set_metadata_string("region_name", "eu868");

View File

@ -98,6 +98,7 @@ async fn test_gateway_filtering() {
let mut rx_info_a = gw::UplinkRxInfo {
gateway_id: gw_a.gateway_id.to_string(),
location: Some(Default::default()),
..Default::default()
};
rx_info_a.set_metadata_string("region_name", "eu868");
@ -105,6 +106,7 @@ async fn test_gateway_filtering() {
let mut rx_info_b = gw::UplinkRxInfo {
gateway_id: gw_b.gateway_id.to_string(),
location: Some(Default::default()),
..Default::default()
};
rx_info_b.set_metadata_string("region_name", "eu868");
@ -247,6 +249,7 @@ async fn test_lorawan_10_errors() {
let mut rx_info = gw::UplinkRxInfo {
gateway_id: gw.gateway_id.to_string(),
location: Some(Default::default()),
..Default::default()
};
rx_info.set_metadata_string("region_name", "eu868");
@ -426,6 +429,7 @@ async fn test_lorawan_11_errors() {
let mut rx_info = gw::UplinkRxInfo {
gateway_id: gw.gateway_id.to_string(),
location: Some(Default::default()),
..Default::default()
};
rx_info.set_metadata_string("region_name", "eu868");
@ -575,6 +579,7 @@ async fn test_lorawan_10_skip_f_cnt() {
let mut rx_info = gw::UplinkRxInfo {
gateway_id: gw.gateway_id.to_string(),
location: Some(Default::default()),
..Default::default()
};
rx_info.set_metadata_string("region_name", "eu868");
@ -763,6 +768,7 @@ async fn test_lorawan_10_device_disabled() {
let mut rx_info = gw::UplinkRxInfo {
gateway_id: gw.gateway_id.to_string(),
location: Some(Default::default()),
..Default::default()
};
rx_info.set_metadata_string("region_name", "eu868");
@ -881,6 +887,7 @@ async fn test_lorawan_10_uplink() {
let mut rx_info = gw::UplinkRxInfo {
gateway_id: gw.gateway_id.to_string(),
location: Some(Default::default()),
..Default::default()
};
rx_info.set_metadata_string("region_name", "eu868");
@ -1495,6 +1502,7 @@ async fn test_lorawan_11_uplink() {
let mut rx_info = gw::UplinkRxInfo {
gateway_id: gw.gateway_id.to_string(),
location: Some(Default::default()),
..Default::default()
};
rx_info.set_metadata_string("region_name", "eu868");
@ -1728,6 +1736,7 @@ async fn test_lorawan_10_rx_delay() {
let mut rx_info = gw::UplinkRxInfo {
gateway_id: gw.gateway_id.to_string(),
location: Some(Default::default()),
..Default::default()
};
rx_info.set_metadata_string("region_name", "eu868");
@ -1936,6 +1945,7 @@ async fn test_lorawan_10_mac_commands() {
let mut rx_info = gw::UplinkRxInfo {
gateway_id: gw.gateway_id.to_string(),
location: Some(Default::default()),
..Default::default()
};
rx_info.set_metadata_string("region_name", "eu868");
@ -2300,6 +2310,7 @@ async fn test_lorawan_11_mac_commands() {
let mut rx_info = gw::UplinkRxInfo {
gateway_id: gw.gateway_id.to_string(),
location: Some(Default::default()),
..Default::default()
};
rx_info.set_metadata_string("region_name", "eu868");
@ -2393,14 +2404,14 @@ async fn test_lorawan_11_mac_commands() {
..Default::default()
},
f_opts: lrwn::MACCommandSet::new(vec![lrwn::MACCommand::Raw(vec![
2, 20, 1,
85, 88, 242,
])]),
..Default::default()
},
f_port: None,
frm_payload: None,
}),
mic: Some([119, 74, 235, 162]),
mic: Some([124, 101, 247, 223]),
},
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
@ -2417,14 +2428,14 @@ async fn test_lorawan_11_mac_commands() {
..Default::default()
},
f_opts: lrwn::MACCommandSet::new(vec![lrwn::MACCommand::Raw(vec![
2, 20, 1,
85, 88, 242,
])]),
..Default::default()
},
f_port: None,
frm_payload: None,
}),
mic: Some([119, 74, 235, 162]),
mic: Some([124, 101, 247, 223]),
},
]),
],
@ -2489,6 +2500,7 @@ async fn test_lorawan_10_device_queue() {
let mut rx_info = gw::UplinkRxInfo {
gateway_id: gw.gateway_id.to_string(),
location: Some(Default::default()),
..Default::default()
};
rx_info.set_metadata_string("region_name", "eu868");
@ -2957,6 +2969,7 @@ async fn test_lorawan_11_device_queue() {
let mut rx_info = gw::UplinkRxInfo {
gateway_id: gw.gateway_id.to_string(),
location: Some(Default::default()),
..Default::default()
};
rx_info.set_metadata_string("region_name", "eu868");
@ -3329,14 +3342,14 @@ async fn test_lorawan_11_device_queue() {
..Default::default()
},
f_opts: lrwn::MACCommandSet::new(vec![
lrwn::MACCommand::Raw(vec![2,20,1]),
lrwn::MACCommand::Raw(vec![85, 88, 242]),
]),
..Default::default()
},
f_port: None,
frm_payload: None,
}),
mic: Some([183, 102, 104, 194]),
mic: Some([227, 104, 50, 163]),
},
lrwn::PhyPayload {
mhdr: lrwn::MHDR {
@ -3355,14 +3368,14 @@ async fn test_lorawan_11_device_queue() {
..Default::default()
},
f_opts: lrwn::MACCommandSet::new(vec![
lrwn::MACCommand::Raw(vec![2,20,1]),
lrwn::MACCommand::Raw(vec![85, 88, 242]),
]),
..Default::default()
},
f_port: None,
frm_payload: None,
}),
mic: Some([183, 102, 104, 194]),
mic: Some([227, 104, 50, 163]),
},
]),
],
@ -3429,6 +3442,7 @@ async fn test_lorawan_10_adr() {
let mut rx_info = gw::UplinkRxInfo {
gateway_id: gw.gateway_id.to_string(),
location: Some(Default::default()),
..Default::default()
};
rx_info.set_metadata_string("region_name", "eu868");
@ -4266,6 +4280,7 @@ async fn test_lorawan_10_device_status_request() {
let mut rx_info = gw::UplinkRxInfo {
gateway_id: gw.gateway_id.to_string(),
location: Some(Default::default()),
..Default::default()
};
rx_info.set_metadata_string("region_name", "eu868");
@ -4524,6 +4539,7 @@ async fn test_lorawan_11_receive_window_selection() {
let mut rx_info = gw::UplinkRxInfo {
gateway_id: gw.gateway_id.to_string(),
location: Some(Default::default()),
..Default::default()
};
rx_info.set_metadata_string("region_name", "eu868");

View File

@ -67,6 +67,7 @@ async fn test_fns() {
let mut rx_info = gw::UplinkRxInfo {
gateway_id: gw.gateway_id.to_string(),
time: Some(recv_time.into()),
location: Some(Default::default()),
..Default::default()
};
rx_info.set_metadata_string("region_name", "eu868");
@ -327,6 +328,7 @@ async fn test_sns() {
let mut rx_info = gw::UplinkRxInfo {
gateway_id: "0302030405060708".to_string(),
time: Some(recv_time.into()),
location: Some(Default::default()),
..Default::default()
};
rx_info.set_metadata_string("region_name", "eu868");

View File

@ -106,6 +106,7 @@ async fn test_gateway_filtering() {
let mut rx_info_a = gw::UplinkRxInfo {
gateway_id: gw_a.gateway_id.to_string(),
location: Some(Default::default()),
..Default::default()
};
rx_info_a.set_metadata_string("region_name", "eu868");
@ -113,6 +114,7 @@ async fn test_gateway_filtering() {
let mut rx_info_b = gw::UplinkRxInfo {
gateway_id: gw_b.gateway_id.to_string(),
location: Some(Default::default()),
..Default::default()
};
rx_info_b.set_metadata_string("region_name", "eu868");
@ -267,6 +269,7 @@ async fn test_lorawan_10() {
let mut rx_info = gw::UplinkRxInfo {
gateway_id: gw.gateway_id.to_string(),
location: Some(Default::default()),
..Default::default()
};
rx_info.set_metadata_string("region_name", "eu868");
@ -910,6 +913,7 @@ async fn test_lorawan_11() {
let mut rx_info = gw::UplinkRxInfo {
gateway_id: gw.gateway_id.to_string(),
location: Some(Default::default()),
..Default::default()
};
rx_info.set_metadata_string("region_name", "eu868");

View File

@ -442,6 +442,7 @@ impl Data {
trace!("Logging uplink frame-set");
let mut ufl: api::UplinkFrameLog = (&self.uplink_frame_set).try_into()?;
ufl.dev_eui = self.device.as_ref().unwrap().dev_eui.to_string();
ufl.plaintext_mac_commands = true;
framelog::log_uplink_for_device(&ufl).await?;
Ok(())
}

View File

@ -70,8 +70,21 @@ impl JoinRequest {
home_ns_req.base.transaction_id = 1234;
}
let async_receiver = match js_client.is_async() {
false => None,
true => Some(
get_async_receiver(
home_ns_req.base.transaction_id,
js_client.get_async_timeout(),
)
.await?,
),
};
trace!("Requesting home netid");
let home_ns_ans = js_client.home_ns_req(&mut home_ns_req, None).await?;
let home_ns_ans = js_client
.home_ns_req(&mut home_ns_req, async_receiver)
.await?;
self.home_net_id = Some(NetID::from_slice(&home_ns_ans.h_net_id)?);
Ok(())

View File

@ -13,7 +13,7 @@ use uuid::Uuid;
use crate::config;
use crate::framelog;
use crate::storage::{gateway, get_redis_conn, redis_key};
use crate::storage::{error::Error as StorageError, gateway, get_redis_conn, redis_key};
use chirpstack_api::{api, common, gw};
use lrwn::region::CommonName;
use lrwn::{MType, PhyPayload, EUI64};
@ -74,6 +74,7 @@ impl TryFrom<&UplinkFrameSet> for api::UplinkFrameLog {
_ => "".to_string(),
},
time: None, // is set below
plaintext_mac_commands: false,
};
for rx_info in &ufl.rx_info {
@ -303,11 +304,19 @@ pub async fn handle_uplink(deduplication_id: Uuid, uplink: gw::UplinkFrameSet) -
}
async fn update_gateway_metadata(ufs: &mut UplinkFrameSet) -> Result<()> {
let conf = config::get();
for rx_info in &mut ufs.rx_info_set {
let gw_id = EUI64::from_str(&rx_info.gateway_id)?;
let gw_meta = match gateway::get_meta(&gw_id).await {
Ok(v) => v,
Err(e) => {
if conf.gateway.allow_unknown_gateways {
if let StorageError::NotFound(_) = e {
ufs.gateway_private_map.insert(gw_id, false);
continue;
}
}
error!(
gateway_id = gw_id.to_string().as_str(),
error = format!("{}", e).as_str(),
@ -317,7 +326,6 @@ async fn update_gateway_metadata(ufs: &mut UplinkFrameSet) -> Result<()> {
}
};
let mut rx_info = rx_info.clone();
rx_info.location = Some(common::Location {
latitude: gw_meta.latitude,
longitude: gw_meta.longitude,

View File

@ -3,7 +3,7 @@ name = "lrwn"
description = "Library for encoding / decoding LoRaWAN frames."
homepage = "https://www.chirpstack.io"
license = "MIT"
version = "4.0.0-test.15"
version = "4.0.0-rc.4"
authors = ["Orne Brocaar <info@brocaar.com>"]
edition = "2018"
repository = "https://github.com/chirpstack/chirpstack"

View File

@ -72,5 +72,5 @@ pub fn get_tx_param_setup_eirp(i: u8) -> Result<f32> {
EIRP_INDEX
.get(i as usize)
.cloned()
.ok_or(anyhow!("Index does not exist"))
.ok_or_else(|| anyhow!("Index does not exist"))
}

View File

@ -1131,7 +1131,14 @@ impl NewChannelReqPayload {
freq: {
let mut freq_b: [u8; 4] = [0; 4];
freq_b[0..3].copy_from_slice(&b[1..4]);
u32::from_le_bytes(freq_b) * 100
let freq = u32::from_le_bytes(freq_b);
if freq >= 12000000 {
// 2.4GHz frequency
freq * 200
} else {
freq * 100
}
},
min_dr: b[4] & 0x0f,
max_dr: (b[4] & 0xf0) >> 4,
@ -1139,10 +1146,19 @@ impl NewChannelReqPayload {
}
pub fn to_bytes(&self) -> Result<[u8; Self::SIZE]> {
if self.freq / 100 >= (1 << 24) {
let mut freq = self.freq;
// Support LoRaWAN 2.4GHz, in which case the stepping is 200Hz:
// See Frequency Encoding in MAC Commands
// https://lora-developers.semtech.com/documentation/tech-papers-and-guides/physical-layer-proposal-2.4ghz/
if freq >= 2400000000 {
freq = freq / 2;
}
if freq / 100 >= (1 << 24) {
return Err(anyhow!("max freq value is 2^24 - 1"));
}
if self.freq % 100 != 0 {
if freq % 100 != 0 {
return Err(anyhow!("freq must be multiple of 100"));
}
if self.min_dr > 15 {
@ -1154,7 +1170,7 @@ impl NewChannelReqPayload {
let mut b: [u8; Self::SIZE] = [0; Self::SIZE];
b[0] = self.ch_index;
b[1..5].copy_from_slice(&(self.freq / 100).to_le_bytes());
b[1..5].copy_from_slice(&(freq / 100).to_le_bytes());
b[4] = self.min_dr | (self.max_dr << 4);
Ok(b)
@ -2005,6 +2021,18 @@ mod test {
)]),
bytes: vec![0x07, 0x03, 0x01, 0x02, 0x04, 0x5a],
},
MACTest {
uplink: false,
maccommand_set: MACCommandSet::new(vec![MACCommand::NewChannelReq(
NewChannelReqPayload {
ch_index: 3,
freq: 2410_000_000,
max_dr: 5,
min_dr: 0,
},
)]),
bytes: vec![7, 3, 80, 222, 183, 80],
},
MACTest {
uplink: true,
maccommand_set: MACCommandSet::new(vec![MACCommand::NewChannelAns(

View File

@ -7,7 +7,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
use crate::Error;
#[derive(PartialEq, Clone, Copy, Hash, Eq)]
#[derive(Default, PartialEq, Clone, Copy, Hash, Eq)]
pub struct NetID([u8; 3]);
impl NetID {
@ -76,12 +76,6 @@ impl NetID {
}
}
impl Default for NetID {
fn default() -> Self {
NetID([0, 0, 0])
}
}
impl fmt::Display for NetID {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", hex::encode(self.0))

View File

@ -1107,7 +1107,7 @@ impl Region for Configuration {
// use the ChMask of the first LinkADRReqPayload, besides
// turning off all 125 kHz this payload contains the ChMask
// for the last block of channels.
if c > 64 {
if c >= 64 {
out[0].ch_mask.set(c % 16, true);
continue;
}
@ -1419,11 +1419,11 @@ pub mod test {
expected_uplink_channels: c.get_uplink_channel_indices(),
expected_link_adr_req_payloads: vec![],
},
// Only activate 0 - 7.
// Only activate 0 - 7 + 64.
Test {
device_channels: c.get_uplink_channel_indices(),
enabled_channels: vec![0, 1, 2, 3, 4, 5, 6, 7],
expected_uplink_channels: vec![0, 1, 2, 3, 4, 5, 6, 7],
enabled_channels: vec![0, 1, 2, 3, 4, 5, 6, 7, 64],
expected_uplink_channels: vec![0, 1, 2, 3, 4, 5, 6, 7, 64],
expected_link_adr_req_payloads: vec![
LinkADRReqPayload {
dr: 0,
@ -1432,7 +1432,10 @@ pub mod test {
ch_mask_cntl: 7,
nb_rep: 0,
},
ch_mask: ChMask::new([false; 16]),
ch_mask: ChMask::new([
true, false, false, false, false, false, false, false, false, false,
false, false, false, false, false, false,
]),
},
LinkADRReqPayload {
dr: 0,
@ -1448,6 +1451,42 @@ pub mod test {
},
],
},
// Only activate 0 - 15 + 64 & 65.
Test {
device_channels: c.get_uplink_channel_indices(),
enabled_channels: vec![
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 64, 65,
],
expected_uplink_channels: vec![
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 64, 65,
],
expected_link_adr_req_payloads: vec![
LinkADRReqPayload {
dr: 0,
tx_power: 0,
redundancy: Redundancy {
ch_mask_cntl: 7,
nb_rep: 0,
},
ch_mask: ChMask::new([
true, true, false, false, false, false, false, false, false, false,
false, false, false, false, false, false,
]),
},
LinkADRReqPayload {
dr: 0,
tx_power: 0,
redundancy: Redundancy {
ch_mask_cntl: 0,
nb_rep: 0,
},
ch_mask: ChMask::new([
true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true,
]),
},
],
},
];
for tst in &tests {

View File

@ -228,12 +228,12 @@ impl FromStr for MacVersion {
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
Ok(match s {
"1.0.0" => MacVersion::LORAWAN_1_0_0,
"1.0.0" | "1.0" => MacVersion::LORAWAN_1_0_0,
"1.0.1" => MacVersion::LORAWAN_1_0_1,
"1.0.2" => MacVersion::LORAWAN_1_0_2,
"1.0.3" => MacVersion::LORAWAN_1_0_3,
"1.0.4" => MacVersion::LORAWAN_1_0_4,
"1.1.0" => MacVersion::LORAWAN_1_1_0,
"1.1.0" | "1.1" => MacVersion::LORAWAN_1_1_0,
_ => {
return Err(anyhow!("Unexpected MacVersion: {}", s));
}
@ -472,7 +472,7 @@ impl RegionBaseConfig {
Ok(self
.data_rates
.get(&dr)
.ok_or(anyhow!("Unknown data-rate index"))?
.ok_or_else(|| anyhow!("Unknown data-rate index"))?
.modulation
.clone())
}
@ -488,35 +488,38 @@ impl RegionBaseConfig {
None => self
.max_payload_size_per_dr
.get(&MacVersion::Latest)
.ok_or(anyhow!("Unknown mac-version"))?,
.ok_or_else(|| anyhow!("Unknown mac-version"))?,
};
let dr_map = match reg_params_map.get(&reg_params_revision) {
Some(v) => v,
None => reg_params_map
.get(&Revision::Latest)
.ok_or(anyhow!("Unknown revision"))?,
.ok_or_else(|| anyhow!("Unknown revision"))?,
};
Ok(dr_map.get(&dr).ok_or(anyhow!("Invalid data-rate"))?.clone())
Ok(dr_map
.get(&dr)
.ok_or_else(|| anyhow!("Invalid data-rate"))?
.clone())
}
fn get_rx1_data_rate_index(&self, uplink_dr: u8, rx1_dr_offset: usize) -> Result<u8> {
let offset_vec = self
.rx1_data_rate_table
.get(&uplink_dr)
.ok_or(anyhow!("Unknown data-rate"))?;
.ok_or_else(|| anyhow!("Unknown data-rate"))?;
Ok(*offset_vec
.get(rx1_dr_offset)
.ok_or(anyhow!("Invalid rx1 data-rate offset"))?)
.ok_or_else(|| anyhow!("Invalid rx1 data-rate offset"))?)
}
fn get_tx_power_offset(&self, tx_power: usize) -> Result<isize> {
Ok(*self
.tx_power_offsets
.get(tx_power)
.ok_or(anyhow!("Invalid tx-power"))?)
.ok_or_else(|| anyhow!("Invalid tx-power"))?)
}
fn add_channel(&mut self, frequency: u32, min_dr: u8, max_dr: u8) -> Result<()> {
@ -544,7 +547,7 @@ impl RegionBaseConfig {
Ok(self
.uplink_channels
.get(channel)
.ok_or(anyhow!("Invalid channel"))?
.ok_or_else(|| anyhow!("Invalid channel"))?
.clone())
}
@ -589,7 +592,7 @@ impl RegionBaseConfig {
Ok(self
.downlink_channels
.get(channel)
.ok_or(anyhow!("Invalid channel"))?
.ok_or_else(|| anyhow!("Invalid channel"))?
.clone())
}
@ -597,7 +600,7 @@ impl RegionBaseConfig {
let mut channel = self
.uplink_channels
.get_mut(channel)
.ok_or(anyhow!("Invalid channel"))?;
.ok_or_else(|| anyhow!("Invalid channel"))?;
channel.enabled = false;
Ok(())
}
@ -606,7 +609,7 @@ impl RegionBaseConfig {
let mut channel = self
.uplink_channels
.get_mut(channel)
.ok_or(anyhow!("Invalid channel"))?;
.ok_or_else(|| anyhow!("Invalid channel"))?;
channel.enabled = true;
Ok(())
}

View File

@ -797,7 +797,7 @@ impl Region for Configuration {
// use the ChMask of the first LinkADRReqPayload, besides
// turning off all 125 kHz this payload contains the ChMask
// for the last block of channels.
if c > 64 {
if c >= 64 {
out[0].ch_mask.set(c % 16, true);
continue;
}
@ -1111,11 +1111,11 @@ pub mod test {
expected_uplink_channels: c.get_uplink_channel_indices(),
expected_link_adr_req_payloads: vec![],
},
// Only activate 0 - 7.
// Only activate 0 - 7 + 64.
Test {
device_channels: c.get_uplink_channel_indices(),
enabled_channels: vec![0, 1, 2, 3, 4, 5, 6, 7],
expected_uplink_channels: vec![0, 1, 2, 3, 4, 5, 6, 7],
enabled_channels: vec![0, 1, 2, 3, 4, 5, 6, 7, 64],
expected_uplink_channels: vec![0, 1, 2, 3, 4, 5, 6, 7, 64],
expected_link_adr_req_payloads: vec![
LinkADRReqPayload {
dr: 0,
@ -1124,7 +1124,10 @@ pub mod test {
ch_mask_cntl: 7,
nb_rep: 0,
},
ch_mask: ChMask::new([false; 16]),
ch_mask: ChMask::new([
true, false, false, false, false, false, false, false, false, false,
false, false, false, false, false, false,
]),
},
LinkADRReqPayload {
dr: 0,
@ -1140,6 +1143,42 @@ pub mod test {
},
],
},
// Only activate 0 - 15 + 64 & 65.
Test {
device_channels: c.get_uplink_channel_indices(),
enabled_channels: vec![
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 64, 65,
],
expected_uplink_channels: vec![
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 64, 65,
],
expected_link_adr_req_payloads: vec![
LinkADRReqPayload {
dr: 0,
tx_power: 0,
redundancy: Redundancy {
ch_mask_cntl: 7,
nb_rep: 0,
},
ch_mask: ChMask::new([
true, true, false, false, false, false, false, false, false, false,
false, false, false, false, false, false,
]),
},
LinkADRReqPayload {
dr: 0,
tx_power: 0,
redundancy: Redundancy {
ch_mask_cntl: 0,
nb_rep: 0,
},
ch_mask: ChMask::new([
true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true,
]),
},
],
},
];
for tst in &tests {

View File

@ -1,6 +1,6 @@
{
"name": "chirpstack-ui",
"version": "4.0.0-test.15",
"version": "4.0.0-rc.4",
"private": true,
"dependencies": {
"@ant-design/colors": "^6.0.0",
@ -68,7 +68,7 @@
"not dead",
"not op_mini all"
],
"proxy": "http://127.0.0.1:8080/",
"proxy": "http://chirpstack:8080/",
"devDependencies": {
"husky": "^7.0.4",
"prettier": "^2.6.2"

View File

@ -469,6 +469,7 @@ class DeviceProfileForm extends Component<IProps, IState> {
<Select.Option value={Region.AS923_3}>AS923-3</Select.Option>
<Select.Option value={Region.AS923_4}>AS923-4</Select.Option>
<Select.Option value={Region.AU915}>AU915</Select.Option>
<Select.Option value={Region.CN470}>CN470</Select.Option>
<Select.Option value={Region.CN779}>CN779</Select.Option>
<Select.Option value={Region.EU433}>EU433</Select.Option>
<Select.Option value={Region.EU868}>EU868</Select.Option>

View File

@ -1,6 +1,6 @@
import React, { Component } from "react";
import { Form, Input, Row, Col, Button, Tabs } from "antd";
import { Form, Input, Row, Col, Button, Tabs, Switch } from "antd";
import { MinusCircleOutlined, PlusOutlined } from "@ant-design/icons";
import { Tenant } from "@chirpstack/chirpstack-api-grpc-web/api/tenant_pb";
@ -36,6 +36,8 @@ class DeviceForm extends Component<IProps> {
d.setDescription(v.description);
d.setDevEui(v.devEui);
d.setDeviceProfileId(v.deviceProfileId);
d.setIsDisabled(v.isDisabled);
d.setSkipFcntCheck(v.skipFcntCheck);
// tags
for (const elm of v.tagsMap) {
@ -108,6 +110,28 @@ class DeviceForm extends Component<IProps> {
getOptions={this.getDeviceProfileOptions}
required
/>
<Row gutter={24}>
<Col span={12}>
<Form.Item
label="Device is disabled"
name="isDisabled"
valuePropName="checked"
tooltip="Received uplink frames and join-requests will be ignored."
>
<Switch />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="Disable frame-counter validation"
name="skipFcntCheck"
valuePropName="checked"
tooltip="You must re-activate your device before this setting becomes effective. Note that disabling the frame-counter validation will compromise security as it allows replay-attacks."
>
<Switch />
</Form.Item>
</Col>
</Row>
</Tabs.TabPane>
<Tabs.TabPane tab="Tags" key="2">
<Form.List name="tagsMap">

View File

@ -1881,7 +1881,7 @@
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
"@chirpstack/chirpstack-api-grpc-web@file:../api/grpc-web":
version "4.0.0-test.9"
version "4.0.0-rc.3"
dependencies:
"@types/google-protobuf" "^3.15.2"
google-protobuf "^3.17.3"