[Pcsclite-cvs-commit] Drivers/ccid/src ccid.c,NONE,1.1 ccid.h,NONE,1.1

rousseau@quantz.debian.org rousseau@quantz.debian.org
Wed, 10 Sep 2003 11:15:53 +0200


Update of /cvsroot/pcsclite/Drivers/ccid/src
In directory quantz:/tmp/cvs-serv7632

Added Files:
	ccid.c ccid.h 
Log Message:
contains common CCID feature for USB and serial (was in ccid_usb before)


--- NEW FILE: ccid.c ---
/*
    ccid.c: CCID common code
    Copyright (C) 2003   Ludovic Rousseau

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

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

/*
 * $Id: ccid.c,v 1.1 2003/09/10 09:15:51 rousseau Exp $
 */

#include "config.h"
#include "debug.h"
#include "pcscdefines.h"
#include "ifdhandler.h"
#include "ccid.h"
#include "commands.h"

/*****************************************************************************
 *
 *					ccid_open_hack
 *
 ****************************************************************************/
int ccid_open_hack(int lun)
{
	_ccid_descriptor *ccid_descriptor = get_ccid_descriptor(lun);

	switch (ccid_descriptor->readerID)
	{
		case CARDMAN3121+1:
			/* Reader announces APDU but is in fact TPDU */
			ccid_descriptor->dwFeatures &= ~CCID_CLASS_EXCHANGE_MASK;
			ccid_descriptor->dwFeatures |= CCID_CLASS_TPDU;
			break;

		case GEMPCKEY:
		case GEMPCTWIN:
			/* Reader announces TPDU but can do APDU */
			if (CmdEscape(lun, ESC_GEMPC_SET_APDU_MODE) == IFD_SUCCESS)
			{
				ccid_descriptor->dwFeatures &= ~CCID_CLASS_EXCHANGE_MASK;
				ccid_descriptor->dwFeatures |= CCID_CLASS_SHORT_APDU;
			}
			break;
	}

	return 0;
} /* ccid_open_hack */

/*****************************************************************************
 *
 *					ccid_error
 *
 ****************************************************************************/
void ccid_error(int error, char *file, int line)
{
	char *text;

	switch (error)
	{
		case 0x00:
			text = "Command not supported or not allowed";
			break;

		case 0x01:
			text = "Wrong command length";
			break;

		case 0x02:
			text = "Reader detects an excessive current. Card powered off";
			break;

		case 0x03:
			text = "Reader detects a defective voltage. Card powered off";
			break;

		case 0x05:
			text = "Slot number is invalid (it must be set to 0)";
			break;

		case 0x07:
		case 0x08:
		case 0x09:
		case 0x0A:
		case 0x15:
			text = "Byte displayed is invalid";
			break;

		case 0xA2:
			text = "Card short-circuiting. Card powered off";
			break;

		case 0xA3:
			text = "ATR too long (> 33)";
			break;

		case 0xB0:
			text = "Reader in EMV mode and T=1 message too long";
			break;

		case 0xBB:
			text = "Protocol error in EMV mode";
			break;

		case 0xBD:
			text = "Card error during T=1 exchange";
			break;

		case 0xBE:
			text = "Wrong APDU command length";
			break;

		case 0xF4:
			text = "Procedure byte conflict";
			break;

		case 0xF7:
			text = "Invalid ATR checksum byte (TCK)";
			break;

		case 0xF8:
			text = "Invalid ATR first byte";
			break;

		case 0xFD:
			text = "Parity error during exchange";
			break;

		case 0xFE:
			text = "Card absent or mute";
			break;

		default:
			text = "Unknown CCID error";
			break;

	}
	debug_msg("%s:%d %s", file, line, text);

} /* ccid_error */


--- NEW FILE: ccid.h ---
/*
    ccid.h: CCID structures
    Copyright (C) 2003   Ludovic Rousseau

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

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

/*
 * $Id: ccid.h,v 1.1 2003/09/10 09:15:51 rousseau Exp $
 */

typedef struct
{
	/*
	 * CCID Sequence number
	 */
	unsigned char bSeq;

	/*
	 * VendorID << 16 + ProductID
	 */
	int readerID;

	/*
	 * Maximum message length
	 */
	int dwMaxCCIDMessageLength;

	/*
	 * Features supported by the reader (directly from class Descriptor)
	 */
	int dwFeatures;

} _ccid_descriptor;

#define CCID_CLASS_AUTO_VOLTAGE		0x00000008
#define CCID_CLASS_EXCHANGE_MASK	0x00070000
#define CCID_CLASS_TPDU				0x00010000
#define CCID_CLASS_SHORT_APDU		0x00020000
#define CCID_CLASS_EXTENDED_APDU	0x00040000

/* See CCID specs ch. 4.2.1 */
#define CCID_COMMAND_FAILED			0x40	/* 01 0000 00 */
#define CCID_TIME_EXTENSION			0x80	/* 10 0000 00 */

/* Product identification for special treatments */
#define GEMPC433	0x08E64433
#define GEMPCKEY	0x08E63438
#define GEMPCTWIN	0x08E63437
#define CARDMAN3121	0x076B3021

/* Escape sequence codes */
#define ESC_GEMPC_SET_ISO_MODE		1
#define ESC_GEMPC_SET_APDU_MODE		2


int ccid_open_hack(int lun);
void ccid_error(int error, char *file, int line);
_ccid_descriptor *get_ccid_descriptor(int lun);

/* convert a 4 byte integer in USB format into an int */
#define dw2i(a, x) ((((((a[x+3] << 8) + a[x+2]) << 8) + a[x+1]) << 8) + a[x])