From 6607d971a087b8b6ee65bb9faa8751c9eef6d654 Mon Sep 17 00:00:00 2001 From: Trompettesib Date: Tue, 21 Nov 2023 16:26:59 +0100 Subject: [PATCH 1/4] fix(btmesh-models): change PublishRetransmit count and interval_steps parsing --- .../configuration/model_publication.rs | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/btmesh-models/src/foundation/configuration/model_publication.rs b/btmesh-models/src/foundation/configuration/model_publication.rs index 9114f8a..c657145 100644 --- a/btmesh-models/src/foundation/configuration/model_publication.rs +++ b/btmesh-models/src/foundation/configuration/model_publication.rs @@ -432,7 +432,7 @@ impl PublishRetransmit { /// Creates new publish retransmit using count and steps. pub fn new(count: u8, interval_steps: u8) -> Self { Self { - retransmit: (count << 5) | (interval_steps & 0b00011111), + retransmit: (interval_steps << 3) | (count & 0b00000111), } } /// Creates new publish period from u8. @@ -442,12 +442,12 @@ impl PublishRetransmit { /// Returns publish retransmit count. pub fn count(&self) -> u8 { - self.retransmit >> 5 + self.retransmit & 0b00000111 } /// Returns publish retransmit steps. pub fn interval_steps(&self) -> u8 { - self.retransmit & 0b00011111 + self.retransmit >> 3 } } @@ -522,10 +522,27 @@ mod tests { #[test] fn test_retransmit() { - let rxt = PublishRetransmit::from(0xa0); - assert_eq!(rxt.count(), 5); + let rxt = PublishRetransmit::new(0, 0); + assert_eq!(rxt.count(), 0); assert_eq!(rxt.interval_steps(), 0); + assert_eq!(u8::from(rxt), 0b00000000); - assert_eq!(u8::from(rxt), 0b10100000); + let rxt2 = PublishRetransmit::new(5, 1); + assert_eq!(rxt2.count(), 5); + assert_eq!(rxt2.interval_steps(), 1); + assert_eq!(u8::from(rxt2), 0b00001101); + + let rxt3 = PublishRetransmit::new(7, 31); + assert_eq!(rxt3.count(), 7); + assert_eq!(rxt3.interval_steps(), 31); + assert_eq!(u8::from(rxt3), 0b11111111); + + let rxt4 = PublishRetransmit::from(0b00000001); + assert_eq!(rxt4.count(), 1); + assert_eq!(rxt4.interval_steps(), 0); + + let rxt5 = PublishRetransmit::from(0b00001001); + assert_eq!(rxt5.count(), 1); + assert_eq!(rxt5.interval_steps(), 1); } } From 92e2278d1346977e0924c4a0ed280ffd30aa9d59 Mon Sep 17 00:00:00 2001 From: Trompettesib Date: Tue, 21 Nov 2023 16:47:50 +0100 Subject: [PATCH 2/4] feat(btmesh-device): Add conversion from PublishRetransmit to PublicationRetransmission --- btmesh-device/src/lib.rs | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/btmesh-device/src/lib.rs b/btmesh-device/src/lib.rs index cf80222..ab4e30c 100644 --- a/btmesh-device/src/lib.rs +++ b/btmesh-device/src/lib.rs @@ -18,7 +18,9 @@ pub use btmesh_common::{ ProductIdentifier, VersionIdentifier, }; use btmesh_common::{IvIndex, ParseError, Ttl}; -use btmesh_models::foundation::configuration::model_publication::{PublishPeriod, Resolution}; +use btmesh_models::foundation::configuration::model_publication::{ + PublishPeriod, PublishRetransmit, Resolution, +}; use btmesh_models::foundation::configuration::{AppKeyIndex, NetKeyIndex}; pub use btmesh_models::Model; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; @@ -56,6 +58,7 @@ pub enum InboundBody { pub enum Control { Shutdown, PublicationCadence(PublicationCadence), + PublicationRetransmission(PublicationRetransmission), } #[cfg_attr(feature = "defmt", derive(defmt::Format))] @@ -82,6 +85,33 @@ impl From for PublicationCadence { } } +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[derive(Copy, Clone, Eq, PartialEq)] +pub struct Retransmission { + pub count: u8, + pub interval: Duration, +} + +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[derive(Copy, Clone, Eq, PartialEq)] +pub enum PublicationRetransmission { + None, + RetransmitCountInterval(Retransmission), +} + +impl From for PublicationRetransmission { + fn from(val: PublishRetransmit) -> Self { + if val.count() == 0 { + PublicationRetransmission::None + } else { + PublicationRetransmission::RetransmitCountInterval(Retransmission { + count: val.count(), + interval: Duration::from_millis((val.interval_steps() as u64 + 1) * 50), + }) + } + } +} + pub struct InboundMessage { pub opcode: Opcode, pub parameters: Vec, @@ -383,12 +413,14 @@ impl From for AppKeyIndex { pub struct CompositionExtra { pub publication_cadence: PublicationCadence, + pub publication_retransmission: PublicationRetransmission, } impl Default for CompositionExtra { fn default() -> Self { Self { publication_cadence: PublicationCadence::None, + publication_retransmission: PublicationRetransmission::None, } } } From 97ee4e6a3e22c79c3b9fa00b972330ad5f3f3463 Mon Sep 17 00:00:00 2001 From: Trompettesib Date: Tue, 21 Nov 2023 17:00:48 +0100 Subject: [PATCH 3/4] feat(btmesh-driver): introduce separate dispatch methods for publication cadence and retransmission --- btmesh-driver/src/dispatch.rs | 28 +++++++++++++++++++- btmesh-driver/src/lib.rs | 49 ++++++++++++++++++++++++++++++++--- 2 files changed, 72 insertions(+), 5 deletions(-) diff --git a/btmesh-driver/src/dispatch.rs b/btmesh-driver/src/dispatch.rs index f376d1d..91155c7 100644 --- a/btmesh-driver/src/dispatch.rs +++ b/btmesh-driver/src/dispatch.rs @@ -5,6 +5,7 @@ use btmesh_common::{ModelIdentifier, Seq}; use btmesh_device::access_counted::AccessCounted; use btmesh_device::{ Control, InboundBody, InboundChannelSender, InboundMessage, InboundPayload, PublicationCadence, + PublicationRetransmission, }; use btmesh_models::foundation::configuration::ConfigurationServer; use btmesh_models::Model; @@ -142,7 +143,7 @@ impl Dispatcher { Ok(()) } - pub async fn dispatch_publish( + pub async fn dispatch_publish_cadence( &self, element_index: u8, model_identifier: ModelIdentifier, @@ -166,6 +167,31 @@ impl Dispatcher { PAYLOAD.wait().await; } } + + pub async fn dispatch_publish_retransmission( + &self, + element_index: u8, + model_identifier: ModelIdentifier, + retransmission: PublicationRetransmission, + ) { + unsafe { + PAYLOAD.set(InboundPayload { + element_index: element_index as usize, + model_identifier: Some(model_identifier), + body: InboundBody::Control(Control::PublicationRetransmission(retransmission)), + }); + } + + if element_index == 0 && model_identifier == ConfigurationServer::IDENTIFIER { + self.foundation_sender.send(unsafe { PAYLOAD.get() }).await; + } + + self.device_sender.send(unsafe { PAYLOAD.get() }).await; + + unsafe { + PAYLOAD.wait().await; + } + } } static mut PAYLOAD: AccessCounted = AccessCounted::new(); diff --git a/btmesh-driver/src/lib.rs b/btmesh-driver/src/lib.rs index 116935c..37aeaf7 100644 --- a/btmesh-driver/src/lib.rs +++ b/btmesh-driver/src/lib.rs @@ -13,7 +13,8 @@ use btmesh_common::address::{Address, UnicastAddress}; use btmesh_common::{Composition, Seq, Ttl, Uuid}; use btmesh_device::{ BluetoothMeshDevice, CompletionToken, CompositionExtra, InboundChannel, InboundChannelReceiver, - KeyHandle, OutboundChannel, OutboundExtra, OutboundPayload, PublicationCadence, SendExtra, + KeyHandle, OutboundChannel, OutboundExtra, OutboundPayload, PublicationCadence, + PublicationRetransmission, SendExtra, }; use btmesh_models::foundation::configuration::model_publication::PublishAddress; use btmesh_models::foundation::configuration::CONFIGURATION_SERVER; @@ -523,11 +524,13 @@ impl<'s, N: NetworkInterfaces, R: RngCore + CryptoRng, B: BackingStore> InnerDri { let pub_cadence = PublicationCadence::from(publication.details.publish_period); + let pub_retransmit = + PublicationRetransmission::from(publication.details.publish_retransmit); if model_descriptor.extra.publication_cadence != pub_cadence { self.dispatcher .borrow() - .dispatch_publish( + .dispatch_publish_cadence( element_index as u8, model_descriptor.model_identifier, pub_cadence, @@ -535,17 +538,41 @@ impl<'s, N: NetworkInterfaces, R: RngCore + CryptoRng, B: BackingStore> InnerDri .await; model_descriptor.extra.publication_cadence = pub_cadence; } + if model_descriptor.extra.publication_retransmission != pub_retransmit { + self.dispatcher + .borrow() + .dispatch_publish_retransmission( + element_index as u8, + model_descriptor.model_identifier, + pub_retransmit, + ) + .await; + model_descriptor.extra.publication_retransmission = pub_retransmit; + } } else if model_descriptor.extra.publication_cadence != PublicationCadence::None { self.dispatcher .borrow() - .dispatch_publish( + .dispatch_publish_cadence( element_index as u8, model_descriptor.model_identifier, PublicationCadence::None, ) .await; model_descriptor.extra.publication_cadence = PublicationCadence::None; + } else if model_descriptor.extra.publication_retransmission + != PublicationRetransmission::None + { + self.dispatcher + .borrow() + .dispatch_publish_retransmission( + element_index as u8, + model_descriptor.model_identifier, + PublicationRetransmission::None, + ) + .await; + model_descriptor.extra.publication_retransmission = + PublicationRetransmission::None; } } } @@ -556,7 +583,7 @@ impl<'s, N: NetworkInterfaces, R: RngCore + CryptoRng, B: BackingStore> InnerDri if model_descriptor.extra.publication_cadence != PublicationCadence::None { self.dispatcher .borrow() - .dispatch_publish( + .dispatch_publish_cadence( element_index as u8, model_descriptor.model_identifier, PublicationCadence::None, @@ -564,6 +591,20 @@ impl<'s, N: NetworkInterfaces, R: RngCore + CryptoRng, B: BackingStore> InnerDri .await; model_descriptor.extra.publication_cadence = PublicationCadence::None; } + if model_descriptor.extra.publication_retransmission + != PublicationRetransmission::None + { + self.dispatcher + .borrow() + .dispatch_publish_retransmission( + element_index as u8, + model_descriptor.model_identifier, + PublicationRetransmission::None, + ) + .await; + model_descriptor.extra.publication_retransmission = + PublicationRetransmission::None; + } } } } From 3ebefb77bd6442cfcbba1f00569259457b2a8ca9 Mon Sep 17 00:00:00 2001 From: Trompettesib Date: Tue, 21 Nov 2023 17:01:49 +0100 Subject: [PATCH 4/4] chore(btmesh-driver): enhance debug output in Publications display function --- btmesh-driver/src/storage/provisioned/publications.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/btmesh-driver/src/storage/provisioned/publications.rs b/btmesh-driver/src/storage/provisioned/publications.rs index 52b8bcf..4b0e7cf 100644 --- a/btmesh-driver/src/storage/provisioned/publications.rs +++ b/btmesh-driver/src/storage/provisioned/publications.rs @@ -1,5 +1,6 @@ use crate::DriverError; use btmesh_common::{Composition, ModelIdentifier}; +use btmesh_device::{PublicationCadence, PublicationRetransmission}; use btmesh_models::foundation::configuration::model_publication::{ PublicationDetails, PublishAddress, }; @@ -30,11 +31,12 @@ impl Publications { if let Some(publication) = self.get(index as u8, model_descriptor.model_identifier) { info!( - " {} --> {} {}/{}", + " {} --> {} {} / {} {}", model_descriptor.model_identifier, publication.details.publish_address, publication.details.publish_ttl, - publication.details.publish_period + PublicationCadence::from(publication.details.publish_period), + PublicationRetransmission::from(publication.details.publish_retransmit) ); } }