From f135e2dbf8f40b2c9832b4f4800d6e3a83610204 Mon Sep 17 00:00:00 2001 From: Kedar Sovani Date: Sat, 7 Jan 2023 21:47:33 +0530 Subject: [PATCH] AdminCommissioning: Baseline support Just add all the 3 attributes, and the command open-commissioning-window that simply sets a variable for now --- matter/src/data_model/device_types.rs | 2 + matter/src/data_model/objects/endpoint.rs | 2 +- .../src/data_model/sdm/admin_commissioning.rs | 163 ++++++++++++++++++ matter/src/data_model/sdm/mod.rs | 1 + 4 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 matter/src/data_model/sdm/admin_commissioning.rs diff --git a/matter/src/data_model/device_types.rs b/matter/src/data_model/device_types.rs index 62b81f5..71a2cf4 100644 --- a/matter/src/data_model/device_types.rs +++ b/matter/src/data_model/device_types.rs @@ -19,6 +19,7 @@ use super::cluster_basic_information::BasicInfoCluster; use super::cluster_basic_information::BasicInfoConfig; use super::cluster_on_off::OnOffCluster; use super::objects::*; +use super::sdm::admin_commissioning::AdminCommCluster; use super::sdm::dev_att::DevAttDataFetcher; use super::sdm::general_commissioning::GenCommCluster; use super::sdm::noc::NocCluster; @@ -51,6 +52,7 @@ pub fn device_type_add_root_node( let failsafe = general_commissioning.failsafe(); node.add_cluster(0, general_commissioning)?; node.add_cluster(0, NwCommCluster::new()?)?; + node.add_cluster(0, AdminCommCluster::new()?)?; node.add_cluster( 0, NocCluster::new(dev_att, fabric_mgr, acl_mgr.clone(), failsafe)?, diff --git a/matter/src/data_model/objects/endpoint.rs b/matter/src/data_model/objects/endpoint.rs index a790fc6..ae5ed4c 100644 --- a/matter/src/data_model/objects/endpoint.rs +++ b/matter/src/data_model/objects/endpoint.rs @@ -19,7 +19,7 @@ use crate::{data_model::objects::ClusterType, error::*, interaction_model::core: use std::fmt; -pub const CLUSTERS_PER_ENDPT: usize = 7; +pub const CLUSTERS_PER_ENDPT: usize = 9; pub struct Endpoint { clusters: Vec>, diff --git a/matter/src/data_model/sdm/admin_commissioning.rs b/matter/src/data_model/sdm/admin_commissioning.rs new file mode 100644 index 0000000..6e7d7b7 --- /dev/null +++ b/matter/src/data_model/sdm/admin_commissioning.rs @@ -0,0 +1,163 @@ +/* + * + * Copyright (c) 2023 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 crate::cmd_enter; +use crate::data_model::objects::*; +use crate::interaction_model::core::IMStatusCode; +use crate::tlv::{FromTLV, Nullable, OctetStr, TLVElement}; +use crate::{error::*, interaction_model::command::CommandReq}; +use log::{error, info}; +use num_derive::FromPrimitive; + +pub const ID: u32 = 0x003C; + +#[derive(FromPrimitive, Debug, Copy, Clone, PartialEq)] +pub enum WindowStatus { + WindowNotOpen = 0, + EnhancedWindowOpen = 1, + BasicWindowOpen = 2, +} + +#[derive(FromPrimitive)] +pub enum Attributes { + WindowStatus = 0, + AdminFabricIndex = 1, + AdminVendorId = 2, +} + +#[derive(FromPrimitive)] +pub enum Commands { + OpenCommWindow = 0x00, + OpenBasicCommWindow = 0x01, + RevokeComm = 0x02, +} + +fn attr_window_status_new() -> Result { + Attribute::new( + Attributes::WindowStatus as u16, + AttrValue::Custom, + Access::RV, + Quality::NONE, + ) +} + +fn attr_admin_fabid_new() -> Result { + Attribute::new( + Attributes::AdminFabricIndex as u16, + AttrValue::Custom, + Access::RV, + Quality::NULLABLE, + ) +} + +fn attr_admin_vid_new() -> Result { + Attribute::new( + Attributes::AdminVendorId as u16, + AttrValue::Custom, + Access::RV, + Quality::NULLABLE, + ) +} + +pub struct AdminCommCluster { + window_status: WindowStatus, + base: Cluster, +} + +impl ClusterType for AdminCommCluster { + fn base(&self) -> &Cluster { + &self.base + } + fn base_mut(&mut self) -> &mut Cluster { + &mut self.base + } + + fn read_custom_attribute(&self, encoder: &mut dyn Encoder, attr: &AttrDetails) { + match num::FromPrimitive::from_u16(attr.attr_id) { + Some(Attributes::WindowStatus) => { + let status = self.window_status as u8; + encoder.encode(EncodeValue::Value(&status)) + } + Some(Attributes::AdminVendorId) => { + let vid = if self.window_status == WindowStatus::WindowNotOpen { + Nullable::Null + } else { + Nullable::NotNull(1_u8) + }; + encoder.encode(EncodeValue::Value(&vid)) + } + Some(Attributes::AdminFabricIndex) => { + let vid = if self.window_status == WindowStatus::WindowNotOpen { + Nullable::Null + } else { + Nullable::NotNull(1_u8) + }; + encoder.encode(EncodeValue::Value(&vid)) + } + _ => { + error!("Unsupported Attribute: this shouldn't happen"); + } + } + } + fn handle_command(&mut self, cmd_req: &mut CommandReq) -> Result<(), IMStatusCode> { + let cmd = cmd_req + .cmd + .path + .leaf + .map(num::FromPrimitive::from_u32) + .ok_or(IMStatusCode::UnsupportedCommand)? + .ok_or(IMStatusCode::UnsupportedCommand)?; + match cmd { + Commands::OpenCommWindow => self.handle_command_opencomm_win(cmd_req), + _ => Err(IMStatusCode::UnsupportedCommand), + } + } +} + +impl AdminCommCluster { + pub fn new() -> Result, Error> { + let mut c = Box::new(AdminCommCluster { + window_status: WindowStatus::WindowNotOpen, + base: Cluster::new(ID)?, + }); + c.base.add_attribute(attr_window_status_new()?)?; + c.base.add_attribute(attr_admin_fabid_new()?)?; + c.base.add_attribute(attr_admin_vid_new()?)?; + Ok(c) + } + + fn handle_command_opencomm_win( + &mut self, + cmd_req: &mut CommandReq, + ) -> Result<(), IMStatusCode> { + cmd_enter!("Open Commissioning Window"); + let _req = + OpenCommWindowReq::from_tlv(&cmd_req.data).map_err(|_| IMStatusCode::InvalidCommand)?; + self.window_status = WindowStatus::EnhancedWindowOpen; + Err(IMStatusCode::Sucess) + } +} + +#[derive(FromTLV)] +#[tlvargs(lifetime = "'a")] +pub struct OpenCommWindowReq<'a> { + _timeout: u16, + _verifier: OctetStr<'a>, + _discriminator: u16, + _iterations: u32, + _salt: OctetStr<'a>, +} diff --git a/matter/src/data_model/sdm/mod.rs b/matter/src/data_model/sdm/mod.rs index cec166d..1ce25ad 100644 --- a/matter/src/data_model/sdm/mod.rs +++ b/matter/src/data_model/sdm/mod.rs @@ -15,6 +15,7 @@ * limitations under the License. */ +pub mod admin_commissioning; pub mod dev_att; pub mod failsafe; pub mod general_commissioning;