Skip to content

Commit

Permalink
Register Wifi NW clusters for the WifiBle stack
Browse files Browse the repository at this point in the history
  • Loading branch information
ivmarkov committed Apr 30, 2024
1 parent e2475b5 commit ca59b1c
Show file tree
Hide file tree
Showing 4 changed files with 363 additions and 16 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,13 +189,13 @@ If the provided `MatterStack` does not cut it, users can implement their own sta
* Thread networking (for ESP32H2 and ESP32C6)
* Wifi Access-Point based commissioning (for ESP32S2 which does not have Bluetooth support)

#### Additional building blocks provided by `rs-matter` and compatible with ESP IDF:
#### Additional building blocks provided by `rs-matter` directly and compatible with ESP IDF:
* UDP and (in future) TCP support
* Enable the [`async-io`]() and [`std`] features on `rs-matter` and use `async-io` sockets. The `async-io` crate has support for ESP IDF out of the box
* Enable the `async-io` and `std` features on `rs-matter` and use `async-io` sockets. The [`async-io`](https://github.com/smol-rs/async-io) crate has support for ESP IDF out of the box
* Random number generator
* Enable the [`std`] feature on `rs-matter`. This way, the [`rng`]() crate will be utilized, which has support for ESP IDF out of the box
* Enable the `std` feature on `rs-matter`. This way, the [`rand`](https://github.com/rust-random/rand) crate will be utilized, which has support for ESP IDF out of the box
* UNIX epoch
* Enable the [`std`] feature on `rs-matter`. This way, the [`rng`]() crate will be utilized, which has support for ESP IDF out of the box
* Enable the `std` feature on `rs-matter`. This way, `rs-matter` will utilize `std::time::SystemTime` which is supported by ESP IDF out of the box

## Build Prerequisites

Expand Down
161 changes: 155 additions & 6 deletions src/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,8 @@ impl<'a> MatterStack<'a, Eth> {
esp_idf_bt_bluedroid_enabled
))]
mod wifible {
use core::borrow::Borrow;
use core::cell::RefCell;
use core::pin::pin;

use embassy_futures::select::select;
Expand All @@ -299,17 +301,43 @@ mod wifible {
use esp_idf_svc::timer::EspTaskTimerService;
use esp_idf_svc::wifi::{AsyncWifi, EspWifi};

use rs_matter::data_model::objects::{AsyncHandler, AsyncMetadata, Endpoint};
use rs_matter::data_model::root_endpoint::{self, RootEndpointHandler};
use rs_matter::acl::AclMgr;
use rs_matter::data_model::cluster_basic_information::{
self, BasicInfoCluster, BasicInfoConfig,
};
use rs_matter::data_model::objects::{
AsyncHandler, AsyncMetadata, Cluster, EmptyHandler, Endpoint,
};
use rs_matter::data_model::sdm::admin_commissioning::AdminCommCluster;
use rs_matter::data_model::sdm::dev_att::DevAttDataFetcher;
use rs_matter::data_model::sdm::failsafe::FailSafe;
use rs_matter::data_model::sdm::general_commissioning::GenCommCluster;
use rs_matter::data_model::sdm::general_diagnostics::GenDiagCluster;
use rs_matter::data_model::sdm::group_key_management::GrpKeyMgmtCluster;
use rs_matter::data_model::sdm::noc::NocCluster;
use rs_matter::data_model::sdm::{
admin_commissioning, general_commissioning, general_diagnostics, group_key_management, noc,
nw_commissioning,
};
use rs_matter::data_model::system_model::access_control::AccessControlCluster;
use rs_matter::data_model::system_model::descriptor::DescriptorCluster;
use rs_matter::data_model::system_model::{access_control, descriptor};
use rs_matter::fabric::FabricMgr;
use rs_matter::mdns::Mdns;
use rs_matter::pairing::DiscoveryCapabilities;
use rs_matter::secure_channel::pake::PaseMgr;
use rs_matter::transport::network::btp::{Btp, BtpContext};
use rs_matter::utils::epoch::Epoch;
use rs_matter::utils::rand::Rand;
use rs_matter::utils::select::Coalesce;
use rs_matter::CommissioningData;
use rs_matter::{handler_chain_type, CommissioningData};

use crate::ble::{BtpGattContext, BtpGattPeripheral};
use crate::error::Error;
use crate::wifi::comm::WifiNwCommCluster;
use crate::wifi::diag::WifiNwDiagCluster;
use crate::wifi::mgmt::WifiManager;
use crate::wifi::WifiContext;
use crate::wifi::{comm, diag, WifiContext};
use crate::{MatterStack, Network};

pub struct WifiBle {
Expand All @@ -334,11 +362,15 @@ mod wifible {

impl<'a> MatterStack<'a, WifiBle> {
pub const fn root_metadata() -> Endpoint<'static> {
root_endpoint::endpoint(0)
Endpoint {
id: 0,
device_type: rs_matter::data_model::device_types::DEV_TYPE_ROOT_NODE,
clusters: &CLUSTERS,
}
}

pub fn root_handler(&self) -> RootEndpointHandler<'_> {
root_endpoint::handler(0, self.matter())
handler(0, self.matter(), &self.network.wifi_context)
}

pub async fn is_commissioned(&self, _nvs: EspDefaultNvsPartition) -> Result<bool, Error> {
Expand Down Expand Up @@ -443,4 +475,121 @@ mod wifible {
}
}
}

pub type RootEndpointHandler<'a> = handler_chain_type!(
descriptor::DescriptorCluster<'static>,
cluster_basic_information::BasicInfoCluster<'a>,
general_commissioning::GenCommCluster<'a>,
comm::WifiNwCommCluster<'a, 3, NoopRawMutex>,
admin_commissioning::AdminCommCluster<'a>,
noc::NocCluster<'a>,
access_control::AccessControlCluster<'a>,
general_diagnostics::GenDiagCluster,
diag::WifiNwDiagCluster,
group_key_management::GrpKeyMgmtCluster
);

const CLUSTERS: [Cluster<'static>; 10] = [
descriptor::CLUSTER,
cluster_basic_information::CLUSTER,
general_commissioning::CLUSTER,
nw_commissioning::WIFI_CLUSTER,
admin_commissioning::CLUSTER,
noc::CLUSTER,
access_control::CLUSTER,
general_diagnostics::CLUSTER,
diag::CLUSTER,
group_key_management::CLUSTER,
];

fn handler<'a, T>(
endpoint_id: u16,
matter: &'a T,
networks: &'a WifiContext<3, NoopRawMutex>,
) -> RootEndpointHandler<'a>
where
T: Borrow<BasicInfoConfig<'a>>
+ Borrow<dyn DevAttDataFetcher + 'a>
+ Borrow<RefCell<PaseMgr>>
+ Borrow<RefCell<FabricMgr>>
+ Borrow<RefCell<AclMgr>>
+ Borrow<RefCell<FailSafe>>
+ Borrow<dyn Mdns + 'a>
+ Borrow<Epoch>
+ Borrow<Rand>
+ 'a,
{
wrap(
endpoint_id,
matter.borrow(),
matter.borrow(),
matter.borrow(),
matter.borrow(),
matter.borrow(),
matter.borrow(),
matter.borrow(),
*matter.borrow(),
*matter.borrow(),
networks,
)
}

#[allow(clippy::too_many_arguments)]
fn wrap<'a>(
endpoint_id: u16,
basic_info: &'a BasicInfoConfig<'a>,
dev_att: &'a dyn DevAttDataFetcher,
pase: &'a RefCell<PaseMgr>,
fabric: &'a RefCell<FabricMgr>,
acl: &'a RefCell<AclMgr>,
failsafe: &'a RefCell<FailSafe>,
mdns: &'a dyn Mdns,
epoch: Epoch,
rand: Rand,
networks: &'a WifiContext<3, NoopRawMutex>,
) -> RootEndpointHandler<'a> {
EmptyHandler
.chain(
endpoint_id,
group_key_management::ID,
GrpKeyMgmtCluster::new(rand),
)
.chain(endpoint_id, diag::ID, WifiNwDiagCluster::new(rand))
.chain(
endpoint_id,
general_diagnostics::ID,
GenDiagCluster::new(rand),
)
.chain(
endpoint_id,
access_control::ID,
AccessControlCluster::new(acl, rand),
)
.chain(
endpoint_id,
noc::ID,
NocCluster::new(dev_att, fabric, acl, failsafe, mdns, epoch, rand),
)
.chain(
endpoint_id,
admin_commissioning::ID,
AdminCommCluster::new(pase, mdns, rand),
)
.chain(
endpoint_id,
nw_commissioning::ID,
WifiNwCommCluster::new(rand, networks),
)
.chain(
endpoint_id,
general_commissioning::ID,
GenCommCluster::new(failsafe, rand),
)
.chain(
endpoint_id,
cluster_basic_information::ID,
BasicInfoCluster::new(basic_info, rand),
)
.chain(endpoint_id, descriptor::ID, DescriptorCluster::new(rand))
}
}
10 changes: 5 additions & 5 deletions src/wifi/comm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ use rs_matter::utils::rand::Rand;

use super::{WifiContext, WifiCredentials};

pub struct WifiCommCluster<'a, const N: usize, M>
pub struct WifiNwCommCluster<'a, const N: usize, M>
where
M: RawMutex,
{
data_ver: Dataver,
networks: &'a WifiContext<N, M>,
}

impl<'a, const N: usize, M> WifiCommCluster<'a, N, M>
impl<'a, const N: usize, M> WifiNwCommCluster<'a, N, M>
where
M: RawMutex,
{
Expand Down Expand Up @@ -377,7 +377,7 @@ where
}
}

impl<'a, const N: usize, M> AsyncHandler for WifiCommCluster<'a, N, M>
impl<'a, const N: usize, M> AsyncHandler for WifiNwCommCluster<'a, N, M>
where
M: RawMutex,
{
Expand All @@ -386,7 +386,7 @@ where
attr: &'m AttrDetails<'_>,
encoder: AttrDataEncoder<'m, '_, '_>,
) -> Result<(), Error> {
WifiCommCluster::read(self, attr, encoder).await
WifiNwCommCluster::read(self, attr, encoder).await
}

async fn invoke<'m>(
Expand All @@ -396,7 +396,7 @@ where
data: &'m TLVElement<'_>,
encoder: CmdDataEncoder<'m, '_, '_>,
) -> Result<(), Error> {
WifiCommCluster::invoke(self, exchange, cmd, data, encoder).await
WifiNwCommCluster::invoke(self, exchange, cmd, data, encoder).await
}
}

Expand Down
Loading

0 comments on commit ca59b1c

Please sign in to comment.