Here is the PCSC sample in Perl language I promised in PC/SC sample in different languages.
The wrapper works on GNU/Linux, Mac OS X and Windows.
The API documentation is available online at http://ludovic.rousseau.free.fr/softwares/pcsc-perl/PCSC.html and http://ludovic.rousseau.free.fr/softwares/pcsc-perl/Card.html.
You can also have a look at the project page project page on CPAN (Comprehensive Perl Archive Network).
The same code can be used on any plateform. No more #ifdef like in C.
The API is still low level and just wrap PC/SC calls from C to Perl.
TransmitWithCheck() is a little more easy to use than Transmit(). This method does the split between data and status word.
In the example above replace the two last blocks with:
This sample code also uses Chipcard::PCSC::Card::ISO7816Error($sw) to transform the status word is something human readable like Normal processing. for 90 00.
Installation
Get the source code from http://ludovic.rousseau.free.fr/softwares/pcsc-perl/. The current version is 1.4.8. If you distribution does not provide a package (Debian does with libpcsc-perl) you can install it by hand using:pcsc-perl-1.4.8$ perl Makefile.PL
osname: linux
LDDFLAGS:
INC: `pkg-config --cflags libpcsclite`
Checking if your kit is complete...
Looks good
Writing Makefile for Chipcard::PCSC::Card
Writing Makefile for Chipcard::PCSC
pcsc-perl-1.4.7$ make
[...]
pcsc-perl-1.4.7$ make test
[...]
pcsc-perl-1.4.7$ make install
[...]
The wrapper works on GNU/Linux, Mac OS X and Windows.
API
The API documentation is available online at http://ludovic.rousseau.free.fr/softwares/pcsc-perl/PCSC.html and http://ludovic.rousseau.free.fr/softwares/pcsc-perl/Card.html.
You can also have a look at the project page project page on CPAN (Comprehensive Perl Archive Network).
Source code
#!/usr/bin/perl -w
use Chipcard::PCSC;
# create a new object
$hContext = new Chipcard::PCSC();
die ("Can't create the PCSC object: $Chipcard::PCSC::errno\n")
unless defined $hContext;
# get the reader list
@ReadersList = $hContext->ListReaders();
die ("Can't get readers' list: $Chipcard::PCSC::errno\n")
unless defined $ReadersList[0];
# connect to the first reader
$hCard = new Chipcard::PCSC::Card($hContext, $ReadersList[0]);
die ("Can't connect: $Chipcard::PCSC::errno\n")
unless defined $hCard;
# send the Select Applet APDU
$cmd = Chipcard::PCSC::ascii_to_array("00 A4 04 00 0A A0 00 00 00 62 03 01 0C 06 01");
$RecvData = $hCard->Transmit($cmd);
die ("Can't transmit data: $Chipcard::PCSC::errno") unless defined $RecvData;
print Chipcard::PCSC::array_to_ascii($RecvData)."\n";
# send the test APDU
$cmd = Chipcard::PCSC::ascii_to_array("00 00 00 00");
$RecvData = $hCard->Transmit($cmd);
die ("Can't transmit data: $Chipcard::PCSC::errno") unless defined $RecvData;
print Chipcard::PCSC::array_to_ascii($RecvData)."\n";
$hCard->Disconnect();
Output
90 00
48 65 6C 6C 6F 20 77 6F 72 6C 64 21 90 00
Lessons learned
Portability
The same code can be used on any plateform. No more #ifdef like in C.
Low level API
The API is still low level and just wrap PC/SC calls from C to Perl.
Higher level API
TransmitWithCheck() is a little more easy to use than Transmit(). This method does the split between data and status word.
In the example above replace the two last blocks with:
# Send the Select Applet APDU
($sw, $RecvData) = $hCard->TransmitWithCheck("00 A4 04 00 0A A0 00 00 00 62 03 01 0C 06 01", "90 00");
die ("Can't transmit data: $Chipcard::PCSC::errno") unless defined $sw;
print $RecvData."\n";
print Chipcard::PCSC::Card::ISO7816Error($sw) . " ($sw)\n";
# Send the test APDU
($sw, $RecvData) = $hCard->TransmitWithCheck("00 00 00 00", "90 00");
die ("Can't transmit data: $Chipcard::PCSC::errno") unless defined $sw;
print $RecvData."\n";
print map { chr hex $_ } split ' ', $RecvData;
print "\n";
print Chipcard::PCSC::Card::ISO7816Error($sw) . " ($sw)\n";
This sample code also uses Chipcard::PCSC::Card::ISO7816Error($sw) to transform the status word is something human readable like Normal processing. for 90 00.
Output
Normal processing. (90 00)
48 65 6C 6C 6F 20 77 6F 72 6C 64 21
Hello world!
Normal processing. (90 00)
ConversionConversion EmoticonEmoticon