#![allow(dead_code)]
use {
super::{asn1, spdu, CaDevice},
anyhow::{Context, Result},
std::io::{IoSlice, Write},
};
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(anyhow!("CA TPDU: invalid packet size"));
}
if data[1] == 0
{
return Err(anyhow!("CA TPDU: invalid 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(anyhow!("CA TPDU: invalid 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(anyhow!("CA TPDU: packet is to large"));
}
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)
.context("CA TPDU: write failed")?;
Ok(())
}
pub fn init(ca: &CaDevice, slot_id: u8) -> Result<()> {
send(ca, slot_id, TT_CREATE_TC, &[])
}