mirror of
https://github.com/chirpstack/chirpstack.git
synced 2025-04-15 15:49:15 +00:00
Compare commits
18 Commits
api/go/v4.
...
fix_migrat
Author | SHA1 | Date | |
---|---|---|---|
532392abe1 | |||
41b3c6a4e4 | |||
4b6391f57e | |||
ed11c88307 | |||
0ed78a1d0a | |||
fdf168bd09 | |||
dddb471878 | |||
f265a815a6 | |||
9bf78eebfd | |||
3d470c6a14 | |||
2b5b54a7b7 | |||
905db6e9b7 | |||
1245386f38 | |||
49e7c1ccb9 | |||
eafda74526 | |||
3378a81a37 | |||
04e676cad6 | |||
e3b83066b7 |
2
.github/workflows/main.yml
vendored
2
.github/workflows/main.yml
vendored
@ -108,7 +108,7 @@ jobs:
|
||||
uses: docker/metadata-action@v3
|
||||
with:
|
||||
images: |
|
||||
chirpstack/${{ github.event.repository.name }}
|
||||
chirpstack/${{ github.event.repository.name }}${{ matrix.database != 'postgres' && format('-{0}', matrix.database) || '' }}
|
||||
tags: |
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}
|
||||
|
423
Cargo.lock
generated
423
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
2
api/grpc-web/package.json
vendored
2
api/grpc-web/package.json
vendored
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@chirpstack/chirpstack-api-grpc-web",
|
||||
"version": "4.10.0-test.2",
|
||||
"version": "4.10.1",
|
||||
"description": "Chirpstack gRPC-web API",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
|
2
api/java/build.gradle.kts
vendored
2
api/java/build.gradle.kts
vendored
@ -8,7 +8,7 @@ plugins {
|
||||
}
|
||||
|
||||
group = "io.chirpstack"
|
||||
version = "4.10.0-test.2"
|
||||
version = "4.10.1"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
|
2
api/js/package.json
vendored
2
api/js/package.json
vendored
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@chirpstack/chirpstack-api",
|
||||
"version": "4.10.0-test.2",
|
||||
"version": "4.10.1",
|
||||
"description": "Chirpstack JS and TS API",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
|
2
api/kotlin/build.gradle.kts
vendored
2
api/kotlin/build.gradle.kts
vendored
@ -9,7 +9,7 @@ plugins {
|
||||
}
|
||||
|
||||
group = "io.chirpstack"
|
||||
version = "4.10.0-test.2"
|
||||
version = "4.10.1"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
|
2
api/php/composer.json
vendored
2
api/php/composer.json
vendored
@ -3,7 +3,7 @@
|
||||
"description": "Chirpstack PHP API",
|
||||
"license": "MIT",
|
||||
"type": "library",
|
||||
"version": "4.10.0-test.2",
|
||||
"version": "4.10.1",
|
||||
"require": {
|
||||
"php": ">=7.0.0",
|
||||
"grpc/grpc": "^v1.57.0",
|
||||
|
2
api/python/src/setup.py
vendored
2
api/python/src/setup.py
vendored
@ -18,7 +18,7 @@ CLASSIFIERS = [
|
||||
|
||||
setup(
|
||||
name='chirpstack-api',
|
||||
version = "4.10.0-test.2",
|
||||
version = "4.10.1",
|
||||
url='https://github.com/brocaar/chirpstack-api',
|
||||
author='Orne Brocaar',
|
||||
author_email='info@brocaar.com',
|
||||
|
4
api/rust/Cargo.toml
vendored
4
api/rust/Cargo.toml
vendored
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "chirpstack_api"
|
||||
description = "ChirpStack Protobuf / gRPC API definitions."
|
||||
version = "4.10.0-test.2"
|
||||
version = "4.10.1"
|
||||
authors = ["Orne Brocaar <info@brocaar.com>"]
|
||||
license = "MIT"
|
||||
homepage = "https://www.chirpstack.io"
|
||||
@ -24,7 +24,7 @@
|
||||
"codegen",
|
||||
"prost",
|
||||
], default-features = false, optional = true }
|
||||
tokio = { version = "1.40", features = ["macros"], optional = true }
|
||||
tokio = { version = "1.41", features = ["macros"], optional = true }
|
||||
pbjson = { version = "0.7", optional = true }
|
||||
pbjson-types = { version = "0.7", optional = true }
|
||||
serde = { version = "1.0", optional = true }
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "backend"
|
||||
version = "4.10.0-test.2"
|
||||
version = "4.10.1"
|
||||
authors = ["Orne Brocaar <info@brocaar.com>"]
|
||||
edition = "2018"
|
||||
publish = false
|
||||
@ -19,7 +19,7 @@
|
||||
"rustls-tls",
|
||||
], default-features = false }
|
||||
chrono = { version = "0.4", features = ["serde"] }
|
||||
tokio = { version = "1.40", features = ["macros"] }
|
||||
tokio = { version = "1.41", features = ["macros"] }
|
||||
chirpstack_api = { path = "../api/rust", default-features = false, features = [
|
||||
"json",
|
||||
] }
|
||||
|
@ -3,13 +3,13 @@
|
||||
description = "Library for building external ChirpStack integrations"
|
||||
homepage = "https://www.chirpstack.io/"
|
||||
license = "MIT"
|
||||
version = "4.10.0-test.2"
|
||||
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.1" }
|
||||
chirpstack_api = { path = "../api/rust", version = "4.10.1" }
|
||||
redis = { version = "0.27", features = [
|
||||
"cluster-async",
|
||||
"tokio-rustls-comp",
|
||||
@ -23,7 +23,7 @@
|
||||
], default-features = true }
|
||||
async-trait = "0.1"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
tokio = { version = "1.40", features = ["macros", "rt-multi-thread"] }
|
||||
tokio = { version = "1.41", features = ["macros", "rt-multi-thread"] }
|
||||
lazy_static = "1.5"
|
||||
serde_json = "1.0"
|
||||
toml = "0.8"
|
||||
|
@ -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.2"
|
||||
version = "4.10.1"
|
||||
authors = ["Orne Brocaar <info@brocaar.com>"]
|
||||
edition = "2021"
|
||||
publish = false
|
||||
@ -20,7 +20,7 @@
|
||||
serde_urlencoded = "0.7"
|
||||
humantime-serde = "1.1"
|
||||
toml = "0.8"
|
||||
handlebars = "6.1"
|
||||
handlebars = "6.2"
|
||||
|
||||
# Database
|
||||
email_address = "0.2"
|
||||
@ -35,7 +35,7 @@
|
||||
"async-connection-wrapper",
|
||||
] }
|
||||
tokio-postgres = { version = "0.7", optional = true }
|
||||
tokio-postgres-rustls = { version = "0.12", optional = true }
|
||||
tokio-postgres-rustls = { version = "0.13", optional = true }
|
||||
bigdecimal = "0.4"
|
||||
redis = { version = "0.27", features = ["tls-rustls", "tokio-rustls-comp"] }
|
||||
deadpool-redis = { version = "0.18", features = ["cluster", "serde"] }
|
||||
@ -83,7 +83,7 @@
|
||||
tonic = "0.12"
|
||||
tonic-web = "0.12"
|
||||
tonic-reflection = "0.12"
|
||||
tokio = { version = "1.40", features = ["macros", "rt-multi-thread"] }
|
||||
tokio = { version = "1.41", features = ["macros", "rt-multi-thread"] }
|
||||
tokio-stream = "0.1"
|
||||
prost-types = "0.13"
|
||||
prost = "0.13"
|
||||
@ -116,7 +116,7 @@
|
||||
"ring",
|
||||
] }
|
||||
rustls-native-certs = "0.8"
|
||||
rustls-pemfile = "2.1"
|
||||
rustls-pemfile = "2.2"
|
||||
pem = "3.0"
|
||||
x509-parser = "0.16"
|
||||
rsa = "0.9"
|
||||
@ -142,14 +142,14 @@
|
||||
|
||||
# Misc
|
||||
lazy_static = "1.5"
|
||||
uuid = { version = "1.10", features = ["v4", "serde"] }
|
||||
uuid = { version = "1.11", features = ["v4", "serde"] }
|
||||
chrono = "0.4"
|
||||
async-trait = "0.1"
|
||||
aes = "0.8"
|
||||
rand = "0.8"
|
||||
base64 = "0.22"
|
||||
async-recursion = "1.1"
|
||||
regex = "1.10"
|
||||
regex = "1.11"
|
||||
petgraph = "0.6"
|
||||
prometheus-client = "0.22"
|
||||
pin-project = "1.1"
|
||||
@ -160,7 +160,7 @@
|
||||
# Development and testing
|
||||
[dev-dependencies]
|
||||
httpmock = "0.7.0"
|
||||
bytes = "1.7"
|
||||
bytes = "1.8"
|
||||
dotenv = "0.15"
|
||||
|
||||
[features]
|
||||
@ -235,19 +235,14 @@
|
||||
"/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"]
|
||||
suggests = "mosquitto, redis"
|
||||
conflicts = "chirpstack"
|
||||
[package.metadata.deb.variants.sqlite]
|
||||
name = "chirpstack-sqlite"
|
||||
suggests = "mosquitto, redis"
|
||||
conflicts = "chirpstack"
|
||||
|
||||
[package.metadata.generate-rpm]
|
||||
auto-req = "no"
|
||||
@ -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"
|
||||
[package.metadata.generate-rpm.variants.sqlite.conflicts]
|
||||
chirpstack = "*"
|
||||
[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 = "*"
|
||||
|
@ -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
|
||||
|
||||
|
@ -0,0 +1,2 @@
|
||||
alter table device_keys
|
||||
alter column dev_nonces type int[] using '{}';
|
@ -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;
|
@ -0,0 +1 @@
|
||||
update device_keys set dev_nonces = '[]';
|
@ -0,0 +1 @@
|
||||
update device_keys set dev_nonces = '{}';
|
@ -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(
|
||||
|
@ -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?)
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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::*;
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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.2"
|
||||
version = "4.10.1"
|
||||
authors = ["Orne Brocaar <info@brocaar.com>"]
|
||||
edition = "2021"
|
||||
repository = "https://github.com/chirpstack/chirpstack"
|
||||
|
@ -3,7 +3,7 @@
|
||||
description = "Library for encoding / decoding LoRaWAN frames."
|
||||
homepage = "https://www.chirpstack.io"
|
||||
license = "MIT"
|
||||
version = "4.10.0-test.2"
|
||||
version = "4.10.1"
|
||||
authors = ["Orne Brocaar <info@brocaar.com>"]
|
||||
edition = "2018"
|
||||
repository = "https://github.com/chirpstack/chirpstack"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "chirpstack-ui",
|
||||
"version": "4.10.0-test.2",
|
||||
"version": "4.10.1",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
Reference in New Issue
Block a user