Skip to content

Commit bd2c373

Browse files
update README with PCD usage example and functionalities
1 parent c099568 commit bd2c373

File tree

1 file changed

+68
-5
lines changed

1 file changed

+68
-5
lines changed

README.md

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,82 @@ SPDX-License-Identifier: GPL-3.0-or-later
99

1010
Rust library to manipulate ISO/IEC 14443 data.
1111

12-
## Fontionalities
12+
## Functionalities
1313

1414
- [x] Type-A
1515
- [x] iso14443-3: REQA/WUPA/ATQA/ANTICOLLISION/SELECT/SAK/HLTA
16-
- [x] CRC_A checks
16+
- [x] iso14443-3: CRC_A checks (hardware-accelerated or software)
17+
- [x] iso14443-3: PCD activation with anticollision cascade (4/7/10-byte UIDs)
1718
- [x] iso14443-4: RATS/ATS/PPS
1819
- [x] iso14443-4: PCB (Protocol Control Byte)
1920
- [x] iso14443-4: Block format (I-block, R-block, S-block)
20-
- [x] iso14443-4: Block chaining
21-
- [x] iso14443-4: Protocol state machine
21+
- [x] iso14443-4: PCD transport layer (APDU exchange, chaining, WTX, error recovery, DESELECT)
22+
- [x] iso14443-4: Generic block protocol handler (reusable for PCD and PICC)
2223
- [ ] Type-B
2324

24-
## Example Usage
25+
## Usage
26+
27+
```rust
28+
use iso14443::type_a::{
29+
activation::{activate, ActivationError},
30+
pcd::{Pcd, PcdError},
31+
vec::FrameVec,
32+
Cid, Frame, Fsdi, PcdTransceiver,
33+
};
34+
35+
/// Dummy PCD transceiver — replace with your real hardware driver
36+
/// (e.g. SPI to an NXP PN532 or ST25R3916).
37+
struct MyTransceiver;
38+
39+
#[derive(Debug)]
40+
struct MyError;
41+
42+
impl PcdTransceiver for MyTransceiver {
43+
type Error = MyError;
44+
45+
fn transceive(&mut self, _frame: &Frame) -> Result<FrameVec, MyError> {
46+
// Send frame bytes over SPI/I2C/UART, return the PICC response.
47+
todo!("implement for your hardware")
48+
}
49+
50+
fn enable_hw_crc(&mut self) -> Result<(), MyError> {
51+
// Enable hardware CRC if the chip supports it.
52+
// Return Err to fall back to software CRC.
53+
Err(MyError)
54+
}
55+
}
56+
57+
fn talk_to_card(t: &mut MyTransceiver) -> Result<(), Box<dyn std::error::Error>> {
58+
// ISO14443-3A: detect tag, resolve UID
59+
let activation = activate(t).map_err(|e| format!("{e:?}"))?;
60+
println!("UID: {:02x?}", activation.uid.as_slice());
61+
62+
// Only proceed to ISO14443-4 if the tag supports it
63+
if !activation.sak.iso14443_4_compliant {
64+
println!("Tag does not support ISO14443-4");
65+
return Ok(());
66+
}
67+
68+
// ISO14443-4: RATS/ATS negotiation, open a session
69+
let cid = Cid::new(0).unwrap();
70+
let (mut pcd, ats) = Pcd::connect(t, Fsdi::Fsd256, cid)
71+
.map_err(|e| format!("{e:?}"))?;
72+
println!("ATS: {ats:?}");
73+
74+
// Exchange an APDU (e.g. SELECT application)
75+
let select_apdu = [0x00, 0xA4, 0x04, 0x00, 0x07,
76+
0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01, 0x00];
77+
let response = pcd.exchange(&select_apdu)
78+
.map_err(|e| format!("{e:?}"))?;
79+
println!("Response: {:02x?}", response.as_slice());
80+
81+
// Clean up
82+
pcd.deselect().map_err(|e| format!("{e:?}"))?;
83+
Ok(())
84+
}
85+
```
86+
87+
## CLI Parser
2588

2689
An example is provided to parse raw data from the ISO14443 protocol:
2790

0 commit comments

Comments
 (0)