diff --git a/matter/src/data_model/sdm/noc.rs b/matter/src/data_model/sdm/noc.rs index 7785fbd..5d2a041 100644 --- a/matter/src/data_model/sdm/noc.rs +++ b/matter/src/data_model/sdm/noc.rs @@ -263,6 +263,23 @@ impl NocCluster { Ok(()) } + fn handle_command_rmfabric(&mut self, cmd_req: &mut CommandReq) -> Result<(), IMStatusCode> { + cmd_enter!("Remove Fabric"); + let req = + RemoveFabricReq::from_tlv(&cmd_req.data).map_err(|_| IMStatusCode::InvalidCommand)?; + if self.fabric_mgr.remove(req.fab_idx).is_ok() { + cmd_req.trans.terminate(); + } else { + NocCluster::create_nocresponse( + cmd_req.resp, + NocStatus::InvalidFabricIndex, + req.fab_idx, + "".to_string(), + ); + } + Ok(()) + } + fn handle_command_addnoc(&mut self, cmd_req: &mut CommandReq) -> Result<(), IMStatusCode> { cmd_enter!("AddNOC"); if let Err(e) = self._handle_command_addnoc(cmd_req) { @@ -437,6 +454,7 @@ impl ClusterType for NocCluster { Commands::AttReq => self.handle_command_attrequest(cmd_req), Commands::CertChainReq => self.handle_command_certchainrequest(cmd_req), Commands::UpdateFabricLabel => self.handle_command_updatefablabel(cmd_req), + Commands::RemoveFabric => self.handle_command_rmfabric(cmd_req), _ => Err(IMStatusCode::UnsupportedCommand), } } @@ -566,6 +584,11 @@ struct CertChainReq { cert_type: u8, } +#[derive(FromTLV)] +struct RemoveFabricReq { + fab_idx: u8, +} + fn get_certchainrequest_params(data: &TLVElement) -> Result { let cert_type = CertChainReq::from_tlv(data)?.cert_type; diff --git a/matter/src/fabric.rs b/matter/src/fabric.rs index 3299f4d..1715db7 100644 --- a/matter/src/fabric.rs +++ b/matter/src/fabric.rs @@ -195,6 +195,17 @@ impl Fabric { } } + fn rm_store(&self, index: usize, psm: &MutexGuard) { + psm.rm(fb_key!(index, ST_RCA)); + psm.rm(fb_key!(index, ST_ICA)); + psm.rm(fb_key!(index, ST_NOC)); + psm.rm(fb_key!(index, ST_IPK)); + psm.rm(fb_key!(index, ST_LBL)); + psm.rm(fb_key!(index, ST_PBKEY)); + psm.rm(fb_key!(index, ST_PRKEY)); + psm.rm(fb_key!(index, ST_VID)); + } + fn store(&self, index: usize, psm: &MutexGuard) -> Result<(), Error> { let mut key = [0u8; MAX_CERT_TLV_LEN]; let len = self.root_ca.as_tlv(&mut key)?; @@ -335,6 +346,19 @@ impl FabricMgr { Ok(index as u8) } + pub fn remove(&self, fab_idx: u8) -> Result<(), Error> { + let fab_idx = fab_idx as usize; + let mut mgr = self.inner.write().unwrap(); + let psm = self.psm.lock().unwrap(); + if let Some(f) = &mgr.fabrics[fab_idx] { + f.rm_store(fab_idx, &psm); + mgr.fabrics[fab_idx] = None; + Ok(()) + } else { + Err(Error::NotFound) + } + } + pub fn match_dest_id(&self, random: &[u8], target: &[u8]) -> Result { let mgr = self.inner.read()?; for i in 0..MAX_SUPPORTED_FABRICS { diff --git a/matter/src/sys/posix.rs b/matter/src/sys/posix.rs index ea1b9d6..2736e51 100644 --- a/matter/src/sys/posix.rs +++ b/matter/src/sys/posix.rs @@ -17,7 +17,7 @@ use std::{ convert::TryInto, - fs::{DirBuilder, File}, + fs::{remove_file, DirBuilder, File}, io::{Read, Write}, sync::{Arc, Mutex, Once}, }; @@ -89,4 +89,8 @@ impl Psm { *val = u64::from_be_bytes(vec.as_slice().try_into()?); Ok(()) } + + pub fn rm(&self, key: &str) { + let _ = remove_file(psm_path!(key)); + } }