use core::future::Future;
use crate::error::*;
use crate::respond::ExchangeHandler;
use crate::transport::exchange::Exchange;
use super::{sc_write, OpCode, SCStatusCodes, PROTO_ID_SECURE_CHANNEL};
pub struct BusySecureChannel(());
impl Default for BusySecureChannel {
fn default() -> Self {
Self::new()
}
}
impl BusySecureChannel {
const BUSY_RETRY_DELAY_MS: u16 = 500;
#[inline(always)]
pub const fn new() -> Self {
Self(())
}
pub async fn handle(&self, mut exchange: Exchange<'_>) -> Result<(), Error> {
let meta = exchange.recv().await?.meta();
if meta.proto_id != PROTO_ID_SECURE_CHANNEL {
Err(ErrorCode::InvalidProto)?;
}
match meta.opcode()? {
OpCode::PBKDFParamRequest | OpCode::CASESigma1 => {
exchange
.send_with(|_, wb| {
sc_write(
wb,
SCStatusCodes::Busy,
&u16::to_le_bytes(Self::BUSY_RETRY_DELAY_MS),
)
})
.await
}
proto_opcode => {
error!("OpCode not handled: {:?}", proto_opcode);
Err(ErrorCode::InvalidOpcode.into())
}
}
}
}
impl ExchangeHandler for BusySecureChannel {
fn handle(&self, exchange: Exchange<'_>) -> impl Future<Output = Result<(), Error>> {
BusySecureChannel::handle(self, exchange)
}
}