AdminCommissioning: Baseline support

Just add all the 3 attributes, and the command open-commissioning-window that
simply sets a variable for now
This commit is contained in:
Kedar Sovani 2023-01-07 21:47:33 +05:30
parent a4915bb0d6
commit f135e2dbf8
4 changed files with 167 additions and 1 deletions

View file

@ -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)?,

View file

@ -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<Box<dyn ClusterType>>,

View file

@ -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, Error> {
Attribute::new(
Attributes::WindowStatus as u16,
AttrValue::Custom,
Access::RV,
Quality::NONE,
)
}
fn attr_admin_fabid_new() -> Result<Attribute, Error> {
Attribute::new(
Attributes::AdminFabricIndex as u16,
AttrValue::Custom,
Access::RV,
Quality::NULLABLE,
)
}
fn attr_admin_vid_new() -> Result<Attribute, Error> {
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<Box<Self>, 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>,
}

View file

@ -15,6 +15,7 @@
* limitations under the License.
*/
pub mod admin_commissioning;
pub mod dev_att;
pub mod failsafe;
pub mod general_commissioning;