Main Page | Data Structures | File List | Data Fields | Globals

ifdhandler.c File Reference


Detailed Description

A low-level driver for the Axis smart card reader.

This provides a low-level reader specific driver for the smart card interface on the Axis hardware platform. This dirver is used with the Linux PCSC interface library see http://www.linuxnet.com.

Note:
This code is based heavly on the source code drivers for the ASC_MOUSE driver. That code is open source maybe this code should be open source.
Author:
Rod Boyce
Date:
22/11/04

#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <termios.h>
#include <axis.h>
#include "types.h"
#include "ifdhandler.h"

Include dependency graph for ifdhandler.c:

Include dependency graph

Data Structures

struct  tsSMARTCARD_HARDWARE
 Define a structure to hold the smart card infomation. More...


Defines

#define SMARTCARD_DEV   "/dev/axis_%d/smart_card"
#define T0_TA_SENT   (0x10)
 The mask to check and see if there is a TA command in the ATR.

#define T0_TB_SENT   (0x20)
 The mask to check and see if there is a TB command in the ATR.

#define T0_TC_SENT   (0x40)
 The mask to check and see if there is a TC command in the ATR.

#define T0_TD_SENT   (0x80)
 The mask to check and see if there is a TD command in the ATR.

#define T0_HISTORICAL_MASK   (0x0f)
 The mask to check and see there if the ATR hss any more data.

#define IFD_SINGLE_DEBUG(x)

Enumerations

enum  eIFDHANDLER_GENERIC_TYPES {
  eIFD_MIN_T1_PKT_SIZE = 4, eIFD_BWT_START = 12, eIFD_MAX_IFSD_SIZE = 32, eIFD_DEVICE_SIZE = 32,
  eIFD_MAX_ATR_SIZE = 33, eIFD_PCB_CHAINING = 0x20, eIFD_MAX_RX_SIZE = 257, eIDF_MAX_BUF_SIZE = 264
}
enum  T1_BLOCK_REPLYS {
  T1_SBLOCK_SUCCESS = 0x200, T1_SBLOCK_WTXREQUEST = 0x201, T1_RBLOCK_SUCCESS = 0x210, T1_IBLOCK_SUCCESS = 0x220,
  T1_ERROR_PARITY_EDC = 0x230, T1_ERROR_OTHER = 0x240, T1_INVALID_BLOCK = 0x250, T1_TIMEOUT = 0x260
}
enum  ePCB_FIELD {
  eIBLOCK_RSLT = 0x00, eIBLOCK_MASK = 0x80, eRBLOCK_RSLT = 0x80, eRBLOCK_MASK = 0xc0,
  eSBLOCK_RSLT = 0xc0, eSBLOCK_MASK = 0xc0
}

Functions

void ifd_ReadAtr (HANDLE fdDev, BYTE *pbAtr, BYTE *bAtrSze)
 Read the ATR from the smart card.

LONG ifd_T1ExchangeData (BYTE *pabTxBuf, LONG lTxLen, BYTE *pabRxBuf, LONG *plRxLen)
 Send a T1 data packet to the smart card.

BYTE ifd_T1CalculateLRC (BYTE *pabBuf, LONG lLen)
 Calculate packet checksum.

LONG ifd_T1Transaction (BYTE *pabRqst, LONG lRqstLen, BYTE *pabRply, LONG *plRplyLen)
 perform a T1 transaction with the smart card

LONG ifd_T1GetResponseType (BYTE bPcb)
 Return the type of PCB we got from the smart card.

LONG ifd_T1WTXResponse (BYTE bWtx, BYTE *bRxBuf, LONG lRxBufLen)
 Send Response to the waiting time extension request.

int ifd_T1BuildPacket (BYTE *pabPktBuf, LONG lPktLen)
 Try and make a packet from the data received so far if so then return 1.

RESPONSECODE IFDHCreateChannel (LONG lLun, LONG lChannel)
 Called to open a channel to a smart card.

RESPONSECODE IFDHCloseChannel (LONG lLun)
RESPONSECODE IFDHGetCapabilities (LONG lLun, LONG lTag, LONG *plLen, BYTE *pabVal)
 Return the requested capibilities for a smart card.

RESPONSECODE IFDHSetCapabilities (LONG lLun, LONG lTag, LONG lLen, BYTE *pabVal)
 Set the smart card capibilities for the smart card.

RESPONSECODE IFDHSetProtocolParameters (LONG lLun, LONG lProto, BYTE bFlgs, BYTE bPts1, BYTE bPts2, BYTE bPts3)
 Set the protocol type selection using the three PTS parameters.

RESPONSECODE IFDHPowerICC (LONG lLun, LONG lAction, BYTE *pabAtr, LONG *plAtrLen)
 Controls the power and reset signals of the smart card.

RESPONSECODE IFDHTransmitToICC (LONG lLun, SCARD_IO_HEADER sTxPci, BYTE *pabTxBuf, LONG lTxLen, BYTE *pabRxBuf, LONG *plRxLen, PSCARD_IO_HEADER psRxPci)
 Perform an ADPU exchange with the smart card.

RESPONSECODE IFDHControl (LONG lLun, BYTE *pabTxBuf, LONG lTxlen, BYTE *pabRxBuf, LONG *plRxLen)
 Perform a data exchange with the smart card reader.

RESPONSECODE IFDHICCPresence (LONG lLun)
 Return the status of the card inserted into the reader.


Variables

tsSMARTCARD_HARDWARE sSmartCard

Define Documentation

#define SMARTCARD_DEV   "/dev/axis_%d/smart_card"
 

/def SMARTCARD_DEV /brief This is the template for smartcard devices in the Axis system

This template is use so that if there are ever more that one Axis device then as long as the devices keep the naming convention that is defined here only the file reader.conf will have to change to access the smart card on the other device

#define T0_HISTORICAL_MASK   (0x0f)
 

The mask to check and see there if the ATR hss any more data.

#define T0_TA_SENT   (0x10)
 

The mask to check and see if there is a TA command in the ATR.

#define T0_TB_SENT   (0x20)
 

The mask to check and see if there is a TB command in the ATR.

#define T0_TC_SENT   (0x40)
 

The mask to check and see if there is a TC command in the ATR.

#define T0_TD_SENT   (0x80)
 

The mask to check and see if there is a TD command in the ATR.


Enumeration Type Documentation

enum eIFDHANDLER_GENERIC_TYPES
 

Enumeration values:
eIFD_MIN_T1_PKT_SIZE  The minimum T1 packet size
eIFD_BWT_START  The default block wait time
eIFD_MAX_IFSD_SIZE  The maximum size of an IFSD
eIFD_DEVICE_SIZE  The size of the device string used to store the device name
eIFD_MAX_ATR_SIZE  The maximum size of the ATR field
eIFD_PCB_CHAINING  The mask to use for the TX PCB chaining flag
eIFD_MAX_RX_SIZE  The maximum size of a Receive packet
eIDF_MAX_BUF_SIZE  The maximum size of a smartcard packet

enum ePCB_FIELD
 

Enumeration values:
eIBLOCK_RSLT  When identifing an I block this it the result after filters out the unneeded bits
eIBLOCK_MASK  The mask to used when trying to identify an I block
eRBLOCK_RSLT  The expected result when identifing a R block
eRBLOCK_MASK  The mask to use for R block identification
eSBLOCK_RSLT  The expected result when identifing a S block
eSBLOCK_MASK  The mask to use for S block identification

enum T1_BLOCK_REPLYS
 

Enumeration values:
T1_SBLOCK_SUCCESS  The sblock transaction was a success
T1_SBLOCK_WTXREQUEST  We received a sblock wtx request
T1_RBLOCK_SUCCESS  A rblock transaction was sucessful
T1_IBLOCK_SUCCESS  An iblock transaction was sucessful
T1_ERROR_PARITY_EDC  There was a parity error with the transaction
T1_ERROR_OTHER  An error occured with the transaction
T1_INVALID_BLOCK  An invalid block was received
T1_TIMEOUT  The transaction timed out


Function Documentation

void ifd_ReadAtr HANDLE  fdDev,
BYTE pbAtr,
BYTE bAtrSze
[static]
 

Read the ATR from the smart card.

Read the ATR from the smart card after the channel has been opened. This code constructs an ATR from the data readin from the smart card. If at any stage an error occures then set the ATR to 0 and return. This makes the code a little untidy with a goto for all read errors.

Date:
17/11/04
Author:
Rod Boyce
Parameters:
fdDev - The file handle to use to read the ATR from.
pbAtr - pointer to store the ATR infomation in.
pbAtrSize - The size of the ATR buffer the the number of bytes of the ATR

History

int ifd_T1BuildPacket BYTE pabPktBuf,
LONG  lPktLen
[static]
 

Try and make a packet from the data received so far if so then return 1.

Given a block of data and a length try and make a T1 packet out of the data. If a packet can be made then return that a valid packet was received otherwise return that a valid packet has not been made.

Date:
25/11/04
Author:
Rod Boyce
Parameters:
pabPktBuf - Pointer to the T1 packet to verify.
lPktLen - the number of bytes in the T1 packet.
Returns:
1 if the buffer is a valid T1 packet or 0 if the buffer is not a valid T1 packet

History

Here is the call graph for this function:

BYTE ifd_T1CalculateLRC BYTE pabBuf,
LONG  lLen
[static]
 

Calculate packet checksum.

Date:
18/11/04
Author:
Rod Boyce
Parameters:
pabBuf - pointer to an array of data to perform the checksum over.
lLen - The number of bytes to check.
Returns:
A Xor checksum of the data packet

History

LONG ifd_T1ExchangeData BYTE pabTxBuf,
LONG  lTxLen,
BYTE pabRxBuf,
LONG plRxLen
[static]
 

Send a T1 data packet to the smart card.

Called when a T1 transaction is performed. The smart card specification says that multi-packet transfers can only be perfromed in one direction either to the smart card or from the smart card. This function can send or receive a maximum of one 255 byte PDU.

Date:
22/11/04
Author:
Rod Boyce
Parameters:
pabTxBuf - Pointer to the Tx buffer
lTxlen - The number of bytes in the Tx buffer
pabRxBuf - Pointer to the Rx buffer
plRxLen - The size of the Rx buffer
Returns:

History

Here is the call graph for this function:

LONG ifd_T1GetResponseType BYTE  bPcb  )  [static]
 

Return the type of PCB we got from the smart card.

Date:
18/11/04
Author:
Rod Boyce
Parameters:
bPcb - the PCB field from the smart card response packet
Returns:
The response type

History

LONG ifd_T1Transaction BYTE pabRqst,
LONG  lRqstLen,
BYTE pabRply,
LONG plRplyLen
[static]
 

perform a T1 transaction with the smart card

Date:
22/11/04
Author:
Rod Boyce
Parameters:
pabRqst - The transmit buffer.
lRqstLen - The number of bytes to send.
pabRply - The receive buffer.
plRplyLen - The number of bytes in the receive buffer.
Returns:
T1_SBLOCK_SUCCESS on completion of a T1 transaction or T1_TIMEOUT if the transaction

did not complete in time.

History

Here is the call graph for this function:

LONG ifd_T1WTXResponse BYTE  bWtx,
BYTE pabRxBuf,
LONG  lRxBufLen
[static]
 

Send Response to the waiting time extension request.

During the transmission of a buffer to the smart card the smart card may request an extension to the stardard block waiting time of this transaction. THis function will replay to this request from the smart card.

Date:
18/11/04
Author:
Rod Boyce
Parameters:
bWtx - The multiplier to the block waiting time.
pabRxBuf - poointer to the receive buffer for this transaction.
lRxBufLen - The size of the receive buffer.

History

Here is the call graph for this function:

IFDHCloseChannel LONG  lLun  ) 
 

Date:
16/11/04
Author:
Rod Boyce
Parameters:
lLun - Logical Unit Number.
Returns:
IFD_SUCCESS if the channel was closed, IFD_COMMUNICATION_ERROR if an error occured

History

IFDHControl LONG  lLun,
BYTE pabTxBuf,
LONG  lTxlen,
BYTE pabRxBuf,
LONG plRxLen
 

Perform a data exchange with the smart card reader.

This is not supported in this implementation

Date:
16/11/04
Author:
Rod Boyce
Parameters:
lLun - Logical Unit Number
pabTxBuf - The data buffer to send to the reader
lTxlen - The number of bytes to send
pabRxBuf - The data returned.
plRxLen - The size of the returned buffer.
Returns:
IFD_SUCCESS for a successful transaction, |IFD_COMMUNICATION_ERROR if an error occured,

IFD_RESPONSE_TIMEOUT if the response timed out.

History

IFDHCreateChannel LONG  lLun,
LONG  lChannel
 

Called to open a channel to a smart card.

Open the chanel to the smart card. In this implementation the open is done later This will just initialise the channel for comms and allow IFDHICCPresence to return the card status

Date:
16/11/04
Author:
Rod Boyce
Parameters:
lLun - Logical Unit number. 0xxxxxyyyy xxxx multiple readers, yyyy multiple slots
lChannel - The channel ID starting from one.
Returns:
IFD_SUCCESS if the channel was opened sucessufully or IFD_COMMUNICATION_ERROR if the channel

is not supported.

History

Here is the call graph for this function:

IFDHGetCapabilities LONG  lLun,
LONG  lTag,
LONG plLen,
BYTE pabVal
 

Return the requested capibilities for a smart card.

Return the requested capibilities. At the moment only the ATR is returned all other Tags get ignored and IFD)ERROR is returned. This is what the acs_mouse driver was doing for the basic cards.

Date:
16/11/04
Author:
Rod Boyce
Parameters:
lLun - Logical Unit Number
lTag - The tag for the requested infomation
plLen - Pointer to a long that is the size of the return buffer
pabVal - pointer to a buffer that will store the returned infomation
Returns:
IFD_SUCCESS - On success, IFD_ERROR_TAG - Tag not used.

History

IFDHICCPresence LONG  lLun  ) 
 

Return the status of the card inserted into the reader.

This function is surposed to detect if a smart card is inserted onto the smartcard holder.

Note:
For the moment this is not possible as the only way to do this is by trying to read the ATR (Answer To Reset). THis fn is called all the time by the upper layers to see if the smart card has been removed or not. There is a change to be able to read the smart card inserted pin of the socket in the future.
Date:
16/11/04
Author:
Rod Boyce
Parameters:
lLun - Logical Unit Number
Returns:
IFD_ICC_PRESENT if there is a card in the reader, IFD_ICC_NOT_PRESENT if there is no

card in the reader, IFD_COMMUNICATION_ERROR if a error occured.

History

IFDHPowerICC LONG  lLun,
LONG  lAction,
BYTE pabAtr,
LONG plAtrLen
 

Controls the power and reset signals of the smart card.

This function is surposed to control the power and reset signals of the smart card. Ok I had to add the extra functionality so lets see how that goes.

Date:
16/11/04
Author:
Rod Boyce
Parameters:
lLun - Logical Unit Number
lAction - Action to be perormed, power up, power down, reset
pabAtr - Answer to reset the ATR value of the inserted card
plAtrLen - The length of the ATR buffer and the returned size of the ATR
Returns:
IDF_SUCCESS on sucess, IFD_ERROR_POWER_ACTION an error in powering or resetting the

card, IFD_COMMUNICATION_ERROR an error occured, IFD_NOT_SUPPORTED the requested action

was not supported.

History

< Reset Action

< Power down action

< Power up action

Here is the call graph for this function:

IFDHSetCapabilities LONG  lLun,
LONG  lTag,
LONG  lLen,
BYTE pabVal
 

Set the smart card capibilities for the smart card.

Return an error code this is what the acs_mouse driver did so this is what we are going to do. At least until I have a resonable need to do something better.

Date:
16/11/04
Author:
Rod Boyce
Parameters:
lLun - Logical Unit Number
lTag - The tag for the infomation needing to be set
lLen - Length of the desired data value
pabVal - Value to set the lTag to.
Returns:
IFD_SUCCESS - for a sucessful operation, IFD_ERROR_TAG if the tag was not understood,

IFD_ERROR_SET_FAILURE - could not set the value, IFD_ERROR_VAULE_READ_ONLY - the value is readonly

History

IFDHSetProtocolParameters LONG  lLun,
LONG  lProto,
BYTE  bFlgs,
BYTE  bPts1,
BYTE  bPts2,
BYTE  bPts3
 

Set the protocol type selection using the three PTS parameters.

Again this is what the acs_mouse driver was doing to this is what I'm going to do until ther eis a better reason to do anything else.

Date:
16/11/04
Author:
Rod Boyce
Parameters:
lLun - Logical Unit Number
lproto - The protocol to set the device to o ... 14 = T0 .. T14
bFlgs - Logical or of possible values IFD_NEGOTIATE_PTS1, PTS2, PTS3 to determine
which PTS values to negotiage
bPts1 - 1st PTS value (See ISO 7816 / EMV documentation)
bPts2 - 2nd PTS value (See ISO 7816 / EMV documentation)
bPts3 - 3rd PTS value (See ISO 7816 / EMV documentation)
Returns:
IFD_SUCCESS for a sucessful result, IFD_ERROR_PTS_FAILURE could not set the PTS value,

IFD_COMMUNICATION_ERROR an error has occured, IFD_PROTOCOL_NOT_SUPPORTED the requested

protocol is not supported

History

IFDHTransmitToICC LONG  lLun,
SCARD_IO_HEADER  sTxPci,
BYTE pabTxBuf,
LONG  lTxLen,
BYTE pabRxBuf,
LONG plRxLen,
PSCARD_IO_HEADER  psRxPci
 

Perform an ADPU exchange with the smart card.

Date:
16/11/04
Author:
Rod Boyce
Parameters:
lLun - Logical Unit Number
sTxPci - protocol to use the length member is not used.
pabTxBuf - The buffer to send to the smart card
lTxLen - The number of bytes to send to the smart card
pabRxBuf - The place to store the receive buffer
plRxLen - The size of the receive buffer
psRxPci - The protocol to use for the reply and the length but the length is not used
Returns:
IFD_SUCCESS after a successful transaction with thte smart card,

IFD_COMMUNICATION_ERROR if a comms error occured, IFD_RESPONSE_TIMEOUT if the response

timed out, IFD_PROTOCOL_NOT_SUPPORTED if the requested protocol is not supported.

History

Here is the call graph for this function:


Variable Documentation

tsSMARTCARD_HARDWARE sSmartCard [static]
 

Initial value:

{
    -1, 0, 0, "", { 0 }, 0
}


Generated on Thu Jan 20 16:17:58 2005 for Smart-card ifd-handler for Axis by doxygen 1.3.6