admin-commissioning: Link PaseMgr with Admin Commissioning
Adding the second commissioner now works successfully through iOS! Yay!
This commit is contained in:
parent
b24c9acc7d
commit
1645754b48
6 changed files with 51 additions and 33 deletions
|
@ -62,8 +62,10 @@ impl Matter {
|
||||||
|
|
||||||
let fabric_mgr = Arc::new(FabricMgr::new()?);
|
let fabric_mgr = Arc::new(FabricMgr::new()?);
|
||||||
let acl_mgr = Arc::new(AclMgr::new()?);
|
let acl_mgr = Arc::new(AclMgr::new()?);
|
||||||
|
let mut pase = PaseMgr::new();
|
||||||
let open_comm_window = fabric_mgr.is_empty();
|
let open_comm_window = fabric_mgr.is_empty();
|
||||||
let data_model = DataModel::new(dev_det, dev_att, fabric_mgr.clone(), acl_mgr)?;
|
let data_model =
|
||||||
|
DataModel::new(dev_det, dev_att, fabric_mgr.clone(), acl_mgr, pase.clone())?;
|
||||||
let mut matter = Box::new(Matter {
|
let mut matter = Box::new(Matter {
|
||||||
transport_mgr: transport::mgr::Mgr::new()?,
|
transport_mgr: transport::mgr::Mgr::new()?,
|
||||||
data_model,
|
data_model,
|
||||||
|
@ -73,12 +75,11 @@ impl Matter {
|
||||||
Box::new(InteractionModel::new(Box::new(matter.data_model.clone())));
|
Box::new(InteractionModel::new(Box::new(matter.data_model.clone())));
|
||||||
matter.transport_mgr.register_protocol(interaction_model)?;
|
matter.transport_mgr.register_protocol(interaction_model)?;
|
||||||
|
|
||||||
let mut pase = PaseMgr::new();
|
|
||||||
if open_comm_window {
|
if open_comm_window {
|
||||||
pase.enable_pase_session(dev_comm.verifier, dev_comm.discriminator)?;
|
pase.enable_pase_session(dev_comm.verifier, dev_comm.discriminator)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let secure_channel = Box::new(SecureChannel::new(pase.clone(), matter.fabric_mgr.clone()));
|
let secure_channel = Box::new(SecureChannel::new(pase, matter.fabric_mgr.clone()));
|
||||||
matter.transport_mgr.register_protocol(secure_channel)?;
|
matter.transport_mgr.register_protocol(secure_channel)?;
|
||||||
Ok(matter)
|
Ok(matter)
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ use crate::{
|
||||||
},
|
},
|
||||||
InteractionConsumer, Transaction,
|
InteractionConsumer, Transaction,
|
||||||
},
|
},
|
||||||
|
secure_channel::pake::PaseMgr,
|
||||||
tlv::{TLVArray, TLVWriter, TagType, ToTLV},
|
tlv::{TLVArray, TLVWriter, TagType, ToTLV},
|
||||||
transport::session::{Session, SessionMode},
|
transport::session::{Session, SessionMode},
|
||||||
};
|
};
|
||||||
|
@ -54,6 +55,7 @@ impl DataModel {
|
||||||
dev_att: Box<dyn DevAttDataFetcher>,
|
dev_att: Box<dyn DevAttDataFetcher>,
|
||||||
fabric_mgr: Arc<FabricMgr>,
|
fabric_mgr: Arc<FabricMgr>,
|
||||||
acl_mgr: Arc<AclMgr>,
|
acl_mgr: Arc<AclMgr>,
|
||||||
|
pase_mgr: PaseMgr,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
let dm = DataModel {
|
let dm = DataModel {
|
||||||
node: Arc::new(RwLock::new(Node::new()?)),
|
node: Arc::new(RwLock::new(Node::new()?)),
|
||||||
|
@ -62,7 +64,14 @@ impl DataModel {
|
||||||
{
|
{
|
||||||
let mut node = dm.node.write()?;
|
let mut node = dm.node.write()?;
|
||||||
node.set_changes_cb(Box::new(dm.clone()));
|
node.set_changes_cb(Box::new(dm.clone()));
|
||||||
device_type_add_root_node(&mut node, dev_details, dev_att, fabric_mgr, acl_mgr)?;
|
device_type_add_root_node(
|
||||||
|
&mut node,
|
||||||
|
dev_details,
|
||||||
|
dev_att,
|
||||||
|
fabric_mgr,
|
||||||
|
acl_mgr,
|
||||||
|
pase_mgr,
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
Ok(dm)
|
Ok(dm)
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ use super::system_model::access_control::AccessControlCluster;
|
||||||
use crate::acl::AclMgr;
|
use crate::acl::AclMgr;
|
||||||
use crate::error::*;
|
use crate::error::*;
|
||||||
use crate::fabric::FabricMgr;
|
use crate::fabric::FabricMgr;
|
||||||
|
use crate::secure_channel::pake::PaseMgr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::RwLockWriteGuard;
|
use std::sync::RwLockWriteGuard;
|
||||||
|
|
||||||
|
@ -39,6 +40,7 @@ pub fn device_type_add_root_node(
|
||||||
dev_att: Box<dyn DevAttDataFetcher>,
|
dev_att: Box<dyn DevAttDataFetcher>,
|
||||||
fabric_mgr: Arc<FabricMgr>,
|
fabric_mgr: Arc<FabricMgr>,
|
||||||
acl_mgr: Arc<AclMgr>,
|
acl_mgr: Arc<AclMgr>,
|
||||||
|
pase_mgr: PaseMgr,
|
||||||
) -> Result<u32, Error> {
|
) -> Result<u32, Error> {
|
||||||
// Add the root endpoint
|
// Add the root endpoint
|
||||||
let endpoint = node.add_endpoint()?;
|
let endpoint = node.add_endpoint()?;
|
||||||
|
@ -52,7 +54,7 @@ pub fn device_type_add_root_node(
|
||||||
let failsafe = general_commissioning.failsafe();
|
let failsafe = general_commissioning.failsafe();
|
||||||
node.add_cluster(0, general_commissioning)?;
|
node.add_cluster(0, general_commissioning)?;
|
||||||
node.add_cluster(0, NwCommCluster::new()?)?;
|
node.add_cluster(0, NwCommCluster::new()?)?;
|
||||||
node.add_cluster(0, AdminCommCluster::new()?)?;
|
node.add_cluster(0, AdminCommCluster::new(pase_mgr)?)?;
|
||||||
node.add_cluster(
|
node.add_cluster(
|
||||||
0,
|
0,
|
||||||
NocCluster::new(dev_att, fabric_mgr, acl_mgr.clone(), failsafe)?,
|
NocCluster::new(dev_att, fabric_mgr, acl_mgr.clone(), failsafe)?,
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
use crate::cmd_enter;
|
use crate::cmd_enter;
|
||||||
use crate::data_model::objects::*;
|
use crate::data_model::objects::*;
|
||||||
use crate::interaction_model::core::IMStatusCode;
|
use crate::interaction_model::core::IMStatusCode;
|
||||||
|
use crate::secure_channel::pake::PaseMgr;
|
||||||
|
use crate::secure_channel::spake2p::VerifierData;
|
||||||
use crate::tlv::{FromTLV, Nullable, OctetStr, TLVElement};
|
use crate::tlv::{FromTLV, Nullable, OctetStr, TLVElement};
|
||||||
use crate::{error::*, interaction_model::command::CommandReq};
|
use crate::{error::*, interaction_model::command::CommandReq};
|
||||||
use log::{error, info};
|
use log::{error, info};
|
||||||
|
@ -74,7 +76,7 @@ fn attr_admin_vid_new() -> Result<Attribute, Error> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AdminCommCluster {
|
pub struct AdminCommCluster {
|
||||||
window_status: WindowStatus,
|
pase_mgr: PaseMgr,
|
||||||
base: Cluster,
|
base: Cluster,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,23 +91,16 @@ impl ClusterType for AdminCommCluster {
|
||||||
fn read_custom_attribute(&self, encoder: &mut dyn Encoder, attr: &AttrDetails) {
|
fn read_custom_attribute(&self, encoder: &mut dyn Encoder, attr: &AttrDetails) {
|
||||||
match num::FromPrimitive::from_u16(attr.attr_id) {
|
match num::FromPrimitive::from_u16(attr.attr_id) {
|
||||||
Some(Attributes::WindowStatus) => {
|
Some(Attributes::WindowStatus) => {
|
||||||
let status = self.window_status as u8;
|
let status = 1_u8;
|
||||||
encoder.encode(EncodeValue::Value(&status))
|
encoder.encode(EncodeValue::Value(&status))
|
||||||
}
|
}
|
||||||
Some(Attributes::AdminVendorId) => {
|
Some(Attributes::AdminVendorId) => {
|
||||||
let vid = if self.window_status == WindowStatus::WindowNotOpen {
|
let vid = Nullable::NotNull(1_u8);
|
||||||
Nullable::Null
|
|
||||||
} else {
|
|
||||||
Nullable::NotNull(1_u8)
|
|
||||||
};
|
|
||||||
encoder.encode(EncodeValue::Value(&vid))
|
encoder.encode(EncodeValue::Value(&vid))
|
||||||
}
|
}
|
||||||
Some(Attributes::AdminFabricIndex) => {
|
Some(Attributes::AdminFabricIndex) => {
|
||||||
let vid = if self.window_status == WindowStatus::WindowNotOpen {
|
let vid = Nullable::NotNull(1_u8);
|
||||||
Nullable::Null
|
|
||||||
} else {
|
|
||||||
Nullable::NotNull(1_u8)
|
|
||||||
};
|
|
||||||
encoder.encode(EncodeValue::Value(&vid))
|
encoder.encode(EncodeValue::Value(&vid))
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -129,9 +124,9 @@ impl ClusterType for AdminCommCluster {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AdminCommCluster {
|
impl AdminCommCluster {
|
||||||
pub fn new() -> Result<Box<Self>, Error> {
|
pub fn new(pase_mgr: PaseMgr) -> Result<Box<Self>, Error> {
|
||||||
let mut c = Box::new(AdminCommCluster {
|
let mut c = Box::new(AdminCommCluster {
|
||||||
window_status: WindowStatus::WindowNotOpen,
|
pase_mgr,
|
||||||
base: Cluster::new(ID)?,
|
base: Cluster::new(ID)?,
|
||||||
});
|
});
|
||||||
c.base.add_attribute(attr_window_status_new()?)?;
|
c.base.add_attribute(attr_window_status_new()?)?;
|
||||||
|
@ -145,9 +140,11 @@ impl AdminCommCluster {
|
||||||
cmd_req: &mut CommandReq,
|
cmd_req: &mut CommandReq,
|
||||||
) -> Result<(), IMStatusCode> {
|
) -> Result<(), IMStatusCode> {
|
||||||
cmd_enter!("Open Commissioning Window");
|
cmd_enter!("Open Commissioning Window");
|
||||||
let _req =
|
let req =
|
||||||
OpenCommWindowReq::from_tlv(&cmd_req.data).map_err(|_| IMStatusCode::InvalidCommand)?;
|
OpenCommWindowReq::from_tlv(&cmd_req.data).map_err(|_| IMStatusCode::InvalidCommand)?;
|
||||||
self.window_status = WindowStatus::EnhancedWindowOpen;
|
let verifier = VerifierData::new(req.verifier.0, req.iterations, req.salt.0);
|
||||||
|
self.pase_mgr
|
||||||
|
.enable_pase_session(verifier, req.discriminator)?;
|
||||||
Err(IMStatusCode::Sucess)
|
Err(IMStatusCode::Sucess)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,8 +153,8 @@ impl AdminCommCluster {
|
||||||
#[tlvargs(lifetime = "'a")]
|
#[tlvargs(lifetime = "'a")]
|
||||||
pub struct OpenCommWindowReq<'a> {
|
pub struct OpenCommWindowReq<'a> {
|
||||||
_timeout: u16,
|
_timeout: u16,
|
||||||
_verifier: OctetStr<'a>,
|
verifier: OctetStr<'a>,
|
||||||
_discriminator: u16,
|
discriminator: u16,
|
||||||
_iterations: u32,
|
iterations: u32,
|
||||||
_salt: OctetStr<'a>,
|
salt: OctetStr<'a>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,13 +42,13 @@ use crate::{
|
||||||
use log::{error, info};
|
use log::{error, info};
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
|
|
||||||
enum PaseSessionState {
|
enum PaseMgrState {
|
||||||
Enabled(PAKE, SysMdnsService),
|
Enabled(PAKE, SysMdnsService),
|
||||||
Disabled,
|
Disabled,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PaseMgrInternal {
|
pub struct PaseMgrInternal {
|
||||||
state: PaseSessionState,
|
state: PaseMgrState,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -58,7 +58,7 @@ pub struct PaseMgr(Arc<Mutex<PaseMgrInternal>>);
|
||||||
impl PaseMgr {
|
impl PaseMgr {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self(Arc::new(Mutex::new(PaseMgrInternal {
|
Self(Arc::new(Mutex::new(PaseMgrInternal {
|
||||||
state: PaseSessionState::Disabled,
|
state: PaseMgrState::Disabled,
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,13 +72,13 @@ impl PaseMgr {
|
||||||
let name = format!("{:016X}", name);
|
let name = format!("{:016X}", name);
|
||||||
let mdns = Mdns::get()?
|
let mdns = Mdns::get()?
|
||||||
.publish_service(&name, mdns::ServiceMode::Commissionable(discriminator))?;
|
.publish_service(&name, mdns::ServiceMode::Commissionable(discriminator))?;
|
||||||
s.state = PaseSessionState::Enabled(PAKE::new(verifier), mdns);
|
s.state = PaseMgrState::Enabled(PAKE::new(verifier), mdns);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn disable_pase_session(&mut self) {
|
pub fn disable_pase_session(&mut self) {
|
||||||
let mut s = self.0.lock().unwrap();
|
let mut s = self.0.lock().unwrap();
|
||||||
s.state = PaseSessionState::Disabled;
|
s.state = PaseMgrState::Disabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If the PASE Session is enabled, execute the closure,
|
/// If the PASE Session is enabled, execute the closure,
|
||||||
|
@ -88,7 +88,7 @@ impl PaseMgr {
|
||||||
F: FnOnce(&mut PAKE, &mut ProtoCtx) -> Result<(), Error>,
|
F: FnOnce(&mut PAKE, &mut ProtoCtx) -> Result<(), Error>,
|
||||||
{
|
{
|
||||||
let mut s = self.0.lock().unwrap();
|
let mut s = self.0.lock().unwrap();
|
||||||
if let PaseSessionState::Enabled(pake, _) = &mut s.state {
|
if let PaseMgrState::Enabled(pake, _) = &mut s.state {
|
||||||
f(pake, ctx)
|
f(pake, ctx)
|
||||||
} else {
|
} else {
|
||||||
error!("PASE Not enabled");
|
error!("PASE Not enabled");
|
||||||
|
@ -190,7 +190,7 @@ impl Default for PakeState {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PAKE {
|
pub struct PAKE {
|
||||||
verifier: VerifierData,
|
pub verifier: VerifierData,
|
||||||
state: PakeState,
|
state: PakeState,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ use matter::{
|
||||||
error::Error,
|
error::Error,
|
||||||
fabric::FabricMgr,
|
fabric::FabricMgr,
|
||||||
interaction_model::{core::OpCode, InteractionModel},
|
interaction_model::{core::OpCode, InteractionModel},
|
||||||
|
secure_channel::pake::PaseMgr,
|
||||||
tlv::{TLVWriter, TagType, ToTLV},
|
tlv::{TLVWriter, TagType, ToTLV},
|
||||||
transport::packet::Packet,
|
transport::packet::Packet,
|
||||||
transport::proto_demux::HandleProto,
|
transport::proto_demux::HandleProto,
|
||||||
|
@ -97,12 +98,20 @@ impl ImEngine {
|
||||||
let dev_att = Box::new(DummyDevAtt {});
|
let dev_att = Box::new(DummyDevAtt {});
|
||||||
let fabric_mgr = Arc::new(FabricMgr::new().unwrap());
|
let fabric_mgr = Arc::new(FabricMgr::new().unwrap());
|
||||||
let acl_mgr = Arc::new(AclMgr::new_with(false).unwrap());
|
let acl_mgr = Arc::new(AclMgr::new_with(false).unwrap());
|
||||||
|
let pase_mgr = PaseMgr::new();
|
||||||
acl_mgr.erase_all();
|
acl_mgr.erase_all();
|
||||||
let mut default_acl = AclEntry::new(1, Privilege::ADMIN, AuthMode::Case);
|
let mut default_acl = AclEntry::new(1, Privilege::ADMIN, AuthMode::Case);
|
||||||
// Only allow the standard peer node id of the IM Engine
|
// Only allow the standard peer node id of the IM Engine
|
||||||
default_acl.add_subject(IM_ENGINE_PEER_ID).unwrap();
|
default_acl.add_subject(IM_ENGINE_PEER_ID).unwrap();
|
||||||
acl_mgr.add(default_acl).unwrap();
|
acl_mgr.add(default_acl).unwrap();
|
||||||
let dm = DataModel::new(dev_det, dev_att, fabric_mgr.clone(), acl_mgr.clone()).unwrap();
|
let dm = DataModel::new(
|
||||||
|
dev_det,
|
||||||
|
dev_att,
|
||||||
|
fabric_mgr.clone(),
|
||||||
|
acl_mgr.clone(),
|
||||||
|
pase_mgr,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut d = dm.node.write().unwrap();
|
let mut d = dm.node.write().unwrap();
|
||||||
|
|
Loading…
Add table
Reference in a new issue