Friday, August 20, 2010

PCSC sample in Ada

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


The PCSC/Ada project is hosted at

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

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 To install the backport package, perform the
following steps:

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

deb 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.


The API documentation is available online at

Source code


all: ada_sample

 @gnatmake -p -Ppcscada_sample

 @rm -rf obj


with "pcscada";

project PCSCAda_Sample is

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

   Compiler_Switches := ("-gnaty3aAbcdefhiIklnprStuxM80o",

   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;


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#);


   --  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 :
      Recv_Buffer : SCard.Byte_Set (1 .. 128);
      SCard.Transmit (Card        => First_Card,
                      Send_Buffer => APDU_Select,
                      Recv_Pci    => Recv_PCI,
                      Recv_Buffer => Recv_Buffer,
                      Recv_Len    => Recv_Len);
        ("Select applet: " & SCU.To_Hex_String
         (Given => Recv_Buffer,
          Len   => 2 * Recv_Len));
   end Send_Select_Applet_APDU;

   Send_Command_APDU :
      Recv_Buffer : SCard.Byte_Set (1 .. 32);
      SCard.Transmit (Card        => First_Card,
                      Send_Buffer => APDU_Command,
                      Recv_Pci    => Recv_PCI,
                      Recv_Buffer => Recv_Buffer,
                      Recv_Len    => Recv_Len);
        ("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);

   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;

end Ada_Sample;


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.


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


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