Compare commits

...

39 Commits

Author SHA1 Message Date
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
edff985ad8 Bump version to 4.0.0-test.15 2022-08-01 10:20:57 +01:00
10d75a1744 Set MQTT persistence to TMP dir instead of CWD. 2022-07-31 13:11:55 +01:00
eee1c4b4b0 Show counter value as rate per aggregation interval. 2022-07-31 13:10:16 +01:00
3ab830f5a0 Change clean_session default + fix re-subscribe.
This changes the clean_session default to false, as only in case of a
persistent session, qos > 0 would be effective. If the client_id is not
set, then ChirpStack will generate a random client_id, which stays the
same during the lifetime of the chirpstack process.

This also implements a subscribe loop, as the client re-connect feature
does not re-subscribe. Even in case of a persistent session there is no
guarantee that the subscription is recovered, as it might have been a
MQTT broker restart. In case the broker stores the sessions in-memory,
the client would re-connect, but without subscriptions.

The (re)subscribe logic is placed outside the on-connected callback, as
the callback function must not block, thus can not wait for the
subscribe result. No the (re)subscribe happens async from the
on-connected.
2022-07-30 13:23:54 +01:00
f58e39e503 Bump version to 4.0.0-test.14 2022-07-28 09:02:54 +01:00
ffa8aa9518 Fix clippy warning. 2022-07-28 08:58:31 +01:00
a53a90b646 Make deduplication_delay configurable. Handle duplicated acks. 2022-07-27 20:19:02 +01:00
35b2f4112d Remove version fix for (lib)clang.
Clang is used by bindgen to generate the quickjs bindings at compile
time.
2022-07-27 12:00:11 +01:00
7a7d3dbd4e Add missing LoRa 2.4 gHz code-rates to enum. 2022-07-27 10:06:14 +01:00
73d581fc4c Update version. 2022-07-26 15:29:01 +01:00
3bfb7d577f Fix coding_rate string in test.
The CodeRate type (in Rust) will decode both "1/3" and "2/6" as
CodeRate::Cr26. To string, this type is always encoded to "2/6".
2022-07-25 10:29:46 +01:00
d10551bce1 Change command exec_id to uint32. 2022-07-22 20:29:07 +01:00
f7f2fa82f2 Update diesel_cli to 2.0.0-rc.1. 2022-07-22 14:44:14 +01:00
85cd5e0b80 Fix formatting after clippy fixes. 2022-07-22 13:06:52 +01:00
4612f84045 Update to diesel 2.0.0-rc.1. 2022-07-22 13:05:45 +01:00
b187efe84c Cleanup clippy warnings. 2022-07-22 13:00:30 +01:00
4d665d3ded Remove update, change apt to apt-get to avoid warnings. 2022-07-22 12:20:20 +01:00
c0a450c8f8 Change LR-FHSS code_rate to CodeRate type. 2022-07-22 12:19:36 +01:00
133 changed files with 2692 additions and 2327 deletions

52
Cargo.lock generated
View File

@ -635,7 +635,7 @@ dependencies = [
[[package]]
name = "backend"
version = "4.0.0-test.11"
version = "4.0.0-rc.2"
dependencies = [
"aes-kw",
"anyhow",
@ -879,7 +879,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chirpstack"
version = "4.0.0-test.11"
version = "4.0.0-rc.2"
dependencies = [
"aes 0.7.5",
"anyhow",
@ -958,7 +958,7 @@ dependencies = [
[[package]]
name = "chirpstack_api"
version = "4.0.0-test.11"
version = "4.0.0-rc.2"
dependencies = [
"hex",
"pbjson",
@ -1068,9 +1068,9 @@ dependencies = [
[[package]]
name = "cmake"
version = "0.1.48"
version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8ad8cef104ac57b68b89df3208164d228503abbdce70f6880ffa3d970e7443a"
checksum = "eb6210b637171dfba4cda12e579ac6dc73f5165ad56133e5d72ef3131f320855"
dependencies = [
"cc",
]
@ -1131,6 +1131,16 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "338089f42c427b86394a5ee60ff321da23a5c89c9d89514c829687b26359fcff"
[[package]]
name = "crossbeam-channel"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.10"
@ -1238,9 +1248,9 @@ dependencies = [
[[package]]
name = "diesel"
version = "2.0.0-rc.0"
version = "2.0.0-rc.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e531d0abf8147036383c88ce3785d9cda6fe1b8b1183021ffa01cf49c5819d24"
checksum = "876a12f2d98c35d1dfaf74083664be5bb71606b72f4756f3792cdb1ddb192b46"
dependencies = [
"bigdecimal",
"bitflags",
@ -1259,9 +1269,9 @@ dependencies = [
[[package]]
name = "diesel_derives"
version = "2.0.0-rc.0"
version = "2.0.0-rc.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "212ba0cdc611523c37f26c7b3b4aedb4af7cbfe9239c4e7736a8a7c82284d77b"
checksum = "2497d9cefebedc40492310f3c94493e1d0bd5b11b5e1bfc0a7f4b106012203ea"
dependencies = [
"proc-macro-error",
"proc-macro2",
@ -1271,9 +1281,9 @@ dependencies = [
[[package]]
name = "diesel_migrations"
version = "2.0.0-rc.0"
version = "2.0.0-rc.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2edcb7e9cff76af48e7fa33cc4680acc7df19e58a4a4aaed3e2b67fb83bc06d"
checksum = "af3e284b00439e362c3f55849a103f38b4c5a9918ae3cf34fca2268b6eb52fef"
dependencies = [
"diesel",
"migrations_internals",
@ -2212,7 +2222,7 @@ dependencies = [
[[package]]
name = "lrwn"
version = "4.0.0-test.11"
version = "4.0.0-rc.2"
dependencies = [
"aes 0.7.5",
"anyhow",
@ -2259,9 +2269,9 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "migrations_internals"
version = "2.0.0-rc.0"
version = "2.0.0-rc.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61e2226081f9176165a49b006a0729de8cafa749615b349e15c444dbd39e4d9d"
checksum = "e03913f1a1c044aa53b37c8f34011599bbf98914092a0444081555e9ca35022c"
dependencies = [
"serde",
"toml",
@ -2269,9 +2279,9 @@ dependencies = [
[[package]]
name = "migrations_macros"
version = "2.0.0-rc.0"
version = "2.0.0-rc.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37dbadac6f186c134552cd9a0ec14b157cf4f04eacacebd5e6c1bfc6aeb158b3"
checksum = "9ccfa634200e9de9fe6497f568d54951e933e9e0ddf61058e52e24bda896de48"
dependencies = [
"migrations_internals",
"proc-macro2",
@ -2600,10 +2610,12 @@ dependencies = [
[[package]]
name = "paho-mqtt"
version = "0.9.1"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d82fea0990fe54e75d575bbd9bc2ee5919fd10cc0b4a95f1967528083129fc4b"
checksum = "9fac58bae33ba9679bb4908ffa7c3950114345860d3f9b98340c4943f18ff324"
dependencies = [
"async-channel",
"crossbeam-channel",
"futures",
"futures-timer",
"libc",
@ -2614,9 +2626,9 @@ dependencies = [
[[package]]
name = "paho-mqtt-sys"
version = "0.5.0"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ad9ac6a77a7e7c70cd51262b94ab666c9e4c38fb0f4201dba8d7f8589aa8ce4"
checksum = "10e6244f27644eed5709e318a3ad7f785906fbb6030f0a9b9ba50923b456c0c5"
dependencies = [
"cmake",
"openssl-sys",

View File

@ -30,7 +30,7 @@ RUN apt-get update && \
git \
libpq-dev \
clang \
libclang-3.9-dev \
libclang-dev \
jq \
gcc-arm-linux-gnueabihf \
g++-arm-linux-gnueabihf \

View File

@ -19,7 +19,7 @@ RUN apt-get update && \
redis-tools \
rpm \
clang \
libclang-3.9-dev \
libclang-dev \
golang-cfssl \
jq \
gcc-arm-linux-gnueabihf \
@ -33,8 +33,9 @@ RUN rustup component add rustfmt clippy
RUN rustup target add armv7-unknown-linux-gnueabihf
RUN rustup target add aarch64-unknown-linux-gnu
RUN cargo install diesel_cli --version 2.0.0-rc.0 --no-default-features --features postgres
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

@ -15,6 +15,11 @@ version:
sed -i 's/"version.*/"version": "$(VERSION)",/g' ./api/js/package.json
sed -i 's/version.*/version = "$(VERSION)",/g' ./api/python/src/setup.py
sed -i 's/^version.*/version = "$(VERSION)"/g' ./api/rust/Cargo.toml
make test
git add .
git commit -v -m "Bump version to $(VERSION)"
git tag -a v$(VERSION) -m "v$(VERSION)"
git tag -a api/go/v$(VERSION) -m "api/go/v$(VERSION)"
api: version
cd api && make

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 (

View File

@ -477,6 +477,58 @@ func (Aggregation) EnumDescriptor() ([]byte, []int) {
return file_common_common_proto_rawDescGZIP(), []int{6}
}
type MetricKind int32
const (
// Incrementing counters that never decrease (these are not reset on each reading).
MetricKind_COUNTER MetricKind = 0
// Counters that do get reset upon reading.
MetricKind_ABSOLUTE MetricKind = 1
// E.g. a temperature value.
MetricKind_GAUGE MetricKind = 2
)
// Enum value maps for MetricKind.
var (
MetricKind_name = map[int32]string{
0: "COUNTER",
1: "ABSOLUTE",
2: "GAUGE",
}
MetricKind_value = map[string]int32{
"COUNTER": 0,
"ABSOLUTE": 1,
"GAUGE": 2,
}
)
func (x MetricKind) Enum() *MetricKind {
p := new(MetricKind)
*p = x
return p
}
func (x MetricKind) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (MetricKind) Descriptor() protoreflect.EnumDescriptor {
return file_common_common_proto_enumTypes[7].Descriptor()
}
func (MetricKind) Type() protoreflect.EnumType {
return &file_common_common_proto_enumTypes[7]
}
func (x MetricKind) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Use MetricKind.Descriptor instead.
func (MetricKind) EnumDescriptor() ([]byte, []int) {
return file_common_common_proto_rawDescGZIP(), []int{7}
}
type Location struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@ -629,6 +681,8 @@ type Metric struct {
Timestamps []*timestamppb.Timestamp `protobuf:"bytes,2,rep,name=timestamps,proto3" json:"timestamps,omitempty"`
// Datasets.
Datasets []*MetricDataset `protobuf:"bytes,3,rep,name=datasets,proto3" json:"datasets,omitempty"`
// Kind.
Kind MetricKind `protobuf:"varint,4,opt,name=kind,proto3,enum=common.MetricKind" json:"kind,omitempty"`
}
func (x *Metric) Reset() {
@ -684,6 +738,13 @@ func (x *Metric) GetDatasets() []*MetricDataset {
return nil
}
func (x *Metric) GetKind() MetricKind {
if x != nil {
return x.Kind
}
return MetricKind_COUNTER
}
type MetricDataset struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@ -764,7 +825,7 @@ var file_common_common_proto_rawDesc = []byte{
0x6b, 0x65, 0x6b, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x08, 0x6b, 0x65, 0x6b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x17, 0x0a, 0x07, 0x61, 0x65, 0x73,
0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x61, 0x65, 0x73, 0x4b,
0x65, 0x79, 0x22, 0x8b, 0x01, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x12, 0x0a,
0x65, 0x79, 0x22, 0xb3, 0x01, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x12, 0x0a,
0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d,
0x65, 0x12, 0x3a, 0x0a, 0x0a, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x73, 0x18,
0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
@ -773,67 +834,73 @@ var file_common_common_proto_rawDesc = []byte{
0x08, 0x64, 0x61, 0x74, 0x61, 0x73, 0x65, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32,
0x15, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44,
0x61, 0x74, 0x61, 0x73, 0x65, 0x74, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x73, 0x65, 0x74, 0x73,
0x22, 0x39, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x61, 0x74, 0x61, 0x73, 0x65,
0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18,
0x02, 0x20, 0x03, 0x28, 0x02, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x2a, 0x2c, 0x0a, 0x0a, 0x4d,
0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x4f, 0x52,
0x41, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x46, 0x53, 0x4b, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07,
0x4c, 0x52, 0x5f, 0x46, 0x48, 0x53, 0x53, 0x10, 0x02, 0x2a, 0xaa, 0x01, 0x0a, 0x06, 0x52, 0x65,
0x67, 0x69, 0x6f, 0x6e, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x55, 0x38, 0x36, 0x38, 0x10, 0x00, 0x12,
0x09, 0x0a, 0x05, 0x55, 0x53, 0x39, 0x31, 0x35, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x43, 0x4e,
0x37, 0x37, 0x39, 0x10, 0x03, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x55, 0x34, 0x33, 0x33, 0x10, 0x04,
0x12, 0x09, 0x0a, 0x05, 0x41, 0x55, 0x39, 0x31, 0x35, 0x10, 0x05, 0x12, 0x09, 0x0a, 0x05, 0x43,
0x4e, 0x34, 0x37, 0x30, 0x10, 0x06, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x53, 0x39, 0x32, 0x33, 0x10,
0x07, 0x12, 0x0b, 0x0a, 0x07, 0x41, 0x53, 0x39, 0x32, 0x33, 0x5f, 0x32, 0x10, 0x0c, 0x12, 0x0b,
0x0a, 0x07, 0x41, 0x53, 0x39, 0x32, 0x33, 0x5f, 0x33, 0x10, 0x0d, 0x12, 0x0b, 0x0a, 0x07, 0x41,
0x53, 0x39, 0x32, 0x33, 0x5f, 0x34, 0x10, 0x0e, 0x12, 0x09, 0x0a, 0x05, 0x4b, 0x52, 0x39, 0x32,
0x30, 0x10, 0x08, 0x12, 0x09, 0x0a, 0x05, 0x49, 0x4e, 0x38, 0x36, 0x35, 0x10, 0x09, 0x12, 0x09,
0x0a, 0x05, 0x52, 0x55, 0x38, 0x36, 0x34, 0x10, 0x0a, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x53, 0x4d,
0x32, 0x34, 0x30, 0x30, 0x10, 0x0b, 0x2a, 0xb3, 0x01, 0x0a, 0x05, 0x4d, 0x54, 0x79, 0x70, 0x65,
0x12, 0x10, 0x0a, 0x0c, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54,
0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x50,
0x54, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x55, 0x4e, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x52, 0x4d,
0x45, 0x44, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x55, 0x50, 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15,
0x55, 0x4e, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x52, 0x4d, 0x45, 0x44, 0x5f, 0x44, 0x41, 0x54, 0x41,
0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x03, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x4f, 0x4e, 0x46, 0x49,
0x52, 0x4d, 0x45, 0x44, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x55, 0x50, 0x10, 0x04, 0x12, 0x17,
0x0a, 0x13, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x52, 0x4d, 0x45, 0x44, 0x5f, 0x44, 0x41, 0x54, 0x41,
0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x05, 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x45, 0x4a, 0x4f, 0x49,
0x4e, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x10, 0x06, 0x12, 0x0f, 0x0a, 0x0b, 0x50,
0x52, 0x4f, 0x50, 0x52, 0x49, 0x45, 0x54, 0x41, 0x52, 0x59, 0x10, 0x07, 0x2a, 0x7e, 0x0a, 0x0a,
0x4d, 0x61, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x11, 0x0a, 0x0d, 0x4c, 0x4f,
0x52, 0x41, 0x57, 0x41, 0x4e, 0x5f, 0x31, 0x5f, 0x30, 0x5f, 0x30, 0x10, 0x00, 0x12, 0x11, 0x0a,
0x0d, 0x4c, 0x4f, 0x52, 0x41, 0x57, 0x41, 0x4e, 0x5f, 0x31, 0x5f, 0x30, 0x5f, 0x31, 0x10, 0x01,
0x12, 0x11, 0x0a, 0x0d, 0x4c, 0x4f, 0x52, 0x41, 0x57, 0x41, 0x4e, 0x5f, 0x31, 0x5f, 0x30, 0x5f,
0x32, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x4c, 0x4f, 0x52, 0x41, 0x57, 0x41, 0x4e, 0x5f, 0x31,
0x5f, 0x30, 0x5f, 0x33, 0x10, 0x03, 0x12, 0x11, 0x0a, 0x0d, 0x4c, 0x4f, 0x52, 0x41, 0x57, 0x41,
0x4e, 0x5f, 0x31, 0x5f, 0x30, 0x5f, 0x34, 0x10, 0x04, 0x12, 0x11, 0x0a, 0x0d, 0x4c, 0x4f, 0x52,
0x41, 0x57, 0x41, 0x4e, 0x5f, 0x31, 0x5f, 0x31, 0x5f, 0x30, 0x10, 0x05, 0x2a, 0x65, 0x0a, 0x11,
0x52, 0x65, 0x67, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f,
0x6e, 0x12, 0x05, 0x0a, 0x01, 0x41, 0x10, 0x00, 0x12, 0x05, 0x0a, 0x01, 0x42, 0x10, 0x01, 0x12,
0x0f, 0x0a, 0x0b, 0x52, 0x50, 0x30, 0x30, 0x32, 0x5f, 0x31, 0x5f, 0x30, 0x5f, 0x30, 0x10, 0x02,
0x12, 0x0f, 0x0a, 0x0b, 0x52, 0x50, 0x30, 0x30, 0x32, 0x5f, 0x31, 0x5f, 0x30, 0x5f, 0x31, 0x10,
0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x52, 0x50, 0x30, 0x30, 0x32, 0x5f, 0x31, 0x5f, 0x30, 0x5f, 0x32,
0x10, 0x04, 0x12, 0x0f, 0x0a, 0x0b, 0x52, 0x50, 0x30, 0x30, 0x32, 0x5f, 0x31, 0x5f, 0x30, 0x5f,
0x33, 0x10, 0x05, 0x2a, 0x8e, 0x01, 0x0a, 0x0e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57,
0x4e, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x47, 0x50, 0x53, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06,
0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, 0x47, 0x45, 0x4f, 0x5f,
0x52, 0x45, 0x53, 0x4f, 0x4c, 0x56, 0x45, 0x52, 0x5f, 0x54, 0x44, 0x4f, 0x41, 0x10, 0x03, 0x12,
0x15, 0x0a, 0x11, 0x47, 0x45, 0x4f, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x4c, 0x56, 0x45, 0x52, 0x5f,
0x52, 0x53, 0x53, 0x49, 0x10, 0x04, 0x12, 0x15, 0x0a, 0x11, 0x47, 0x45, 0x4f, 0x5f, 0x52, 0x45,
0x53, 0x4f, 0x4c, 0x56, 0x45, 0x52, 0x5f, 0x47, 0x4e, 0x53, 0x53, 0x10, 0x05, 0x12, 0x15, 0x0a,
0x11, 0x47, 0x45, 0x4f, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x4c, 0x56, 0x45, 0x52, 0x5f, 0x57, 0x49,
0x46, 0x49, 0x10, 0x06, 0x2a, 0x2b, 0x0a, 0x0b, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x4f, 0x55, 0x52, 0x10, 0x00, 0x12, 0x07, 0x0a,
0x03, 0x44, 0x41, 0x59, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x4d, 0x4f, 0x4e, 0x54, 0x48, 0x10,
0x02, 0x42, 0x55, 0x0a, 0x11, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61,
0x63, 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x50, 0x72,
0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x63, 0x68, 0x69,
0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x76,
0x34, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x12, 0x26, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12,
0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x4b, 0x69,
0x6e, 0x64, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x22, 0x39, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x72,
0x69, 0x63, 0x44, 0x61, 0x74, 0x61, 0x73, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62,
0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12,
0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x03, 0x28, 0x02, 0x52, 0x04, 0x64,
0x61, 0x74, 0x61, 0x2a, 0x2c, 0x0a, 0x0a, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x4f, 0x52, 0x41, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x46,
0x53, 0x4b, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x4c, 0x52, 0x5f, 0x46, 0x48, 0x53, 0x53, 0x10,
0x02, 0x2a, 0xaa, 0x01, 0x0a, 0x06, 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x09, 0x0a, 0x05,
0x45, 0x55, 0x38, 0x36, 0x38, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x55, 0x53, 0x39, 0x31, 0x35,
0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x43, 0x4e, 0x37, 0x37, 0x39, 0x10, 0x03, 0x12, 0x09, 0x0a,
0x05, 0x45, 0x55, 0x34, 0x33, 0x33, 0x10, 0x04, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x55, 0x39, 0x31,
0x35, 0x10, 0x05, 0x12, 0x09, 0x0a, 0x05, 0x43, 0x4e, 0x34, 0x37, 0x30, 0x10, 0x06, 0x12, 0x09,
0x0a, 0x05, 0x41, 0x53, 0x39, 0x32, 0x33, 0x10, 0x07, 0x12, 0x0b, 0x0a, 0x07, 0x41, 0x53, 0x39,
0x32, 0x33, 0x5f, 0x32, 0x10, 0x0c, 0x12, 0x0b, 0x0a, 0x07, 0x41, 0x53, 0x39, 0x32, 0x33, 0x5f,
0x33, 0x10, 0x0d, 0x12, 0x0b, 0x0a, 0x07, 0x41, 0x53, 0x39, 0x32, 0x33, 0x5f, 0x34, 0x10, 0x0e,
0x12, 0x09, 0x0a, 0x05, 0x4b, 0x52, 0x39, 0x32, 0x30, 0x10, 0x08, 0x12, 0x09, 0x0a, 0x05, 0x49,
0x4e, 0x38, 0x36, 0x35, 0x10, 0x09, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x55, 0x38, 0x36, 0x34, 0x10,
0x0a, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x53, 0x4d, 0x32, 0x34, 0x30, 0x30, 0x10, 0x0b, 0x2a, 0xb3,
0x01, 0x0a, 0x05, 0x4d, 0x54, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x0c, 0x4a, 0x4f, 0x49, 0x4e,
0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x4a, 0x4f,
0x49, 0x4e, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x55,
0x4e, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x52, 0x4d, 0x45, 0x44, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f,
0x55, 0x50, 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15, 0x55, 0x4e, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x52,
0x4d, 0x45, 0x44, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x03, 0x12,
0x15, 0x0a, 0x11, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x52, 0x4d, 0x45, 0x44, 0x5f, 0x44, 0x41, 0x54,
0x41, 0x5f, 0x55, 0x50, 0x10, 0x04, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x52,
0x4d, 0x45, 0x44, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x05, 0x12,
0x12, 0x0a, 0x0e, 0x52, 0x45, 0x4a, 0x4f, 0x49, 0x4e, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53,
0x54, 0x10, 0x06, 0x12, 0x0f, 0x0a, 0x0b, 0x50, 0x52, 0x4f, 0x50, 0x52, 0x49, 0x45, 0x54, 0x41,
0x52, 0x59, 0x10, 0x07, 0x2a, 0x7e, 0x0a, 0x0a, 0x4d, 0x61, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69,
0x6f, 0x6e, 0x12, 0x11, 0x0a, 0x0d, 0x4c, 0x4f, 0x52, 0x41, 0x57, 0x41, 0x4e, 0x5f, 0x31, 0x5f,
0x30, 0x5f, 0x30, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x4c, 0x4f, 0x52, 0x41, 0x57, 0x41, 0x4e,
0x5f, 0x31, 0x5f, 0x30, 0x5f, 0x31, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x4c, 0x4f, 0x52, 0x41,
0x57, 0x41, 0x4e, 0x5f, 0x31, 0x5f, 0x30, 0x5f, 0x32, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x4c,
0x4f, 0x52, 0x41, 0x57, 0x41, 0x4e, 0x5f, 0x31, 0x5f, 0x30, 0x5f, 0x33, 0x10, 0x03, 0x12, 0x11,
0x0a, 0x0d, 0x4c, 0x4f, 0x52, 0x41, 0x57, 0x41, 0x4e, 0x5f, 0x31, 0x5f, 0x30, 0x5f, 0x34, 0x10,
0x04, 0x12, 0x11, 0x0a, 0x0d, 0x4c, 0x4f, 0x52, 0x41, 0x57, 0x41, 0x4e, 0x5f, 0x31, 0x5f, 0x31,
0x5f, 0x30, 0x10, 0x05, 0x2a, 0x65, 0x0a, 0x11, 0x52, 0x65, 0x67, 0x50, 0x61, 0x72, 0x61, 0x6d,
0x73, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x05, 0x0a, 0x01, 0x41, 0x10, 0x00,
0x12, 0x05, 0x0a, 0x01, 0x42, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x52, 0x50, 0x30, 0x30, 0x32,
0x5f, 0x31, 0x5f, 0x30, 0x5f, 0x30, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x52, 0x50, 0x30, 0x30,
0x32, 0x5f, 0x31, 0x5f, 0x30, 0x5f, 0x31, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x52, 0x50, 0x30,
0x30, 0x32, 0x5f, 0x31, 0x5f, 0x30, 0x5f, 0x32, 0x10, 0x04, 0x12, 0x0f, 0x0a, 0x0b, 0x52, 0x50,
0x30, 0x30, 0x32, 0x5f, 0x31, 0x5f, 0x30, 0x5f, 0x33, 0x10, 0x05, 0x2a, 0x8e, 0x01, 0x0a, 0x0e,
0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x0b,
0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x47,
0x50, 0x53, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x10, 0x02,
0x12, 0x15, 0x0a, 0x11, 0x47, 0x45, 0x4f, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x4c, 0x56, 0x45, 0x52,
0x5f, 0x54, 0x44, 0x4f, 0x41, 0x10, 0x03, 0x12, 0x15, 0x0a, 0x11, 0x47, 0x45, 0x4f, 0x5f, 0x52,
0x45, 0x53, 0x4f, 0x4c, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x53, 0x53, 0x49, 0x10, 0x04, 0x12, 0x15,
0x0a, 0x11, 0x47, 0x45, 0x4f, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x4c, 0x56, 0x45, 0x52, 0x5f, 0x47,
0x4e, 0x53, 0x53, 0x10, 0x05, 0x12, 0x15, 0x0a, 0x11, 0x47, 0x45, 0x4f, 0x5f, 0x52, 0x45, 0x53,
0x4f, 0x4c, 0x56, 0x45, 0x52, 0x5f, 0x57, 0x49, 0x46, 0x49, 0x10, 0x06, 0x2a, 0x2b, 0x0a, 0x0b,
0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x08, 0x0a, 0x04, 0x48,
0x4f, 0x55, 0x52, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x44, 0x41, 0x59, 0x10, 0x01, 0x12, 0x09,
0x0a, 0x05, 0x4d, 0x4f, 0x4e, 0x54, 0x48, 0x10, 0x02, 0x2a, 0x32, 0x0a, 0x0a, 0x4d, 0x65, 0x74,
0x72, 0x69, 0x63, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4f, 0x55, 0x4e, 0x54,
0x45, 0x52, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x41, 0x42, 0x53, 0x4f, 0x4c, 0x55, 0x54, 0x45,
0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x47, 0x41, 0x55, 0x47, 0x45, 0x10, 0x02, 0x42, 0x55, 0x0a,
0x11, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61,
0x70, 0x69, 0x42, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50,
0x01, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68,
0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74,
0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x63, 0x6f,
0x6d, 0x6d, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@ -848,7 +915,7 @@ func file_common_common_proto_rawDescGZIP() []byte {
return file_common_common_proto_rawDescData
}
var file_common_common_proto_enumTypes = make([]protoimpl.EnumInfo, 7)
var file_common_common_proto_enumTypes = make([]protoimpl.EnumInfo, 8)
var file_common_common_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
var file_common_common_proto_goTypes = []interface{}{
(Modulation)(0), // 0: common.Modulation
@ -858,21 +925,23 @@ var file_common_common_proto_goTypes = []interface{}{
(RegParamsRevision)(0), // 4: common.RegParamsRevision
(LocationSource)(0), // 5: common.LocationSource
(Aggregation)(0), // 6: common.Aggregation
(*Location)(nil), // 7: common.Location
(*KeyEnvelope)(nil), // 8: common.KeyEnvelope
(*Metric)(nil), // 9: common.Metric
(*MetricDataset)(nil), // 10: common.MetricDataset
(*timestamppb.Timestamp)(nil), // 11: google.protobuf.Timestamp
(MetricKind)(0), // 7: common.MetricKind
(*Location)(nil), // 8: common.Location
(*KeyEnvelope)(nil), // 9: common.KeyEnvelope
(*Metric)(nil), // 10: common.Metric
(*MetricDataset)(nil), // 11: common.MetricDataset
(*timestamppb.Timestamp)(nil), // 12: google.protobuf.Timestamp
}
var file_common_common_proto_depIdxs = []int32{
5, // 0: common.Location.source:type_name -> common.LocationSource
11, // 1: common.Metric.timestamps:type_name -> google.protobuf.Timestamp
10, // 2: common.Metric.datasets:type_name -> common.MetricDataset
3, // [3:3] is the sub-list for method output_type
3, // [3:3] is the sub-list for method input_type
3, // [3:3] is the sub-list for extension type_name
3, // [3:3] is the sub-list for extension extendee
0, // [0:3] is the sub-list for field type_name
12, // 1: common.Metric.timestamps:type_name -> google.protobuf.Timestamp
11, // 2: common.Metric.datasets:type_name -> common.MetricDataset
7, // 3: common.Metric.kind:type_name -> common.MetricKind
4, // [4:4] is the sub-list for method output_type
4, // [4:4] is the sub-list for method input_type
4, // [4:4] is the sub-list for extension type_name
4, // [4:4] is the sub-list for extension extendee
0, // [0:4] is the sub-list for field type_name
}
func init() { file_common_common_proto_init() }
@ -935,7 +1004,7 @@ func file_common_common_proto_init() {
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_common_common_proto_rawDesc,
NumEnums: 7,
NumEnums: 8,
NumMessages: 4,
NumExtensions: 0,
NumServices: 0,

1175
api/go/gw/gw.pb.go vendored

File diff suppressed because it is too large Load Diff

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

@ -75,6 +75,9 @@ export class Metric extends jspb.Message {
clearDatasetsList(): Metric;
addDatasets(value?: MetricDataset, index?: number): MetricDataset;
getKind(): MetricKind;
setKind(value: MetricKind): Metric;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): Metric.AsObject;
static toObject(includeInstance: boolean, msg: Metric): Metric.AsObject;
@ -88,6 +91,7 @@ export namespace Metric {
name: string,
timestampsList: Array<google_protobuf_timestamp_pb.Timestamp.AsObject>,
datasetsList: Array<MetricDataset.AsObject>,
kind: MetricKind,
}
}
@ -176,3 +180,8 @@ export enum Aggregation {
DAY = 1,
MONTH = 2,
}
export enum MetricKind {
COUNTER = 0,
ABSOLUTE = 1,
GAUGE = 2,
}

View File

@ -25,6 +25,7 @@ goog.exportSymbol('proto.common.MType', null, global);
goog.exportSymbol('proto.common.MacVersion', null, global);
goog.exportSymbol('proto.common.Metric', null, global);
goog.exportSymbol('proto.common.MetricDataset', null, global);
goog.exportSymbol('proto.common.MetricKind', null, global);
goog.exportSymbol('proto.common.Modulation', null, global);
goog.exportSymbol('proto.common.RegParamsRevision', null, global);
goog.exportSymbol('proto.common.Region', null, global);
@ -589,7 +590,8 @@ proto.common.Metric.toObject = function(includeInstance, msg) {
timestampsList: jspb.Message.toObjectList(msg.getTimestampsList(),
google_protobuf_timestamp_pb.Timestamp.toObject, includeInstance),
datasetsList: jspb.Message.toObjectList(msg.getDatasetsList(),
proto.common.MetricDataset.toObject, includeInstance)
proto.common.MetricDataset.toObject, includeInstance),
kind: jspb.Message.getFieldWithDefault(msg, 4, 0)
};
if (includeInstance) {
@ -640,6 +642,10 @@ proto.common.Metric.deserializeBinaryFromReader = function(msg, reader) {
reader.readMessage(value,proto.common.MetricDataset.deserializeBinaryFromReader);
msg.addDatasets(value);
break;
case 4:
var value = /** @type {!proto.common.MetricKind} */ (reader.readEnum());
msg.setKind(value);
break;
default:
reader.skipField();
break;
@ -692,6 +698,13 @@ proto.common.Metric.serializeBinaryToWriter = function(message, writer) {
proto.common.MetricDataset.serializeBinaryToWriter
);
}
f = message.getKind();
if (f !== 0.0) {
writer.writeEnum(
4,
f
);
}
};
@ -789,6 +802,24 @@ proto.common.Metric.prototype.clearDatasetsList = function() {
};
/**
* optional MetricKind kind = 4;
* @return {!proto.common.MetricKind}
*/
proto.common.Metric.prototype.getKind = function() {
return /** @type {!proto.common.MetricKind} */ (jspb.Message.getFieldWithDefault(this, 4, 0));
};
/**
* @param {!proto.common.MetricKind} value
* @return {!proto.common.Metric} returns this
*/
proto.common.Metric.prototype.setKind = function(value) {
return jspb.Message.setProto3EnumField(this, 4, value);
};
/**
* List of repeated fields within this message type.
@ -1066,4 +1097,13 @@ proto.common.Aggregation = {
MONTH: 2
};
/**
* @enum {number}
*/
proto.common.MetricKind = {
COUNTER: 0,
ABSOLUTE: 1,
GAUGE: 2
};
goog.object.extend(exports, proto.common);

View File

@ -1,6 +1,6 @@
{
"name": "@chirpstack/chirpstack-api-grpc-web",
"version": "4.0.0-test.11",
"version": "4.0.0-rc.2",
"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

@ -80,6 +80,9 @@ export class Metric extends jspb.Message {
setDatasetsList(value: Array<MetricDataset>): void;
addDatasets(value?: MetricDataset, index?: number): MetricDataset;
getKind(): MetricKindMap[keyof MetricKindMap];
setKind(value: MetricKindMap[keyof MetricKindMap]): void;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): Metric.AsObject;
static toObject(includeInstance: boolean, msg: Metric): Metric.AsObject;
@ -95,6 +98,7 @@ export namespace Metric {
name: string,
timestampsList: Array<google_protobuf_timestamp_pb.Timestamp.AsObject>,
datasetsList: Array<MetricDataset.AsObject>,
kind: MetricKindMap[keyof MetricKindMap],
}
}
@ -206,3 +210,11 @@ export interface AggregationMap {
export const Aggregation: AggregationMap;
export interface MetricKindMap {
COUNTER: 0;
ABSOLUTE: 1;
GAUGE: 2;
}
export const MetricKind: MetricKindMap;

View File

@ -18,6 +18,7 @@ goog.exportSymbol('proto.common.MType', null, global);
goog.exportSymbol('proto.common.MacVersion', null, global);
goog.exportSymbol('proto.common.Metric', null, global);
goog.exportSymbol('proto.common.MetricDataset', null, global);
goog.exportSymbol('proto.common.MetricKind', null, global);
goog.exportSymbol('proto.common.Modulation', null, global);
goog.exportSymbol('proto.common.RegParamsRevision', null, global);
goog.exportSymbol('proto.common.Region', null, global);
@ -555,7 +556,8 @@ proto.common.Metric.toObject = function(includeInstance, msg) {
timestampsList: jspb.Message.toObjectList(msg.getTimestampsList(),
google_protobuf_timestamp_pb.Timestamp.toObject, includeInstance),
datasetsList: jspb.Message.toObjectList(msg.getDatasetsList(),
proto.common.MetricDataset.toObject, includeInstance)
proto.common.MetricDataset.toObject, includeInstance),
kind: msg.getKind()
};
if (includeInstance) {
@ -608,6 +610,10 @@ proto.common.Metric.deserializeBinaryFromReader = function(msg, reader) {
msg.getDatasetsList().push(value);
msg.setDatasetsList(msg.getDatasetsList());
break;
case 4:
var value = /** @type {!proto.common.MetricKind} */ (reader.readEnum());
msg.setKind(value);
break;
default:
reader.skipField();
break;
@ -669,6 +675,13 @@ proto.common.Metric.prototype.serializeBinaryToWriter = function (writer) {
proto.common.MetricDataset.serializeBinaryToWriter
);
}
f = this.getKind();
if (f !== 0.0) {
writer.writeEnum(
4,
f
);
}
};
@ -742,6 +755,21 @@ proto.common.Metric.prototype.clearDatasetsList = function() {
};
/**
* optional MetricKind kind = 4;
* @return {!proto.common.MetricKind}
*/
proto.common.Metric.prototype.getKind = function() {
return /** @type {!proto.common.MetricKind} */ (jspb.Message.getFieldProto3(this, 4, 0));
};
/** @param {!proto.common.MetricKind} value */
proto.common.Metric.prototype.setKind = function(value) {
jspb.Message.setField(this, 4, value);
};
/**
* Generated by JsPbCodeGenerator.
@ -1031,4 +1059,13 @@ proto.common.Aggregation = {
MONTH: 2
};
/**
* @enum {number}
*/
proto.common.MetricKind = {
COUNTER: 0,
ABSOLUTE: 1,
GAUGE: 2
};
goog.object.extend(exports, proto.common);

54
api/js/gw/gw_pb.d.ts vendored
View File

@ -189,8 +189,11 @@ export class LrFhssModulationInfo extends jspb.Message {
getOperatingChannelWidth(): number;
setOperatingChannelWidth(value: number): void;
getCodeRate(): string;
setCodeRate(value: string): void;
getCodeRateLegacy(): string;
setCodeRateLegacy(value: string): void;
getCodeRate(): CodeRateMap[keyof CodeRateMap];
setCodeRate(value: CodeRateMap[keyof CodeRateMap]): void;
getGridSteps(): number;
setGridSteps(value: number): void;
@ -208,7 +211,8 @@ export class LrFhssModulationInfo extends jspb.Message {
export namespace LrFhssModulationInfo {
export type AsObject = {
operatingChannelWidth: number,
codeRate: string,
codeRateLegacy: string,
codeRate: CodeRateMap[keyof CodeRateMap],
gridSteps: number,
}
}
@ -509,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;
@ -549,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,
@ -1187,10 +1199,8 @@ export class GatewayCommandExecRequest extends jspb.Message {
getCommand(): string;
setCommand(value: string): void;
getExecid(): Uint8Array | string;
getExecid_asU8(): Uint8Array;
getExecid_asB64(): string;
setExecid(value: Uint8Array | string): void;
getExecId(): number;
setExecId(value: number): void;
getStdin(): Uint8Array | string;
getStdin_asU8(): Uint8Array;
@ -1214,7 +1224,7 @@ export namespace GatewayCommandExecRequest {
gatewayIdLegacy: Uint8Array | string,
gatewayId: string,
command: string,
execid: Uint8Array | string,
execId: number,
stdin: Uint8Array | string,
environmentMap: Array<[string, string]>,
}
@ -1229,10 +1239,8 @@ export class GatewayCommandExecResponse extends jspb.Message {
getGatewayId(): string;
setGatewayId(value: string): void;
getExecId(): Uint8Array | string;
getExecId_asU8(): Uint8Array;
getExecId_asB64(): string;
setExecId(value: Uint8Array | string): void;
getExecId(): number;
setExecId(value: number): void;
getStdout(): Uint8Array | string;
getStdout_asU8(): Uint8Array;
@ -1261,7 +1269,7 @@ export namespace GatewayCommandExecResponse {
export type AsObject = {
gatewayIdLegacy: Uint8Array | string,
gatewayId: string,
execId: Uint8Array | string,
execId: number,
stdout: Uint8Array | string,
stderr: Uint8Array | string,
error: string,
@ -1277,11 +1285,6 @@ export class RawPacketForwarderEvent extends jspb.Message {
getGatewayId(): string;
setGatewayId(value: string): void;
getRawId(): Uint8Array | string;
getRawId_asU8(): Uint8Array;
getRawId_asB64(): string;
setRawId(value: Uint8Array | string): void;
getPayload(): Uint8Array | string;
getPayload_asU8(): Uint8Array;
getPayload_asB64(): string;
@ -1301,7 +1304,6 @@ export namespace RawPacketForwarderEvent {
export type AsObject = {
gatewayIdLegacy: Uint8Array | string,
gatewayId: string,
rawId: Uint8Array | string,
payload: Uint8Array | string,
}
}
@ -1315,11 +1317,6 @@ export class RawPacketForwarderCommand extends jspb.Message {
getGatewayId(): string;
setGatewayId(value: string): void;
getRawId(): Uint8Array | string;
getRawId_asU8(): Uint8Array;
getRawId_asB64(): string;
setRawId(value: Uint8Array | string): void;
getPayload(): Uint8Array | string;
getPayload_asU8(): Uint8Array;
getPayload_asB64(): string;
@ -1339,7 +1336,6 @@ export namespace RawPacketForwarderCommand {
export type AsObject = {
gatewayIdLegacy: Uint8Array | string,
gatewayId: string,
rawId: Uint8Array | string,
payload: Uint8Array | string,
}
}
@ -1387,6 +1383,14 @@ export interface CodeRateMap {
CR_4_6: 2;
CR_4_7: 3;
CR_4_8: 4;
CR_3_8: 5;
CR_2_6: 6;
CR_1_4: 7;
CR_1_6: 8;
CR_5_6: 9;
CR_LI_4_5: 10;
CR_LI_4_6: 11;
CR_LI_4_8: 12;
}
export const CodeRate: CodeRateMap;

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

@ -1393,6 +1393,7 @@ proto.gw.LrFhssModulationInfo.prototype.toObject = function(opt_includeInstance)
proto.gw.LrFhssModulationInfo.toObject = function(includeInstance, msg) {
var f, obj = {
operatingChannelWidth: msg.getOperatingChannelWidth(),
codeRateLegacy: msg.getCodeRateLegacy(),
codeRate: msg.getCodeRate(),
gridSteps: msg.getGridSteps()
};
@ -1437,6 +1438,10 @@ proto.gw.LrFhssModulationInfo.deserializeBinaryFromReader = function(msg, reader
break;
case 2:
var value = /** @type {string} */ (reader.readString());
msg.setCodeRateLegacy(value);
break;
case 4:
var value = /** @type {!proto.gw.CodeRate} */ (reader.readEnum());
msg.setCodeRate(value);
break;
case 3:
@ -1488,13 +1493,20 @@ proto.gw.LrFhssModulationInfo.prototype.serializeBinaryToWriter = function (writ
f
);
}
f = this.getCodeRate();
f = this.getCodeRateLegacy();
if (f.length > 0) {
writer.writeString(
2,
f
);
}
f = this.getCodeRate();
if (f !== 0.0) {
writer.writeEnum(
4,
f
);
}
f = this.getGridSteps();
if (f !== 0) {
writer.writeUint32(
@ -1530,20 +1542,35 @@ proto.gw.LrFhssModulationInfo.prototype.setOperatingChannelWidth = function(valu
/**
* optional string code_rate = 2;
* optional string code_rate_legacy = 2;
* @return {string}
*/
proto.gw.LrFhssModulationInfo.prototype.getCodeRate = function() {
proto.gw.LrFhssModulationInfo.prototype.getCodeRateLegacy = function() {
return /** @type {string} */ (jspb.Message.getFieldProto3(this, 2, ""));
};
/** @param {string} value */
proto.gw.LrFhssModulationInfo.prototype.setCodeRate = function(value) {
proto.gw.LrFhssModulationInfo.prototype.setCodeRateLegacy = function(value) {
jspb.Message.setField(this, 2, value);
};
/**
* optional CodeRate code_rate = 4;
* @return {!proto.gw.CodeRate}
*/
proto.gw.LrFhssModulationInfo.prototype.getCodeRate = function() {
return /** @type {!proto.gw.CodeRate} */ (jspb.Message.getFieldProto3(this, 4, 0));
};
/** @param {!proto.gw.CodeRate} value */
proto.gw.LrFhssModulationInfo.prototype.setCodeRate = function(value) {
jspb.Message.setField(this, 4, value);
};
/**
* optional uint32 grid_steps = 3;
* @return {number}
@ -3637,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),
@ -3711,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);
@ -3821,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
);
@ -3846,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
);
@ -4021,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);
};
@ -4076,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}
*/
@ -4101,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()`
@ -4115,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);
};
@ -4145,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;
};
@ -8863,7 +8944,7 @@ proto.gw.GatewayCommandExecRequest.toObject = function(includeInstance, msg) {
gatewayIdLegacy: msg.getGatewayIdLegacy_asB64(),
gatewayId: msg.getGatewayId(),
command: msg.getCommand(),
execid: msg.getExecid_asB64(),
execId: msg.getExecId(),
stdin: msg.getStdin_asB64(),
environmentMap: (f = msg.getEnvironmentMap(true)) ? f.toArray() : []
};
@ -8914,9 +8995,9 @@ proto.gw.GatewayCommandExecRequest.deserializeBinaryFromReader = function(msg, r
var value = /** @type {string} */ (reader.readString());
msg.setCommand(value);
break;
case 3:
var value = /** @type {!Uint8Array} */ (reader.readBytes());
msg.setExecid(value);
case 7:
var value = /** @type {number} */ (reader.readUint32());
msg.setExecId(value);
break;
case 4:
var value = /** @type {!Uint8Array} */ (reader.readBytes());
@ -8987,10 +9068,10 @@ proto.gw.GatewayCommandExecRequest.prototype.serializeBinaryToWriter = function
f
);
}
f = this.getExecid_asU8();
if (f.length > 0) {
writer.writeBytes(
3,
f = this.getExecId();
if (f !== 0) {
writer.writeUint32(
7,
f
);
}
@ -9087,41 +9168,17 @@ proto.gw.GatewayCommandExecRequest.prototype.setCommand = function(value) {
/**
* optional bytes ExecId = 3;
* @return {!(string|Uint8Array)}
* optional uint32 exec_id = 7;
* @return {number}
*/
proto.gw.GatewayCommandExecRequest.prototype.getExecid = function() {
return /** @type {!(string|Uint8Array)} */ (jspb.Message.getFieldProto3(this, 3, ""));
proto.gw.GatewayCommandExecRequest.prototype.getExecId = function() {
return /** @type {number} */ (jspb.Message.getFieldProto3(this, 7, 0));
};
/**
* optional bytes ExecId = 3;
* This is a type-conversion wrapper around `getExecid()`
* @return {string}
*/
proto.gw.GatewayCommandExecRequest.prototype.getExecid_asB64 = function() {
return /** @type {string} */ (jspb.Message.bytesAsB64(
this.getExecid()));
};
/**
* optional bytes ExecId = 3;
* Note that Uint8Array is not supported on all browsers.
* @see http://caniuse.com/Uint8Array
* This is a type-conversion wrapper around `getExecid()`
* @return {!Uint8Array}
*/
proto.gw.GatewayCommandExecRequest.prototype.getExecid_asU8 = function() {
return /** @type {!Uint8Array} */ (jspb.Message.bytesAsU8(
this.getExecid()));
};
/** @param {!(string|Uint8Array)} value */
proto.gw.GatewayCommandExecRequest.prototype.setExecid = function(value) {
jspb.Message.setField(this, 3, value);
/** @param {number} value */
proto.gw.GatewayCommandExecRequest.prototype.setExecId = function(value) {
jspb.Message.setField(this, 7, value);
};
@ -9225,7 +9282,7 @@ proto.gw.GatewayCommandExecResponse.toObject = function(includeInstance, msg) {
var f, obj = {
gatewayIdLegacy: msg.getGatewayIdLegacy_asB64(),
gatewayId: msg.getGatewayId(),
execId: msg.getExecId_asB64(),
execId: msg.getExecId(),
stdout: msg.getStdout_asB64(),
stderr: msg.getStderr_asB64(),
error: msg.getError()
@ -9273,8 +9330,8 @@ proto.gw.GatewayCommandExecResponse.deserializeBinaryFromReader = function(msg,
var value = /** @type {string} */ (reader.readString());
msg.setGatewayId(value);
break;
case 2:
var value = /** @type {!Uint8Array} */ (reader.readBytes());
case 7:
var value = /** @type {number} */ (reader.readUint32());
msg.setExecId(value);
break;
case 3:
@ -9341,10 +9398,10 @@ proto.gw.GatewayCommandExecResponse.prototype.serializeBinaryToWriter = function
f
);
}
f = this.getExecId_asU8();
if (f.length > 0) {
writer.writeBytes(
2,
f = this.getExecId();
if (f !== 0) {
writer.writeUint32(
7,
f
);
}
@ -9436,41 +9493,17 @@ proto.gw.GatewayCommandExecResponse.prototype.setGatewayId = function(value) {
/**
* optional bytes exec_id = 2;
* @return {!(string|Uint8Array)}
* optional uint32 exec_id = 7;
* @return {number}
*/
proto.gw.GatewayCommandExecResponse.prototype.getExecId = function() {
return /** @type {!(string|Uint8Array)} */ (jspb.Message.getFieldProto3(this, 2, ""));
return /** @type {number} */ (jspb.Message.getFieldProto3(this, 7, 0));
};
/**
* optional bytes exec_id = 2;
* This is a type-conversion wrapper around `getExecId()`
* @return {string}
*/
proto.gw.GatewayCommandExecResponse.prototype.getExecId_asB64 = function() {
return /** @type {string} */ (jspb.Message.bytesAsB64(
this.getExecId()));
};
/**
* optional bytes exec_id = 2;
* Note that Uint8Array is not supported on all browsers.
* @see http://caniuse.com/Uint8Array
* This is a type-conversion wrapper around `getExecId()`
* @return {!Uint8Array}
*/
proto.gw.GatewayCommandExecResponse.prototype.getExecId_asU8 = function() {
return /** @type {!Uint8Array} */ (jspb.Message.bytesAsU8(
this.getExecId()));
};
/** @param {!(string|Uint8Array)} value */
/** @param {number} value */
proto.gw.GatewayCommandExecResponse.prototype.setExecId = function(value) {
jspb.Message.setField(this, 2, value);
jspb.Message.setField(this, 7, value);
};
@ -9615,7 +9648,6 @@ proto.gw.RawPacketForwarderEvent.toObject = function(includeInstance, msg) {
var f, obj = {
gatewayIdLegacy: msg.getGatewayIdLegacy_asB64(),
gatewayId: msg.getGatewayId(),
rawId: msg.getRawId_asB64(),
payload: msg.getPayload_asB64()
};
@ -9661,10 +9693,6 @@ proto.gw.RawPacketForwarderEvent.deserializeBinaryFromReader = function(msg, rea
var value = /** @type {string} */ (reader.readString());
msg.setGatewayId(value);
break;
case 2:
var value = /** @type {!Uint8Array} */ (reader.readBytes());
msg.setRawId(value);
break;
case 3:
var value = /** @type {!Uint8Array} */ (reader.readBytes());
msg.setPayload(value);
@ -9721,13 +9749,6 @@ proto.gw.RawPacketForwarderEvent.prototype.serializeBinaryToWriter = function (w
f
);
}
f = this.getRawId_asU8();
if (f.length > 0) {
writer.writeBytes(
2,
f
);
}
f = this.getPayload_asU8();
if (f.length > 0) {
writer.writeBytes(
@ -9801,45 +9822,6 @@ proto.gw.RawPacketForwarderEvent.prototype.setGatewayId = function(value) {
};
/**
* optional bytes raw_id = 2;
* @return {!(string|Uint8Array)}
*/
proto.gw.RawPacketForwarderEvent.prototype.getRawId = function() {
return /** @type {!(string|Uint8Array)} */ (jspb.Message.getFieldProto3(this, 2, ""));
};
/**
* optional bytes raw_id = 2;
* This is a type-conversion wrapper around `getRawId()`
* @return {string}
*/
proto.gw.RawPacketForwarderEvent.prototype.getRawId_asB64 = function() {
return /** @type {string} */ (jspb.Message.bytesAsB64(
this.getRawId()));
};
/**
* optional bytes raw_id = 2;
* Note that Uint8Array is not supported on all browsers.
* @see http://caniuse.com/Uint8Array
* This is a type-conversion wrapper around `getRawId()`
* @return {!Uint8Array}
*/
proto.gw.RawPacketForwarderEvent.prototype.getRawId_asU8 = function() {
return /** @type {!Uint8Array} */ (jspb.Message.bytesAsU8(
this.getRawId()));
};
/** @param {!(string|Uint8Array)} value */
proto.gw.RawPacketForwarderEvent.prototype.setRawId = function(value) {
jspb.Message.setField(this, 2, value);
};
/**
* optional bytes payload = 3;
* @return {!(string|Uint8Array)}
@ -9927,7 +9909,6 @@ proto.gw.RawPacketForwarderCommand.toObject = function(includeInstance, msg) {
var f, obj = {
gatewayIdLegacy: msg.getGatewayIdLegacy_asB64(),
gatewayId: msg.getGatewayId(),
rawId: msg.getRawId_asB64(),
payload: msg.getPayload_asB64()
};
@ -9973,10 +9954,6 @@ proto.gw.RawPacketForwarderCommand.deserializeBinaryFromReader = function(msg, r
var value = /** @type {string} */ (reader.readString());
msg.setGatewayId(value);
break;
case 2:
var value = /** @type {!Uint8Array} */ (reader.readBytes());
msg.setRawId(value);
break;
case 3:
var value = /** @type {!Uint8Array} */ (reader.readBytes());
msg.setPayload(value);
@ -10033,13 +10010,6 @@ proto.gw.RawPacketForwarderCommand.prototype.serializeBinaryToWriter = function
f
);
}
f = this.getRawId_asU8();
if (f.length > 0) {
writer.writeBytes(
2,
f
);
}
f = this.getPayload_asU8();
if (f.length > 0) {
writer.writeBytes(
@ -10113,45 +10083,6 @@ proto.gw.RawPacketForwarderCommand.prototype.setGatewayId = function(value) {
};
/**
* optional bytes raw_id = 2;
* @return {!(string|Uint8Array)}
*/
proto.gw.RawPacketForwarderCommand.prototype.getRawId = function() {
return /** @type {!(string|Uint8Array)} */ (jspb.Message.getFieldProto3(this, 2, ""));
};
/**
* optional bytes raw_id = 2;
* This is a type-conversion wrapper around `getRawId()`
* @return {string}
*/
proto.gw.RawPacketForwarderCommand.prototype.getRawId_asB64 = function() {
return /** @type {string} */ (jspb.Message.bytesAsB64(
this.getRawId()));
};
/**
* optional bytes raw_id = 2;
* Note that Uint8Array is not supported on all browsers.
* @see http://caniuse.com/Uint8Array
* This is a type-conversion wrapper around `getRawId()`
* @return {!Uint8Array}
*/
proto.gw.RawPacketForwarderCommand.prototype.getRawId_asU8 = function() {
return /** @type {!Uint8Array} */ (jspb.Message.bytesAsU8(
this.getRawId()));
};
/** @param {!(string|Uint8Array)} value */
proto.gw.RawPacketForwarderCommand.prototype.setRawId = function(value) {
jspb.Message.setField(this, 2, value);
};
/**
* optional bytes payload = 3;
* @return {!(string|Uint8Array)}
@ -10444,7 +10375,15 @@ proto.gw.CodeRate = {
CR_4_5: 1,
CR_4_6: 2,
CR_4_7: 3,
CR_4_8: 4
CR_4_8: 4,
CR_3_8: 5,
CR_2_6: 6,
CR_1_4: 7,
CR_1_6: 8,
CR_5_6: 9,
CR_LI_4_5: 10,
CR_LI_4_6: 11,
CR_LI_4_8: 12
};
/**

2
api/js/package.json vendored
View File

@ -1,6 +1,6 @@
{
"name": "@chirpstack/chirpstack-api",
"version": "4.0.0-test.11",
"version": "4.0.0-rc.2",
"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

@ -142,6 +142,17 @@ enum Aggregation {
MONTH = 2;
}
enum MetricKind {
// Incrementing counters that never decrease (these are not reset on each reading).
COUNTER = 0;
// Counters that do get reset upon reading.
ABSOLUTE = 1;
// E.g. a temperature value.
GAUGE = 2;
}
message Location {
// Latitude.
double latitude = 1;
@ -176,6 +187,9 @@ message Metric {
// Datasets.
repeated MetricDataset datasets = 3;
// Kind.
MetricKind kind = 4;
}
message MetricDataset {

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

@ -15,10 +15,18 @@ import "google/protobuf/struct.proto";
enum CodeRate {
CR_UNDEFINED = 0;
CR_4_5 = 1;
CR_4_5 = 1; // LoRa
CR_4_6 = 2;
CR_4_7 = 3;
CR_4_8 = 4;
CR_3_8 = 5; // LR-FHSS
CR_2_6 = 6;
CR_1_4 = 7;
CR_1_6 = 8;
CR_5_6 = 9;
CR_LI_4_5 = 10; // LoRa 2.4 gHz
CR_LI_4_6 = 11;
CR_LI_4_8 = 12;
}
enum DownlinkTiming {
@ -159,7 +167,11 @@ message LrFhssModulationInfo {
uint32 operating_channel_width = 1;
// Code-rate.
string code_rate = 2;
// Deprecated: use code_rate.
string code_rate_legacy = 2;
// Code-rate.
CodeRate code_rate = 4;
// Hopping grid number of steps.
uint32 grid_steps = 3;
@ -319,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 {
@ -599,10 +617,10 @@ message GatewayCommandExecRequest {
// This command must be pre-configured in the LoRa Gateway Bridge configuration.
string command = 2;
// Execution request ID (UUID).
// The same token will be returned when the execution of the command has
// Execution request ID.
// The same will be returned when the execution of the command has
// completed.
bytes ExecId = 3;
uint32 exec_id = 7;
// Standard input.
bytes stdin = 4;
@ -619,8 +637,8 @@ message GatewayCommandExecResponse {
// Gateway ID.
string gateway_id = 6;
// Execution request ID (UUID).
bytes exec_id = 2;
// Execution request ID.
uint32 exec_id = 7;
// Standard output.
bytes stdout = 3;
@ -643,9 +661,6 @@ message RawPacketForwarderEvent {
// Gateway ID.
string gateway_id = 4;
// Raw ID (UUID).
bytes raw_id = 2;
// Payload contains the raw payload.
bytes payload = 3;
}
@ -661,9 +676,6 @@ message RawPacketForwarderCommand {
// Gateway ID.
string gateway_id = 4;
// Raw ID (UUID).
bytes raw_id = 2;
// Payload contains the raw payload.
bytes payload = 3;
}

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

@ -142,6 +142,17 @@ enum Aggregation {
MONTH = 2;
}
enum MetricKind {
// Incrementing counters that never decrease (these are not reset on each reading).
COUNTER = 0;
// Counters that do get reset upon reading.
ABSOLUTE = 1;
// E.g. a temperature value.
GAUGE = 2;
}
message Location {
// Latitude.
double latitude = 1;
@ -176,6 +187,9 @@ message Metric {
// Datasets.
repeated MetricDataset datasets = 3;
// Kind.
MetricKind kind = 4;
}
message MetricDataset {

View File

@ -15,10 +15,18 @@ import "google/protobuf/struct.proto";
enum CodeRate {
CR_UNDEFINED = 0;
CR_4_5 = 1;
CR_4_5 = 1; // LoRa
CR_4_6 = 2;
CR_4_7 = 3;
CR_4_8 = 4;
CR_3_8 = 5; // LR-FHSS
CR_2_6 = 6;
CR_1_4 = 7;
CR_1_6 = 8;
CR_5_6 = 9;
CR_LI_4_5 = 10; // LoRa 2.4 gHz
CR_LI_4_6 = 11;
CR_LI_4_8 = 12;
}
enum DownlinkTiming {
@ -159,7 +167,11 @@ message LrFhssModulationInfo {
uint32 operating_channel_width = 1;
// Code-rate.
string code_rate = 2;
// Deprecated: use code_rate.
string code_rate_legacy = 2;
// Code-rate.
CodeRate code_rate = 4;
// Hopping grid number of steps.
uint32 grid_steps = 3;
@ -319,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 {
@ -599,10 +617,10 @@ message GatewayCommandExecRequest {
// This command must be pre-configured in the LoRa Gateway Bridge configuration.
string command = 2;
// Execution request ID (UUID).
// The same token will be returned when the execution of the command has
// Execution request ID.
// The same will be returned when the execution of the command has
// completed.
bytes ExecId = 3;
uint32 exec_id = 7;
// Standard input.
bytes stdin = 4;
@ -619,8 +637,8 @@ message GatewayCommandExecResponse {
// Gateway ID.
string gateway_id = 6;
// Execution request ID (UUID).
bytes exec_id = 2;
// Execution request ID.
uint32 exec_id = 7;
// Standard output.
bytes stdout = 3;
@ -643,9 +661,6 @@ message RawPacketForwarderEvent {
// Gateway ID.
string gateway_id = 4;
// Raw ID (UUID).
bytes raw_id = 2;
// Payload contains the raw payload.
bytes payload = 3;
}
@ -661,9 +676,6 @@ message RawPacketForwarderCommand {
// Gateway ID.
string gateway_id = 4;
// Raw ID (UUID).
bytes raw_id = 2;
// Payload contains the raw payload.
bytes payload = 3;
}

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)

View File

@ -16,7 +16,7 @@ _sym_db = _symbol_database.Default()
from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\"chirpstack-api/common/common.proto\x12\x06\x63ommon\x1a\x1fgoogle/protobuf/timestamp.proto\"{\n\x08Location\x12\x10\n\x08latitude\x18\x01 \x01(\x01\x12\x11\n\tlongitude\x18\x02 \x01(\x01\x12\x10\n\x08\x61ltitude\x18\x03 \x01(\x01\x12&\n\x06source\x18\x04 \x01(\x0e\x32\x16.common.LocationSource\x12\x10\n\x08\x61\x63\x63uracy\x18\x05 \x01(\x02\"1\n\x0bKeyEnvelope\x12\x11\n\tkek_label\x18\x01 \x01(\t\x12\x0f\n\x07\x61\x65s_key\x18\x02 \x01(\x0c\"o\n\x06Metric\x12\x0c\n\x04name\x18\x01 \x01(\t\x12.\n\ntimestamps\x18\x02 \x03(\x0b\x32\x1a.google.protobuf.Timestamp\x12\'\n\x08\x64\x61tasets\x18\x03 \x03(\x0b\x32\x15.common.MetricDataset\",\n\rMetricDataset\x12\r\n\x05label\x18\x01 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x02 \x03(\x02*,\n\nModulation\x12\x08\n\x04LORA\x10\x00\x12\x07\n\x03\x46SK\x10\x01\x12\x0b\n\x07LR_FHSS\x10\x02*\xaa\x01\n\x06Region\x12\t\n\x05\x45U868\x10\x00\x12\t\n\x05US915\x10\x02\x12\t\n\x05\x43N779\x10\x03\x12\t\n\x05\x45U433\x10\x04\x12\t\n\x05\x41U915\x10\x05\x12\t\n\x05\x43N470\x10\x06\x12\t\n\x05\x41S923\x10\x07\x12\x0b\n\x07\x41S923_2\x10\x0c\x12\x0b\n\x07\x41S923_3\x10\r\x12\x0b\n\x07\x41S923_4\x10\x0e\x12\t\n\x05KR920\x10\x08\x12\t\n\x05IN865\x10\t\x12\t\n\x05RU864\x10\n\x12\x0b\n\x07ISM2400\x10\x0b*\xb3\x01\n\x05MType\x12\x10\n\x0cJOIN_REQUEST\x10\x00\x12\x0f\n\x0bJOIN_ACCEPT\x10\x01\x12\x17\n\x13UNCONFIRMED_DATA_UP\x10\x02\x12\x19\n\x15UNCONFIRMED_DATA_DOWN\x10\x03\x12\x15\n\x11\x43ONFIRMED_DATA_UP\x10\x04\x12\x17\n\x13\x43ONFIRMED_DATA_DOWN\x10\x05\x12\x12\n\x0eREJOIN_REQUEST\x10\x06\x12\x0f\n\x0bPROPRIETARY\x10\x07*~\n\nMacVersion\x12\x11\n\rLORAWAN_1_0_0\x10\x00\x12\x11\n\rLORAWAN_1_0_1\x10\x01\x12\x11\n\rLORAWAN_1_0_2\x10\x02\x12\x11\n\rLORAWAN_1_0_3\x10\x03\x12\x11\n\rLORAWAN_1_0_4\x10\x04\x12\x11\n\rLORAWAN_1_1_0\x10\x05*e\n\x11RegParamsRevision\x12\x05\n\x01\x41\x10\x00\x12\x05\n\x01\x42\x10\x01\x12\x0f\n\x0bRP002_1_0_0\x10\x02\x12\x0f\n\x0bRP002_1_0_1\x10\x03\x12\x0f\n\x0bRP002_1_0_2\x10\x04\x12\x0f\n\x0bRP002_1_0_3\x10\x05*\x8e\x01\n\x0eLocationSource\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x07\n\x03GPS\x10\x01\x12\n\n\x06\x43ONFIG\x10\x02\x12\x15\n\x11GEO_RESOLVER_TDOA\x10\x03\x12\x15\n\x11GEO_RESOLVER_RSSI\x10\x04\x12\x15\n\x11GEO_RESOLVER_GNSS\x10\x05\x12\x15\n\x11GEO_RESOLVER_WIFI\x10\x06*+\n\x0b\x41ggregation\x12\x08\n\x04HOUR\x10\x00\x12\x07\n\x03\x44\x41Y\x10\x01\x12\t\n\x05MONTH\x10\x02\x42U\n\x11io.chirpstack.apiB\x0b\x43ommonProtoP\x01Z1github.com/chirpstack/chirpstack/api/go/v4/commonb\x06proto3')
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\"chirpstack-api/common/common.proto\x12\x06\x63ommon\x1a\x1fgoogle/protobuf/timestamp.proto\"{\n\x08Location\x12\x10\n\x08latitude\x18\x01 \x01(\x01\x12\x11\n\tlongitude\x18\x02 \x01(\x01\x12\x10\n\x08\x61ltitude\x18\x03 \x01(\x01\x12&\n\x06source\x18\x04 \x01(\x0e\x32\x16.common.LocationSource\x12\x10\n\x08\x61\x63\x63uracy\x18\x05 \x01(\x02\"1\n\x0bKeyEnvelope\x12\x11\n\tkek_label\x18\x01 \x01(\t\x12\x0f\n\x07\x61\x65s_key\x18\x02 \x01(\x0c\"\x91\x01\n\x06Metric\x12\x0c\n\x04name\x18\x01 \x01(\t\x12.\n\ntimestamps\x18\x02 \x03(\x0b\x32\x1a.google.protobuf.Timestamp\x12\'\n\x08\x64\x61tasets\x18\x03 \x03(\x0b\x32\x15.common.MetricDataset\x12 \n\x04kind\x18\x04 \x01(\x0e\x32\x12.common.MetricKind\",\n\rMetricDataset\x12\r\n\x05label\x18\x01 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x02 \x03(\x02*,\n\nModulation\x12\x08\n\x04LORA\x10\x00\x12\x07\n\x03\x46SK\x10\x01\x12\x0b\n\x07LR_FHSS\x10\x02*\xaa\x01\n\x06Region\x12\t\n\x05\x45U868\x10\x00\x12\t\n\x05US915\x10\x02\x12\t\n\x05\x43N779\x10\x03\x12\t\n\x05\x45U433\x10\x04\x12\t\n\x05\x41U915\x10\x05\x12\t\n\x05\x43N470\x10\x06\x12\t\n\x05\x41S923\x10\x07\x12\x0b\n\x07\x41S923_2\x10\x0c\x12\x0b\n\x07\x41S923_3\x10\r\x12\x0b\n\x07\x41S923_4\x10\x0e\x12\t\n\x05KR920\x10\x08\x12\t\n\x05IN865\x10\t\x12\t\n\x05RU864\x10\n\x12\x0b\n\x07ISM2400\x10\x0b*\xb3\x01\n\x05MType\x12\x10\n\x0cJOIN_REQUEST\x10\x00\x12\x0f\n\x0bJOIN_ACCEPT\x10\x01\x12\x17\n\x13UNCONFIRMED_DATA_UP\x10\x02\x12\x19\n\x15UNCONFIRMED_DATA_DOWN\x10\x03\x12\x15\n\x11\x43ONFIRMED_DATA_UP\x10\x04\x12\x17\n\x13\x43ONFIRMED_DATA_DOWN\x10\x05\x12\x12\n\x0eREJOIN_REQUEST\x10\x06\x12\x0f\n\x0bPROPRIETARY\x10\x07*~\n\nMacVersion\x12\x11\n\rLORAWAN_1_0_0\x10\x00\x12\x11\n\rLORAWAN_1_0_1\x10\x01\x12\x11\n\rLORAWAN_1_0_2\x10\x02\x12\x11\n\rLORAWAN_1_0_3\x10\x03\x12\x11\n\rLORAWAN_1_0_4\x10\x04\x12\x11\n\rLORAWAN_1_1_0\x10\x05*e\n\x11RegParamsRevision\x12\x05\n\x01\x41\x10\x00\x12\x05\n\x01\x42\x10\x01\x12\x0f\n\x0bRP002_1_0_0\x10\x02\x12\x0f\n\x0bRP002_1_0_1\x10\x03\x12\x0f\n\x0bRP002_1_0_2\x10\x04\x12\x0f\n\x0bRP002_1_0_3\x10\x05*\x8e\x01\n\x0eLocationSource\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x07\n\x03GPS\x10\x01\x12\n\n\x06\x43ONFIG\x10\x02\x12\x15\n\x11GEO_RESOLVER_TDOA\x10\x03\x12\x15\n\x11GEO_RESOLVER_RSSI\x10\x04\x12\x15\n\x11GEO_RESOLVER_GNSS\x10\x05\x12\x15\n\x11GEO_RESOLVER_WIFI\x10\x06*+\n\x0b\x41ggregation\x12\x08\n\x04HOUR\x10\x00\x12\x07\n\x03\x44\x41Y\x10\x01\x12\t\n\x05MONTH\x10\x02*2\n\nMetricKind\x12\x0b\n\x07\x43OUNTER\x10\x00\x12\x0c\n\x08\x41\x42SOLUTE\x10\x01\x12\t\n\x05GAUGE\x10\x02\x42U\n\x11io.chirpstack.apiB\x0b\x43ommonProtoP\x01Z1github.com/chirpstack/chirpstack/api/go/v4/commonb\x06proto3')
_MODULATION = DESCRIPTOR.enum_types_by_name['Modulation']
Modulation = enum_type_wrapper.EnumTypeWrapper(_MODULATION)
@ -32,6 +32,8 @@ _LOCATIONSOURCE = DESCRIPTOR.enum_types_by_name['LocationSource']
LocationSource = enum_type_wrapper.EnumTypeWrapper(_LOCATIONSOURCE)
_AGGREGATION = DESCRIPTOR.enum_types_by_name['Aggregation']
Aggregation = enum_type_wrapper.EnumTypeWrapper(_AGGREGATION)
_METRICKIND = DESCRIPTOR.enum_types_by_name['MetricKind']
MetricKind = enum_type_wrapper.EnumTypeWrapper(_METRICKIND)
LORA = 0
FSK = 1
LR_FHSS = 2
@ -79,6 +81,9 @@ GEO_RESOLVER_WIFI = 6
HOUR = 0
DAY = 1
MONTH = 2
COUNTER = 0
ABSOLUTE = 1
GAUGE = 2
_LOCATION = DESCRIPTOR.message_types_by_name['Location']
@ -117,26 +122,28 @@ if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\021io.chirpstack.apiB\013CommonProtoP\001Z1github.com/chirpstack/chirpstack/api/go/v4/common'
_MODULATION._serialized_start=414
_MODULATION._serialized_end=458
_REGION._serialized_start=461
_REGION._serialized_end=631
_MTYPE._serialized_start=634
_MTYPE._serialized_end=813
_MACVERSION._serialized_start=815
_MACVERSION._serialized_end=941
_REGPARAMSREVISION._serialized_start=943
_REGPARAMSREVISION._serialized_end=1044
_LOCATIONSOURCE._serialized_start=1047
_LOCATIONSOURCE._serialized_end=1189
_AGGREGATION._serialized_start=1191
_AGGREGATION._serialized_end=1234
_MODULATION._serialized_start=449
_MODULATION._serialized_end=493
_REGION._serialized_start=496
_REGION._serialized_end=666
_MTYPE._serialized_start=669
_MTYPE._serialized_end=848
_MACVERSION._serialized_start=850
_MACVERSION._serialized_end=976
_REGPARAMSREVISION._serialized_start=978
_REGPARAMSREVISION._serialized_end=1079
_LOCATIONSOURCE._serialized_start=1082
_LOCATIONSOURCE._serialized_end=1224
_AGGREGATION._serialized_start=1226
_AGGREGATION._serialized_end=1269
_METRICKIND._serialized_start=1271
_METRICKIND._serialized_end=1321
_LOCATION._serialized_start=79
_LOCATION._serialized_end=202
_KEYENVELOPE._serialized_start=204
_KEYENVELOPE._serialized_end=253
_METRIC._serialized_start=255
_METRIC._serialized_end=366
_METRICDATASET._serialized_start=368
_METRICDATASET._serialized_end=412
_METRIC._serialized_start=256
_METRIC._serialized_end=401
_METRICDATASET._serialized_start=403
_METRICDATASET._serialized_end=447
# @@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.11",
version = "4.0.0-rc.2",
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.11"
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.11"
version = "4.0.0-rc.2"
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

@ -142,6 +142,17 @@ enum Aggregation {
MONTH = 2;
}
enum MetricKind {
// Incrementing counters that never decrease (these are not reset on each reading).
COUNTER = 0;
// Counters that do get reset upon reading.
ABSOLUTE = 1;
// E.g. a temperature value.
GAUGE = 2;
}
message Location {
// Latitude.
double latitude = 1;
@ -176,6 +187,9 @@ message Metric {
// Datasets.
repeated MetricDataset datasets = 3;
// Kind.
MetricKind kind = 4;
}
message MetricDataset {

View File

@ -15,10 +15,18 @@ import "google/protobuf/struct.proto";
enum CodeRate {
CR_UNDEFINED = 0;
CR_4_5 = 1;
CR_4_5 = 1; // LoRa
CR_4_6 = 2;
CR_4_7 = 3;
CR_4_8 = 4;
CR_3_8 = 5; // LR-FHSS
CR_2_6 = 6;
CR_1_4 = 7;
CR_1_6 = 8;
CR_5_6 = 9;
CR_LI_4_5 = 10; // LoRa 2.4 gHz
CR_LI_4_6 = 11;
CR_LI_4_8 = 12;
}
enum DownlinkTiming {
@ -159,7 +167,11 @@ message LrFhssModulationInfo {
uint32 operating_channel_width = 1;
// Code-rate.
string code_rate = 2;
// Deprecated: use code_rate.
string code_rate_legacy = 2;
// Code-rate.
CodeRate code_rate = 4;
// Hopping grid number of steps.
uint32 grid_steps = 3;
@ -319,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 {
@ -599,10 +617,10 @@ message GatewayCommandExecRequest {
// This command must be pre-configured in the LoRa Gateway Bridge configuration.
string command = 2;
// Execution request ID (UUID).
// The same token will be returned when the execution of the command has
// Execution request ID.
// The same will be returned when the execution of the command has
// completed.
bytes ExecId = 3;
uint32 exec_id = 7;
// Standard input.
bytes stdin = 4;
@ -619,8 +637,8 @@ message GatewayCommandExecResponse {
// Gateway ID.
string gateway_id = 6;
// Execution request ID (UUID).
bytes exec_id = 2;
// Execution request ID.
uint32 exec_id = 7;
// Standard output.
bytes stdout = 3;
@ -643,9 +661,6 @@ message RawPacketForwarderEvent {
// Gateway ID.
string gateway_id = 4;
// Raw ID (UUID).
bytes raw_id = 2;
// Payload contains the raw payload.
bytes payload = 3;
}
@ -661,9 +676,6 @@ message RawPacketForwarderCommand {
// Gateway ID.
string gateway_id = 4;
// Raw ID (UUID).
bytes raw_id = 2;
// Payload contains the raw payload.
bytes payload = 3;
}

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

@ -1,8 +1,56 @@
use rand::Rng;
use std::error::Error;
use std::str::FromStr;
tonic::include_proto!("gw/gw");
include!(concat!(env!("OUT_DIR"), "/gw/gw.serde.rs"));
#[allow(clippy::from_over_into)]
impl Into<String> for CodeRate {
fn into(self) -> String {
match self {
CodeRate::CrUndefined => "",
CodeRate::Cr45 => "4/5",
CodeRate::Cr46 => "4/6",
CodeRate::Cr47 => "4/7",
CodeRate::Cr48 => "4/8",
CodeRate::Cr38 => "3/8",
CodeRate::Cr26 => "2/6",
CodeRate::Cr14 => "1/4",
CodeRate::Cr16 => "1/6",
CodeRate::Cr56 => "5/6",
CodeRate::CrLi45 => "4/5LI",
CodeRate::CrLi46 => "4/6LI",
CodeRate::CrLi48 => "4/8LI",
}
.to_string()
}
}
impl FromStr for CodeRate {
type Err = Box<dyn Error>;
fn from_str(s: &str) -> Result<Self, Box<dyn Error>> {
Ok(match s {
"4/5" => CodeRate::Cr45,
"4/6" | "2/3" => CodeRate::Cr46,
"4/7" => CodeRate::Cr47,
"4/8" | "2/4" | "1/2" => CodeRate::Cr48,
"3/8" => CodeRate::Cr38,
"2/6" | "1/3" => CodeRate::Cr26,
"1/4" => CodeRate::Cr14,
"1/6" => CodeRate::Cr16,
"5/6" => CodeRate::Cr56,
"4/5LI" => CodeRate::CrLi45,
"4/6LI" => CodeRate::CrLi46,
"4/8LI" => CodeRate::CrLi48,
_ => {
return Err("invalid code-rate".into());
}
})
}
}
#[allow(clippy::from_over_into)]
impl Into<String> for TxAckStatus {
fn into(self) -> String {
@ -35,14 +83,9 @@ impl UplinkFrame {
modulation::Parameters::Lora(LoraModulationInfo {
bandwidth: info.bandwidth * 1000,
spreading_factor: info.spreading_factor,
code_rate: match info.code_rate_legacy.as_ref() {
"4/5" => CodeRate::Cr45,
"2/3" | "4/6" => CodeRate::Cr46,
"4/7" => CodeRate::Cr47,
"1/2" | "2/4" | "4/8" => CodeRate::Cr48,
_ => CodeRate::CrUndefined,
}
.into(),
code_rate: CodeRate::from_str(&info.code_rate_legacy)
.unwrap_or(CodeRate::CrUndefined)
.into(),
code_rate_legacy: "".into(),
polarization_inversion: info.polarization_inversion,
})
@ -51,7 +94,13 @@ impl UplinkFrame {
modulation::Parameters::Fsk(info.clone())
}
uplink_tx_info_legacy::ModulationInfo::LrFhssModulationInfo(info) => {
modulation::Parameters::LrFhss(info.clone())
modulation::Parameters::LrFhss(LrFhssModulationInfo {
code_rate: CodeRate::from_str(&info.code_rate_legacy)
.unwrap_or(CodeRate::CrUndefined)
.into(),
code_rate_legacy: "".into(),
..info.clone()
})
}
}),
}),
@ -72,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(),
@ -156,14 +207,7 @@ impl DownlinkFrame {
LoraModulationInfo {
bandwidth: v.bandwidth / 1000,
spreading_factor: v.spreading_factor,
code_rate_legacy: match v.code_rate() {
CodeRate::CrUndefined => "",
CodeRate::Cr45 => "4/5",
CodeRate::Cr46 => "4/6",
CodeRate::Cr47 => "4/7",
CodeRate::Cr48 => "4/8",
}
.into(),
code_rate_legacy: v.code_rate().into(),
polarization_inversion: v.polarization_inversion,
..Default::default()
},
@ -235,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.11"
version = "4.0.0-rc.2"
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");
@ -974,7 +979,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 +1089,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

@ -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.11"
version = "4.0.0-rc.2"
authors = ["Orne Brocaar <info@brocaar.com>"]
edition = "2021"
publish = false
@ -23,8 +23,8 @@ handlebars = "4.1"
# Database
validator = "0.13"
diesel = { version = "2.0.0-rc.0", features = [ "chrono", "postgres", "r2d2", "uuid", "serde_json", "numeric" ] }
diesel_migrations = { version = "2.0.0-rc.0" }
diesel = { version = "2.0.0-rc.1", features = [ "chrono", "postgres", "r2d2", "uuid", "serde_json", "numeric" ] }
diesel_migrations = { version = "2.0.0-rc.1" }
r2d2 = "0.8"
bigdecimal = "0.3"
redis = { version = "0.21", features = ["r2d2", "cluster"] }
@ -90,7 +90,7 @@ openssl = { version = "0.10", features = ["vendored"] }
openidconnect = { version = "2.3.1", features = ["accept-rfc3339-timestamps"] }
# MQTT
paho-mqtt = { version = "0.9", features = ["vendored-ssl"] }
paho-mqtt = { version = "0.11", features = ["vendored-ssl"] }
hex = "0.4"
# Codecs

View File

@ -4,35 +4,35 @@ TARGET_ARCH := $(shell rustc --print cfg |grep target_arch |sed 's/target_arch="
PKG_VERSION := $(shell cargo metadata --no-deps --format-version 1 | jq -r '.packages[0].version')
debug-amd64:
apt update && apt install -y libpq-dev:amd64
apt-get install -y libpq-dev:amd64
cargo build
debug-armv7hf:
# We can not install this by default, as only one libpq-dev version can be
# installed at a time.
apt update && apt install -y libpq-dev:armhf
apt-get install -y libpq-dev:armhf
BINDGEN_EXTRA_CLANG_ARGS="--sysroot=/usr/arm-linux-gnueabihf" \
PKG_CONFIG_SYSROOT_DIR="/usr/arm-linux-gnueabihf" \
cargo build --target armv7-unknown-linux-gnueabihf
debug-arm64:
apt update && apt install -y libpq-dev:arm64
apt-get install -y libpq-dev:arm64
BINDGEN_EXTRA_CLANG_ARGS="--sysroot=/usr/aarch64-linux-gnu" \
PKG_CONFIG_SYSROOT_DIR="/usr/aarch64-linux-gnu" \
cargo build --target aarch64-unknown-linux-gnu
release-amd64:
apt update && apt install -y libpq-dev:amd64
apt-get install -y libpq-dev:amd64
cargo build --release
release-armv7hf:
apt update && apt install -y libpq-dev:armhf
apt-get install -y libpq-dev:armhf
BINDGEN_EXTRA_CLANG_ARGS="--sysroot=/usr/arm-linux-gnueabihf" \
PKG_CONFIG_SYSROOT_DIR="/usr/arm-linux-gnueabihf" \
cargo build --target armv7-unknown-linux-gnueabihf --release
release-arm64:
apt update && apt install -y libpq-dev:arm64
apt-get install -y libpq-dev:arm64
BINDGEN_EXTRA_CLANG_ARGS="--sysroot=/usr/aarch64-linux-gnu" \
PKG_CONFIG_SYSROOT_DIR="/usr/aarch64-linux-gnu" \
cargo build --target aarch64-unknown-linux-gnu --release
@ -48,13 +48,13 @@ dist: release-deb-amd64 \
release-targz-arm64 \
release-deb-amd64:
apt update && apt install -y libpq-dev:amd64
apt-get install -y libpq-dev:amd64
mkdir -p /chirpstack/dist
cargo deb
cp ../target/debian/*.deb /chirpstack/dist
release-deb-armv7hf:
apt update && apt install -y libpq-dev:armhf
apt-get install -y libpq-dev:armhf
mkdir -p /chirpstack/dist
BINDGEN_EXTRA_CLANG_ARGS="--sysroot=/usr/arm-linux-gnueabihf" \
PKG_CONFIG_SYSROOT_DIR="/usr/arm-linux-gnueabihf" \
@ -62,7 +62,7 @@ release-deb-armv7hf:
cp ../target/armv7-unknown-linux-gnueabihf/debian/*.deb /chirpstack/dist
release-deb-arm64:
apt update && apt install -y libpq-dev:arm64
apt-get install -y libpq-dev:arm64
mkdir -p /chirpstack/dist
BINDGEN_EXTRA_CLANG_ARGS="--sysroot=/usr/aarch64-linux-gnu" \
PKG_CONFIG_SYSROOT_DIR="/usr/aarch64-linux-gnu" \
@ -70,13 +70,13 @@ release-deb-arm64:
cp ../target/aarch64-unknown-linux-gnu/debian/*.deb /chirpstack/dist
release-rpm-amd64:
apt update && apt install -y libpq-dev:amd64
apt-get install -y libpq-dev:amd64
mkdir -p /chirpstack/dist
cargo rpm build
find ../target/release/rpmbuild/RPMS -type f -exec cp {} /chirpstack/dist \;
release-rpm-armv7hf:
apt update && apt install -y libpq-dev:armhf
apt-get install -y libpq-dev:armhf
mkdir -p /chirpstack/dist
BINDGEN_EXTRA_CLANG_ARGS="--sysroot=/usr/arm-linux-gnueabihf" \
PKG_CONFIG_SYSROOT_DIR="/usr/arm-linux-gnueabihf" \
@ -84,7 +84,7 @@ release-rpm-armv7hf:
find ../target/armv7-unknown-linux-gnueabihf/release/rpmbuild/RPMS -type f -exec cp {} /chirpstack/dist \;
release-rpm-arm64:
apt update && apt install -y libpq-dev:arm64
apt-get install -y libpq-dev:arm64
mkdir -p /chirpstack/dist
BINDGEN_EXTRA_CLANG_ARGS="--sysroot=/usr/aarch64-linux-gnu" \
PKG_CONFIG_SYSROOT_DIR="/usr/aarch64-linux-gnu" \

View File

@ -57,13 +57,13 @@
# 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=true
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. When left blank,
# a random id will be generated. This requires clean_session=true.
# 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)

View File

@ -57,13 +57,13 @@
# 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=true
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. When left blank,
# a random id will be generated. This requires clean_session=true.
# 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)

View File

@ -57,13 +57,13 @@
# 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=true
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. When left blank,
# a random id will be generated. This requires clean_session=true.
# 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)

View File

@ -57,13 +57,13 @@
# 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=true
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. When left blank,
# a random id will be generated. This requires clean_session=true.
# 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)

View File

@ -57,13 +57,13 @@
# 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=true
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. When left blank,
# a random id will be generated. This requires clean_session=true.
# 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)

View File

@ -57,13 +57,13 @@
# 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=true
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. When left blank,
# a random id will be generated. This requires clean_session=true.
# 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)

View File

@ -57,13 +57,13 @@
# 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=true
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. When left blank,
# a random id will be generated. This requires clean_session=true.
# 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)

View File

@ -57,13 +57,13 @@
# 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=true
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. When left blank,
# a random id will be generated. This requires clean_session=true.
# 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)

View File

@ -57,13 +57,13 @@
# 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=true
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. When left blank,
# a random id will be generated. This requires clean_session=true.
# 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)

View File

@ -57,13 +57,13 @@
# 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=true
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. When left blank,
# a random id will be generated. This requires clean_session=true.
# 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)

View File

@ -57,13 +57,13 @@
# 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=true
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. When left blank,
# a random id will be generated. This requires clean_session=true.
# 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)

View File

@ -57,13 +57,13 @@
# 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=true
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. When left blank,
# a random id will be generated. This requires clean_session=true.
# 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)

View File

@ -57,13 +57,13 @@
# 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=true
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. When left blank,
# a random id will be generated. This requires clean_session=true.
# 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)

View File

@ -57,13 +57,13 @@
# 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=true
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. When left blank,
# a random id will be generated. This requires clean_session=true.
# 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)

View File

@ -57,13 +57,13 @@
# 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=true
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. When left blank,
# a random id will be generated. This requires clean_session=true.
# 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)

View File

@ -57,13 +57,13 @@
# 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=true
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. When left blank,
# a random id will be generated. This requires clean_session=true.
# 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)

View File

@ -57,13 +57,13 @@
# 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=true
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. When left blank,
# a random id will be generated. This requires clean_session=true.
# 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)

View File

@ -57,13 +57,13 @@
# 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=true
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. When left blank,
# a random id will be generated. This requires clean_session=true.
# 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)

View File

@ -57,13 +57,13 @@
# 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=true
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. When left blank,
# a random id will be generated. This requires clean_session=true.
# 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)

View File

@ -57,13 +57,13 @@
# 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=true
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. When left blank,
# a random id will be generated. This requires clean_session=true.
# 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)

View File

@ -57,13 +57,13 @@
# 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=true
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. When left blank,
# a random id will be generated. This requires clean_session=true.
# 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)

View File

@ -57,13 +57,13 @@
# 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=true
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. When left blank,
# a random id will be generated. This requires clean_session=true.
# 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)

View File

@ -57,13 +57,13 @@
# 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=true
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. When left blank,
# a random id will be generated. This requires clean_session=true.
# 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)

View File

@ -57,13 +57,13 @@
# 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=true
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. When left blank,
# a random id will be generated. This requires clean_session=true.
# 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)

View File

@ -57,13 +57,13 @@
# 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=true
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. When left blank,
# a random id will be generated. This requires clean_session=true.
# 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)

View File

@ -57,13 +57,13 @@
# 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=true
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. When left blank,
# a random id will be generated. This requires clean_session=true.
# 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)

View File

@ -57,13 +57,13 @@
# 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=true
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. When left blank,
# a random id will be generated. This requires clean_session=true.
# 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)

View File

@ -52,10 +52,10 @@ impl Handler for Algorithm {
// Get median RSSI.
let med_rssi = get_median(&req.uplink_history);
// If the median RSSI is below -130, coding-rate 1/3 is recommended,
// If the median RSSI is below -130, coding-rate 2/6 is recommended,
// if we are on this coding-rate already, there is nothing to do.
if let lrwn::region::DataRateModulation::LrFhss(dr) = &current_dr {
if med_rssi < -130 && dr.coding_rate == "1/3" {
if med_rssi < -130 && dr.coding_rate == "2/6" {
return Ok(resp);
}
}
@ -85,7 +85,7 @@ impl Handler for Algorithm {
let mut drs: Vec<u8> = Vec::new();
// Select LR-FHSS data-rate with coding-rate 4/6 (if any available).
// Note: that for RSSI (median) < -130, coding-rate 1/3 is recommended.
// Note: that for RSSI (median) < -130, coding-rate 2/6 is recommended.
// As the median is taken from the uplink history, make sure that we
// take the median from a full history table.
if med_rssi >= -130 && req.uplink_history.len() == 20 {
@ -105,8 +105,8 @@ impl Handler for Algorithm {
);
}
// This either means coding-rate 1/3 must be used, or no data-rate with
// coding-rate 3/6 is enabled, and thus 1/3 is the only option.
// This either means coding-rate 2/6 must be used, or no data-rate with
// coding-rate 3/6 is enabled, and thus 2/6 is the only option.
if drs.is_empty() {
drs.extend_from_slice(
&lr_fhss_drs
@ -115,7 +115,7 @@ impl Handler for Algorithm {
.filter(|dr| {
let dr = region_conf.get_data_rate(*dr).unwrap();
if let lrwn::region::DataRateModulation::LrFhss(dr) = dr {
dr.coding_rate == "1/3"
dr.coding_rate == "2/6"
} else {
false
}
@ -135,7 +135,7 @@ impl Handler for Algorithm {
resp.dr = drs
.choose(&mut rand::thread_rng())
.cloned()
.ok_or(anyhow!("Random returned None"))?;
.ok_or_else(|| anyhow!("Random returned None"))?;
resp.nb_trans = 1; // 1 is the recommeded value
resp.tx_power_index = 0; // for now this ADR algorithm only controls the DR

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

@ -581,7 +581,7 @@ impl DeviceService for Device {
let start = SystemTime::try_from(
req.start
.as_ref()
.ok_or(anyhow!("start is None"))
.ok_or_else(|| anyhow!("start is None"))
.map_err(|e| e.status())?
.clone(),
)
@ -590,7 +590,7 @@ impl DeviceService for Device {
let end = SystemTime::try_from(
req.end
.as_ref()
.ok_or(anyhow!("end is None"))
.ok_or_else(|| anyhow!("end is None"))
.map_err(|e| e.status())?
.clone(),
)
@ -664,6 +664,13 @@ impl DeviceService for Device {
})
.collect(),
}],
kind: match v.kind {
fields::MeasurementKind::COUNTER => common::MetricKind::Counter,
fields::MeasurementKind::ABSOLUTE => common::MetricKind::Absolute,
fields::MeasurementKind::GAUGE => common::MetricKind::Gauge,
_ => common::MetricKind::Gauge,
}
.into(),
},
);
}
@ -690,7 +697,7 @@ impl DeviceService for Device {
let start = SystemTime::try_from(
req.start
.as_ref()
.ok_or(anyhow!("start is None"))
.ok_or_else(|| anyhow!("start is None"))
.map_err(|e| e.status())?
.clone(),
)
@ -699,7 +706,7 @@ impl DeviceService for Device {
let end = SystemTime::try_from(
req.end
.as_ref()
.ok_or(anyhow!("end is None"))
.ok_or_else(|| anyhow!("end is None"))
.map_err(|e| e.status())?
.clone(),
)
@ -737,6 +744,7 @@ impl DeviceService for Device {
.map(|row| row.metrics.get("rx_count").cloned().unwrap_or(0.0) as f32)
.collect(),
}],
kind: common::MetricKind::Absolute.into(),
}),
gw_rssi: Some(common::Metric {
name: "RSSI".to_string(),
@ -763,6 +771,7 @@ impl DeviceService for Device {
})
.collect(),
}],
kind: common::MetricKind::Absolute.into(),
}),
gw_snr: Some(common::Metric {
name: "SNR".to_string(),
@ -789,6 +798,7 @@ impl DeviceService for Device {
})
.collect(),
}],
kind: common::MetricKind::Absolute.into(),
}),
rx_packets_per_freq: Some({
// discover all data-sets
@ -826,6 +836,7 @@ impl DeviceService for Device {
.collect(),
})
.collect(),
kind: common::MetricKind::Absolute.into(),
}
}),
rx_packets_per_dr: Some({
@ -864,6 +875,7 @@ impl DeviceService for Device {
.collect(),
})
.collect(),
kind: common::MetricKind::Absolute.into(),
}
}),
errors: Some({
@ -902,6 +914,7 @@ impl DeviceService for Device {
.collect(),
})
.collect(),
kind: common::MetricKind::Absolute.into(),
}
}),
};

View File

@ -279,7 +279,7 @@ impl GatewayService for Gateway {
let start = SystemTime::try_from(
req.start
.as_ref()
.ok_or(anyhow!("start is None"))
.ok_or_else(|| anyhow!("start is None"))
.map_err(|e| e.status())?
.clone(),
)
@ -288,7 +288,7 @@ impl GatewayService for Gateway {
let end = SystemTime::try_from(
req.end
.as_ref()
.ok_or(anyhow!("end is None"))
.ok_or_else(|| anyhow!("end is None"))
.map_err(|e| e.status())?
.clone(),
)
@ -326,6 +326,7 @@ impl GatewayService for Gateway {
.map(|row| row.metrics.get("rx_count").cloned().unwrap_or(0.0) as f32)
.collect(),
}],
kind: common::MetricKind::Absolute.into(),
}),
tx_packets: Some(common::Metric {
name: "Transmitted".to_string(),
@ -344,6 +345,7 @@ impl GatewayService for Gateway {
.map(|row| row.metrics.get("tx_count").cloned().unwrap_or(0.0) as f32)
.collect(),
}],
kind: common::MetricKind::Absolute.into(),
}),
tx_packets_per_freq: Some({
// discover all data-sets
@ -381,6 +383,7 @@ impl GatewayService for Gateway {
.collect(),
})
.collect(),
kind: common::MetricKind::Absolute.into(),
}
}),
rx_packets_per_freq: Some({
@ -419,6 +422,7 @@ impl GatewayService for Gateway {
.collect(),
})
.collect(),
kind: common::MetricKind::Absolute.into(),
}
}),
rx_packets_per_dr: Some({
@ -457,6 +461,7 @@ impl GatewayService for Gateway {
.collect(),
})
.collect(),
kind: common::MetricKind::Absolute.into(),
}
}),
tx_packets_per_dr: Some({
@ -495,6 +500,7 @@ impl GatewayService for Gateway {
.collect(),
})
.collect(),
kind: common::MetricKind::Absolute.into(),
}
}),
tx_packets_per_status: Some({
@ -533,6 +539,7 @@ impl GatewayService for Gateway {
.collect(),
})
.collect(),
kind: common::MetricKind::Absolute.into(),
}
}),
};
@ -781,6 +788,7 @@ pub mod test {
label: "rx_count".to_string(),
data: vec![10.0],
}],
kind: common::MetricKind::Absolute.into(),
}),
stats_resp.rx_packets
);

View File

@ -75,17 +75,6 @@ pub async fn callback_handler(args: CallbackArgs) -> Result<impl Reply, Rejectio
))
}
fn handle_error<T: std::error::Error>(fail: &T, msg: &'static str) {
let mut err_msg = format!("ERROR: {}", msg);
let mut cur_fail: Option<&dyn std::error::Error> = Some(fail);
while let Some(cause) = cur_fail {
err_msg += &format!("\n caused by: {}", cause);
cur_fail = cause.source();
}
println!("{}", err_msg);
panic!("boom");
}
pub async fn get_user(code: &str, state: &str) -> Result<User> {
let state = CsrfToken::new(state.to_string());
let nonce = get_nonce(&state).await?;
@ -94,11 +83,7 @@ pub async fn get_user(code: &str, state: &str) -> Result<User> {
let token_response = client
.exchange_code(AuthorizationCode::new(code.to_string()))
.request_async(async_http_client)
.await
.unwrap_or_else(|err| {
handle_error(&err, "token extahcnage");
unreachable!();
});
.await?;
let id_token_verifier: CoreIdTokenVerifier = client.id_token_verifier();
let _id_token_claims: &CoreIdTokenClaims = token_response

View File

@ -289,7 +289,9 @@ pub fn ul_meta_data_to_tx_info(ul_meta_data: &ULMetaData) -> Result<gw::UplinkTx
lrwn::region::DataRateModulation::LrFhss(v) => {
gw::modulation::Parameters::LrFhss(gw::LrFhssModulationInfo {
operating_channel_width: v.occupied_channel_width,
code_rate: v.coding_rate,
code_rate: gw::CodeRate::from_str(&v.coding_rate)
.map_err(|e| anyhow!("{}", e))?
.into(),
// GridSteps: this value can't be derived from a DR?
..Default::default()
})

View File

@ -96,13 +96,13 @@ 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 }}"
# Network related configuration.
@ -127,6 +127,14 @@ pub fn run() {
# after no activity.
device_session_ttl="{{ network.device_session_ttl }}"
# Time to wait for uplink de-duplication.
#
# This is the time that ChirpStack will wait for other gateways to receive
# the same uplink frame. Please note that this value affects the
# roundtrip time. The total roundtrip time (which includes network latency)
# must be less than the (first) receive-window.
deduplication_delay="{{ network.deduplication_delay }}"
# Mac-commands disabled.
mac_commands_disabled={{ network.mac_commands_disabled }}
@ -308,8 +316,8 @@ pub fn run() {
# 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. When left blank,
# a random id will be generated. This requires clean_session=true.
# broker. A client id must be no longer than 23 characters. If left blank,
# a random id will be generated by ChirpStack.
client_id="{{ integration.mqtt.client_id }}"
# CA certificate file (optional)
@ -326,6 +334,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

@ -717,9 +717,18 @@ impl CayenneLpp {
};
if let Some(prost_types::value::Kind::StructValue(s)) = &v.kind {
let x = s.fields.get("x").ok_or(anyhow!("x field is missing"))?;
let y = s.fields.get("y").ok_or(anyhow!("y field is missing"))?;
let z = s.fields.get("z").ok_or(anyhow!("z field is missing"))?;
let x = s
.fields
.get("x")
.ok_or_else(|| anyhow!("x field is missing"))?;
let y = s
.fields
.get("y")
.ok_or_else(|| anyhow!("y field is missing"))?;
let z = s
.fields
.get("z")
.ok_or_else(|| anyhow!("z field is missing"))?;
if let Some(prost_types::value::Kind::NumberValue(v)) = &x.kind {
item.x = *v;
@ -789,9 +798,18 @@ impl CayenneLpp {
};
if let Some(prost_types::value::Kind::StructValue(s)) = &v.kind {
let x = s.fields.get("x").ok_or(anyhow!("x field is missing"))?;
let y = s.fields.get("y").ok_or(anyhow!("y field is missing"))?;
let z = s.fields.get("z").ok_or(anyhow!("z field is missing"))?;
let x = s
.fields
.get("x")
.ok_or_else(|| anyhow!("x field is missing"))?;
let y = s
.fields
.get("y")
.ok_or_else(|| anyhow!("y field is missing"))?;
let z = s
.fields
.get("z")
.ok_or_else(|| anyhow!("z field is missing"))?;
if let Some(prost_types::value::Kind::NumberValue(v)) = &x.kind {
item.x = *v;
@ -849,15 +867,15 @@ impl CayenneLpp {
let lat = s
.fields
.get("latitude")
.ok_or(anyhow!("latitude field is missing"))?;
.ok_or_else(|| anyhow!("latitude field is missing"))?;
let lon = s
.fields
.get("longitude")
.ok_or(anyhow!("longitude field is missing"))?;
.ok_or_else(|| anyhow!("longitude field is missing"))?;
let alt = s
.fields
.get("altitude")
.ok_or(anyhow!("altitude field is missing"))?;
.ok_or_else(|| anyhow!("altitude field is missing"))?;
if let Some(prost_types::value::Kind::NumberValue(v)) = &lat.kind {
item.latitude = *v;

View File

@ -151,6 +151,8 @@ pub struct Network {
pub enabled_regions: Vec<String>,
#[serde(with = "humantime_serde")]
pub device_session_ttl: Duration,
#[serde(with = "humantime_serde")]
pub deduplication_delay: Duration,
pub mac_commands_disabled: bool,
pub adr_plugins: Vec<String>,
pub scheduler: Scheduler,
@ -162,6 +164,7 @@ impl Default for Network {
net_id: NetID::from_be_bytes([0x00, 0x00, 0x00]),
enabled_regions: vec!["eu868".into()],
device_session_ttl: Duration::from_secs(60 * 60 * 24 * 31),
deduplication_delay: Duration::from_millis(200),
mac_commands_disabled: false,
adr_plugins: vec![],
scheduler: Default::default(),
@ -277,7 +280,7 @@ impl Default for MqttIntegration {
username: "".into(),
password: "".into(),
qos: 0,
clean_session: true,
clean_session: false,
client_id: "".into(),
ca_cert: "".into(),
tls_cert: "".into(),
@ -529,7 +532,7 @@ impl Default for Region {
command_topic: "eu868/gateway/{{ gateway_id }}/command/{{ command }}"
.into(),
server: "tcp://127.0.0.1:1883".into(),
clean_session: true,
clean_session: false,
..Default::default()
},
},

View File

@ -557,6 +557,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.

View File

@ -44,11 +44,11 @@ impl Data {
let region_name = uplink_rx_info[0]
.get_metadata_string("region_name")
.ok_or(anyhow!("No region_name in metadata"))?;
.ok_or_else(|| anyhow!("No region_name in metadata"))?;
let region_common_name = uplink_rx_info[0]
.get_metadata_string("region_common_name")
.ok_or(anyhow!("No region_common_name in metadata"))?;
.ok_or_else(|| anyhow!("No region_common_name in metadata"))?;
let region_common_name = CommonName::from_str(&region_common_name)?;
let mut ctx = Data {
@ -78,7 +78,7 @@ impl Data {
.uplink_rx_info
.first()
.cloned()
.ok_or(anyhow!("rx_info is empty"))?;
.ok_or_else(|| anyhow!("rx_info is empty"))?;
self.downlink_frame.gateway_id = rx_info.gateway_id.clone();
if self.dl_meta_data.dl_freq_1.is_some()

View File

@ -77,7 +77,7 @@ impl Multicast {
let region_name = &*(gw.properties)
.get("region_name")
.cloned()
.ok_or(anyhow!("Gateway does not have region_name property"))?;
.ok_or_else(|| anyhow!("Gateway does not have region_name property"))?;
self.region_name = region_name.to_string();
Ok(())

View File

@ -126,7 +126,7 @@ impl TxAck {
let gw_df = &df
.downlink_frame
.as_ref()
.ok_or(anyhow!("downlink_frame is None"))?;
.ok_or_else(|| anyhow!("downlink_frame is None"))?;
// Validate that we don't receive more ack items than downlink items that were
// sent to the gateway. Receiving less acks is valid, e.g. the gateway might
@ -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;
@ -384,7 +384,7 @@ impl TxAck {
let gw_df = df
.downlink_frame
.as_ref()
.ok_or(anyhow!("downlink_frame is None"))?;
.ok_or_else(|| anyhow!("downlink_frame is None"))?;
let dfi = self.downlink_frame_item.as_ref().unwrap();
let phy = self.phy_payload.as_mut().unwrap();
@ -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,4 +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};
@ -10,12 +15,16 @@ use prometheus_client::encoding::text::Encode;
use prometheus_client::metrics::counter::Counter;
use prometheus_client::metrics::family::Family;
use prost::Message;
use rand::Rng;
use serde::Serialize;
use tokio::sync::mpsc;
use tokio::task;
use tracing::{error, info, trace};
use super::GatewayBackend;
use crate::config::GatewayBackendMqtt;
use crate::monitoring::prometheus;
use crate::storage::{get_redis_conn, redis_key};
use crate::{downlink, uplink};
use lrwn::region::CommonName;
@ -48,6 +57,7 @@ lazy_static! {
);
counter
};
static ref GATEWAY_JSON: RwLock<HashMap<String, bool>> = RwLock::new(HashMap::new());
}
struct MqttContext {
@ -77,18 +87,57 @@ impl<'a> MqttBackend<'a> {
let mut templates = Handlebars::new();
templates.register_template_string("command_topic", &conf.command_topic)?;
// get client id, this will generate a random client_id when no client_id has been
// configured.
let client_id = if conf.client_id.is_empty() {
let mut rnd = rand::thread_rng();
let client_id: u64 = rnd.gen();
format!("{:x}", client_id)
} else {
conf.client_id.clone()
};
// Create subscribe channel
// This is needed as we can't subscribe within the set_connected_callback as this would
// block the callback (we want to wait for success or error), which would create a
// deadlock. We need to re-subscribe on (re)connect to be sure we have a subscription. Even
// in case of a persistent MQTT session, there is no guarantee that the MQTT persisted the
// session and that a re-connect would recover the subscription.
let (subscribe_tx, mut subscribe_rx) = mpsc::channel(10);
// create client
let create_opts = mqtt::CreateOptionsBuilder::new()
.server_uri(&conf.server)
.client_id(&conf.client_id)
.client_id(&client_id)
.user_data(Box::new(MqttContext {
region_name: region_name.to_string(),
region_common_name,
}))
.persistence(mqtt::create_options::PersistenceType::FilePath(temp_dir()))
.finalize();
let mut client = mqtt::AsyncClient::new(create_opts).context("Create MQTT client")?;
client.set_connected_callback(connected_callback);
client.set_connection_lost_callback(connection_lost_callback);
client.set_connected_callback(move |client| {
let ctx = client
.user_data()
.unwrap()
.downcast_ref::<MqttContext>()
.unwrap();
info!(region_name = %ctx.region_name, "Connected to MQTT broker");
if let Err(e) = subscribe_tx.try_send(()) {
error!(region_name = %ctx.region_name, error = %e, "Send to subscribe channel error");
}
});
client.set_connection_lost_callback(|client| {
let ctx = client
.user_data()
.unwrap()
.downcast_ref::<MqttContext>()
.unwrap();
info!(region_name = %ctx.region_name, "MQTT connection to broker lost");
});
// connection options
let mut conn_opts_b = mqtt::ConnectOptionsBuilder::new();
@ -138,24 +187,13 @@ impl<'a> MqttBackend<'a> {
};
// connect
info!(
server_uri = conf.server.as_str(),
"Connecting to MQTT broker"
);
info!(region_name = %region_name, server_uri = %conf.server, clean_session = conf.clean_session, client_id = %client_id, "Connecting to MQTT broker");
b.client
.connect(conn_opts)
.await
.context("Connect to MQTT broker")?;
info!(
event_topic = conf.event_topic.as_str(),
"Subscribing to gateway event topic"
);
b.client
.subscribe(&conf.event_topic, conf.qos as i32)
.await
.context("MQTT subscribe error")?;
// Consumer loop.
tokio::spawn({
let region_name = region_name.to_string();
@ -169,6 +207,23 @@ impl<'a> MqttBackend<'a> {
}
});
// (Re)subscribe loop.
tokio::spawn({
let region_name = region_name.to_string();
let event_topic = conf.event_topic.clone();
let client = b.client.clone();
let qos = conf.qos as i32;
async move {
while subscribe_rx.recv().await.is_some() {
info!(region_name = %region_name, event_topic = %event_topic, "Subscribing to gateway event topic");
if let Err(e) = client.subscribe(&event_topic, qos).await {
error!(region_name = %region_name, event_topic = %event_topic, error = %e, "MQTT subscribe error");
}
}
}
});
// return backend
Ok(b)
}
@ -195,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");
@ -215,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");
@ -231,24 +295,46 @@ async fn message_callback(region_name: &str, region_common_name: CommonName, msg
let qos = msg.qos();
let b = msg.payload();
info!(
region_name = region_name,
topic = topic,
qos = qos,
"Message received from gateway"
);
let mut hasher = DefaultHasher::new();
hasher.write(b);
let key = redis_key(format!("gw:mqtt:lock:{:x}", hasher.finish()));
let locked = is_locked(key).await;
let err = || -> Result<()> {
if locked? {
trace!(
region_name = region_name,
topic = topic,
qos = qos,
"Message is already handled by different instance"
);
return Ok(());
}
let json = payload_is_json(b);
info!(
region_name = region_name,
topic = topic,
qos = qos,
json = json,
"Message received from gateway"
);
if topic.ends_with("/up") {
EVENT_COUNTER
.get_or_create(&EventLabels {
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());
}
@ -260,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());
@ -268,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
@ -275,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"));
@ -296,28 +391,35 @@ async fn message_callback(region_name: &str, region_common_name: CommonName, msg
}
}
fn connected_callback(client: &mqtt::AsyncClient) {
let ctx = client
.user_data()
.unwrap()
.downcast_ref::<MqttContext>()
.unwrap();
async fn is_locked(key: String) -> Result<bool> {
task::spawn_blocking({
move || -> Result<bool> {
let mut c = get_redis_conn()?;
info!(
region_name = ctx.region_name.as_str(),
"Connected to MQTT broker"
);
let set: bool = redis::cmd("SET")
.arg(key)
.arg("lock")
.arg("PX")
.arg(5000)
.arg("NX")
.query(&mut *c)?;
Ok(!set)
}
})
.await?
}
fn connection_lost_callback(client: &mqtt::AsyncClient) {
let ctx = client
.user_data()
.unwrap()
.downcast_ref::<MqttContext>()
.unwrap();
info!(
region_name = ctx.region_name.as_str(),
"MQTT connection to broker lost"
);
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

@ -68,7 +68,9 @@ impl Integration {
let client = aws_sdk_sns::Client::new(&config);
Ok(Integration {
json: match Encoding::from_i32(conf.encoding).ok_or(anyhow!("Invalid encoding"))? {
json: match Encoding::from_i32(conf.encoding)
.ok_or_else(|| anyhow!("Invalid encoding"))?
{
Encoding::Json => true,
Encoding::Protobuf => false,
},

View File

@ -32,7 +32,9 @@ impl Integration {
Ok(Integration {
timeout: Duration::from_secs(5),
json: match Encoding::from_i32(conf.encoding).ok_or(anyhow!("Invalid encoding"))? {
json: match Encoding::from_i32(conf.encoding)
.ok_or_else(|| anyhow!("Invalid encoding"))?
{
Encoding::Json => true,
Encoding::Protobuf => false,
},

View File

@ -48,7 +48,9 @@ impl Integration {
let auth_manager = AuthenticationManager::from(service_account);
Ok(Integration {
json: match Encoding::from_i32(conf.encoding).ok_or(anyhow!("Invalid encoding"))? {
json: match Encoding::from_i32(conf.encoding)
.ok_or_else(|| anyhow!("Invalid encoding"))?
{
Encoding::Json => true,
Encoding::Protobuf => false,
},

View File

@ -38,13 +38,14 @@ impl Integration {
Ok(Integration {
timeout: Duration::from_secs(5),
endpoint: conf.endpoint.clone(),
version: InfluxDbVersion::from_i32(conf.version).ok_or(anyhow!("Invalid version"))?,
version: InfluxDbVersion::from_i32(conf.version)
.ok_or_else(|| anyhow!("Invalid version"))?,
db: conf.db.clone(),
username: conf.username.clone(),
password: conf.password.clone(),
retention_policy_name: conf.retention_policy_name.clone(),
precision: match InfluxDbPrecision::from_i32(conf.precision)
.ok_or(anyhow!("Invalid precision"))?
.ok_or_else(|| anyhow!("Invalid precision"))?
{
InfluxDbPrecision::Ns => "ns",
InfluxDbPrecision::U => "u",

View File

@ -201,7 +201,7 @@ pub async fn uplink_event(
}
for e in join_all(futures).await {
let _ = e?;
e?;
}
Ok(())
@ -226,7 +226,7 @@ pub async fn join_event(
}
for e in join_all(futures).await {
let _ = e?;
e?;
}
Ok(())
@ -251,7 +251,7 @@ pub async fn ack_event(
}
for e in join_all(futures).await {
let _ = e?;
e?;
}
Ok(())
@ -276,7 +276,7 @@ pub async fn txack_event(
}
for e in join_all(futures).await {
let _ = e?;
e?;
}
Ok(())
@ -301,7 +301,7 @@ pub async fn log_event(
}
for e in join_all(futures).await {
let _ = e?;
e?;
}
Ok(())
@ -326,7 +326,7 @@ pub async fn status_event(
}
for e in join_all(futures).await {
let _ = e?;
e?;
}
Ok(())
@ -351,7 +351,7 @@ pub async fn location_event(
}
for e in join_all(futures).await {
let _ = e?;
e?;
}
Ok(())
@ -376,7 +376,7 @@ pub async fn integration_event(
}
for e in join_all(futures).await {
let _ = e?;
e?;
}
Ok(())
@ -423,7 +423,7 @@ async fn handle_down_command(application_id: String, pl: integration::DownlinkCo
..Default::default()
};
let _ = device_queue::enqueue_item(qi).await?;
device_queue::enqueue_item(qi).await?;
Ok(())
}

View File

@ -1,4 +1,5 @@
use std::collections::HashMap;
use std::env::temp_dir;
use std::io::Cursor;
use std::time::Duration;
@ -8,8 +9,10 @@ use futures::stream::StreamExt;
use handlebars::Handlebars;
use paho_mqtt as mqtt;
use prost::Message;
use rand::Rng;
use regex::Regex;
use serde::Serialize;
use tokio::sync::mpsc;
use tracing::{error, info};
use super::Integration as IntegrationTrait;
@ -48,14 +51,49 @@ impl<'a> Integration<'a> {
templates.register_template_string("event_topic", &conf.event_topic)?;
templates.register_template_string("command_topic", &conf.command_topic)?;
let command_topic = templates.render(
"command_topic",
&CommandTopicContext {
application_id: "+".into(),
dev_eui: "+".into(),
command: "+".into(),
},
)?;
// get client id, this will generate a random client_id when no client_id has been
// configured.
let client_id = if conf.client_id.is_empty() {
let mut rnd = rand::thread_rng();
let client_id: u64 = rnd.gen();
format!("{:x}", client_id)
} else {
conf.client_id.clone()
};
// Create subscribe channel
// This is needed as we can't subscribe within the set_connected_callback as this would
// block the callback (we want to wait for success or error), which would create a
// deadlock. We need to re-subscribe on (re)connect to be sure we have a subscription. Even
// in case of a persistent MQTT session, there is no guarantee that the MQTT persisted the
// session and that a re-connect would recover the subscription.
let (subscribe_tx, mut subscribe_rx) = mpsc::channel(10);
// create client
let create_opts = mqtt::CreateOptionsBuilder::new()
.server_uri(&conf.server)
.client_id(&conf.client_id)
.client_id(&client_id)
.persistence(mqtt::create_options::PersistenceType::FilePath(temp_dir()))
.finalize();
let mut client = mqtt::AsyncClient::new(create_opts).context("Create MQTT client")?;
client.set_connected_callback(connected_callback);
client.set_connection_lost_callback(connection_lost_callback);
client.set_connected_callback(move |_client| {
info!("Connected to MQTT broker");
if let Err(e) = subscribe_tx.try_send(()) {
error!(error = %e, "Send to subscribe channel error");
}
});
client.set_connection_lost_callback(|_client| {
error!("MQTT connection to broker lost");
});
// connection options
let mut conn_opts_b = mqtt::ConnectOptionsBuilder::new();
@ -114,29 +152,13 @@ impl<'a> Integration<'a> {
};
// connect
info!(server_uri = %conf.server, "Connecting to MQTT broker");
info!(server_uri = %conf.server, client_id = %client_id, clean_session = conf.clean_session, "Connecting to MQTT broker");
i.client
.connect(conn_opts)
.await
.context("Connect to MQTT broker")?;
let command_topic = i.templates.render(
"command_topic",
&CommandTopicContext {
application_id: "+".into(),
dev_eui: "+".into(),
command: "+".into(),
},
)?;
info!(
command_topic = %command_topic,
"Subscribing to command topic"
);
i.client
.subscribe(&command_topic, conf.qos as i32)
.await
.context("MQTT subscribe")?;
// Command consume loop.
tokio::spawn({
let command_regex = i.command_regex.clone();
@ -169,6 +191,21 @@ impl<'a> Integration<'a> {
}
});
// (Re)subscribe loop.
tokio::spawn({
let client = i.client.clone();
let qos = conf.qos as i32;
async move {
while subscribe_rx.recv().await.is_some() {
info!(command_topic = %command_topic, "Subscribing to command topic");
if let Err(e) = client.subscribe(&command_topic, qos).await {
error!(error = %e, "MQTT subscribe error");
}
}
}
});
// Return integration.
Ok(i)
}
@ -202,7 +239,7 @@ impl IntegrationTrait for Integration<'_> {
let dev_info = pl
.device_info
.as_ref()
.ok_or(anyhow!("device_info is None"))?;
.ok_or_else(|| anyhow!("device_info is None"))?;
let topic = self.get_event_topic(&dev_info.application_id, &dev_info.dev_eui, "up")?;
let b = match self.json {
@ -221,7 +258,7 @@ impl IntegrationTrait for Integration<'_> {
let dev_info = pl
.device_info
.as_ref()
.ok_or(anyhow!("device_info is None"))?;
.ok_or_else(|| anyhow!("device_info is None"))?;
let topic = self.get_event_topic(&dev_info.application_id, &dev_info.dev_eui, "join")?;
let b = match self.json {
@ -240,7 +277,7 @@ impl IntegrationTrait for Integration<'_> {
let dev_info = pl
.device_info
.as_ref()
.ok_or(anyhow!("device_info is None"))?;
.ok_or_else(|| anyhow!("device_info is None"))?;
let topic = self.get_event_topic(&dev_info.application_id, &dev_info.dev_eui, "ack")?;
let b = match self.json {
@ -259,7 +296,7 @@ impl IntegrationTrait for Integration<'_> {
let dev_info = pl
.device_info
.as_ref()
.ok_or(anyhow!("device_info is None"))?;
.ok_or_else(|| anyhow!("device_info is None"))?;
let topic = self.get_event_topic(&dev_info.application_id, &dev_info.dev_eui, "txack")?;
let b = match self.json {
@ -278,7 +315,7 @@ impl IntegrationTrait for Integration<'_> {
let dev_info = pl
.device_info
.as_ref()
.ok_or(anyhow!("device_info is None"))?;
.ok_or_else(|| anyhow!("device_info is None"))?;
let topic = self.get_event_topic(&dev_info.application_id, &dev_info.dev_eui, "log")?;
let b = match self.json {
@ -297,7 +334,7 @@ impl IntegrationTrait for Integration<'_> {
let dev_info = pl
.device_info
.as_ref()
.ok_or(anyhow!("device_info is None"))?;
.ok_or_else(|| anyhow!("device_info is None"))?;
let topic = self.get_event_topic(&dev_info.application_id, &dev_info.dev_eui, "status")?;
let b = match self.json {
@ -316,7 +353,7 @@ impl IntegrationTrait for Integration<'_> {
let dev_info = pl
.device_info
.as_ref()
.ok_or(anyhow!("device_info is None"))?;
.ok_or_else(|| anyhow!("device_info is None"))?;
let topic =
self.get_event_topic(&dev_info.application_id, &dev_info.dev_eui, "location")?;
@ -336,7 +373,7 @@ impl IntegrationTrait for Integration<'_> {
let dev_info = pl
.device_info
.as_ref()
.ok_or(anyhow!("device_info is None"))?;
.ok_or_else(|| anyhow!("device_info is None"))?;
let topic =
self.get_event_topic(&dev_info.application_id, &dev_info.dev_eui, "integration")?;
@ -349,14 +386,6 @@ impl IntegrationTrait for Integration<'_> {
}
}
fn connected_callback(_: &mqtt::AsyncClient) {
info!("Connected to MQTT broker");
}
fn connection_lost_callback(_: &mqtt::AsyncClient) {
info!("Connection to MQTT broker lost");
}
async fn message_callback(
application_id: String,
dev_eui: String,

View File

@ -28,7 +28,7 @@ impl IntegrationTrait for Integration {
let dev_info = pl
.device_info
.as_ref()
.ok_or(anyhow!("device_info is None"))?;
.ok_or_else(|| anyhow!("device_info is None"))?;
let b = pl.encode_to_vec();
eventlog::log_event_for_device("up", &dev_info.dev_eui, &b).await
}
@ -41,7 +41,7 @@ impl IntegrationTrait for Integration {
let dev_info = pl
.device_info
.as_ref()
.ok_or(anyhow!("device_info is None"))?;
.ok_or_else(|| anyhow!("device_info is None"))?;
let b = pl.encode_to_vec();
eventlog::log_event_for_device("join", &dev_info.dev_eui, &b).await
}
@ -54,7 +54,7 @@ impl IntegrationTrait for Integration {
let dev_info = pl
.device_info
.as_ref()
.ok_or(anyhow!("device_info is None"))?;
.ok_or_else(|| anyhow!("device_info is None"))?;
let b = pl.encode_to_vec();
eventlog::log_event_for_device("ack", &dev_info.dev_eui, &b).await
}
@ -67,7 +67,7 @@ impl IntegrationTrait for Integration {
let dev_info = pl
.device_info
.as_ref()
.ok_or(anyhow!("device_info is None"))?;
.ok_or_else(|| anyhow!("device_info is None"))?;
let b = pl.encode_to_vec();
eventlog::log_event_for_device("txack", &dev_info.dev_eui, &b).await
}
@ -80,7 +80,7 @@ impl IntegrationTrait for Integration {
let dev_info = pl
.device_info
.as_ref()
.ok_or(anyhow!("device_info is None"))?;
.ok_or_else(|| anyhow!("device_info is None"))?;
let b = pl.encode_to_vec();
eventlog::log_event_for_device("log", &dev_info.dev_eui, &b).await
}
@ -93,7 +93,7 @@ impl IntegrationTrait for Integration {
let dev_info = pl
.device_info
.as_ref()
.ok_or(anyhow!("device_info is None"))?;
.ok_or_else(|| anyhow!("device_info is None"))?;
let b = pl.encode_to_vec();
eventlog::log_event_for_device("status", &dev_info.dev_eui, &b).await
}
@ -106,7 +106,7 @@ impl IntegrationTrait for Integration {
let dev_info = pl
.device_info
.as_ref()
.ok_or(anyhow!("device_info is None"))?;
.ok_or_else(|| anyhow!("device_info is None"))?;
let b = pl.encode_to_vec();
eventlog::log_event_for_device("location", &dev_info.dev_eui, &b).await
}
@ -119,7 +119,7 @@ impl IntegrationTrait for Integration {
let dev_info = pl
.device_info
.as_ref()
.ok_or(anyhow!("device_info is None"))?;
.ok_or_else(|| anyhow!("device_info is None"))?;
let b = pl.encode_to_vec();
eventlog::log_event_for_device("integration", &dev_info.dev_eui, &b).await
}

View File

@ -23,7 +23,9 @@ pub async fn handle(
dev: &device::Device,
block: &lrwn::MACCommandSet,
) -> Result<Option<lrwn::MACCommandSet>> {
let mac = (&**block).first().ok_or(anyhow!("Expected DevStatusAns"))?;
let mac = (&**block)
.first()
.ok_or_else(|| anyhow!("Expected DevStatusAns"))?;
if let lrwn::MACCommand::DevStatusAns(pl) = mac {
info!(dev_eui = %dev.dev_eui, battery = pl.battery, margin = pl.margin, "DevStatusAns received");

View File

@ -8,7 +8,7 @@ pub async fn handle(
) -> Result<Option<lrwn::MACCommandSet>> {
let mac = (&**block)
.first()
.ok_or(anyhow!("Expected DeviceModeInd"))?;
.ok_or_else(|| anyhow!("Expected DeviceModeInd"))?;
if let lrwn::MACCommand::DeviceModeInd(pl) = mac {
device::set_enabled_class(&dev.dev_eui, &pl.class.to_string()).await?;

View File

@ -15,7 +15,7 @@ pub fn handle(
) -> Result<Option<lrwn::MACCommandSet>> {
let _ = (&**block)
.first()
.ok_or(anyhow!("Expected DeviceTimeReq"))?;
.ok_or_else(|| anyhow!("Expected DeviceTimeReq"))?;
let rx_time: DateTime<Utc> = helpers::get_rx_timestamp(&uplink_frame_set.rx_info_set).into();
let gps_time = rx_time.to_gps_time();

View File

@ -11,7 +11,9 @@ pub fn handle(
dev: &device::Device,
block: &lrwn::MACCommandSet,
) -> Result<Option<lrwn::MACCommandSet>> {
let _ = (&**block).first().ok_or(anyhow!("Expected LinkCheckReq"));
let _ = (&**block)
.first()
.ok_or_else(|| anyhow!("Expected LinkCheckReq"));
info!(dev_eui = %dev.dev_eui, "Received LinkCheckReq");
@ -19,11 +21,11 @@ pub fn handle(
.tx_info
.modulation
.as_ref()
.ok_or(anyhow!("modulation can not be None"))?;
.ok_or_else(|| anyhow!("modulation can not be None"))?;
let mod_params = mod_info
.parameters
.as_ref()
.ok_or(anyhow!("parameters can not be None"))?;
.ok_or_else(|| anyhow!("parameters can not be None"))?;
if let gw::modulation::Parameters::Lora(pl) = mod_params {
let required_snr = config::get_required_snr_for_sf(pl.spreading_factor as u8)?;

View File

@ -23,16 +23,18 @@ pub fn handle(
let block_macs = &**block;
let pending_macs = &**pending.unwrap();
let req_pl = if let lrwn::MACCommand::PingSlotChannelReq(pl) =
pending_macs.first().ok_or(anyhow!("Empty MACCommandSet"))?
let req_pl = if let lrwn::MACCommand::PingSlotChannelReq(pl) = pending_macs
.first()
.ok_or_else(|| anyhow!("Empty MACCommandSet"))?
{
pl
} else {
return Err(anyhow!("Expected PingSlotChannelReq"));
};
let ans_pl = if let lrwn::MACCommand::PingSlotChannelAns(pl) =
block_macs.first().ok_or(anyhow!("Empty MACCommandSet"))?
let ans_pl = if let lrwn::MACCommand::PingSlotChannelAns(pl) = block_macs
.first()
.ok_or_else(|| anyhow!("Empty MACCommandSet"))?
{
pl
} else {

View File

@ -11,7 +11,7 @@ pub fn handle(
) -> Result<Option<lrwn::MACCommandSet>> {
let mac = (&**block)
.first()
.ok_or(anyhow!("MACCommandSet is empty"))?;
.ok_or_else(|| anyhow!("MACCommandSet is empty"))?;
let pl = if let lrwn::MACCommand::PingSlotInfoReq(pl) = &mac {
pl

View File

@ -25,10 +25,10 @@ pub fn handle(
let ans_mac = (&**block)
.first()
.ok_or(anyhow!("MACCommandSet is empty"))?;
.ok_or_else(|| anyhow!("MACCommandSet is empty"))?;
let req_mac = (&**pending.unwrap())
.first()
.ok_or(anyhow!("MACCommandSet is empty"))?;
.ok_or_else(|| anyhow!("MACCommandSet is empty"))?;
let req_pl = if let lrwn::MACCommand::RejoinParamSetupReq(pl) = req_mac {
pl

View File

@ -11,7 +11,7 @@ pub fn handle(
) -> Result<Option<lrwn::MACCommandSet>> {
let block_mac = (&**block)
.first()
.ok_or(anyhow!("MACCommandSet is empty"))?;
.ok_or_else(|| anyhow!("MACCommandSet is empty"))?;
let req_pl = if let lrwn::MACCommand::RekeyInd(pl) = block_mac {
pl

Some files were not shown because too many files have changed in this diff Show More