Compare commits

..

10 Commits

Author SHA1 Message Date
a811ec5c80 Bump version to 4.9.0-test.6 2024-08-07 15:11:09 +01:00
5794f41324 Fix clippy feedback (cargo clippy --fix). 2024-08-07 14:59:25 +01:00
7158c0c610 ui: Update codec template with JSDoc (#473) 2024-08-05 11:17:13 +01:00
eda6646b18 Update dependencies. 2024-08-05 10:15:23 +01:00
40a2b83bf5 Update redis dependency. 2024-08-05 10:06:48 +01:00
4e0106a4e8 Replace warp with axum.
The warp dependency was causing some issues with upgrading dependencies
as it depends on http v0.2, where other dependencies (e.g. tonic) have
already upgraded to http v1+.
2024-08-01 11:33:57 +01:00
98978135c4 ui: Fix formatting template after merging #460. 2024-07-30 11:18:52 +01:00
6a691c62e2 Update dependencies. 2024-07-24 14:12:50 +01:00
66ab41036b Update lapin crate.
This disables the default features (rustls), because lapin enables the
default rustls features, which pulls in the aws-lc-rs dependency besides
ring.

Most likely, the next lapin version will fix this by exposing feature
flags to either enable aws-lc-rs or ring backend for rustls.
2024-07-24 14:05:46 +01:00
dc57e6fe51 Update rustls to 0.23. 2024-07-23 14:03:09 +01:00
115 changed files with 1911 additions and 1950 deletions

1612
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -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" }

View File

@ -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": {

View File

@ -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
View File

@ -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": {

View File

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

View File

@ -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",

View File

@ -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
View File

@ -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
View File

@ -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),
);
}
_ => {}
}

View File

@ -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

View File

@ -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",
] }

View File

@ -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),
)?;

View File

@ -3,7 +3,7 @@
description = "ChirpStack is an open-source LoRaWAN(TM) Network Server"
repository = "https://github.com/chirpstack/chirpstack"
homepage = "https://www.chirpstack.io/"
version = "4.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"

View File

@ -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
}

View File

@ -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());
}
}

View File

@ -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),

View File

@ -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,

View File

@ -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;
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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!(

View 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()
}

View File

@ -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") {

View File

@ -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<()> {

View File

@ -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
}
}

View File

@ -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> {

View File

@ -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> {

View File

@ -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
}
}

View File

@ -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());
}

View File

@ -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());
}

View File

@ -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;
}
}
}

View File

@ -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())

View File

@ -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,

View File

@ -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,

View File

@ -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;

View File

@ -1,2 +1,3 @@
pub mod errors;
pub mod tls;
pub mod tls22; // rustls 0.22

View 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())
}
}

View File

@ -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")?;

View File

@ -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;

View File

@ -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)?;

View File

@ -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> {

View File

@ -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)?,

View File

@ -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()
}

View File

@ -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!(

View File

@ -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();

View File

@ -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

View File

@ -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()

View File

@ -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!(

View File

@ -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!(

View File

@ -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!(

View File

@ -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!(

View File

@ -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!(

View File

@ -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!(

View File

@ -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!(

View File

@ -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!(

View File

@ -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!(

View File

@ -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!(

View File

@ -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!(

View File

@ -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());
}
}

View File

@ -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());
}
}

View File

@ -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,);
}
}

View File

@ -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());
}
}

View File

@ -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());
}
}

View File

@ -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());
}
}

View File

@ -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]

View File

@ -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]

View File

@ -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());
}
}

View File

@ -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");

View File

@ -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

View File

@ -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]

View File

@ -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());
}
}

View File

@ -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 {

View File

@ -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(),

View File

@ -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 {

View File

@ -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());

View File

@ -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();

View File

@ -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;

View File

@ -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 {

View File

@ -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 {

View File

@ -91,5 +91,5 @@ pub async fn prepare<'a>() -> std::sync::MutexGuard<'a, ()> {
// setup adr
adr::setup().await.unwrap();
return guard;
guard
}

View File

@ -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();

View File

@ -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;

View File

@ -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();

View File

@ -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;

View File

@ -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;

View File

@ -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(),

View File

@ -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,

View File

@ -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)]

View File

@ -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 => {

View File

@ -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();

View File

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

View File

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

View File

@ -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);
}

View File

@ -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]

View File

@ -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,
}),

View File

@ -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

View File

@ -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]

View File

@ -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