Skip to content

Commit

Permalink
Seal most wireless traits; implemnent wireless operation with already…
Browse files Browse the repository at this point in the history
… initialized controller
  • Loading branch information
ivmarkov committed Oct 5, 2024
1 parent cf2a8ad commit 4e0805f
Show file tree
Hide file tree
Showing 4 changed files with 177 additions and 69 deletions.
5 changes: 2 additions & 3 deletions src/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ where
)
}

/// Resets the Matter instance to the factory defaults putting it into a
/// Reset the Matter instance to the factory defaults putting it into a
/// Commissionable mode.
pub fn reset(&self) -> Result<(), Error> {
// TODO: Reset fabrics and ACLs
Expand All @@ -103,9 +103,8 @@ where
/// Run the Matter stack for Ethernet network.
///
/// Parameters:
/// - `netif` - a user-provided `Netif` implementation for the Ethernet network
/// - `persist` - a user-provided `Persist` implementation
/// - `netif` - a user-provided `Netif` implementation
/// - `dev_comm` - the commissioning data
/// - `handler` - a user-provided DM handler implementation
/// - `user` - a user-provided future that will be polled only when the netif interface is up
pub async fn run<'d, I, P, H, U>(
Expand Down
5 changes: 5 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ pub mod udp;
pub mod utils;
pub mod wireless;

mod private {
/// A marker super-trait for sealed traits
pub trait Sealed {}
}

const MAX_SUBSCRIPTIONS: usize = 3;
const MAX_IM_BUFFERS: usize = 10;
const MAX_RESPONDERS: usize = 4;
Expand Down
187 changes: 125 additions & 62 deletions src/wireless.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ use rs_matter::transport::network::NoNetwork;
use rs_matter::utils::init::{init, Init};
use rs_matter::utils::select::Coalesce;
use traits::{
ConcurrencyMode, DisconnectedController, Thread, ThreadData, Wifi, WifiData, Wireless,
WirelessConfig, WirelessData, NC,
ConcurrencyMode, ConcurrentWirelessConfig, DisconnectedController, Thread, ThreadData, Wifi,
WifiData, Wireless, WirelessConfig, WirelessData, NC,
};

use crate::netif::{Netif, NetifRun};
Expand Down Expand Up @@ -173,14 +173,65 @@ pub type WifiNCMatterStack<'a, M, E> = MatterStack<'a, WirelessBle<M, Wifi<NC>,
/// Note that Alexa does not (yet) work with non-concurrent commissioning.
pub type ThreadNCMatterStack<'a, M, E> = MatterStack<'a, WirelessBle<M, Thread<NC>, E>>;

impl<'a, M, T, E> MatterStack<'a, WirelessBle<M, T, E>>
where
M: RawMutex + Send + Sync + 'static,
T: ConcurrentWirelessConfig,
<T::Data as WirelessData>::NetworkCredentials: Clone + for<'t> FromTLV<'t> + ToTLV,
E: Embedding + 'static,
{
/// Run the Matter stack for a wireless network which is already initialized.
///
/// Parameters:
/// - `controller` - a user-provided wireless `Controller` implementation
/// - `netif` - a user-provided `Netif` implementation for the wireless network
/// - `ble` - a user-provided `Ble` implementation
/// - `persist` - a user-provided `Persist` implementation
/// - `handler` - a user-provided DM handler implementation
/// - `user` - a user-provided future that will be polled only when the netif interface is up
pub async fn run_with_controller<'d, C, N, B, P, H, U>(
&'static self,
controller: C,
netif: N,
ble: B,
persist: P,
handler: H,
user: U,
) -> Result<(), Error>
where
C: Controller<Data = T::Data>,
<C::Data as WirelessData>::ScanResult: Clone,
<C::Data as WirelessData>::Stats: Default,
N: Netif + UdpBind,
B: Ble,
P: Persist,
H: AsyncHandler + AsyncMetadata,
U: Future<Output = Result<(), Error>>,
{
info!("Matter Stack memory: {}B", core::mem::size_of_val(self));

// TODO persist.load().await?;

self.matter().reset_transport()?;

let mut net_task = pin!(self.run_net_with_controller(controller, netif, ble));
let mut handler_task = pin!(self.run_handlers(persist, handler));
let mut user_task = pin!(user);

select3(&mut net_task, &mut handler_task, &mut user_task)
.coalesce()
.await
}
}

impl<'a, M, T, E> MatterStack<'a, WirelessBle<M, T, E>>
where
M: RawMutex + Send + Sync + 'static,
T: WirelessConfig,
<T::Data as WirelessData>::NetworkCredentials: Clone + for<'t> FromTLV<'t> + ToTLV,
E: Embedding + 'static,
{
/// Resets the Matter instance to the factory defaults putting it into a
/// Reset the Matter instance to the factory defaults putting it into a
/// Commissionable mode.
pub fn reset(&self) -> Result<(), Error> {
// TODO: Reset fabrics and ACLs
Expand All @@ -191,6 +242,14 @@ where
Ok(())
}

/// Run the Matter stack for a wireless network.
///
/// Parameters:
/// - `wireless` - a user-provided `Wireless` implementation
/// - `ble` - a user-provided `Ble` implementation
/// - `persist` - a user-provided `Persist` implementation
/// - `handler` - a user-provided DM handler implementation
/// - `user` - a user-provided future that will be polled only when the netif interface is up
pub async fn run<'d, W, B, P, H, U>(
&'static self,
wireless: W,
Expand All @@ -200,10 +259,10 @@ where
user: U,
) -> Result<(), Error>
where
B: Ble,
W: Wireless<Data = T::Data>,
<W::Data as WirelessData>::ScanResult: Clone,
<W::Data as WirelessData>::Stats: Default,
B: Ble,
P: Persist,
H: AsyncHandler + AsyncMetadata,
U: Future<Output = Result<(), Error>>,
Expand Down Expand Up @@ -231,67 +290,11 @@ where
<W::Data as WirelessData>::Stats: Default,
{
if T::CONCURRENT {
let (netif, mut controller) = wireless.start().await?;

let mut mgr = WirelessManager::new(&self.network.network_context.controller_proxy);
let (netif, controller) = wireless.start().await?;

info!("Wireless driver started");

loop {
let commissioned = self.is_commissioned().await?;

if !commissioned {
self.matter()
.enable_basic_commissioning(DiscoveryCapabilities::BLE, 0)
.await?; // TODO

let btp = Btp::new(ble.start().await?, &self.network.btp_context);

info!("BLE driver started");

let mut netif_task = pin!(netif.run());
let mut net_task = pin!(self.run_comm_net(&netif, &btp));
let mut mgr_task = pin!(mgr.run(&self.network.network_context));
let mut proxy_task = pin!(self
.network
.network_context
.controller_proxy
.process_with(&mut controller)?);

select4(
&mut netif_task,
&mut net_task,
&mut mgr_task,
&mut proxy_task,
)
.coalesce()
.await?;
} else {
self.matter().disable_commissioning()?;

let mut netif_task = pin!(netif.run());
let mut net_task = pin!(self.run_oper_net(
&netif,
core::future::pending(),
Option::<(NoNetwork, NoNetwork)>::None
));
let mut mgr_task = pin!(mgr.run(&self.network.network_context));
let mut proxy_task = pin!(self
.network
.network_context
.controller_proxy
.process_with(&mut controller)?);

select4(
&mut netif_task,
&mut net_task,
&mut mgr_task,
&mut proxy_task,
)
.coalesce()
.await?;
}
}
self.run_net_with_controller(controller, netif, ble).await
} else {
loop {
let commissioned = self.is_commissioned().await?;
Expand Down Expand Up @@ -343,6 +346,66 @@ where
}
}

async fn run_net_with_controller<'d, C, N, B>(
&'static self,
mut controller: C,
netif: N,
mut ble: B,
) -> Result<(), Error>
where
C: Controller<Data = T::Data>,
N: Netif + UdpBind,
B: Ble,
<C::Data as WirelessData>::ScanResult: Clone,
<C::Data as WirelessData>::Stats: Default,
{
let mut mgr = WirelessManager::new(&self.network.network_context.controller_proxy);

loop {
let commissioned = self.is_commissioned().await?;

if !commissioned {
self.matter()
.enable_basic_commissioning(DiscoveryCapabilities::BLE, 0)
.await?; // TODO

let btp = Btp::new(ble.start().await?, &self.network.btp_context);

info!("BLE driver started");

let mut net_task = pin!(self.run_comm_net(&netif, &btp));
let mut mgr_task = pin!(mgr.run(&self.network.network_context));
let mut proxy_task = pin!(self
.network
.network_context
.controller_proxy
.process_with(&mut controller)?);

select3(&mut net_task, &mut mgr_task, &mut proxy_task)
.coalesce()
.await?;
} else {
self.matter().disable_commissioning()?;

let mut net_task = pin!(self.run_oper_net(
&netif,
core::future::pending(),
Option::<(NoNetwork, NoNetwork)>::None
));
let mut mgr_task = pin!(mgr.run(&self.network.network_context));
let mut proxy_task = pin!(self
.network
.network_context
.controller_proxy
.process_with(&mut controller)?);

select3(&mut net_task, &mut mgr_task, &mut proxy_task)
.coalesce()
.await?;
}
}
}

async fn run_comm_net<'d, N, B>(
&self,
mut netif: N,
Expand Down
Loading

0 comments on commit 4e0805f

Please sign in to comment.