Struct pcsc::CardStatus

source ·
pub struct CardStatus<'names_buf, 'atr_buf> { /* private fields */ }
Expand description

Status of a card in a card reader.

Implementations§

source§

impl<'names_buf, 'atr_buf> CardStatus<'names_buf, 'atr_buf>

source

pub fn reader_names(&self) -> ReaderNames<'names_buf>

Iterator over the names by which the connected card reader is known.

Examples found in repository?
examples/connect.rs (line 39)
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
fn main() {
    // Get a context.
    let ctx = Context::establish(Scope::User).expect("failed to establish context");

    // List connected readers.
    let mut readers_buf = [0; 2048];
    let readers = ctx
        .list_readers(&mut readers_buf)
        .expect("failed to list readers")
        .collect::<Vec<_>>();
    println!("Readers: {:?}", readers);

    if readers.is_empty() {
        return;
    }

    {
        // Try to connect to a card in the first reader.
        let mut card = ctx
            .connect(readers[0], ShareMode::Shared, Protocols::ANY)
            .expect("failed to connect to card");

        {
            // Start an exclusive transaction (not required -- can work on card directly).
            let tx = card.transaction().expect("failed to begin card transaction");

            // Get the card status.
            let (names_len, _atr_len) = tx.status2_len().expect("failed to get the status length");
            let mut names_buf = vec![0; names_len];
            let mut atr_buf = [0; MAX_ATR_SIZE];
            let status = tx
                .status2(&mut names_buf, &mut atr_buf)
                .expect("failed to get card status");
            println!("Status from status: {:?}", status.status());
            println!(
                "Reader names from status: {:?}",
                status.reader_names().collect::<Vec<_>>()
            );
            if let Some(protocol) = status.protocol2() {
                println!("Protocol from status: {:?}", protocol);
            } else {
                println!("Protocol from status: directly connected");
            }
            println!("ATR from status: {:?}", status.atr());

            // Send some harmless APDU to the card.
            if let Some(_) = status.protocol2() {
                let apdu = b"\x00\xa4\x04\x00\x08\x31\x54\x49\x43\x2e\x49\x43\x41";
                let mut rapdu_buf = [0; MAX_BUFFER_SIZE];
                let rapdu = tx
                    .transmit(apdu, &mut rapdu_buf)
                    .expect("failed to transmit APDU to card");
                println!("RAPDU: {:?}", rapdu);
            }

            // Get the card's ATR.
            let mut atr_buf = [0; MAX_ATR_SIZE];
            let atr = tx
                .get_attribute(Attribute::AtrString, &mut atr_buf)
                .expect("failed to get ATR attribute");
            println!("ATR from attribute: {:?}", atr);

            // Get some attribute.
            let mut ifd_version_buf = [0; 4];
            let ifd_version = tx
                .get_attribute(Attribute::VendorIfdVersion, &mut ifd_version_buf)
                .expect("failed to get vendor IFD version attribute");
            println!("Vendor IFD version: {:?}", ifd_version);

            // Get some other attribute.
            // This time we allocate a buffer of the needed length.
            let vendor_name_len = tx
                .get_attribute_len(Attribute::VendorName)
                .expect("failed to get the vendor name attribute length");
            let mut vendor_name_buf = vec![0; vendor_name_len];
            let vendor_name = tx
                .get_attribute(Attribute::VendorName, &mut vendor_name_buf)
                .expect("failed to get vendor name attribute");
            println!("Vendor name: {}", std::str::from_utf8(vendor_name).unwrap());

            // Can either end explicity, which allows error handling,
            // and setting the disposition method, or leave it to drop, which
            // swallows any error and hardcodes LeaveCard.
            tx.end(Disposition::LeaveCard)
                .map_err(|(_, err)| err)
                .expect("failed to end transaction");
        }

        // Can either disconnect explicity, which allows error handling,
        // and setting the disposition method, or leave it to drop, which
        // swallows any error and hardcodes ResetCard.
        card.disconnect(Disposition::ResetCard)
            .map_err(|(_, err)| err)
            .expect("failed to disconnect from card");
    }

    // Can either release explicity, which allows error handling,
    // or leave it to drop, which swallows any error.
    // The function fails if there are any live clones.
    ctx.release()
        .map_err(|(_, err)| err)
        .expect("failed to release context");
}
source

pub fn status(&self) -> Status

Current status of the smart card in the reader.

Examples found in repository?
examples/connect.rs (line 36)
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
fn main() {
    // Get a context.
    let ctx = Context::establish(Scope::User).expect("failed to establish context");

    // List connected readers.
    let mut readers_buf = [0; 2048];
    let readers = ctx
        .list_readers(&mut readers_buf)
        .expect("failed to list readers")
        .collect::<Vec<_>>();
    println!("Readers: {:?}", readers);

    if readers.is_empty() {
        return;
    }

    {
        // Try to connect to a card in the first reader.
        let mut card = ctx
            .connect(readers[0], ShareMode::Shared, Protocols::ANY)
            .expect("failed to connect to card");

        {
            // Start an exclusive transaction (not required -- can work on card directly).
            let tx = card.transaction().expect("failed to begin card transaction");

            // Get the card status.
            let (names_len, _atr_len) = tx.status2_len().expect("failed to get the status length");
            let mut names_buf = vec![0; names_len];
            let mut atr_buf = [0; MAX_ATR_SIZE];
            let status = tx
                .status2(&mut names_buf, &mut atr_buf)
                .expect("failed to get card status");
            println!("Status from status: {:?}", status.status());
            println!(
                "Reader names from status: {:?}",
                status.reader_names().collect::<Vec<_>>()
            );
            if let Some(protocol) = status.protocol2() {
                println!("Protocol from status: {:?}", protocol);
            } else {
                println!("Protocol from status: directly connected");
            }
            println!("ATR from status: {:?}", status.atr());

            // Send some harmless APDU to the card.
            if let Some(_) = status.protocol2() {
                let apdu = b"\x00\xa4\x04\x00\x08\x31\x54\x49\x43\x2e\x49\x43\x41";
                let mut rapdu_buf = [0; MAX_BUFFER_SIZE];
                let rapdu = tx
                    .transmit(apdu, &mut rapdu_buf)
                    .expect("failed to transmit APDU to card");
                println!("RAPDU: {:?}", rapdu);
            }

            // Get the card's ATR.
            let mut atr_buf = [0; MAX_ATR_SIZE];
            let atr = tx
                .get_attribute(Attribute::AtrString, &mut atr_buf)
                .expect("failed to get ATR attribute");
            println!("ATR from attribute: {:?}", atr);

            // Get some attribute.
            let mut ifd_version_buf = [0; 4];
            let ifd_version = tx
                .get_attribute(Attribute::VendorIfdVersion, &mut ifd_version_buf)
                .expect("failed to get vendor IFD version attribute");
            println!("Vendor IFD version: {:?}", ifd_version);

            // Get some other attribute.
            // This time we allocate a buffer of the needed length.
            let vendor_name_len = tx
                .get_attribute_len(Attribute::VendorName)
                .expect("failed to get the vendor name attribute length");
            let mut vendor_name_buf = vec![0; vendor_name_len];
            let vendor_name = tx
                .get_attribute(Attribute::VendorName, &mut vendor_name_buf)
                .expect("failed to get vendor name attribute");
            println!("Vendor name: {}", std::str::from_utf8(vendor_name).unwrap());

            // Can either end explicity, which allows error handling,
            // and setting the disposition method, or leave it to drop, which
            // swallows any error and hardcodes LeaveCard.
            tx.end(Disposition::LeaveCard)
                .map_err(|(_, err)| err)
                .expect("failed to end transaction");
        }

        // Can either disconnect explicity, which allows error handling,
        // and setting the disposition method, or leave it to drop, which
        // swallows any error and hardcodes ResetCard.
        card.disconnect(Disposition::ResetCard)
            .map_err(|(_, err)| err)
            .expect("failed to disconnect from card");
    }

    // Can either release explicity, which allows error handling,
    // or leave it to drop, which swallows any error.
    // The function fails if there are any live clones.
    ctx.release()
        .map_err(|(_, err)| err)
        .expect("failed to release context");
}
source

pub fn protocol2(&self) -> Option<Protocol>

Current protocol of the card, if any.

The value is meaningful only if a communication protocol has already been established.

If connected to a reader directly without an active protocol, returns None.

Examples found in repository?
examples/connect.rs (line 41)
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
fn main() {
    // Get a context.
    let ctx = Context::establish(Scope::User).expect("failed to establish context");

    // List connected readers.
    let mut readers_buf = [0; 2048];
    let readers = ctx
        .list_readers(&mut readers_buf)
        .expect("failed to list readers")
        .collect::<Vec<_>>();
    println!("Readers: {:?}", readers);

    if readers.is_empty() {
        return;
    }

    {
        // Try to connect to a card in the first reader.
        let mut card = ctx
            .connect(readers[0], ShareMode::Shared, Protocols::ANY)
            .expect("failed to connect to card");

        {
            // Start an exclusive transaction (not required -- can work on card directly).
            let tx = card.transaction().expect("failed to begin card transaction");

            // Get the card status.
            let (names_len, _atr_len) = tx.status2_len().expect("failed to get the status length");
            let mut names_buf = vec![0; names_len];
            let mut atr_buf = [0; MAX_ATR_SIZE];
            let status = tx
                .status2(&mut names_buf, &mut atr_buf)
                .expect("failed to get card status");
            println!("Status from status: {:?}", status.status());
            println!(
                "Reader names from status: {:?}",
                status.reader_names().collect::<Vec<_>>()
            );
            if let Some(protocol) = status.protocol2() {
                println!("Protocol from status: {:?}", protocol);
            } else {
                println!("Protocol from status: directly connected");
            }
            println!("ATR from status: {:?}", status.atr());

            // Send some harmless APDU to the card.
            if let Some(_) = status.protocol2() {
                let apdu = b"\x00\xa4\x04\x00\x08\x31\x54\x49\x43\x2e\x49\x43\x41";
                let mut rapdu_buf = [0; MAX_BUFFER_SIZE];
                let rapdu = tx
                    .transmit(apdu, &mut rapdu_buf)
                    .expect("failed to transmit APDU to card");
                println!("RAPDU: {:?}", rapdu);
            }

            // Get the card's ATR.
            let mut atr_buf = [0; MAX_ATR_SIZE];
            let atr = tx
                .get_attribute(Attribute::AtrString, &mut atr_buf)
                .expect("failed to get ATR attribute");
            println!("ATR from attribute: {:?}", atr);

            // Get some attribute.
            let mut ifd_version_buf = [0; 4];
            let ifd_version = tx
                .get_attribute(Attribute::VendorIfdVersion, &mut ifd_version_buf)
                .expect("failed to get vendor IFD version attribute");
            println!("Vendor IFD version: {:?}", ifd_version);

            // Get some other attribute.
            // This time we allocate a buffer of the needed length.
            let vendor_name_len = tx
                .get_attribute_len(Attribute::VendorName)
                .expect("failed to get the vendor name attribute length");
            let mut vendor_name_buf = vec![0; vendor_name_len];
            let vendor_name = tx
                .get_attribute(Attribute::VendorName, &mut vendor_name_buf)
                .expect("failed to get vendor name attribute");
            println!("Vendor name: {}", std::str::from_utf8(vendor_name).unwrap());

            // Can either end explicity, which allows error handling,
            // and setting the disposition method, or leave it to drop, which
            // swallows any error and hardcodes LeaveCard.
            tx.end(Disposition::LeaveCard)
                .map_err(|(_, err)| err)
                .expect("failed to end transaction");
        }

        // Can either disconnect explicity, which allows error handling,
        // and setting the disposition method, or leave it to drop, which
        // swallows any error and hardcodes ResetCard.
        card.disconnect(Disposition::ResetCard)
            .map_err(|(_, err)| err)
            .expect("failed to disconnect from card");
    }

    // Can either release explicity, which allows error handling,
    // or leave it to drop, which swallows any error.
    // The function fails if there are any live clones.
    ctx.release()
        .map_err(|(_, err)| err)
        .expect("failed to release context");
}
source

pub fn protocol(&self) -> Protocol

Current protocol of the card, if any.

The value is meaningful only if a communication protocol has already been established.

Panics

This function panics when connected to a reader directly without an active protocol. Use protocol2() instead if you want to avoid this.

source

pub fn atr(&self) -> &'atr_buf [u8]

The current ATR string of the card.

Examples found in repository?
examples/connect.rs (line 46)
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
fn main() {
    // Get a context.
    let ctx = Context::establish(Scope::User).expect("failed to establish context");

    // List connected readers.
    let mut readers_buf = [0; 2048];
    let readers = ctx
        .list_readers(&mut readers_buf)
        .expect("failed to list readers")
        .collect::<Vec<_>>();
    println!("Readers: {:?}", readers);

    if readers.is_empty() {
        return;
    }

    {
        // Try to connect to a card in the first reader.
        let mut card = ctx
            .connect(readers[0], ShareMode::Shared, Protocols::ANY)
            .expect("failed to connect to card");

        {
            // Start an exclusive transaction (not required -- can work on card directly).
            let tx = card.transaction().expect("failed to begin card transaction");

            // Get the card status.
            let (names_len, _atr_len) = tx.status2_len().expect("failed to get the status length");
            let mut names_buf = vec![0; names_len];
            let mut atr_buf = [0; MAX_ATR_SIZE];
            let status = tx
                .status2(&mut names_buf, &mut atr_buf)
                .expect("failed to get card status");
            println!("Status from status: {:?}", status.status());
            println!(
                "Reader names from status: {:?}",
                status.reader_names().collect::<Vec<_>>()
            );
            if let Some(protocol) = status.protocol2() {
                println!("Protocol from status: {:?}", protocol);
            } else {
                println!("Protocol from status: directly connected");
            }
            println!("ATR from status: {:?}", status.atr());

            // Send some harmless APDU to the card.
            if let Some(_) = status.protocol2() {
                let apdu = b"\x00\xa4\x04\x00\x08\x31\x54\x49\x43\x2e\x49\x43\x41";
                let mut rapdu_buf = [0; MAX_BUFFER_SIZE];
                let rapdu = tx
                    .transmit(apdu, &mut rapdu_buf)
                    .expect("failed to transmit APDU to card");
                println!("RAPDU: {:?}", rapdu);
            }

            // Get the card's ATR.
            let mut atr_buf = [0; MAX_ATR_SIZE];
            let atr = tx
                .get_attribute(Attribute::AtrString, &mut atr_buf)
                .expect("failed to get ATR attribute");
            println!("ATR from attribute: {:?}", atr);

            // Get some attribute.
            let mut ifd_version_buf = [0; 4];
            let ifd_version = tx
                .get_attribute(Attribute::VendorIfdVersion, &mut ifd_version_buf)
                .expect("failed to get vendor IFD version attribute");
            println!("Vendor IFD version: {:?}", ifd_version);

            // Get some other attribute.
            // This time we allocate a buffer of the needed length.
            let vendor_name_len = tx
                .get_attribute_len(Attribute::VendorName)
                .expect("failed to get the vendor name attribute length");
            let mut vendor_name_buf = vec![0; vendor_name_len];
            let vendor_name = tx
                .get_attribute(Attribute::VendorName, &mut vendor_name_buf)
                .expect("failed to get vendor name attribute");
            println!("Vendor name: {}", std::str::from_utf8(vendor_name).unwrap());

            // Can either end explicity, which allows error handling,
            // and setting the disposition method, or leave it to drop, which
            // swallows any error and hardcodes LeaveCard.
            tx.end(Disposition::LeaveCard)
                .map_err(|(_, err)| err)
                .expect("failed to end transaction");
        }

        // Can either disconnect explicity, which allows error handling,
        // and setting the disposition method, or leave it to drop, which
        // swallows any error and hardcodes ResetCard.
        card.disconnect(Disposition::ResetCard)
            .map_err(|(_, err)| err)
            .expect("failed to disconnect from card");
    }

    // Can either release explicity, which allows error handling,
    // or leave it to drop, which swallows any error.
    // The function fails if there are any live clones.
    ctx.release()
        .map_err(|(_, err)| err)
        .expect("failed to release context");
}

Trait Implementations§

source§

impl<'names_buf, 'atr_buf> Clone for CardStatus<'names_buf, 'atr_buf>

source§

fn clone(&self) -> CardStatus<'names_buf, 'atr_buf>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'names_buf, 'atr_buf> Debug for CardStatus<'names_buf, 'atr_buf>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'names_buf, 'atr_buf> RefUnwindSafe for CardStatus<'names_buf, 'atr_buf>

§

impl<'names_buf, 'atr_buf> Send for CardStatus<'names_buf, 'atr_buf>

§

impl<'names_buf, 'atr_buf> Sync for CardStatus<'names_buf, 'atr_buf>

§

impl<'names_buf, 'atr_buf> Unpin for CardStatus<'names_buf, 'atr_buf>

§

impl<'names_buf, 'atr_buf> UnwindSafe for CardStatus<'names_buf, 'atr_buf>

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.