/* * * Copyright (c) 2020-2022 Project CHIP Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ use core::{borrow::Borrow, cell::RefCell}; use crate::{ acl::AclMgr, data_model::{ cluster_basic_information::BasicInfoConfig, sdm::{dev_att::DevAttDataFetcher, failsafe::FailSafe}, }, error::*, fabric::FabricMgr, mdns::{Mdns, MdnsMgr}, pairing::{print_pairing_code_and_qr, DiscoveryCapabilities}, secure_channel::{pake::PaseMgr, spake2p::VerifierData}, utils::{epoch::Epoch, rand::Rand}, }; /* The Matter Port */ pub const MATTER_PORT: u16 = 5540; /// Device Commissioning Data pub struct CommissioningData { /// The data like password or verifier that is required to authenticate pub verifier: VerifierData, /// The 12-bit discriminator used to differentiate between multiple devices pub discriminator: u16, } /// The primary Matter Object pub struct Matter<'a> { pub fabric_mgr: RefCell, pub acl_mgr: RefCell, pub pase_mgr: RefCell, pub failsafe: RefCell, pub mdns_mgr: MdnsMgr<'a>, pub epoch: Epoch, pub rand: Rand, pub dev_det: &'a BasicInfoConfig<'a>, pub dev_att: &'a dyn DevAttDataFetcher, pub port: u16, } impl<'a> Matter<'a> { #[cfg(feature = "std")] #[inline(always)] pub fn new_default( dev_det: &'a BasicInfoConfig<'a>, dev_att: &'a dyn DevAttDataFetcher, mdns: &'a dyn Mdns, port: u16, ) -> Self { use crate::utils::epoch::sys_epoch; use crate::utils::rand::sys_rand; Self::new(dev_det, dev_att, mdns, sys_epoch, sys_rand, port) } /// Creates a new Matter object /// /// # Parameters /// * dev_att: An object that implements the trait [DevAttDataFetcher]. Any Matter device /// requires a set of device attestation certificates and keys. It is the responsibility of /// this object to return the device attestation details when queried upon. #[inline(always)] pub fn new( dev_det: &'a BasicInfoConfig<'a>, dev_att: &'a dyn DevAttDataFetcher, mdns: &'a dyn Mdns, epoch: Epoch, rand: Rand, port: u16, ) -> Self { Self { fabric_mgr: RefCell::new(FabricMgr::new()), acl_mgr: RefCell::new(AclMgr::new()), pase_mgr: RefCell::new(PaseMgr::new(epoch, rand)), failsafe: RefCell::new(FailSafe::new()), mdns_mgr: MdnsMgr::new(dev_det.vid, dev_det.pid, dev_det.device_name, port, mdns), epoch, rand, dev_det, dev_att, port, } } pub fn dev_det(&self) -> &BasicInfoConfig<'_> { self.dev_det } pub fn dev_att(&self) -> &dyn DevAttDataFetcher { self.dev_att } pub fn port(&self) -> u16 { self.port } pub fn load_fabrics(&self, data: &[u8]) -> Result<(), Error> { self.fabric_mgr.borrow_mut().load(data, &self.mdns_mgr) } pub fn load_acls(&self, data: &[u8]) -> Result<(), Error> { self.acl_mgr.borrow_mut().load(data) } pub fn store_fabrics<'b>(&self, buf: &'b mut [u8]) -> Result, Error> { self.fabric_mgr.borrow_mut().store(buf) } pub fn store_acls<'b>(&self, buf: &'b mut [u8]) -> Result, Error> { self.acl_mgr.borrow_mut().store(buf) } pub fn is_changed(&self) -> bool { self.acl_mgr.borrow().is_changed() || self.fabric_mgr.borrow().is_changed() } pub fn start_comissioning( &self, dev_comm: CommissioningData, buf: &mut [u8], ) -> Result { if !self.pase_mgr.borrow().is_pase_session_enabled() && self.fabric_mgr.borrow().is_empty() { print_pairing_code_and_qr( self.dev_det, &dev_comm, DiscoveryCapabilities::default(), buf, )?; self.pase_mgr.borrow_mut().enable_pase_session( dev_comm.verifier, dev_comm.discriminator, &self.mdns_mgr, )?; Ok(true) } else { Ok(false) } } } impl<'a> Borrow> for Matter<'a> { fn borrow(&self) -> &RefCell { &self.fabric_mgr } } impl<'a> Borrow> for Matter<'a> { fn borrow(&self) -> &RefCell { &self.acl_mgr } } impl<'a> Borrow> for Matter<'a> { fn borrow(&self) -> &RefCell { &self.pase_mgr } } impl<'a> Borrow> for Matter<'a> { fn borrow(&self) -> &RefCell { &self.failsafe } } impl<'a> Borrow> for Matter<'a> { fn borrow(&self) -> &MdnsMgr<'a> { &self.mdns_mgr } } impl<'a> Borrow> for Matter<'a> { fn borrow(&self) -> &BasicInfoConfig<'a> { self.dev_det } } impl<'a> Borrow for Matter<'a> { fn borrow(&self) -> &(dyn DevAttDataFetcher + 'a) { self.dev_att } } impl<'a> Borrow for Matter<'a> { fn borrow(&self) -> &(dyn Mdns + 'a) { self.mdns_mgr.mdns } } impl<'a> Borrow for Matter<'a> { fn borrow(&self) -> &Epoch { &self.epoch } } impl<'a> Borrow for Matter<'a> { fn borrow(&self) -> &Rand { &self.rand } }