#!/usr/bin/perl
# test.pl: simple sample program to test the PCSC Perl wrapper
# Copyright (C) 2001 Lionel Victor, 2003,2006 Ludovic Rousseau
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# $Id: test.pl,v 1.15 2011/03/06 15:51:42 rousseau Exp $
use Test::More;
use Chipcard::PCSC;
use Chipcard::PCSC::Card;
plan 'no_plan';
use warnings;
use strict;
my $hContext;
my @ReadersList;
my $hCard;
my @StatusResult;
my $tmpVal;
my $SendData;
my $RecvData;
my $sw;
#--------------------------------------------------------------------------
diag("Getting context:");
$hContext = new Chipcard::PCSC();
die ("Can't create the pcsc object: $Chipcard::PCSC::errno\n") unless (defined $hContext);
ok(defined $hContext, "new Chipcard::PCSC()");
#--------------------------------------------------------------------------
diag("Retrieving readers'list:");
@ReadersList = $hContext->ListReaders ();
die ("Can't get readers' list: $Chipcard::PCSC::errno\n") unless (defined($ReadersList[0]));
$, = "\n ";
$" = "\n ";
ok(defined($ReadersList[0]), "\$hContext->ListReaders ()");
diag(@ReadersList);
#--------------------------------------------------------------------------
diag("Getting status change:");
my (@readers_states, $reader_state, $timeout, $event_state);
# create the list or readers to watch
map { push @readers_states, ({'reader_name'=>"$_"}) } @ReadersList;
@StatusResult = $hContext->GetStatusChange(\@readers_states);
for my $i (0..$#readers_states)
{
diag("reader: " . $readers_states[$i]{'reader_name'});
diag(" ATR: " . Chipcard::PCSC::array_to_ascii($readers_states[$i]{'ATR'}))
if (defined $readers_states[$i]{'ATR'});
diag(" state:");
$event_state = $readers_states[$i]{'event_state'};
diag(" state changed")
if ($event_state & $Chipcard::PCSC::SCARD_STATE_CHANGED);
diag(" card present")
if ($event_state & $Chipcard::PCSC::SCARD_STATE_PRESENT);
diag(" card absent")
if ($event_state & $Chipcard::PCSC::SCARD_STATE_EMPTY);
diag(" card mute")
if ($event_state & $Chipcard::PCSC::SCARD_STATE_MUTE);
$readers_states[$i]{'current_state'} = $event_state;
}
if (! ($readers_states[0]{'event_state'} &
$Chipcard::PCSC::SCARD_STATE_PRESENT))
{
$timeout = 10 * 1000; # 10 seconds
diag("Insert a card in the first reader please (timeout in $timeout ms)");
@StatusResult = $hContext->GetStatusChange(\@readers_states, $timeout);
}
#--------------------------------------------------------------------------
diag("Connecting to the card:");
$hCard = new Chipcard::PCSC::Card ($hContext);
die ("Can't create the reader object: $Chipcard::PCSC::errno\n") unless (defined($hCard));
$tmpVal = $hCard->Connect($ReadersList[0], $Chipcard::PCSC::SCARD_SHARE_SHARED);
unless ($tmpVal) {
# Try to reconnect and reset if connect fails
diag("Connect failed: trying to reset the card:");
$tmpVal = $hCard->Reconnect ($Chipcard::PCSC::SCARD_SHARE_SHARED, $Chipcard::PCSC::SCARD_PROTOCOL_T0, $Chipcard::PCSC::SCARD_RESET_CARD);
die ("Can't reconnect to the reader '$ReadersList[0]': $Chipcard::PCSC::errno\n") unless ($tmpVal);
}
ok($hCard->{dwProtocol}==$Chipcard::PCSC::SCARD_PROTOCOL_T0 ||
$hCard->{dwProtocol}==$Chipcard::PCSC::SCARD_PROTOCOL_T1 ||
$hCard->{dwProtocol}==$Chipcard::PCSC::SCARD_PROTOCOL_RAW,
"Can understand the current protocol: $hCard->{dwProtocol}");
#--------------------------------------------------------------------------
diag("Getting status:");
@StatusResult = $hCard->Status();
die ("Can't get status: $Chipcard::PCSC::errno\n") unless ($StatusResult[0]);
diag("Reader name is $StatusResult[0]");
diag("State: $StatusResult[1]");
diag("Current protocol: $StatusResult[2]");
diag("ATR: " . Chipcard::PCSC::array_to_ascii ($StatusResult[3]));
#--------------------------------------------------------------------------
diag("Initiating transaction:");
die ("Can't initiate transaction: $Chipcard::PCSC::errno\n") unless ($hCard->BeginTransaction());
diag($hCard->BeginTransaction(), "\$hCard->BeginTransaction()");
#--------------------------------------------------------------------------
diag("Exchanging data:");
$SendData = Chipcard::PCSC::ascii_to_array ("00 A4 01 00 02 01 00");
$RecvData = $hCard->Transmit($SendData);
die ("Can't transmit data: $Chipcard::PCSC::errno") unless (defined ($RecvData));
diag(" Send -> " . Chipcard::PCSC::array_to_ascii ($SendData));
diag(" Recv <- " . Chipcard::PCSC::array_to_ascii ($RecvData));
#--------------------------------------------------------------------------
diag("TransmitWithCheck:");
$SendData = "00 A4 00 00 02 3F 00"; # select DF 3F 00
# wait for ".. .." since we the SW will depend on the inserted card
($sw, $RecvData) = $hCard->TransmitWithCheck($SendData, ".. ..", 1);
warn "TransmitWithCheck: $Chipcard::PCSC::Card::Error" unless defined $sw;
ok(defined $sw, "\$hCard->TransmitWithCheck");
diag(" Send -> $SendData");
diag(" Recv <- $RecvData (SW: $sw)");
#--------------------------------------------------------------------------
diag("ISO7816Error:");
diag("$sw: " . &Chipcard::PCSC::Card::ISO7816Error($sw));
#--------------------------------------------------------------------------
# This test is commented since it is reader/driver specific and may do bad
# things for another reader. Reader your reader and driver
# specifications to know what data to use.
#
#diag("Control");
#$SendData = Chipcard::PCSC::ascii_to_array ("02");
#$RecvData = $hCard->Control(0x42000001, $SendData);
#die ("Can't Control data: $Chipcard::PCSC::errno") unless (defined ($RecvData));
#
#diag(" Send -> " . Chipcard::PCSC::array_to_ascii ($SendData));
#diag(" Recv <- " . Chipcard::PCSC::array_to_ascii ($RecvData));
#--------------------------------------------------------------------------
diag("Ending transaction:");
die ("Can't terminate transaction: $Chipcard::PCSC::errno\n") unless ($hCard->EndTransaction($Chipcard::PCSC::SCARD_LEAVE_CARD));
ok($hCard->EndTransaction($Chipcard::PCSC::SCARD_LEAVE_CARD),
"\$hCard->EndTransaction($Chipcard::PCSC::SCARD_LEAVE_CARD)");
#--------------------------------------------------------------------------
diag("Disconnecting the card:");
$tmpVal = $hCard->Disconnect($Chipcard::PCSC::SCARD_LEAVE_CARD);
die ("Can't disconnect the Chipcard::PCSC object: $Chipcard::PCSC::errno\n") unless $tmpVal;
ok($tmpVal, "\$hCard->Disconnect");
#--------------------------------------------------------------------------
diag("Closing card object:");
$hCard = undef;
#--------------------------------------------------------------------------
diag("Closing context:");
$hContext = undef;
# End of File #