use {
std::{
io::{
Write,
IoSlice,
},
},
super::{
asn1,
CaDevice,
spdu,
},
crate::error::{
Error,
Result,
},
};
pub use {
ca_tpdu_tag::*,
};
pub const TPDU_SIZE_MAX: usize = 2048;
mod ca_tpdu_tag {
pub const TT_SB: u8 = 0x80;
pub const TT_RCV: u8 = 0x81;
pub const TT_CREATE_TC: u8 = 0x82;
pub const TT_CTC_REPLY: u8 = 0x83;
pub const TT_DELETE_TC: u8 = 0x84;
pub const TT_DTC_REPLY: u8 = 0x85;
pub const TT_REQUEST_TC: u8 = 0x86;
pub const TT_NEW_TC: u8 = 0x87;
pub const TT_TC_ERROR: u8 = 0x88;
pub const TT_DATA_LAST: u8 = 0xA0;
pub const TT_DATA_MORE: u8 = 0xA1;
}
pub fn _read(ca: &mut CaDevice, data: &[u8]) -> Result<()> {
if data.len() < 4 {
return Err(Error::InvalidData("invalid ca tpdu packet size".to_owned()));
}
if data[1] == 0 {
return Err(Error::InvalidData(format!("invalid ca tpdu slot id {}", data[1])));
}
let slot_id = data[1] - 1;
let tag = data[2];
match tag {
TT_CTC_REPLY => {
}
TT_DTC_REPLY => {
}
TT_DATA_MORE => {
}
TT_DATA_LAST => {
spdu::handle(ca, slot_id, &[])?;
}
TT_SB => {}
_ => {
return Err(Error::InvalidData(format!("invalid ca tpdu tag 0x{:02X}", tag)));
}
}
Ok(())
}
pub fn send(ca: &CaDevice, slot_id: u8, tag: u8, data: &[u8]) -> Result<()> {
if data.len() >= TPDU_SIZE_MAX {
return Err(Error::InvalidData("ca tpdu packet is to large".to_owned()));
}
let t_c_id = slot_id + 1;
let mut header: Vec<u8> = Vec::with_capacity(8);
header.push(slot_id);
header.push(t_c_id);
header.push(tag);
asn1::encode(data.len() as u16 + 1, &mut header);
header.push(t_c_id);
let bufs = &mut [
IoSlice::new(&header),
IoSlice::new(data),
];
(&ca.file).write_vectored(bufs)?;
Ok(())
}
pub fn init(ca: &CaDevice, slot_id: u8) -> Result<()> {
send(ca, slot_id, TT_CREATE_TC, &[])
}