#![allow(unexpected_cfgs)]
#![recursion_limit = "256"]
fn main() -> Result<(), anyhow::Error> {
#[cfg(any(esp32c6, esp32h2))]
{
example::main()
}
#[cfg(not(any(esp32c6, esp32h2)))]
panic!("This example is only supported on ESP32-C6 and ESP32-H2 chips. Please select a different example or target.");
}
#[cfg(any(esp32c6, esp32h2))]
mod example {
use core::pin::pin;
use alloc::sync::Arc;
use esp_idf_matter::eth::EspEthMatterStack;
use esp_idf_matter::init_async_io;
use esp_idf_matter::matter::crypto::{default_crypto, Crypto};
use esp_idf_matter::matter::dm::clusters::app::on_off::test::TestOnOffDeviceLogic;
use esp_idf_matter::matter::dm::clusters::app::on_off::{self, OnOffHandler, OnOffHooks};
use esp_idf_matter::matter::dm::clusters::desc::{ClusterHandler as _, DescHandler};
use esp_idf_matter::matter::dm::clusters::gen_diag::InterfaceTypeEnum;
use esp_idf_matter::matter::dm::devices::test::{
DAC_PRIVKEY, TEST_DEV_ATT, TEST_DEV_COMM, TEST_DEV_DET,
};
use esp_idf_matter::matter::dm::devices::DEV_TYPE_ON_OFF_LIGHT;
use esp_idf_matter::matter::dm::endpoints::ROOT_ENDPOINT_ID;
use esp_idf_matter::matter::dm::{Async, Dataver, EmptyHandler, Endpoint, Node};
use esp_idf_matter::matter::persist::DummyKvBlobStore;
use esp_idf_matter::matter::utils::init::InitMaybeUninit;
use esp_idf_matter::matter::{clusters, devices};
use esp_idf_matter::netif::{EspMatterNetStack, EspMatterNetif};
use esp_idf_matter::thread::EspMatterThreadSrp;
use esp_idf_svc::eventloop::EspSystemEventLoop;
use esp_idf_svc::hal::peripherals::Peripherals;
use esp_idf_svc::hal::task::block_on;
use esp_idf_svc::hal::task::thread::ThreadSpawnConfiguration;
use esp_idf_svc::io::vfs::MountedEventfs;
use esp_idf_svc::nvs::EspDefaultNvsPartition;
use esp_idf_svc::thread::EspThread;
use log::{error, info};
use static_cell::StaticCell;
extern crate alloc;
const STACK_SIZE: usize = 20 * 1024; const BUMP_SIZE: usize = 17000;
const THREAD_DATASET: &str = env!("THREAD_DATASET");
pub fn main() -> Result<(), anyhow::Error> {
esp_idf_svc::log::init_from_env();
info!("Starting...");
ThreadSpawnConfiguration::set(&ThreadSpawnConfiguration {
name: Some(c"matter"),
..Default::default()
})?;
let thread = std::thread::Builder::new()
.stack_size(STACK_SIZE)
.spawn(run)
.unwrap();
thread.join().unwrap()
}
#[inline(never)]
#[cold]
fn run() -> Result<(), anyhow::Error> {
let result = block_on(matter());
if let Err(e) = &result {
error!("Matter aborted execution with error: {e:?}");
}
{
info!("Matter finished execution successfully");
}
result
}
async fn matter() -> Result<(), anyhow::Error> {
let stack = MATTER_STACK.uninit().init_with(EspEthMatterStack::init(
&TEST_DEV_DET,
TEST_DEV_COMM,
&TEST_DEV_ATT,
));
let sysloop = EspSystemEventLoop::take()?;
let nvs = EspDefaultNvsPartition::take()?;
let peripherals = Peripherals::take()?;
let mounted_event_fs = Arc::new(MountedEventfs::mount(6)?);
init_async_io(mounted_event_fs.clone())?;
let mut thread = EspThread::new(
peripherals.modem,
sysloop.clone(),
nvs.clone(),
mounted_event_fs,
)?;
info!("Thread driver created");
thread.set_tod_hexstr(THREAD_DATASET)?;
info!("Thread dataset set to: {THREAD_DATASET}");
thread.enable_ipv6(true)?;
info!("Thread IPv6 enabled");
thread.enable_thread(true)?;
info!("Thread enabled");
thread.start()?;
info!("Thread started");
let crypto = default_crypto(rand::rng(), DAC_PRIVKEY);
let mut weak_rand = crypto.weak_rand()?;
let on_off = OnOffHandler::new_standalone(
Dataver::new_rand(&mut weak_rand),
LIGHT_ENDPOINT_ID,
TestOnOffDeviceLogic::new(true),
);
let handler = EmptyHandler
.chain(
|e, _| e == ROOT_ENDPOINT_ID,
Async(EspEthMatterStack::<0, ()>::root_handler(
&(),
&mut weak_rand,
)),
)
.chain(
|e, c| e == LIGHT_ENDPOINT_ID && c == TestOnOffDeviceLogic::CLUSTER.id,
on_off::HandlerAsyncAdaptor(&on_off),
)
.chain(
|e, c| e == LIGHT_ENDPOINT_ID && c == DescHandler::CLUSTER.id,
Async(DescHandler::new(Dataver::new_rand(&mut weak_rand)).adapt()),
);
let mut store = DummyKvBlobStore;
stack.startup(&crypto, &mut store).await?;
let kv = stack.kv(store);
let matter = pin!(stack.run_preex(
EspMatterNetStack::new(),
EspMatterNetif::new(thread.netif(), InterfaceTypeEnum::Thread, sysloop),
EspMatterThreadSrp::new(&thread),
&crypto,
(NODE, handler),
&kv,
(),
));
matter.await?;
Ok(())
}
static MATTER_STACK: StaticCell<EspEthMatterStack<BUMP_SIZE, ()>> = StaticCell::new();
const LIGHT_ENDPOINT_ID: u16 = 1;
const NODE: Node = Node {
endpoints: &[
EspEthMatterStack::<0, ()>::root_endpoint(),
Endpoint::new(
LIGHT_ENDPOINT_ID,
devices!(DEV_TYPE_ON_OFF_LIGHT),
clusters!(DescHandler::CLUSTER, TestOnOffDeviceLogic::CLUSTER),
),
],
};
}