/* * * 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 num_derive::FromPrimitive; use crate::{error::Error, transport::packet::Packet}; use super::status_report::{create_status_report, GeneralCode}; /* Interaction Model ID as per the Matter Spec */ pub const PROTO_ID_SECURE_CHANNEL: u16 = 0x00; #[derive(FromPrimitive, Debug)] pub enum OpCode { MsgCounterSyncReq = 0x00, MsgCounterSyncResp = 0x01, MRPStandAloneAck = 0x10, PBKDFParamRequest = 0x20, PBKDFParamResponse = 0x21, PASEPake1 = 0x22, PASEPake2 = 0x23, PASEPake3 = 0x24, CASESigma1 = 0x30, CASESigma2 = 0x31, CASESigma3 = 0x32, CASESigma2Resume = 0x33, StatusReport = 0x40, } #[derive(PartialEq)] pub enum SCStatusCodes { SessionEstablishmentSuccess = 0, NoSharedTrustRoots = 1, InvalidParameter = 2, CloseSession = 3, Busy = 4, SessionNotFound = 5, } pub fn create_sc_status_report( proto_tx: &mut Packet, status_code: SCStatusCodes, proto_data: Option<&[u8]>, ) -> Result<(), Error> { proto_tx.reset(); let general_code = match status_code { SCStatusCodes::SessionEstablishmentSuccess => GeneralCode::Success, SCStatusCodes::CloseSession => { proto_tx.unset_reliable(); // No time to manage reliable delivery for close session // the session will be closed soon GeneralCode::Success } SCStatusCodes::Busy | SCStatusCodes::InvalidParameter | SCStatusCodes::NoSharedTrustRoots | SCStatusCodes::SessionNotFound => GeneralCode::Failure, }; create_status_report( proto_tx, general_code, PROTO_ID_SECURE_CHANNEL as u32, status_code as u16, proto_data, ) } pub fn create_mrp_standalone_ack(proto_tx: &mut Packet) { proto_tx.reset(); proto_tx.set_proto_id(PROTO_ID_SECURE_CHANNEL); proto_tx.set_proto_opcode(OpCode::MRPStandAloneAck as u8); proto_tx.unset_reliable(); } // TODO // 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) // }