Compare commits

...

7 Commits

Author SHA1 Message Date
532392abe1 Fix dev_nonces migration. 2024-11-13 11:42:08 +00:00
41b3c6a4e4 Implement support for storing DevNonces per JoinEUI. 2024-11-13 09:33:16 +00:00
4b6391f57e Bump version to 4.10.1 2024-11-04 15:20:07 +00:00
ed11c88307 Bump version to 4.10.1-test.1 2024-11-04 12:33:08 +00:00
0ed78a1d0a Fix incorrect systemd service-name after #540.
Currently, cargo-deb does not use the variant name option as systemd
service-name, causing the postgres variant with name 'chirpstack' to
install a 'chirpstack-postgres' systemd service. See also
https://github.com/kornelski/cargo-deb/issues/150.

This also fixes the RPM systemd service-name for the sqlite variant.
2024-11-04 12:19:19 +00:00
fdf168bd09 Bump version to 4.10.0 2024-11-04 09:09:44 +00:00
dddb471878 Update dependencies. 2024-11-01 13:45:59 +00:00
28 changed files with 185 additions and 167 deletions

120
Cargo.lock generated
View File

@ -160,9 +160,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.91"
version = "1.0.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8"
checksum = "74f37166d7d48a0284b99dd824694c26119c700b53bf0d1540cdb147dbdaaf13"
[[package]]
name = "approx"
@ -212,7 +212,7 @@ checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.85",
"syn 2.0.86",
"synstructure",
]
@ -224,7 +224,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.85",
"syn 2.0.86",
]
[[package]]
@ -279,7 +279,7 @@ dependencies = [
"async-task",
"concurrent-queue",
"fastrand 2.1.1",
"futures-lite 2.3.0",
"futures-lite 2.4.0",
"slab",
]
@ -294,7 +294,7 @@ dependencies = [
"async-io 2.3.4",
"async-lock 3.4.0",
"blocking",
"futures-lite 2.3.0",
"futures-lite 2.4.0",
"once_cell",
]
@ -339,7 +339,7 @@ dependencies = [
"cfg-if",
"concurrent-queue",
"futures-io",
"futures-lite 2.3.0",
"futures-lite 2.4.0",
"parking",
"polling 3.7.3",
"rustix 0.38.38",
@ -391,7 +391,7 @@ dependencies = [
"blocking",
"cfg-if",
"event-listener 5.3.1",
"futures-lite 2.3.0",
"futures-lite 2.4.0",
"rustix 0.38.38",
"tracing",
]
@ -416,7 +416,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.85",
"syn 2.0.86",
]
[[package]]
@ -453,7 +453,7 @@ dependencies = [
"futures-channel",
"futures-core",
"futures-io",
"futures-lite 2.3.0",
"futures-lite 2.4.0",
"gloo-timers",
"kv-log-macro",
"log",
@ -484,7 +484,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.85",
"syn 2.0.86",
]
[[package]]
@ -501,7 +501,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.85",
"syn 2.0.86",
]
[[package]]
@ -611,7 +611,7 @@ dependencies = [
[[package]]
name = "backend"
version = "4.10.0-test.7"
version = "4.10.1"
dependencies = [
"aes-kw",
"anyhow",
@ -710,7 +710,7 @@ dependencies = [
"regex",
"rustc-hash 1.1.0",
"shlex",
"syn 2.0.85",
"syn 2.0.86",
"which",
]
@ -759,7 +759,7 @@ dependencies = [
"async-channel 2.3.1",
"async-task",
"futures-io",
"futures-lite 2.3.0",
"futures-lite 2.4.0",
"piper",
]
@ -813,7 +813,7 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
[[package]]
name = "chirpstack"
version = "4.10.0-test.7"
version = "4.10.1"
dependencies = [
"aes",
"anyhow",
@ -907,7 +907,7 @@ dependencies = [
[[package]]
name = "chirpstack_api"
version = "4.10.0-test.7"
version = "4.10.1"
dependencies = [
"hex",
"pbjson",
@ -924,7 +924,7 @@ dependencies = [
[[package]]
name = "chirpstack_integration"
version = "4.10.0-test.7"
version = "4.10.1"
dependencies = [
"anyhow",
"async-trait",
@ -1006,7 +1006,7 @@ dependencies = [
"heck",
"proc-macro2",
"quote",
"syn 2.0.85",
"syn 2.0.86",
]
[[package]]
@ -1174,7 +1174,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.85",
"syn 2.0.86",
]
[[package]]
@ -1198,7 +1198,7 @@ dependencies = [
"proc-macro2",
"quote",
"strsim",
"syn 2.0.85",
"syn 2.0.86",
]
[[package]]
@ -1209,7 +1209,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
dependencies = [
"darling_core",
"quote",
"syn 2.0.85",
"syn 2.0.86",
]
[[package]]
@ -1294,7 +1294,7 @@ checksum = "8034092389675178f570469e6c3b0465d3d30b4505c294a6550db47f3c17ad18"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.85",
"syn 2.0.86",
]
[[package]]
@ -1330,9 +1330,9 @@ dependencies = [
[[package]]
name = "diesel-async"
version = "0.5.0"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcb799bb6f8ca6a794462125d7b8983b0c86e6c93a33a9c55934a4a5de4409d3"
checksum = "4c5c6ec8d5c7b8444d19a47161797cbe361e0fb1ee40c6a8124ec915b64a4125"
dependencies = [
"async-trait",
"deadpool",
@ -1353,7 +1353,7 @@ dependencies = [
"dsl_auto_type",
"proc-macro2",
"quote",
"syn 2.0.85",
"syn 2.0.86",
]
[[package]]
@ -1373,7 +1373,7 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "209c735641a413bc68c4923a9d6ad4bcb3ca306b794edaa7eb0b3228a99ffb25"
dependencies = [
"syn 2.0.85",
"syn 2.0.86",
]
[[package]]
@ -1417,7 +1417,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.85",
"syn 2.0.86",
]
[[package]]
@ -1443,7 +1443,7 @@ dependencies = [
"heck",
"proc-macro2",
"quote",
"syn 2.0.85",
"syn 2.0.86",
]
[[package]]
@ -1733,9 +1733,9 @@ dependencies = [
[[package]]
name = "futures-lite"
version = "2.3.0"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5"
checksum = "3f1fa2f9765705486b33fd2acf1577f8ec449c2ba1f318ae5447697b7c08d210"
dependencies = [
"fastrand 2.1.1",
"futures-core",
@ -1752,7 +1752,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.85",
"syn 2.0.86",
]
[[package]]
@ -2522,7 +2522,7 @@ dependencies = [
[[package]]
name = "lrwn"
version = "4.10.0-test.7"
version = "4.10.1"
dependencies = [
"aes",
"anyhow",
@ -2536,7 +2536,7 @@ dependencies = [
[[package]]
name = "lrwn_filters"
version = "4.10.0-test.7"
version = "4.10.1"
dependencies = [
"hex",
"lrwn",
@ -3036,7 +3036,7 @@ dependencies = [
"pest_meta",
"proc-macro2",
"quote",
"syn 2.0.85",
"syn 2.0.86",
]
[[package]]
@ -3110,7 +3110,7 @@ checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.85",
"syn 2.0.86",
]
[[package]]
@ -3263,7 +3263,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033"
dependencies = [
"proc-macro2",
"syn 2.0.85",
"syn 2.0.86",
]
[[package]]
@ -3338,7 +3338,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.85",
"syn 2.0.86",
]
[[package]]
@ -3368,7 +3368,7 @@ dependencies = [
"prost",
"prost-types",
"regex",
"syn 2.0.85",
"syn 2.0.86",
"tempfile",
]
@ -3382,7 +3382,7 @@ dependencies = [
"itertools 0.13.0",
"proc-macro2",
"quote",
"syn 2.0.85",
"syn 2.0.86",
]
[[package]]
@ -3728,7 +3728,7 @@ dependencies = [
"proc-macro2",
"quote",
"rquickjs-core",
"syn 2.0.85",
"syn 2.0.86",
]
[[package]]
@ -3800,7 +3800,7 @@ dependencies = [
"proc-macro2",
"quote",
"rust-embed-utils",
"syn 2.0.85",
"syn 2.0.86",
"walkdir",
]
@ -4073,7 +4073,7 @@ checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.85",
"syn 2.0.86",
]
[[package]]
@ -4165,7 +4165,7 @@ dependencies = [
"darling",
"proc-macro2",
"quote",
"syn 2.0.85",
"syn 2.0.86",
]
[[package]]
@ -4394,9 +4394,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.85"
version = "2.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56"
checksum = "e89275301d38033efb81a6e60e3497e734dfcc62571f2854bf4b16690398824c"
dependencies = [
"proc-macro2",
"quote",
@ -4426,7 +4426,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.85",
"syn 2.0.86",
]
[[package]]
@ -4464,22 +4464,22 @@ dependencies = [
[[package]]
name = "thiserror"
version = "1.0.65"
version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5"
checksum = "5d171f59dbaa811dbbb1aee1e73db92ec2b122911a48e1390dfe327a821ddede"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.65"
version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602"
checksum = "b08be0f17bd307950653ce45db00cd31200d82b624b36e181337d9c7d92765b5"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.85",
"syn 2.0.86",
]
[[package]]
@ -4565,7 +4565,7 @@ checksum = "8d9ef545650e79f30233c0003bcc2504d7efac6dad25fca40744de773fe2049c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.85",
"syn 2.0.86",
]
[[package]]
@ -4604,7 +4604,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.85",
"syn 2.0.86",
]
[[package]]
@ -4794,7 +4794,7 @@ dependencies = [
"prost-build",
"prost-types",
"quote",
"syn 2.0.85",
"syn 2.0.86",
]
[[package]]
@ -4932,7 +4932,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.85",
"syn 2.0.86",
]
[[package]]
@ -5185,7 +5185,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
"syn 2.0.85",
"syn 2.0.86",
"wasm-bindgen-shared",
]
@ -5219,7 +5219,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.85",
"syn 2.0.86",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@ -5565,7 +5565,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.85",
"syn 2.0.86",
]
[[package]]
@ -5585,5 +5585,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.85",
"syn 2.0.86",
]

View File

@ -1,6 +1,6 @@
{
"name": "@chirpstack/chirpstack-api-grpc-web",
"version": "4.10.0-test.7",
"version": "4.10.1",
"description": "Chirpstack gRPC-web API",
"license": "MIT",
"devDependencies": {

View File

@ -8,7 +8,7 @@ plugins {
}
group = "io.chirpstack"
version = "4.10.0-test.7"
version = "4.10.1"
repositories {
mavenCentral()

2
api/js/package.json vendored
View File

@ -1,6 +1,6 @@
{
"name": "@chirpstack/chirpstack-api",
"version": "4.10.0-test.7",
"version": "4.10.1",
"description": "Chirpstack JS and TS API",
"license": "MIT",
"devDependencies": {

View File

@ -9,7 +9,7 @@ plugins {
}
group = "io.chirpstack"
version = "4.10.0-test.7"
version = "4.10.1"
repositories {
mavenCentral()

View File

@ -3,7 +3,7 @@
"description": "Chirpstack PHP API",
"license": "MIT",
"type": "library",
"version": "4.10.0-test.7",
"version": "4.10.1",
"require": {
"php": ">=7.0.0",
"grpc/grpc": "^v1.57.0",

View File

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

2
api/rust/Cargo.toml vendored
View File

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

View File

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

View File

@ -3,13 +3,13 @@
description = "Library for building external ChirpStack integrations"
homepage = "https://www.chirpstack.io/"
license = "MIT"
version = "4.10.0-test.7"
version = "4.10.1"
authors = ["Orne Brocaar <info@brocaar.com>"]
edition = "2021"
repository = "https://github.com/chirpstack/chirpstack"
[dependencies]
chirpstack_api = { path = "../api/rust", version = "4.10.0-test.7" }
chirpstack_api = { path = "../api/rust", version = "4.10.1" }
redis = { version = "0.27", features = [
"cluster-async",
"tokio-rustls-comp",

View File

@ -3,7 +3,7 @@
description = "ChirpStack is an open-source LoRaWAN(TM) Network Server"
repository = "https://github.com/chirpstack/chirpstack"
homepage = "https://www.chirpstack.io/"
version = "4.10.0-test.7"
version = "4.10.1"
authors = ["Orne Brocaar <info@brocaar.com>"]
edition = "2021"
publish = false
@ -235,17 +235,12 @@
"/etc/chirpstack/region_us915_7.toml",
]
suggests = "postgresql, mosquitto, redis"
conflicts = "chirpstack-sqlite"
maintainer-scripts = "debian/"
systemd-units = { enable = true }
[package.metadata.deb.variants.postgres]
name = "chirpstack"
suggests = "postgresql, mosquitto, redis"
conflicts = "chirpstack-sqlite"
[package.metadata.deb.variants.sqlite]
default-features = false
features = ["sqlite"]
name = "chirpstack-sqlite"
suggests = "mosquitto, redis"
conflicts = "chirpstack"
@ -271,12 +266,16 @@ chmod 640 /etc/chirpstack/*.toml
{ source = "rpm/chirpstack.service", dest = "/lib/systemd/system/chirpstack.service" },
]
[package.metadata.generate-rpm.variants.postgres]
name = "chirpstack"
[package.metadata.generate-rpm.variants.postgres.conflicts]
chirpstack-sqlite = "*"
[package.metadata.generate-rpm.conflicts]
chirpstack-sqlite = "*"
[package.metadata.generate-rpm.variants.sqlite]
name = "chirpstack-sqlite"
assets = [
{ source = "target/release/chirpstack", dest = "/usr/bin/chirpstack", mode = "755" },
{ source = "configuration/*", dest = "/etc/chirpstack" },
{ source = "rpm/chirpstack.service", dest = "/lib/systemd/system/chirpstack-sqlite.service" },
]
[package.metadata.generate-rpm.variants.sqlite.conflicts]
chirpstack = "*"

View File

@ -2,6 +2,11 @@
PKG_VERSION := $(shell cargo metadata --no-deps --format-version 1 | jq -r '.packages[0].version')
DATABASE ?= postgres
ifeq ($(DATABASE),postgres)
VARIANT_FLAGS ?=
else
VARIANT_FLAGS ?= --variant="$(DATABASE)"
endif
debug-amd64:
cross build --target x86_64-unknown-linux-musl --no-default-features --features="$(DATABASE)"
@ -17,13 +22,13 @@ dist:
cross build --target x86_64-unknown-linux-musl --release --no-default-features --features="$(DATABASE)"
cross build --target armv7-unknown-linux-musleabihf --release --no-default-features --features="$(DATABASE)"
cargo deb --target x86_64-unknown-linux-musl --no-build --no-strip --variant="$(DATABASE)"
cargo deb --target armv7-unknown-linux-musleabihf --no-build --no-strip --variant="$(DATABASE)"
cargo deb --target aarch64-unknown-linux-musl --no-build --no-strip --variant="$(DATABASE)"
cargo deb --target x86_64-unknown-linux-musl --no-build --no-strip $(VARIANT_FLAGS)
cargo deb --target armv7-unknown-linux-musleabihf --no-build --no-strip $(VARIANT_FLAGS)
cargo deb --target aarch64-unknown-linux-musl --no-build --no-strip $(VARIANT_FLAGS)
cargo generate-rpm --target x86_64-unknown-linux-musl --target-dir ../target --variant="$(DATABASE)"
cargo generate-rpm --target armv7-unknown-linux-musleabihf --target-dir ../target --variant="$(DATABASE)"
cargo generate-rpm --target aarch64-unknown-linux-musl --target-dir ../target --variant="$(DATABASE)"
cargo generate-rpm --target x86_64-unknown-linux-musl --target-dir ../target $(VARIANT_FLAGS)
cargo generate-rpm --target armv7-unknown-linux-musleabihf --target-dir ../target $(VARIANT_FLAGS)
cargo generate-rpm --target aarch64-unknown-linux-musl --target-dir ../target $(VARIANT_FLAGS)
mkdir -p ../dist

View File

@ -0,0 +1,2 @@
alter table device_keys
alter column dev_nonces type int[] using '{}';

View File

@ -0,0 +1,7 @@
alter table device_keys
alter column dev_nonces type jsonb using jsonb_build_object('0000000000000000', dev_nonces);
update device_keys
set dev_nonces = jsonb_build_object(encode(device.join_eui, 'hex'), dev_nonces->'0000000000000000')
from device
where device.dev_eui = device_keys.dev_eui;

View File

@ -0,0 +1 @@
update device_keys set dev_nonces = '[]';

View File

@ -0,0 +1 @@
update device_keys set dev_nonces = '{}';

View File

@ -469,7 +469,7 @@ impl DeviceService for Device {
)
.await?;
device_keys::set_dev_nonces(&dev_eui, &Vec::new())
device_keys::set_dev_nonces(dev_eui, &fields::DevNonces::default())
.await
.map_err(|e| e.status())?;
@ -1429,10 +1429,13 @@ pub mod test {
);
// flush dev nonces
let _ =
device_keys::set_dev_nonces(&EUI64::from_str("0102030405060708").unwrap(), &[1, 2, 3])
.await
.unwrap();
let _ = device_keys::set_dev_nonces(EUI64::from_str("0102030405060708").unwrap(), &{
let mut dev_nonces = fields::DevNonces::default();
dev_nonces.insert(EUI64::from_str("0102030405060708").unwrap(), 123);
dev_nonces
})
.await
.unwrap();
let flush_dev_nonces_req = get_request(
&u.id,
api::FlushDevNoncesRequest {
@ -1446,7 +1449,7 @@ pub mod test {
let dk = device_keys::get(&EUI64::from_str("0102030405060708").unwrap())
.await
.unwrap();
assert_eq!(0, dk.dev_nonces.len());
assert_eq!(fields::DevNonces::default(), dk.dev_nonces);
// delete keys
let del_keys_req = get_request(

View File

@ -38,7 +38,7 @@ impl Default for DeviceKeys {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
]),
dev_nonces: Vec::new().into(),
dev_nonces: fields::DevNonces::default(),
join_nonce: 0,
}
}
@ -93,10 +93,12 @@ pub async fn delete(dev_eui: &EUI64) -> Result<(), Error> {
Ok(())
}
pub async fn set_dev_nonces(dev_eui: &EUI64, nonces: &[i32]) -> Result<DeviceKeys, Error> {
let nonces: Vec<Option<i32>> = nonces.iter().map(|v| Some(*v)).collect();
pub async fn set_dev_nonces(
dev_eui: EUI64,
nonces: &fields::DevNonces,
) -> Result<DeviceKeys, Error> {
let dk: DeviceKeys = diesel::update(device_keys::dsl::device_keys.find(dev_eui))
.set(device_keys::dev_nonces.eq(fields::DevNonces::from(nonces)))
.set(device_keys::dev_nonces.eq(nonces))
.get_result(&mut get_async_db_conn().await?)
.await
.map_err(|e| Error::from_diesel(e, dev_eui.to_string()))?;
@ -108,8 +110,9 @@ pub async fn set_dev_nonces(dev_eui: &EUI64, nonces: &[i32]) -> Result<DeviceKey
}
pub async fn validate_incr_join_and_store_dev_nonce(
dev_eui: &EUI64,
dev_nonce: i32,
join_eui: EUI64,
dev_eui: EUI64,
dev_nonce: u16,
) -> Result<DeviceKeys, Error> {
let mut c = get_async_db_conn().await?;
let dk: DeviceKeys = db_transaction::<DeviceKeys, Error, _>(&mut c, |c| {
@ -122,11 +125,11 @@ pub async fn validate_incr_join_and_store_dev_nonce(
.await
.map_err(|e| Error::from_diesel(e, dev_eui.to_string()))?;
if dk.dev_nonces.contains(&(Some(dev_nonce))) {
if dk.dev_nonces.contains(join_eui, dev_nonce) {
return Err(Error::InvalidDevNonce);
}
dk.dev_nonces.push(Some(dev_nonce));
dk.dev_nonces.insert(join_eui, dev_nonce);
dk.join_nonce += 1;
diesel::update(device_keys::dsl::device_keys.find(&dev_eui))
@ -155,7 +158,7 @@ pub mod test {
pub async fn reset_nonces(dev_eui: &EUI64) -> Result<DeviceKeys, Error> {
let dk: DeviceKeys = diesel::update(device_keys::dsl::device_keys.find(&dev_eui))
.set((
device_keys::dev_nonces.eq(fields::DevNonces::from(Vec::new())),
device_keys::dev_nonces.eq(fields::DevNonces::default()),
device_keys::join_nonce.eq(0),
))
.get_result(&mut get_async_db_conn().await?)

View File

@ -1,67 +1,48 @@
use std::collections::HashMap;
use diesel::backend::Backend;
use diesel::{deserialize, serialize};
#[cfg(feature = "postgres")]
use diesel::{
pg::Pg,
sql_types::{Array, Int4, Nullable},
};
use diesel::{pg::Pg, sql_types::Jsonb};
#[cfg(feature = "sqlite")]
use diesel::{sql_types::Text, sqlite::Sqlite};
use serde::{Deserialize, Serialize};
#[cfg(feature = "postgres")]
type DevNoncesPgType = Array<Nullable<Int4>>;
use lrwn::EUI64;
// Sqlite has no native array type so use text
#[derive(Deserialize, Serialize, Clone, Debug, Eq, PartialEq, AsExpression, FromSqlRow)]
#[serde(transparent)]
#[cfg_attr(feature = "postgres", diesel(sql_type = DevNoncesPgType))]
#[derive(Default, Debug, Clone, PartialEq, Eq, AsExpression, FromSqlRow)]
#[cfg_attr(feature = "postgres", diesel(sql_type = Jsonb))]
#[cfg_attr(feature = "sqlite", diesel(sql_type = Text))]
#[derive(Default)]
pub struct DevNonces(DevNoncesInner);
pub struct DevNonces(HashMap<EUI64, Vec<u16>>);
pub type DevNoncesInner = Vec<Option<i32>>;
impl std::convert::AsRef<DevNoncesInner> for DevNonces {
fn as_ref(&self) -> &DevNoncesInner {
&self.0
impl DevNonces {
pub fn contains(&self, join_eui: EUI64, dev_nonce: u16) -> bool {
if let Some(v) = self.0.get(&join_eui) {
v.contains(&dev_nonce)
} else {
false
}
}
}
impl std::convert::From<DevNoncesInner> for DevNonces {
fn from(value: DevNoncesInner) -> Self {
Self(value)
}
}
impl std::ops::Deref for DevNonces {
type Target = DevNoncesInner;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl std::ops::DerefMut for DevNonces {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
pub fn insert(&mut self, join_eui: EUI64, dev_nonce: u16) {
self.0.entry(join_eui).or_default().push(dev_nonce)
}
}
#[cfg(feature = "postgres")]
impl deserialize::FromSql<DevNoncesPgType, Pg> for DevNonces {
impl deserialize::FromSql<Jsonb, Pg> for DevNonces {
fn from_sql(value: <Pg as Backend>::RawValue<'_>) -> deserialize::Result<Self> {
let sql_val = <DevNoncesInner>::from_sql(value)?;
Ok(DevNonces(sql_val))
let value = <serde_json::Value as deserialize::FromSql<Jsonb, Pg>>::from_sql(value)?;
let dev_nonces: HashMap<EUI64, Vec<u16>> = serde_json::from_value(value)?;
Ok(DevNonces(dev_nonces))
}
}
#[cfg(feature = "postgres")]
impl serialize::ToSql<DevNoncesPgType, Pg> for DevNonces {
fn to_sql(&self, out: &mut serialize::Output<'_, '_, Pg>) -> serialize::Result {
<DevNoncesInner as serialize::ToSql<DevNoncesPgType, Pg>>::to_sql(
&self.0,
&mut out.reborrow(),
)
impl serialize::ToSql<Jsonb, Pg> for DevNonces {
fn to_sql<'b>(&'b self, out: &mut serialize::Output<'b, '_, Pg>) -> serialize::Result {
let value = serde_json::to_value(&self.0)?;
<serde_json::Value as serialize::ToSql<Jsonb, Pg>>::to_sql(&value, &mut out.reborrow())
}
}
@ -73,15 +54,15 @@ where
fn from_sql(value: <Sqlite as Backend>::RawValue<'_>) -> deserialize::Result<Self> {
let s =
<*const str as deserialize::FromSql<diesel::sql_types::Text, Sqlite>>::from_sql(value)?;
let nonces = serde_json::from_str::<DevNonces>(unsafe { &*s })?;
Ok(nonces)
let dev_nonces: HashMap<EUI64, Vec<u16>> = serde_json::from_str(unsafe { &*s })?;
Ok(DevNonces(dev_nonces))
}
}
#[cfg(feature = "sqlite")]
impl serialize::ToSql<Text, Sqlite> for DevNonces {
fn to_sql<'b>(&self, out: &mut serialize::Output<'b, '_, Sqlite>) -> serialize::Result {
out.set_value(serde_json::to_string(self)?);
fn to_sql<'b>(&'b self, out: &mut serialize::Output<'b, '_, Sqlite>) -> serialize::Result {
out.set_value(serde_json::to_string(&self.0)?);
Ok(serialize::IsNull::No)
}
}

View File

@ -7,7 +7,7 @@ mod multicast_group_scheduling_type;
mod uuid;
pub use big_decimal::BigDecimal;
pub use dev_nonces::*;
pub use dev_nonces::DevNonces;
pub use device_session::DeviceSession;
pub use key_value::KeyValue;
pub use measurements::*;

View File

@ -75,7 +75,7 @@ diesel::table! {
updated_at -> Timestamptz,
nwk_key -> Bytea,
app_key -> Bytea,
dev_nonces -> Array<Nullable<Int4>>,
dev_nonces -> Jsonb,
join_nonce -> Int4,
}
}

View File

@ -15,7 +15,7 @@ use crate::storage::{
device::{self, DeviceClass},
device_keys, device_profile, gateway, tenant,
};
use crate::{config, test, uplink};
use crate::{config, storage::fields, test, uplink};
use chirpstack_api::gw;
use lrwn::{AES128Key, EUI64Prefix, NetID, EUI64};
@ -314,7 +314,7 @@ async fn test_sns() {
let dk = device_keys::create(device_keys::DeviceKeys {
dev_eui: dev.dev_eui,
nwk_key: AES128Key::from_bytes([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]),
dev_nonces: vec![].into(),
dev_nonces: fields::DevNonces::default(),
..Default::default()
})
.await
@ -499,7 +499,7 @@ async fn test_sns_roaming_not_allowed() {
let dk = device_keys::create(device_keys::DeviceKeys {
dev_eui: dev.dev_eui,
nwk_key: AES128Key::from_bytes([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]),
dev_nonces: vec![].into(),
dev_nonces: fields::DevNonces::default(),
..Default::default()
})
.await

View File

@ -10,7 +10,9 @@ use crate::storage::{
device::{self, DeviceClass},
device_keys, device_profile, gateway, tenant,
};
use crate::{config, gateway::backend as gateway_backend, integration, region, test, uplink};
use crate::{
config, gateway::backend as gateway_backend, integration, region, storage::fields, test, uplink,
};
use chirpstack_api::{common, gw, internal, stream};
use lrwn::keys::get_js_int_key;
use lrwn::{AES128Key, EUI64};
@ -101,7 +103,11 @@ async fn test_gateway_filtering() {
let dk = device_keys::create(device_keys::DeviceKeys {
dev_eui: dev.dev_eui,
nwk_key: AES128Key::from_bytes([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]),
dev_nonces: vec![Some(258)].into(),
dev_nonces: {
let mut dev_nonces = fields::DevNonces::default();
dev_nonces.insert(EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]), 258);
dev_nonces
},
..Default::default()
})
.await
@ -273,7 +279,11 @@ async fn test_lorawan_10() {
let dk = device_keys::create(device_keys::DeviceKeys {
dev_eui: dev.dev_eui,
nwk_key: AES128Key::from_bytes([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]),
dev_nonces: vec![Some(258)].into(),
dev_nonces: {
let mut dev_nonces = fields::DevNonces::default();
dev_nonces.insert(EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]), 258);
dev_nonces
},
..Default::default()
})
.await
@ -929,7 +939,11 @@ async fn test_lorawan_11() {
dev_eui: dev.dev_eui,
nwk_key: AES128Key::from_bytes([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]),
app_key: AES128Key::from_bytes([16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]),
dev_nonces: vec![Some(258)].into(),
dev_nonces: {
let mut dev_nonces = fields::DevNonces::default();
dev_nonces.insert(EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]), 258);
dev_nonces
},
..Default::default()
})
.await

View File

@ -456,8 +456,9 @@ impl JoinRequest {
self.device_keys = Some(
match device_keys::validate_incr_join_and_store_dev_nonce(
&dev.dev_eui,
join_request.dev_nonce as i32,
join_request.join_eui,
dev.dev_eui,
join_request.dev_nonce,
)
.await
{

View File

@ -353,8 +353,9 @@ impl JoinRequest {
self.device_keys = Some(
match device_keys::validate_incr_join_and_store_dev_nonce(
&dev.dev_eui,
join_request.dev_nonce as i32,
join_request.join_eui,
dev.dev_eui,
join_request.dev_nonce,
)
.await
{

View File

@ -3,7 +3,7 @@
description = "Library for filtering LoRaWAN payloads on DevAddr and JoinEUIs prefixes"
homepage = "https://www.chirpstack.io/"
license = "MIT"
version = "4.10.0-test.7"
version = "4.10.1"
authors = ["Orne Brocaar <info@brocaar.com>"]
edition = "2021"
repository = "https://github.com/chirpstack/chirpstack"

View File

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

View File

@ -1,6 +1,6 @@
{
"name": "chirpstack-ui",
"version": "4.10.0-test.7",
"version": "4.10.1",
"private": true,
"type": "module",
"scripts": {