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.