Skip to content

Commit

Permalink
Merge pull request #23 from badrbouslikhin/main
Browse files Browse the repository at this point in the history
feat: support publish retransmit
  • Loading branch information
Ulf Lilleengen authored Nov 22, 2023
2 parents d93b61e + 3ebefb7 commit 9ced9b4
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 14 deletions.
34 changes: 33 additions & 1 deletion btmesh-device/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -56,6 +58,7 @@ pub enum InboundBody {
pub enum Control {
Shutdown,
PublicationCadence(PublicationCadence),
PublicationRetransmission(PublicationRetransmission),
}

#[cfg_attr(feature = "defmt", derive(defmt::Format))]
Expand All @@ -82,6 +85,33 @@ impl From<PublishPeriod> 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<PublishRetransmit> 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<u8, 380>,
Expand Down Expand Up @@ -383,12 +413,14 @@ impl From<ApplicationKeyHandle> 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,
}
}
}
28 changes: 27 additions & 1 deletion btmesh-driver/src/dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand All @@ -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<InboundPayload> = AccessCounted::new();
49 changes: 45 additions & 4 deletions btmesh-driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -523,29 +524,55 @@ 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,
)
.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;
}
}
}
Expand All @@ -556,14 +583,28 @@ 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,
)
.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;
}
}
}
}
Expand Down
6 changes: 4 additions & 2 deletions btmesh-driver/src/storage/provisioned/publications.rs
Original file line number Diff line number Diff line change
@@ -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,
};
Expand Down Expand Up @@ -30,11 +31,12 @@ impl<const N: usize> Publications<N> {
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)
);
}
}
Expand Down
29 changes: 23 additions & 6 deletions btmesh-models/src/foundation/configuration/model_publication.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
}
}

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

0 comments on commit 9ced9b4

Please sign in to comment.