use crate::command::{build, push_lv, BuildError, Capdu};
const BEGIN_P1_RMAC: u8 = 0x10;
const END_P2_END_AND_RETURN: u8 = 0x03;
const END_P2_RETURN_ONLY: u8 = 0x01;
#[allow(clippy::module_name_repetitions)] pub fn begin_rmac_session(data: &[u8]) -> Result<Capdu, BuildError> {
if data.is_empty() || data.len() > 24 {
return Err(BuildError::Overflow);
}
let mut field = Capdu::new();
push_lv(&mut field, data)?; build(0x80, 0x7A, BEGIN_P1_RMAC, 0x00, &field, true)
}
#[must_use]
#[allow(clippy::module_name_repetitions)] pub fn end_rmac_session(end_session: bool) -> Capdu {
let p2 = if end_session {
END_P2_END_AND_RETURN
} else {
END_P2_RETURN_ONLY
};
let mut apdu = Capdu::new();
let _ = apdu.extend_from_slice(&[0x80, 0x78, 0x00, p2, 0x00]);
apdu
}
#[cfg(test)]
mod tests {
use super::*;
use scll_test_util::HexSlice;
#[test]
fn begin_wraps_data_lv_with_p1_10() {
let apdu = begin_rmac_session(&[0xA1, 0xB2, 0xC3]).unwrap();
assert_eq!(
HexSlice(&apdu),
HexSlice([0x80, 0x7A, 0x10, 0x00, 0x04, 0x03, 0xA1, 0xB2, 0xC3, 0x00])
);
}
#[test]
fn begin_rejects_empty_and_oversized_data() {
assert_eq!(begin_rmac_session(&[]), Err(BuildError::Overflow));
assert_eq!(begin_rmac_session(&[0u8; 25]), Err(BuildError::Overflow));
assert!(begin_rmac_session(&[0u8; 24]).is_ok());
}
#[test]
fn end_p2_selects_end_vs_return_only() {
assert_eq!(
HexSlice(&end_rmac_session(true)),
HexSlice([0x80, 0x78, 0x00, 0x03, 0x00])
);
assert_eq!(
HexSlice(&end_rmac_session(false)),
HexSlice([0x80, 0x78, 0x00, 0x01, 0x00])
);
}
}