scll_core/transport.rs
1//! Transport abstraction — PDD §3.2.
2//!
3//! Blocking; per-APDU timeout owned by the transport. The caller owns the
4//! transport; the library borrows `&mut dyn Transport`. Reader enumeration is
5//! the transport's responsibility. Concrete adapters live in
6//! `scll-transport-pcsc` and `scll-transport-jcsim`.
7//!
8//! `no_std`: the trait is alloc-free even though the concrete PCSC/jcsim
9//! adapters are `std` host crates — they fill these bounded `heapless` buffers.
10//! `transmit` returns one short R-APDU (≤ `RAPDU_MAX`); `reset` returns ATR/ATS
11//! bytes (≤ `ATR_ATS_MAX`).
12
13use heapless::{String, Vec};
14
15use crate::limits::{ATR_ATS_MAX, OTHER_DETAIL_MAX, RAPDU_MAX};
16
17/// One short C-APDU in, one R-APDU out, plus capability/reset/liveness queries.
18pub trait Transport {
19 /// Send one short C-APDU, get one R-APDU. Per-call timeout enforced inside.
20 ///
21 /// # Errors
22 /// Returns a [`TransportError`] if the exchange fails — e.g.
23 /// [`TransportError::Timeout`], [`TransportError::CardRemoved`],
24 /// [`TransportError::ReaderGone`] or [`TransportError::ProtocolError`].
25 fn transmit(&mut self, capdu: &[u8]) -> Result<Vec<u8, RAPDU_MAX>, TransportError>;
26
27 /// Report transport capabilities (T=0 GET RESPONSE handling, protocol, contactless).
28 fn capabilities(&self) -> TransportCaps;
29
30 /// Cold/warm reset; return ATR (contact) or ATS (contactless).
31 ///
32 /// # Errors
33 /// Returns a [`TransportError`] if the card cannot be reset — e.g.
34 /// [`TransportError::ReaderGone`] or [`TransportError::ProtocolError`].
35 fn reset(&mut self) -> Result<AtrAts, TransportError>;
36
37 /// Currently negotiated protocol.
38 fn protocol(&self) -> TransportProtocol;
39
40 /// Liveness check without sending an APDU.
41 fn is_connected(&self) -> bool;
42}
43
44/// Transport-level failure taxonomy (PDD §3.2, minimum set).
45#[derive(Debug, Clone)]
46#[non_exhaustive]
47pub enum TransportError {
48 CardRemoved,
49 ReaderGone,
50 Timeout,
51 ProtocolError,
52 Other(String<OTHER_DETAIL_MAX>),
53}
54
55/// Self-reported transport capabilities.
56#[derive(Debug, Clone)]
57pub struct TransportCaps {
58 pub handles_t0_get_response: bool,
59 pub protocol: TransportProtocol,
60 pub contactless: bool,
61}
62
63/// Negotiated card protocol.
64#[derive(Debug, Clone, Copy, PartialEq, Eq)]
65pub enum TransportProtocol {
66 T0,
67 T1,
68 TCl,
69}
70
71/// Answer-To-Reset (contact) or Answer-To-Select (contactless) bytes.
72#[derive(Debug, Clone)]
73pub struct AtrAts {
74 pub bytes: Vec<u8, ATR_ATS_MAX>,
75 pub protocol: TransportProtocol,
76}