Package: PCSC.SCard

Dependencies

with Ada.Containers.Indefinite_Vectors;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;

with PCSC.Thin;

Description

Copyright (c) 2008-2009, Reto Buerki <reet@codelabs.ch>

This file is part of PCSC/Ada.

PCSC/Ada is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.

PCSC/Ada 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 Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with PCSC/Ada; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

Purpose:
PC/SC thick-binding package. Provides abstraction from the C style functions and types provided in the thin binding in PCSC.Thin.

Header

package PCSC.SCard is
 

Type Summary

Action
ATR
Primitive Operations:  Size, Size, Status, To_Atr
Attribute
Byte_Set
Card (limited type)
Primitive Operations:  Begin_Transaction, Connect, Control, Disconnect, End_Transaction, Get_Active_Proto, Get_Attribute, Get_PCI, Init_Attribute_Set, Reconnect, SPE_Exec, SPE_Init, Status, Transmit
Card_State
Card_States_Set
Primitive Operations:  Add, Is_In, Status
Context (limited type)
Primitive Operations:  Cancel, Connect, Establish_Context, Is_Valid, List_Readers, Release_Context, Status_Change, Wait_For_Readers
Mode
PCI
Proto
Reader_Condition
Primitive Operations:  Add, Get
Reader_Condition_Handle
Reader_Condition_Set
Primitive Operations:  Add, Find, First_Index, Get, Last_Index, Length, Status_Change
Reader_ID
Primitive Operations:  Connect, Find, First_Item, Get, Last_Item, To_Reader_ID
Reader_ID_Set
Primitive Operations:  Empty, First_Index, First_Item, Get, Last_Index, Last_Item, List_Readers
Reader_State
Reader_States_Set
Primitive Operations:  Add, First_Index, First_Item, Get, Is_In, Last_Index, Last_Item, Remove
Scope

Constants and Named Numbers

Null_ATR : constant ATR;
Null initialized ATR
Null_Byte_Set : constant Byte_Set;
Empty Byte_Set
Null_Reader_ID : constant Reader_ID;
Empty reader ID

Other Items:

type Context is limited private;
This is the PC/SC-Context. This object is initialized by Establish_Context below and is used with all services.

type Card is limited private;
SCard-Handler, returned by Connect. Used to access a specific smartcard.

type Byte_Set is array (Natural range <>) of aliased Thin.Byte;
Byte_Sets are used to send and receive data to/from SCard-Readers.

type ATR is private;
Card ATR type

type Reader_ID is private;
Reader friendly name

type Reader_ID_Set is tagged private;
Set of ReaderIDs

type Scope is
  (Scope_User,
   --  Scope in user space
   Scope_Terminal,
   --  Scope in terminal
   Scope_System
   --  Scope in system
  );
Possible scopes for a PC/SC-context

type Mode is
  (Share_Exclusive,
   --  Exclusive mode only
   Share_Shared,
   --  Shared mode only
   Share_Direct
   --  Raw mode only
  );
Possible share Modes for SCard connects

type Proto is
  (Proto_Undefined,
   --  Protocol not set
   Proto_Unset,
   --  Backward compatibility
   Proto_T0,
   --  T=0 active protocol
   Proto_T1,
   --  T=1 active protocol
   Proto_RAW,
   --  Raw active protocol
   Proto_T15
   --  T=15 protocol
  );
Possible Protos for SCard connects

type Action is
  (Leave_Card,
   --  Do nothing on close
   Reset_Card,
   --  Reset on close
   Unpower_Card,
   --  Power down on close
   Eject_Card
   --  Eject on close
  );
Possible card Actions

type Card_State is
  (S_Card_Unknown,
   --  Unknown state
   S_Card_Absent,
   --  Card is absent
   S_Card_Present,
   --  Card is present
   S_Card_Swallowed,
   --  Card not powered
   S_Card_Powered,
   --  Card is powered
   S_Card_Negotiable,
   --  Ready for PTS
   S_Card_Specific
   --  PTS has been set
  );
Card states

type Card_States_Set is tagged private;
Set of card states

type Reader_State is
  (S_Reader_Unaware,
   --  App wants status
   S_Reader_Ignore,
   --  Ignore this reader
   S_Reader_Changed,
   --  State has changed
   S_Reader_Unknown,
   --  Reader unknown
   S_Reader_Unavailable,
   --  Status unavailable
   S_Reader_Empty,
   --  Card removed
   S_Reader_Present,
   --  Card inserted
   S_Reader_Atrmatch,
   --  ATR matches card
   S_Reader_Exclusive,
   --  Exclusive Mode
   S_Reader_Inuse,
   --  Shared Mode
   S_Reader_Mute,
   --  Unresponsive card
   S_Reader_Unpowered
   --  Unpowered card
  );
Reader / Card states

type Reader_States_Set is tagged private;
Set of reader states

type Reader_Condition is record
   Name          : Reader_ID := Null_Reader_ID;
   Current_State : Reader_States_Set;
   Event_State   : Reader_States_Set;
   Event_Counter : Natural := 0;
   Card_ATR      : ATR     := Null_ATR;
end record;
Reader condition type for status change handling. Current_State defines the current assumed state. Event_State and Card_ATR is updated by calling the Status_Change() procedure. Event_Counter stores the event count for the reader identified by 'Name'.

type Reader_Condition_Handle is access all Reader_Condition;
Handle to Reader_Condition type.

type Reader_Condition_Set is tagged private;
Set of reader status types

subtype IO_Request is Thin.SCARD_IO_REQUEST;
Thick binding IO request subtype, used in Transmit() procedure

type PCI is
  (PCI_T0,
   --  (PCI) for T=0
   PCI_T1,
   --  (PCI) for T=1
   PCI_RAW
   --  (PCI) for RAW protocol
  );
Protocol control information types

type Attribute is
  (Attr_Vendor_Name,
   Attr_Vendor_IFD_Type,
   Attr_Vendor_IFD_Version,
   Attr_Vendor_IFD_Serial,
   Attr_Channel_ID,
   Attr_Default_CLK,
   Attr_Max_CLK,
   Attr_Default_Data_Rate,
   Attr_Max_Data_Rate,
   Attr_Max_IFSD,
   Attr_Power_Mgmt_Support,
   Attr_Characteristics,
   Attr_Current_Protocol_Type,
   Attr_Current_CLK,
   Attr_Current_F,
   Attr_Current_D,
   Attr_Current_N,
   Attr_Current_W,
   Attr_Current_IFSC,
   Attr_Current_IFSD,
   Attr_Current_BWT,
   Attr_Current_CWT,
   Attr_Current_EBC_Encoding,
   Attr_Extended_BWT,
   Attr_ICC_Presence,
   Attr_ICC_Interface_Status,
   Attr_Current_IO_State,
   Attr_ATR_String,
   Attr_ICC_Type_Per_ATR,
   Attr_ESC_Preset,
   Attr_ESC_Cancel,
   Attr_ESC_Authrequest,
   Attr_Maxinput,
   Attr_Device_Unit,
   Attr_Device_In_Use,
   Attr_Device_Friendly_Name_A,
   Attr_Device_System_Name_A,
   Attr_Device_Friendly_Name_W,
   Attr_Device_System_Name_W,
   Attr_Supress_T1_IFS_Request);
Possible attributes for Get_Attribute procedure

procedure Add
  (States : in out Card_States_Set;
   State  :        Card_State);
Add a new card state to card states set.

procedure Add
  (States : in out Reader_States_Set;
   State  :        Reader_State);
Add a new reader state to reader states set.

procedure Add
  (Set    : in out Reader_Condition_Set;
   Status :        Reader_Condition);
Add a new reader to reader condition array. State specifies the assumed initial state of the reader/card.

procedure Begin_Transaction (Card : SCard.Card);
This procedure establishes a temporary exclusive access mode for doing a series of commands or transactions with a SCard.

procedure Cancel (Context : SCard.Context);
This procedure cancels all pending blocking requests on the Status_Change() procedure for a given SCard 'Context'.

procedure Connect
  (Context :        SCard.Context;
   Card    : in out SCard.Card;
   Reader  :        Reader_ID  := Null_Reader_ID;
   Mode    :        SCard.Mode := Share_Shared);
Connect to a SCard identified by Reader (Reader_ID). Handle to connected SCard will be stored in 'Card' parameter.

procedure Control
  (Card        :        SCard.Card;
   Code        :        Natural;
   Send_Buffer :        Byte_Set := Null_Byte_Set;
   Recv_Buffer : in out Byte_Set;
   Recv_Len    : in out Natural);
This procedure sends a control command to the reader connected to by Connect(). It returns the the control response in Recv_Buffer.

procedure Disconnect
  (Card   : SCard.Card;
   Action : SCard.Action);
This procedure terminates a connection to a card.

function Empty (Set : Reader_ID_Set) return Boolean;
This function returns True if the reader ID set contains no readers.

procedure End_Transaction
  (Card   : SCard.Card;
   Action : SCard.Action);
This procedure ends a previously started transaction.

procedure Establish_Context
  (Context : in out SCard.Context;
   Scope   :        SCard.Scope);
Establish PC/SC-context. Possible Scope values are defined in the SCard_Scope type.

function Find
  (Set       : Reader_Condition_Set;
   Reader_ID : SCard.Reader_ID)
   return Boolean;
Search a given Reader_ID in Reader_Condition_Set. If found, True is returned, False if not found.

function First_Index (Set : Reader_ID_Set) return Natural;
Returns the first index of the given reader ID set.

function First_Index (Set : Reader_States_Set) return Natural;
Returns the first index of the given reader states set.

function First_Index (Set : Reader_Condition_Set) return Natural;
Returns the first index of the given reader condition set.

function First_Item (Set : Reader_ID_Set) return Reader_ID;
Returns the first reader ID from the given reader ID set.

function First_Item (Set : Reader_States_Set) return Reader_State;
Returns the first reader state from the given reader states set.

function Get
  (Set   : Reader_ID_Set;
   Index : Natural)
   return Reader_ID;
Returns the reader ID at given index in the set.

function Get
  (Set   : Reader_States_Set;
   Index : Natural)
   return Reader_State;
Returns the reader state at given index in the set.

function Get
  (Set   : Reader_Condition_Set;
   Index : Natural)
   return Reader_Condition;
Returns the reader condition at given index in the set.

function Get_Active_Proto (Card : SCard.Card) return Proto;
Return protocol in use for a given card.

procedure Get_Attribute
  (Card        :        SCard.Card;
   Attr        :        Attribute;
   Recv_Buffer : in out Byte_Set);
This procedure gets an attribute from the IFD handler. Call Init_Attribute_Set prior to this function to allocate the correct byte set for the call.

function Get_PCI (Card : SCard.Card) return Thin.SCARD_IO_REQUEST;
Return PCI to use for a given card. If no valid PCI for a proto is found, a No_PCI_for_Proto exception will be thrown.

function Get_Return_Code return String;
Return string representation of last stored return code.

function Init_Attribute_Set
  (Card : SCard.Card;
   Attr : Attribute)
   return Byte_Set;
This function returns an Null_Byte initialized byte set to provide storage for an attribute 'Attr'. The byte set can then be used as parameter to the Get_Attribute function to actually retrieve the attribute data.

function Is_In
  (States : Reader_States_Set;
   State  : Reader_State)
   return Boolean;
Function returns True if given reader state is found in the reader states set.

function Is_In
  (States : Card_States_Set;
   State  : Card_State)
   return Boolean;
Function returns True if given card state is found in the card states set.

function Is_Valid (Context : SCard.Context) return Boolean;
Verify that given SCard context is valid.

function Last_Index (Set : Reader_ID_Set) return Natural;
Returns the last index of a reader ID set.

function Last_Index (Set : Reader_States_Set) return Natural;
Returns the last index of a reader states set.

function Last_Index (Set : Reader_Condition_Set) return Natural;
Returns the last index of a reader condition set.

function Last_Item (Set : Reader_ID_Set) return Reader_ID;
Returns the last reader ID in a reader ID set.

function Last_Item (Set : Reader_States_Set) return Reader_State;
Returns the last reader state in a reader states set.

function Length (Set : Reader_Condition_Set) return Natural;
Returns the length of a reader condition set.

function List_Readers (Context : SCard.Context) return Reader_ID_Set;
Return list of all available readers for given PC/SC context.

procedure Reconnect
  (Card   : in out SCard.Card;
   Mode   :        SCard.Mode;
   Action :        SCard.Action);
This procedure re-establishes a connection. The Init argument defines the desired SCard action to perform on the card/reader.

procedure Release_Context (Context : in out SCard.Context);
Release previously acquired SCard context.

procedure Remove
  (States : in out Reader_States_Set;
   State  :        Reader_State);
Remove reader state from given reader states set.

procedure SPE_Exec (Card : in out SCard.Card; Result : in out Byte_Set);
Request the reader connected to by 'Card' to perform a secure PIN entry operation. If not already done by the client code, this procedure will use the SPE_Init() procedure to check if the reader supports SPE and to initialize the verify ctrl code. If the SPE operation is not supported or does not work as expected, an SCard_Not_Supported exception is raised. If the SPE operation is successful, the bytes returned from the reader will be stored in 'Result' byte set.

procedure SPE_Init (Card : in out SCard.Card; Result : in out Boolean);
Procedure checks if a reader connected by 'Card' handle supports SPE (secure PIN entry) operation. If it does, 'Result' will be True, otherwise 'Result' will be False.

function Size (Atr : SCard.ATR := Null_ATR) return Natural;
Return current size of an ATR as Natural.

function Size (Atr : SCard.ATR := Null_ATR) return String;
Return current size of an ATR as string.

procedure Status
  (Card  :     SCard.Card;
   State : out SCard.Card_States_Set;
   Proto : out SCard.Proto;
   Atr   : out SCard.ATR);
This procedure checks the current status of the reader connected to by 'Card'. Current state, protocol and ATR value of inserted card are returned as out parameters.

procedure Status_Change
  (Context    :        SCard.Context;
   Timeout    :        Natural := 0;
   Conditions : in out Reader_Condition_Set);
This procedure takes a reader condition set containing reader names with their assumed state. It then blocks maximum 'Timeout' milliseconds time for a change in state to occur. If no timeout is given, 0 will be used, which will block forever. When a status change occurs, the Conditions object is updated to reflect the change(s). If this procedure is called with an empty Conditions object, Wait_For_Readers() is used to wait for a reader to appear, then the procedure returns.

procedure Wait_For_Readers (Context : SCard.Context);
This procedure calls SCardGetStatusChange for reader detection. If there is no reader available, the call will block until a reader is connected. If there are readers present when this function is called, it will return immediately.

procedure Transmit
  (Card        :        SCard.Card;
   Send_Buffer :        Byte_Set := Null_Byte_Set;
   Recv_Pci    : in out IO_Request;
   Recv_Buffer : in out Byte_Set;
   Recv_Len    : in out Natural);
Transmit APDUs to SCard.

function To_Atr (Bytes : Byte_Set) return ATR;
Create new ATR object from given byte set. If 'Bytes' is too big to be converted into an ATR type, a 'Bytes_Too_Big' exception will be raised.

function To_Reader_ID (Name : String) return Reader_ID;
Returns a new reader ID initialized with 'Name' string.

private

   --  Implementation-defined ...
end PCSC.SCard;