From 00f54ab0c2584cfed7022c8bc776c8a5ccf66be3 Mon Sep 17 00:00:00 2001 From: user Date: Sat, 27 Jul 2024 23:17:33 +0500 Subject: [PATCH 1/9] formatting fix --- chirpstack/src/api/device.rs | 21 ++++++++++----- chirpstack/src/devaddr.rs | 2 +- chirpstack/src/storage/device_slot.rs | 4 +-- chirpstack/src/storage/helpers.rs | 38 +++++++++++++-------------- chirpstack/src/storage/mod.rs | 2 +- chirpstack/src/storage/schema.rs | 2 +- chirpstack/src/uplink/join.rs | 5 +++- lrwn/src/devaddr.rs | 9 +++---- lrwn/src/region/eu868.rs | 4 ++- 9 files changed, 49 insertions(+), 38 deletions(-) diff --git a/chirpstack/src/api/device.rs b/chirpstack/src/api/device.rs index 1b50bcea..8dca325d 100644 --- a/chirpstack/src/api/device.rs +++ b/chirpstack/src/api/device.rs @@ -474,8 +474,8 @@ impl DeviceService for Device { .await?; let dev_addr = DevAddr::from_str(&req_ds.dev_addr).map_err(|e| e.status())?; - let multicast_group_id = Uuid::from_str(&req_ds.multicast_group_id).map_err(|e| e.status())?; - + let multicast_group_id = + Uuid::from_str(&req_ds.multicast_group_id).map_err(|e| e.status())?; let ds = device_slot::DeviceSlot { dev_eui, @@ -509,12 +509,15 @@ impl DeviceService for Device { let slot: u32 = match ds.slot { Some(s) => s as u32, None => return Err(Status::invalid_argument("Slot is missing")), - }; + }; let dev_addr = match ds.dev_addr { Some(addr) => addr.to_string(), - None => return Err(Status::invalid_argument("DevAddr is missing or not specified")), + None => { + return Err(Status::invalid_argument( + "DevAddr is missing or not specified", + )) + } }; - let response = api::GetDeviceSlotResponse { dev_addr, @@ -553,7 +556,9 @@ impl DeviceService for Device { created_at: ds.created_at, }; - device_slot::update(updated_ds).await.map_err(|e| e.status())?; + device_slot::update(updated_ds) + .await + .map_err(|e| e.status())?; Ok(Response::new(())) } @@ -573,7 +578,9 @@ impl DeviceService for Device { ) .await?; - device_slot::delete(&dev_eui).await.map_err(|e| e.status())?; + device_slot::delete(&dev_eui) + .await + .map_err(|e| e.status())?; Ok(Response::new(())) } diff --git a/chirpstack/src/devaddr.rs b/chirpstack/src/devaddr.rs index 4065141a..8c28955c 100644 --- a/chirpstack/src/devaddr.rs +++ b/chirpstack/src/devaddr.rs @@ -135,7 +135,7 @@ fn regenerate_dev_addr_for_slot(slot: i32, max_slot_count: i32) -> DevAddr { for &byte in sha256_hash.iter().take(8) { big_int = (big_int << 8) | byte as u64; } - + let hash_int = (big_int % max_slot_count as u64) as i32; if hash_int % max_slot_count == slot { diff --git a/chirpstack/src/storage/device_slot.rs b/chirpstack/src/storage/device_slot.rs index 0f3909a1..672649a5 100644 --- a/chirpstack/src/storage/device_slot.rs +++ b/chirpstack/src/storage/device_slot.rs @@ -5,7 +5,7 @@ use diesel_async::RunQueryDsl; use tracing::info; use uuid::Uuid; -use lrwn::{EUI64, DevAddr}; +use lrwn::{DevAddr, EUI64}; use super::error::Error; use super::get_async_db_conn; @@ -82,4 +82,4 @@ pub async fn delete(dev_eui: &EUI64) -> Result<(), Error> { "Device slot deleted" ); Ok(()) -} \ No newline at end of file +} diff --git a/chirpstack/src/storage/helpers.rs b/chirpstack/src/storage/helpers.rs index cf6ca409..9862a262 100644 --- a/chirpstack/src/storage/helpers.rs +++ b/chirpstack/src/storage/helpers.rs @@ -1,14 +1,16 @@ use diesel::prelude::*; use diesel_async::RunQueryDsl; -use super::schema::{application, device, device_profile, tenant, multicast_group, multicast_group_device}; +use super::schema::{ + application, device, device_profile, multicast_group, multicast_group_device, tenant, +}; use super::{ - application::Application, device::Device, device_profile::DeviceProfile, tenant::Tenant + application::Application, device::Device, device_profile::DeviceProfile, tenant::Tenant, }; use super::{error::Error, get_async_db_conn}; use lrwn::EUI64; -use uuid::Uuid; use sha2::{Digest, Sha256}; +use uuid::Uuid; pub async fn get_all_device_data( dev_eui: EUI64, @@ -24,12 +26,9 @@ pub async fn get_all_device_data( Ok(res) } - static SECRET_KEY: &[u8; 32] = b"e2fc714cef004ad48c91d2c08b8c4f75"; // Custom function for ts-lora -pub async fn get_channel_index( - dev_eui: EUI64, -) -> Result { +pub async fn get_channel_index(dev_eui: EUI64) -> Result { let mut db_conn = get_async_db_conn().await?; // Query to find the multicast group ID for the given dev_eui @@ -38,14 +37,21 @@ pub async fn get_channel_index( .select(multicast_group_device::dsl::multicast_group_id) .first::(&mut db_conn) .await - .map_err(|e| Error::from_diesel(e, "Error while retrieving multicast group ID".to_string()))?; + .map_err(|e| { + Error::from_diesel(e, "Error while retrieving multicast group ID".to_string()) + })?; let counter = multicast_group::table .filter(multicast_group::dsl::id.eq(id)) .select(multicast_group::dsl::f_cnt) .first::(&mut db_conn) .await - .map_err(|e| Error::from_diesel(e, "Error while retrieving frame counter from Multicast Group".to_string()))?; + .map_err(|e| { + Error::from_diesel( + e, + "Error while retrieving frame counter from Multicast Group".to_string(), + ) + })?; let channel_index = generate_channel(counter, SECRET_KEY, id); @@ -63,11 +69,7 @@ fn generate_channel(asn: i64, key: &[u8], offset_uuid: Uuid) -> usize { let msb_3 = (hash_bytes[0] >> 5) as usize; // Calculate OFFSET_j' using the UUID bytes. - let sum_uuid_bytes: u64 = offset_uuid - .as_bytes() - .iter() - .map(|&b| b as u64) - .sum(); + let sum_uuid_bytes: u64 = offset_uuid.as_bytes().iter().map(|&b| b as u64).sum(); let offset_j_prime = ((sum_uuid_bytes as i64 + asn) % 8) as usize; // Convert OFFSET_j' to binary. @@ -80,8 +82,6 @@ fn generate_channel(asn: i64, key: &[u8], offset_uuid: Uuid) -> usize { let x_1 = (msb_3 >> 1) & 0b1; let x_2 = msb_3 & 0b1; - // Calculate the channel. - let ch_j = (x_0 ^ b_0) << 2 | (x_1 ^ b_1) << 1 | (x_2 ^ b_2); - - ch_j -} \ No newline at end of file + // Calculate and return the channel. + (x_0 ^ b_0) << 2 | (x_1 ^ b_1) << 1 | (x_2 ^ b_2) +} diff --git a/chirpstack/src/storage/mod.rs b/chirpstack/src/storage/mod.rs index 9e817477..10035b46 100644 --- a/chirpstack/src/storage/mod.rs +++ b/chirpstack/src/storage/mod.rs @@ -23,11 +23,11 @@ pub mod application; pub mod device; pub mod device_gateway; pub mod device_keys; -pub mod device_slot; pub mod device_profile; pub mod device_profile_template; pub mod device_queue; pub mod device_session; +pub mod device_slot; pub mod downlink_frame; pub mod error; pub mod fields; diff --git a/chirpstack/src/storage/schema.rs b/chirpstack/src/storage/schema.rs index 6e7bab9e..3dd4b71c 100644 --- a/chirpstack/src/storage/schema.rs +++ b/chirpstack/src/storage/schema.rs @@ -84,7 +84,7 @@ diesel::table! { device_slot (dev_eui) { dev_eui -> Bytea, dev_addr -> Nullable, - slot -> Nullable, + slot -> Nullable, multicast_group_id -> Uuid, created_at -> Timestamptz, } diff --git a/chirpstack/src/uplink/join.rs b/chirpstack/src/uplink/join.rs index 5cc376b4..f98e7391 100644 --- a/chirpstack/src/uplink/join.rs +++ b/chirpstack/src/uplink/join.rs @@ -801,7 +801,10 @@ impl JoinRequest { device_profile.reset_session_to_boot_params(&mut ds); - println!("in set_device_session: enabled channels for device {}", device.dev_eui); + println!( + "in set_device_session: enabled channels for device {}", + device.dev_eui + ); for ch in ds.enabled_uplink_channel_indices.clone().into_iter() { println!("{}", ch); } diff --git a/lrwn/src/devaddr.rs b/lrwn/src/devaddr.rs index 5358f2be..c1376460 100644 --- a/lrwn/src/devaddr.rs +++ b/lrwn/src/devaddr.rs @@ -199,18 +199,18 @@ impl DevAddr { // pub fn set_dev_addr_prefix_and_slot(&mut self, prefix: DevAddrPrefix, slot: i32) { // // convert devaddr to u32 // let mut devaddr = u32::from_be_bytes(self.0); - + // // Clean the prefix bits and the slot area (11 least significant bits) // let prefix_size = prefix.size(); // number of bits in prefix // let mask = (u32::MAX >> prefix_size) << 11; // clears bits for prefix and the 11 bit slot // devaddr &= !mask; - + // // Set the prefix // devaddr |= u32::from_be_bytes(prefix.prefix()); - + // // Set the slot in the 11 least significant bits // devaddr |= (slot as u32) & 0x07FF; // ensure slot is within 11 bits - + // self.0 = devaddr.to_be_bytes(); // } @@ -275,7 +275,6 @@ impl Iterator for DevAddrIntoIterator { } } - impl fmt::Display for DevAddr { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", hex::encode(self.0)) diff --git a/lrwn/src/region/eu868.rs b/lrwn/src/region/eu868.rs index a0748640..7ed400e9 100644 --- a/lrwn/src/region/eu868.rs +++ b/lrwn/src/region/eu868.rs @@ -784,7 +784,9 @@ impl Region for Configuration { device_enabled_channels: &[usize], ) -> Vec { self.base - .custom_get_link_adr_req_payloads_for_enabled_uplink_channel_indices(device_enabled_channels) + .custom_get_link_adr_req_payloads_for_enabled_uplink_channel_indices( + device_enabled_channels, + ) } fn get_enabled_uplink_channel_indices_for_link_adr_payloads( From 067bca67b81dffa848f8d2e0f6a7d8b263bf8a83 Mon Sep 17 00:00:00 2001 From: user Date: Sun, 28 Jul 2024 00:02:36 +0500 Subject: [PATCH 2/9] Readme and Makefile streamlined --- Makefile | 17 +++++++++++++++++ README.md | 8 ++++++++ 2 files changed, 25 insertions(+) diff --git a/Makefile b/Makefile index 9a7fc35c..1404a0dd 100644 --- a/Makefile +++ b/Makefile @@ -72,3 +72,20 @@ test-all: cd chirpstack-integration && cargo test cd lrwn && make test cd lrwn-filters && make test + +# does everything above +compile-everything: + cd api && make grpc-web + cd ui && make build + docker compose up -d && + cd api && make rust + cd backend && cargo test + cd chirpstack && make test + cd lrwn && make test + cd lrwn-filters && make test + cargo install cross --version 0.2.5 + cargo install diesel_cli --version 2.1.1 --no-default-features --features postgres + cargo install cargo-deb --version 1.43.1 + cargo install cargo-generate-rpm --version 0.12.1 + cd api && make grpc-web + cd chirpstack && make dist diff --git a/README.md b/README.md index 9fd2e58e..d47163ef 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,14 @@ Or if you do not have Nix installed, execute the following command: make docker-devshell ``` +### Do everything below + +If you want to automatically do all the steps below with make dist, enter this command: + +```bash +make compile-everything +``` + ### Building the UI To build the ChirpStack UI, execute the following command: From 1fdd86de207d372b805a1a62a40b57b3e9c6a84a Mon Sep 17 00:00:00 2001 From: user Date: Sun, 28 Jul 2024 00:19:01 +0500 Subject: [PATCH 3/9] remove a redundant loop --- Makefile | 2 +- chirpstack/src/devaddr.rs | 35 ++++++++++++++++------------------- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/Makefile b/Makefile index 1404a0dd..000d7177 100644 --- a/Makefile +++ b/Makefile @@ -77,7 +77,7 @@ test-all: compile-everything: cd api && make grpc-web cd ui && make build - docker compose up -d && + docker compose up -d cd api && make rust cd backend && cargo test cd chirpstack && make test diff --git a/chirpstack/src/devaddr.rs b/chirpstack/src/devaddr.rs index 8c28955c..da45d564 100644 --- a/chirpstack/src/devaddr.rs +++ b/chirpstack/src/devaddr.rs @@ -226,25 +226,22 @@ pub fn get_random_dev_addr() -> DevAddr { let generated_slot: u32 = sum % NUMBER_OF_SLOTS; // regenerate the dev_addr until the correct one is generated. - loop { - unsafe { - match CURRENT_SLOT == generated_slot { - true => { - // define the next time slot to generate - CURRENT_SLOT = CURRENT_SLOT + 1; - // print the generated time slot and devaddr value - println!( - "{:?} connected, time slot is: {}", - dev_addr.clone(), - generated_slot - ); - break; - } - false => { - return get_random_dev_addr(); - } - }; - } + unsafe { + match CURRENT_SLOT == generated_slot { + true => { + // define the next time slot to generate + CURRENT_SLOT = CURRENT_SLOT + 1; + // print the generated time slot and devaddr value + println!( + "{:?} connected, time slot is: {}", + dev_addr.clone(), + generated_slot + ); + } + false => { + return get_random_dev_addr(); + } + }; } dev_addr } From 476b4b90f4bdf0dd78df08ebdfd2af89e98cf77a Mon Sep 17 00:00:00 2001 From: Aidar <98528915+mrBluestSky@users.noreply.github.com> Date: Tue, 3 Sep 2024 17:15:55 +0500 Subject: [PATCH 4/9] Update tenant.rs --- chirpstack/src/api/tenant.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/chirpstack/src/api/tenant.rs b/chirpstack/src/api/tenant.rs index a3966251..e947c822 100644 --- a/chirpstack/src/api/tenant.rs +++ b/chirpstack/src/api/tenant.rs @@ -6,6 +6,8 @@ use uuid::Uuid; use chirpstack_api::api; use chirpstack_api::api::tenant_service_server::TenantService; +// ./chirpstack/src/api/auth/validator.rs is super::auth::validator +// validator::RequestValidator is an empty struct with lots of traits connected to databases use super::auth::{validator, AuthID}; use super::error::ToStatus; use super::helpers; @@ -23,6 +25,7 @@ impl Tenant { #[tonic::async_trait] impl TenantService for Tenant { + // I guess this function creates an instance of a tenant async fn create( &self, request: Request, From 807298b3f5bd9612daf791c6be5ea4216a83178c Mon Sep 17 00:00:00 2001 From: Aidar <98528915+mrBluestSky@users.noreply.github.com> Date: Tue, 3 Sep 2024 17:32:36 +0500 Subject: [PATCH 5/9] Update devaddr.rs Remove unneeded code --- chirpstack/src/devaddr.rs | 78 +-------------------------------------- 1 file changed, 2 insertions(+), 76 deletions(-) diff --git a/chirpstack/src/devaddr.rs b/chirpstack/src/devaddr.rs index da45d564..aa80befc 100644 --- a/chirpstack/src/devaddr.rs +++ b/chirpstack/src/devaddr.rs @@ -20,10 +20,10 @@ use crate::storage::schema::{ }; use crate::storage::{get_async_db_conn, AsyncPgPoolConnection}; -const NUMBER_OF_SLOTS: u32 = 64; -static mut CURRENT_SLOT: u32 = 0; pub async fn get_random_dev_addr_slot(dev_eui: EUI64) -> Result { + // The function get_async_db_conn() is defined in ./chirpstack/src/storage/mod.rs + // let mut conn = get_async_db_conn().await?; // Fetch multicast group ID and max slot count @@ -171,77 +171,3 @@ fn generate_dev_addr() -> DevAddr { dev_addr } - -// Old implementation -// project/chirpstack/src/devaddr.rs -pub fn get_random_dev_addr() -> DevAddr { - // check whether we still have any time slots left - unsafe { - // old implementation, panic if I run out of time slots - /* - if CURRENT_SLOT == NUMBER_OF_SLOTS { - panic!("no free time slots left!"); - }*/ - - // new implementation, counts slots from zero - if CURRENT_SLOT == NUMBER_OF_SLOTS { - CURRENT_SLOT = 0; - } - } - - let conf = config::get(); - let mut rng = rand::thread_rng(); - - // Get configured DevAddr prefixes. - let prefixes = if conf.network.dev_addr_prefixes.is_empty() { - vec![conf.network.net_id.dev_addr_prefix()] - } else { - conf.network.dev_addr_prefixes.clone() - }; - - // Pick a random one (in case multiple prefixes are configured). - let prefix = *prefixes.choose(&mut rng).unwrap(); - - // Generate random DevAddr. - let mut dev_addr: [u8; 4] = [0; 4]; - rng.fill_bytes(&mut dev_addr); - #[cfg(test)] - { - dev_addr = [1, 2, 3, 4]; - } - let mut dev_addr = DevAddr::from_be_bytes(dev_addr); - - // Set DevAddr prefix. - dev_addr.set_dev_addr_prefix(prefix); - - // print DevAddr as 4 integers - //dbg!(dev_addr.clone()); - // print the address prefix (AddrPrefix) - //dbg!(prefix); - - // find the slot of the DevAddr - - // hash function - let sum: u32 = dev_addr.clone().into_iter().map(|x| x as u32).sum(); - let generated_slot: u32 = sum % NUMBER_OF_SLOTS; - - // regenerate the dev_addr until the correct one is generated. - unsafe { - match CURRENT_SLOT == generated_slot { - true => { - // define the next time slot to generate - CURRENT_SLOT = CURRENT_SLOT + 1; - // print the generated time slot and devaddr value - println!( - "{:?} connected, time slot is: {}", - dev_addr.clone(), - generated_slot - ); - } - false => { - return get_random_dev_addr(); - } - }; - } - dev_addr -} From b55a3a41b297435cc0a96e6e4e01ef77ed8845ed Mon Sep 17 00:00:00 2001 From: Aidar <98528915+mrBluestSky@users.noreply.github.com> Date: Wed, 4 Sep 2024 13:21:01 +0500 Subject: [PATCH 6/9] Update devaddr.rs, add comment Code is easier to understand thanks to few new comments --- chirpstack/src/devaddr.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/chirpstack/src/devaddr.rs b/chirpstack/src/devaddr.rs index aa80befc..9c7bd4cb 100644 --- a/chirpstack/src/devaddr.rs +++ b/chirpstack/src/devaddr.rs @@ -20,10 +20,10 @@ use crate::storage::schema::{ }; use crate::storage::{get_async_db_conn, AsyncPgPoolConnection}; - +// this is the main caller function in this file that calls other functions below pub async fn get_random_dev_addr_slot(dev_eui: EUI64) -> Result { // The function get_async_db_conn() is defined in ./chirpstack/src/storage/mod.rs - // + // it connects asynchroninously to the program's postgres database in a safe way let mut conn = get_async_db_conn().await?; // Fetch multicast group ID and max slot count @@ -32,6 +32,7 @@ pub async fn get_random_dev_addr_slot(dev_eui: EUI64) -> Result { .select(multicast_group_device::dsl::multicast_group_id) .first(&mut conn) .await?; + // get the total number of time slots stored in the tenant table let max_slot_count = device::table .inner_join(application::table.on(application::dsl::id.eq(device::dsl::application_id))) .inner_join(tenant::table.on(tenant::dsl::id.eq(application::dsl::tenant_id))) @@ -41,11 +42,13 @@ pub async fn get_random_dev_addr_slot(dev_eui: EUI64) -> Result { .await?; // Get current device slot record, if exists + // the datatype of the existing_ds variable is Result. DeviceSlot contains a single record for the device_slot database table. let existing_ds = device_slot::get(&dev_eui).await; let (new_slot, dev_addr): (i32, DevAddr); // Determine if new slot needs to be calculated or reused if let Ok(existing_ds) = existing_ds { + // Check whether a given end device belongs to the multicast group where it used to belong when we last calculate its time-slot? if existing_ds.multicast_group_id == multicast_group_id { // Reuse existing slot and regenerate device address new_slot = existing_ds.slot.expect("Existing slot must be present"); From b4b3ed9369097b38d6c161c06436e72b52da1ec7 Mon Sep 17 00:00:00 2001 From: Aidar <98528915+mrBluestSky@users.noreply.github.com> Date: Wed, 4 Sep 2024 14:41:01 +0500 Subject: [PATCH 7/9] Update device_slot.rs, add comments --- chirpstack/src/storage/device_slot.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/chirpstack/src/storage/device_slot.rs b/chirpstack/src/storage/device_slot.rs index 672649a5..5a735eb9 100644 --- a/chirpstack/src/storage/device_slot.rs +++ b/chirpstack/src/storage/device_slot.rs @@ -35,6 +35,7 @@ impl Default for DeviceSlot { } } +// Creates an record in the device_slot table with a given information about the record in the ds variable pub async fn create(ds: DeviceSlot) -> Result { let ds: DeviceSlot = diesel::insert_into(device_slot::table) .values(&ds) @@ -48,6 +49,7 @@ pub async fn create(ds: DeviceSlot) -> Result { Ok(ds) } +// return a device's time slot for its dev_eui value pub async fn get(dev_eui: &EUI64) -> Result { let ds = device_slot::dsl::device_slot .find(&dev_eui) @@ -57,6 +59,7 @@ pub async fn get(dev_eui: &EUI64) -> Result { Ok(ds) } +// give a new device_slot value for a given end device pub async fn update(ds: DeviceSlot) -> Result { let ds: DeviceSlot = diesel::update(device_slot::dsl::device_slot.find(&ds.dev_eui)) .set(&ds) @@ -70,6 +73,7 @@ pub async fn update(ds: DeviceSlot) -> Result { Ok(ds) } +// delete a device slot instance attached to an end device pub async fn delete(dev_eui: &EUI64) -> Result<(), Error> { let ra = diesel::delete(device_slot::dsl::device_slot.find(&dev_eui)) .execute(&mut get_async_db_conn().await?) From 030362de6964fc984fd7aa29eeb3ee3ceb910617 Mon Sep 17 00:00:00 2001 From: Aidar <98528915+mrBluestSky@users.noreply.github.com> Date: Fri, 6 Sep 2024 12:38:34 +0500 Subject: [PATCH 8/9] Update mod.rs, add comments --- chirpstack/src/uplink/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/chirpstack/src/uplink/mod.rs b/chirpstack/src/uplink/mod.rs index 590cabdd..be10c4c5 100644 --- a/chirpstack/src/uplink/mod.rs +++ b/chirpstack/src/uplink/mod.rs @@ -80,6 +80,7 @@ pub struct RelayContext { } #[derive(Clone)] +// contains a complete data of an uplink frame received from an end device pub struct UplinkFrameSet { pub uplink_set_id: Uuid, pub dr: u8, From 679d3f8e4eef212b840cf59de6ce2a2505113ed9 Mon Sep 17 00:00:00 2001 From: Aidar <98528915+mrBluestSky@users.noreply.github.com> Date: Fri, 6 Sep 2024 13:21:03 +0500 Subject: [PATCH 9/9] Update join.rs add comments --- chirpstack/src/uplink/join.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/chirpstack/src/uplink/join.rs b/chirpstack/src/uplink/join.rs index f98e7391..0e1927f9 100644 --- a/chirpstack/src/uplink/join.rs +++ b/chirpstack/src/uplink/join.rs @@ -53,6 +53,7 @@ pub struct JoinRequest { } impl JoinRequest { + // notify in logs if an error happens while handling a join request pub async fn handle(ufs: UplinkFrameSet) { let span = span!(Level::INFO, "join_request", dev_eui = tracing::field::Empty); @@ -86,6 +87,7 @@ impl JoinRequest { } } + // fill the join request struct with needed data and does needed manipulations to do the join event async fn _handle(ufs: UplinkFrameSet) -> Result<()> { let mut ctx = JoinRequest { uplink_frame_set: ufs,