mirror of
https://github.com/chirpstack/chirpstack.git
synced 2025-04-17 20:50:14 +00:00
Compare commits
10 Commits
v4.9.0-tes
...
v4.9.0-tes
Author | SHA1 | Date | |
---|---|---|---|
a811ec5c80 | |||
5794f41324 | |||
7158c0c610 | |||
eda6646b18 | |||
40a2b83bf5 | |||
4e0106a4e8 | |||
98978135c4 | |||
6a691c62e2 | |||
66ab41036b | |||
dc57e6fe51 |
1612
Cargo.lock
generated
1612
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -13,3 +13,7 @@
|
||||
opt-level = 'z'
|
||||
lto = true
|
||||
codegen-units = 1
|
||||
|
||||
|
||||
[patch.crates-io]
|
||||
deadpool-redis = { git = "https://github.com/bikeshedder/deadpool.git", rev = "6c361a306059bc8b0d3426515991e253015af6be" }
|
||||
|
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.9.0-test.5",
|
||||
"version": "4.9.0-test.6",
|
||||
"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.9.0-test.5"
|
||||
version = "4.9.0-test.6"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
|
2
api/js/package.json
vendored
2
api/js/package.json
vendored
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@chirpstack/chirpstack-api",
|
||||
"version": "4.9.0-test.5",
|
||||
"version": "4.9.0-test.6",
|
||||
"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.9.0-test.5"
|
||||
version = "4.9.0-test.6"
|
||||
|
||||
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.9.0-test.5",
|
||||
"version": "4.9.0-test.6",
|
||||
"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.9.0-test.5",
|
||||
version = "4.9.0-test.6",
|
||||
url='https://github.com/brocaar/chirpstack-api',
|
||||
author='Orne Brocaar',
|
||||
author_email='info@brocaar.com',
|
||||
|
16
api/rust/Cargo.toml
vendored
16
api/rust/Cargo.toml
vendored
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "chirpstack_api"
|
||||
description = "ChirpStack Protobuf / gRPC API definitions."
|
||||
version = "4.9.0-test.5"
|
||||
version = "4.9.0-test.6"
|
||||
authors = ["Orne Brocaar <info@brocaar.com>"]
|
||||
license = "MIT"
|
||||
homepage = "https://www.chirpstack.io"
|
||||
@ -16,23 +16,23 @@
|
||||
internal = []
|
||||
|
||||
[dependencies]
|
||||
prost = "0.12"
|
||||
prost-types = "0.12"
|
||||
prost = "0.13"
|
||||
prost-types = "0.13"
|
||||
hex = "0.4"
|
||||
rand = "0.8"
|
||||
|
||||
tonic = { version = "0.11", features = [
|
||||
tonic = { version = "0.12", features = [
|
||||
"codegen",
|
||||
"prost",
|
||||
], default-features = false, optional = true }
|
||||
tokio = { version = "1.38", features = ["macros"], optional = true }
|
||||
pbjson = { version = "0.6", optional = true }
|
||||
pbjson-types = { version = "0.6", optional = true }
|
||||
pbjson = { version = "0.7", optional = true }
|
||||
pbjson-types = { version = "0.7", optional = true }
|
||||
serde = { version = "1.0", optional = true }
|
||||
diesel = { version = "2.2", features = ["postgres_backend"], optional = true }
|
||||
|
||||
[build-dependencies]
|
||||
tonic-build = { version = "0.11", features = [
|
||||
tonic-build = { version = "0.12", features = [
|
||||
"prost",
|
||||
], default-features = false }
|
||||
pbjson-build = "0.6"
|
||||
pbjson-build = "0.7"
|
||||
|
24
api/rust/src/gw.rs
vendored
24
api/rust/src/gw.rs
vendored
@ -95,7 +95,7 @@ impl UplinkFrame {
|
||||
})
|
||||
}
|
||||
uplink_tx_info_legacy::ModulationInfo::FskModulationInfo(info) => {
|
||||
modulation::Parameters::Fsk(info.clone())
|
||||
modulation::Parameters::Fsk(*info)
|
||||
}
|
||||
uplink_tx_info_legacy::ModulationInfo::LrFhssModulationInfo(info) => {
|
||||
modulation::Parameters::LrFhss(LrFhssModulationInfo {
|
||||
@ -120,9 +120,9 @@ impl UplinkFrame {
|
||||
self.rx_info = Some(UplinkRxInfo {
|
||||
gateway_id: hex::encode(&rx_info.gateway_id),
|
||||
uplink_id: rng.gen::<u32>(),
|
||||
gw_time: rx_info.time.clone(),
|
||||
gw_time: rx_info.time,
|
||||
ns_time: None,
|
||||
time_since_gps_epoch: rx_info.time_since_gps_epoch.clone(),
|
||||
time_since_gps_epoch: rx_info.time_since_gps_epoch,
|
||||
fine_time_since_gps_epoch: None,
|
||||
rssi: rx_info.rssi,
|
||||
snr: rx_info.lora_snr as f32,
|
||||
@ -130,7 +130,7 @@ impl UplinkFrame {
|
||||
rf_chain: rx_info.rf_chain,
|
||||
board: rx_info.board,
|
||||
antenna: rx_info.antenna,
|
||||
location: rx_info.location.clone(),
|
||||
location: rx_info.location,
|
||||
context: rx_info.context.clone(),
|
||||
metadata: rx_info.metadata.clone(),
|
||||
crc_status: rx_info.crc_status,
|
||||
@ -195,23 +195,19 @@ impl DownlinkFrame {
|
||||
Some(timing::Parameters::Immediately(v)) => {
|
||||
tx_info_legacy.timing = DownlinkTiming::Immediately.into();
|
||||
tx_info_legacy.timing_info = Some(
|
||||
downlink_tx_info_legacy::TimingInfo::ImmediatelyTimingInfo(
|
||||
v.clone(),
|
||||
),
|
||||
downlink_tx_info_legacy::TimingInfo::ImmediatelyTimingInfo(*v),
|
||||
);
|
||||
}
|
||||
Some(timing::Parameters::Delay(v)) => {
|
||||
tx_info_legacy.timing = DownlinkTiming::Delay.into();
|
||||
tx_info_legacy.timing_info = Some(
|
||||
downlink_tx_info_legacy::TimingInfo::DelayTimingInfo(v.clone()),
|
||||
);
|
||||
tx_info_legacy.timing_info =
|
||||
Some(downlink_tx_info_legacy::TimingInfo::DelayTimingInfo(*v));
|
||||
}
|
||||
Some(timing::Parameters::GpsEpoch(v)) => {
|
||||
tx_info_legacy.timing = DownlinkTiming::GpsEpoch.into();
|
||||
tx_info_legacy.timing_info =
|
||||
Some(downlink_tx_info_legacy::TimingInfo::GpsEpochTimingInfo(
|
||||
v.clone(),
|
||||
));
|
||||
tx_info_legacy.timing_info = Some(
|
||||
downlink_tx_info_legacy::TimingInfo::GpsEpochTimingInfo(*v),
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "backend"
|
||||
version = "4.9.0-test.5"
|
||||
version = "4.9.0-test.6"
|
||||
authors = ["Orne Brocaar <info@brocaar.com>"]
|
||||
edition = "2018"
|
||||
publish = false
|
||||
|
@ -3,14 +3,14 @@
|
||||
description = "Library for building external ChirpStack integrations"
|
||||
homepage = "https://www.chirpstack.io/"
|
||||
license = "MIT"
|
||||
version = "4.9.0-test.5"
|
||||
version = "4.9.0-test.6"
|
||||
authors = ["Orne Brocaar <info@brocaar.com>"]
|
||||
edition = "2021"
|
||||
repository = "https://github.com/chirpstack/chirpstack"
|
||||
|
||||
[dependencies]
|
||||
chirpstack_api = { path = "../api/rust", version = "4.9.0-test.1" }
|
||||
redis = { version = "0.25", features = [
|
||||
redis = { version = "0.26", features = [
|
||||
"cluster-async",
|
||||
"tokio-rustls-comp",
|
||||
] }
|
||||
|
@ -215,7 +215,7 @@ impl Integration {
|
||||
info!(key = %k, "Event received from Redis stream");
|
||||
match k.as_ref() {
|
||||
"up" => {
|
||||
if let redis::Value::Data(b) = v {
|
||||
if let redis::Value::BulkString(b) = v {
|
||||
let pl = integration_pb::UplinkEvent::decode(
|
||||
&mut Cursor::new(b),
|
||||
)?;
|
||||
@ -223,21 +223,21 @@ impl Integration {
|
||||
}
|
||||
}
|
||||
"join" => {
|
||||
if let redis::Value::Data(b) = v {
|
||||
if let redis::Value::BulkString(b) = v {
|
||||
let pl =
|
||||
integration_pb::JoinEvent::decode(&mut Cursor::new(b))?;
|
||||
tokio::spawn(join_event(pl));
|
||||
}
|
||||
}
|
||||
"ack" => {
|
||||
if let redis::Value::Data(b) = v {
|
||||
if let redis::Value::BulkString(b) = v {
|
||||
let pl =
|
||||
integration_pb::AckEvent::decode(&mut Cursor::new(b))?;
|
||||
tokio::spawn(ack_event(pl));
|
||||
}
|
||||
}
|
||||
"txack" => {
|
||||
if let redis::Value::Data(b) = v {
|
||||
if let redis::Value::BulkString(b) = v {
|
||||
let pl = integration_pb::TxAckEvent::decode(
|
||||
&mut Cursor::new(b),
|
||||
)?;
|
||||
@ -245,7 +245,7 @@ impl Integration {
|
||||
}
|
||||
}
|
||||
"status" => {
|
||||
if let redis::Value::Data(b) = v {
|
||||
if let redis::Value::BulkString(b) = v {
|
||||
let pl = integration_pb::StatusEvent::decode(
|
||||
&mut Cursor::new(b),
|
||||
)?;
|
||||
@ -253,14 +253,14 @@ impl Integration {
|
||||
}
|
||||
}
|
||||
"log" => {
|
||||
if let redis::Value::Data(b) = v {
|
||||
if let redis::Value::BulkString(b) = v {
|
||||
let pl =
|
||||
integration_pb::LogEvent::decode(&mut Cursor::new(b))?;
|
||||
tokio::spawn(log_event(pl));
|
||||
}
|
||||
}
|
||||
"location" => {
|
||||
if let redis::Value::Data(b) = v {
|
||||
if let redis::Value::BulkString(b) = v {
|
||||
let pl = integration_pb::LocationEvent::decode(
|
||||
&mut Cursor::new(b),
|
||||
)?;
|
||||
@ -268,7 +268,7 @@ impl Integration {
|
||||
}
|
||||
}
|
||||
"integration" => {
|
||||
if let redis::Value::Data(b) = v {
|
||||
if let redis::Value::BulkString(b) = v {
|
||||
let pl = integration_pb::IntegrationEvent::decode(
|
||||
&mut Cursor::new(b),
|
||||
)?;
|
||||
|
@ -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.9.0-test.5"
|
||||
version = "4.9.0-test.6"
|
||||
authors = ["Orne Brocaar <info@brocaar.com>"]
|
||||
edition = "2021"
|
||||
publish = false
|
||||
@ -39,9 +39,9 @@
|
||||
"async-connection-wrapper",
|
||||
] }
|
||||
tokio-postgres = "0.7"
|
||||
tokio-postgres-rustls = "0.11"
|
||||
tokio-postgres-rustls = "0.12"
|
||||
bigdecimal = "0.4"
|
||||
redis = { version = "0.25.2", features = ["tls-rustls", "tokio-rustls-comp"] }
|
||||
redis = { version = "0.26", features = ["tls-rustls", "tokio-rustls-comp"] }
|
||||
deadpool-redis = { version = "0.15", features = ["cluster"] }
|
||||
|
||||
# Logging
|
||||
@ -78,8 +78,8 @@
|
||||
sha2 = "0.10"
|
||||
urlencoding = "2.1"
|
||||
geohash = "0.13"
|
||||
gcp_auth = "0.11"
|
||||
lapin = "2.3"
|
||||
gcp_auth = "0.12"
|
||||
lapin = { version = "2.5", default-features = false }
|
||||
tokio-executor-trait = "2.1"
|
||||
tokio-reactor-trait = "1.1"
|
||||
rdkafka = { version = "0.36", default-features = false, features = [
|
||||
@ -88,26 +88,26 @@
|
||||
] }
|
||||
|
||||
# gRPC and Protobuf
|
||||
tonic = "0.11"
|
||||
tonic-web = "0.11"
|
||||
tonic-reflection = "0.11"
|
||||
tonic = "0.12"
|
||||
tonic-web = "0.12"
|
||||
tonic-reflection = "0.12"
|
||||
tokio = { version = "1.38", features = ["macros", "rt-multi-thread"] }
|
||||
tokio-stream = "0.1"
|
||||
prost-types = "0.12"
|
||||
prost = "0.12"
|
||||
pbjson-types = "0.6"
|
||||
prost-types = "0.13"
|
||||
prost = "0.13"
|
||||
pbjson-types = "0.7"
|
||||
|
||||
# gRPC and HTTP multiplexing
|
||||
warp = { version = "0.3", features = ["tls"], default-features = false }
|
||||
hyper = "0.14"
|
||||
tower = "0.4"
|
||||
axum = "0.7"
|
||||
axum-server = { version = "0.7.1", features = ["tls-rustls-no-provider"] }
|
||||
tower = { version = "0.4" }
|
||||
futures = "0.3"
|
||||
futures-util = "0.3"
|
||||
http = "0.2"
|
||||
http-body = "0.4"
|
||||
http = "1.1"
|
||||
http-body = "1.0"
|
||||
rust-embed = "8.5"
|
||||
mime_guess = "2.0"
|
||||
tower-http = { version = "0.4", features = ["trace", "auth"] }
|
||||
tower-http = { version = "0.5", features = ["trace", "auth"] }
|
||||
|
||||
# Error handling
|
||||
thiserror = "1.0"
|
||||
@ -117,7 +117,12 @@
|
||||
pbkdf2 = { version = "0.12", features = ["simple"] }
|
||||
rand_core = { version = "0.6", features = ["std"] }
|
||||
jsonwebtoken = "9.2"
|
||||
rustls = "0.22"
|
||||
rustls = { version = "0.23", default-features = false, features = [
|
||||
"logging",
|
||||
"std",
|
||||
"tls12",
|
||||
"ring",
|
||||
] }
|
||||
rustls-native-certs = "0.7"
|
||||
rustls-pemfile = "2.1"
|
||||
pem = "3.0"
|
||||
|
@ -1945,9 +1945,7 @@ pub mod test {
|
||||
}),
|
||||
};
|
||||
let mut create_req = Request::new(create_req);
|
||||
create_req
|
||||
.extensions_mut()
|
||||
.insert(AuthID::User(u.id.clone()));
|
||||
create_req.extensions_mut().insert(AuthID::User(u.id));
|
||||
let create_resp = service.create(create_req).await.unwrap();
|
||||
let create_resp = create_resp.get_ref();
|
||||
|
||||
@ -1956,7 +1954,7 @@ pub mod test {
|
||||
id: create_resp.id.clone(),
|
||||
};
|
||||
let mut get_req = Request::new(get_req);
|
||||
get_req.extensions_mut().insert(AuthID::User(u.id.clone()));
|
||||
get_req.extensions_mut().insert(AuthID::User(u.id));
|
||||
let get_resp = service.get(get_req).await.unwrap();
|
||||
assert_eq!(
|
||||
Some(api::Application {
|
||||
@ -1978,7 +1976,7 @@ pub mod test {
|
||||
}),
|
||||
};
|
||||
let mut up_req = Request::new(up_req);
|
||||
up_req.extensions_mut().insert(AuthID::User(u.id.clone()));
|
||||
up_req.extensions_mut().insert(AuthID::User(u.id));
|
||||
let _ = service.update(up_req).await.unwrap();
|
||||
|
||||
//get
|
||||
@ -1986,7 +1984,7 @@ pub mod test {
|
||||
id: create_resp.id.clone(),
|
||||
};
|
||||
let mut get_req = Request::new(get_req);
|
||||
get_req.extensions_mut().insert(AuthID::User(u.id.clone()));
|
||||
get_req.extensions_mut().insert(AuthID::User(u.id));
|
||||
let get_resp = service.get(get_req).await.unwrap();
|
||||
assert_eq!(
|
||||
Some(api::Application {
|
||||
@ -2006,7 +2004,7 @@ pub mod test {
|
||||
offset: 0,
|
||||
};
|
||||
let mut list_req = Request::new(list_req);
|
||||
list_req.extensions_mut().insert(AuthID::User(u.id.clone()));
|
||||
list_req.extensions_mut().insert(AuthID::User(u.id));
|
||||
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());
|
||||
@ -2016,14 +2014,14 @@ pub mod test {
|
||||
id: create_resp.id.clone(),
|
||||
};
|
||||
let mut del_req = Request::new(del_req);
|
||||
del_req.extensions_mut().insert(AuthID::User(u.id.clone()));
|
||||
del_req.extensions_mut().insert(AuthID::User(u.id));
|
||||
let _ = service.delete(del_req).await.unwrap();
|
||||
|
||||
let del_req = api::DeleteApplicationRequest {
|
||||
id: create_resp.id.clone(),
|
||||
};
|
||||
let mut del_req = Request::new(del_req);
|
||||
del_req.extensions_mut().insert(AuthID::User(u.id.clone()));
|
||||
del_req.extensions_mut().insert(AuthID::User(u.id));
|
||||
let del_resp = service.delete(del_req).await;
|
||||
assert!(del_resp.is_err());
|
||||
}
|
||||
@ -2038,7 +2036,7 @@ pub mod test {
|
||||
.unwrap();
|
||||
|
||||
application::create(application::Application {
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
name: "test-app".into(),
|
||||
..Default::default()
|
||||
})
|
||||
@ -2059,7 +2057,7 @@ pub mod test {
|
||||
|
||||
fn get_request<T>(user_id: &Uuid, req: T) -> Request<T> {
|
||||
let mut req = Request::new(req);
|
||||
req.extensions_mut().insert(AuthID::User(user_id.clone()));
|
||||
req.extensions_mut().insert(AuthID::User(*user_id));
|
||||
req
|
||||
}
|
||||
|
||||
|
@ -95,14 +95,11 @@ pub mod test {
|
||||
assert_eq!(claim, decoded);
|
||||
|
||||
// different key
|
||||
assert_eq!(
|
||||
true,
|
||||
AuthClaim::decode(&token, other_secret.as_ref()).is_err()
|
||||
);
|
||||
assert!(AuthClaim::decode(&token, other_secret.as_ref()).is_err());
|
||||
|
||||
// expired
|
||||
claim.exp = Some(exp.timestamp() as usize);
|
||||
let token = claim.encode(secrect.as_ref()).unwrap();
|
||||
assert_eq!(true, AuthClaim::decode(&token, secrect.as_ref()).is_err());
|
||||
assert!(AuthClaim::decode(&token, secrect.as_ref()).is_err());
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ pub mod claims;
|
||||
pub mod error;
|
||||
pub mod validator;
|
||||
|
||||
#[derive(PartialEq, Eq, Debug)]
|
||||
#[derive(PartialEq, Eq, Debug, Clone)]
|
||||
pub enum AuthID {
|
||||
None,
|
||||
User(Uuid),
|
||||
|
@ -2138,7 +2138,7 @@ pub mod test {
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
for u in vec![
|
||||
for u in [
|
||||
&user,
|
||||
&tenant_user,
|
||||
&tenant_admin,
|
||||
@ -2382,7 +2382,7 @@ pub mod test {
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
for u in vec![
|
||||
for u in [
|
||||
&user,
|
||||
&user_admin,
|
||||
&tenant_admin,
|
||||
@ -2654,7 +2654,7 @@ pub mod test {
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
for u in vec![
|
||||
for u in [
|
||||
&user_active,
|
||||
&user_admin,
|
||||
&tenant_admin,
|
||||
@ -2919,7 +2919,7 @@ pub mod test {
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
for u in vec![&user_active, &user_admin] {
|
||||
for u in [&user_active, &user_admin] {
|
||||
user::create(u.clone()).await.unwrap();
|
||||
}
|
||||
|
||||
@ -3075,7 +3075,7 @@ pub mod test {
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
for u in vec![
|
||||
for u in [
|
||||
&user_active,
|
||||
&user_admin,
|
||||
&tenant_admin,
|
||||
@ -3093,14 +3093,14 @@ pub mod test {
|
||||
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "test-dp".into(),
|
||||
tenant_id: tenant_a.id.clone(),
|
||||
tenant_id: tenant_a.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
let dp_api_key_tenant = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "test-dp-tenant".into(),
|
||||
tenant_id: api_key_tenant.tenant_id.unwrap().clone(),
|
||||
tenant_id: api_key_tenant.tenant_id.unwrap(),
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -3378,7 +3378,7 @@ pub mod test {
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
for u in vec![
|
||||
for u in [
|
||||
&user_active,
|
||||
&user_admin,
|
||||
&tenant_admin,
|
||||
@ -3636,7 +3636,7 @@ pub mod test {
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
for u in vec![&user_active, &user_admin, &tenant_user] {
|
||||
for u in [&user_active, &user_admin, &tenant_user] {
|
||||
user::create(u.clone()).await.unwrap();
|
||||
}
|
||||
|
||||
@ -3765,7 +3765,7 @@ pub mod test {
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
for u in vec![
|
||||
for u in [
|
||||
&user_active,
|
||||
&user_admin,
|
||||
&tenant_admin,
|
||||
@ -4038,7 +4038,7 @@ pub mod test {
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
for u in vec![
|
||||
for u in [
|
||||
&user_active,
|
||||
&user_admin,
|
||||
&tenant_admin,
|
||||
|
@ -5,18 +5,28 @@ use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use anyhow::Result;
|
||||
use axum::{
|
||||
body::Bytes,
|
||||
response::{IntoResponse, Json, Response},
|
||||
Router,
|
||||
};
|
||||
use chrono::Utc;
|
||||
use http::StatusCode;
|
||||
use redis::streams::StreamReadReply;
|
||||
use rustls::{
|
||||
server::{NoClientAuth, WebPkiClientVerifier},
|
||||
ServerConfig,
|
||||
};
|
||||
use serde::Serialize;
|
||||
use tokio::sync::oneshot;
|
||||
use tokio::task;
|
||||
use tracing::{error, info, span, warn, Instrument, Level};
|
||||
use uuid::Uuid;
|
||||
use warp::{http::StatusCode, Filter, Reply};
|
||||
|
||||
use crate::backend::{joinserver, keywrap, roaming};
|
||||
use crate::downlink::data_fns;
|
||||
use crate::helpers::errors::PrintFullError;
|
||||
use crate::helpers::tls::{get_root_certs, load_cert, load_key};
|
||||
use crate::storage::{
|
||||
device, error::Error as StorageError, get_async_redis_conn, passive_roaming, redis_key,
|
||||
};
|
||||
@ -39,47 +49,47 @@ pub async fn setup() -> Result<()> {
|
||||
let addr: SocketAddr = conf.backend_interfaces.bind.parse()?;
|
||||
info!(bind = %conf.backend_interfaces.bind, "Setting up backend interfaces API");
|
||||
|
||||
let routes = warp::post()
|
||||
.and(warp::body::content_length_limit(1024 * 16))
|
||||
.and(warp::body::aggregate())
|
||||
.then(handle_request);
|
||||
let app = Router::new().fallback(handle_request);
|
||||
|
||||
if !conf.backend_interfaces.ca_cert.is_empty()
|
||||
|| !conf.backend_interfaces.tls_cert.is_empty()
|
||||
|| !conf.backend_interfaces.tls_key.is_empty()
|
||||
{
|
||||
let mut w = warp::serve(routes).tls();
|
||||
if !conf.backend_interfaces.ca_cert.is_empty() {
|
||||
w = w.client_auth_required_path(&conf.backend_interfaces.ca_cert);
|
||||
}
|
||||
if !conf.backend_interfaces.tls_cert.is_empty() {
|
||||
w = w.cert_path(&conf.backend_interfaces.tls_cert);
|
||||
}
|
||||
if !conf.backend_interfaces.tls_key.is_empty() {
|
||||
w = w.key_path(&conf.backend_interfaces.tls_key);
|
||||
}
|
||||
w.run(addr).await;
|
||||
let mut server_config = ServerConfig::builder()
|
||||
.with_client_cert_verifier(if conf.backend_interfaces.ca_cert.is_empty() {
|
||||
Arc::new(NoClientAuth)
|
||||
} else {
|
||||
let root_certs = get_root_certs(Some(conf.backend_interfaces.ca_cert.clone()))?;
|
||||
WebPkiClientVerifier::builder(root_certs.into()).build()?
|
||||
})
|
||||
.with_single_cert(
|
||||
load_cert(&conf.backend_interfaces.tls_cert).await?,
|
||||
load_key(&conf.backend_interfaces.tls_key).await?,
|
||||
)?;
|
||||
server_config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
|
||||
|
||||
axum_server::bind_rustls(
|
||||
addr,
|
||||
axum_server::tls_rustls::RustlsConfig::from_config(Arc::new(server_config)),
|
||||
)
|
||||
.serve(app.into_make_service())
|
||||
.await?;
|
||||
} else {
|
||||
warp::serve(routes).run(addr).await;
|
||||
axum_server::bind(addr)
|
||||
.serve(app.into_make_service())
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn handle_request(mut body: impl warp::Buf) -> http::Response<hyper::Body> {
|
||||
let mut b: Vec<u8> = vec![];
|
||||
|
||||
while body.has_remaining() {
|
||||
b.extend_from_slice(body.chunk());
|
||||
let cnt = body.chunk().len();
|
||||
body.advance(cnt);
|
||||
}
|
||||
pub async fn handle_request(b: Bytes) -> Response {
|
||||
let b: Vec<u8> = b.into();
|
||||
|
||||
let bp: BasePayload = match serde_json::from_slice(&b) {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
return warp::reply::with_status(e.to_string(), StatusCode::BAD_REQUEST)
|
||||
.into_response();
|
||||
return (StatusCode::BAD_REQUEST, e.to_string()).into_response();
|
||||
}
|
||||
};
|
||||
|
||||
@ -87,7 +97,7 @@ pub async fn handle_request(mut body: impl warp::Buf) -> http::Response<hyper::B
|
||||
_handle_request(bp, b).instrument(span).await
|
||||
}
|
||||
|
||||
pub async fn _handle_request(bp: BasePayload, b: Vec<u8>) -> http::Response<hyper::Body> {
|
||||
pub async fn _handle_request(bp: BasePayload, b: Vec<u8>) -> Response {
|
||||
info!("Request received");
|
||||
|
||||
let sender_client = {
|
||||
@ -100,7 +110,7 @@ pub async fn _handle_request(bp: BasePayload, b: Vec<u8>) -> http::Response<hype
|
||||
let msg = format!("Error decoding SenderID: {}", e);
|
||||
let pl = bp.to_base_payload_result(backend::ResultCode::MalformedRequest, &msg);
|
||||
log_request_response(&bp, &b, &pl).await;
|
||||
return warp::reply::json(&pl).into_response();
|
||||
return Json(&pl).into_response();
|
||||
}
|
||||
};
|
||||
|
||||
@ -111,7 +121,7 @@ pub async fn _handle_request(bp: BasePayload, b: Vec<u8>) -> http::Response<hype
|
||||
let msg = format!("Unknown SenderID: {}", sender_id);
|
||||
let pl = bp.to_base_payload_result(backend::ResultCode::UnknownSender, &msg);
|
||||
log_request_response(&bp, &b, &pl).await;
|
||||
return warp::reply::json(&pl).into_response();
|
||||
return Json(&pl).into_response();
|
||||
}
|
||||
}
|
||||
} else if bp.sender_id.len() == 3 {
|
||||
@ -123,7 +133,7 @@ pub async fn _handle_request(bp: BasePayload, b: Vec<u8>) -> http::Response<hype
|
||||
let msg = format!("Error decoding SenderID: {}", e);
|
||||
let pl = bp.to_base_payload_result(backend::ResultCode::MalformedRequest, &msg);
|
||||
log_request_response(&bp, &b, &pl).await;
|
||||
return warp::reply::json(&pl).into_response();
|
||||
return Json(&pl).into_response();
|
||||
}
|
||||
};
|
||||
|
||||
@ -134,7 +144,7 @@ pub async fn _handle_request(bp: BasePayload, b: Vec<u8>) -> http::Response<hype
|
||||
let msg = format!("Unknown SenderID: {}", sender_id);
|
||||
let pl = bp.to_base_payload_result(backend::ResultCode::UnknownSender, &msg);
|
||||
log_request_response(&bp, &b, &pl).await;
|
||||
return warp::reply::json(&pl).into_response();
|
||||
return Json(&pl).into_response();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -145,7 +155,7 @@ pub async fn _handle_request(bp: BasePayload, b: Vec<u8>) -> http::Response<hype
|
||||
"Invalid SenderID length",
|
||||
);
|
||||
log_request_response(&bp, &b, &pl).await;
|
||||
return warp::reply::json(&pl).into_response();
|
||||
return Json(&pl).into_response();
|
||||
}
|
||||
};
|
||||
|
||||
@ -156,7 +166,7 @@ pub async fn _handle_request(bp: BasePayload, b: Vec<u8>) -> http::Response<hype
|
||||
error!(error = %e.full(), "Handle async answer error");
|
||||
}
|
||||
});
|
||||
return warp::reply::with_status("", StatusCode::OK).into_response();
|
||||
return (StatusCode::OK, "").into_response();
|
||||
}
|
||||
|
||||
match bp.message_type {
|
||||
@ -165,11 +175,11 @@ pub async fn _handle_request(bp: BasePayload, b: Vec<u8>) -> http::Response<hype
|
||||
MessageType::XmitDataReq => handle_xmit_data_req(sender_client, bp, &b).await,
|
||||
MessageType::HomeNSReq => handle_home_ns_req(sender_client, bp, &b).await,
|
||||
// Unknown message
|
||||
_ => warp::reply::with_status(
|
||||
"Handler for {:?} is not implemented",
|
||||
_ => (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
format!("Handler for {:?} is not implemented", bp.message_type),
|
||||
)
|
||||
.into_response(),
|
||||
.into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -201,7 +211,7 @@ async fn handle_pr_start_req(
|
||||
sender_client: Arc<backend::Client>,
|
||||
bp: backend::BasePayload,
|
||||
b: &[u8],
|
||||
) -> http::Response<hyper::Body> {
|
||||
) -> Response {
|
||||
if sender_client.is_async() {
|
||||
let b = b.to_vec();
|
||||
task::spawn(async move {
|
||||
@ -222,18 +232,17 @@ async fn handle_pr_start_req(
|
||||
error!(error = %e.full(), transaction_id = bp.transaction_id, "Send async PRStartAns error");
|
||||
}
|
||||
});
|
||||
|
||||
warp::reply::with_status("", StatusCode::OK).into_response()
|
||||
(StatusCode::OK, "").into_response()
|
||||
} else {
|
||||
match _handle_pr_start_req(b).await {
|
||||
Ok(ans) => {
|
||||
log_request_response(&bp, b, &ans).await;
|
||||
warp::reply::json(&ans).into_response()
|
||||
Json(&ans).into_response()
|
||||
}
|
||||
Err(e) => {
|
||||
let ans = err_to_response(e, &bp);
|
||||
log_request_response(&bp, b, &ans).await;
|
||||
warp::reply::json(&ans).into_response()
|
||||
Json(&ans).into_response()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -363,7 +372,7 @@ async fn handle_pr_stop_req(
|
||||
sender_client: Arc<backend::Client>,
|
||||
bp: backend::BasePayload,
|
||||
b: &[u8],
|
||||
) -> http::Response<hyper::Body> {
|
||||
) -> Response {
|
||||
if sender_client.is_async() {
|
||||
let b = b.to_vec();
|
||||
task::spawn(async move {
|
||||
@ -383,18 +392,17 @@ async fn handle_pr_stop_req(
|
||||
error!(error = %e.full(), "Send async PRStopAns error");
|
||||
}
|
||||
});
|
||||
|
||||
warp::reply::with_status("", StatusCode::OK).into_response()
|
||||
(StatusCode::OK, "").into_response()
|
||||
} else {
|
||||
match _handle_pr_stop_req(b).await {
|
||||
Ok(ans) => {
|
||||
log_request_response(&bp, b, &ans).await;
|
||||
warp::reply::json(&ans).into_response()
|
||||
Json(&ans).into_response()
|
||||
}
|
||||
Err(e) => {
|
||||
let ans = err_to_response(e, &bp);
|
||||
log_request_response(&bp, b, &ans).await;
|
||||
warp::reply::json(&ans).into_response()
|
||||
Json(&ans).into_response()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -430,13 +438,13 @@ async fn handle_xmit_data_req(
|
||||
sender_client: Arc<backend::Client>,
|
||||
bp: backend::BasePayload,
|
||||
b: &[u8],
|
||||
) -> http::Response<hyper::Body> {
|
||||
) -> Response {
|
||||
let pl: backend::XmitDataReqPayload = match serde_json::from_slice(b) {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
let ans = err_to_response(anyhow::Error::new(e), &bp);
|
||||
log_request_response(&bp, b, &ans).await;
|
||||
return warp::reply::json(&ans).into_response();
|
||||
return Json(&ans).into_response();
|
||||
}
|
||||
};
|
||||
|
||||
@ -465,18 +473,17 @@ async fn handle_xmit_data_req(
|
||||
error!(error = %e.full(), "Send async XmitDataAns error");
|
||||
}
|
||||
});
|
||||
|
||||
warp::reply::with_status("", StatusCode::OK).into_response()
|
||||
(StatusCode::OK, "").into_response()
|
||||
} else {
|
||||
match _handle_xmit_data_req(pl).await {
|
||||
Ok(ans) => {
|
||||
log_request_response(&bp, b, &ans).await;
|
||||
warp::reply::json(&ans).into_response()
|
||||
Json(&ans).into_response()
|
||||
}
|
||||
Err(e) => {
|
||||
let ans = err_to_response(e, &bp);
|
||||
log_request_response(&bp, b, &ans).await;
|
||||
warp::reply::json(&ans).into_response()
|
||||
Json(&ans).into_response()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -529,13 +536,13 @@ async fn handle_home_ns_req(
|
||||
sender_client: Arc<backend::Client>,
|
||||
bp: backend::BasePayload,
|
||||
b: &[u8],
|
||||
) -> http::Response<hyper::Body> {
|
||||
) -> Response {
|
||||
let pl: backend::HomeNSReqPayload = match serde_json::from_slice(b) {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
let ans = err_to_response(anyhow::Error::new(e), &bp);
|
||||
log_request_response(&bp, b, &ans).await;
|
||||
return warp::reply::json(&ans).into_response();
|
||||
return Json(&ans).into_response();
|
||||
}
|
||||
};
|
||||
|
||||
@ -560,17 +567,17 @@ async fn handle_home_ns_req(
|
||||
}
|
||||
});
|
||||
|
||||
warp::reply::with_status("", StatusCode::OK).into_response()
|
||||
(StatusCode::OK, "").into_response()
|
||||
} else {
|
||||
match _handle_home_ns_req(pl).await {
|
||||
Ok(ans) => {
|
||||
log_request_response(&bp, b, &ans).await;
|
||||
warp::reply::json(&ans).into_response()
|
||||
Json(&ans).into_response()
|
||||
}
|
||||
Err(e) => {
|
||||
let ans = err_to_response(e, &bp);
|
||||
log_request_response(&bp, b, &ans).await;
|
||||
warp::reply::json(&ans).into_response()
|
||||
Json(&ans).into_response()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -587,7 +594,7 @@ async fn _handle_home_ns_req(pl: backend::HomeNSReqPayload) -> Result<backend::H
|
||||
})
|
||||
}
|
||||
|
||||
async fn handle_async_ans(bp: &BasePayload, b: &[u8]) -> Result<http::Response<hyper::Body>> {
|
||||
async fn handle_async_ans(bp: &BasePayload, b: &[u8]) -> Result<Response> {
|
||||
let transaction_id = bp.transaction_id;
|
||||
|
||||
let key = redis_key(format!("backend:async:{}", transaction_id));
|
||||
@ -609,7 +616,7 @@ async fn handle_async_ans(bp: &BasePayload, b: &[u8]) -> Result<http::Response<h
|
||||
.query_async(&mut get_async_redis_conn().await?)
|
||||
.await?;
|
||||
|
||||
Ok(warp::reply().into_response())
|
||||
Ok((StatusCode::OK, "").into_response())
|
||||
}
|
||||
|
||||
pub async fn get_async_receiver(
|
||||
@ -651,7 +658,7 @@ pub async fn get_async_receiver(
|
||||
for (k, v) in &stream_id.map {
|
||||
match k.as_ref() {
|
||||
"pl" => {
|
||||
if let redis::Value::Data(b) = v {
|
||||
if let redis::Value::BulkString(b) = v {
|
||||
let _ = tx.send(b.to_vec());
|
||||
return;
|
||||
}
|
||||
|
@ -695,20 +695,18 @@ impl DeviceService for Device {
|
||||
.await?;
|
||||
|
||||
let start = SystemTime::try_from(
|
||||
req.start
|
||||
*req.start
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow!("start is None"))
|
||||
.map_err(|e| e.status())?
|
||||
.clone(),
|
||||
.map_err(|e| e.status())?,
|
||||
)
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
let end = SystemTime::try_from(
|
||||
req.end
|
||||
*req.end
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow!("end is None"))
|
||||
.map_err(|e| e.status())?
|
||||
.clone(),
|
||||
.map_err(|e| e.status())?,
|
||||
)
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
@ -819,20 +817,18 @@ impl DeviceService for Device {
|
||||
.await?;
|
||||
|
||||
let start = SystemTime::try_from(
|
||||
req.start
|
||||
*req.start
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow!("start is None"))
|
||||
.map_err(|e| e.status())?
|
||||
.clone(),
|
||||
.map_err(|e| e.status())?,
|
||||
)
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
let end = SystemTime::try_from(
|
||||
req.end
|
||||
*req.end
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow!("end is None"))
|
||||
.map_err(|e| e.status())?
|
||||
.clone(),
|
||||
.map_err(|e| e.status())?,
|
||||
)
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
@ -1256,7 +1252,7 @@ pub mod test {
|
||||
// create application
|
||||
let app = application::create(application::Application {
|
||||
name: "test-app".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -1265,7 +1261,7 @@ pub mod test {
|
||||
// create device-profile
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "test-dp".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -1421,12 +1417,10 @@ pub mod test {
|
||||
);
|
||||
|
||||
// flush dev nonces
|
||||
let _ = device_keys::set_dev_nonces(
|
||||
&EUI64::from_str("0102030405060708").unwrap(),
|
||||
&vec![1, 2, 3],
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
let _ =
|
||||
device_keys::set_dev_nonces(&EUI64::from_str("0102030405060708").unwrap(), &[1, 2, 3])
|
||||
.await
|
||||
.unwrap();
|
||||
let flush_dev_nonces_req = get_request(
|
||||
&u.id,
|
||||
api::FlushDevNoncesRequest {
|
||||
@ -1618,7 +1612,7 @@ pub mod test {
|
||||
.await
|
||||
.unwrap();
|
||||
let dev_addr = DevAddr::from_str(&get_random_dev_addr_resp.get_ref().dev_addr).unwrap();
|
||||
let mut dev_addr_copy = dev_addr.clone();
|
||||
let mut dev_addr_copy = dev_addr;
|
||||
dev_addr_copy.set_dev_addr_prefix(NetID::from_str("000000").unwrap().dev_addr_prefix());
|
||||
assert_eq!(dev_addr, dev_addr_copy);
|
||||
|
||||
@ -1666,10 +1660,10 @@ pub mod test {
|
||||
assert_eq!(2, get_queue_resp.total_count);
|
||||
assert_eq!(2, get_queue_resp.result.len());
|
||||
assert_eq!(vec![3, 2, 1], get_queue_resp.result[0].data);
|
||||
assert_eq!(false, get_queue_resp.result[0].is_encrypted);
|
||||
assert!(!get_queue_resp.result[0].is_encrypted);
|
||||
assert_eq!(0, get_queue_resp.result[0].f_cnt_down);
|
||||
assert_eq!(vec![1, 2, 3], get_queue_resp.result[1].data);
|
||||
assert_eq!(true, get_queue_resp.result[1].is_encrypted);
|
||||
assert!(get_queue_resp.result[1].is_encrypted);
|
||||
assert_eq!(10, get_queue_resp.result[1].f_cnt_down);
|
||||
|
||||
// get next FCntDown (from queue)
|
||||
@ -1726,7 +1720,7 @@ pub mod test {
|
||||
|
||||
fn get_request<T>(user_id: &Uuid, req: T) -> Request<T> {
|
||||
let mut req = Request::new(req);
|
||||
req.extensions_mut().insert(AuthID::User(user_id.clone()));
|
||||
req.extensions_mut().insert(AuthID::User(*user_id));
|
||||
req
|
||||
}
|
||||
}
|
||||
|
@ -600,7 +600,7 @@ pub mod test {
|
||||
|
||||
fn get_request<T>(user_id: &Uuid, req: T) -> Request<T> {
|
||||
let mut req = Request::new(req);
|
||||
req.extensions_mut().insert(AuthID::User(user_id.clone()));
|
||||
req.extensions_mut().insert(AuthID::User(*user_id));
|
||||
req
|
||||
}
|
||||
}
|
||||
|
@ -444,7 +444,7 @@ pub mod test {
|
||||
|
||||
fn get_request<T>(user_id: &Uuid, req: T) -> Request<T> {
|
||||
let mut req = Request::new(req);
|
||||
req.extensions_mut().insert(AuthID::User(user_id.clone()));
|
||||
req.extensions_mut().insert(AuthID::User(*user_id));
|
||||
req
|
||||
}
|
||||
}
|
||||
|
@ -345,20 +345,18 @@ impl GatewayService for Gateway {
|
||||
.await?;
|
||||
|
||||
let start = SystemTime::try_from(
|
||||
req.start
|
||||
*req.start
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow!("start is None"))
|
||||
.map_err(|e| e.status())?
|
||||
.clone(),
|
||||
.map_err(|e| e.status())?,
|
||||
)
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
let end = SystemTime::try_from(
|
||||
req.end
|
||||
*req.end
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow!("end is None"))
|
||||
.map_err(|e| e.status())?
|
||||
.clone(),
|
||||
.map_err(|e| e.status())?,
|
||||
)
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
@ -634,20 +632,18 @@ impl GatewayService for Gateway {
|
||||
.await?;
|
||||
|
||||
let start = SystemTime::try_from(
|
||||
req.start
|
||||
*req.start
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow!("start is None"))
|
||||
.map_err(|e| e.status())?
|
||||
.clone(),
|
||||
.map_err(|e| e.status())?,
|
||||
)
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
let end = SystemTime::try_from(
|
||||
req.end
|
||||
*req.end
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow!("end is None"))
|
||||
.map_err(|e| e.status())?
|
||||
.clone(),
|
||||
.map_err(|e| e.status())?,
|
||||
)
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
@ -1032,9 +1028,7 @@ pub mod test {
|
||||
}),
|
||||
};
|
||||
let mut create_req = Request::new(create_req);
|
||||
create_req
|
||||
.extensions_mut()
|
||||
.insert(AuthID::User(u.id.clone()));
|
||||
create_req.extensions_mut().insert(AuthID::User(u.id));
|
||||
let _ = service.create(create_req).await.unwrap();
|
||||
|
||||
// get
|
||||
@ -1042,7 +1036,7 @@ pub mod test {
|
||||
gateway_id: "0102030405060708".into(),
|
||||
};
|
||||
let mut get_req = Request::new(get_req);
|
||||
get_req.extensions_mut().insert(AuthID::User(u.id.clone()));
|
||||
get_req.extensions_mut().insert(AuthID::User(u.id));
|
||||
let get_resp = service.get(get_req).await.unwrap();
|
||||
assert_eq!(
|
||||
Some(api::Gateway {
|
||||
@ -1076,7 +1070,7 @@ pub mod test {
|
||||
}),
|
||||
};
|
||||
let mut up_req = Request::new(up_req);
|
||||
up_req.extensions_mut().insert(AuthID::User(u.id.clone()));
|
||||
up_req.extensions_mut().insert(AuthID::User(u.id));
|
||||
let _ = service.update(up_req).await.unwrap();
|
||||
|
||||
// get
|
||||
@ -1084,7 +1078,7 @@ pub mod test {
|
||||
gateway_id: "0102030405060708".into(),
|
||||
};
|
||||
let mut get_req = Request::new(get_req);
|
||||
get_req.extensions_mut().insert(AuthID::User(u.id.clone()));
|
||||
get_req.extensions_mut().insert(AuthID::User(u.id));
|
||||
let get_resp = service.get(get_req).await.unwrap();
|
||||
assert_eq!(
|
||||
Some(api::Gateway {
|
||||
@ -1111,7 +1105,7 @@ pub mod test {
|
||||
..Default::default()
|
||||
};
|
||||
let mut list_req = Request::new(list_req);
|
||||
list_req.extensions_mut().insert(AuthID::User(u.id.clone()));
|
||||
list_req.extensions_mut().insert(AuthID::User(u.id));
|
||||
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());
|
||||
@ -1121,14 +1115,14 @@ pub mod test {
|
||||
gateway_id: "0102030405060708".into(),
|
||||
};
|
||||
let mut del_req = Request::new(del_req);
|
||||
del_req.extensions_mut().insert(AuthID::User(u.id.clone()));
|
||||
del_req.extensions_mut().insert(AuthID::User(u.id));
|
||||
let _ = service.delete(del_req).await.unwrap();
|
||||
|
||||
let del_req = api::DeleteGatewayRequest {
|
||||
gateway_id: "0102030405060708".into(),
|
||||
};
|
||||
let mut del_req = Request::new(del_req);
|
||||
del_req.extensions_mut().insert(AuthID::User(u.id.clone()));
|
||||
del_req.extensions_mut().insert(AuthID::User(u.id));
|
||||
let del_resp = service.delete(del_req).await;
|
||||
assert!(del_resp.is_err());
|
||||
}
|
||||
@ -1160,7 +1154,7 @@ pub mod test {
|
||||
// create gateway
|
||||
let _ = gateway::create(gateway::Gateway {
|
||||
gateway_id: EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
name: "test-gw".into(),
|
||||
..Default::default()
|
||||
})
|
||||
@ -1172,7 +1166,7 @@ pub mod test {
|
||||
// insert stats
|
||||
let mut m = metrics::Record {
|
||||
kind: metrics::Kind::ABSOLUTE,
|
||||
time: now.into(),
|
||||
time: now,
|
||||
metrics: HashMap::new(),
|
||||
};
|
||||
|
||||
@ -1204,9 +1198,7 @@ pub mod test {
|
||||
aggregation: common::Aggregation::Day.into(),
|
||||
};
|
||||
let mut stats_req = Request::new(stats_req);
|
||||
stats_req
|
||||
.extensions_mut()
|
||||
.insert(AuthID::User(u.id.clone()));
|
||||
stats_req.extensions_mut().insert(AuthID::User(u.id));
|
||||
let stats_resp = service.get_metrics(stats_req).await.unwrap();
|
||||
let stats_resp = stats_resp.get_ref();
|
||||
assert_eq!(
|
||||
@ -1257,7 +1249,7 @@ pub mod test {
|
||||
// create gateway
|
||||
let _ = gateway::create(gateway::Gateway {
|
||||
gateway_id: EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
name: "test-gw".into(),
|
||||
..Default::default()
|
||||
})
|
||||
@ -1269,7 +1261,7 @@ pub mod test {
|
||||
// insert stats
|
||||
let mut m = metrics::Record {
|
||||
kind: metrics::Kind::COUNTER,
|
||||
time: now.into(),
|
||||
time: now,
|
||||
metrics: HashMap::new(),
|
||||
};
|
||||
|
||||
@ -1297,9 +1289,7 @@ pub mod test {
|
||||
end: Some(now_st.into()),
|
||||
};
|
||||
let mut stats_req = Request::new(stats_req);
|
||||
stats_req
|
||||
.extensions_mut()
|
||||
.insert(AuthID::User(u.id.clone()));
|
||||
stats_req.extensions_mut().insert(AuthID::User(u.id));
|
||||
let stats_resp = service.get_duty_cycle_metrics(stats_req).await.unwrap();
|
||||
let stats_resp = stats_resp.get_ref();
|
||||
assert_eq!(
|
||||
|
141
chirpstack/src/api/grpc_multiplex.rs
Normal file
141
chirpstack/src/api/grpc_multiplex.rs
Normal file
@ -0,0 +1,141 @@
|
||||
use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
use futures::ready;
|
||||
use http::{header::CONTENT_TYPE, Request, Response};
|
||||
use http_body::Body;
|
||||
use pin_project::pin_project;
|
||||
use tower::{Layer, Service};
|
||||
|
||||
type BoxError = Box<dyn std::error::Error + Send + Sync>;
|
||||
|
||||
#[pin_project(project = GrpcMultiplexFutureEnumProj)]
|
||||
enum GrpcMultiplexFutureEnum<FS, FO> {
|
||||
Grpc {
|
||||
#[pin]
|
||||
future: FS,
|
||||
},
|
||||
Other {
|
||||
#[pin]
|
||||
future: FO,
|
||||
},
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
pub struct GrpcMultiplexFuture<FS, FO> {
|
||||
#[pin]
|
||||
future: GrpcMultiplexFutureEnum<FS, FO>,
|
||||
}
|
||||
|
||||
impl<ResBody, FS, FO, ES, EO> Future for GrpcMultiplexFuture<FS, FO>
|
||||
where
|
||||
ResBody: Body,
|
||||
FS: Future<Output = Result<Response<ResBody>, ES>>,
|
||||
FO: Future<Output = Result<Response<ResBody>, EO>>,
|
||||
ES: Into<BoxError> + Send,
|
||||
EO: Into<BoxError> + Send,
|
||||
{
|
||||
type Output = Result<Response<ResBody>, Box<dyn std::error::Error + Send + Sync + 'static>>;
|
||||
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
let this = self.project();
|
||||
match this.future.project() {
|
||||
GrpcMultiplexFutureEnumProj::Grpc { future } => future.poll(cx).map_err(Into::into),
|
||||
GrpcMultiplexFutureEnumProj::Other { future } => future.poll(cx).map_err(Into::into),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct GrpcMultiplexService<S, O> {
|
||||
grpc: S,
|
||||
other: O,
|
||||
grpc_ready: bool,
|
||||
other_ready: bool,
|
||||
}
|
||||
|
||||
impl<ReqBody, ResBody, S, O> Service<Request<ReqBody>> for GrpcMultiplexService<S, O>
|
||||
where
|
||||
ResBody: Body,
|
||||
S: Service<Request<ReqBody>, Response = Response<ResBody>>,
|
||||
O: Service<Request<ReqBody>, Response = Response<ResBody>>,
|
||||
S::Error: Into<BoxError> + Send,
|
||||
O::Error: Into<BoxError> + Send,
|
||||
{
|
||||
type Response = S::Response;
|
||||
type Error = Box<dyn std::error::Error + Send + Sync + 'static>;
|
||||
type Future = GrpcMultiplexFuture<S::Future, O::Future>;
|
||||
|
||||
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
loop {
|
||||
match (self.grpc_ready, self.other_ready) {
|
||||
(true, true) => {
|
||||
return Ok(()).into();
|
||||
}
|
||||
(false, _) => {
|
||||
ready!(self.grpc.poll_ready(cx)).map_err(Into::into)?;
|
||||
self.grpc_ready = true;
|
||||
}
|
||||
(_, false) => {
|
||||
ready!(self.other.poll_ready(cx)).map_err(Into::into)?;
|
||||
self.other_ready = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn call(&mut self, request: Request<ReqBody>) -> Self::Future {
|
||||
assert!(self.grpc_ready);
|
||||
assert!(self.other_ready);
|
||||
|
||||
if is_grpc_request(&request) {
|
||||
GrpcMultiplexFuture {
|
||||
future: GrpcMultiplexFutureEnum::Grpc {
|
||||
future: self.grpc.call(request),
|
||||
},
|
||||
}
|
||||
} else {
|
||||
GrpcMultiplexFuture {
|
||||
future: GrpcMultiplexFutureEnum::Other {
|
||||
future: self.other.call(request),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct GrpcMultiplexLayer<O> {
|
||||
other: O,
|
||||
}
|
||||
|
||||
impl<O> GrpcMultiplexLayer<O> {
|
||||
pub fn new(other: O) -> Self {
|
||||
Self { other }
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, O> Layer<S> for GrpcMultiplexLayer<O>
|
||||
where
|
||||
O: Clone,
|
||||
{
|
||||
type Service = GrpcMultiplexService<S, O>;
|
||||
|
||||
fn layer(&self, grpc: S) -> Self::Service {
|
||||
GrpcMultiplexService {
|
||||
grpc,
|
||||
other: self.other.clone(),
|
||||
grpc_ready: false,
|
||||
other_ready: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_grpc_request<B>(req: &Request<B>) -> bool {
|
||||
req.headers()
|
||||
.get(CONTENT_TYPE)
|
||||
.map(|content_type| content_type.as_bytes())
|
||||
.filter(|content_type| content_type.starts_with(b"application/grpc"))
|
||||
.is_some()
|
||||
}
|
@ -1,4 +1,3 @@
|
||||
use std::convert::Infallible;
|
||||
use std::time::{Duration, Instant};
|
||||
use std::{
|
||||
future::Future,
|
||||
@ -7,23 +6,27 @@ use std::{
|
||||
};
|
||||
|
||||
use anyhow::Result;
|
||||
use futures::future::{self, Either, TryFutureExt};
|
||||
use hyper::{service::make_service_fn, Server};
|
||||
use axum::{response::IntoResponse, routing::get, Router};
|
||||
use http::{
|
||||
header::{self, HeaderMap, HeaderValue},
|
||||
Request, StatusCode, Uri,
|
||||
};
|
||||
use pin_project::pin_project;
|
||||
use prometheus_client::encoding::EncodeLabelSet;
|
||||
use prometheus_client::metrics::counter::Counter;
|
||||
use prometheus_client::metrics::family::Family;
|
||||
use prometheus_client::metrics::histogram::Histogram;
|
||||
use rust_embed::RustEmbed;
|
||||
use tokio::{task, try_join};
|
||||
use tokio::task;
|
||||
use tokio::try_join;
|
||||
use tonic::transport::Server as TonicServer;
|
||||
use tonic::Code;
|
||||
use tonic_reflection::server::Builder as TonicReflectionBuilder;
|
||||
use tonic_web::GrpcWebLayer;
|
||||
use tower::{Service, ServiceBuilder};
|
||||
use tower::util::ServiceExt;
|
||||
use tower::Service;
|
||||
use tower_http::trace::TraceLayer;
|
||||
use tracing::{error, info};
|
||||
use warp::{http::header::HeaderValue, path::Tail, reply::Response, Filter, Rejection, Reply};
|
||||
|
||||
use chirpstack_api::api::application_service_server::ApplicationServiceServer;
|
||||
use chirpstack_api::api::device_profile_service_server::DeviceProfileServiceServer;
|
||||
@ -51,6 +54,7 @@ pub mod device_profile;
|
||||
pub mod device_profile_template;
|
||||
pub mod error;
|
||||
pub mod gateway;
|
||||
mod grpc_multiplex;
|
||||
pub mod helpers;
|
||||
pub mod internal;
|
||||
pub mod monitoring;
|
||||
@ -89,210 +93,120 @@ lazy_static! {
|
||||
};
|
||||
}
|
||||
|
||||
type Error = Box<dyn std::error::Error + Send + Sync + 'static>;
|
||||
|
||||
#[derive(RustEmbed)]
|
||||
#[folder = "../ui/build"]
|
||||
struct Asset;
|
||||
|
||||
type BoxError = Box<dyn std::error::Error + Send + Sync>;
|
||||
|
||||
pub async fn setup() -> Result<()> {
|
||||
let conf = config::get();
|
||||
let addr = conf.api.bind.parse()?;
|
||||
let bind = conf.api.bind.parse()?;
|
||||
|
||||
info!(bind = %conf.api.bind, "Setting up API interface");
|
||||
info!(bind = %bind, "Setting up API interface");
|
||||
|
||||
// Taken from the tonic hyper_warp_multiplex example:
|
||||
// https://github.com/hyperium/tonic/blob/master/examples/src/hyper_warp_multiplex/server.rs#L101
|
||||
let service = make_service_fn(move |_| {
|
||||
// tonic gRPC service
|
||||
let tonic_service = TonicServer::builder()
|
||||
.accept_http1(true)
|
||||
.layer(GrpcWebLayer::new())
|
||||
.add_service(
|
||||
TonicReflectionBuilder::configure()
|
||||
.register_encoded_file_descriptor_set(chirpstack_api::api::DESCRIPTOR)
|
||||
.build()
|
||||
.unwrap(),
|
||||
)
|
||||
.add_service(InternalServiceServer::with_interceptor(
|
||||
internal::Internal::new(
|
||||
validator::RequestValidator::new(),
|
||||
conf.api.secret.clone(),
|
||||
),
|
||||
auth::auth_interceptor,
|
||||
))
|
||||
.add_service(ApplicationServiceServer::with_interceptor(
|
||||
application::Application::new(validator::RequestValidator::new()),
|
||||
auth::auth_interceptor,
|
||||
))
|
||||
.add_service(DeviceProfileServiceServer::with_interceptor(
|
||||
device_profile::DeviceProfile::new(validator::RequestValidator::new()),
|
||||
auth::auth_interceptor,
|
||||
))
|
||||
.add_service(DeviceProfileTemplateServiceServer::with_interceptor(
|
||||
device_profile_template::DeviceProfileTemplate::new(
|
||||
validator::RequestValidator::new(),
|
||||
),
|
||||
auth::auth_interceptor,
|
||||
))
|
||||
.add_service(TenantServiceServer::with_interceptor(
|
||||
tenant::Tenant::new(validator::RequestValidator::new()),
|
||||
auth::auth_interceptor,
|
||||
))
|
||||
.add_service(DeviceServiceServer::with_interceptor(
|
||||
device::Device::new(validator::RequestValidator::new()),
|
||||
auth::auth_interceptor,
|
||||
))
|
||||
.add_service(UserServiceServer::with_interceptor(
|
||||
user::User::new(validator::RequestValidator::new()),
|
||||
auth::auth_interceptor,
|
||||
))
|
||||
.add_service(GatewayServiceServer::with_interceptor(
|
||||
gateway::Gateway::new(validator::RequestValidator::new()),
|
||||
auth::auth_interceptor,
|
||||
))
|
||||
.add_service(MulticastGroupServiceServer::with_interceptor(
|
||||
multicast::MulticastGroup::new(validator::RequestValidator::new()),
|
||||
auth::auth_interceptor,
|
||||
))
|
||||
.add_service(RelayServiceServer::with_interceptor(
|
||||
relay::Relay::new(validator::RequestValidator::new()),
|
||||
auth::auth_interceptor,
|
||||
))
|
||||
.into_service();
|
||||
let mut tonic_service = ServiceBuilder::new()
|
||||
.layer(
|
||||
TraceLayer::new_for_grpc()
|
||||
.make_span_with(|req: &http::Request<hyper::Body>| {
|
||||
tracing::info_span!(
|
||||
"gRPC",
|
||||
uri = %req.uri().path(),
|
||||
)
|
||||
})
|
||||
.on_request(OnRequest {})
|
||||
.on_response(OnResponse {}),
|
||||
)
|
||||
.layer(ApiLogger {})
|
||||
.service(tonic_service);
|
||||
let web = Router::new()
|
||||
.route("/auth/oidc/login", get(oidc::login_handler))
|
||||
.route("/auth/oidc/callback", get(oidc::callback_handler))
|
||||
.route("/auth/oauth2/login", get(oauth2::login_handler))
|
||||
.route("/auth/oauth2/callback", get(oauth2::callback_handler))
|
||||
.fallback(service_static_handler)
|
||||
.into_service()
|
||||
.map_response(|r| r.map(tonic::body::boxed));
|
||||
|
||||
// HTTP service
|
||||
let warp_service = warp::service(
|
||||
warp::path!("auth" / "oidc" / "login")
|
||||
.and_then(oidc::login_handler)
|
||||
.or(warp::path!("auth" / "oidc" / "callback")
|
||||
.and(warp::query::<oidc::CallbackArgs>())
|
||||
.and_then(oidc::callback_handler))
|
||||
.or(warp::path!("auth" / "oauth2" / "login").and_then(oauth2::login_handler))
|
||||
.or(warp::path!("auth" / "oauth2" / "callback")
|
||||
.and(warp::query::<oauth2::CallbackArgs>())
|
||||
.and_then(oauth2::callback_handler))
|
||||
.or(warp::path::tail().and_then(http_serve)),
|
||||
);
|
||||
let mut warp_service = ServiceBuilder::new()
|
||||
.layer(
|
||||
TraceLayer::new_for_http()
|
||||
.make_span_with(|req: &http::Request<hyper::Body>| {
|
||||
tracing::info_span!(
|
||||
"http",
|
||||
method = req.method().as_str(),
|
||||
uri = %req.uri().path(),
|
||||
version = ?req.version(),
|
||||
)
|
||||
})
|
||||
.on_request(OnRequest {})
|
||||
.on_response(OnResponse {}),
|
||||
)
|
||||
.service(warp_service);
|
||||
|
||||
future::ok::<_, Infallible>(tower::service_fn(
|
||||
move |req: hyper::Request<hyper::Body>| match req.method() {
|
||||
&hyper::Method::GET => Either::Left(
|
||||
warp_service
|
||||
.call(req)
|
||||
.map_ok(|res| res.map(EitherBody::Right))
|
||||
.map_err(Error::from),
|
||||
),
|
||||
_ => Either::Right(
|
||||
tonic_service
|
||||
.call(req)
|
||||
.map_ok(|res| res.map(EitherBody::Left))
|
||||
.map_err(Error::from),
|
||||
),
|
||||
},
|
||||
let grpc = TonicServer::builder()
|
||||
.accept_http1(true)
|
||||
.layer(
|
||||
TraceLayer::new_for_grpc()
|
||||
.make_span_with(|req: &Request<_>| {
|
||||
tracing::info_span!(
|
||||
"gRPC",
|
||||
uri = %req.uri().path(),
|
||||
)
|
||||
})
|
||||
.on_request(OnRequest {})
|
||||
.on_response(OnResponse {}),
|
||||
)
|
||||
.layer(grpc_multiplex::GrpcMultiplexLayer::new(web))
|
||||
.layer(ApiLoggerLayer {})
|
||||
.layer(GrpcWebLayer::new())
|
||||
.add_service(
|
||||
TonicReflectionBuilder::configure()
|
||||
.register_encoded_file_descriptor_set(chirpstack_api::api::DESCRIPTOR)
|
||||
.build()
|
||||
.unwrap(),
|
||||
)
|
||||
.add_service(InternalServiceServer::with_interceptor(
|
||||
internal::Internal::new(validator::RequestValidator::new(), conf.api.secret.clone()),
|
||||
auth::auth_interceptor,
|
||||
))
|
||||
});
|
||||
.add_service(ApplicationServiceServer::with_interceptor(
|
||||
application::Application::new(validator::RequestValidator::new()),
|
||||
auth::auth_interceptor,
|
||||
))
|
||||
.add_service(DeviceProfileServiceServer::with_interceptor(
|
||||
device_profile::DeviceProfile::new(validator::RequestValidator::new()),
|
||||
auth::auth_interceptor,
|
||||
))
|
||||
.add_service(DeviceProfileTemplateServiceServer::with_interceptor(
|
||||
device_profile_template::DeviceProfileTemplate::new(validator::RequestValidator::new()),
|
||||
auth::auth_interceptor,
|
||||
))
|
||||
.add_service(TenantServiceServer::with_interceptor(
|
||||
tenant::Tenant::new(validator::RequestValidator::new()),
|
||||
auth::auth_interceptor,
|
||||
))
|
||||
.add_service(DeviceServiceServer::with_interceptor(
|
||||
device::Device::new(validator::RequestValidator::new()),
|
||||
auth::auth_interceptor,
|
||||
))
|
||||
.add_service(UserServiceServer::with_interceptor(
|
||||
user::User::new(validator::RequestValidator::new()),
|
||||
auth::auth_interceptor,
|
||||
))
|
||||
.add_service(GatewayServiceServer::with_interceptor(
|
||||
gateway::Gateway::new(validator::RequestValidator::new()),
|
||||
auth::auth_interceptor,
|
||||
))
|
||||
.add_service(MulticastGroupServiceServer::with_interceptor(
|
||||
multicast::MulticastGroup::new(validator::RequestValidator::new()),
|
||||
auth::auth_interceptor,
|
||||
))
|
||||
.add_service(RelayServiceServer::with_interceptor(
|
||||
relay::Relay::new(validator::RequestValidator::new()),
|
||||
auth::auth_interceptor,
|
||||
));
|
||||
|
||||
let backend_handle = tokio::spawn(backend::setup());
|
||||
let monitoring_handle = tokio::spawn(monitoring::setup());
|
||||
let api_handle = tokio::spawn(Server::bind(&addr).serve(service));
|
||||
let grpc_handle = tokio::spawn(grpc.serve(bind));
|
||||
|
||||
let _ = try_join!(api_handle, backend_handle, monitoring_handle)?;
|
||||
let _ = try_join!(grpc_handle, backend_handle, monitoring_handle)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
enum EitherBody<A, B> {
|
||||
Left(A),
|
||||
Right(B),
|
||||
}
|
||||
|
||||
impl<A, B> http_body::Body for EitherBody<A, B>
|
||||
where
|
||||
A: http_body::Body + Send + Unpin,
|
||||
B: http_body::Body<Data = A::Data> + Send + Unpin,
|
||||
A::Error: Into<Error>,
|
||||
B::Error: Into<Error>,
|
||||
{
|
||||
type Data = A::Data;
|
||||
type Error = Box<dyn std::error::Error + Send + Sync + 'static>;
|
||||
|
||||
fn is_end_stream(&self) -> bool {
|
||||
match self {
|
||||
EitherBody::Left(b) => b.is_end_stream(),
|
||||
EitherBody::Right(b) => b.is_end_stream(),
|
||||
}
|
||||
}
|
||||
|
||||
fn poll_data(
|
||||
self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<Option<Result<Self::Data, Self::Error>>> {
|
||||
match self.get_mut() {
|
||||
EitherBody::Left(b) => Pin::new(b).poll_data(cx).map(map_option_err),
|
||||
EitherBody::Right(b) => Pin::new(b).poll_data(cx).map(map_option_err),
|
||||
}
|
||||
}
|
||||
|
||||
fn poll_trailers(
|
||||
self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<Result<Option<http::HeaderMap>, Self::Error>> {
|
||||
match self.get_mut() {
|
||||
EitherBody::Left(b) => Pin::new(b).poll_trailers(cx).map_err(Into::into),
|
||||
EitherBody::Right(b) => Pin::new(b).poll_trailers(cx).map_err(Into::into),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn map_option_err<T, U: Into<Error>>(err: Option<Result<T, U>>) -> Option<Result<T, Error>> {
|
||||
err.map(|e| e.map_err(Into::into))
|
||||
}
|
||||
|
||||
async fn http_serve(path: Tail) -> Result<impl Reply, Rejection> {
|
||||
let mut path = path.as_str();
|
||||
async fn service_static_handler(uri: Uri) -> impl IntoResponse {
|
||||
let mut path = {
|
||||
let mut chars = uri.path().chars();
|
||||
chars.next();
|
||||
chars.as_str()
|
||||
};
|
||||
if path.is_empty() {
|
||||
path = "index.html";
|
||||
}
|
||||
|
||||
let asset = Asset::get(path).ok_or_else(warp::reject::not_found)?;
|
||||
let mime = mime_guess::from_path(path).first_or_octet_stream();
|
||||
|
||||
let mut res = Response::new(asset.data.into());
|
||||
res.headers_mut().insert(
|
||||
"content-type",
|
||||
HeaderValue::from_str(mime.as_ref()).unwrap(),
|
||||
);
|
||||
Ok(res)
|
||||
if let Some(asset) = Asset::get(path) {
|
||||
let mime = mime_guess::from_path(path).first_or_octet_stream();
|
||||
let mut headers = HeaderMap::new();
|
||||
headers.insert(
|
||||
header::CONTENT_TYPE,
|
||||
HeaderValue::from_str(mime.as_ref()).unwrap(),
|
||||
);
|
||||
(StatusCode::OK, headers, asset.data.into())
|
||||
} else {
|
||||
(StatusCode::NOT_FOUND, HeaderMap::new(), vec![])
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@ -320,13 +234,14 @@ struct GrpcLabels {
|
||||
status_code: String,
|
||||
}
|
||||
|
||||
struct ApiLogger {}
|
||||
#[derive(Debug, Clone)]
|
||||
struct ApiLoggerLayer {}
|
||||
|
||||
impl<S> tower::Layer<S> for ApiLogger {
|
||||
impl<S> tower::Layer<S> for ApiLoggerLayer {
|
||||
type Service = ApiLoggerService<S>;
|
||||
|
||||
fn layer(&self, service: S) -> Self::Service {
|
||||
ApiLoggerService { inner: service }
|
||||
fn layer(&self, inner: S) -> Self::Service {
|
||||
ApiLoggerService { inner }
|
||||
}
|
||||
}
|
||||
|
||||
@ -335,15 +250,15 @@ struct ApiLoggerService<S> {
|
||||
inner: S,
|
||||
}
|
||||
|
||||
impl<S, ReqBody, ResBody> Service<http::Request<ReqBody>> for ApiLoggerService<S>
|
||||
impl<ReqBody, ResBody, S> Service<http::Request<ReqBody>> for ApiLoggerService<S>
|
||||
where
|
||||
S: Service<http::Request<ReqBody>, Response = http::Response<ResBody>>,
|
||||
ReqBody: http_body::Body,
|
||||
ResBody: http_body::Body,
|
||||
S: Service<http::Request<ReqBody>, Response = http::Response<ResBody>>,
|
||||
S::Error: Into<BoxError> + Send,
|
||||
{
|
||||
type Response = S::Response;
|
||||
type Error = S::Error;
|
||||
type Future = ApiLoggerResponseFuture<S::Future>;
|
||||
type Future = ApiLoggerFuture<S::Future>;
|
||||
|
||||
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
self.inner.poll_ready(cx)
|
||||
@ -352,10 +267,10 @@ where
|
||||
fn call(&mut self, request: http::Request<ReqBody>) -> Self::Future {
|
||||
let uri = request.uri().path().to_string();
|
||||
let uri_parts: Vec<&str> = uri.split('/').collect();
|
||||
let response_future = self.inner.call(request);
|
||||
let future = self.inner.call(request);
|
||||
let start = Instant::now();
|
||||
ApiLoggerResponseFuture {
|
||||
response_future,
|
||||
ApiLoggerFuture {
|
||||
future,
|
||||
start,
|
||||
service: uri_parts.get(1).map(|v| v.to_string()).unwrap_or_default(),
|
||||
method: uri_parts.get(2).map(|v| v.to_string()).unwrap_or_default(),
|
||||
@ -364,25 +279,26 @@ where
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
struct ApiLoggerResponseFuture<F> {
|
||||
struct ApiLoggerFuture<F> {
|
||||
#[pin]
|
||||
response_future: F,
|
||||
future: F,
|
||||
start: Instant,
|
||||
service: String,
|
||||
method: String,
|
||||
}
|
||||
|
||||
impl<F, ResBody, Error> Future for ApiLoggerResponseFuture<F>
|
||||
impl<ResBody, F, E> Future for ApiLoggerFuture<F>
|
||||
where
|
||||
F: Future<Output = Result<http::Response<ResBody>, Error>>,
|
||||
ResBody: http_body::Body,
|
||||
F: Future<Output = Result<http::Response<ResBody>, E>>,
|
||||
E: Into<BoxError> + Send,
|
||||
{
|
||||
type Output = Result<http::Response<ResBody>, Error>;
|
||||
type Output = Result<http::Response<ResBody>, E>;
|
||||
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
let this = self.project();
|
||||
|
||||
match this.response_future.poll(cx) {
|
||||
match this.future.poll(cx) {
|
||||
Poll::Ready(result) => {
|
||||
if let Ok(response) = &result {
|
||||
let status_code: i32 = match response.headers().get("grpc-status") {
|
||||
|
@ -1,51 +1,49 @@
|
||||
use std::convert::Infallible;
|
||||
use std::net::SocketAddr;
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use axum::{
|
||||
response::{IntoResponse, Response},
|
||||
routing::get,
|
||||
Router,
|
||||
};
|
||||
use diesel_async::RunQueryDsl;
|
||||
use http::StatusCode;
|
||||
use tracing::info;
|
||||
use warp::{http::Response, http::StatusCode, Filter};
|
||||
|
||||
use crate::config;
|
||||
use crate::monitoring::prometheus;
|
||||
use crate::storage::{get_async_db_conn, get_async_redis_conn};
|
||||
|
||||
pub async fn setup() {
|
||||
pub async fn setup() -> Result<()> {
|
||||
let conf = config::get();
|
||||
if conf.monitoring.bind.is_empty() {
|
||||
return;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let addr: SocketAddr = conf.monitoring.bind.parse().unwrap();
|
||||
info!(bind = %conf.monitoring.bind, "Setting up monitoring endpoint");
|
||||
|
||||
let prom_endpoint = warp::get()
|
||||
.and(warp::path!("metrics"))
|
||||
.and_then(prometheus_handler);
|
||||
let app = Router::new()
|
||||
.route("/metrics", get(prometheus_handler))
|
||||
.route("/health", get(health_handler));
|
||||
|
||||
let health_endpoint = warp::get()
|
||||
.and(warp::path!("health"))
|
||||
.and_then(health_handler);
|
||||
|
||||
let routes = prom_endpoint.or(health_endpoint);
|
||||
|
||||
warp::serve(routes).run(addr).await;
|
||||
axum_server::bind(addr)
|
||||
.serve(app.into_make_service())
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn prometheus_handler() -> Result<impl warp::Reply, Infallible> {
|
||||
async fn prometheus_handler() -> Response {
|
||||
let body = prometheus::encode_to_string().unwrap_or_default();
|
||||
Ok(Response::builder().body(body))
|
||||
body.into_response()
|
||||
}
|
||||
|
||||
async fn health_handler() -> Result<impl warp::Reply, Infallible> {
|
||||
async fn health_handler() -> Response {
|
||||
if let Err(e) = _health_handler().await {
|
||||
return Ok(warp::reply::with_status(
|
||||
e.to_string(),
|
||||
StatusCode::SERVICE_UNAVAILABLE,
|
||||
));
|
||||
(StatusCode::SERVICE_UNAVAILABLE, e.to_string()).into_response()
|
||||
} else {
|
||||
(StatusCode::OK, "".to_string()).into_response()
|
||||
}
|
||||
|
||||
Ok(warp::reply::with_status("OK".to_string(), StatusCode::OK))
|
||||
}
|
||||
|
||||
async fn _health_handler() -> Result<()> {
|
||||
|
@ -550,7 +550,7 @@ pub mod test {
|
||||
// create application
|
||||
let app = application::create(application::Application {
|
||||
name: "test-app".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -559,7 +559,7 @@ pub mod test {
|
||||
// create device-profile
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "test-dp".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -871,7 +871,7 @@ pub mod test {
|
||||
|
||||
fn get_request<T>(user_id: &Uuid, req: T) -> Request<T> {
|
||||
let mut req = Request::new(req);
|
||||
req.extensions_mut().insert(AuthID::User(user_id.clone()));
|
||||
req.extensions_mut().insert(AuthID::User(*user_id));
|
||||
req
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,10 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use axum::{
|
||||
extract::Query,
|
||||
response::{IntoResponse, Redirect, Response},
|
||||
};
|
||||
use chrono::Duration;
|
||||
use http::StatusCode;
|
||||
use oauth2::basic::BasicClient;
|
||||
use oauth2::reqwest;
|
||||
use oauth2::{
|
||||
@ -11,7 +14,6 @@ use oauth2::{
|
||||
use reqwest::header::AUTHORIZATION;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tracing::{error, trace};
|
||||
use warp::{Rejection, Reply};
|
||||
|
||||
use crate::config;
|
||||
use crate::helpers::errors::PrintFullError;
|
||||
@ -26,7 +28,7 @@ struct ClerkUserinfo {
|
||||
pub user_id: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Deserialize)]
|
||||
pub struct CallbackArgs {
|
||||
pub code: String,
|
||||
pub state: String,
|
||||
@ -39,16 +41,12 @@ pub struct User {
|
||||
pub external_id: String,
|
||||
}
|
||||
|
||||
pub async fn login_handler() -> Result<impl Reply, Rejection> {
|
||||
pub async fn login_handler() -> Response {
|
||||
let client = match get_client() {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
error!(error = %e.full(), "Get OAuth2 client error");
|
||||
return Ok(warp::reply::with_status(
|
||||
"Internal error",
|
||||
warp::http::StatusCode::INTERNAL_SERVER_ERROR,
|
||||
)
|
||||
.into_response());
|
||||
return (StatusCode::INTERNAL_SERVER_ERROR, "Internal error").into_response();
|
||||
}
|
||||
};
|
||||
|
||||
@ -64,26 +62,16 @@ pub async fn login_handler() -> Result<impl Reply, Rejection> {
|
||||
|
||||
if let Err(e) = store_verifier(&csrf_token, &pkce_verifier).await {
|
||||
error!(error = %e.full(), "Store verifier error");
|
||||
return Ok(warp::reply::with_status(
|
||||
"Internal error",
|
||||
warp::http::StatusCode::INTERNAL_SERVER_ERROR,
|
||||
)
|
||||
.into_response());
|
||||
return (StatusCode::INTERNAL_SERVER_ERROR, "Internal error").into_response();
|
||||
}
|
||||
|
||||
Ok(
|
||||
warp::redirect::found(warp::http::Uri::from_str(auth_url.as_str()).unwrap())
|
||||
.into_response(),
|
||||
)
|
||||
Redirect::temporary(auth_url.as_str()).into_response()
|
||||
}
|
||||
|
||||
pub async fn callback_handler(args: CallbackArgs) -> Result<impl Reply, Rejection> {
|
||||
// warp::redirect does not work with '#'.
|
||||
Ok(warp::reply::with_header(
|
||||
warp::http::StatusCode::PERMANENT_REDIRECT,
|
||||
warp::http::header::LOCATION,
|
||||
format!("/#/login?code={}&state={}", args.code, args.state),
|
||||
))
|
||||
pub async fn callback_handler(args: Query<CallbackArgs>) -> Response {
|
||||
let args: CallbackArgs = args.0;
|
||||
Redirect::permanent(&format!("/#/login?code={}&state={}", args.code, args.state))
|
||||
.into_response()
|
||||
}
|
||||
|
||||
fn get_client() -> Result<Client> {
|
||||
|
@ -1,8 +1,12 @@
|
||||
use std::collections::HashMap;
|
||||
use std::str::FromStr;
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use axum::{
|
||||
extract::Query,
|
||||
response::{IntoResponse, Redirect, Response},
|
||||
};
|
||||
use chrono::Duration;
|
||||
use http::StatusCode;
|
||||
use openidconnect::core::{
|
||||
CoreClient, CoreGenderClaim, CoreIdTokenClaims, CoreIdTokenVerifier, CoreProviderMetadata,
|
||||
CoreResponseType,
|
||||
@ -15,7 +19,6 @@ use openidconnect::{
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
use tracing::{error, trace};
|
||||
use warp::{Rejection, Reply};
|
||||
|
||||
use crate::config;
|
||||
use crate::helpers::errors::PrintFullError;
|
||||
@ -40,22 +43,18 @@ pub struct CustomClaims {
|
||||
|
||||
impl AdditionalClaims for CustomClaims {}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Deserialize)]
|
||||
pub struct CallbackArgs {
|
||||
pub code: String,
|
||||
pub state: String,
|
||||
}
|
||||
|
||||
pub async fn login_handler() -> Result<impl Reply, Rejection> {
|
||||
pub async fn login_handler() -> Response {
|
||||
let client = match get_client().await {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
error!(error = %e.full(), "Get OIDC client error");
|
||||
return Ok(warp::reply::with_status(
|
||||
"Internal error",
|
||||
warp::http::StatusCode::INTERNAL_SERVER_ERROR,
|
||||
)
|
||||
.into_response());
|
||||
return (StatusCode::INTERNAL_SERVER_ERROR, "Internal error").into_response();
|
||||
}
|
||||
};
|
||||
|
||||
@ -72,26 +71,16 @@ pub async fn login_handler() -> Result<impl Reply, Rejection> {
|
||||
|
||||
if let Err(e) = store_nonce(&csrf_state, &nonce).await {
|
||||
error!(error = %e.full(), "Store nonce error");
|
||||
return Ok(warp::reply::with_status(
|
||||
"Internal error",
|
||||
warp::http::StatusCode::INTERNAL_SERVER_ERROR,
|
||||
)
|
||||
.into_response());
|
||||
return (StatusCode::INTERNAL_SERVER_ERROR, "Internal error").into_response();
|
||||
}
|
||||
|
||||
Ok(
|
||||
warp::redirect::found(warp::http::Uri::from_str(auth_url.as_str()).unwrap())
|
||||
.into_response(),
|
||||
)
|
||||
Redirect::temporary(auth_url.as_str()).into_response()
|
||||
}
|
||||
|
||||
pub async fn callback_handler(args: CallbackArgs) -> Result<impl Reply, Rejection> {
|
||||
// warp::redirect does not work with '#'.
|
||||
Ok(warp::reply::with_header(
|
||||
warp::http::StatusCode::PERMANENT_REDIRECT,
|
||||
warp::http::header::LOCATION,
|
||||
format!("/#/login?code={}&state={}", args.code, args.state),
|
||||
))
|
||||
pub async fn callback_handler(args: Query<CallbackArgs>) -> Response {
|
||||
let args: CallbackArgs = args.0;
|
||||
Redirect::permanent(&format!("/#/login?code={}&state={}", args.code, args.state))
|
||||
.into_response()
|
||||
}
|
||||
|
||||
pub async fn get_user(code: &str, state: &str) -> Result<User> {
|
||||
|
@ -315,7 +315,7 @@ pub mod test {
|
||||
|
||||
fn get_request<T>(user_id: &Uuid, req: T) -> Request<T> {
|
||||
let mut req = Request::new(req);
|
||||
req.extensions_mut().insert(AuthID::User(user_id.clone()));
|
||||
req.extensions_mut().insert(AuthID::User(*user_id));
|
||||
req
|
||||
}
|
||||
}
|
||||
|
@ -482,9 +482,7 @@ pub mod test {
|
||||
}),
|
||||
};
|
||||
let mut create_req = Request::new(create_req);
|
||||
create_req
|
||||
.extensions_mut()
|
||||
.insert(AuthID::User(u.id.clone()));
|
||||
create_req.extensions_mut().insert(AuthID::User(u.id));
|
||||
let create_resp = service.create(create_req).await.unwrap();
|
||||
|
||||
// get
|
||||
@ -492,7 +490,7 @@ pub mod test {
|
||||
id: create_resp.get_ref().id.clone(),
|
||||
};
|
||||
let mut get_req = Request::new(get_req);
|
||||
get_req.extensions_mut().insert(AuthID::User(u.id.clone()));
|
||||
get_req.extensions_mut().insert(AuthID::User(u.id));
|
||||
let get_resp = service.get(get_req).await.unwrap();
|
||||
assert_eq!(
|
||||
Some(api::Tenant {
|
||||
@ -520,7 +518,7 @@ pub mod test {
|
||||
}),
|
||||
};
|
||||
let mut up_req = Request::new(up_req);
|
||||
up_req.extensions_mut().insert(AuthID::User(u.id.clone()));
|
||||
up_req.extensions_mut().insert(AuthID::User(u.id));
|
||||
let _ = service.update(up_req).await.unwrap();
|
||||
|
||||
// get
|
||||
@ -528,7 +526,7 @@ pub mod test {
|
||||
id: create_resp.get_ref().id.clone(),
|
||||
};
|
||||
let mut get_req = Request::new(get_req);
|
||||
get_req.extensions_mut().insert(AuthID::User(u.id.clone()));
|
||||
get_req.extensions_mut().insert(AuthID::User(u.id));
|
||||
let get_resp = service.get(get_req).await.unwrap();
|
||||
assert_eq!(
|
||||
Some(api::Tenant {
|
||||
@ -551,7 +549,7 @@ pub mod test {
|
||||
user_id: "".into(),
|
||||
};
|
||||
let mut list_req = Request::new(list_req);
|
||||
list_req.extensions_mut().insert(AuthID::User(u.id.clone()));
|
||||
list_req.extensions_mut().insert(AuthID::User(u.id));
|
||||
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());
|
||||
@ -561,14 +559,14 @@ pub mod test {
|
||||
id: create_resp.get_ref().id.clone(),
|
||||
};
|
||||
let mut del_req = Request::new(del_req);
|
||||
del_req.extensions_mut().insert(AuthID::User(u.id.clone()));
|
||||
del_req.extensions_mut().insert(AuthID::User(u.id));
|
||||
let _ = service.delete(del_req).await.unwrap();
|
||||
|
||||
let del_req = api::DeleteTenantRequest {
|
||||
id: create_resp.get_ref().id.clone(),
|
||||
};
|
||||
let mut del_req = Request::new(del_req);
|
||||
del_req.extensions_mut().insert(AuthID::User(u.id.clone()));
|
||||
del_req.extensions_mut().insert(AuthID::User(u.id));
|
||||
let del_resp = service.delete(del_req).await;
|
||||
assert!(del_resp.is_err());
|
||||
}
|
||||
|
@ -292,9 +292,7 @@ pub mod test {
|
||||
}),
|
||||
};
|
||||
let mut create_req = Request::new(create_req);
|
||||
create_req
|
||||
.extensions_mut()
|
||||
.insert(AuthID::User(u.id.clone()));
|
||||
create_req.extensions_mut().insert(AuthID::User(u.id));
|
||||
let create_resp = service.create(create_req).await.unwrap();
|
||||
|
||||
// get
|
||||
@ -302,7 +300,7 @@ pub mod test {
|
||||
id: create_resp.get_ref().id.clone(),
|
||||
};
|
||||
let mut get_req = Request::new(get_req);
|
||||
get_req.extensions_mut().insert(AuthID::User(u.id.clone()));
|
||||
get_req.extensions_mut().insert(AuthID::User(u.id));
|
||||
let get_resp = service.get(get_req).await.unwrap();
|
||||
assert_eq!(
|
||||
Some(api::User {
|
||||
@ -328,7 +326,7 @@ pub mod test {
|
||||
}),
|
||||
};
|
||||
let mut up_req = Request::new(up_req);
|
||||
up_req.extensions_mut().insert(AuthID::User(u.id.clone()));
|
||||
up_req.extensions_mut().insert(AuthID::User(u.id));
|
||||
let _ = service.update(up_req).await.unwrap();
|
||||
|
||||
// get
|
||||
@ -336,7 +334,7 @@ pub mod test {
|
||||
id: create_resp.get_ref().id.clone(),
|
||||
};
|
||||
let mut get_req = Request::new(get_req);
|
||||
get_req.extensions_mut().insert(AuthID::User(u.id.clone()));
|
||||
get_req.extensions_mut().insert(AuthID::User(u.id));
|
||||
let get_resp = service.get(get_req).await.unwrap();
|
||||
assert_eq!(
|
||||
Some(api::User {
|
||||
@ -356,7 +354,7 @@ pub mod test {
|
||||
password: "newpassword".into(),
|
||||
};
|
||||
let mut up_req = Request::new(up_req);
|
||||
up_req.extensions_mut().insert(AuthID::User(u.id.clone()));
|
||||
up_req.extensions_mut().insert(AuthID::User(u.id));
|
||||
let _ = service.update_password(up_req).await.unwrap();
|
||||
|
||||
// list
|
||||
@ -365,7 +363,7 @@ pub mod test {
|
||||
limit: 10,
|
||||
};
|
||||
let mut list_req = Request::new(list_req);
|
||||
list_req.extensions_mut().insert(AuthID::User(u.id.clone()));
|
||||
list_req.extensions_mut().insert(AuthID::User(u.id));
|
||||
let list_resp = service.list(list_req).await.unwrap();
|
||||
// * Admin from migrations
|
||||
// * User that we created for auth
|
||||
@ -378,14 +376,14 @@ pub mod test {
|
||||
id: create_resp.get_ref().id.clone(),
|
||||
};
|
||||
let mut del_req = Request::new(del_req);
|
||||
del_req.extensions_mut().insert(AuthID::User(u.id.clone()));
|
||||
del_req.extensions_mut().insert(AuthID::User(u.id));
|
||||
let _ = service.delete(del_req).await.unwrap();
|
||||
|
||||
let del_req = api::DeleteUserRequest {
|
||||
id: create_resp.get_ref().id.clone(),
|
||||
};
|
||||
let mut del_req = Request::new(del_req);
|
||||
del_req.extensions_mut().insert(AuthID::User(u.id.clone()));
|
||||
del_req.extensions_mut().insert(AuthID::User(u.id));
|
||||
let del_resp = service.delete(del_req).await;
|
||||
assert!(del_resp.is_err());
|
||||
|
||||
@ -393,7 +391,7 @@ pub mod test {
|
||||
id: u.id.to_string(),
|
||||
};
|
||||
let mut del_req = Request::new(del_req);
|
||||
del_req.extensions_mut().insert(AuthID::User(u.id.clone()));
|
||||
del_req.extensions_mut().insert(AuthID::User(u.id));
|
||||
let del_resp = service.delete(del_req).await;
|
||||
assert!(del_resp.is_err());
|
||||
}
|
||||
|
@ -127,8 +127,8 @@ pub mod test {
|
||||
|
||||
for _ in 0..100000 {
|
||||
let offset = get_ping_offset(beacon_ts, &dev_addr, ping_nb).unwrap();
|
||||
assert!(offset <= ping_period - 1);
|
||||
beacon_ts = beacon_ts + *BEACON_PERIOD;
|
||||
assert!(offset < ping_period);
|
||||
beacon_ts += *BEACON_PERIOD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1349,7 +1349,7 @@ impl Data {
|
||||
ds.last_device_status_request = Some(Utc::now().into());
|
||||
}
|
||||
Some(ts) => {
|
||||
let ts: DateTime<Utc> = ts.clone().try_into().map_err(anyhow::Error::msg)?;
|
||||
let ts: DateTime<Utc> = (*ts).try_into().map_err(anyhow::Error::msg)?;
|
||||
let req_interval = Duration::from_secs(60 * 60 * 24)
|
||||
/ self.device_profile.device_status_req_interval as u32;
|
||||
|
||||
@ -1711,8 +1711,7 @@ impl Data {
|
||||
|
||||
match &rd.w_f_cnt_last_request {
|
||||
Some(v) => {
|
||||
let last_req: DateTime<Utc> =
|
||||
v.clone().try_into().map_err(anyhow::Error::msg)?;
|
||||
let last_req: DateTime<Utc> = (*v).try_into().map_err(anyhow::Error::msg)?;
|
||||
if last_req
|
||||
< Utc::now()
|
||||
.checked_sub_signed(chrono::Duration::try_hours(24).unwrap())
|
||||
|
@ -319,7 +319,7 @@ mod tests {
|
||||
for _ in 0..100 {
|
||||
let out = select_downlink_gateway(
|
||||
test.tenant_id,
|
||||
&"eu868",
|
||||
"eu868",
|
||||
test.min_snr_margin,
|
||||
&mut rx_info,
|
||||
)
|
||||
@ -328,8 +328,7 @@ mod tests {
|
||||
}
|
||||
|
||||
assert_eq!(test.expected_gws.len(), gw_map.len());
|
||||
assert_eq!(
|
||||
true,
|
||||
assert!(
|
||||
expected_gws.keys().all(|k| gw_map.contains_key(k)),
|
||||
"Expected: {:?}, got: {:?}",
|
||||
expected_gws,
|
||||
|
@ -649,7 +649,7 @@ impl TxAck {
|
||||
}
|
||||
|
||||
let dfl = stream_pb::DownlinkFrameLog {
|
||||
time: dfl.time.clone(),
|
||||
time: dfl.time,
|
||||
phy_payload: phy.to_vec()?,
|
||||
tx_info: dfl.tx_info.clone(),
|
||||
downlink_id: dfl.downlink_id,
|
||||
|
@ -23,7 +23,7 @@ use tracing::{error, info, trace};
|
||||
|
||||
use super::GatewayBackend;
|
||||
use crate::config::GatewayBackendMqtt;
|
||||
use crate::helpers::tls::{get_root_certs, load_cert, load_key};
|
||||
use crate::helpers::tls22::{get_root_certs, load_cert, load_key};
|
||||
use crate::monitoring::prometheus;
|
||||
use crate::{downlink, uplink};
|
||||
use lrwn::region::CommonName;
|
||||
|
@ -1,2 +1,3 @@
|
||||
pub mod errors;
|
||||
pub mod tls;
|
||||
pub mod tls22; // rustls 0.22
|
||||
|
88
chirpstack/src/helpers/tls22.rs
Normal file
88
chirpstack/src/helpers/tls22.rs
Normal file
@ -0,0 +1,88 @@
|
||||
use std::fs::File;
|
||||
use std::io::BufReader;
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use rumqttc::tokio_rustls::rustls::{
|
||||
self,
|
||||
pki_types::{CertificateDer, PrivateKeyDer},
|
||||
};
|
||||
use tokio::fs;
|
||||
|
||||
// Return root certificates, optionally with the provided ca_file appended.
|
||||
pub fn get_root_certs(ca_file: Option<String>) -> Result<rustls::RootCertStore> {
|
||||
let mut roots = rustls::RootCertStore::empty();
|
||||
for cert in rustls_native_certs::load_native_certs()? {
|
||||
roots.add(cert)?;
|
||||
}
|
||||
|
||||
if let Some(ca_file) = &ca_file {
|
||||
let f = File::open(ca_file).context("Open CA certificate")?;
|
||||
let mut reader = BufReader::new(f);
|
||||
let certs = rustls_pemfile::certs(&mut reader);
|
||||
for cert in certs.flatten() {
|
||||
roots.add(cert)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(roots)
|
||||
}
|
||||
|
||||
pub async fn load_cert(cert_file: &str) -> Result<Vec<CertificateDer<'static>>> {
|
||||
let cert_s = fs::read_to_string(cert_file)
|
||||
.await
|
||||
.context("Read TLS certificate")?;
|
||||
let mut cert_b = cert_s.as_bytes();
|
||||
let certs = rustls_pemfile::certs(&mut cert_b);
|
||||
let mut out = Vec::new();
|
||||
for cert in certs {
|
||||
out.push(cert?.into_owned());
|
||||
}
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
pub async fn load_key(key_file: &str) -> Result<PrivateKeyDer<'static>> {
|
||||
let key_s = fs::read_to_string(key_file)
|
||||
.await
|
||||
.context("Read private key")?;
|
||||
let key_s = private_key_to_pkcs8(&key_s)?;
|
||||
let mut key_b = key_s.as_bytes();
|
||||
let mut keys = rustls_pemfile::pkcs8_private_keys(&mut key_b);
|
||||
if let Some(key) = keys.next() {
|
||||
match key {
|
||||
Ok(v) => return Ok(PrivateKeyDer::Pkcs8(v.clone_key())),
|
||||
Err(e) => {
|
||||
return Err(anyhow!("Error parsing private key, error: {}", e));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Err(anyhow!("No private key found"))
|
||||
}
|
||||
|
||||
pub fn private_key_to_pkcs8(pem: &str) -> Result<String> {
|
||||
if pem.contains("RSA PRIVATE KEY") {
|
||||
use rsa::{
|
||||
pkcs1::DecodeRsaPrivateKey,
|
||||
pkcs8::{EncodePrivateKey, LineEnding},
|
||||
RsaPrivateKey,
|
||||
};
|
||||
|
||||
let pkey = RsaPrivateKey::from_pkcs1_pem(pem).context("Read RSA PKCS#1")?;
|
||||
let pkcs8_pem = pkey.to_pkcs8_pem(LineEnding::default())?;
|
||||
Ok(pkcs8_pem.as_str().to_owned())
|
||||
} else if pem.contains("EC PRIVATE KEY") {
|
||||
use elliptic_curve::{
|
||||
pkcs8::{EncodePrivateKey, LineEnding},
|
||||
SecretKey,
|
||||
};
|
||||
|
||||
// We assume it is a P256 based secret-key, which is the most popular curve.
|
||||
// Attempting to decode it as P256 is still better than just failing to read it.
|
||||
let pkey: SecretKey<p256::NistP256> =
|
||||
SecretKey::from_sec1_pem(pem).context("Read EC SEC1")?;
|
||||
let pkcs8_pem = pkey.to_pkcs8_pem(LineEnding::default())?;
|
||||
Ok(pkcs8_pem.as_str().to_owned())
|
||||
} else {
|
||||
Ok(pem.to_string())
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ use std::time::Duration;
|
||||
use anyhow::{Context, Result};
|
||||
use async_trait::async_trait;
|
||||
use base64::{engine::general_purpose, Engine as _};
|
||||
use gcp_auth::{AuthenticationManager, CustomServiceAccount};
|
||||
use gcp_auth::{CustomServiceAccount, TokenProvider};
|
||||
use prost::Message;
|
||||
use reqwest::header::{HeaderMap, AUTHORIZATION, CONTENT_TYPE};
|
||||
use reqwest::Client;
|
||||
@ -20,7 +20,7 @@ pub struct Integration {
|
||||
json: bool,
|
||||
project_id: String,
|
||||
topic_name: String,
|
||||
auth_manager: gcp_auth::AuthenticationManager,
|
||||
service_account: gcp_auth::CustomServiceAccount,
|
||||
timeout: Duration,
|
||||
}
|
||||
|
||||
@ -46,7 +46,6 @@ impl Integration {
|
||||
pub async fn new(conf: &GcpPubSubConfiguration) -> Result<Integration> {
|
||||
trace!("Initializing GCP Pub-Sub integration");
|
||||
let service_account = CustomServiceAccount::from_json(&conf.credentials_file)?;
|
||||
let auth_manager = AuthenticationManager::try_from(service_account)?;
|
||||
|
||||
Ok(Integration {
|
||||
json: match Encoding::try_from(conf.encoding)
|
||||
@ -57,7 +56,7 @@ impl Integration {
|
||||
},
|
||||
project_id: conf.project_id.clone(),
|
||||
topic_name: conf.topic_name.clone(),
|
||||
auth_manager,
|
||||
service_account,
|
||||
timeout: Duration::from_secs(5),
|
||||
})
|
||||
}
|
||||
@ -89,8 +88,8 @@ impl Integration {
|
||||
let pl = serde_json::to_string(&pl)?;
|
||||
|
||||
let token = self
|
||||
.auth_manager
|
||||
.get_token(&["https://www.googleapis.com/auth/pubsub"])
|
||||
.service_account
|
||||
.token(&["https://www.googleapis.com/auth/pubsub"])
|
||||
.await
|
||||
.context("Get GCP bearer token")?;
|
||||
|
||||
|
@ -43,7 +43,7 @@ pub async fn get_geoloc_buffer(
|
||||
None => {
|
||||
return false;
|
||||
}
|
||||
Some(v) => match v.clone().try_into() {
|
||||
Some(v) => match (*v).try_into() {
|
||||
Ok(v) => v,
|
||||
Err(_) => {
|
||||
return false;
|
||||
|
@ -44,11 +44,7 @@ impl Integration {
|
||||
let di = pl.device_info.as_ref().unwrap();
|
||||
|
||||
info!(dev_eui = %di.dev_eui, "Forwarding join notification");
|
||||
let ts: DateTime<Utc> = pl
|
||||
.time
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.clone()
|
||||
let ts: DateTime<Utc> = (*pl.time.as_ref().unwrap())
|
||||
.try_into()
|
||||
.map_err(anyhow::Error::msg)?;
|
||||
let dev_eui = EUI64::from_str(&di.dev_eui)?;
|
||||
@ -74,11 +70,7 @@ impl Integration {
|
||||
let di = pl.device_info.as_ref().unwrap();
|
||||
|
||||
info!(dev_eui = %di.dev_eui, "Forwarding updf message");
|
||||
let ts: DateTime<Utc> = pl
|
||||
.time
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.clone()
|
||||
let ts: DateTime<Utc> = (*pl.time.as_ref().unwrap())
|
||||
.try_into()
|
||||
.map_err(anyhow::Error::msg)?;
|
||||
let dev_eui = EUI64::from_str(&di.dev_eui)?;
|
||||
@ -150,11 +142,7 @@ impl Integration {
|
||||
) -> Result<()> {
|
||||
let di = pl.device_info.as_ref().unwrap();
|
||||
info!(dev_eui = %di.dev_eui, "Forwarding uplink meta-data");
|
||||
let ts: DateTime<Utc> = pl
|
||||
.time
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.clone()
|
||||
let ts: DateTime<Utc> = (*pl.time.as_ref().unwrap())
|
||||
.try_into()
|
||||
.map_err(anyhow::Error::msg)?;
|
||||
let dev_eui = EUI64::from_str(&di.dev_eui)?;
|
||||
@ -242,11 +230,7 @@ impl Integration {
|
||||
}
|
||||
|
||||
let di = pl.device_info.as_ref().unwrap();
|
||||
let ts: DateTime<Utc> = pl
|
||||
.time
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.clone()
|
||||
let ts: DateTime<Utc> = (*pl.time.as_ref().unwrap())
|
||||
.try_into()
|
||||
.map_err(anyhow::Error::msg)?;
|
||||
let dev_eui = EUI64::from_str(&di.dev_eui)?;
|
||||
|
@ -19,7 +19,7 @@ use tracing::{error, info, trace, warn};
|
||||
|
||||
use super::Integration as IntegrationTrait;
|
||||
use crate::config::MqttIntegration as Config;
|
||||
use crate::helpers::tls::{get_root_certs, load_cert, load_key};
|
||||
use crate::helpers::tls22::{get_root_certs, load_cert, load_key};
|
||||
use chirpstack_api::integration;
|
||||
|
||||
pub struct Integration<'a> {
|
||||
|
@ -268,11 +268,7 @@ impl IntegrationTrait for Integration {
|
||||
|
||||
let e = EventUp {
|
||||
deduplication_id: Uuid::from_str(&pl.deduplication_id)?,
|
||||
time: pl
|
||||
.time
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.clone()
|
||||
time: (*pl.time.as_ref().unwrap())
|
||||
.try_into()
|
||||
.map_err(anyhow::Error::msg)?,
|
||||
tenant_id: Uuid::from_str(&di.tenant_id)?,
|
||||
@ -314,11 +310,7 @@ impl IntegrationTrait for Integration {
|
||||
|
||||
let e = EventJoin {
|
||||
deduplication_id: Uuid::from_str(&pl.deduplication_id)?,
|
||||
time: pl
|
||||
.time
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.clone()
|
||||
time: (*pl.time.as_ref().unwrap())
|
||||
.try_into()
|
||||
.map_err(anyhow::Error::msg)?,
|
||||
tenant_id: Uuid::from_str(&di.tenant_id)?,
|
||||
@ -352,11 +344,7 @@ impl IntegrationTrait for Integration {
|
||||
let e = EventAck {
|
||||
queue_item_id: Uuid::from_str(&pl.queue_item_id)?,
|
||||
deduplication_id: Uuid::from_str(&pl.deduplication_id)?,
|
||||
time: pl
|
||||
.time
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.clone()
|
||||
time: (*pl.time.as_ref().unwrap())
|
||||
.try_into()
|
||||
.map_err(anyhow::Error::msg)?,
|
||||
tenant_id: Uuid::from_str(&di.tenant_id)?,
|
||||
@ -391,11 +379,7 @@ impl IntegrationTrait for Integration {
|
||||
let e = EventTxAck {
|
||||
queue_item_id: Uuid::from_str(&pl.queue_item_id)?,
|
||||
downlink_id: pl.downlink_id as i64,
|
||||
time: pl
|
||||
.time
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.clone()
|
||||
time: (*pl.time.as_ref().unwrap())
|
||||
.try_into()
|
||||
.map_err(anyhow::Error::msg)?,
|
||||
tenant_id: Uuid::from_str(&di.tenant_id)?,
|
||||
@ -429,11 +413,7 @@ impl IntegrationTrait for Integration {
|
||||
info!(dev_eui = %di.dev_eui, event = "log", "Inserting event");
|
||||
|
||||
let e = EventLog {
|
||||
time: pl
|
||||
.time
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.clone()
|
||||
time: (*pl.time.as_ref().unwrap())
|
||||
.try_into()
|
||||
.map_err(anyhow::Error::msg)?,
|
||||
tenant_id: Uuid::from_str(&di.tenant_id)?,
|
||||
@ -469,11 +449,7 @@ impl IntegrationTrait for Integration {
|
||||
|
||||
let e = EventStatus {
|
||||
deduplication_id: Uuid::from_str(&pl.deduplication_id)?,
|
||||
time: pl
|
||||
.time
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.clone()
|
||||
time: (*pl.time.as_ref().unwrap())
|
||||
.try_into()
|
||||
.map_err(anyhow::Error::msg)?,
|
||||
tenant_id: Uuid::from_str(&di.tenant_id)?,
|
||||
@ -510,11 +486,7 @@ impl IntegrationTrait for Integration {
|
||||
|
||||
let e = EventLocation {
|
||||
deduplication_id: Uuid::from_str(&pl.deduplication_id)?,
|
||||
time: pl
|
||||
.time
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.clone()
|
||||
time: (*pl.time.as_ref().unwrap())
|
||||
.try_into()
|
||||
.map_err(anyhow::Error::msg)?,
|
||||
tenant_id: Uuid::from_str(&di.tenant_id)?,
|
||||
@ -551,11 +523,7 @@ impl IntegrationTrait for Integration {
|
||||
|
||||
let e = EventIntegration {
|
||||
deduplication_id: Uuid::from_str(&pl.deduplication_id)?,
|
||||
time: pl
|
||||
.time
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.clone()
|
||||
time: (*pl.time.as_ref().unwrap())
|
||||
.try_into()
|
||||
.map_err(anyhow::Error::msg)?,
|
||||
tenant_id: Uuid::from_str(&di.tenant_id)?,
|
||||
|
@ -240,10 +240,10 @@ pub mod test {
|
||||
async fn assert_reply(last_id: &str, event: &str, b: &[u8]) -> String {
|
||||
let srr: StreamReadReply = redis::cmd("XREAD")
|
||||
.arg("COUNT")
|
||||
.arg(1 as usize)
|
||||
.arg(1_usize)
|
||||
.arg("STREAMS")
|
||||
.arg("device:stream:event")
|
||||
.arg(&last_id)
|
||||
.arg(last_id)
|
||||
.query_async(&mut get_async_redis_conn().await.unwrap())
|
||||
.await
|
||||
.unwrap();
|
||||
@ -254,7 +254,7 @@ pub mod test {
|
||||
let stream_id = &stream_key.ids[0];
|
||||
|
||||
let v = stream_id.map.get(event).unwrap();
|
||||
assert_eq!(&redis::Value::Data(b.to_vec()), v);
|
||||
assert_eq!(&redis::Value::BulkString(b.to_vec()), v);
|
||||
|
||||
stream_id.id.clone()
|
||||
}
|
||||
|
@ -128,10 +128,10 @@ mod test {
|
||||
);
|
||||
|
||||
if let Some(e) = &tst.expected_error {
|
||||
assert_eq!(true, resp.is_err(), "{}", tst.name);
|
||||
assert!(resp.is_err(), "{}", tst.name);
|
||||
assert_eq!(e, &format!("{}", resp.err().unwrap()), "{}", tst.name);
|
||||
} else {
|
||||
assert_eq!(true, resp.unwrap().is_none());
|
||||
assert!(resp.unwrap().is_none());
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
|
@ -297,10 +297,10 @@ mod test {
|
||||
.await;
|
||||
|
||||
if let Some(e) = &tst.expected_error {
|
||||
assert_eq!(true, resp.is_err(), "{}", tst.name);
|
||||
assert!(resp.is_err(), "{}", tst.name);
|
||||
assert_eq!(e, &format!("{}", resp.err().unwrap()), "{}", tst.name);
|
||||
} else {
|
||||
assert_eq!(true, resp.unwrap().is_none());
|
||||
assert!(resp.unwrap().is_none());
|
||||
}
|
||||
|
||||
let d = device::get(&dev.dev_eui).await.unwrap();
|
||||
|
@ -137,22 +137,22 @@ pub mod test {
|
||||
.await
|
||||
.unwrap();
|
||||
let app = application::create(application::Application {
|
||||
tenant_id: tenant.id.clone(),
|
||||
tenant_id: tenant.id,
|
||||
name: "test-app".into(),
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
tenant_id: tenant.id.clone(),
|
||||
tenant_id: tenant.id,
|
||||
name: "test-dp".into(),
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
let dev = device::create(device::Device {
|
||||
application_id: app.id.clone(),
|
||||
device_profile_id: dp.id.clone(),
|
||||
application_id: app.id,
|
||||
device_profile_id: dp.id,
|
||||
dev_eui: EUI64::from_str("0102030405060708").unwrap(),
|
||||
name: "test-device".into(),
|
||||
..Default::default()
|
||||
@ -170,7 +170,7 @@ pub mod test {
|
||||
let resp = handle(&ufs, &tenant, &app, &dp, &dev, &block)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(true, resp.is_none());
|
||||
assert!(resp.is_none());
|
||||
|
||||
// Integration events are handled async.
|
||||
sleep(Duration::from_millis(100)).await;
|
||||
@ -201,7 +201,7 @@ pub mod test {
|
||||
|
||||
let d = device::get(&dev.dev_eui).await.unwrap();
|
||||
assert_eq!(Some(10), d.margin);
|
||||
assert_eq!(false, d.external_power_source);
|
||||
assert!(!d.external_power_source);
|
||||
assert_eq!(
|
||||
Some(BigDecimal::from_str("100.00").unwrap()),
|
||||
d.battery_level
|
||||
|
@ -50,22 +50,22 @@ pub mod test {
|
||||
.await
|
||||
.unwrap();
|
||||
let app = application::create(application::Application {
|
||||
tenant_id: tenant.id.clone(),
|
||||
tenant_id: tenant.id,
|
||||
name: "test-app".into(),
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
tenant_id: tenant.id.clone(),
|
||||
tenant_id: tenant.id,
|
||||
name: "test-dp".into(),
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
let dev = device::create(device::Device {
|
||||
application_id: app.id.clone(),
|
||||
device_profile_id: dp.id.clone(),
|
||||
application_id: app.id,
|
||||
device_profile_id: dp.id,
|
||||
dev_eui: EUI64::from_str("0102030405060708").unwrap(),
|
||||
name: "test-device".into(),
|
||||
..Default::default()
|
||||
|
@ -188,10 +188,10 @@ mod test {
|
||||
);
|
||||
|
||||
if let Some(e) = &tst.expected_error {
|
||||
assert_eq!(true, resp.is_err(), "{}", tst.name);
|
||||
assert!(resp.is_err(), "{}", tst.name);
|
||||
assert_eq!(e, &format!("{}", resp.err().unwrap()), "{}", tst.name);
|
||||
} else {
|
||||
assert_eq!(true, resp.unwrap().is_none());
|
||||
assert!(resp.unwrap().is_none());
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
|
@ -222,10 +222,10 @@ mod test {
|
||||
let resp = handle(&mut dev, &tst.filter_list_ans, tst.filter_list_req.as_ref());
|
||||
|
||||
if let Some(e) = &tst.expected_error {
|
||||
assert_eq!(true, resp.is_err(), "{}", tst.name);
|
||||
assert!(resp.is_err(), "{}", tst.name);
|
||||
assert_eq!(e, &format!("{}", resp.err().unwrap()), "{}", tst.name);
|
||||
} else {
|
||||
assert_eq!(true, resp.unwrap().is_none());
|
||||
assert!(resp.unwrap().is_none());
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
|
@ -171,7 +171,7 @@ pub mod test {
|
||||
#[test]
|
||||
fn test() {
|
||||
region::set(
|
||||
&"eu868",
|
||||
"eu868",
|
||||
lrwn::region::get(lrwn::region::CommonName::EU868, false, false),
|
||||
);
|
||||
|
||||
@ -367,19 +367,17 @@ pub mod test {
|
||||
let block = lrwn::MACCommandSet::new(vec![lrwn::MACCommand::LinkADRAns(
|
||||
tst.link_adr_ans.clone(),
|
||||
)]);
|
||||
let pending = match &tst.link_adr_req {
|
||||
Some(v) => Some(lrwn::MACCommandSet::new(vec![
|
||||
lrwn::MACCommand::LinkADRReq(v.clone()),
|
||||
])),
|
||||
None => None,
|
||||
};
|
||||
let pending = tst
|
||||
.link_adr_req
|
||||
.as_ref()
|
||||
.map(|v| lrwn::MACCommandSet::new(vec![lrwn::MACCommand::LinkADRReq(v.clone())]));
|
||||
|
||||
let res = handle(&ufs, &mut dev, &block, pending.as_ref());
|
||||
if let Some(e) = &tst.expected_error {
|
||||
assert_eq!(true, res.is_err(), "{}", tst.name);
|
||||
assert!(res.is_err(), "{}", tst.name);
|
||||
assert_eq!(e, &format!("{}", res.err().unwrap()), "{}", tst.name);
|
||||
} else {
|
||||
assert_eq!(true, res.unwrap().is_none(), "{}", tst.name);
|
||||
assert!(res.unwrap().is_none(), "{}", tst.name);
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
|
@ -479,10 +479,10 @@ pub mod test {
|
||||
let res = handle(&mut dev, &tst.new_channel_ans, tst.new_channel_req.as_ref());
|
||||
|
||||
if let Some(e) = &tst.expected_error {
|
||||
assert_eq!(true, res.is_err(), "{}", tst.name);
|
||||
assert!(res.is_err(), "{}", tst.name);
|
||||
assert_eq!(e, &format!("{}", res.err().unwrap()), "{}", tst.name);
|
||||
} else {
|
||||
assert_eq!(true, res.unwrap().is_none(), "{}", tst.name);
|
||||
assert!(res.unwrap().is_none(), "{}", tst.name);
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
|
@ -193,10 +193,10 @@ pub mod test {
|
||||
);
|
||||
|
||||
if let Some(e) = &tst.expected_error {
|
||||
assert_eq!(true, resp.is_err(), "{}", tst.name);
|
||||
assert!(resp.is_err(), "{}", tst.name);
|
||||
assert_eq!(e, &format!("{}", resp.err().unwrap()), "{}", tst.name);
|
||||
} else {
|
||||
assert_eq!(true, resp.unwrap().is_none());
|
||||
assert!(resp.unwrap().is_none());
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
|
@ -171,10 +171,10 @@ pub mod test {
|
||||
);
|
||||
|
||||
if let Some(e) = &tst.expected_error {
|
||||
assert_eq!(true, resp.is_err(), "{}", tst.name);
|
||||
assert!(resp.is_err(), "{}", tst.name);
|
||||
assert_eq!(e, &format!("{}", resp.err().unwrap()), "{}", tst.name);
|
||||
} else {
|
||||
assert_eq!(true, resp.unwrap().is_none());
|
||||
assert!(resp.unwrap().is_none());
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
|
@ -186,10 +186,10 @@ mod test {
|
||||
let resp = handle(&mut dev, &tst.relay_conf_ans, tst.relay_conf_req.as_ref());
|
||||
|
||||
if let Some(e) = &tst.expected_error {
|
||||
assert_eq!(true, resp.is_err(), "{}", tst.name);
|
||||
assert!(resp.is_err(), "{}", tst.name);
|
||||
assert_eq!(e, &format!("{}", resp.err().unwrap()), "{}", tst.name);
|
||||
} else {
|
||||
assert_eq!(true, resp.unwrap().is_none());
|
||||
assert!(resp.unwrap().is_none());
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
|
@ -194,10 +194,10 @@ pub mod test {
|
||||
);
|
||||
|
||||
if let Some(e) = &tst.expected_error {
|
||||
assert_eq!(true, resp.is_err(), "{}", tst.name);
|
||||
assert!(resp.is_err(), "{}", tst.name);
|
||||
assert_eq!(e, &format!("{}", resp.err().unwrap()), "{}", tst.name);
|
||||
} else {
|
||||
assert_eq!(true, resp.unwrap().is_none());
|
||||
assert!(resp.unwrap().is_none());
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
|
@ -113,10 +113,10 @@ pub mod test {
|
||||
);
|
||||
|
||||
if let Some(e) = &tst.expected_error {
|
||||
assert_eq!(true, resp.is_err(), "{}", tst.name);
|
||||
assert!(resp.is_err(), "{}", tst.name);
|
||||
assert_eq!(e, &format!("{}", resp.err().unwrap()), "{}", tst.name);
|
||||
} else {
|
||||
assert_eq!(true, resp.unwrap().is_none());
|
||||
assert!(resp.unwrap().is_none());
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
|
@ -149,10 +149,10 @@ pub mod test {
|
||||
);
|
||||
|
||||
if let Some(e) = &tst.expected_error {
|
||||
assert_eq!(true, resp.is_err(), "{}", tst.name);
|
||||
assert!(resp.is_err(), "{}", tst.name);
|
||||
assert_eq!(e, &format!("{}", resp.err().unwrap()), "{}", tst.name);
|
||||
} else {
|
||||
assert_eq!(true, resp.unwrap().is_none());
|
||||
assert!(resp.unwrap().is_none());
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
|
@ -137,10 +137,10 @@ pub mod test {
|
||||
);
|
||||
|
||||
if let Some(e) = &tst.expected_error {
|
||||
assert_eq!(true, resp.is_err(), "{}", tst.name);
|
||||
assert!(resp.is_err(), "{}", tst.name);
|
||||
assert_eq!(e, &format!("{}", resp.err().unwrap()), "{}", tst.name);
|
||||
} else {
|
||||
assert_eq!(true, resp.unwrap().is_none());
|
||||
assert!(resp.unwrap().is_none());
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
|
@ -127,7 +127,7 @@ pub mod test {
|
||||
pub async fn create_api_key(is_admin: bool, is_tenant: bool) -> ApiKey {
|
||||
let ak = ApiKey {
|
||||
name: "test api key".into(),
|
||||
is_admin: is_admin,
|
||||
is_admin,
|
||||
tenant_id: match is_tenant {
|
||||
false => None,
|
||||
true => Some(tenant::test::create_tenant().await.id),
|
||||
@ -191,6 +191,6 @@ pub mod test {
|
||||
|
||||
// delete
|
||||
delete(&ak_admin.id).await.unwrap();
|
||||
assert_eq!(true, delete(&ak_admin.id).await.is_err());
|
||||
assert!(delete(&ak_admin.id).await.is_err());
|
||||
}
|
||||
}
|
||||
|
@ -556,7 +556,7 @@ pub mod test {
|
||||
};
|
||||
|
||||
let a = Application {
|
||||
tenant_id: tenant_id,
|
||||
tenant_id,
|
||||
name: "test application".into(),
|
||||
description: "test application description".into(),
|
||||
..Default::default()
|
||||
@ -662,6 +662,6 @@ pub mod test {
|
||||
|
||||
// delete
|
||||
delete(&app.id).await.unwrap();
|
||||
assert_eq!(true, delete(&app.id).await.is_err());
|
||||
assert!(delete(&app.id).await.is_err());
|
||||
}
|
||||
}
|
||||
|
@ -795,9 +795,9 @@ pub mod test {
|
||||
|
||||
let d = Device {
|
||||
name: "test-dev".into(),
|
||||
dev_eui: dev_eui,
|
||||
application_id: application_id,
|
||||
device_profile_id: device_profile_id,
|
||||
dev_eui,
|
||||
application_id,
|
||||
device_profile_id,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
@ -899,7 +899,7 @@ pub mod test {
|
||||
|
||||
// delete
|
||||
delete(&d.dev_eui).await.unwrap();
|
||||
assert_eq!(true, delete(&d.dev_eui).await.is_err());
|
||||
assert!(delete(&d.dev_eui).await.is_err());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@ -1005,7 +1005,7 @@ pub mod test {
|
||||
#[test]
|
||||
fn test_get_full_f_cnt_up() {
|
||||
// server, device, expected
|
||||
let tests = vec![
|
||||
let tests = [
|
||||
(1, 1, 1), // frame-counter is as expected
|
||||
(1 << 16, 0, 1 << 16), // frame-counter is as expected
|
||||
((1 << 16) + 1, 1, (1 << 16) + 1), // frame-counter is as expected
|
||||
@ -1014,7 +1014,7 @@ pub mod test {
|
||||
(2, 1, 1), // re-transmission of previous frame
|
||||
((1 << 16) + 1, 0, (1 << 16)), // re-transmission of previous frame
|
||||
((1 << 16), (1 << 16) - 1, (1 << 16) - 1), // re-transmission of previous frame
|
||||
(u32::MAX, 0, 0), // 32bit frame-counter rollover
|
||||
(u32::MAX, 0, 0),
|
||||
];
|
||||
|
||||
for (i, tst) in tests.iter().enumerate() {
|
||||
@ -1363,7 +1363,7 @@ pub mod test {
|
||||
|
||||
let d = get_for_phypayload_and_incr_f_cnt_up(false, &mut phy, 0, 0).await;
|
||||
if tst.expected_error.is_some() {
|
||||
assert_eq!(true, d.is_err());
|
||||
assert!(d.is_err());
|
||||
assert_eq!(
|
||||
tst.expected_error.as_ref().unwrap(),
|
||||
&d.err().unwrap().to_string()
|
||||
@ -1380,15 +1380,15 @@ pub mod test {
|
||||
}
|
||||
|
||||
if let ValidationStatus::Ok(full_f_cnt, d) = d {
|
||||
assert_eq!(false, tst.expected_retransmission);
|
||||
assert!(!tst.expected_retransmission);
|
||||
assert_eq!(tst.expected_dev_eui, d.dev_eui,);
|
||||
assert_eq!(tst.expected_fcnt_up, full_f_cnt);
|
||||
} else if let ValidationStatus::Retransmission(full_f_cnt, d) = d {
|
||||
assert_eq!(true, tst.expected_retransmission);
|
||||
assert!(tst.expected_retransmission);
|
||||
assert_eq!(tst.expected_dev_eui, d.dev_eui,);
|
||||
assert_eq!(tst.expected_fcnt_up, full_f_cnt);
|
||||
} else if let ValidationStatus::Reset(_, d) = d {
|
||||
assert_eq!(true, tst.expected_reset);
|
||||
assert!(tst.expected_reset);
|
||||
assert_eq!(tst.expected_dev_eui, d.dev_eui,);
|
||||
}
|
||||
}
|
||||
|
@ -189,7 +189,7 @@ pub mod test {
|
||||
};
|
||||
|
||||
let dk = DeviceKeys {
|
||||
dev_eui: dev_eui,
|
||||
dev_eui,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
@ -213,6 +213,6 @@ pub mod test {
|
||||
|
||||
// delete
|
||||
delete(&dk.dev_eui).await.unwrap();
|
||||
assert_eq!(true, delete(&dk.dev_eui).await.is_err());
|
||||
assert!(delete(&dk.dev_eui).await.is_err());
|
||||
}
|
||||
}
|
||||
|
@ -397,7 +397,7 @@ pub mod test {
|
||||
kv.insert("foo".into(), "bar".into());
|
||||
|
||||
let dp = DeviceProfile {
|
||||
tenant_id: tenant_id,
|
||||
tenant_id,
|
||||
name: "test device-profile".into(),
|
||||
region: CommonName::EU868,
|
||||
mac_version: MacVersion::LORAWAN_1_0_2,
|
||||
@ -501,6 +501,6 @@ pub mod test {
|
||||
|
||||
// delete
|
||||
delete(&dp.id).await.unwrap();
|
||||
assert_eq!(true, delete(&dp.id).await.is_err());
|
||||
assert!(delete(&dp.id).await.is_err());
|
||||
}
|
||||
}
|
||||
|
@ -361,6 +361,6 @@ pub mod test {
|
||||
|
||||
// delete
|
||||
delete(&dp.id).await.unwrap();
|
||||
assert_eq!(true, delete(&dp.id).await.is_err());
|
||||
assert!(delete(&dp.id).await.is_err());
|
||||
}
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ pub mod test {
|
||||
// next next queue item for dev eui
|
||||
let resp = get_next_for_dev_eui(&d.dev_eui).await.unwrap();
|
||||
assert_eq!(qi, resp.0);
|
||||
assert_eq!(false, resp.1);
|
||||
assert!(!resp.1);
|
||||
|
||||
// update
|
||||
qi.is_pending = true;
|
||||
@ -244,7 +244,7 @@ pub mod test {
|
||||
|
||||
// delete
|
||||
delete_item(&qi.id).await.unwrap();
|
||||
assert_eq!(true, delete_item(&qi.id).await.is_err());
|
||||
assert!(delete_item(&qi.id).await.is_err());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@ -269,7 +269,7 @@ pub mod test {
|
||||
|
||||
// flush
|
||||
flush_for_dev_eui(&d.dev_eui).await.unwrap();
|
||||
assert_eq!(true, delete_item(&qi.id).await.is_err());
|
||||
assert!(delete_item(&qi.id).await.is_err());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
@ -502,7 +502,7 @@ pub mod test {
|
||||
|
||||
let gw = Gateway {
|
||||
gateway_id: id,
|
||||
tenant_id: tenant_id,
|
||||
tenant_id,
|
||||
name: "gw".into(),
|
||||
..Default::default()
|
||||
};
|
||||
@ -653,7 +653,7 @@ pub mod test {
|
||||
|
||||
// delete
|
||||
delete(&gw.gateway_id).await.unwrap();
|
||||
assert_eq!(true, delete(&gw.gateway_id).await.is_err());
|
||||
assert!(delete(&gw.gateway_id).await.is_err());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
@ -87,6 +87,6 @@ pub mod test {
|
||||
let resp = get_pending(&dev_eui, lrwn::CID::DevStatusReq)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(true, resp.is_none());
|
||||
assert!(resp.is_none());
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ pub async fn save(ds: &internal::PassiveRoamingDeviceSession) -> Result<()> {
|
||||
EUI64::from_slice(&ds.dev_eui)?
|
||||
};
|
||||
|
||||
let lifetime: DateTime<Utc> = match ds.lifetime.clone() {
|
||||
let lifetime: DateTime<Utc> = match ds.lifetime {
|
||||
Some(v) => v.try_into().map_err(anyhow::Error::msg)?,
|
||||
None => {
|
||||
debug!("Not saving passive-roaming device-session, no passive-roaming lifetime set");
|
||||
|
@ -254,7 +254,7 @@ pub mod test {
|
||||
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "test-dp".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -262,7 +262,7 @@ pub mod test {
|
||||
|
||||
let a = application::create(application::Application {
|
||||
name: "test-app".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -271,7 +271,7 @@ pub mod test {
|
||||
let _gw = gateway::create(gateway::Gateway {
|
||||
gateway_id: EUI64::from_str("0102030405060708").unwrap(),
|
||||
name: "test-gateway".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -280,8 +280,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.clone(),
|
||||
device_profile_id: dp.id.clone(),
|
||||
application_id: a.id,
|
||||
device_profile_id: dp.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -322,8 +322,8 @@ pub mod test {
|
||||
|
||||
// User is tenant-user, this returns results.
|
||||
tenant::add_user(tenant::TenantUser {
|
||||
tenant_id: t.id.clone(),
|
||||
user_id: u.id.clone(),
|
||||
tenant_id: t.id,
|
||||
user_id: u.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
|
@ -344,7 +344,7 @@ pub mod test {
|
||||
let _guard = test::prepare().await;
|
||||
|
||||
// delete default tenant
|
||||
let _ = delete(&Uuid::from_str("52f14cd4-c6f1-4fbd-8f87-4025e1d49242").unwrap())
|
||||
delete(&Uuid::from_str("52f14cd4-c6f1-4fbd-8f87-4025e1d49242").unwrap())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
@ -454,7 +454,7 @@ pub mod test {
|
||||
|
||||
// delete
|
||||
delete(&t.id).await.unwrap();
|
||||
assert_eq!(true, delete(&t.id).await.is_err());
|
||||
assert!(delete(&t.id).await.is_err());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
@ -232,20 +232,20 @@ pub mod test {
|
||||
email_verified: true,
|
||||
..Default::default()
|
||||
};
|
||||
user.set_password_hash(&"password!", 1).unwrap();
|
||||
user.set_password_hash("password!", 1).unwrap();
|
||||
create(user).await.unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hash_password() {
|
||||
assert_eq!(true, hash_password(&"foobar", 1000).is_ok());
|
||||
assert!(hash_password("foobar", 1000).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_verify_password() {
|
||||
// this is the ChirpStack Application Server default admin hash, with == removed
|
||||
// to test the compatibility betweeh the two pbkdf2 implementations.
|
||||
assert_eq!(true, verify_password(&"admin", &"$pbkdf2-sha512$i=1,l=64$l8zGKtxRESq3PA2kFhHRWA$H3lGMxOt55wjwoc+myeOoABofJY9oDpldJa7fhqdjbh700V6FLPML75UmBOt9J5VFNjAL1AvqCozA1HJM0QVGA"));
|
||||
assert!(verify_password("admin", "$pbkdf2-sha512$i=1,l=64$l8zGKtxRESq3PA2kFhHRWA$H3lGMxOt55wjwoc+myeOoABofJY9oDpldJa7fhqdjbh700V6FLPML75UmBOt9J5VFNjAL1AvqCozA1HJM0QVGA"));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@ -262,23 +262,20 @@ pub mod test {
|
||||
user = update(user).await.unwrap();
|
||||
|
||||
// get by external id
|
||||
let user_get = get_by_external_id(&"external_id").await.unwrap();
|
||||
let user_get = get_by_external_id("external_id").await.unwrap();
|
||||
assert_eq!(user, user_get);
|
||||
|
||||
// get_by_email_and_pw
|
||||
assert_eq!(
|
||||
true,
|
||||
get_by_email_and_pw(&"test@example.com", &"bar")
|
||||
.await
|
||||
.is_err()
|
||||
);
|
||||
let user_get = get_by_email_and_pw(&"test@example.com", &"password!")
|
||||
assert!(get_by_email_and_pw("test@example.com", "bar")
|
||||
.await
|
||||
.is_err());
|
||||
let user_get = get_by_email_and_pw("test@example.com", "password!")
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(user, user_get);
|
||||
|
||||
// delete
|
||||
delete(&user.id).await.unwrap();
|
||||
assert_eq!(true, delete(&user.id).await.is_err());
|
||||
assert!(delete(&user.id).await.is_err());
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ mod tests {
|
||||
let key = redis_key("api:stream:request".to_string());
|
||||
let srr: StreamReadReply = redis::cmd("XREAD")
|
||||
.arg("COUNT")
|
||||
.arg(1 as usize)
|
||||
.arg(1_usize)
|
||||
.arg("STREAMS")
|
||||
.arg(&key)
|
||||
.arg("0")
|
||||
@ -62,7 +62,7 @@ mod tests {
|
||||
assert_eq!(1, srr.keys.len());
|
||||
assert_eq!(1, srr.keys[0].ids.len());
|
||||
|
||||
if let Some(redis::Value::Data(b)) = srr.keys[0].ids[0].map.get("request") {
|
||||
if let Some(redis::Value::BulkString(b)) = srr.keys[0].ids[0].map.get("request") {
|
||||
let pl_recv = stream::ApiRequestLog::decode(&mut Cursor::new(b)).unwrap();
|
||||
assert_eq!(pl, pl_recv);
|
||||
} else {
|
||||
|
@ -115,7 +115,7 @@ async fn handle_stream(
|
||||
match k {
|
||||
"up" => {
|
||||
trace!(key = %k, id = %stream_id, "Event-log received from stream");
|
||||
if let redis::Value::Data(b) = v {
|
||||
if let redis::Value::BulkString(b) = v {
|
||||
let pl = integration::UplinkEvent::decode(&mut Cursor::new(b))?;
|
||||
let pl = api::LogItem {
|
||||
id: stream_id.to_string(),
|
||||
@ -141,7 +141,7 @@ async fn handle_stream(
|
||||
}
|
||||
"join" => {
|
||||
trace!(key = %k, id = %stream_id, "Event-log received from stream");
|
||||
if let redis::Value::Data(b) = v {
|
||||
if let redis::Value::BulkString(b) = v {
|
||||
let pl = integration::JoinEvent::decode(&mut Cursor::new(b))?;
|
||||
let pl = api::LogItem {
|
||||
id: stream_id.to_string(),
|
||||
@ -162,7 +162,7 @@ async fn handle_stream(
|
||||
}
|
||||
"ack" => {
|
||||
trace!(key = %k, id = %stream_id, "Event-log received from stream");
|
||||
if let redis::Value::Data(b) = v {
|
||||
if let redis::Value::BulkString(b) = v {
|
||||
let pl = integration::AckEvent::decode(&mut Cursor::new(b))?;
|
||||
let pl = api::LogItem {
|
||||
id: stream_id.to_string(),
|
||||
@ -180,7 +180,7 @@ async fn handle_stream(
|
||||
}
|
||||
"txack" => {
|
||||
trace!(key = %k, id = %stream_id, "Event-log received from stream");
|
||||
if let redis::Value::Data(b) = v {
|
||||
if let redis::Value::BulkString(b) = v {
|
||||
let pl = integration::TxAckEvent::decode(&mut Cursor::new(b))?;
|
||||
let pl = api::LogItem {
|
||||
id: stream_id.to_string(),
|
||||
@ -198,7 +198,7 @@ async fn handle_stream(
|
||||
}
|
||||
"status" => {
|
||||
trace!(key = %k, id = %stream_id, "Event-log received from stream");
|
||||
if let redis::Value::Data(b) = v {
|
||||
if let redis::Value::BulkString(b) = v {
|
||||
let pl = integration::StatusEvent::decode(&mut Cursor::new(b))?;
|
||||
let pl = api::LogItem {
|
||||
id: stream_id.to_string(),
|
||||
@ -230,7 +230,7 @@ async fn handle_stream(
|
||||
}
|
||||
"log" => {
|
||||
trace!(key = %k, id =%stream_id, "Event-log received from stream");
|
||||
if let redis::Value::Data(b) = v {
|
||||
if let redis::Value::BulkString(b) = v {
|
||||
let pl = integration::LogEvent::decode(&mut Cursor::new(b))?;
|
||||
let pl = api::LogItem {
|
||||
id: stream_id.to_string(),
|
||||
@ -254,7 +254,7 @@ async fn handle_stream(
|
||||
}
|
||||
"location" => {
|
||||
trace!(key = %k, id=%stream_id, "Event-log received from stream");
|
||||
if let redis::Value::Data(b) = v {
|
||||
if let redis::Value::BulkString(b) = v {
|
||||
let pl = integration::LocationEvent::decode(&mut Cursor::new(b))?;
|
||||
let pl = api::LogItem {
|
||||
id: stream_id.to_string(),
|
||||
@ -272,7 +272,7 @@ async fn handle_stream(
|
||||
}
|
||||
"integration" => {
|
||||
trace!(key = %k, id=%stream_id, "Event-log received from stream");
|
||||
if let redis::Value::Data(b) = v {
|
||||
if let redis::Value::BulkString(b) = v {
|
||||
let pl = integration::IntegrationEvent::decode(&mut Cursor::new(b))?;
|
||||
let pl = api::LogItem {
|
||||
id: stream_id.to_string(),
|
||||
|
@ -30,7 +30,7 @@ pub async fn log_uplink_for_gateways(ufl: &stream::UplinkFrameLog) -> Result<()>
|
||||
m_type: ufl.m_type,
|
||||
dev_addr: ufl.dev_addr.clone(),
|
||||
dev_eui: ufl.dev_eui.clone(),
|
||||
time: ufl.time.clone(),
|
||||
time: ufl.time,
|
||||
plaintext_f_opts: ufl.plaintext_f_opts,
|
||||
plaintext_frm_payload: ufl.plaintext_frm_payload,
|
||||
};
|
||||
@ -279,7 +279,7 @@ async fn handle_stream(
|
||||
match k {
|
||||
"up" => {
|
||||
trace!(key = %k, id = %stream_id, "Frame-log received from stream");
|
||||
if let redis::Value::Data(b) = v {
|
||||
if let redis::Value::BulkString(b) = v {
|
||||
let pl = stream::UplinkFrameLog::decode(&mut Cursor::new(b))?;
|
||||
let mut phy = lrwn::PhyPayload::from_slice(&pl.phy_payload)?;
|
||||
if pl.plaintext_f_opts {
|
||||
@ -320,7 +320,7 @@ async fn handle_stream(
|
||||
}
|
||||
"down" => {
|
||||
trace!(key = %k, id = %stream_id, "frame-log received from stream");
|
||||
if let redis::Value::Data(b) = v {
|
||||
if let redis::Value::BulkString(b) = v {
|
||||
let pl = stream::DownlinkFrameLog::decode(&mut Cursor::new(b))?;
|
||||
let mut phy = lrwn::PhyPayload::from_slice(&pl.phy_payload)?;
|
||||
if pl.plaintext_f_opts {
|
||||
|
@ -25,7 +25,7 @@ pub type Validator = Box<dyn Fn() -> Pin<Box<dyn Future<Output = ()>>>>;
|
||||
|
||||
pub fn f_cnt_up(dev_eui: EUI64, f_cnt: u32) -> Validator {
|
||||
Box::new(move || {
|
||||
let dev_eui = dev_eui.clone();
|
||||
let dev_eui = dev_eui;
|
||||
Box::pin(async move {
|
||||
let d = device::get(&dev_eui).await.unwrap();
|
||||
let ds = d.get_device_session().unwrap();
|
||||
@ -36,7 +36,7 @@ pub fn f_cnt_up(dev_eui: EUI64, f_cnt: u32) -> Validator {
|
||||
|
||||
pub fn n_f_cnt_down(dev_eui: EUI64, f_cnt: u32) -> Validator {
|
||||
Box::new(move || {
|
||||
let dev_eui = dev_eui.clone();
|
||||
let dev_eui = dev_eui;
|
||||
Box::pin(async move {
|
||||
let d = device::get(&dev_eui).await.unwrap();
|
||||
let ds = d.get_device_session().unwrap();
|
||||
@ -47,7 +47,7 @@ pub fn n_f_cnt_down(dev_eui: EUI64, f_cnt: u32) -> Validator {
|
||||
|
||||
pub fn a_f_cnt_down(dev_eui: EUI64, f_cnt: u32) -> Validator {
|
||||
Box::new(move || {
|
||||
let dev_eui = dev_eui.clone();
|
||||
let dev_eui = dev_eui;
|
||||
Box::pin(async move {
|
||||
let d = device::get(&dev_eui).await.unwrap();
|
||||
let ds = d.get_device_session().unwrap();
|
||||
@ -58,7 +58,7 @@ pub fn a_f_cnt_down(dev_eui: EUI64, f_cnt: u32) -> Validator {
|
||||
|
||||
pub fn tx_power_index(dev_eui: EUI64, tx_power: u32) -> Validator {
|
||||
Box::new(move || {
|
||||
let dev_eui = dev_eui.clone();
|
||||
let dev_eui = dev_eui;
|
||||
Box::pin(async move {
|
||||
let d = device::get(&dev_eui).await.unwrap();
|
||||
let ds = d.get_device_session().unwrap();
|
||||
@ -69,7 +69,7 @@ pub fn tx_power_index(dev_eui: EUI64, tx_power: u32) -> Validator {
|
||||
|
||||
pub fn nb_trans(dev_eui: EUI64, nb_trans: u32) -> Validator {
|
||||
Box::new(move || {
|
||||
let dev_eui = dev_eui.clone();
|
||||
let dev_eui = dev_eui;
|
||||
Box::pin(async move {
|
||||
let d = device::get(&dev_eui).await.unwrap();
|
||||
let ds = d.get_device_session().unwrap();
|
||||
@ -80,7 +80,7 @@ pub fn nb_trans(dev_eui: EUI64, nb_trans: u32) -> Validator {
|
||||
|
||||
pub fn enabled_uplink_channel_indices(dev_eui: EUI64, channels: Vec<u32>) -> Validator {
|
||||
Box::new(move || {
|
||||
let dev_eui = dev_eui.clone();
|
||||
let dev_eui = dev_eui;
|
||||
let channels = channels.clone();
|
||||
Box::pin(async move {
|
||||
let d = device::get(&dev_eui).await.unwrap();
|
||||
@ -92,7 +92,7 @@ pub fn enabled_uplink_channel_indices(dev_eui: EUI64, channels: Vec<u32>) -> Val
|
||||
|
||||
pub fn dr(dev_eui: EUI64, dr: u32) -> Validator {
|
||||
Box::new(move || {
|
||||
let dev_eui = dev_eui.clone();
|
||||
let dev_eui = dev_eui;
|
||||
Box::pin(async move {
|
||||
let d = device::get(&dev_eui).await.unwrap();
|
||||
let ds = d.get_device_session().unwrap();
|
||||
@ -103,7 +103,7 @@ pub fn dr(dev_eui: EUI64, dr: u32) -> Validator {
|
||||
|
||||
pub fn mac_command_error_count(dev_eui: EUI64, cid: lrwn::CID, count: u32) -> Validator {
|
||||
Box::new(move || {
|
||||
let dev_eui = dev_eui.clone();
|
||||
let dev_eui = dev_eui;
|
||||
Box::pin(async move {
|
||||
let d = device::get(&dev_eui).await.unwrap();
|
||||
let ds = d.get_device_session().unwrap();
|
||||
@ -120,7 +120,7 @@ pub fn mac_command_error_count(dev_eui: EUI64, cid: lrwn::CID, count: u32) -> Va
|
||||
|
||||
pub fn uplink_adr_history(dev_eui: EUI64, uh: Vec<internal::UplinkAdrHistory>) -> Validator {
|
||||
Box::new(move || {
|
||||
let dev_eui = dev_eui.clone();
|
||||
let dev_eui = dev_eui;
|
||||
let uh = uh.clone();
|
||||
Box::pin(async move {
|
||||
let d = device::get(&dev_eui).await.unwrap();
|
||||
@ -361,7 +361,7 @@ pub fn downlink_frame_saved(df: internal::DownlinkFrame) -> Validator {
|
||||
pub fn device_queue_items(dev_eui: EUI64, items: Vec<device_queue::DeviceQueueItem>) -> Validator {
|
||||
Box::new(move || {
|
||||
let items = items.clone();
|
||||
let dev_eui = dev_eui.clone();
|
||||
let dev_eui = dev_eui;
|
||||
Box::pin(async move {
|
||||
let items_get = device_queue::get_for_dev_eui(&dev_eui).await.unwrap();
|
||||
|
||||
@ -394,8 +394,8 @@ pub fn device_queue_items(dev_eui: EUI64, items: Vec<device_queue::DeviceQueueIt
|
||||
|
||||
pub fn enabled_class(dev_eui: EUI64, c: DeviceClass) -> Validator {
|
||||
Box::new(move || {
|
||||
let c = c.clone();
|
||||
let dev_eui = dev_eui.clone();
|
||||
let c = c;
|
||||
let dev_eui = dev_eui;
|
||||
Box::pin(async move {
|
||||
let dev = device::get(&dev_eui).await.unwrap();
|
||||
assert_eq!(c, dev.enabled_class);
|
||||
@ -410,7 +410,7 @@ pub fn uplink_meta_log(um: stream::UplinkMeta) -> Validator {
|
||||
let key = redis_key("stream:meta".to_string());
|
||||
let srr: StreamReadReply = redis::cmd("XREAD")
|
||||
.arg("COUNT")
|
||||
.arg(1 as usize)
|
||||
.arg(1_usize)
|
||||
.arg("STREAMS")
|
||||
.arg(&key)
|
||||
.arg("0")
|
||||
@ -422,7 +422,7 @@ pub fn uplink_meta_log(um: stream::UplinkMeta) -> Validator {
|
||||
for stream_id in &stream_key.ids {
|
||||
for (k, v) in &stream_id.map {
|
||||
assert_eq!("up", k);
|
||||
if let redis::Value::Data(b) = v {
|
||||
if let redis::Value::BulkString(b) = v {
|
||||
let pl = stream::UplinkMeta::decode(&mut Cursor::new(b)).unwrap();
|
||||
assert_eq!(um, pl);
|
||||
} else {
|
||||
@ -446,7 +446,7 @@ pub fn device_uplink_frame_log(uf: stream::UplinkFrameLog) -> Validator {
|
||||
let key = redis_key(format!("device:{{{}}}:stream:frame", uf.dev_eui));
|
||||
let srr: StreamReadReply = redis::cmd("XREAD")
|
||||
.arg("COUNT")
|
||||
.arg(1 as usize)
|
||||
.arg(1_usize)
|
||||
.arg("STREAMS")
|
||||
.arg(&key)
|
||||
.arg("0")
|
||||
@ -458,7 +458,7 @@ pub fn device_uplink_frame_log(uf: stream::UplinkFrameLog) -> Validator {
|
||||
for stream_id in &stream_key.ids {
|
||||
for (k, v) in &stream_id.map {
|
||||
assert_eq!("up", k);
|
||||
if let redis::Value::Data(b) = v {
|
||||
if let redis::Value::BulkString(b) = v {
|
||||
let mut pl =
|
||||
stream::UplinkFrameLog::decode(&mut Cursor::new(b)).unwrap();
|
||||
pl.time = None; // we don't have control over this value
|
||||
@ -477,7 +477,7 @@ pub fn device_uplink_frame_log(uf: stream::UplinkFrameLog) -> Validator {
|
||||
|
||||
pub fn scheduler_run_after_set(dev_eui: EUI64) -> Validator {
|
||||
Box::new(move || {
|
||||
let dev_eui = dev_eui.clone();
|
||||
let dev_eui = dev_eui;
|
||||
Box::pin(async move {
|
||||
let d = device::get(&dev_eui).await.unwrap();
|
||||
assert!(d.scheduler_run_after.is_some());
|
||||
|
@ -123,7 +123,7 @@ async fn test_fns_uplink() {
|
||||
ul_meta_data: backend::ULMetaData {
|
||||
ul_freq: Some(868.1),
|
||||
data_rate: Some(0),
|
||||
recv_time: recv_time,
|
||||
recv_time,
|
||||
rf_region: "EU868".to_string(),
|
||||
gw_cnt: Some(1),
|
||||
gw_info: roaming::rx_info_to_gw_info(&[rx_info.clone()]).unwrap(),
|
||||
@ -150,7 +150,7 @@ async fn test_fns_uplink() {
|
||||
.status(200);
|
||||
});
|
||||
|
||||
gateway_backend::set_backend(&"eu868", Box::new(gateway_backend::mock::Backend {})).await;
|
||||
gateway_backend::set_backend("eu868", Box::new(gateway_backend::mock::Backend {})).await;
|
||||
|
||||
// Simulate uplink
|
||||
uplink::handle_uplink(
|
||||
@ -201,7 +201,7 @@ async fn test_sns_uplink() {
|
||||
|
||||
let app = application::create(application::Application {
|
||||
name: "app".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -209,7 +209,7 @@ async fn test_sns_uplink() {
|
||||
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "dp".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
region: lrwn::region::CommonName::EU868,
|
||||
mac_version: lrwn::region::MacVersion::LORAWAN_1_0_2,
|
||||
reg_params_revision: lrwn::region::Revision::A,
|
||||
@ -225,8 +225,8 @@ async fn test_sns_uplink() {
|
||||
|
||||
let dev = device::create(device::Device {
|
||||
name: "device".into(),
|
||||
application_id: app.id.clone(),
|
||||
device_profile_id: dp.id.clone(),
|
||||
application_id: app.id,
|
||||
device_profile_id: dp.id,
|
||||
dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]),
|
||||
enabled_class: DeviceClass::B,
|
||||
dev_addr: Some(dev_addr),
|
||||
@ -324,7 +324,7 @@ async fn test_sns_uplink() {
|
||||
ul_meta_data: backend::ULMetaData {
|
||||
ul_freq: Some(868.1),
|
||||
data_rate: Some(0),
|
||||
recv_time: recv_time,
|
||||
recv_time,
|
||||
rf_region: "EU868".to_string(),
|
||||
gw_cnt: Some(1),
|
||||
gw_info: roaming::rx_info_to_gw_info(&[rx_info.clone()]).unwrap(),
|
||||
@ -383,7 +383,9 @@ async fn test_sns_uplink() {
|
||||
let resp =
|
||||
backend_api::handle_request(Bytes::from(serde_json::to_string(&pr_start_req).unwrap()))
|
||||
.await;
|
||||
let resp_b = hyper::body::to_bytes(resp.into_body()).await.unwrap();
|
||||
let resp_b = axum::body::to_bytes(resp.into_body(), usize::MAX)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let pr_start_ans: backend::PRStartAnsPayload = serde_json::from_slice(&resp_b).unwrap();
|
||||
|
||||
@ -448,7 +450,7 @@ async fn test_sns_roaming_not_allowed() {
|
||||
|
||||
let app = application::create(application::Application {
|
||||
name: "app".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -456,7 +458,7 @@ async fn test_sns_roaming_not_allowed() {
|
||||
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "dp".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
region: lrwn::region::CommonName::EU868,
|
||||
mac_version: lrwn::region::MacVersion::LORAWAN_1_0_2,
|
||||
reg_params_revision: lrwn::region::Revision::A,
|
||||
@ -471,8 +473,8 @@ async fn test_sns_roaming_not_allowed() {
|
||||
|
||||
let dev = device::create(device::Device {
|
||||
name: "device".into(),
|
||||
application_id: app.id.clone(),
|
||||
device_profile_id: dp.id.clone(),
|
||||
application_id: app.id,
|
||||
device_profile_id: dp.id,
|
||||
dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]),
|
||||
enabled_class: DeviceClass::B,
|
||||
dev_addr: Some(dev_addr),
|
||||
@ -561,7 +563,7 @@ async fn test_sns_roaming_not_allowed() {
|
||||
ul_meta_data: backend::ULMetaData {
|
||||
ul_freq: Some(868.1),
|
||||
data_rate: Some(0),
|
||||
recv_time: recv_time,
|
||||
recv_time,
|
||||
rf_region: "EU868".to_string(),
|
||||
gw_cnt: Some(1),
|
||||
gw_info: roaming::rx_info_to_gw_info(&[rx_info.clone()]).unwrap(),
|
||||
@ -572,7 +574,9 @@ async fn test_sns_roaming_not_allowed() {
|
||||
let resp =
|
||||
backend_api::handle_request(Bytes::from(serde_json::to_string(&pr_start_req).unwrap()))
|
||||
.await;
|
||||
let resp_b = hyper::body::to_bytes(resp.into_body()).await.unwrap();
|
||||
let resp_b = axum::body::to_bytes(resp.into_body(), usize::MAX)
|
||||
.await
|
||||
.unwrap();
|
||||
let pr_start_ans: backend::PRStartAnsPayload = serde_json::from_slice(&resp_b).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
@ -672,7 +676,7 @@ async fn test_sns_dev_not_found() {
|
||||
ul_meta_data: backend::ULMetaData {
|
||||
ul_freq: Some(868.1),
|
||||
data_rate: Some(0),
|
||||
recv_time: recv_time,
|
||||
recv_time,
|
||||
rf_region: "EU868".to_string(),
|
||||
gw_cnt: Some(1),
|
||||
gw_info: roaming::rx_info_to_gw_info(&[rx_info.clone()]).unwrap(),
|
||||
@ -683,7 +687,9 @@ async fn test_sns_dev_not_found() {
|
||||
let resp =
|
||||
backend_api::handle_request(Bytes::from(serde_json::to_string(&pr_start_req).unwrap()))
|
||||
.await;
|
||||
let resp_b = hyper::body::to_bytes(resp.into_body()).await.unwrap();
|
||||
let resp_b = axum::body::to_bytes(resp.into_body(), usize::MAX)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let pr_start_ans: backend::PRStartAnsPayload = serde_json::from_slice(&resp_b).unwrap();
|
||||
|
||||
|
@ -52,7 +52,7 @@ async fn test_gateway_filtering() {
|
||||
|
||||
let gw_a = gateway::create(gateway::Gateway {
|
||||
name: "gateway-a".into(),
|
||||
tenant_id: t_a.id.clone(),
|
||||
tenant_id: t_a.id,
|
||||
gateway_id: EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
..Default::default()
|
||||
})
|
||||
@ -61,7 +61,7 @@ async fn test_gateway_filtering() {
|
||||
|
||||
let gw_b = gateway::create(gateway::Gateway {
|
||||
name: "gateway-b".into(),
|
||||
tenant_id: t_b.id.clone(),
|
||||
tenant_id: t_b.id,
|
||||
gateway_id: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]),
|
||||
..Default::default()
|
||||
})
|
||||
@ -70,7 +70,7 @@ async fn test_gateway_filtering() {
|
||||
|
||||
let app = application::create(application::Application {
|
||||
name: "app".into(),
|
||||
tenant_id: t_a.id.clone(),
|
||||
tenant_id: t_a.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -78,7 +78,7 @@ async fn test_gateway_filtering() {
|
||||
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "dp".into(),
|
||||
tenant_id: t_a.id.clone(),
|
||||
tenant_id: t_a.id,
|
||||
region: lrwn::region::CommonName::EU868,
|
||||
mac_version: lrwn::region::MacVersion::LORAWAN_1_0_2,
|
||||
reg_params_revision: lrwn::region::Revision::A,
|
||||
@ -90,8 +90,8 @@ async fn test_gateway_filtering() {
|
||||
|
||||
let dev = device::create(device::Device {
|
||||
name: "device".into(),
|
||||
application_id: app.id.clone(),
|
||||
device_profile_id: dp.id.clone(),
|
||||
application_id: app.id,
|
||||
device_profile_id: dp.id,
|
||||
dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]),
|
||||
enabled_class: DeviceClass::B,
|
||||
dev_addr: Some(DevAddr::from_be_bytes([1, 2, 3, 4])),
|
||||
@ -144,7 +144,7 @@ async fn test_gateway_filtering() {
|
||||
frequency: 868100000,
|
||||
..Default::default()
|
||||
};
|
||||
uplink::helpers::set_uplink_modulation(&"eu868", &mut tx_info, 0).unwrap();
|
||||
uplink::helpers::set_uplink_modulation("eu868", &mut tx_info, 0).unwrap();
|
||||
|
||||
let tests = vec![
|
||||
Test {
|
||||
@ -256,8 +256,8 @@ async fn test_region_config_id_filtering() {
|
||||
|
||||
let dev = device::create(device::Device {
|
||||
name: "device".into(),
|
||||
application_id: app.id.clone(),
|
||||
device_profile_id: dp.id.clone(),
|
||||
application_id: app.id,
|
||||
device_profile_id: dp.id,
|
||||
dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]),
|
||||
enabled_class: DeviceClass::A,
|
||||
dev_addr: Some(DevAddr::from_be_bytes([1, 2, 3, 4])),
|
||||
@ -294,7 +294,7 @@ async fn test_region_config_id_filtering() {
|
||||
frequency: 868100000,
|
||||
..Default::default()
|
||||
};
|
||||
uplink::helpers::set_uplink_modulation(&"eu868", &mut tx_info, 0).unwrap();
|
||||
uplink::helpers::set_uplink_modulation("eu868", &mut tx_info, 0).unwrap();
|
||||
|
||||
let ds = internal::DeviceSession {
|
||||
mac_version: common::MacVersion::Lorawan102.into(),
|
||||
@ -387,7 +387,7 @@ async fn test_lorawan_10_errors() {
|
||||
|
||||
let gw = gateway::create(gateway::Gateway {
|
||||
name: "gateway".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
gateway_id: EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
..Default::default()
|
||||
})
|
||||
@ -396,7 +396,7 @@ async fn test_lorawan_10_errors() {
|
||||
|
||||
let app = application::create(application::Application {
|
||||
name: "app".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -404,7 +404,7 @@ async fn test_lorawan_10_errors() {
|
||||
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "dp".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
region: lrwn::region::CommonName::EU868,
|
||||
mac_version: lrwn::region::MacVersion::LORAWAN_1_0_2,
|
||||
reg_params_revision: lrwn::region::Revision::A,
|
||||
@ -416,8 +416,8 @@ async fn test_lorawan_10_errors() {
|
||||
|
||||
let dev = device::create(device::Device {
|
||||
name: "device".into(),
|
||||
application_id: app.id.clone(),
|
||||
device_profile_id: dp.id.clone(),
|
||||
application_id: app.id,
|
||||
device_profile_id: dp.id,
|
||||
dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]),
|
||||
enabled_class: DeviceClass::A,
|
||||
dev_addr: Some(DevAddr::from_be_bytes([1, 2, 3, 4])),
|
||||
@ -442,7 +442,7 @@ async fn test_lorawan_10_errors() {
|
||||
frequency: 868100000,
|
||||
..Default::default()
|
||||
};
|
||||
uplink::helpers::set_uplink_modulation(&"eu868", &mut tx_info, 0).unwrap();
|
||||
uplink::helpers::set_uplink_modulation("eu868", &mut tx_info, 0).unwrap();
|
||||
|
||||
let ds = internal::DeviceSession {
|
||||
mac_version: common::MacVersion::Lorawan102.into(),
|
||||
@ -584,7 +584,7 @@ async fn test_lorawan_11_errors() {
|
||||
|
||||
let gw = gateway::create(gateway::Gateway {
|
||||
name: "gateway".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
gateway_id: EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
..Default::default()
|
||||
})
|
||||
@ -593,7 +593,7 @@ async fn test_lorawan_11_errors() {
|
||||
|
||||
let app = application::create(application::Application {
|
||||
name: "app".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -601,7 +601,7 @@ async fn test_lorawan_11_errors() {
|
||||
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "dp".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
region: lrwn::region::CommonName::EU868,
|
||||
mac_version: lrwn::region::MacVersion::LORAWAN_1_1_0,
|
||||
reg_params_revision: lrwn::region::Revision::RP002_1_0_3,
|
||||
@ -613,8 +613,8 @@ async fn test_lorawan_11_errors() {
|
||||
|
||||
let dev = device::create(device::Device {
|
||||
name: "device".into(),
|
||||
application_id: app.id.clone(),
|
||||
device_profile_id: dp.id.clone(),
|
||||
application_id: app.id,
|
||||
device_profile_id: dp.id,
|
||||
dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]),
|
||||
enabled_class: DeviceClass::A,
|
||||
dev_addr: Some(DevAddr::from_be_bytes([1, 2, 3, 4])),
|
||||
@ -639,13 +639,13 @@ async fn test_lorawan_11_errors() {
|
||||
frequency: 868300000,
|
||||
..Default::default()
|
||||
};
|
||||
uplink::helpers::set_uplink_modulation(&"eu868", &mut tx_info_freq, 0).unwrap();
|
||||
uplink::helpers::set_uplink_modulation("eu868", &mut tx_info_freq, 0).unwrap();
|
||||
|
||||
let mut tx_info_dr = gw::UplinkTxInfo {
|
||||
frequency: 868100000,
|
||||
..Default::default()
|
||||
};
|
||||
uplink::helpers::set_uplink_modulation(&"eu868", &mut tx_info_dr, 3).unwrap();
|
||||
uplink::helpers::set_uplink_modulation("eu868", &mut tx_info_dr, 3).unwrap();
|
||||
|
||||
let ds = internal::DeviceSession {
|
||||
mac_version: common::MacVersion::Lorawan102.into(),
|
||||
@ -738,7 +738,7 @@ async fn test_lorawan_10_skip_f_cnt() {
|
||||
|
||||
let gw = gateway::create(gateway::Gateway {
|
||||
name: "gateway".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
gateway_id: EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
..Default::default()
|
||||
})
|
||||
@ -747,7 +747,7 @@ async fn test_lorawan_10_skip_f_cnt() {
|
||||
|
||||
let app = application::create(application::Application {
|
||||
name: "app".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -755,7 +755,7 @@ async fn test_lorawan_10_skip_f_cnt() {
|
||||
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "dp".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
region: lrwn::region::CommonName::EU868,
|
||||
mac_version: lrwn::region::MacVersion::LORAWAN_1_0_2,
|
||||
reg_params_revision: lrwn::region::Revision::A,
|
||||
@ -767,8 +767,8 @@ async fn test_lorawan_10_skip_f_cnt() {
|
||||
|
||||
let dev = device::create(device::Device {
|
||||
name: "device".into(),
|
||||
application_id: app.id.clone(),
|
||||
device_profile_id: dp.id.clone(),
|
||||
application_id: app.id,
|
||||
device_profile_id: dp.id,
|
||||
dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]),
|
||||
enabled_class: DeviceClass::A,
|
||||
skip_fcnt_check: true,
|
||||
@ -794,7 +794,7 @@ async fn test_lorawan_10_skip_f_cnt() {
|
||||
frequency: 868100000,
|
||||
..Default::default()
|
||||
};
|
||||
uplink::helpers::set_uplink_modulation(&"eu868", &mut tx_info, 0).unwrap();
|
||||
uplink::helpers::set_uplink_modulation("eu868", &mut tx_info, 0).unwrap();
|
||||
|
||||
let ds = internal::DeviceSession {
|
||||
mac_version: common::MacVersion::Lorawan102.into(),
|
||||
@ -932,7 +932,7 @@ async fn test_lorawan_10_device_disabled() {
|
||||
|
||||
let gw = gateway::create(gateway::Gateway {
|
||||
name: "gateway".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
gateway_id: EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
..Default::default()
|
||||
})
|
||||
@ -941,7 +941,7 @@ async fn test_lorawan_10_device_disabled() {
|
||||
|
||||
let app = application::create(application::Application {
|
||||
name: "app".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -949,7 +949,7 @@ async fn test_lorawan_10_device_disabled() {
|
||||
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "dp".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
region: lrwn::region::CommonName::EU868,
|
||||
mac_version: lrwn::region::MacVersion::LORAWAN_1_0_2,
|
||||
reg_params_revision: lrwn::region::Revision::A,
|
||||
@ -961,8 +961,8 @@ async fn test_lorawan_10_device_disabled() {
|
||||
|
||||
let dev = device::create(device::Device {
|
||||
name: "device".into(),
|
||||
application_id: app.id.clone(),
|
||||
device_profile_id: dp.id.clone(),
|
||||
application_id: app.id,
|
||||
device_profile_id: dp.id,
|
||||
dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]),
|
||||
enabled_class: DeviceClass::A,
|
||||
is_disabled: true,
|
||||
@ -988,7 +988,7 @@ async fn test_lorawan_10_device_disabled() {
|
||||
frequency: 868100000,
|
||||
..Default::default()
|
||||
};
|
||||
uplink::helpers::set_uplink_modulation(&"eu868", &mut tx_info, 0).unwrap();
|
||||
uplink::helpers::set_uplink_modulation("eu868", &mut tx_info, 0).unwrap();
|
||||
|
||||
let ds = internal::DeviceSession {
|
||||
mac_version: common::MacVersion::Lorawan102.into(),
|
||||
@ -1056,7 +1056,7 @@ async fn test_lorawan_10_uplink() {
|
||||
|
||||
let gw = gateway::create(gateway::Gateway {
|
||||
name: "gateway".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
gateway_id: EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
..Default::default()
|
||||
})
|
||||
@ -1065,7 +1065,7 @@ async fn test_lorawan_10_uplink() {
|
||||
|
||||
let app = application::create(application::Application {
|
||||
name: "app".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -1073,7 +1073,7 @@ async fn test_lorawan_10_uplink() {
|
||||
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "dp".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
region: lrwn::region::CommonName::EU868,
|
||||
mac_version: lrwn::region::MacVersion::LORAWAN_1_0_4,
|
||||
reg_params_revision: lrwn::region::Revision::RP002_1_0_3,
|
||||
@ -1085,8 +1085,8 @@ async fn test_lorawan_10_uplink() {
|
||||
|
||||
let dev = device::create(device::Device {
|
||||
name: "device".into(),
|
||||
application_id: app.id.clone(),
|
||||
device_profile_id: dp.id.clone(),
|
||||
application_id: app.id,
|
||||
device_profile_id: dp.id,
|
||||
dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]),
|
||||
enabled_class: DeviceClass::A,
|
||||
dev_addr: Some(DevAddr::from_be_bytes([1, 2, 3, 4])),
|
||||
@ -1111,13 +1111,13 @@ async fn test_lorawan_10_uplink() {
|
||||
frequency: 868100000,
|
||||
..Default::default()
|
||||
};
|
||||
uplink::helpers::set_uplink_modulation(&"eu868", &mut tx_info, 0).unwrap();
|
||||
uplink::helpers::set_uplink_modulation("eu868", &mut tx_info, 0).unwrap();
|
||||
|
||||
let mut tx_info_lr_fhss = gw::UplinkTxInfo {
|
||||
frequency: 867300000,
|
||||
..Default::default()
|
||||
};
|
||||
uplink::helpers::set_uplink_modulation(&"eu868", &mut tx_info_lr_fhss, 10).unwrap();
|
||||
uplink::helpers::set_uplink_modulation("eu868", &mut tx_info_lr_fhss, 10).unwrap();
|
||||
|
||||
let ds = internal::DeviceSession {
|
||||
mac_version: common::MacVersion::Lorawan104.into(),
|
||||
@ -1693,7 +1693,7 @@ async fn test_lorawan_10_end_to_end_enc() {
|
||||
|
||||
let gw = gateway::create(gateway::Gateway {
|
||||
name: "gateway".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
gateway_id: EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
..Default::default()
|
||||
})
|
||||
@ -1702,7 +1702,7 @@ async fn test_lorawan_10_end_to_end_enc() {
|
||||
|
||||
let app = application::create(application::Application {
|
||||
name: "app".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -1710,7 +1710,7 @@ async fn test_lorawan_10_end_to_end_enc() {
|
||||
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "dp".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
region: lrwn::region::CommonName::EU868,
|
||||
mac_version: lrwn::region::MacVersion::LORAWAN_1_0_4,
|
||||
reg_params_revision: lrwn::region::Revision::RP002_1_0_3,
|
||||
@ -1722,8 +1722,8 @@ async fn test_lorawan_10_end_to_end_enc() {
|
||||
|
||||
let dev = device::create(device::Device {
|
||||
name: "device".into(),
|
||||
application_id: app.id.clone(),
|
||||
device_profile_id: dp.id.clone(),
|
||||
application_id: app.id,
|
||||
device_profile_id: dp.id,
|
||||
dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]),
|
||||
enabled_class: DeviceClass::A,
|
||||
dev_addr: Some(DevAddr::from_be_bytes([1, 2, 3, 4])),
|
||||
@ -1748,7 +1748,7 @@ async fn test_lorawan_10_end_to_end_enc() {
|
||||
frequency: 868100000,
|
||||
..Default::default()
|
||||
};
|
||||
uplink::helpers::set_uplink_modulation(&"eu868", &mut tx_info, 0).unwrap();
|
||||
uplink::helpers::set_uplink_modulation("eu868", &mut tx_info, 0).unwrap();
|
||||
|
||||
let ds_sess_key_id = internal::DeviceSession {
|
||||
mac_version: common::MacVersion::Lorawan104.into(),
|
||||
@ -2021,7 +2021,7 @@ async fn test_lorawan_11_uplink() {
|
||||
|
||||
let gw = gateway::create(gateway::Gateway {
|
||||
name: "gateway".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
gateway_id: EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
..Default::default()
|
||||
})
|
||||
@ -2030,7 +2030,7 @@ async fn test_lorawan_11_uplink() {
|
||||
|
||||
let app = application::create(application::Application {
|
||||
name: "app".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -2038,7 +2038,7 @@ async fn test_lorawan_11_uplink() {
|
||||
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "dp".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
region: lrwn::region::CommonName::EU868,
|
||||
mac_version: lrwn::region::MacVersion::LORAWAN_1_1_0,
|
||||
reg_params_revision: lrwn::region::Revision::RP002_1_0_3,
|
||||
@ -2050,8 +2050,8 @@ async fn test_lorawan_11_uplink() {
|
||||
|
||||
let dev = device::create(device::Device {
|
||||
name: "device".into(),
|
||||
application_id: app.id.clone(),
|
||||
device_profile_id: dp.id.clone(),
|
||||
application_id: app.id,
|
||||
device_profile_id: dp.id,
|
||||
dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]),
|
||||
enabled_class: DeviceClass::A,
|
||||
dev_addr: Some(DevAddr::from_be_bytes([1, 2, 3, 4])),
|
||||
@ -2076,13 +2076,13 @@ async fn test_lorawan_11_uplink() {
|
||||
frequency: 868100000,
|
||||
..Default::default()
|
||||
};
|
||||
uplink::helpers::set_uplink_modulation(&"eu868", &mut tx_info, 0).unwrap();
|
||||
uplink::helpers::set_uplink_modulation("eu868", &mut tx_info, 0).unwrap();
|
||||
|
||||
let mut tx_info_lr_fhss = gw::UplinkTxInfo {
|
||||
frequency: 868100000,
|
||||
..Default::default()
|
||||
};
|
||||
uplink::helpers::set_uplink_modulation(&"eu868", &mut tx_info_lr_fhss, 8).unwrap();
|
||||
uplink::helpers::set_uplink_modulation("eu868", &mut tx_info_lr_fhss, 8).unwrap();
|
||||
|
||||
let ds = internal::DeviceSession {
|
||||
mac_version: common::MacVersion::Lorawan110.into(),
|
||||
@ -2260,7 +2260,7 @@ async fn test_lorawan_10_rx_delay() {
|
||||
|
||||
let gw = gateway::create(gateway::Gateway {
|
||||
name: "gateway".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
gateway_id: EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
..Default::default()
|
||||
})
|
||||
@ -2269,7 +2269,7 @@ async fn test_lorawan_10_rx_delay() {
|
||||
|
||||
let app = application::create(application::Application {
|
||||
name: "app".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -2277,7 +2277,7 @@ async fn test_lorawan_10_rx_delay() {
|
||||
|
||||
let mut dp = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "dp".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
region: lrwn::region::CommonName::EU868,
|
||||
mac_version: lrwn::region::MacVersion::LORAWAN_1_0_4,
|
||||
reg_params_revision: lrwn::region::Revision::RP002_1_0_3,
|
||||
@ -2289,8 +2289,8 @@ async fn test_lorawan_10_rx_delay() {
|
||||
|
||||
let dev = device::create(device::Device {
|
||||
name: "device".into(),
|
||||
application_id: app.id.clone(),
|
||||
device_profile_id: dp.id.clone(),
|
||||
application_id: app.id,
|
||||
device_profile_id: dp.id,
|
||||
dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]),
|
||||
enabled_class: DeviceClass::A,
|
||||
dev_addr: Some(DevAddr::from_be_bytes([1, 2, 3, 4])),
|
||||
@ -2315,13 +2315,13 @@ async fn test_lorawan_10_rx_delay() {
|
||||
frequency: 868100000,
|
||||
..Default::default()
|
||||
};
|
||||
uplink::helpers::set_uplink_modulation(&"eu868", &mut tx_info, 0).unwrap();
|
||||
uplink::helpers::set_uplink_modulation("eu868", &mut tx_info, 0).unwrap();
|
||||
|
||||
let mut tx_info_lr_fhss = gw::UplinkTxInfo {
|
||||
frequency: 868100000,
|
||||
..Default::default()
|
||||
};
|
||||
uplink::helpers::set_uplink_modulation(&"eu868", &mut tx_info_lr_fhss, 8).unwrap();
|
||||
uplink::helpers::set_uplink_modulation("eu868", &mut tx_info_lr_fhss, 8).unwrap();
|
||||
|
||||
let ds = internal::DeviceSession {
|
||||
mac_version: common::MacVersion::Lorawan104.into(),
|
||||
@ -2705,7 +2705,7 @@ async fn test_lorawan_10_mac_commands() {
|
||||
|
||||
let gw = gateway::create(gateway::Gateway {
|
||||
name: "gateway".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
gateway_id: EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
..Default::default()
|
||||
})
|
||||
@ -2714,7 +2714,7 @@ async fn test_lorawan_10_mac_commands() {
|
||||
|
||||
let app = application::create(application::Application {
|
||||
name: "app".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -2722,7 +2722,7 @@ async fn test_lorawan_10_mac_commands() {
|
||||
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "dp".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
region: lrwn::region::CommonName::EU868,
|
||||
mac_version: lrwn::region::MacVersion::LORAWAN_1_0_4,
|
||||
reg_params_revision: lrwn::region::Revision::RP002_1_0_3,
|
||||
@ -2734,8 +2734,8 @@ async fn test_lorawan_10_mac_commands() {
|
||||
|
||||
let dev = device::create(device::Device {
|
||||
name: "device".into(),
|
||||
application_id: app.id.clone(),
|
||||
device_profile_id: dp.id.clone(),
|
||||
application_id: app.id,
|
||||
device_profile_id: dp.id,
|
||||
dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]),
|
||||
enabled_class: DeviceClass::A,
|
||||
dev_addr: Some(DevAddr::from_be_bytes([1, 2, 3, 4])),
|
||||
@ -2760,13 +2760,13 @@ async fn test_lorawan_10_mac_commands() {
|
||||
frequency: 868100000,
|
||||
..Default::default()
|
||||
};
|
||||
uplink::helpers::set_uplink_modulation(&"eu868", &mut tx_info, 0).unwrap();
|
||||
uplink::helpers::set_uplink_modulation("eu868", &mut tx_info, 0).unwrap();
|
||||
|
||||
let mut tx_info_lr_fhss = gw::UplinkTxInfo {
|
||||
frequency: 868100000,
|
||||
..Default::default()
|
||||
};
|
||||
uplink::helpers::set_uplink_modulation(&"eu868", &mut tx_info_lr_fhss, 8).unwrap();
|
||||
uplink::helpers::set_uplink_modulation("eu868", &mut tx_info_lr_fhss, 8).unwrap();
|
||||
|
||||
let ds = internal::DeviceSession {
|
||||
mac_version: common::MacVersion::Lorawan104.into(),
|
||||
@ -2793,7 +2793,7 @@ async fn test_lorawan_10_mac_commands() {
|
||||
dev_eui: dev.dev_eui,
|
||||
device_queue_items: vec![],
|
||||
before_func: Some(Box::new(move || {
|
||||
let dp_id = dp.id.clone();
|
||||
let dp_id = dp.id;
|
||||
Box::pin(async move {
|
||||
let mut dp = device_profile::get(&dp_id).await.unwrap();
|
||||
dp.device_status_req_interval = 1;
|
||||
@ -2801,7 +2801,7 @@ async fn test_lorawan_10_mac_commands() {
|
||||
})
|
||||
})),
|
||||
after_func: Some(Box::new(move || {
|
||||
let dp_id = dp.id.clone();
|
||||
let dp_id = dp.id;
|
||||
Box::pin(async move {
|
||||
let mut dp = device_profile::get(&dp_id).await.unwrap();
|
||||
dp.device_status_req_interval = 0;
|
||||
@ -2892,7 +2892,7 @@ async fn test_lorawan_10_mac_commands() {
|
||||
..Default::default()
|
||||
}],
|
||||
before_func: Some(Box::new(move || {
|
||||
let dp_id = dp.id.clone();
|
||||
let dp_id = dp.id;
|
||||
Box::pin(async move {
|
||||
let mut dp = device_profile::get(&dp_id).await.unwrap();
|
||||
dp.device_status_req_interval = 1;
|
||||
@ -2900,7 +2900,7 @@ async fn test_lorawan_10_mac_commands() {
|
||||
})
|
||||
})),
|
||||
after_func: Some(Box::new(move || {
|
||||
let dp_id = dp.id.clone();
|
||||
let dp_id = dp.id;
|
||||
Box::pin(async move {
|
||||
let mut dp = device_profile::get(&dp_id).await.unwrap();
|
||||
dp.device_status_req_interval = 0;
|
||||
@ -3076,7 +3076,7 @@ async fn test_lorawan_11_mac_commands() {
|
||||
|
||||
let gw = gateway::create(gateway::Gateway {
|
||||
name: "gateway".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
gateway_id: EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
..Default::default()
|
||||
})
|
||||
@ -3085,7 +3085,7 @@ async fn test_lorawan_11_mac_commands() {
|
||||
|
||||
let app = application::create(application::Application {
|
||||
name: "app".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -3093,7 +3093,7 @@ async fn test_lorawan_11_mac_commands() {
|
||||
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "dp".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
region: lrwn::region::CommonName::EU868,
|
||||
mac_version: lrwn::region::MacVersion::LORAWAN_1_1_0,
|
||||
reg_params_revision: lrwn::region::Revision::RP002_1_0_3,
|
||||
@ -3105,8 +3105,8 @@ async fn test_lorawan_11_mac_commands() {
|
||||
|
||||
let dev = device::create(device::Device {
|
||||
name: "device".into(),
|
||||
application_id: app.id.clone(),
|
||||
device_profile_id: dp.id.clone(),
|
||||
application_id: app.id,
|
||||
device_profile_id: dp.id,
|
||||
dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]),
|
||||
enabled_class: DeviceClass::A,
|
||||
dev_addr: Some(DevAddr::from_be_bytes([1, 2, 3, 4])),
|
||||
@ -3131,7 +3131,7 @@ async fn test_lorawan_11_mac_commands() {
|
||||
frequency: 868100000,
|
||||
..Default::default()
|
||||
};
|
||||
uplink::helpers::set_uplink_modulation(&"eu868", &mut tx_info, 0).unwrap();
|
||||
uplink::helpers::set_uplink_modulation("eu868", &mut tx_info, 0).unwrap();
|
||||
|
||||
let ds = internal::DeviceSession {
|
||||
mac_version: common::MacVersion::Lorawan110.into(),
|
||||
@ -3270,7 +3270,7 @@ async fn test_lorawan_10_device_queue() {
|
||||
|
||||
let gw = gateway::create(gateway::Gateway {
|
||||
name: "gateway".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
gateway_id: EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
..Default::default()
|
||||
})
|
||||
@ -3279,7 +3279,7 @@ async fn test_lorawan_10_device_queue() {
|
||||
|
||||
let app = application::create(application::Application {
|
||||
name: "app".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -3287,7 +3287,7 @@ async fn test_lorawan_10_device_queue() {
|
||||
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "dp".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
region: lrwn::region::CommonName::EU868,
|
||||
mac_version: lrwn::region::MacVersion::LORAWAN_1_0_4,
|
||||
reg_params_revision: lrwn::region::Revision::RP002_1_0_3,
|
||||
@ -3299,8 +3299,8 @@ async fn test_lorawan_10_device_queue() {
|
||||
|
||||
let dev = device::create(device::Device {
|
||||
name: "device".into(),
|
||||
application_id: app.id.clone(),
|
||||
device_profile_id: dp.id.clone(),
|
||||
application_id: app.id,
|
||||
device_profile_id: dp.id,
|
||||
dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]),
|
||||
enabled_class: DeviceClass::A,
|
||||
dev_addr: Some(DevAddr::from_be_bytes([1, 2, 3, 4])),
|
||||
@ -3325,7 +3325,7 @@ async fn test_lorawan_10_device_queue() {
|
||||
frequency: 868100000,
|
||||
..Default::default()
|
||||
};
|
||||
uplink::helpers::set_uplink_modulation(&"eu868", &mut tx_info, 0).unwrap();
|
||||
uplink::helpers::set_uplink_modulation("eu868", &mut tx_info, 0).unwrap();
|
||||
|
||||
let ds = internal::DeviceSession {
|
||||
mac_version: common::MacVersion::Lorawan104.into(),
|
||||
@ -3747,7 +3747,7 @@ async fn test_lorawan_11_device_queue() {
|
||||
|
||||
let gw = gateway::create(gateway::Gateway {
|
||||
name: "gateway".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
gateway_id: EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
..Default::default()
|
||||
})
|
||||
@ -3756,7 +3756,7 @@ async fn test_lorawan_11_device_queue() {
|
||||
|
||||
let app = application::create(application::Application {
|
||||
name: "app".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -3764,7 +3764,7 @@ async fn test_lorawan_11_device_queue() {
|
||||
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "dp".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
region: lrwn::region::CommonName::EU868,
|
||||
mac_version: lrwn::region::MacVersion::LORAWAN_1_1_0,
|
||||
reg_params_revision: lrwn::region::Revision::RP002_1_0_3,
|
||||
@ -3776,8 +3776,8 @@ async fn test_lorawan_11_device_queue() {
|
||||
|
||||
let dev = device::create(device::Device {
|
||||
name: "device".into(),
|
||||
application_id: app.id.clone(),
|
||||
device_profile_id: dp.id.clone(),
|
||||
application_id: app.id,
|
||||
device_profile_id: dp.id,
|
||||
dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]),
|
||||
enabled_class: DeviceClass::A,
|
||||
dev_addr: Some(DevAddr::from_be_bytes([1, 2, 3, 4])),
|
||||
@ -3802,7 +3802,7 @@ async fn test_lorawan_11_device_queue() {
|
||||
frequency: 868100000,
|
||||
..Default::default()
|
||||
};
|
||||
uplink::helpers::set_uplink_modulation(&"eu868", &mut tx_info, 0).unwrap();
|
||||
uplink::helpers::set_uplink_modulation("eu868", &mut tx_info, 0).unwrap();
|
||||
|
||||
let ds = internal::DeviceSession {
|
||||
mac_version: common::MacVersion::Lorawan110.into(),
|
||||
@ -4227,7 +4227,7 @@ async fn test_lorawan_10_adr() {
|
||||
|
||||
let gw = gateway::create(gateway::Gateway {
|
||||
name: "gateway".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
gateway_id: EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
..Default::default()
|
||||
})
|
||||
@ -4236,7 +4236,7 @@ async fn test_lorawan_10_adr() {
|
||||
|
||||
let app = application::create(application::Application {
|
||||
name: "app".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -4244,7 +4244,7 @@ async fn test_lorawan_10_adr() {
|
||||
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "dp".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
region: lrwn::region::CommonName::EU868,
|
||||
mac_version: lrwn::region::MacVersion::LORAWAN_1_0_4,
|
||||
reg_params_revision: lrwn::region::Revision::RP002_1_0_3,
|
||||
@ -4257,8 +4257,8 @@ async fn test_lorawan_10_adr() {
|
||||
|
||||
let dev = device::create(device::Device {
|
||||
name: "device".into(),
|
||||
application_id: app.id.clone(),
|
||||
device_profile_id: dp.id.clone(),
|
||||
application_id: app.id,
|
||||
device_profile_id: dp.id,
|
||||
dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]),
|
||||
enabled_class: DeviceClass::A,
|
||||
dev_addr: Some(DevAddr::from_be_bytes([1, 2, 3, 4])),
|
||||
@ -4283,7 +4283,7 @@ async fn test_lorawan_10_adr() {
|
||||
frequency: 868100000,
|
||||
..Default::default()
|
||||
};
|
||||
uplink::helpers::set_uplink_modulation(&"eu868", &mut tx_info, 0).unwrap();
|
||||
uplink::helpers::set_uplink_modulation("eu868", &mut tx_info, 0).unwrap();
|
||||
|
||||
let ds = internal::DeviceSession {
|
||||
mac_version: common::MacVersion::Lorawan104.into(),
|
||||
@ -5070,7 +5070,7 @@ async fn test_lorawan_10_device_status_request() {
|
||||
|
||||
let gw = gateway::create(gateway::Gateway {
|
||||
name: "gateway".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
gateway_id: EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
..Default::default()
|
||||
})
|
||||
@ -5079,7 +5079,7 @@ async fn test_lorawan_10_device_status_request() {
|
||||
|
||||
let app = application::create(application::Application {
|
||||
name: "app".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -5087,7 +5087,7 @@ async fn test_lorawan_10_device_status_request() {
|
||||
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "dp".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
region: lrwn::region::CommonName::EU868,
|
||||
mac_version: lrwn::region::MacVersion::LORAWAN_1_0_4,
|
||||
reg_params_revision: lrwn::region::Revision::RP002_1_0_3,
|
||||
@ -5100,8 +5100,8 @@ async fn test_lorawan_10_device_status_request() {
|
||||
|
||||
let dev = device::create(device::Device {
|
||||
name: "device".into(),
|
||||
application_id: app.id.clone(),
|
||||
device_profile_id: dp.id.clone(),
|
||||
application_id: app.id,
|
||||
device_profile_id: dp.id,
|
||||
dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]),
|
||||
enabled_class: DeviceClass::A,
|
||||
dev_addr: Some(DevAddr::from_be_bytes([1, 2, 3, 4])),
|
||||
@ -5126,7 +5126,7 @@ async fn test_lorawan_10_device_status_request() {
|
||||
frequency: 868100000,
|
||||
..Default::default()
|
||||
};
|
||||
uplink::helpers::set_uplink_modulation(&"eu868", &mut tx_info, 0).unwrap();
|
||||
uplink::helpers::set_uplink_modulation("eu868", &mut tx_info, 0).unwrap();
|
||||
|
||||
let ds = internal::DeviceSession {
|
||||
mac_version: common::MacVersion::Lorawan104.into(),
|
||||
@ -5336,7 +5336,7 @@ async fn test_lorawan_11_receive_window_selection() {
|
||||
|
||||
let gw = gateway::create(gateway::Gateway {
|
||||
name: "gateway".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
gateway_id: EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
..Default::default()
|
||||
})
|
||||
@ -5345,7 +5345,7 @@ async fn test_lorawan_11_receive_window_selection() {
|
||||
|
||||
let app = application::create(application::Application {
|
||||
name: "app".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -5353,7 +5353,7 @@ async fn test_lorawan_11_receive_window_selection() {
|
||||
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "dp".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
region: lrwn::region::CommonName::EU868,
|
||||
mac_version: lrwn::region::MacVersion::LORAWAN_1_1_0,
|
||||
reg_params_revision: lrwn::region::Revision::RP002_1_0_3,
|
||||
@ -5365,8 +5365,8 @@ async fn test_lorawan_11_receive_window_selection() {
|
||||
|
||||
let dev = device::create(device::Device {
|
||||
name: "device".into(),
|
||||
application_id: app.id.clone(),
|
||||
device_profile_id: dp.id.clone(),
|
||||
application_id: app.id,
|
||||
device_profile_id: dp.id,
|
||||
dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]),
|
||||
enabled_class: DeviceClass::A,
|
||||
dev_addr: Some(DevAddr::from_be_bytes([1, 2, 3, 4])),
|
||||
@ -5391,13 +5391,13 @@ async fn test_lorawan_11_receive_window_selection() {
|
||||
frequency: 868100000,
|
||||
..Default::default()
|
||||
};
|
||||
uplink::helpers::set_uplink_modulation(&"eu868", &mut tx_info, 0).unwrap();
|
||||
uplink::helpers::set_uplink_modulation("eu868", &mut tx_info, 0).unwrap();
|
||||
|
||||
let mut tx_info_lr_fhss = gw::UplinkTxInfo {
|
||||
frequency: 868100000,
|
||||
..Default::default()
|
||||
};
|
||||
uplink::helpers::set_uplink_modulation(&"eu868", &mut tx_info_lr_fhss, 8).unwrap();
|
||||
uplink::helpers::set_uplink_modulation("eu868", &mut tx_info_lr_fhss, 8).unwrap();
|
||||
|
||||
let ds = internal::DeviceSession {
|
||||
mac_version: common::MacVersion::Lorawan110.into(),
|
||||
@ -5660,7 +5660,7 @@ async fn test_lorawan_11_receive_window_selection() {
|
||||
})
|
||||
.await;
|
||||
|
||||
uplink::helpers::set_uplink_modulation(&"eu868", &mut tx_info, 5).unwrap();
|
||||
uplink::helpers::set_uplink_modulation("eu868", &mut tx_info, 5).unwrap();
|
||||
|
||||
run_test(&Test {
|
||||
name: "unconfirmed uplink with payload (rx1, payload exceeds rx2 limit)".into(),
|
||||
@ -5774,7 +5774,7 @@ async fn run_test(t: &Test) {
|
||||
reset_redis().await.unwrap();
|
||||
|
||||
integration::set_mock().await;
|
||||
gateway_backend::set_backend(&"eu868", Box::new(gateway_backend::mock::Backend {})).await;
|
||||
gateway_backend::set_backend("eu868", Box::new(gateway_backend::mock::Backend {})).await;
|
||||
|
||||
integration::mock::reset().await;
|
||||
gateway_backend::mock::reset().await;
|
||||
|
@ -48,7 +48,7 @@ async fn test_uplink() {
|
||||
|
||||
let gw = gateway::create(gateway::Gateway {
|
||||
name: "gateway".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
gateway_id: EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
..Default::default()
|
||||
})
|
||||
@ -57,7 +57,7 @@ async fn test_uplink() {
|
||||
|
||||
let app = application::create(application::Application {
|
||||
name: "app".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -65,7 +65,7 @@ async fn test_uplink() {
|
||||
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "dp".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
region: lrwn::region::CommonName::EU868,
|
||||
mac_version: lrwn::region::MacVersion::LORAWAN_1_0_4,
|
||||
reg_params_revision: lrwn::region::Revision::RP002_1_0_3,
|
||||
@ -78,8 +78,8 @@ async fn test_uplink() {
|
||||
|
||||
let dev = device::create(device::Device {
|
||||
name: "device".into(),
|
||||
application_id: app.id.clone(),
|
||||
device_profile_id: dp.id.clone(),
|
||||
application_id: app.id,
|
||||
device_profile_id: dp.id,
|
||||
dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]),
|
||||
enabled_class: DeviceClass::A,
|
||||
dev_addr: Some(DevAddr::from_be_bytes([1, 2, 3, 4])),
|
||||
@ -103,7 +103,7 @@ async fn test_uplink() {
|
||||
frequency: 868100000,
|
||||
..Default::default()
|
||||
};
|
||||
uplink::helpers::set_uplink_modulation(&"eu868", &mut tx_info, 0).unwrap();
|
||||
uplink::helpers::set_uplink_modulation("eu868", &mut tx_info, 0).unwrap();
|
||||
|
||||
let ds = internal::DeviceSession {
|
||||
mac_version: common::MacVersion::Lorawan104.into(),
|
||||
@ -157,8 +157,8 @@ async fn test_uplink() {
|
||||
mic: Some([241, 100, 207, 79]),
|
||||
},
|
||||
assert: vec![
|
||||
assert::f_cnt_up(dev.dev_eui.clone(), 9),
|
||||
assert::enabled_class(dev.dev_eui.clone(), DeviceClass::B),
|
||||
assert::f_cnt_up(dev.dev_eui, 9),
|
||||
assert::enabled_class(dev.dev_eui, DeviceClass::B),
|
||||
],
|
||||
})
|
||||
.await;
|
||||
@ -192,8 +192,8 @@ async fn test_uplink() {
|
||||
mic: Some([137, 180, 12, 148]),
|
||||
},
|
||||
assert: vec![
|
||||
assert::f_cnt_up(dev.dev_eui.clone(), 9),
|
||||
assert::enabled_class(dev.dev_eui.clone(), DeviceClass::A),
|
||||
assert::f_cnt_up(dev.dev_eui, 9),
|
||||
assert::enabled_class(dev.dev_eui, DeviceClass::A),
|
||||
],
|
||||
})
|
||||
.await;
|
||||
@ -213,7 +213,7 @@ async fn test_downlink_scheduler() {
|
||||
|
||||
let gw = gateway::create(gateway::Gateway {
|
||||
name: "gateway".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
gateway_id: EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
..Default::default()
|
||||
})
|
||||
@ -222,7 +222,7 @@ async fn test_downlink_scheduler() {
|
||||
|
||||
let app = application::create(application::Application {
|
||||
name: "app".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -230,7 +230,7 @@ async fn test_downlink_scheduler() {
|
||||
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "dp".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
region: lrwn::region::CommonName::EU868,
|
||||
mac_version: lrwn::region::MacVersion::LORAWAN_1_0_4,
|
||||
reg_params_revision: lrwn::region::Revision::RP002_1_0_3,
|
||||
@ -243,8 +243,8 @@ async fn test_downlink_scheduler() {
|
||||
|
||||
let dev = device::create(device::Device {
|
||||
name: "device".into(),
|
||||
application_id: app.id.clone(),
|
||||
device_profile_id: dp.id.clone(),
|
||||
application_id: app.id,
|
||||
device_profile_id: dp.id,
|
||||
dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]),
|
||||
enabled_class: DeviceClass::B,
|
||||
dev_addr: Some(DevAddr::from_be_bytes([1, 2, 3, 4])),
|
||||
@ -296,7 +296,7 @@ async fn test_downlink_scheduler() {
|
||||
dev_eui: dev.dev_eui,
|
||||
device_queue_items: vec![device_queue::DeviceQueueItem {
|
||||
id: Uuid::nil(),
|
||||
dev_eui: dev.dev_eui.clone(),
|
||||
dev_eui: dev.dev_eui,
|
||||
f_port: 10,
|
||||
data: vec![1, 2, 3],
|
||||
..Default::default()
|
||||
@ -304,8 +304,8 @@ async fn test_downlink_scheduler() {
|
||||
device_session: Some(ds.clone()),
|
||||
device_gateway_rx_info: Some(device_gateway_rx_info.clone()),
|
||||
assert: vec![
|
||||
assert::f_cnt_up(dev.dev_eui.clone(), 8),
|
||||
assert::n_f_cnt_down(dev.dev_eui.clone(), 5),
|
||||
assert::f_cnt_up(dev.dev_eui, 8),
|
||||
assert::n_f_cnt_down(dev.dev_eui, 5),
|
||||
assert::downlink_frame(gw::DownlinkFrame {
|
||||
gateway_id: "0102030405060708".into(),
|
||||
items: vec![gw::DownlinkFrameItem {
|
||||
@ -348,7 +348,7 @@ async fn test_downlink_scheduler() {
|
||||
dev_eui: dev.dev_eui,
|
||||
device_queue_items: vec![device_queue::DeviceQueueItem {
|
||||
id: Uuid::nil(),
|
||||
dev_eui: dev.dev_eui.clone(),
|
||||
dev_eui: dev.dev_eui,
|
||||
f_port: 10,
|
||||
data: vec![1, 2, 3],
|
||||
..Default::default()
|
||||
@ -376,14 +376,14 @@ async fn test_downlink_scheduler() {
|
||||
device_queue_items: vec![
|
||||
device_queue::DeviceQueueItem {
|
||||
id: Uuid::nil(),
|
||||
dev_eui: dev.dev_eui.clone(),
|
||||
dev_eui: dev.dev_eui,
|
||||
f_port: 10,
|
||||
data: vec![1, 2, 3],
|
||||
..Default::default()
|
||||
},
|
||||
device_queue::DeviceQueueItem {
|
||||
id: Uuid::new_v4(),
|
||||
dev_eui: dev.dev_eui.clone(),
|
||||
dev_eui: dev.dev_eui,
|
||||
f_port: 10,
|
||||
data: vec![1, 2, 3, 4],
|
||||
..Default::default()
|
||||
@ -392,8 +392,8 @@ async fn test_downlink_scheduler() {
|
||||
device_session: Some(ds.clone()),
|
||||
device_gateway_rx_info: Some(device_gateway_rx_info.clone()),
|
||||
assert: vec![
|
||||
assert::f_cnt_up(dev.dev_eui.clone(), 8),
|
||||
assert::n_f_cnt_down(dev.dev_eui.clone(), 5),
|
||||
assert::f_cnt_up(dev.dev_eui, 8),
|
||||
assert::n_f_cnt_down(dev.dev_eui, 5),
|
||||
assert::downlink_frame(gw::DownlinkFrame {
|
||||
gateway_id: "0102030405060708".into(),
|
||||
items: vec![gw::DownlinkFrameItem {
|
||||
@ -440,7 +440,7 @@ async fn run_uplink_test(t: &UplinkTest) {
|
||||
reset_redis().await.unwrap();
|
||||
|
||||
integration::set_mock().await;
|
||||
gateway_backend::set_backend(&"eu868", Box::new(gateway_backend::mock::Backend {})).await;
|
||||
gateway_backend::set_backend("eu868", Box::new(gateway_backend::mock::Backend {})).await;
|
||||
|
||||
integration::mock::reset().await;
|
||||
gateway_backend::mock::reset().await;
|
||||
@ -482,7 +482,7 @@ async fn run_scheduler_test(t: &DownlinkTest) {
|
||||
reset_redis().await.unwrap();
|
||||
|
||||
integration::set_mock().await;
|
||||
gateway_backend::set_backend(&"eu868", Box::new(gateway_backend::mock::Backend {})).await;
|
||||
gateway_backend::set_backend("eu868", Box::new(gateway_backend::mock::Backend {})).await;
|
||||
|
||||
integration::mock::reset().await;
|
||||
gateway_backend::mock::reset().await;
|
||||
@ -498,7 +498,7 @@ async fn run_scheduler_test(t: &DownlinkTest) {
|
||||
.unwrap();
|
||||
|
||||
if let Some(rx_info) = &t.device_gateway_rx_info {
|
||||
let _ = device_gateway::save_rx_info(rx_info).await.unwrap();
|
||||
device_gateway::save_rx_info(rx_info).await.unwrap();
|
||||
}
|
||||
|
||||
for qi in &t.device_queue_items {
|
||||
|
@ -38,7 +38,7 @@ async fn test_downlink_scheduler() {
|
||||
|
||||
let gw = gateway::create(gateway::Gateway {
|
||||
name: "gateway".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
gateway_id: EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
..Default::default()
|
||||
})
|
||||
@ -47,7 +47,7 @@ async fn test_downlink_scheduler() {
|
||||
|
||||
let app = application::create(application::Application {
|
||||
name: "app".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -55,7 +55,7 @@ async fn test_downlink_scheduler() {
|
||||
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "dp".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
region: lrwn::region::CommonName::EU868,
|
||||
mac_version: lrwn::region::MacVersion::LORAWAN_1_0_4,
|
||||
reg_params_revision: lrwn::region::Revision::RP002_1_0_3,
|
||||
@ -68,8 +68,8 @@ async fn test_downlink_scheduler() {
|
||||
|
||||
let dev = device::create(device::Device {
|
||||
name: "device".into(),
|
||||
application_id: app.id.clone(),
|
||||
device_profile_id: dp.id.clone(),
|
||||
application_id: app.id,
|
||||
device_profile_id: dp.id,
|
||||
dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]),
|
||||
enabled_class: DeviceClass::C,
|
||||
dev_addr: Some(DevAddr::from_be_bytes([1, 2, 3, 4])),
|
||||
@ -115,7 +115,7 @@ async fn test_downlink_scheduler() {
|
||||
dev_eui: dev.dev_eui,
|
||||
device_queue_items: vec![device_queue::DeviceQueueItem {
|
||||
id: Uuid::nil(),
|
||||
dev_eui: dev.dev_eui.clone(),
|
||||
dev_eui: dev.dev_eui,
|
||||
f_port: 10,
|
||||
data: vec![1, 2, 3],
|
||||
..Default::default()
|
||||
@ -142,7 +142,7 @@ async fn test_downlink_scheduler() {
|
||||
dev_eui: dev.dev_eui,
|
||||
device_queue_items: vec![device_queue::DeviceQueueItem {
|
||||
id: Uuid::nil(),
|
||||
dev_eui: dev.dev_eui.clone(),
|
||||
dev_eui: dev.dev_eui,
|
||||
f_port: 10,
|
||||
data: vec![1, 2, 3],
|
||||
..Default::default()
|
||||
@ -150,7 +150,7 @@ async fn test_downlink_scheduler() {
|
||||
device_session: Some(ds.clone()),
|
||||
device_gateway_rx_info: Some(device_gateway_rx_info.clone()),
|
||||
assert: vec![
|
||||
assert::n_f_cnt_down(dev.dev_eui.clone(), 5),
|
||||
assert::n_f_cnt_down(dev.dev_eui, 5),
|
||||
assert::downlink_frame(gw::DownlinkFrame {
|
||||
gateway_id: "0102030405060708".into(),
|
||||
items: vec![gw::DownlinkFrameItem {
|
||||
@ -189,7 +189,7 @@ async fn test_downlink_scheduler() {
|
||||
dev_eui: dev.dev_eui,
|
||||
device_queue_items: vec![device_queue::DeviceQueueItem {
|
||||
id: Uuid::nil(),
|
||||
dev_eui: dev.dev_eui.clone(),
|
||||
dev_eui: dev.dev_eui,
|
||||
f_port: 10,
|
||||
data: vec![1, 2, 3],
|
||||
..Default::default()
|
||||
@ -216,7 +216,7 @@ async fn test_downlink_scheduler() {
|
||||
dev_eui: dev.dev_eui,
|
||||
device_queue_items: vec![device_queue::DeviceQueueItem {
|
||||
id: Uuid::nil(),
|
||||
dev_eui: dev.dev_eui.clone(),
|
||||
dev_eui: dev.dev_eui,
|
||||
f_port: 10,
|
||||
data: vec![1, 2, 3],
|
||||
confirmed: true,
|
||||
@ -225,7 +225,7 @@ async fn test_downlink_scheduler() {
|
||||
device_session: Some(ds.clone()),
|
||||
device_gateway_rx_info: Some(device_gateway_rx_info.clone()),
|
||||
assert: vec![
|
||||
assert::n_f_cnt_down(dev.dev_eui.clone(), 5),
|
||||
assert::n_f_cnt_down(dev.dev_eui, 5),
|
||||
assert::downlink_frame(gw::DownlinkFrame {
|
||||
gateway_id: "0102030405060708".into(),
|
||||
items: vec![gw::DownlinkFrameItem {
|
||||
@ -277,7 +277,7 @@ async fn test_downlink_scheduler() {
|
||||
dev_eui: dev.dev_eui,
|
||||
device_queue_items: vec![device_queue::DeviceQueueItem {
|
||||
id: Uuid::nil(),
|
||||
dev_eui: dev.dev_eui.clone(),
|
||||
dev_eui: dev.dev_eui,
|
||||
f_port: 10,
|
||||
data: vec![0; 300],
|
||||
..Default::default()
|
||||
@ -295,7 +295,7 @@ async fn run_scheduler_test(t: &DownlinkTest) {
|
||||
reset_redis().await.unwrap();
|
||||
|
||||
integration::set_mock().await;
|
||||
gateway_backend::set_backend(&"eu868", Box::new(gateway_backend::mock::Backend {})).await;
|
||||
gateway_backend::set_backend("eu868", Box::new(gateway_backend::mock::Backend {})).await;
|
||||
|
||||
integration::mock::reset().await;
|
||||
gateway_backend::mock::reset().await;
|
||||
@ -311,7 +311,7 @@ async fn run_scheduler_test(t: &DownlinkTest) {
|
||||
.unwrap();
|
||||
|
||||
if let Some(rx_info) = &t.device_gateway_rx_info {
|
||||
let _ = device_gateway::save_rx_info(rx_info).await.unwrap();
|
||||
device_gateway::save_rx_info(rx_info).await.unwrap();
|
||||
}
|
||||
|
||||
for qi in &t.device_queue_items {
|
||||
|
@ -91,5 +91,5 @@ pub async fn prepare<'a>() -> std::sync::MutexGuard<'a, ()> {
|
||||
// setup adr
|
||||
adr::setup().await.unwrap();
|
||||
|
||||
return guard;
|
||||
guard
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ async fn test_multicast() {
|
||||
// device-profile
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "test-dp".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -232,7 +232,7 @@ async fn run_scheduler_test(t: &MulticastTest) {
|
||||
println!("> {}", t.name);
|
||||
|
||||
integration::set_mock().await;
|
||||
gateway_backend::set_backend(&"eu868", Box::new(gateway_backend::mock::Backend {})).await;
|
||||
gateway_backend::set_backend("eu868", Box::new(gateway_backend::mock::Backend {})).await;
|
||||
|
||||
// overwrite multicast-group to deal with frame-counter increments
|
||||
multicast::update(t.multicast_group.clone()).await.unwrap();
|
||||
|
@ -33,7 +33,7 @@ async fn test_js() {
|
||||
|
||||
let gw = gateway::create(gateway::Gateway {
|
||||
name: "gw".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
gateway_id: EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
..Default::default()
|
||||
})
|
||||
@ -42,7 +42,7 @@ async fn test_js() {
|
||||
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "dp".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
region: lrwn::region::CommonName::EU868,
|
||||
mac_version: lrwn::region::MacVersion::LORAWAN_1_0_3,
|
||||
reg_params_revision: lrwn::region::Revision::A,
|
||||
@ -54,7 +54,7 @@ async fn test_js() {
|
||||
|
||||
let app = application::create(application::Application {
|
||||
name: "app".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -62,8 +62,8 @@ async fn test_js() {
|
||||
|
||||
let dev = device::create(device::Device {
|
||||
name: "dev".into(),
|
||||
application_id: app.id.clone(),
|
||||
device_profile_id: dp.id.clone(),
|
||||
application_id: app.id,
|
||||
device_profile_id: dp.id,
|
||||
dev_eui: EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
..Default::default()
|
||||
})
|
||||
@ -74,7 +74,7 @@ async fn test_js() {
|
||||
frequency: 868100000,
|
||||
..Default::default()
|
||||
};
|
||||
uplink::helpers::set_uplink_modulation(&"eu868", &mut tx_info, 0).unwrap();
|
||||
uplink::helpers::set_uplink_modulation("eu868", &mut tx_info, 0).unwrap();
|
||||
|
||||
let mut rx_info = gw::UplinkRxInfo {
|
||||
gateway_id: gw.gateway_id.to_string(),
|
||||
@ -95,7 +95,7 @@ async fn test_js() {
|
||||
},
|
||||
payload: lrwn::Payload::JoinRequest(lrwn::JoinRequestPayload {
|
||||
join_eui: EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
dev_eui: dev.dev_eui.clone(),
|
||||
dev_eui: dev.dev_eui,
|
||||
dev_nonce: 1,
|
||||
}),
|
||||
mic: Some([1, 2, 3, 4]),
|
||||
@ -153,7 +153,7 @@ async fn test_js() {
|
||||
},
|
||||
assert: vec![
|
||||
assert::device_session(
|
||||
dev.dev_eui.clone(),
|
||||
dev.dev_eui,
|
||||
internal::DeviceSession {
|
||||
dev_addr: vec![1, 2, 3, 4],
|
||||
mac_version: common::MacVersion::Lorawan103.into(),
|
||||
@ -220,7 +220,7 @@ async fn test_js() {
|
||||
},
|
||||
assert: vec![
|
||||
assert::device_session(
|
||||
dev.dev_eui.clone(),
|
||||
dev.dev_eui,
|
||||
internal::DeviceSession {
|
||||
dev_addr: vec![1, 2, 3, 4],
|
||||
mac_version: common::MacVersion::Lorawan103.into(),
|
||||
@ -290,7 +290,7 @@ async fn test_js() {
|
||||
},
|
||||
assert: vec![
|
||||
assert::device_session(
|
||||
dev.dev_eui.clone(),
|
||||
dev.dev_eui,
|
||||
internal::DeviceSession {
|
||||
dev_addr: vec![1, 2, 3, 4],
|
||||
mac_version: common::MacVersion::Lorawan103.into(),
|
||||
@ -365,7 +365,7 @@ async fn run_test(t: &Test) {
|
||||
joinserver::setup().await.unwrap();
|
||||
|
||||
integration::set_mock().await;
|
||||
gateway_backend::set_backend(&"eu868", Box::new(gateway_backend::mock::Backend {})).await;
|
||||
gateway_backend::set_backend("eu868", Box::new(gateway_backend::mock::Backend {})).await;
|
||||
|
||||
integration::mock::reset().await;
|
||||
gateway_backend::mock::reset().await;
|
||||
|
@ -154,7 +154,7 @@ async fn test_fns() {
|
||||
dev_eui: vec![8, 7, 6, 5, 4, 3, 2, 1],
|
||||
ul_freq: Some(868.1),
|
||||
data_rate: Some(0),
|
||||
recv_time: recv_time,
|
||||
recv_time,
|
||||
rf_region: "EU868".to_string(),
|
||||
gw_cnt: Some(1),
|
||||
gw_info: roaming::rx_info_to_gw_info(&[rx_info.clone()]).unwrap(),
|
||||
@ -189,7 +189,7 @@ async fn test_fns() {
|
||||
.status(200);
|
||||
});
|
||||
|
||||
gateway_backend::set_backend(&"eu868", Box::new(gateway_backend::mock::Backend {})).await;
|
||||
gateway_backend::set_backend("eu868", Box::new(gateway_backend::mock::Backend {})).await;
|
||||
gateway_backend::mock::reset().await;
|
||||
|
||||
// Simulate uplink
|
||||
@ -281,7 +281,7 @@ async fn test_sns() {
|
||||
|
||||
let app = application::create(application::Application {
|
||||
name: "app".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -289,7 +289,7 @@ async fn test_sns() {
|
||||
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "dp".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
region: lrwn::region::CommonName::EU868,
|
||||
mac_version: lrwn::region::MacVersion::LORAWAN_1_0_2,
|
||||
reg_params_revision: lrwn::region::Revision::A,
|
||||
@ -302,8 +302,8 @@ async fn test_sns() {
|
||||
|
||||
let dev = device::create(device::Device {
|
||||
name: "device".into(),
|
||||
application_id: app.id.clone(),
|
||||
device_profile_id: dp.id.clone(),
|
||||
application_id: app.id,
|
||||
device_profile_id: dp.id,
|
||||
dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]),
|
||||
enabled_class: DeviceClass::B,
|
||||
..Default::default()
|
||||
@ -312,7 +312,7 @@ async fn test_sns() {
|
||||
.unwrap();
|
||||
|
||||
let dk = device_keys::create(device_keys::DeviceKeys {
|
||||
dev_eui: dev.dev_eui.clone(),
|
||||
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![],
|
||||
..Default::default()
|
||||
@ -368,7 +368,7 @@ async fn test_sns() {
|
||||
dev_eui: dev.dev_eui.to_vec(),
|
||||
ul_freq: Some(868.1),
|
||||
data_rate: Some(0),
|
||||
recv_time: recv_time,
|
||||
recv_time,
|
||||
rf_region: "EU868".to_string(),
|
||||
gw_cnt: Some(1),
|
||||
gw_info: roaming::rx_info_to_gw_info(&[rx_info.clone()]).unwrap(),
|
||||
@ -379,7 +379,9 @@ async fn test_sns() {
|
||||
let resp =
|
||||
backend_api::handle_request(Bytes::from(serde_json::to_string(&pr_start_req).unwrap()))
|
||||
.await;
|
||||
let resp_b = hyper::body::to_bytes(resp.into_body()).await.unwrap();
|
||||
let resp_b = axum::body::to_bytes(resp.into_body(), usize::MAX)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let pr_start_ans: backend::PRStartAnsPayload = serde_json::from_slice(&resp_b).unwrap();
|
||||
|
||||
@ -465,7 +467,7 @@ async fn test_sns_roaming_not_allowed() {
|
||||
|
||||
let app = application::create(application::Application {
|
||||
name: "app".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -473,7 +475,7 @@ async fn test_sns_roaming_not_allowed() {
|
||||
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "dp".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
region: lrwn::region::CommonName::EU868,
|
||||
mac_version: lrwn::region::MacVersion::LORAWAN_1_0_2,
|
||||
reg_params_revision: lrwn::region::Revision::A,
|
||||
@ -485,8 +487,8 @@ async fn test_sns_roaming_not_allowed() {
|
||||
|
||||
let dev = device::create(device::Device {
|
||||
name: "device".into(),
|
||||
application_id: app.id.clone(),
|
||||
device_profile_id: dp.id.clone(),
|
||||
application_id: app.id,
|
||||
device_profile_id: dp.id,
|
||||
dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]),
|
||||
enabled_class: DeviceClass::B,
|
||||
..Default::default()
|
||||
@ -495,7 +497,7 @@ async fn test_sns_roaming_not_allowed() {
|
||||
.unwrap();
|
||||
|
||||
let dk = device_keys::create(device_keys::DeviceKeys {
|
||||
dev_eui: dev.dev_eui.clone(),
|
||||
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![],
|
||||
..Default::default()
|
||||
@ -551,7 +553,7 @@ async fn test_sns_roaming_not_allowed() {
|
||||
dev_eui: dev.dev_eui.to_vec(),
|
||||
ul_freq: Some(868.1),
|
||||
data_rate: Some(0),
|
||||
recv_time: recv_time,
|
||||
recv_time,
|
||||
rf_region: "EU868".to_string(),
|
||||
gw_cnt: Some(1),
|
||||
gw_info: roaming::rx_info_to_gw_info(&[rx_info.clone()]).unwrap(),
|
||||
@ -562,7 +564,9 @@ async fn test_sns_roaming_not_allowed() {
|
||||
let resp =
|
||||
backend_api::handle_request(Bytes::from(serde_json::to_string(&pr_start_req).unwrap()))
|
||||
.await;
|
||||
let resp_b = hyper::body::to_bytes(resp.into_body()).await.unwrap();
|
||||
let resp_b = axum::body::to_bytes(resp.into_body(), usize::MAX)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let pr_start_ans: backend::PRStartAnsPayload = serde_json::from_slice(&resp_b).unwrap();
|
||||
|
||||
|
@ -51,7 +51,7 @@ async fn test_gateway_filtering() {
|
||||
|
||||
let gw_a = gateway::create(gateway::Gateway {
|
||||
name: "gateway-a".into(),
|
||||
tenant_id: t_a.id.clone(),
|
||||
tenant_id: t_a.id,
|
||||
gateway_id: EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
..Default::default()
|
||||
})
|
||||
@ -60,7 +60,7 @@ async fn test_gateway_filtering() {
|
||||
|
||||
let gw_b = gateway::create(gateway::Gateway {
|
||||
name: "gateway-b".into(),
|
||||
tenant_id: t_b.id.clone(),
|
||||
tenant_id: t_b.id,
|
||||
gateway_id: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]),
|
||||
..Default::default()
|
||||
})
|
||||
@ -69,7 +69,7 @@ async fn test_gateway_filtering() {
|
||||
|
||||
let app = application::create(application::Application {
|
||||
name: "app".into(),
|
||||
tenant_id: t_a.id.clone(),
|
||||
tenant_id: t_a.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -77,7 +77,7 @@ async fn test_gateway_filtering() {
|
||||
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "dp".into(),
|
||||
tenant_id: t_a.id.clone(),
|
||||
tenant_id: t_a.id,
|
||||
region: lrwn::region::CommonName::EU868,
|
||||
mac_version: lrwn::region::MacVersion::LORAWAN_1_0_2,
|
||||
reg_params_revision: lrwn::region::Revision::A,
|
||||
@ -89,8 +89,8 @@ async fn test_gateway_filtering() {
|
||||
|
||||
let dev = device::create(device::Device {
|
||||
name: "device".into(),
|
||||
application_id: app.id.clone(),
|
||||
device_profile_id: dp.id.clone(),
|
||||
application_id: app.id,
|
||||
device_profile_id: dp.id,
|
||||
dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]),
|
||||
enabled_class: DeviceClass::B,
|
||||
..Default::default()
|
||||
@ -99,7 +99,7 @@ async fn test_gateway_filtering() {
|
||||
.unwrap();
|
||||
|
||||
let dk = device_keys::create(device_keys::DeviceKeys {
|
||||
dev_eui: dev.dev_eui.clone(),
|
||||
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)],
|
||||
..Default::default()
|
||||
@ -135,7 +135,7 @@ async fn test_gateway_filtering() {
|
||||
frequency: 868100000,
|
||||
..Default::default()
|
||||
};
|
||||
uplink::helpers::set_uplink_modulation(&"eu868", &mut tx_info, 0).unwrap();
|
||||
uplink::helpers::set_uplink_modulation("eu868", &mut tx_info, 0).unwrap();
|
||||
|
||||
let mut jr_pl = lrwn::PhyPayload {
|
||||
mhdr: lrwn::MHDR {
|
||||
@ -144,7 +144,7 @@ async fn test_gateway_filtering() {
|
||||
},
|
||||
payload: lrwn::Payload::JoinRequest(lrwn::JoinRequestPayload {
|
||||
join_eui: EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
dev_eui: dev.dev_eui.clone(),
|
||||
dev_eui: dev.dev_eui,
|
||||
dev_nonce: 258,
|
||||
}),
|
||||
mic: None,
|
||||
@ -156,7 +156,7 @@ async fn test_gateway_filtering() {
|
||||
name: "private gateway of same tenant".into(),
|
||||
dev_eui: dev.dev_eui,
|
||||
before_func: Some(Box::new(move || {
|
||||
let dev_eui = dev.dev_eui.clone();
|
||||
let dev_eui = dev.dev_eui;
|
||||
Box::pin(async move {
|
||||
device_keys::test::reset_nonces(&dev_eui).await.unwrap();
|
||||
})
|
||||
@ -167,7 +167,7 @@ async fn test_gateway_filtering() {
|
||||
phy_payload: jr_pl.clone(),
|
||||
extra_uplink_channels: vec![],
|
||||
assert: vec![assert::device_session(
|
||||
dev.dev_eui.clone(),
|
||||
dev.dev_eui,
|
||||
internal::DeviceSession {
|
||||
dev_addr: vec![1, 2, 3, 4],
|
||||
mac_version: common::MacVersion::Lorawan102.into(),
|
||||
@ -200,7 +200,7 @@ async fn test_gateway_filtering() {
|
||||
name: "private gateway other tenant".into(),
|
||||
dev_eui: dev.dev_eui,
|
||||
before_func: Some(Box::new(move || {
|
||||
let dev_eui = dev.dev_eui.clone();
|
||||
let dev_eui = dev.dev_eui;
|
||||
Box::pin(async move {
|
||||
device_keys::test::reset_nonces(&dev_eui).await.unwrap();
|
||||
})
|
||||
@ -210,7 +210,7 @@ async fn test_gateway_filtering() {
|
||||
tx_info: tx_info.clone(),
|
||||
phy_payload: jr_pl.clone(),
|
||||
extra_uplink_channels: vec![],
|
||||
assert: vec![assert::no_device_session(dev.dev_eui.clone())],
|
||||
assert: vec![assert::no_device_session(dev.dev_eui)],
|
||||
},
|
||||
];
|
||||
|
||||
@ -232,7 +232,7 @@ async fn test_lorawan_10() {
|
||||
|
||||
let gw = gateway::create(gateway::Gateway {
|
||||
name: "gateway".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
gateway_id: EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
..Default::default()
|
||||
})
|
||||
@ -241,7 +241,7 @@ async fn test_lorawan_10() {
|
||||
|
||||
let app = application::create(application::Application {
|
||||
name: "app".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -249,7 +249,7 @@ async fn test_lorawan_10() {
|
||||
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "dp".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
region: lrwn::region::CommonName::EU868,
|
||||
mac_version: lrwn::region::MacVersion::LORAWAN_1_0_2,
|
||||
reg_params_revision: lrwn::region::Revision::A,
|
||||
@ -261,8 +261,8 @@ async fn test_lorawan_10() {
|
||||
|
||||
let dev = device::create(device::Device {
|
||||
name: "device".into(),
|
||||
application_id: app.id.clone(),
|
||||
device_profile_id: dp.id.clone(),
|
||||
application_id: app.id,
|
||||
device_profile_id: dp.id,
|
||||
dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]),
|
||||
enabled_class: DeviceClass::B,
|
||||
..Default::default()
|
||||
@ -271,7 +271,7 @@ async fn test_lorawan_10() {
|
||||
.unwrap();
|
||||
|
||||
let dk = device_keys::create(device_keys::DeviceKeys {
|
||||
dev_eui: dev.dev_eui.clone(),
|
||||
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)],
|
||||
..Default::default()
|
||||
@ -295,7 +295,7 @@ async fn test_lorawan_10() {
|
||||
frequency: 868100000,
|
||||
..Default::default()
|
||||
};
|
||||
uplink::helpers::set_uplink_modulation(&"eu868", &mut tx_info, 0).unwrap();
|
||||
uplink::helpers::set_uplink_modulation("eu868", &mut tx_info, 0).unwrap();
|
||||
|
||||
let mut jr_pl = lrwn::PhyPayload {
|
||||
mhdr: lrwn::MHDR {
|
||||
@ -304,7 +304,7 @@ async fn test_lorawan_10() {
|
||||
},
|
||||
payload: lrwn::Payload::JoinRequest(lrwn::JoinRequestPayload {
|
||||
join_eui: EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
dev_eui: dev.dev_eui.clone(),
|
||||
dev_eui: dev.dev_eui,
|
||||
dev_nonce: 258,
|
||||
}),
|
||||
mic: None,
|
||||
@ -391,7 +391,7 @@ async fn test_lorawan_10() {
|
||||
name: "join-request accepted".into(),
|
||||
dev_eui: dev.dev_eui,
|
||||
before_func: Some(Box::new(move || {
|
||||
let dev_eui = dev.dev_eui.clone();
|
||||
let dev_eui = dev.dev_eui;
|
||||
Box::pin(async move {
|
||||
device_keys::test::reset_nonces(&dev_eui).await.unwrap();
|
||||
})
|
||||
@ -407,7 +407,7 @@ async fn test_lorawan_10() {
|
||||
EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
),
|
||||
assert::device_session(
|
||||
dev.dev_eui.clone(),
|
||||
dev.dev_eui,
|
||||
internal::DeviceSession {
|
||||
dev_addr: vec![1, 2, 3, 4],
|
||||
mac_version: common::MacVersion::Lorawan102.into(),
|
||||
@ -563,8 +563,8 @@ async fn test_lorawan_10() {
|
||||
}),
|
||||
..Default::default()
|
||||
}),
|
||||
assert::enabled_class(dev.dev_eui.clone(), DeviceClass::A),
|
||||
assert::device_queue_items(dev.dev_eui.clone(), vec![]),
|
||||
assert::enabled_class(dev.dev_eui, DeviceClass::A),
|
||||
assert::device_queue_items(dev.dev_eui, vec![]),
|
||||
assert::uplink_meta_log(stream::UplinkMeta {
|
||||
dev_eui: dev.dev_eui.to_string(),
|
||||
tx_info: Some(tx_info.clone()),
|
||||
@ -579,7 +579,7 @@ async fn test_lorawan_10() {
|
||||
name: "join-request accepted + skip fcnt check".into(),
|
||||
dev_eui: dev.dev_eui,
|
||||
before_func: Some(Box::new(move || {
|
||||
let dev_eui = dev.dev_eui.clone();
|
||||
let dev_eui = dev.dev_eui;
|
||||
Box::pin(async move {
|
||||
device_keys::test::reset_nonces(&dev_eui).await.unwrap();
|
||||
|
||||
@ -589,7 +589,7 @@ async fn test_lorawan_10() {
|
||||
})
|
||||
})),
|
||||
after_func: Some(Box::new(move || {
|
||||
let dev_eui = dev.dev_eui.clone();
|
||||
let dev_eui = dev.dev_eui;
|
||||
Box::pin(async move {
|
||||
let mut dev = device::get(&dev_eui).await.unwrap();
|
||||
dev.skip_fcnt_check = false;
|
||||
@ -601,7 +601,7 @@ async fn test_lorawan_10() {
|
||||
phy_payload: jr_pl.clone(),
|
||||
extra_uplink_channels: vec![],
|
||||
assert: vec![assert::device_session(
|
||||
dev.dev_eui.clone(),
|
||||
dev.dev_eui,
|
||||
internal::DeviceSession {
|
||||
dev_addr: vec![1, 2, 3, 4],
|
||||
mac_version: common::MacVersion::Lorawan102.into(),
|
||||
@ -635,7 +635,7 @@ async fn test_lorawan_10() {
|
||||
name: "join-request accepted + cflist".into(),
|
||||
dev_eui: dev.dev_eui,
|
||||
before_func: Some(Box::new(move || {
|
||||
let dev_eui = dev.dev_eui.clone();
|
||||
let dev_eui = dev.dev_eui;
|
||||
Box::pin(async move {
|
||||
device_keys::test::reset_nonces(&dev_eui).await.unwrap();
|
||||
})
|
||||
@ -647,7 +647,7 @@ async fn test_lorawan_10() {
|
||||
extra_uplink_channels: vec![867100000, 867300000, 867500000, 867700000, 867900000],
|
||||
assert: vec![
|
||||
assert::device_session(
|
||||
dev.dev_eui.clone(),
|
||||
dev.dev_eui,
|
||||
internal::DeviceSession {
|
||||
dev_addr: vec![1, 2, 3, 4],
|
||||
mac_version: common::MacVersion::Lorawan102.into(),
|
||||
@ -787,8 +787,8 @@ async fn test_lorawan_10() {
|
||||
name: "join-request accepted + class-b supported".into(),
|
||||
dev_eui: dev.dev_eui,
|
||||
before_func: Some(Box::new(move || {
|
||||
let dev_eui = dev.dev_eui.clone();
|
||||
let dp_id = dp.id.clone();
|
||||
let dev_eui = dev.dev_eui;
|
||||
let dp_id = dp.id;
|
||||
Box::pin(async move {
|
||||
device_keys::test::reset_nonces(&dev_eui).await.unwrap();
|
||||
|
||||
@ -798,7 +798,7 @@ async fn test_lorawan_10() {
|
||||
})
|
||||
})),
|
||||
after_func: Some(Box::new(move || {
|
||||
let dp_id = dp.id.clone();
|
||||
let dp_id = dp.id;
|
||||
Box::pin(async move {
|
||||
let mut dp = device_profile::get(&dp_id).await.unwrap();
|
||||
dp.supports_class_b = false;
|
||||
@ -809,14 +809,14 @@ async fn test_lorawan_10() {
|
||||
tx_info: tx_info.clone(),
|
||||
phy_payload: jr_pl.clone(),
|
||||
extra_uplink_channels: Vec::new(),
|
||||
assert: vec![assert::enabled_class(dev.dev_eui.clone(), DeviceClass::A)],
|
||||
assert: vec![assert::enabled_class(dev.dev_eui, DeviceClass::A)],
|
||||
},
|
||||
Test {
|
||||
name: "join-request accepted + class-c supported".into(),
|
||||
dev_eui: dev.dev_eui,
|
||||
before_func: Some(Box::new(move || {
|
||||
let dev_eui = dev.dev_eui.clone();
|
||||
let dp_id = dp.id.clone();
|
||||
let dev_eui = dev.dev_eui;
|
||||
let dp_id = dp.id;
|
||||
Box::pin(async move {
|
||||
device_keys::test::reset_nonces(&dev_eui).await.unwrap();
|
||||
|
||||
@ -826,7 +826,7 @@ async fn test_lorawan_10() {
|
||||
})
|
||||
})),
|
||||
after_func: Some(Box::new(move || {
|
||||
let dp_id = dp.id.clone();
|
||||
let dp_id = dp.id;
|
||||
Box::pin(async move {
|
||||
let mut dp = device_profile::get(&dp_id).await.unwrap();
|
||||
dp.supports_class_c = false;
|
||||
@ -837,13 +837,13 @@ async fn test_lorawan_10() {
|
||||
tx_info: tx_info.clone(),
|
||||
phy_payload: jr_pl.clone(),
|
||||
extra_uplink_channels: Vec::new(),
|
||||
assert: vec![assert::enabled_class(dev.dev_eui.clone(), DeviceClass::C)],
|
||||
assert: vec![assert::enabled_class(dev.dev_eui, DeviceClass::C)],
|
||||
},
|
||||
Test {
|
||||
name: "device disabled".into(),
|
||||
dev_eui: dev.dev_eui,
|
||||
before_func: Some(Box::new(move || {
|
||||
let dev_eui = dev.dev_eui.clone();
|
||||
let dev_eui = dev.dev_eui;
|
||||
Box::pin(async move {
|
||||
device_keys::test::reset_nonces(&dev_eui).await.unwrap();
|
||||
|
||||
@ -853,7 +853,7 @@ async fn test_lorawan_10() {
|
||||
})
|
||||
})),
|
||||
after_func: Some(Box::new(move || {
|
||||
let dev_eui = dev.dev_eui.clone();
|
||||
let dev_eui = dev.dev_eui;
|
||||
Box::pin(async move {
|
||||
let mut dev = device::get(&dev_eui).await.unwrap();
|
||||
dev.is_disabled = false;
|
||||
@ -887,7 +887,7 @@ async fn test_lorawan_11() {
|
||||
|
||||
let gw = gateway::create(gateway::Gateway {
|
||||
name: "gateway".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
gateway_id: EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
..Default::default()
|
||||
})
|
||||
@ -896,7 +896,7 @@ async fn test_lorawan_11() {
|
||||
|
||||
let app = application::create(application::Application {
|
||||
name: "app".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -904,7 +904,7 @@ async fn test_lorawan_11() {
|
||||
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "dp".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
region: lrwn::region::CommonName::EU868,
|
||||
mac_version: lrwn::region::MacVersion::LORAWAN_1_1_0,
|
||||
reg_params_revision: lrwn::region::Revision::RP002_1_0_3,
|
||||
@ -916,8 +916,8 @@ async fn test_lorawan_11() {
|
||||
|
||||
let dev = device::create(device::Device {
|
||||
name: "device".into(),
|
||||
application_id: app.id.clone(),
|
||||
device_profile_id: dp.id.clone(),
|
||||
application_id: app.id,
|
||||
device_profile_id: dp.id,
|
||||
dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]),
|
||||
enabled_class: DeviceClass::B,
|
||||
..Default::default()
|
||||
@ -926,7 +926,7 @@ async fn test_lorawan_11() {
|
||||
.unwrap();
|
||||
|
||||
let dk = device_keys::create(device_keys::DeviceKeys {
|
||||
dev_eui: dev.dev_eui.clone(),
|
||||
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)],
|
||||
@ -951,7 +951,7 @@ async fn test_lorawan_11() {
|
||||
frequency: 868100000,
|
||||
..Default::default()
|
||||
};
|
||||
uplink::helpers::set_uplink_modulation(&"eu868", &mut tx_info, 0).unwrap();
|
||||
uplink::helpers::set_uplink_modulation("eu868", &mut tx_info, 0).unwrap();
|
||||
|
||||
let mut jr_pl = lrwn::PhyPayload {
|
||||
mhdr: lrwn::MHDR {
|
||||
@ -960,7 +960,7 @@ async fn test_lorawan_11() {
|
||||
},
|
||||
payload: lrwn::Payload::JoinRequest(lrwn::JoinRequestPayload {
|
||||
join_eui: EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
dev_eui: dev.dev_eui.clone(),
|
||||
dev_eui: dev.dev_eui,
|
||||
dev_nonce: 258,
|
||||
}),
|
||||
mic: None,
|
||||
@ -1014,7 +1014,7 @@ async fn test_lorawan_11() {
|
||||
name: "join-request accepted".into(),
|
||||
dev_eui: dev.dev_eui,
|
||||
before_func: Some(Box::new(move || {
|
||||
let dev_eui = dev.dev_eui.clone();
|
||||
let dev_eui = dev.dev_eui;
|
||||
Box::pin(async move {
|
||||
device_keys::test::reset_nonces(&dev_eui).await.unwrap();
|
||||
})
|
||||
@ -1026,7 +1026,7 @@ async fn test_lorawan_11() {
|
||||
extra_uplink_channels: vec![],
|
||||
assert: vec![
|
||||
assert::device_session(
|
||||
dev.dev_eui.clone(),
|
||||
dev.dev_eui,
|
||||
internal::DeviceSession {
|
||||
dev_addr: vec![1, 2, 3, 4],
|
||||
mac_version: common::MacVersion::Lorawan110.into(),
|
||||
@ -1185,16 +1185,16 @@ async fn test_lorawan_11() {
|
||||
}),
|
||||
..Default::default()
|
||||
}),
|
||||
assert::enabled_class(dev.dev_eui.clone(), DeviceClass::A),
|
||||
assert::device_queue_items(dev.dev_eui.clone(), vec![]),
|
||||
assert::enabled_class(dev.dev_eui, DeviceClass::A),
|
||||
assert::device_queue_items(dev.dev_eui, vec![]),
|
||||
],
|
||||
},
|
||||
Test {
|
||||
name: "join-request accepted + class-c supported".into(),
|
||||
dev_eui: dev.dev_eui,
|
||||
before_func: Some(Box::new(move || {
|
||||
let dev_eui = dev.dev_eui.clone();
|
||||
let dp_id = dp.id.clone();
|
||||
let dev_eui = dev.dev_eui;
|
||||
let dp_id = dp.id;
|
||||
Box::pin(async move {
|
||||
device_keys::test::reset_nonces(&dev_eui).await.unwrap();
|
||||
|
||||
@ -1204,7 +1204,7 @@ async fn test_lorawan_11() {
|
||||
})
|
||||
})),
|
||||
after_func: Some(Box::new(move || {
|
||||
let dp_id = dp.id.clone();
|
||||
let dp_id = dp.id;
|
||||
Box::pin(async move {
|
||||
let mut dp = device_profile::get(&dp_id).await.unwrap();
|
||||
dp.supports_class_c = false;
|
||||
@ -1215,7 +1215,7 @@ async fn test_lorawan_11() {
|
||||
tx_info: tx_info.clone(),
|
||||
phy_payload: jr_pl.clone(),
|
||||
extra_uplink_channels: Vec::new(),
|
||||
assert: vec![assert::enabled_class(dev.dev_eui.clone(), DeviceClass::A)],
|
||||
assert: vec![assert::enabled_class(dev.dev_eui, DeviceClass::A)],
|
||||
},
|
||||
];
|
||||
|
||||
@ -1242,7 +1242,7 @@ async fn run_test(t: &Test) {
|
||||
region::setup().unwrap();
|
||||
|
||||
integration::set_mock().await;
|
||||
gateway_backend::set_backend(&"eu868", Box::new(gateway_backend::mock::Backend {})).await;
|
||||
gateway_backend::set_backend("eu868", Box::new(gateway_backend::mock::Backend {})).await;
|
||||
|
||||
integration::mock::reset().await;
|
||||
gateway_backend::mock::reset().await;
|
||||
|
@ -121,7 +121,7 @@ async fn test_lorawan_10() {
|
||||
frequency: 868100000,
|
||||
..Default::default()
|
||||
};
|
||||
uplink::helpers::set_uplink_modulation(&"eu868", &mut tx_info, 5).unwrap();
|
||||
uplink::helpers::set_uplink_modulation("eu868", &mut tx_info, 5).unwrap();
|
||||
|
||||
let ds_relay = internal::DeviceSession {
|
||||
mac_version: common::MacVersion::Lorawan104.into(),
|
||||
@ -769,7 +769,7 @@ async fn run_test(t: &Test) {
|
||||
reset_redis().await.unwrap();
|
||||
|
||||
integration::set_mock().await;
|
||||
gateway_backend::set_backend(&"eu868", Box::new(gateway_backend::mock::Backend {})).await;
|
||||
gateway_backend::set_backend("eu868", Box::new(gateway_backend::mock::Backend {})).await;
|
||||
|
||||
integration::mock::reset().await;
|
||||
gateway_backend::mock::reset().await;
|
||||
|
@ -16,7 +16,7 @@ use lrwn::{AES128Key, DevAddr, EUI64};
|
||||
async fn test_lorawan_10() {
|
||||
let _guard = test::prepare().await;
|
||||
integration::set_mock().await;
|
||||
gateway_backend::set_backend(&"eu868", Box::new(gateway_backend::mock::Backend {})).await;
|
||||
gateway_backend::set_backend("eu868", Box::new(gateway_backend::mock::Backend {})).await;
|
||||
|
||||
integration::mock::reset().await;
|
||||
gateway_backend::mock::reset().await;
|
||||
@ -31,7 +31,7 @@ async fn test_lorawan_10() {
|
||||
|
||||
let gw = gateway::create(gateway::Gateway {
|
||||
name: "gateway".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
gateway_id: EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
..Default::default()
|
||||
})
|
||||
@ -40,7 +40,7 @@ async fn test_lorawan_10() {
|
||||
|
||||
let app = application::create(application::Application {
|
||||
name: "app".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
@ -48,7 +48,7 @@ async fn test_lorawan_10() {
|
||||
|
||||
let dp = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "dp".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
region: lrwn::region::CommonName::EU868,
|
||||
mac_version: lrwn::region::MacVersion::LORAWAN_1_0_2,
|
||||
reg_params_revision: lrwn::region::Revision::A,
|
||||
@ -60,7 +60,7 @@ async fn test_lorawan_10() {
|
||||
|
||||
let dp_relay = device_profile::create(device_profile::DeviceProfile {
|
||||
name: "dp".into(),
|
||||
tenant_id: t.id.clone(),
|
||||
tenant_id: t.id,
|
||||
region: lrwn::region::CommonName::EU868,
|
||||
mac_version: lrwn::region::MacVersion::LORAWAN_1_0_2,
|
||||
reg_params_revision: lrwn::region::Revision::A,
|
||||
@ -73,8 +73,8 @@ async fn test_lorawan_10() {
|
||||
|
||||
let dev = device::create(device::Device {
|
||||
name: "device".into(),
|
||||
application_id: app.id.clone(),
|
||||
device_profile_id: dp.id.clone(),
|
||||
application_id: app.id,
|
||||
device_profile_id: dp.id,
|
||||
dev_eui: EUI64::from_be_bytes([1, 1, 1, 1, 1, 1, 1, 1]),
|
||||
enabled_class: DeviceClass::A,
|
||||
..Default::default()
|
||||
@ -83,7 +83,7 @@ async fn test_lorawan_10() {
|
||||
.unwrap();
|
||||
|
||||
let dk_dev = device_keys::create(device_keys::DeviceKeys {
|
||||
dev_eui: dev.dev_eui.clone(),
|
||||
dev_eui: dev.dev_eui,
|
||||
nwk_key: AES128Key::from_bytes([1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
..Default::default()
|
||||
})
|
||||
@ -92,8 +92,8 @@ async fn test_lorawan_10() {
|
||||
|
||||
let dev_relay = device::create(device::Device {
|
||||
name: "relay-device".into(),
|
||||
application_id: app.id.clone(),
|
||||
device_profile_id: dp_relay.id.clone(),
|
||||
application_id: app.id,
|
||||
device_profile_id: dp_relay.id,
|
||||
dev_eui: EUI64::from_be_bytes([1, 1, 1, 1, 1, 1, 1, 2]),
|
||||
enabled_class: DeviceClass::A,
|
||||
dev_addr: Some(DevAddr::from_be_bytes([4, 3, 2, 1])),
|
||||
@ -133,7 +133,7 @@ async fn test_lorawan_10() {
|
||||
frequency: 868100000,
|
||||
..Default::default()
|
||||
};
|
||||
uplink::helpers::set_uplink_modulation(&"eu868", &mut tx_info, 0).unwrap();
|
||||
uplink::helpers::set_uplink_modulation("eu868", &mut tx_info, 0).unwrap();
|
||||
|
||||
let mut jr_pl = lrwn::PhyPayload {
|
||||
mhdr: lrwn::MHDR {
|
||||
@ -142,7 +142,7 @@ async fn test_lorawan_10() {
|
||||
},
|
||||
payload: lrwn::Payload::JoinRequest(lrwn::JoinRequestPayload {
|
||||
join_eui: EUI64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||
dev_eui: dev.dev_eui.clone(),
|
||||
dev_eui: dev.dev_eui,
|
||||
dev_nonce: 1,
|
||||
}),
|
||||
mic: None,
|
||||
@ -265,7 +265,7 @@ async fn test_lorawan_10() {
|
||||
|
||||
let assertions = vec![
|
||||
assert::device_session(
|
||||
dev.dev_eui.clone(),
|
||||
dev.dev_eui,
|
||||
internal::DeviceSession {
|
||||
dev_addr: vec![1, 2, 3, 4],
|
||||
mac_version: common::MacVersion::Lorawan102.into(),
|
||||
|
@ -1029,11 +1029,9 @@ impl Data {
|
||||
match v {
|
||||
pbjson_types::value::Kind::NumberValue(v) => {
|
||||
let record = metrics::Record {
|
||||
time: DateTime::<Utc>::try_from(
|
||||
up_event.time.as_ref().unwrap().clone(),
|
||||
)
|
||||
.map_err(anyhow::Error::msg)?
|
||||
.with_timezone(&Local),
|
||||
time: DateTime::<Utc>::try_from(*up_event.time.as_ref().unwrap())
|
||||
.map_err(anyhow::Error::msg)?
|
||||
.with_timezone(&Local),
|
||||
kind: match dp_m.kind {
|
||||
fields::MeasurementKind::COUNTER => metrics::Kind::COUNTER,
|
||||
fields::MeasurementKind::ABSOLUTE => metrics::Kind::ABSOLUTE,
|
||||
|
@ -69,7 +69,7 @@ pub fn get_rx_timestamp(rx_info: &[gw::UplinkRxInfo]) -> SystemTime {
|
||||
// Then search for time.
|
||||
for rxi in rx_info {
|
||||
if let Some(ts) = &rxi.gw_time {
|
||||
let ts: Result<DateTime<Utc>> = ts.clone().try_into().map_err(anyhow::Error::msg);
|
||||
let ts: Result<DateTime<Utc>> = (*ts).try_into().map_err(anyhow::Error::msg);
|
||||
if let Ok(ts) = ts {
|
||||
return ts.into();
|
||||
}
|
||||
@ -96,7 +96,7 @@ pub fn get_rx_timestamp_chrono(rx_info: &[gw::UplinkRxInfo]) -> DateTime<Utc> {
|
||||
// Then search for time.
|
||||
for rxi in rx_info {
|
||||
if let Some(ts) = &rxi.gw_time {
|
||||
let ts: Result<DateTime<Utc>> = ts.clone().try_into().map_err(anyhow::Error::msg);
|
||||
let ts: Result<DateTime<Utc>> = (*ts).try_into().map_err(anyhow::Error::msg);
|
||||
if let Ok(ts) = ts {
|
||||
return ts;
|
||||
}
|
||||
@ -140,9 +140,7 @@ pub fn get_start_location(rx_info: &[gw::UplinkRxInfo]) -> Option<common::Locati
|
||||
.cloned()
|
||||
.collect();
|
||||
with_loc.sort_by(|a, b| a.snr.partial_cmp(&b.snr).unwrap());
|
||||
with_loc
|
||||
.first()
|
||||
.map(|i| i.location.as_ref().unwrap().clone())
|
||||
with_loc.first().map(|i| *i.location.as_ref().unwrap())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -75,8 +75,7 @@ impl MeshHeartbeat {
|
||||
let border_gw = gateway::get(&self.gateway_id).await?;
|
||||
|
||||
let ts: DateTime<Utc> = match &self.mesh_stats.time {
|
||||
Some(v) => v
|
||||
.clone()
|
||||
Some(v) => (*v)
|
||||
.try_into()
|
||||
.map_err(|e| anyhow!("Convert time error: {}", e))?,
|
||||
None => {
|
||||
|
@ -102,9 +102,7 @@ impl Stats {
|
||||
|
||||
let mut m = metrics::Record {
|
||||
time: match &self.stats.time {
|
||||
Some(v) => DateTime::try_from(v.clone())
|
||||
.map_err(anyhow::Error::msg)?
|
||||
.into(),
|
||||
Some(v) => DateTime::try_from(*v).map_err(anyhow::Error::msg)?.into(),
|
||||
None => Local::now(),
|
||||
},
|
||||
kind: metrics::Kind::ABSOLUTE,
|
||||
@ -179,15 +177,12 @@ impl Stats {
|
||||
|
||||
let window: Duration = duty_cycle_stats
|
||||
.window
|
||||
.clone()
|
||||
.map(|v| v.try_into().unwrap_or_default())
|
||||
.unwrap_or_default();
|
||||
|
||||
let mut m = metrics::Record {
|
||||
time: match &self.stats.time {
|
||||
Some(v) => DateTime::try_from(v.clone())
|
||||
.map_err(anyhow::Error::msg)?
|
||||
.into(),
|
||||
Some(v) => DateTime::try_from(*v).map_err(anyhow::Error::msg)?.into(),
|
||||
None => Local::now(),
|
||||
},
|
||||
kind: metrics::Kind::COUNTER,
|
||||
@ -197,12 +192,10 @@ impl Stats {
|
||||
for b in &duty_cycle_stats.bands {
|
||||
let load_max: Duration = b
|
||||
.load_max
|
||||
.clone()
|
||||
.map(|d| d.try_into().unwrap_or_default())
|
||||
.unwrap_or_default();
|
||||
let load_tracked: Duration = b
|
||||
.load_tracked
|
||||
.clone()
|
||||
.map(|d| d.try_into().unwrap_or_default())
|
||||
.unwrap_or_default();
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
description = "Library for filtering LoRaWAN payloads on DevAddr and JoinEUIs prefixes"
|
||||
homepage = "https://www.chirpstack.io/"
|
||||
license = "MIT"
|
||||
version = "4.9.0-test.5"
|
||||
version = "4.9.0-test.6"
|
||||
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.9.0-test.5"
|
||||
version = "4.9.0-test.6"
|
||||
authors = ["Orne Brocaar <info@brocaar.com>"]
|
||||
edition = "2018"
|
||||
repository = "https://github.com/chirpstack/chirpstack"
|
||||
|
@ -373,7 +373,7 @@ mod tests {
|
||||
];
|
||||
|
||||
for tst in tests {
|
||||
let mut devaddr = tst.devaddr.clone();
|
||||
let mut devaddr = tst.devaddr;
|
||||
devaddr.set_dev_addr_prefix(tst.netid.dev_addr_prefix());
|
||||
assert_eq!(tst.expected_devaddr, devaddr);
|
||||
}
|
||||
|
@ -287,7 +287,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_eui64_from_str() {
|
||||
let eui = EUI64::from_be_bytes([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]);
|
||||
assert_eq!(eui, EUI64::from_str(&"0102030405060708").unwrap());
|
||||
assert_eq!(eui, EUI64::from_str("0102030405060708").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -2649,7 +2649,7 @@ mod test {
|
||||
uplink: false,
|
||||
command: MACCommand::NewChannelReq(NewChannelReqPayload {
|
||||
ch_index: 3,
|
||||
freq: 2410_000_000,
|
||||
freq: 2_410_000_000,
|
||||
max_dr: 5,
|
||||
min_dr: 0,
|
||||
}),
|
||||
|
@ -464,7 +464,7 @@ mod tests {
|
||||
// before it can be decoded
|
||||
assert_eq!(
|
||||
Payload::Raw(vec![0x01, 0x02, 0x03]),
|
||||
Payload::from_slice(MType::JoinAccept, &vec![0x01, 0x02, 0x03]).unwrap()
|
||||
Payload::from_slice(MType::JoinAccept, &[0x01, 0x02, 0x03]).unwrap()
|
||||
);
|
||||
|
||||
// test decoding the (decrypted) join-accept payload
|
||||
|
@ -1000,8 +1000,7 @@ pub mod test {
|
||||
use crate::*;
|
||||
|
||||
fn config() -> Configuration {
|
||||
let c = Configuration::new(CommonName::AS923, true, true);
|
||||
c
|
||||
Configuration::new(CommonName::AS923, true, true)
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1219,8 +1219,7 @@ pub mod test {
|
||||
use crate::*;
|
||||
|
||||
fn config_full() -> Configuration {
|
||||
let c = Configuration::new(false, false);
|
||||
c
|
||||
Configuration::new(false, false)
|
||||
}
|
||||
|
||||
fn config_chan_8_15() -> Configuration {
|
||||
@ -1340,7 +1339,7 @@ pub mod test {
|
||||
#[test]
|
||||
fn test_cf_list() {
|
||||
let c = config_chan_8_15();
|
||||
assert_eq!(true, c.get_cf_list(MacVersion::LORAWAN_1_0_2).is_none());
|
||||
assert!(c.get_cf_list(MacVersion::LORAWAN_1_0_2).is_none());
|
||||
|
||||
let lw_11_cf_list = c.get_cf_list(MacVersion::LORAWAN_1_1_0).unwrap();
|
||||
assert_eq!(
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user