diff --git a/src/stack/wifible.rs b/src/stack/wifible.rs index e1b1a86..9445d59 100644 --- a/src/stack/wifible.rs +++ b/src/stack/wifible.rs @@ -9,6 +9,7 @@ ))] use core::borrow::Borrow; +use core::cell::RefCell; use core::pin::pin; use alloc::boxed::Box; @@ -32,6 +33,7 @@ use rs_matter::data_model::cluster_basic_information; use rs_matter::data_model::objects::{ AsyncHandler, AsyncMetadata, Cluster, Endpoint, HandlerCompat, }; +use rs_matter::data_model::sdm::failsafe::FailSafe; use rs_matter::data_model::sdm::{ admin_commissioning, general_commissioning, general_diagnostics, group_key_management, noc, nw_commissioning, @@ -185,8 +187,14 @@ impl<'a> MatterStack<'a, WifiBle> { } // Reset the matter transport to free up sessions and exchanges + // and to clear any PASE sessions and their keys (as per Matter Core spec) self.matter().reset(); + // As per spec, we need to indicate the expectation of a re-arm with a CASE session + // even if the current session is a PASE one (this is specific for non-concurrent commissiioning flows) + let failsafe: &RefCell = self.matter().borrow(); + failsafe.borrow_mut().expect_case_rearm()?; + let mut wifi = Box::new(EspWifi::new( &mut modem, sysloop.clone(), diff --git a/src/wifi.rs b/src/wifi.rs index 1342409..dbc91aa 100644 --- a/src/wifi.rs +++ b/src/wifi.rs @@ -1,8 +1,9 @@ use core::cell::RefCell; use embassy_sync::blocking_mutex::{self, raw::RawMutex}; +use embassy_time::{Duration, Timer}; -use log::info; +use log::{info, warn}; use rs_matter::data_model::sdm::nw_commissioning::NetworkCommissioningStatus; use rs_matter::error::{Error, ErrorCode}; @@ -149,6 +150,12 @@ where self.network_connect_requested.wait().await; } + warn!( + "Giving BLE/BTP extra 4 seconds for any outstanding messages before switching to Wifi" + ); + + Timer::after(Duration::from_secs(4)).await; + Ok(()) } } diff --git a/src/wifi/comm.rs b/src/wifi/comm.rs index 2e8f112..b402290 100644 --- a/src/wifi/comm.rs +++ b/src/wifi/comm.rs @@ -7,9 +7,9 @@ use rs_matter::data_model::objects::{ CmdDetails, Dataver, }; use rs_matter::data_model::sdm::nw_commissioning::{ - AddWifiNetworkRequest, Attributes, Commands, ConnectNetworkRequest, NetworkCommissioningStatus, - NetworkConfigResponse, NwInfo, RemoveNetworkRequest, ReorderNetworkRequest, ResponseCommands, - ScanNetworksRequest, WIFI_CLUSTER, + AddWifiNetworkRequest, Attributes, Commands, ConnectNetworkRequest, ConnectNetworkResponse, + NetworkCommissioningStatus, NetworkConfigResponse, NwInfo, RemoveNetworkRequest, + ReorderNetworkRequest, ResponseCommands, ScanNetworksRequest, WIFI_CLUSTER, }; use rs_matter::error::{Error, ErrorCode}; use rs_matter::interaction_model::core::IMStatusCode; @@ -301,28 +301,39 @@ where &self, _exchange: &Exchange<'_>, req: &ConnectNetworkRequest<'_>, - _encoder: CmdDataEncoder<'_, '_, '_>, + encoder: CmdDataEncoder<'_, '_, '_>, ) -> Result<(), Error> { // TODO: Check failsafe status // Non-concurrent commissioning scenario (i.e. only BLE is active, and the ESP IDF co-exist mode is not enabled) - // Notify that we have received a connect command let ssid = core::str::from_utf8(req.network_id.0).unwrap(); + info!( + "Request to connect to network with SSID {} received", + core::str::from_utf8(req.network_id.0).unwrap(), + ); + self.networks.state.lock(|state| { let mut state = state.borrow_mut(); state.connect_requested = Some(ssid.try_into().unwrap()); }); - self.networks.network_connect_requested.notify(); + let writer = encoder.with_command(ResponseCommands::NetworkConfigResponse as _)?; - warn!("Connecting to network with SSID {} not supported due to non-concurrent commissioning in place", ssid); - warn!("Response to ConnectNetwork will pend forever"); + // As per spec, return success even though though whether we'll be able to connect to the network + // will become apparent later, once we switch to Wifi + writer.set(ConnectNetworkResponse { + status: NetworkCommissioningStatus::Success, + debug_text: None, + error_value: 0, + })?; - // Block forever waiting for the firware to restart - core::future::pending().await + // Notify that we have received a connect command + self.networks.network_connect_requested.notify(); + + Ok(()) } fn reorder_network(