>From my blog http://ludovicrousseau.blogspot.com/

PCSC sample in Perl
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)

-- 
 Dr. Ludovic Rousseau
_______________________________________________
Muscle mailing list
[email protected]
http://lists.drizzle.com/mailman/listinfo/muscle

Reply via email to