diff --git a/matter/src/data_model/sdm/noc.rs b/matter/src/data_model/sdm/noc.rs index 0b94500..6352bc0 100644 --- a/matter/src/data_model/sdm/noc.rs +++ b/matter/src/data_model/sdm/noc.rs @@ -30,7 +30,7 @@ use crate::interaction_model::messages::ib; use crate::tlv::{FromTLV, OctetStr, TLVElement, TLVWriter, TagType, ToTLV, UtfStr}; use crate::transport::session::SessionMode; use crate::utils::writebuf::WriteBuf; -use crate::{cmd_enter, error::*}; +use crate::{cmd_enter, error::*, secure_channel}; use log::{error, info}; use num_derive::FromPrimitive; @@ -177,6 +177,15 @@ impl NocCluster { return Err(NocStatus::InsufficientPrivlege); } + // This command's processing may take longer, send a stand alone ACK to the peer to avoid any retranmissions + let ack_send = secure_channel::common::send_mrp_standalone_ack( + cmd_req.trans.exch, + cmd_req.trans.session, + ); + if ack_send.is_err() { + error!("Error sending Standalone ACK, falling back to piggybacked ACK"); + } + let r = AddNocReq::from_tlv(&cmd_req.data).map_err(|_| NocStatus::InvalidNOC)?; let noc_value = Cert::new(r.noc_value.0).map_err(|_| NocStatus::InvalidNOC)?; @@ -188,7 +197,6 @@ impl NocCluster { } else { None }; - let fabric = Fabric::new( noc_data.key_pair, noc_data.root_ca, diff --git a/matter/src/interaction_model/command.rs b/matter/src/interaction_model/command.rs index 4ee17bc..323c093 100644 --- a/matter/src/interaction_model/command.rs +++ b/matter/src/interaction_model/command.rs @@ -37,11 +37,11 @@ macro_rules! cmd_enter { }}; } -pub struct CommandReq<'a, 'b, 'c, 'd> { +pub struct CommandReq<'a, 'b, 'c, 'd, 'e> { pub cmd: ib::CmdPath, pub data: TLVElement<'a>, pub resp: &'a mut TLVWriter<'b, 'c>, - pub trans: &'a mut Transaction<'d>, + pub trans: &'a mut Transaction<'d, 'e>, } impl InteractionModel { diff --git a/matter/src/interaction_model/core.rs b/matter/src/interaction_model/core.rs index adbda94..1d548eb 100644 --- a/matter/src/interaction_model/core.rs +++ b/matter/src/interaction_model/core.rs @@ -25,7 +25,7 @@ use crate::{ exchange::Exchange, packet::Packet, proto_demux::{self, ProtoCtx, ResponseRequired}, - session::Session, + session::SessionHandle, }, }; use colored::Colorize; @@ -59,8 +59,8 @@ pub enum OpCode { TimedRequest = 10, } -impl<'a> Transaction<'a> { - pub fn new(session: &'a mut Session, exch: &'a mut Exchange) -> Self { +impl<'a, 'b> Transaction<'a, 'b> { + pub fn new(session: &'a mut SessionHandle<'b>, exch: &'a mut Exchange) -> Self { Self { state: TransactionState::Ongoing, session, diff --git a/matter/src/interaction_model/mod.rs b/matter/src/interaction_model/mod.rs index 98af4af..2caf55f 100644 --- a/matter/src/interaction_model/mod.rs +++ b/matter/src/interaction_model/mod.rs @@ -18,7 +18,7 @@ use crate::{ error::Error, tlv::TLVWriter, - transport::{exchange::Exchange, proto_demux::ResponseRequired, session::Session}, + transport::{exchange::Exchange, proto_demux::ResponseRequired, session::SessionHandle}, }; use self::{ @@ -32,9 +32,9 @@ pub enum TransactionState { Complete, Terminate, } -pub struct Transaction<'a> { +pub struct Transaction<'a, 'b> { pub state: TransactionState, - pub session: &'a mut Session, + pub session: &'a mut SessionHandle<'b>, pub exch: &'a mut Exchange, } diff --git a/matter/src/secure_channel/common.rs b/matter/src/secure_channel/common.rs index f368624..511bb5c 100644 --- a/matter/src/secure_channel/common.rs +++ b/matter/src/secure_channel/common.rs @@ -15,9 +15,18 @@ * limitations under the License. */ +use boxslab::Slab; +use log::info; use num_derive::FromPrimitive; -use crate::{error::Error, transport::packet::Packet}; +use crate::{ + error::Error, + transport::{ + exchange::Exchange, + packet::{Packet, PacketPool}, + session::SessionHandle, + }, +}; use super::status_report::{create_status_report, GeneralCode}; @@ -83,3 +92,10 @@ pub fn create_mrp_standalone_ack(proto_tx: &mut Packet) { proto_tx.set_proto_opcode(OpCode::MRPStandAloneAck as u8); proto_tx.unset_reliable(); } + +pub fn send_mrp_standalone_ack(exch: &mut Exchange, sess: &mut SessionHandle) -> Result<(), Error> { + info!("Sending standalone ACK"); + let mut ack_packet = Slab::::try_new(Packet::new_tx()?).ok_or(Error::NoMemory)?; + create_mrp_standalone_ack(&mut ack_packet); + exch.send(ack_packet, sess) +} diff --git a/matter/src/transport/exchange.rs b/matter/src/transport/exchange.rs index 54f8a7a..ae5711d 100644 --- a/matter/src/transport/exchange.rs +++ b/matter/src/transport/exchange.rs @@ -175,7 +175,7 @@ impl Exchange { } } - fn send( + pub fn send( &mut self, mut proto_tx: BoxSlab, session: &mut SessionHandle,