PCSC sample in Ada

Here is the PCSC sample in Ada language I promised in PC/SC sample in different languages.

Installation


The PCSC/Ada project is hosted at http://www.nongnu.org/pcscada.

PCSC/Ada is available as package in Debian testing/unstable and Ubuntu
10.04.

Debian squeeze (testing at time of writing this article)


To install the PCSC/Ada development package type:
$ sudo apt-get install libpcscada1-dev

Debian Lenny (stable)


If you use Debian stable (Lenny), an unofficial backport is also
available from codelabs.ch. To install the backport package, perform the
following steps:

Add this line to /etc/apt/sources.list:

deb http://www.codelabs.ch/debian lenny-backports main contrib non-free

Then, execute the following commands:
$ sudo apt-get update
$ sudo apt-get install debian-codelabs-archive-keyring
$ sudo apt-get update

To install the PCSC/Ada development package type:
$ sudo apt-get install libpcscada1-dev

If you want to compile PCSC/Ada from source, see the distributed README
file for details.

API


The API documentation is available online at
http://www.nongnu.org/pcscada/api/index.html.


Source code


Makefile


all: ada_sample

ada_sample:
@gnatmake -p -Ppcscada_sample

clean:
@rm -rf obj

pcscada_sample.gpr


with "pcscada";

project PCSCAda_Sample is

for Object_Dir use "obj";
for Source_Dirs use (".");
for Main use ("ada_sample.adb");

Compiler_Switches := ("-gnaty3aAbcdefhiIklnprStuxM80o",
"-gnatVa",
"-gnat05",
"-gnatwal",
"-gnatf",
"-fstack-check",
"-gnato",
"-g");

package Compiler is
for Default_Switches ("ada") use Compiler_Switches;
end Compiler;

package Binder is
for Default_Switches ("ada") use ("-E");
end Binder;

end PCSCAda_Sample;


ada_sample.adb


with Ada.Text_IO;

with PCSC.SCard.Utils;

use PCSC;

procedure Ada_Sample is

package SCU renames SCard.Utils;

My_Context : SCard.Context;
First_Card : SCard.Card;
Readers : SCard.Reader_ID_Set;
Recv_PCI : SCard.IO_Request;
Recv_Len : Natural := 0;

APDU_Select : constant SCard.Byte_Set :=
(16#00#, 16#A4#, 16#04#, 16#00#, 16#0A#,
16#A0#, 16#00#, 16#00#, 16#00#, 16#62#,
16#03#, 16#01#, 16#0C#, 16#06#, 16#01#);
APDU_Command : constant SCard.Byte_Set :=
(16#00#, 16#00#, 16#00#, 16#00#);

begin

-- Establish context

SCard.Establish_Context (Context => My_Context,
Scope => SCard.Scope_System);

-- List readers

Readers := SCard.List_Readers (Context => My_Context);
Ada.Text_IO.Put_Line ("Readers found:");
SCU.For_Every_Reader (Readers => Readers,
Call => SCU.Print_ReaderID'Access);

-- Connect with the card in first reader

SCard.Connect (Context => My_Context,
Card => First_Card,
Reader => Readers.First_Item,
Mode => SCard.Share_Shared);

-- Send APDUs

Send_Select_Applet_APDU :
declare
Recv_Buffer : SCard.Byte_Set (1 .. 128);
begin
SCard.Transmit (Card => First_Card,
Send_Buffer => APDU_Select,
Recv_Pci => Recv_PCI,
Recv_Buffer => Recv_Buffer,
Recv_Len => Recv_Len);
Ada.Text_IO.Put_Line
("Select applet: " & SCU.To_Hex_String
(Given => Recv_Buffer,
Len => 2 * Recv_Len));
end Send_Select_Applet_APDU;

Send_Command_APDU :
declare
Recv_Buffer : SCard.Byte_Set (1 .. 32);
begin
SCard.Transmit (Card => First_Card,
Send_Buffer => APDU_Command,
Recv_Pci => Recv_PCI,
Recv_Buffer => Recv_Buffer,
Recv_Len => Recv_Len);
Ada.Text_IO.Put_Line
("Command : "
& SCU.To_String (Given => Recv_Buffer (1 .. Recv_Len)));
end Send_Command_APDU;

-- Disconnect the card

SCard.Disconnect (Card => First_Card,
Action => SCard.Unpower_Card);

-- Release context

SCard.Release_Context (Context => My_Context);

exception
when others =>
Ada.Text_IO.Put_Line ("OOPS - got an exception:");
if SCard.Is_Valid (Context => My_Context) then
SCard.Release_Context (Context => My_Context);
end if;

raise;
end Ada_Sample;

Compilation


Just type make.

$ make
object directory "/home/rousseau/blog/pcscada_sample/obj" created
gcc-4.4 -c -gnaty3aAbcdefhiIklnprStuxM80o -gnatVa -gnat05 -gnatwal -gnatf -fstack-check -gnato -g -I- -gnatA /home/rousseau/blog/pcscada_sample/ada_sample.adb
gnatbind -shared -E -I- -x /home/rousseau/blog/pcscada_sample/obj/ada_sample.ali
gnatlink /home/rousseau/blog/pcscada_sample/obj/ada_sample.ali -shared-libgcc -L/usr/lib -lpcscada -o /home/rousseau/blog/pcscada_sample/obj/ada_sample

The generated binary is ./obj/ada_sample.

Output


$ ./obj/ada_sample 
Readers found:
Gemalto GemPC Twin 00 00
Select applet: 9000
Command : Hello world!�

Conclusion


I do not use Ada myself so I can't really say more. This wrapper should do the job if you do use Ada.

Thanks a lot to Reto Buerki, the author of the Ada wrapper, for writing the sample code for me.


Flattr this
Previous
Next Post »