connect_owned/
connect-owned.rs

1// Example of communication with a smart card.
2use pcsc::*;
3
4fn main() {
5    // Get a context.
6    let ctx = Context::establish(Scope::User).expect("failed to establish context");
7
8    // List connected readers.
9    let readers = ctx.list_readers_owned().expect("failed to list readers");
10    println!("Readers: {:?}", readers);
11
12    if readers.is_empty() {
13        return;
14    }
15
16    {
17        // Try to connect to a card in the first reader.
18        let mut card = ctx
19            .connect(&readers[0], ShareMode::Shared, Protocols::ANY)
20            .expect("failed to connect to card");
21
22        {
23            // Start an exclusive transaction (not required -- can work on card directly).
24            let tx = card.transaction().expect("failed to begin card transaction");
25
26            // Get the card status.
27            let status = tx.status2_owned().expect("failed to get card status");
28            println!("Reader names from status: {:?}", status.reader_names());
29            if let Some(protocol) = status.protocol2() {
30                println!("Protocol from status: {:?}", protocol);
31            } else {
32                println!("Protocol from status: directly connected");
33            }
34            println!("ATR from status: {:?}", status.atr());
35
36            // Send some harmless APDU to the card.
37            if let Some(_) = status.protocol2() {
38                let apdu = b"\x00\xa4\x04\x00\x08\x31\x54\x49\x43\x2e\x49\x43\x41";
39                let mut rapdu_buf = [0; MAX_BUFFER_SIZE];
40                let rapdu = tx
41                    .transmit(apdu, &mut rapdu_buf)
42                    .expect("failed to transmit APDU to card");
43                println!("RAPDU: {:?}", rapdu);
44            }
45
46            // Get the card's ATR.
47            let atr = tx
48                .get_attribute_owned(Attribute::AtrString)
49                .expect("failed to get ATR attribute");
50            println!("ATR from attribute: {:?}", atr);
51
52            // Get some attribute.
53            let ifd_version = tx
54                .get_attribute_owned(Attribute::VendorIfdVersion)
55                .expect("failed to get vendor IFD version attribute");
56            println!("Vendor IFD version: {:?}", ifd_version);
57
58            // Get some other attribute.
59            let vendor_name = tx
60                .get_attribute_owned(Attribute::VendorName)
61                .expect("failed to get vendor name attribute");
62            println!("Vendor name: {}", String::from_utf8(vendor_name).unwrap());
63
64            // Can either end explicity, which allows error handling,
65            // and setting the disposition method, or leave it to drop, which
66            // swallows any error and hardcodes LeaveCard.
67            tx.end(Disposition::LeaveCard)
68                .map_err(|(_, err)| err)
69                .expect("failed to end transaction");
70        }
71
72        // Can either disconnect explicity, which allows error handling,
73        // and setting the disposition method, or leave it to drop, which
74        // swallows any error and hardcodes ResetCard.
75        card.disconnect(Disposition::ResetCard)
76            .map_err(|(_, err)| err)
77            .expect("failed to disconnect from card");
78    }
79
80    // Can either release explicity, which allows error handling,
81    // or leave it to drop, which swallows any error.
82    // The function fails if there are any live clones.
83    ctx.release()
84        .map_err(|(_, err)| err)
85        .expect("failed to release context");
86}