use num_derive::FromPrimitive;
use crate::{
error::Error,
transport::{exchange::Exchange, packet::Packet},
};
use super::status_report::{create_status_report, GeneralCode};
pub const PROTO_ID_SECURE_CHANNEL: u16 = 0x00;
#[derive(FromPrimitive, Debug, Copy, Clone, Eq, PartialEq)]
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 async fn complete_with_status(
exchange: &mut Exchange<'_>,
tx: &mut Packet<'_>,
status_code: SCStatusCodes,
proto_data: Option<&[u8]>,
) -> Result<(), Error> {
create_sc_status_report(tx, status_code, proto_data)?;
exchange.send_complete(tx).await
}
pub fn create_sc_status_report(
proto_tx: &mut Packet,
status_code: SCStatusCodes,
proto_data: Option<&[u8]>,
) -> Result<(), Error> {
let general_code = match status_code {
SCStatusCodes::SessionEstablishmentSuccess => GeneralCode::Success,
SCStatusCodes::CloseSession => {
proto_tx.unset_reliable();
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();
}