use pcsc::*;
fn main() {
let ctx = Context::establish(Scope::User).expect("failed to establish context");
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;
}
{
let mut card = ctx
.connect(readers[0], ShareMode::Shared, Protocols::ANY)
.expect("failed to connect to card");
{
let tx = card.transaction().expect("failed to begin card transaction");
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());
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);
}
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);
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);
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());
tx.end(Disposition::LeaveCard)
.map_err(|(_, err)| err)
.expect("failed to end transaction");
}
card.disconnect(Disposition::ResetCard)
.map_err(|(_, err)| err)
.expect("failed to disconnect from card");
}
ctx.release()
.map_err(|(_, err)| err)
.expect("failed to release context");
}