Compare commits

..

No commits in common. "master" and "api/go/v4.12.0-test.2" have entirely different histories.

79 changed files with 1415 additions and 1475 deletions

489
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,9 @@ dist:
cd chirpstack && make dist
# Install dev dependencies
# TODO: test latest cargo-deb and move it to shell.nix.
dev-dependencies:
cargo install cargo-deb --version 1.43.1 --locked
cargo install cargo-generate-rpm --version 0.12.1 --locked
# Set the versions

7
api/go/go.mod vendored
View File

@ -1,7 +1,6 @@
module github.com/chirpstack/chirpstack/api/go/v4
go 1.21
toolchain go1.24.1
require (
google.golang.org/genproto/googleapis/api v0.0.0-20240325203815-454cdb8f5daa
@ -11,8 +10,8 @@ require (
require (
github.com/golang/protobuf v1.5.4 // indirect
golang.org/x/net v0.36.0 // indirect
golang.org/x/sys v0.30.0 // indirect
golang.org/x/text v0.22.0 // indirect
golang.org/x/net v0.33.0 // indirect
golang.org/x/sys v0.28.0 // indirect
golang.org/x/text v0.21.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240325203815-454cdb8f5daa // indirect
)

12
api/go/go.sum vendored
View File

@ -2,12 +2,12 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA=
golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I=
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
google.golang.org/genproto/googleapis/api v0.0.0-20240325203815-454cdb8f5daa h1:Jt1XW5PaLXF1/ePZrznsh/aAUvI7Adfc3LY1dAKlzRs=
google.golang.org/genproto/googleapis/api v0.0.0-20240325203815-454cdb8f5daa/go.mod h1:K4kfzHtI0kqWA79gecJarFtDn/Mls+GxQcg3Zox91Ac=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240325203815-454cdb8f5daa h1:RBgMaUMP+6soRkik4VoN8ojR2nex2TqZwjSSogic+eo=

View File

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

View File

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

2
api/js/package.json vendored
View File

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

View File

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

View File

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

View File

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

6
api/rust/Cargo.toml vendored
View File

@ -1,7 +1,7 @@
[package]
name = "chirpstack_api"
description = "ChirpStack Protobuf / gRPC API definitions."
version = "4.12.0-test.3"
version = "4.12.0-test.2"
authors = ["Orne Brocaar <info@brocaar.com>"]
license = "MIT"
homepage = "https://www.chirpstack.io"
@ -19,7 +19,7 @@
prost-types = "0.13"
hex = "0.4"
rand = "0.9"
tonic = { version = "0.13", features = [
tonic = { version = "0.12", features = [
"codegen",
"prost",
], default-features = false, optional = true }
@ -29,7 +29,7 @@
serde = { version = "1.0", optional = true }
[build-dependencies]
tonic-build = { version = "0.13", features = [
tonic-build = { version = "0.12", features = [
"prost",
], default-features = false }
pbjson-build = "0.7"

View File

@ -1,6 +1,6 @@
[package]
name = "backend"
version = "4.12.0-test.3"
version = "4.12.0-test.2"
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.12.0-test.3"
version = "4.12.0-test.2"
authors = ["Orne Brocaar <info@brocaar.com>"]
edition = "2021"
repository = "https://github.com/chirpstack/chirpstack"
[dependencies]
chirpstack_api = { path = "../api/rust", version = "4.12.0-test.3" }
chirpstack_api = { path = "../api/rust", version = "4.12.0-test.2" }
redis = { version = "0.29", features = [
"cluster-async",
"tokio-rustls-comp",

View File

@ -203,7 +203,7 @@ impl Integration {
for stream_key in &srr.keys {
for stream_id in &stream_key.ids {
let _: () = redis::cmd("XACK")
redis::cmd("XACK")
.arg(&key)
.arg(&self.consumer_group)
.arg(&stream_id.id)

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.12.0-test.3"
version = "4.12.0-test.2"
authors = ["Orne Brocaar <info@brocaar.com>"]
edition = "2021"
publish = false
@ -78,9 +78,9 @@
] }
# gRPC and Protobuf
tonic = "0.13"
tonic-web = "0.13"
tonic-reflection = "0.13"
tonic = "0.12"
tonic-web = "0.12"
tonic-reflection = "0.12"
tokio = { version = "1.44", features = ["macros", "rt-multi-thread"] }
tokio-stream = "0.1"
prost-types = "0.13"
@ -95,7 +95,7 @@
futures-util = "0.3"
http = "1.3"
http-body = "1.0"
rust-embed = "8.7"
rust-embed = "8.6"
mime_guess = "2.0"
tower-http = { version = "0.6", features = ["trace", "auth"] }
@ -147,7 +147,7 @@
async-recursion = "1.1"
regex = "1.11"
petgraph = "0.7"
prometheus-client = "0.23"
prometheus-client = "0.22"
pin-project = "1.1"
scoped-futures = { version = "0.1", features = ["std"] }
signal-hook = "0.3"

View File

@ -26,7 +26,7 @@ insert into "user" (
password_hash,
note
) values (
gen_random_uuid(),
'05244f12-6daf-4e1f-8315-c66783a0ab56',
now(),
now(),
true,
@ -63,7 +63,7 @@ insert into "tenant" (
max_gateway_count,
private_gateways
) values (
gen_random_uuid(),
'52f14cd4-c6f1-4fbd-8f87-4025e1d49242',
now(),
now(),
'ChirpStack',

View File

@ -1,6 +1,3 @@
alter table device
drop column app_layer_params;
alter table device_keys
drop column gen_app_key;

View File

@ -73,9 +73,3 @@ alter table device_keys
alter table device_keys
alter column gen_app_key drop default;
alter table device
add column app_layer_params jsonb not null default '{}';
alter table device
alter column app_layer_params drop default;

View File

@ -1,6 +1,3 @@
alter table device
drop column app_layer_params;
alter table device_keys
drop column gen_app_key;

View File

@ -70,6 +70,3 @@ create index idx_fuota_deployment_job_scheduler_run_after on fuota_deployment_jo
alter table device_keys
add column gen_app_key blob not null default x'00000000000000000000000000000000';
alter table device
add column app_layer_params text not null default '{}';

View File

@ -2010,7 +2010,7 @@ pub mod test {
let mut create_req = Request::new(create_req);
create_req
.extensions_mut()
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id)));
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id).clone()));
let create_resp = service.create(create_req).await.unwrap();
let create_resp = create_resp.get_ref();
@ -2021,7 +2021,7 @@ pub mod test {
let mut get_req = Request::new(get_req);
get_req
.extensions_mut()
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id)));
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id).clone()));
let get_resp = service.get(get_req).await.unwrap();
assert_eq!(
Some(api::Application {
@ -2045,7 +2045,7 @@ pub mod test {
let mut up_req = Request::new(up_req);
up_req
.extensions_mut()
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id)));
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id).clone()));
let _ = service.update(up_req).await.unwrap();
//get
@ -2055,7 +2055,7 @@ pub mod test {
let mut get_req = Request::new(get_req);
get_req
.extensions_mut()
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id)));
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id).clone()));
let get_resp = service.get(get_req).await.unwrap();
assert_eq!(
Some(api::Application {
@ -2077,7 +2077,7 @@ pub mod test {
let mut list_req = Request::new(list_req);
list_req
.extensions_mut()
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id)));
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id).clone()));
let list_resp = service.list(list_req).await.unwrap();
assert_eq!(1, list_resp.get_ref().total_count);
assert_eq!(1, list_resp.get_ref().result.len());
@ -2089,7 +2089,7 @@ pub mod test {
let mut del_req = Request::new(del_req);
del_req
.extensions_mut()
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id)));
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id).clone()));
let _ = service.delete(del_req).await.unwrap();
let del_req = api::DeleteApplicationRequest {
@ -2098,7 +2098,7 @@ pub mod test {
let mut del_req = Request::new(del_req);
del_req
.extensions_mut()
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id)));
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id).clone()));
let del_resp = service.delete(del_req).await;
assert!(del_resp.is_err());
}

View File

@ -2483,7 +2483,7 @@ pub mod test {
tenant::add_user(tenant::TenantUser {
tenant_id: tenant_a.id,
user_id: tenant_user.id,
user_id: tenant_user.id.into(),
..Default::default()
})
.await
@ -2491,7 +2491,7 @@ pub mod test {
tenant::add_user(tenant::TenantUser {
tenant_id: tenant_a.id,
user_id: tenant_admin.id,
user_id: tenant_admin.id.into(),
is_admin: true,
..Default::default()
})
@ -2727,7 +2727,7 @@ pub mod test {
tenant::add_user(tenant::TenantUser {
tenant_id: tenant_a.id,
user_id: tenant_admin.id,
user_id: tenant_admin.id.into(),
is_admin: true,
..Default::default()
})
@ -2735,21 +2735,21 @@ pub mod test {
.unwrap();
tenant::add_user(tenant::TenantUser {
tenant_id: tenant_a.id,
user_id: tenant_user.id,
user_id: tenant_user.id.into(),
..Default::default()
})
.await
.unwrap();
tenant::add_user(tenant::TenantUser {
tenant_id: api_key_tenant.tenant_id.unwrap(),
user_id: tenant_user.id,
tenant_id: api_key_tenant.tenant_id.unwrap().into(),
user_id: tenant_user.id.into(),
..Default::default()
})
.await
.unwrap();
tenant::add_user(tenant::TenantUser {
tenant_id: tenant_a.id,
user_id: tenant_user_other.id,
user_id: tenant_user_other.id.into(),
..Default::default()
})
.await
@ -3091,7 +3091,7 @@ pub mod test {
tenant::add_user(tenant::TenantUser {
tenant_id: tenant_a.id,
user_id: tenant_admin.id,
user_id: tenant_admin.id.into(),
is_admin: true,
..Default::default()
})
@ -3099,7 +3099,7 @@ pub mod test {
.unwrap();
tenant::add_user(tenant::TenantUser {
tenant_id: tenant_a.id,
user_id: tenant_device_admin.id,
user_id: tenant_device_admin.id.into(),
is_device_admin: true,
..Default::default()
})
@ -3107,7 +3107,7 @@ pub mod test {
.unwrap();
tenant::add_user(tenant::TenantUser {
tenant_id: tenant_a.id,
user_id: tenant_gateway_admin.id,
user_id: tenant_gateway_admin.id.into(),
is_gateway_admin: true,
..Default::default()
})
@ -3115,7 +3115,7 @@ pub mod test {
.unwrap();
tenant::add_user(tenant::TenantUser {
tenant_id: tenant_a.id,
user_id: tenant_user.id,
user_id: tenant_user.id.into(),
..Default::default()
})
.await
@ -3538,7 +3538,7 @@ pub mod test {
tenant::add_user(tenant::TenantUser {
tenant_id: tenant_a.id,
user_id: tenant_admin.id,
user_id: tenant_admin.id.into(),
is_admin: true,
..Default::default()
})
@ -3546,7 +3546,7 @@ pub mod test {
.unwrap();
tenant::add_user(tenant::TenantUser {
tenant_id: tenant_a.id,
user_id: tenant_device_admin.id,
user_id: tenant_device_admin.id.into(),
is_device_admin: true,
..Default::default()
})
@ -3554,7 +3554,7 @@ pub mod test {
.unwrap();
tenant::add_user(tenant::TenantUser {
tenant_id: tenant_a.id,
user_id: tenant_gateway_admin.id,
user_id: tenant_gateway_admin.id.into(),
is_gateway_admin: true,
..Default::default()
})
@ -3562,7 +3562,7 @@ pub mod test {
.unwrap();
tenant::add_user(tenant::TenantUser {
tenant_id: tenant_a.id,
user_id: tenant_user.id,
user_id: tenant_user.id.into(),
..Default::default()
})
.await
@ -3840,32 +3840,32 @@ pub mod test {
.await;
tenant::add_user(tenant::TenantUser {
tenant_id: api_key_tenant.tenant_id.unwrap(),
user_id: tenant_admin.id,
tenant_id: api_key_tenant.tenant_id.unwrap().into(),
user_id: tenant_admin.id.into(),
is_admin: true,
..Default::default()
})
.await
.unwrap();
tenant::add_user(tenant::TenantUser {
tenant_id: api_key_tenant.tenant_id.unwrap(),
user_id: tenant_device_admin.id,
tenant_id: api_key_tenant.tenant_id.unwrap().into(),
user_id: tenant_device_admin.id.into(),
is_device_admin: true,
..Default::default()
})
.await
.unwrap();
tenant::add_user(tenant::TenantUser {
tenant_id: api_key_tenant.tenant_id.unwrap(),
user_id: tenant_gateway_admin.id,
tenant_id: api_key_tenant.tenant_id.unwrap().into(),
user_id: tenant_gateway_admin.id.into(),
is_gateway_admin: true,
..Default::default()
})
.await
.unwrap();
tenant::add_user(tenant::TenantUser {
tenant_id: api_key_tenant.tenant_id.unwrap(),
user_id: tenant_user.id,
tenant_id: api_key_tenant.tenant_id.unwrap().into(),
user_id: tenant_user.id.into(),
..Default::default()
})
.await
@ -4093,8 +4093,8 @@ pub mod test {
.await;
tenant::add_user(tenant::TenantUser {
tenant_id: api_key_tenant.tenant_id.unwrap(),
user_id: tenant_user.id,
tenant_id: api_key_tenant.tenant_id.unwrap().into(),
user_id: tenant_user.id.into(),
..Default::default()
})
.await
@ -4237,7 +4237,7 @@ pub mod test {
let gw_api_key_tenant = gateway::create(gateway::Gateway {
name: "test-gw-tenant".into(),
gateway_id: EUI64::from_str("0202030405060708").unwrap(),
tenant_id: api_key_tenant.tenant_id.unwrap(),
tenant_id: api_key_tenant.tenant_id.unwrap().into(),
..Default::default()
})
.await
@ -4245,7 +4245,7 @@ pub mod test {
tenant::add_user(tenant::TenantUser {
tenant_id: tenant_a.id,
user_id: tenant_admin.id,
user_id: tenant_admin.id.into(),
is_admin: true,
..Default::default()
})
@ -4253,7 +4253,7 @@ pub mod test {
.unwrap();
tenant::add_user(tenant::TenantUser {
tenant_id: tenant_a.id,
user_id: tenant_gateway_admin.id,
user_id: tenant_gateway_admin.id.into(),
is_gateway_admin: true,
..Default::default()
})
@ -4261,7 +4261,7 @@ pub mod test {
.unwrap();
tenant::add_user(tenant::TenantUser {
tenant_id: tenant_a.id,
user_id: tenant_user.id,
user_id: tenant_user.id.into(),
..Default::default()
})
.await
@ -4513,32 +4513,32 @@ pub mod test {
.await;
tenant::add_user(tenant::TenantUser {
tenant_id: api_key_tenant.tenant_id.unwrap(),
user_id: tenant_admin.id,
tenant_id: api_key_tenant.tenant_id.unwrap().into(),
user_id: tenant_admin.id.into(),
is_admin: true,
..Default::default()
})
.await
.unwrap();
tenant::add_user(tenant::TenantUser {
tenant_id: api_key_tenant.tenant_id.unwrap(),
user_id: tenant_device_admin.id,
tenant_id: api_key_tenant.tenant_id.unwrap().into(),
user_id: tenant_device_admin.id.into(),
is_device_admin: true,
..Default::default()
})
.await
.unwrap();
tenant::add_user(tenant::TenantUser {
tenant_id: api_key_tenant.tenant_id.unwrap(),
user_id: tenant_gateway_admin.id,
tenant_id: api_key_tenant.tenant_id.unwrap().into(),
user_id: tenant_gateway_admin.id.into(),
is_gateway_admin: true,
..Default::default()
})
.await
.unwrap();
tenant::add_user(tenant::TenantUser {
tenant_id: api_key_tenant.tenant_id.unwrap(),
user_id: tenant_user.id,
tenant_id: api_key_tenant.tenant_id.unwrap().into(),
user_id: tenant_user.id.into(),
..Default::default()
})
.await
@ -4901,7 +4901,7 @@ pub mod test {
.await
.unwrap();
tenant::add_user(tenant::TenantUser {
tenant_id: api_key_tenant.tenant_id.unwrap(),
tenant_id: api_key_tenant.tenant_id.unwrap().into(),
user_id: tenant_device_admin.id,
is_device_admin: true,
..Default::default()

View File

@ -88,7 +88,7 @@ impl DeviceProfileService for DeviceProfile {
rx1_delay: req_dp.abp_rx1_delay as u8,
rx1_dr_offset: req_dp.abp_rx1_dr_offset as u8,
rx2_dr: req_dp.abp_rx2_dr as u8,
rx2_freq: req_dp.abp_rx2_freq,
rx2_freq: req_dp.abp_rx2_freq as u32,
})
},
class_b_params: if req_dp.supports_class_b {
@ -96,7 +96,7 @@ impl DeviceProfileService for DeviceProfile {
timeout: req_dp.class_b_timeout as u16,
ping_slot_nb_k: req_dp.class_b_ping_slot_nb_k as u8,
ping_slot_dr: req_dp.class_b_ping_slot_dr as u8,
ping_slot_freq: req_dp.class_b_ping_slot_freq,
ping_slot_freq: req_dp.class_b_ping_slot_freq as u32,
})
} else {
None
@ -116,7 +116,7 @@ impl DeviceProfileService for DeviceProfile {
relay_enabled: req_dp.relay_enabled,
relay_cad_periodicity: req_dp.relay_cad_periodicity as u8,
default_channel_index: req_dp.relay_default_channel_index as u8,
second_channel_freq: req_dp.relay_second_channel_freq,
second_channel_freq: req_dp.relay_second_channel_freq as u32,
second_channel_dr: req_dp.relay_second_channel_dr as u8,
second_channel_ack_offset: req_dp.relay_second_channel_ack_offset as u8,
ed_activation_mode: req_dp.relay_ed_activation_mode().from_proto(),
@ -344,7 +344,7 @@ impl DeviceProfileService for DeviceProfile {
rx1_delay: req_dp.abp_rx1_delay as u8,
rx1_dr_offset: req_dp.abp_rx1_dr_offset as u8,
rx2_dr: req_dp.abp_rx2_dr as u8,
rx2_freq: req_dp.abp_rx2_freq,
rx2_freq: req_dp.abp_rx2_freq as u32,
})
},
class_b_params: if req_dp.supports_class_b {
@ -352,7 +352,7 @@ impl DeviceProfileService for DeviceProfile {
timeout: req_dp.class_b_timeout as u16,
ping_slot_nb_k: req_dp.class_b_ping_slot_nb_k as u8,
ping_slot_dr: req_dp.class_b_ping_slot_dr as u8,
ping_slot_freq: req_dp.class_b_ping_slot_freq,
ping_slot_freq: req_dp.class_b_ping_slot_freq as u32,
})
} else {
None
@ -372,7 +372,7 @@ impl DeviceProfileService for DeviceProfile {
relay_enabled: req_dp.relay_enabled,
relay_cad_periodicity: req_dp.relay_cad_periodicity as u8,
default_channel_index: req_dp.relay_default_channel_index as u8,
second_channel_freq: req_dp.relay_second_channel_freq,
second_channel_freq: req_dp.relay_second_channel_freq as u32,
second_channel_dr: req_dp.relay_second_channel_dr as u8,
second_channel_ack_offset: req_dp.relay_second_channel_ack_offset as u8,
ed_activation_mode: req_dp.relay_ed_activation_mode().from_proto(),
@ -406,6 +406,7 @@ impl DeviceProfileService for DeviceProfile {
ts004_f_port: app_layer_params.ts004_f_port as u8,
ts005_version: app_layer_params.ts005_version().from_proto(),
ts005_f_port: app_layer_params.ts005_f_port as u8,
..Default::default()
}
},
..Default::default()

View File

@ -50,9 +50,9 @@ impl ToStatus for storage::error::Error {
storage::error::Error::ValidatorValidate(_) => {
Status::new(Code::InvalidArgument, format!("{:#}", self))
}
storage::error::Error::Multi(errors) => {
storage::error::Error::MultiError(errors) => {
let errors = errors
.iter()
.into_iter()
.map(|e| e.to_string())
.collect::<Vec<String>>()
.join(", ");

View File

@ -346,11 +346,11 @@ impl FuotaService for Fuota {
started_at: d
.started_at
.as_ref()
.map(helpers::datetime_to_prost_timestamp),
.map(|ts| helpers::datetime_to_prost_timestamp(ts)),
completed_at: d
.completed_at
.as_ref()
.map(helpers::datetime_to_prost_timestamp),
.map(|ts| helpers::datetime_to_prost_timestamp(ts)),
name: d.name.clone(),
})
.collect(),
@ -462,23 +462,23 @@ impl FuotaService for Fuota {
completed_at: d
.completed_at
.as_ref()
.map(helpers::datetime_to_prost_timestamp),
.map(|ts| helpers::datetime_to_prost_timestamp(ts)),
mc_group_setup_completed_at: d
.mc_group_setup_completed_at
.as_ref()
.map(helpers::datetime_to_prost_timestamp),
.map(|ts| helpers::datetime_to_prost_timestamp(ts)),
mc_session_completed_at: d
.mc_session_completed_at
.as_ref()
.map(helpers::datetime_to_prost_timestamp),
.map(|ts| helpers::datetime_to_prost_timestamp(ts)),
frag_session_setup_completed_at: d
.frag_session_setup_completed_at
.as_ref()
.map(helpers::datetime_to_prost_timestamp),
.map(|ts| helpers::datetime_to_prost_timestamp(ts)),
frag_status_completed_at: d
.frag_status_completed_at
.as_ref()
.map(helpers::datetime_to_prost_timestamp),
.map(|ts| helpers::datetime_to_prost_timestamp(ts)),
error_msg: d.error_msg.clone(),
})
.collect(),
@ -624,7 +624,7 @@ impl FuotaService for Fuota {
completed_at: j
.completed_at
.as_ref()
.map(helpers::datetime_to_prost_timestamp),
.map(|ts| helpers::datetime_to_prost_timestamp(ts)),
max_retry_count: j.max_retry_count as u32,
attempt_count: j.attempt_count as u32,
scheduler_run_after: Some(helpers::datetime_to_prost_timestamp(

View File

@ -1036,7 +1036,7 @@ pub mod test {
let mut create_req = Request::new(create_req);
create_req
.extensions_mut()
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id)));
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id).clone()));
let _ = service.create(create_req).await.unwrap();
// get
@ -1046,7 +1046,7 @@ pub mod test {
let mut get_req = Request::new(get_req);
get_req
.extensions_mut()
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id)));
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id).clone()));
let get_resp = service.get(get_req).await.unwrap();
assert_eq!(
Some(api::Gateway {
@ -1082,7 +1082,7 @@ pub mod test {
let mut up_req = Request::new(up_req);
up_req
.extensions_mut()
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id)));
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id).clone()));
let _ = service.update(up_req).await.unwrap();
// get
@ -1092,7 +1092,7 @@ pub mod test {
let mut get_req = Request::new(get_req);
get_req
.extensions_mut()
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id)));
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id).clone()));
let get_resp = service.get(get_req).await.unwrap();
assert_eq!(
Some(api::Gateway {
@ -1121,7 +1121,7 @@ pub mod test {
let mut list_req = Request::new(list_req);
list_req
.extensions_mut()
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id)));
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id).clone()));
let list_resp = service.list(list_req).await.unwrap();
assert_eq!(1, list_resp.get_ref().total_count);
assert_eq!(1, list_resp.get_ref().result.len());
@ -1133,7 +1133,7 @@ pub mod test {
let mut del_req = Request::new(del_req);
del_req
.extensions_mut()
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id)));
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id).clone()));
let _ = service.delete(del_req).await.unwrap();
let del_req = api::DeleteGatewayRequest {
@ -1142,7 +1142,7 @@ pub mod test {
let mut del_req = Request::new(del_req);
del_req
.extensions_mut()
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id)));
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id).clone()));
let del_resp = service.delete(del_req).await;
assert!(del_resp.is_err());
}
@ -1220,7 +1220,7 @@ pub mod test {
let mut stats_req = Request::new(stats_req);
stats_req
.extensions_mut()
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id)));
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id).clone()));
let stats_resp = service.get_metrics(stats_req).await.unwrap();
let stats_resp = stats_resp.get_ref();
assert_eq!(

View File

@ -5,7 +5,7 @@ use std::{
task::{Context, Poll},
};
use anyhow::{Context as AnyhowContext, Result};
use anyhow::Result;
use axum::{response::IntoResponse, routing::get, Router};
use http::{
header::{self, HeaderMap, HeaderValue},
@ -103,7 +103,7 @@ type BoxError = Box<dyn std::error::Error + Send + Sync>;
pub async fn setup() -> Result<()> {
let conf = config::get();
let bind = conf.api.bind.parse().context("Parse api.bind config")?;
let bind = conf.api.bind.parse()?;
info!(bind = %bind, "Setting up API interface");
@ -114,7 +114,7 @@ pub async fn setup() -> Result<()> {
.route("/auth/oauth2/callback", get(oauth2::callback_handler))
.fallback(service_static_handler)
.into_service()
.map_response(|r| r.map(tonic::body::Body::new));
.map_response(|r| r.map(tonic::body::boxed));
let grpc = TonicServer::builder()
.accept_http1(true)

View File

@ -484,7 +484,7 @@ pub mod test {
let mut create_req = Request::new(create_req);
create_req
.extensions_mut()
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id)));
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id).clone()));
let create_resp = service.create(create_req).await.unwrap();
// get
@ -494,7 +494,7 @@ pub mod test {
let mut get_req = Request::new(get_req);
get_req
.extensions_mut()
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id)));
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id).clone()));
let get_resp = service.get(get_req).await.unwrap();
assert_eq!(
Some(api::Tenant {
@ -524,7 +524,7 @@ pub mod test {
let mut up_req = Request::new(up_req);
up_req
.extensions_mut()
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id)));
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id).clone()));
let _ = service.update(up_req).await.unwrap();
// get
@ -534,7 +534,7 @@ pub mod test {
let mut get_req = Request::new(get_req);
get_req
.extensions_mut()
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id)));
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id).clone()));
let get_resp = service.get(get_req).await.unwrap();
assert_eq!(
Some(api::Tenant {
@ -559,7 +559,7 @@ pub mod test {
let mut list_req = Request::new(list_req);
list_req
.extensions_mut()
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id)));
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id).clone()));
let list_resp = service.list(list_req).await.unwrap();
assert_eq!(1, list_resp.get_ref().total_count);
assert_eq!(1, list_resp.get_ref().result.len());
@ -571,7 +571,7 @@ pub mod test {
let mut del_req = Request::new(del_req);
del_req
.extensions_mut()
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id)));
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id).clone()));
let _ = service.delete(del_req).await.unwrap();
let del_req = api::DeleteTenantRequest {
@ -580,7 +580,7 @@ pub mod test {
let mut del_req = Request::new(del_req);
del_req
.extensions_mut()
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id)));
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id).clone()));
let del_resp = service.delete(del_req).await;
assert!(del_resp.is_err());
}

View File

@ -294,7 +294,7 @@ pub mod test {
let mut create_req = Request::new(create_req);
create_req
.extensions_mut()
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id)));
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id).clone()));
let create_resp = service.create(create_req).await.unwrap();
// get
@ -304,7 +304,7 @@ pub mod test {
let mut get_req = Request::new(get_req);
get_req
.extensions_mut()
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id)));
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id).clone()));
let get_resp = service.get(get_req).await.unwrap();
assert_eq!(
Some(api::User {
@ -332,7 +332,7 @@ pub mod test {
let mut up_req = Request::new(up_req);
up_req
.extensions_mut()
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id)));
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id).clone()));
let _ = service.update(up_req).await.unwrap();
// get
@ -342,7 +342,7 @@ pub mod test {
let mut get_req = Request::new(get_req);
get_req
.extensions_mut()
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id)));
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id).clone()));
let get_resp = service.get(get_req).await.unwrap();
assert_eq!(
Some(api::User {
@ -364,7 +364,7 @@ pub mod test {
let mut up_req = Request::new(up_req);
up_req
.extensions_mut()
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id)));
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id).clone()));
let _ = service.update_password(up_req).await.unwrap();
// list
@ -375,7 +375,7 @@ pub mod test {
let mut list_req = Request::new(list_req);
list_req
.extensions_mut()
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id)));
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id).clone()));
let list_resp = service.list(list_req).await.unwrap();
// * Admin from migrations
// * User that we created for auth
@ -390,7 +390,7 @@ pub mod test {
let mut del_req = Request::new(del_req);
del_req
.extensions_mut()
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id)));
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id).clone()));
let _ = service.delete(del_req).await.unwrap();
let del_req = api::DeleteUserRequest {
@ -399,7 +399,7 @@ pub mod test {
let mut del_req = Request::new(del_req);
del_req
.extensions_mut()
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id)));
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id).clone()));
let del_resp = service.delete(del_req).await;
assert!(del_resp.is_err());
@ -409,7 +409,7 @@ pub mod test {
let mut del_req = Request::new(del_req);
del_req
.extensions_mut()
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id)));
.insert(AuthID::User(Into::<uuid::Uuid>::into(u.id).clone()));
let del_resp = service.delete(del_req).await;
assert!(del_resp.is_err());
}

View File

@ -33,8 +33,11 @@ async fn handle_uplink_v100(
) -> Result<()> {
let pl = clocksync::v1::Payload::from_slice(true, data)?;
if let clocksync::v1::Payload::AppTimeReq(pl) = pl {
handle_v1_app_time_req(dev, dp, rx_info, pl).await?
match pl {
clocksync::v1::Payload::AppTimeReq(pl) => {
handle_v1_app_time_req(dev, dp, rx_info, pl).await?
}
_ => {}
}
Ok(())
@ -48,8 +51,11 @@ async fn handle_uplink_v200(
) -> Result<()> {
let pl = clocksync::v2::Payload::from_slice(true, data)?;
if let clocksync::v2::Payload::AppTimeReq(pl) = pl {
handle_v2_app_time_req(dev, dp, rx_info, pl).await?
match pl {
clocksync::v2::Payload::AppTimeReq(pl) => {
handle_v2_app_time_req(dev, dp, rx_info, pl).await?
}
_ => {}
}
Ok(())
@ -175,7 +181,7 @@ mod test {
Test {
name: "device synced".into(),
rx_info: gw::UplinkRxInfo {
time_since_gps_epoch: Some(Duration::from_secs(1234).into()),
time_since_gps_epoch: Some(Duration::from_secs(1234).try_into().unwrap()),
..Default::default()
},
req: clocksync::v1::AppTimeReqPayload {
@ -190,7 +196,7 @@ mod test {
Test {
name: "device synced - ans required".into(),
rx_info: gw::UplinkRxInfo {
time_since_gps_epoch: Some(Duration::from_secs(1234).into()),
time_since_gps_epoch: Some(Duration::from_secs(1234).try_into().unwrap()),
..Default::default()
},
req: clocksync::v1::AppTimeReqPayload {
@ -208,7 +214,7 @@ mod test {
Test {
name: "device not synced (positive correction)".into(),
rx_info: gw::UplinkRxInfo {
time_since_gps_epoch: Some(Duration::from_secs(1234).into()),
time_since_gps_epoch: Some(Duration::from_secs(1234).try_into().unwrap()),
..Default::default()
},
req: clocksync::v1::AppTimeReqPayload {
@ -226,7 +232,7 @@ mod test {
Test {
name: "device not synced (negative correction)".into(),
rx_info: gw::UplinkRxInfo {
time_since_gps_epoch: Some(Duration::from_secs(1200).into()),
time_since_gps_epoch: Some(Duration::from_secs(1200).try_into().unwrap()),
..Default::default()
},
req: clocksync::v1::AppTimeReqPayload {
@ -324,7 +330,7 @@ mod test {
Test {
name: "device synced".into(),
rx_info: gw::UplinkRxInfo {
time_since_gps_epoch: Some(Duration::from_secs(1234).into()),
time_since_gps_epoch: Some(Duration::from_secs(1234).try_into().unwrap()),
..Default::default()
},
req: clocksync::v2::AppTimeReqPayload {
@ -339,7 +345,7 @@ mod test {
Test {
name: "device synced - ans required".into(),
rx_info: gw::UplinkRxInfo {
time_since_gps_epoch: Some(Duration::from_secs(1234).into()),
time_since_gps_epoch: Some(Duration::from_secs(1234).try_into().unwrap()),
..Default::default()
},
req: clocksync::v2::AppTimeReqPayload {
@ -357,7 +363,7 @@ mod test {
Test {
name: "device not synced (positive correction)".into(),
rx_info: gw::UplinkRxInfo {
time_since_gps_epoch: Some(Duration::from_secs(1234).into()),
time_since_gps_epoch: Some(Duration::from_secs(1234).try_into().unwrap()),
..Default::default()
},
req: clocksync::v2::AppTimeReqPayload {
@ -375,7 +381,7 @@ mod test {
Test {
name: "device not synced (negative correction)".into(),
rx_info: gw::UplinkRxInfo {
time_since_gps_epoch: Some(Duration::from_secs(1200).into()),
time_since_gps_epoch: Some(Duration::from_secs(1200).try_into().unwrap()),
..Default::default()
},
req: clocksync::v2::AppTimeReqPayload {

View File

@ -397,20 +397,6 @@ impl Flow {
)
.to_vec()?,
Some(Ts004Version::V200) => {
let dev = device::get(&fuota_dev.dev_eui).await?;
let session_cnt = dev.app_layer_params.ts004_session_cnt[0];
let mut app_layer_params = dev.app_layer_params.clone();
app_layer_params.ts004_session_cnt[0] += 1;
device::partial_update(
fuota_dev.dev_eui,
&device::DeviceChangeset {
app_layer_params: Some(app_layer_params),
..Default::default()
},
)
.await?;
let dev_keys = device_keys::get(&fuota_dev.dev_eui).await?;
let data_block_int_key = match self.device_profile.mac_version {
MacVersion::LORAWAN_1_0_0
@ -426,7 +412,7 @@ impl Flow {
};
let mic = fragmentation::v2::calculate_mic(
data_block_int_key,
session_cnt,
0,
0,
[0, 0, 0, 0],
&self.fuota_deployment.payload,
@ -448,7 +434,7 @@ impl Flow {
},
descriptor: [0, 0, 0, 0],
mic,
session_cnt,
session_cnt: 0,
},
)
.to_vec()?
@ -514,7 +500,7 @@ impl Flow {
FuotaJob::Enqueue,
self.fuota_deployment
.multicast_session_start
.unwrap_or_else(Utc::now),
.unwrap_or_else(|| Utc::now()),
)));
}
@ -671,7 +657,7 @@ impl Flow {
FuotaJob::Enqueue,
self.fuota_deployment
.multicast_session_start
.unwrap_or_else(Utc::now),
.unwrap_or_else(|| Utc::now()),
)))
}
}
@ -770,7 +756,7 @@ impl Flow {
FuotaJob::DeleteMcGroup,
self.fuota_deployment
.multicast_session_end
.unwrap_or_else(Utc::now),
.unwrap_or_else(|| Utc::now()),
))),
RequestFragmentationSessionStatus::AfterFragEnqueue => {
Ok(Some((FuotaJob::FragStatus, Utc::now())))
@ -779,7 +765,7 @@ impl Flow {
FuotaJob::FragStatus,
self.fuota_deployment
.multicast_session_end
.unwrap_or_else(Utc::now),
.unwrap_or_else(|| Utc::now()),
))),
}
}
@ -866,7 +852,7 @@ impl Flow {
FuotaJob::DeleteMcGroup,
self.fuota_deployment
.multicast_session_end
.unwrap_or_else(Utc::now),
.unwrap_or_else(|| Utc::now()),
)))
}
}

View File

@ -1000,7 +1000,7 @@ pub fn run() {
let conf = config::get();
println!(
"{}",
reg.render_template(template, &conf)
reg.render_template(&template, &conf)
.expect("render configfile error")
);
}

View File

@ -1827,19 +1827,20 @@ impl Data {
let set = lrwn::MACCommandSet::new(vec![lrwn::MACCommand::ConfigureFwdLimitReq(
lrwn::ConfigureFwdLimitReqPayload {
reload_rate: lrwn::FwdLimitReloadRatePL {
overall_reload_rate: relay_params.relay_overall_limit_reload_rate,
overall_reload_rate: relay_params.relay_overall_limit_reload_rate as u8,
global_uplink_reload_rate: relay_params
.relay_global_uplink_limit_reload_rate,
notify_reload_rate: relay_params.relay_notify_limit_reload_rate,
join_req_reload_rate: relay_params.relay_join_req_limit_reload_rate,
.relay_global_uplink_limit_reload_rate
as u8,
notify_reload_rate: relay_params.relay_notify_limit_reload_rate as u8,
join_req_reload_rate: relay_params.relay_join_req_limit_reload_rate as u8,
reset_limit_counter: lrwn::ResetLimitCounter::NoChange,
},
load_capacity: lrwn::FwdLimitLoadCapacityPL {
overall_limit_size: relay_params.relay_overall_limit_bucket_size,
global_uplink_limit_size: relay_params
.relay_global_uplink_limit_bucket_size,
notify_limit_size: relay_params.relay_notify_limit_bucket_size,
join_req_limit_size: relay_params.relay_join_req_limit_bucket_size,
overall_limit_size: relay_params.relay_overall_limit_bucket_size as u8,
global_uplink_limit_size: relay_params.relay_global_uplink_limit_bucket_size
as u8,
notify_limit_size: relay_params.relay_notify_limit_bucket_size as u8,
join_req_limit_size: relay_params.relay_join_req_limit_bucket_size as u8,
},
},
)]);
@ -2051,7 +2052,7 @@ impl Data {
if relay.enabled != relay_params.relay_enabled
|| relay.cad_periodicity != relay_params.relay_cad_periodicity as u32
|| relay.default_channel_index != relay_params.default_channel_index as u32
|| relay.second_channel_freq != relay_params.second_channel_freq
|| relay.second_channel_freq != relay_params.second_channel_freq as u32
|| relay.second_channel_dr != relay_params.second_channel_dr as u32
|| relay.second_channel_ack_offset != relay_params.second_channel_ack_offset as u32
{
@ -2062,17 +2063,17 @@ impl Data {
true => 1,
false => 0,
},
cad_periodicity: relay_params.relay_cad_periodicity,
default_ch_idx: relay_params.default_channel_index,
cad_periodicity: relay_params.relay_cad_periodicity as u8,
default_ch_idx: relay_params.default_channel_index as u8,
second_ch_idx: if relay_params.second_channel_freq > 0 {
1
} else {
0
},
second_ch_dr: relay_params.second_channel_dr,
second_ch_ack_offset: relay_params.second_channel_ack_offset,
second_ch_dr: relay_params.second_channel_dr as u8,
second_ch_ack_offset: relay_params.second_channel_ack_offset as u8,
},
second_ch_freq: relay_params.second_channel_freq,
second_ch_freq: relay_params.second_channel_freq as u32,
},
)]);
mac_command::set_pending(&dev_eui, lrwn::CID::RelayConfReq, &set).await?;
@ -2101,7 +2102,7 @@ impl Data {
if relay.ed_activation_mode != relay_params.ed_activation_mode.to_u8() as u32
|| relay.ed_smart_enable_level != relay_params.ed_smart_enable_level as u32
|| relay.ed_back_off != relay_params.ed_back_off as u32
|| relay.second_channel_freq != relay_params.second_channel_freq
|| relay.second_channel_freq != relay_params.second_channel_freq as u32
|| relay.second_channel_dr != relay_params.second_channel_dr as u32
|| relay.second_channel_ack_offset != relay_params.second_channel_ack_offset as u32
{
@ -2109,19 +2110,19 @@ impl Data {
lrwn::EndDeviceConfReqPayload {
activation_relay_mode: lrwn::ActivationRelayMode {
relay_mode_activation: relay_params.ed_activation_mode,
smart_enable_level: relay_params.ed_smart_enable_level,
smart_enable_level: relay_params.ed_smart_enable_level as u8,
},
channel_settings_ed: lrwn::ChannelSettingsED {
second_ch_ack_offset: relay_params.second_channel_ack_offset,
second_ch_dr: relay_params.second_channel_dr,
second_ch_ack_offset: relay_params.second_channel_ack_offset as u8,
second_ch_dr: relay_params.second_channel_dr as u8,
second_ch_idx: if relay_params.second_channel_freq > 0 {
1
} else {
0
},
backoff: relay_params.ed_back_off,
backoff: relay_params.ed_back_off as u8,
},
second_ch_freq: relay_params.second_channel_freq,
second_ch_freq: relay_params.second_channel_freq as u32,
},
)]);
mac_command::set_pending(&dev_eui, lrwn::CID::EndDeviceConfReq, &set).await?;

View File

@ -128,7 +128,7 @@ impl<'a> Integration<'a> {
}
#[async_trait]
impl IntegrationTrait for Integration<'_> {
impl<'a> IntegrationTrait for Integration<'a> {
async fn uplink_event(
&self,
_vars: &HashMap<String, String>,

View File

@ -107,7 +107,7 @@ impl<'a> Integration<'a> {
}
#[async_trait]
impl IntegrationTrait for Integration<'_> {
impl<'a> IntegrationTrait for Integration<'a> {
async fn uplink_event(
&self,
_vars: &HashMap<String, String>,

View File

@ -539,7 +539,7 @@ impl<'de> Deserialize<'de> for Eui64Wrapper {
struct Eui64WrapperVisitor;
impl Visitor<'_> for Eui64WrapperVisitor {
impl<'de> Visitor<'de> for Eui64WrapperVisitor {
type Value = Eui64Wrapper;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {

View File

@ -33,7 +33,7 @@ pub mod update_uplink_list;
// This returns the mac-commands which must be sent back to the device as response and a bool
// indicating if a downlink must be sent. For some mac-commands, no mac-command answer is required,
// but the device expects a downlink as confirmation, even if the downlink frame is empty.
pub async fn handle_uplink(
pub async fn handle_uplink<'a>(
uplink_frame_set: &UplinkFrameSet,
cmds: &lrwn::MACCommandSet,
tenant: &tenant::Tenant,

View File

@ -116,7 +116,6 @@ pub struct Device {
pub join_eui: EUI64,
pub secondary_dev_addr: Option<DevAddr>,
pub device_session: Option<fields::DeviceSession>,
pub app_layer_params: fields::device::AppLayerParams,
}
#[derive(AsChangeset, Debug, Clone, Default)]
@ -134,7 +133,6 @@ pub struct DeviceChangeset {
pub battery_level: Option<Option<fields::BigDecimal>>,
pub scheduler_run_after: Option<Option<DateTime<Utc>>>,
pub is_disabled: Option<bool>,
pub app_layer_params: Option<fields::device::AppLayerParams>,
}
impl Device {
@ -192,7 +190,6 @@ impl Default for Device {
join_eui: EUI64::default(),
secondary_dev_addr: None,
device_session: None,
app_layer_params: Default::default(),
}
}
}
@ -555,7 +552,6 @@ pub async fn update(d: Device) -> Result<Device, Error> {
device::tags.eq(&d.tags),
device::variables.eq(&d.variables),
device::join_eui.eq(&d.join_eui),
device::app_layer_params.eq(&d.app_layer_params),
))
.get_result(&mut get_async_db_conn().await?)
.await

View File

@ -109,7 +109,7 @@ impl DeviceProfile {
if let Some(class_b_params) = &self.class_b_params {
ds.class_b_ping_slot_dr = class_b_params.ping_slot_dr as u32;
ds.class_b_ping_slot_freq = class_b_params.ping_slot_freq;
ds.class_b_ping_slot_freq = class_b_params.ping_slot_freq as u32;
ds.class_b_ping_slot_nb = 1 << class_b_params.ping_slot_nb_k as u32;
}
@ -133,7 +133,7 @@ impl DeviceProfile {
ds.rx1_delay = abp_params.rx1_delay as u32;
ds.rx1_dr_offset = abp_params.rx1_dr_offset as u32;
ds.rx2_dr = abp_params.rx2_dr as u32;
ds.rx2_frequency = abp_params.rx2_freq;
ds.rx2_frequency = abp_params.rx2_freq as u32;
}
}
}

View File

@ -34,7 +34,7 @@ pub enum Error {
NotAllowed(String),
#[error("Multiple errors")]
Multi(Vec<Error>),
MultiError(Vec<Error>),
#[error(transparent)]
Diesel(#[from] diesel::result::Error),

View File

@ -1,52 +0,0 @@
use diesel::backend::Backend;
use diesel::{deserialize, serialize};
#[cfg(feature = "postgres")]
use diesel::{pg::Pg, sql_types::Jsonb};
#[cfg(feature = "sqlite")]
use diesel::{sql_types::Text, sqlite::Sqlite};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, AsExpression, FromSqlRow)]
#[cfg_attr(feature = "postgres", diesel(sql_type = Jsonb))]
#[cfg_attr(feature = "sqlite", diesel(sql_type = Text))]
#[serde(default)]
#[derive(Default)]
pub struct AppLayerParams {
pub ts004_session_cnt: [u16; 4],
}
#[cfg(feature = "postgres")]
impl deserialize::FromSql<Jsonb, Pg> for AppLayerParams {
fn from_sql(value: <Pg as Backend>::RawValue<'_>) -> deserialize::Result<Self> {
let value = <serde_json::Value as deserialize::FromSql<Jsonb, Pg>>::from_sql(value)?;
Ok(serde_json::from_value(value)?)
}
}
#[cfg(feature = "postgres")]
impl serialize::ToSql<Jsonb, Pg> for AppLayerParams {
fn to_sql<'b>(&'b self, out: &mut serialize::Output<'b, '_, Pg>) -> serialize::Result {
let value = serde_json::to_value(self)?;
<serde_json::Value as serialize::ToSql<Jsonb, Pg>>::to_sql(&value, &mut out.reborrow())
}
}
#[cfg(feature = "sqlite")]
impl deserialize::FromSql<Text, Sqlite> for AppLayerParams
where
*const str: deserialize::FromSql<Text, Sqlite>,
{
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)?;
Ok(serde_json::from_str(unsafe { &*s })?)
}
}
#[cfg(feature = "sqlite")]
impl serialize::ToSql<Text, Sqlite> for AppLayerParams {
fn to_sql<'b>(&'b self, out: &mut serialize::Output<'b, '_, Sqlite>) -> serialize::Result {
out.set_value(serde_json::to_string(&self)?);
Ok(serialize::IsNull::No)
}
}

View File

@ -29,7 +29,7 @@ impl deserialize::FromSql<Jsonb, Pg> for AbpParams {
#[cfg(feature = "postgres")]
impl serialize::ToSql<Jsonb, Pg> for AbpParams {
fn to_sql<'b>(&'b self, out: &mut serialize::Output<'b, '_, Pg>) -> serialize::Result {
let value = serde_json::to_value(self)?;
let value = serde_json::to_value(&self)?;
<serde_json::Value as serialize::ToSql<Jsonb, Pg>>::to_sql(&value, &mut out.reborrow())
}
}
@ -77,7 +77,7 @@ impl deserialize::FromSql<Jsonb, Pg> for ClassBParams {
#[cfg(feature = "postgres")]
impl serialize::ToSql<Jsonb, Pg> for ClassBParams {
fn to_sql<'b>(&'b self, out: &mut serialize::Output<'b, '_, Pg>) -> serialize::Result {
let value = serde_json::to_value(self)?;
let value = serde_json::to_value(&self)?;
<serde_json::Value as serialize::ToSql<Jsonb, Pg>>::to_sql(&value, &mut out.reborrow())
}
}
@ -122,7 +122,7 @@ impl deserialize::FromSql<Jsonb, Pg> for ClassCParams {
#[cfg(feature = "postgres")]
impl serialize::ToSql<Jsonb, Pg> for ClassCParams {
fn to_sql<'b>(&'b self, out: &mut serialize::Output<'b, '_, Pg>) -> serialize::Result {
let value = serde_json::to_value(self)?;
let value = serde_json::to_value(&self)?;
<serde_json::Value as serialize::ToSql<Jsonb, Pg>>::to_sql(&value, &mut out.reborrow())
}
}
@ -189,7 +189,7 @@ impl deserialize::FromSql<Jsonb, Pg> for RelayParams {
#[cfg(feature = "postgres")]
impl serialize::ToSql<Jsonb, Pg> for RelayParams {
fn to_sql<'b>(&'b self, out: &mut serialize::Output<'b, '_, Pg>) -> serialize::Result {
let value = serde_json::to_value(self)?;
let value = serde_json::to_value(&self)?;
<serde_json::Value as serialize::ToSql<Jsonb, Pg>>::to_sql(&value, &mut out.reborrow())
}
}
@ -263,9 +263,14 @@ impl Default for AppLayerParams {
impl AppLayerParams {
pub fn is_app_layer_f_port(&self, f_port: u8) -> bool {
(self.ts003_version.is_some() && self.ts003_f_port == f_port)
if (self.ts003_version.is_some() && self.ts003_f_port == f_port)
|| (self.ts004_version.is_some() && self.ts004_f_port == f_port)
|| (self.ts005_version.is_some() && self.ts005_f_port == f_port)
{
true
} else {
false
}
}
}
@ -280,7 +285,7 @@ impl deserialize::FromSql<Jsonb, Pg> for AppLayerParams {
#[cfg(feature = "postgres")]
impl serialize::ToSql<Jsonb, Pg> for AppLayerParams {
fn to_sql<'b>(&'b self, out: &mut serialize::Output<'b, '_, Pg>) -> serialize::Result {
let value = serde_json::to_value(self)?;
let value = serde_json::to_value(&self)?;
<serde_json::Value as serialize::ToSql<Jsonb, Pg>>::to_sql(&value, &mut out.reborrow())
}
}

View File

@ -1,6 +1,5 @@
mod big_decimal;
mod dev_nonces;
pub mod device;
pub mod device_profile;
mod device_session;
mod fuota;

View File

@ -336,7 +336,7 @@ pub async fn add_devices(fuota_deployment_id: Uuid, dev_euis: Vec<EUI64>) -> Res
if errors.is_empty() {
Ok(())
} else {
Err(Error::Multi(errors))
Err(Error::MultiError(errors))
}
}
@ -552,7 +552,7 @@ pub async fn add_gateways(fuota_deployment_id: Uuid, gateway_ids: Vec<EUI64>) ->
if errors.is_empty() {
Ok(())
} else {
Err(Error::Multi(errors))
Err(Error::MultiError(errors))
}
}
@ -789,7 +789,7 @@ pub fn get_multicast_timeout(d: &FuotaDeployment) -> Result<usize> {
conf.network.scheduler.multicast_class_c_margin.as_secs() as usize;
// Multiply by the number of fragments (+1 for additional margin).
let mc_class_c_duration_secs = mc_class_c_margin_secs * (total_fragments + 1);
let mc_class_c_duration_secs = mc_class_c_margin_secs * (total_fragments + 1 as usize);
// Calculate the timeout value. In case of Class-C, timeout is defined as seconds,
// where the number of seconds is 2^timeout.

View File

@ -1012,7 +1012,7 @@ pub mod test {
// invalid f_port
assert!(enqueue(
MulticastGroupQueueItem {
multicast_group_id: mg.id,
multicast_group_id: mg.id.into(),
gateway_id: gw.gateway_id,
f_cnt: 1,
f_port: 0,
@ -1026,7 +1026,7 @@ pub mod test {
assert!(enqueue(
MulticastGroupQueueItem {
multicast_group_id: mg.id,
multicast_group_id: mg.id.into(),
gateway_id: gw.gateway_id,
f_cnt: 1,
f_port: 256,
@ -1041,7 +1041,7 @@ pub mod test {
// Enqueue (Class-C) (delay)
let (ids, f_cnt) = enqueue(
MulticastGroupQueueItem {
multicast_group_id: mg.id,
multicast_group_id: mg.id.into(),
gateway_id: gw.gateway_id,
f_cnt: 1,
f_port: 2,
@ -1071,7 +1071,7 @@ pub mod test {
let mut mg = update(mg).await.unwrap();
let (ids, f_cnt) = enqueue(
MulticastGroupQueueItem {
multicast_group_id: mg.id,
multicast_group_id: mg.id.into(),
gateway_id: gw.gateway_id,
f_cnt: 1,
f_port: 2,
@ -1098,7 +1098,7 @@ pub mod test {
let mg = update(mg).await.unwrap();
let (ids, f_cnt) = enqueue(
MulticastGroupQueueItem {
multicast_group_id: mg.id,
multicast_group_id: mg.id.into(),
gateway_id: gw.gateway_id,
f_cnt: 1,
f_port: 2,

View File

@ -65,7 +65,6 @@ diesel::table! {
join_eui -> Bytea,
secondary_dev_addr -> Nullable<Bytea>,
device_session -> Nullable<Bytea>,
app_layer_params -> Jsonb,
}
}

View File

@ -60,7 +60,6 @@ diesel::table! {
join_eui -> Binary,
secondary_dev_addr -> Nullable<Binary>,
device_session -> Nullable<Binary>,
app_layer_params -> Text,
}
}

View File

@ -449,8 +449,8 @@ pub mod test {
let _d = device::create(device::Device {
dev_eui: EUI64::from_str("0203040506070809").unwrap(),
name: "test-device".into(),
application_id: a.id,
device_profile_id: dp.id,
application_id: a.id.clone(),
device_profile_id: dp.id.clone(),
tags: build_tags(&[("common_tag", "value"), ("mytag", "dev_value")]),
..Default::default()
})

View File

@ -325,6 +325,7 @@ pub mod test {
use crate::storage::user::test::create_user;
use crate::test;
use chrono::SubsecRound;
use std::str::FromStr;
use uuid::Uuid;
struct FilterTest<'a> {
@ -356,19 +357,10 @@ pub mod test {
async fn test_tenant() {
let _guard = test::prepare().await;
// delete existing tenants.
let tenants = list(
10,
0,
&Filters {
..Default::default()
},
)
.await
.unwrap();
for t in &tenants {
delete(&t.id).await.unwrap();
}
// delete default tenant
delete(&Uuid::from_str("52f14cd4-c6f1-4fbd-8f87-4025e1d49242").unwrap())
.await
.unwrap();
let mut t = create_tenant().await;
@ -387,7 +379,7 @@ pub mod test {
let tu = TenantUser {
tenant_id: t.id,
user_id: user.id,
user_id: user.id.into(),
is_admin: true,
..Default::default()
};
@ -488,7 +480,7 @@ pub mod test {
let tu = TenantUser {
tenant_id: t.id,
user_id: user.id,
user_id: user.id.into(),
is_admin: true,
..Default::default()
};

View File

@ -14,6 +14,7 @@ use crate::storage::{get_async_redis_conn, redis_key};
use chirpstack_api::{api, integration};
#[allow(clippy::enum_variant_names)]
pub async fn log_event_for_device(typ: &str, dev_eui: &str, b: &[u8]) -> Result<()> {
let conf = config::get();

View File

@ -150,7 +150,7 @@ async fn test_fns_uplink() {
// Simulate uplink
uplink::handle_uplink(
CommonName::EU868,
"eu868",
"eu868".into(),
Uuid::new_v4(),
gw::UplinkFrameSet {
phy_payload: data_phy.to_vec().unwrap(),

View File

@ -5558,7 +5558,7 @@ async fn run_test(t: &Test) {
uplink::handle_uplink(
CommonName::EU868,
"eu868",
"eu868".into(),
Uuid::new_v4(),
gw::UplinkFrameSet {
phy_payload: t.phy_payload.to_vec().unwrap(),

View File

@ -462,7 +462,7 @@ async fn run_uplink_test(t: &UplinkTest) {
uplink::handle_uplink(
CommonName::EU868,
"eu868",
"eu868".into(),
Uuid::new_v4(),
gw::UplinkFrameSet {
phy_payload: t.phy_payload.to_vec().unwrap(),

View File

@ -367,7 +367,7 @@ async fn run_test(t: &Test) {
uplink::handle_uplink(
CommonName::EU868,
"eu868",
"eu868".into(),
Uuid::new_v4(),
gw::UplinkFrameSet {
phy_payload: t.phy_payload.to_vec().unwrap(),

View File

@ -190,7 +190,7 @@ async fn test_fns() {
// Simulate uplink
uplink::handle_uplink(
CommonName::EU868,
"eu868",
"eu868".into(),
Uuid::new_v4(),
gw::UplinkFrameSet {
phy_payload: jr_phy.to_vec().unwrap(),

View File

@ -1250,7 +1250,7 @@ async fn run_test(t: &Test) {
uplink::handle_uplink(
CommonName::EU868,
"eu868",
"eu868".into(),
Uuid::new_v4(),
gw::UplinkFrameSet {
phy_payload: t.phy_payload.to_vec().unwrap(),

View File

@ -821,7 +821,7 @@ async fn run_test(t: &Test) {
uplink::handle_uplink(
CommonName::EU868,
"eu868",
"eu868".into(),
Uuid::new_v4(),
gw::UplinkFrameSet {
phy_payload: t.phy_payload.to_vec().unwrap(),

View File

@ -220,7 +220,7 @@ async fn test_lorawan_10() {
uplink::handle_uplink(
CommonName::EU868,
"eu868",
"eu868".into(),
Uuid::new_v4(),
gw::UplinkFrameSet {
phy_payload: phy_relay_jr.to_vec().unwrap(),
@ -293,7 +293,8 @@ async fn test_lorawan_10() {
nb_trans: 1,
region_config_id: "eu868".to_string(),
..Default::default()
},
}
.into(),
),
assert::downlink_frame(gw::DownlinkFrame {
items: vec![

View File

@ -51,8 +51,8 @@ lazy_static! {
);
counter
};
static ref DEDUPLICATE_LOCKED_COUNTER: Counter = {
let counter = Counter::default();
static ref DEDUPLICATE_LOCKED_COUNTER: Family<(), Counter> = {
let counter = Family::<(), Counter>::default();
prometheus::register(
"deduplicate_locked_count",
"Number of times the deduplication function was called and the deduplication was already locked",
@ -60,8 +60,8 @@ lazy_static! {
);
counter
};
static ref DEDUPLICATE_NO_LOCK_COUNTER: Counter = {
let counter = Counter::default();
static ref DEDUPLICATE_NO_LOCK_COUNTER: Family<(), Counter> = {
let counter = Family::<(), Counter>::default();
prometheus::register(
"deduplicate_no_lock_count",
"Number of times the deduplication function was called and it was not yet locked",
@ -203,12 +203,12 @@ async fn _deduplicate_uplink(
"Deduplication is already locked by an other process"
);
DEDUPLICATE_LOCKED_COUNTER.inc();
DEDUPLICATE_LOCKED_COUNTER.get_or_create(&()).inc();
return Ok(());
}
DEDUPLICATE_NO_LOCK_COUNTER.inc();
DEDUPLICATE_NO_LOCK_COUNTER.get_or_create(&()).inc();
trace!(
key = key.as_str(),

View File

@ -25,7 +25,7 @@ services:
- "8080:8080"
postgres:
image: postgres:13-alpine
image: postgres:11-alpine
volumes:
- ./.docker-compose/postgresql/initdb:/docker-entrypoint-initdb.d
environment:

View File

@ -1,145 +0,0 @@
export function name() {
return "JS example for default ADR algorithm";
}
export function id() {
return "js_example_default";
}
export function handle(req) {
let resp = {
dr: req.dr,
txPowerIndex: req.txPowerIndex,
nbTrans: req.nbTrans,
};
if (!req.adr) {
return resp;
}
if (req.dr > req.maxDr) {
resp.dr = req.maxDr;
}
// Set the new Nb Trans.
resp.nbTrans = getNbTrans(req.nbTrans, getPacketLossPercentage(req));
// Calculate the number of steps.
let snrMax = getMaxSnr(req);
let snrMargin = snrMax - req.requiredSnrForDr - req.installationMargin;
let nStep = Math.floor(snrMargin / 3);
// In case of negative steps the ADR algorithm will increase the TxPower
// if possible. To avoid up / down / up / down TxPower changes, wait until
// we have at least the required number of uplink history elements.
if (nStep < 0 && getHistoryCount(req) != requiredHistoryCount()) {
return resp;
}
let [desiredTxPowerIndex, desiredDr] = getIdealTxPowerIndexAndDr(
nStep,
resp.txPowerIndex,
resp.dr,
req.maxTxPowerIndex,
req.maxDr,
);
resp.dr = desiredDr;
resp.txPowerIndex = desiredTxPowerIndex;
return resp;
}
function getIdealTxPowerIndexAndDr(nbStep, txPowerIndex, dr, maxTxPowerIndex, maxDr) {
while (nbStep !== 0) {
if (nbStep > 0) {
if (dr < maxDr) {
// Increase the DR.
dr++;
} else if (txPowerIndex < maxTxPowerIndex) {
// Decrease the Tx Power.
txPowerIndex++;
}
nbStep--;
} else {
// Incease the TxPower.
if (txPowerIndex > 0) {
txPowerIndex--;
}
nbStep++;
}
}
return [txPowerIndex, dr];
}
function requiredHistoryCount() {
return 20;
}
function getHistoryCount(req) {
let count = 0;
for (let uh of req.uplinkHistory) {
if (uh.txPowerIndex === req.txPowerIndex) {
count++;
}
}
return count;
}
function getMaxSnr(req) {
let maxSnr = -999.0;
for (let uh of req.uplinkHistory) {
if (uh.maxSnr > maxSnr) {
maxSnr = uh.maxSnr;
}
}
return maxSnr;
}
function getNbTrans(currentNbTrans, pktLossRate) {
const pktLossTable = [
[1, 1, 2],
[1, 2, 3],
[2, 3, 3],
[3, 3, 3],
];
if (currentNbTrans < 1) {
currentNbTrans = 1;
}
if (currentNbTrans > 3) {
currentNbTrans = 3;
}
const nbTransIndex = currentNbTrans - 1;
if (pktLossRate < 5.0) {
return pktLossTable[0][nbTransIndex];
} else if (pktLossRate < 10.0) {
return pktLossTable[1][nbTransIndex];
} else if (pktLossRate < 30.0) {
return pktLossTable[2][nbTransIndex];
}
return pktLossTable[3][nbTransIndex];
}
function getPacketLossPercentage(req) {
if (req.uplinkHistory.length < requiredHistoryCount()) {
return 0.0;
}
let lostPackets = 0;
let previousFCnt = req.uplinkHistory[0].fCnt;
for (let uh of req.uplinkHistory.slice(1)) {
lostPackets += uh.fCnt - previousFCnt - 1;
previousFCnt = uh.fCnt;
}
return lostPackets / req.uplinkHistory.length * 100.0;
}

View File

@ -12,6 +12,6 @@ require (
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/google/go-cmp v0.5.9 // indirect
golang.org/x/net v0.36.0 // indirect
golang.org/x/sys v0.30.0 // indirect
golang.org/x/net v0.33.0 // indirect
golang.org/x/sys v0.28.0 // indirect
)

View File

@ -12,11 +12,11 @@ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA=
golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I=
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=

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.12.0-test.3"
version = "4.12.0-test.2"
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.12.0-test.3"
version = "4.12.0-test.2"
authors = ["Orne Brocaar <info@brocaar.com>"]
edition = "2018"
repository = "https://github.com/chirpstack/chirpstack"
@ -22,6 +22,9 @@
thiserror = "2.0"
anyhow = "1.0"
# Misc
lazy_static = "1.5"
[features]
default = []
diesel = ["dep:diesel", "serde"]

View File

@ -95,7 +95,7 @@ impl<'de> Deserialize<'de> for AES128Key {
struct Aes128KeyVisitor;
#[cfg(feature = "serde")]
impl Visitor<'_> for Aes128KeyVisitor {
impl<'de> Visitor<'de> for Aes128KeyVisitor {
type Value = AES128Key;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {

View File

@ -266,7 +266,7 @@ impl PayloadCodec for FragSessionSetupReqPayload {
mc_group_bit_mask: {
let mut mask = [false; 4];
for (i, v) in mask.iter_mut().enumerate() {
*v = b[0] & (1 << i) != 0;
*v = b[0] & 1 << i != 0;
}
mask
},

View File

@ -302,7 +302,7 @@ impl PayloadCodec for FragSessionSetupReqPayload {
mc_group_bit_mask: {
let mut mask = [false; 4];
for (i, v) in mask.iter_mut().enumerate() {
*v = b[0] & (1 << i) != 0;
*v = b[0] & 1 << i != 0;
}
mask
},

View File

@ -92,7 +92,7 @@ impl<'de> Deserialize<'de> for DevAddrPrefix {
struct DevAddrPrefixVisitor;
#[cfg(feature = "serde")]
impl Visitor<'_> for DevAddrPrefixVisitor {
impl<'de> Visitor<'de> for DevAddrPrefixVisitor {
type Value = DevAddrPrefix;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {

View File

@ -103,7 +103,7 @@ impl<'de> Deserialize<'de> for EUI64 {
struct Eui64Visitor;
#[cfg(feature = "serde")]
impl Visitor<'_> for Eui64Visitor {
impl<'de> Visitor<'de> for Eui64Visitor {
type Value = EUI64;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
@ -251,7 +251,7 @@ impl<'de> Deserialize<'de> for EUI64Prefix {
struct EUI64PrefixVisitor;
#[cfg(feature = "serde")]
impl Visitor<'_> for EUI64PrefixVisitor {
impl<'de> Visitor<'de> for EUI64PrefixVisitor {
type Value = EUI64Prefix;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {

View File

@ -3,6 +3,8 @@
extern crate diesel;
#[macro_use]
extern crate anyhow;
#[macro_use]
extern crate lazy_static;
pub use self::aes128::*;
pub use self::cflist::*;
@ -41,24 +43,26 @@ mod relay;
pub const LA_FPORT_RELAY: u8 = 226;
const EIRP_INDEX: [f32; 16] = [
8.0, // 0
10.0, // 1
12.0, // 2
13.0, // 3
14.0, // 4
16.0, // 5
18.0, // 6
20.0, // 7
21.0, // 8
24.0, // 9
26.0, // 10
27.0, // 11
29.0, // 12
30.0, // 13
33.0, // 14
36.0, // 15
];
lazy_static! {
static ref EIRP_INDEX: Vec<f32> = vec![
8.0, // 0
10.0, // 1
12.0, // 2
13.0, // 3
14.0, // 4
16.0, // 5
18.0, // 6
20.0, // 7
21.0, // 8
24.0, // 9
26.0, // 10
27.0, // 11
29.0, // 12
30.0, // 13
33.0, // 14
36.0, // 15
];
}
pub fn get_tx_param_setup_eirp_index(eirp: f32) -> u8 {
let mut out: u8 = 0;

View File

@ -1910,7 +1910,7 @@ impl ChannelSettingsED {
ChannelSettingsED {
second_ch_ack_offset: b[0] & 0x07,
second_ch_dr: (b[0] & 0x78) >> 3,
second_ch_idx: ((b[0] & 0x80) >> 7) | ((b[1] & 0x01) << 1),
second_ch_idx: (b[0] & 0x80) >> 7 | (b[1] & 0x01) << 1,
backoff: (b[1] & 0x7e) >> 1,
}
}
@ -2419,7 +2419,7 @@ impl PowerLevel {
let wor_snr = (wor_snr + 20) as u8;
let wor_rssi = -(wor_rssi + 15) as u8;
[wor_snr | (wor_rssi << 5), wor_rssi >> 3]
[wor_snr | wor_rssi << 5, wor_rssi >> 3]
}
}

View File

@ -161,7 +161,7 @@ impl<'de> Deserialize<'de> for NetID {
struct NetIdVisitor;
#[cfg(feature = "serde")]
impl Visitor<'_> for NetIdVisitor {
impl<'de> Visitor<'de> for NetIdVisitor {
type Value = NetID;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {

View File

@ -892,7 +892,7 @@ impl Region for Configuration {
min_dr
} else {
dr as u8
};
} as u8;
Ok(if dr > 5 { 5 } else { dr })
}

View File

@ -40,11 +40,7 @@ impl UplinkMetadata {
let snr = (snr + 20) as u8;
let rssi = -(rssi + 15) as u8;
Ok([
self.dr | (snr << 4),
(snr >> 4) | (rssi << 1),
self.wor_channel,
])
Ok([self.dr | snr << 4, snr >> 4 | rssi << 1, self.wor_channel])
}
}

View File

@ -21,7 +21,6 @@ pkgs.mkShell {
pkgs.sqlite # sqlite binary + library for diesel
pkgs.postgresql # psql binary + library for diesel
pkgs.cargo-cross # cross-compiling
pkgs.cargo-deb # deb packaging
pkgs.diesel-cli # diesel cli
];
LIBCLANG_PATH = "${pkgs.llvmPackages.libclang.lib}/lib";

View File

@ -1,6 +1,6 @@
{
"name": "chirpstack-ui",
"version": "4.12.0-test.3",
"version": "4.12.0-test.2",
"private": true,
"type": "module",
"scripts": {
@ -51,12 +51,12 @@
"@types/react-dom": "^18.3.0",
"@typescript-eslint/eslint-plugin": "^7.13.1",
"@typescript-eslint/parser": "^7.13.1",
"@vitejs/plugin-react-swc": "^3.9.0",
"@vitejs/plugin-react-swc": "^3.5.0",
"eslint": "^8.57.0",
"eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-react-refresh": "^0.4.7",
"prettier": "^3.3.2",
"typescript": "^5.2.2",
"vite": "^6.2.6"
"vite": "^5.4.12"
}
}

View File

@ -168,7 +168,7 @@ function FuotaDeploymentLayout(props: IProps) {
description="Are you sure you want to start the deploymen? Once started, you will not be able to make changes."
onConfirm={startFuotaDeployment}
>
<Button type="primary" disabled={getFuotaDeploymentResponse.getStartedAt() !== undefined}>Start deployment</Button>
<Button type="primary">Start deployment</Button>
</Popconfirm>
<DeleteConfirm typ="FUOTA deployment" confirm={d.getName()} onConfirm={deleteFuotaDeployment}>
<Button danger type="primary">

File diff suppressed because it is too large Load Diff