[Pcsclite-cvs-commit] r1808 - trunk/Drivers/ccid/src

Ludovic Rousseau rousseau at costa.debian.org
Wed Jan 18 10:25:38 UTC 2006


Author: rousseau
Date: 2006-01-18 10:25:34 +0000 (Wed, 18 Jan 2006)
New Revision: 1808

Modified:
   trunk/Drivers/ccid/src/ccid.h
   trunk/Drivers/ccid/src/ccid_serial.c
   trunk/Drivers/ccid/src/ccid_usb.c
   trunk/Drivers/ccid/src/defs.h
   trunk/Drivers/ccid/src/reader.conf.in
Log:
add support of GemCore SIM Pro and GemCore POS Pro (serial and USB).


Modified: trunk/Drivers/ccid/src/ccid.h
===================================================================
--- trunk/Drivers/ccid/src/ccid.h	2006-01-18 10:24:09 UTC (rev 1807)
+++ trunk/Drivers/ccid/src/ccid.h	2006-01-18 10:25:34 UTC (rev 1808)
@@ -119,6 +119,8 @@
 #define GEMPCKEY	0x08E63438
 #define GEMPCTWIN	0x08E63437
 #define GEMPCPINPAD 0x08E63478
+#define GEMCORESIMPRO 0x08E63480
+#define GEMCOREPOSPRO 0x08E63479
 #define CARDMAN3121	0x076B3021
 #define LTC31		0x07830003
 #define SCR331DI	0x04E65111
@@ -156,3 +158,17 @@
 /* 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])
 
+/* all the data rates specified by ISO 7816-3 Fi/Di tables */
+#define ISO_DATA_RATES 10753, 14337, 15625, 17204, \
+		20833, 21505, 23438, 25806, 28674, \
+		31250, 32258, 34409, 39063, 41667, \
+		43011, 46875, 52083, 53763, 57348, \
+		62500, 64516, 68817, 71685, 78125, \
+		83333, 86022, 93750, 104167, 107527, \
+		114695, 125000, 129032, 143369, 156250, \
+		166667, 172043, 215054, 229391, 250000, \
+		344086
+
+/* data rates supported by the secondary slots on the GemCore Pos Pro & SIM Pro */
+#define GEMPLUS_CUSTOM_DATA_RATES 10753, 21505, 43011, 125000
+

Modified: trunk/Drivers/ccid/src/ccid_serial.c
===================================================================
--- trunk/Drivers/ccid/src/ccid_serial.c	2006-01-18 10:24:09 UTC (rev 1807)
+++ trunk/Drivers/ccid/src/ccid_serial.c	2006-01-18 10:25:34 UTC (rev 1808)
@@ -42,6 +42,7 @@
 #include "ccid.h"
 #include "utils.h"
 #include "commands.h"
+#include "parser.h"
 
 #define SYNC 0x03
 #define CTRL_ACK 0x06
@@ -108,6 +109,17 @@
 	/*@null@*/ char *device;
 
 	/*
+	 * Number of slots using the same device
+	 */
+	int real_nb_opened_slots;
+	int *nb_opened_slots;
+
+	/*
+	 * does the reader echoes the serial communication bytes?
+	 */
+	int echo;
+
+	/*
 	 * serial communication buffer
 	 */
 	unsigned char buffer[GEMPCTWIN_MAXBUF];
@@ -132,50 +144,15 @@
 /* The _serialDevice structure must be defined before including ccid_serial.h */
 #include "ccid_serial.h"
 
-unsigned int SerialDataRates[] = {
-		10753,
-		14337,
-		15625,
-		17204,
-		20833,
-		21505,
-		23438,
-		25806,
-		28674,
-		31250,
-		32258,
-		34409,
-		39063,
-		41667,
-		43011,
-		46875,
-		52083,
-		53763,
-		57348,
-		62500,
-		64516,
-		68817,
-		71685,
-		78125,
-		83333,
-		86022,
-		93750,
-		104167,
-		107527,
-		114695,
-		125000,
-		129032,
-		143369,
-		156250,
-		166667,
-		172043,
-		215054,
-		229391,
-		250000,
-		344086,
-		0
-	};
+/* data rates supported by the GemPC Twin (serial and PCMCIA) */
+unsigned int SerialTwinDataRates[] = { ISO_DATA_RATES, 0 };
 
+/* data rates supported by the GemPC PinPad, GemCore Pos Pro & SIM Pro */
+unsigned int SerialExtendedDataRates[] = { ISO_DATA_RATES, 500000, 0 };
+
+/* data rates supported by the secondary slots on the GemCore Pos Pro & SIM Pro */
+unsigned int SerialCustomDataRates[] = { GEMPLUS_CUSTOM_DATA_RATES, 0 };
+
 /* no need to initialize to 0 since it is static */
 static _serialDevice serialDevice[CCID_DRIVER_MAX_READERS];
 
@@ -251,7 +228,7 @@
 	int i;
 
 	/* we get the echo first */
-	echo = TRUE;
+	echo = serialDevice[reader_index].echo;
 
 start:
 	DEBUG_COMM("start");
@@ -512,28 +489,175 @@
 
 /*****************************************************************************
  * 
+ *				set_ccid_descriptor: init ccid descriptor 
+ *				depending on reader type specified in device.
+ *
+ *				return: STATUS_UNSUCCESSFUL,
+ *						STATUS_SUCCESS,
+ *						-1 (Reader already used)
+ *
+ *****************************************************************************/
+static status_t set_ccid_descriptor(unsigned int reader_index,
+	const char *reader_name, const char *dev_name)
+{
+	long readerID;
+	int i;
+	int already_used = FALSE;
+	static int previous_reader_index = -1;
+
+	readerID = GEMPCTWIN;
+	if (0 == strcasecmp(reader_name,"GemCorePOSPro")) 
+		readerID = GEMCOREPOSPRO;
+	else if (0 == strcasecmp(reader_name,"GemCoreSIMPro"))
+		readerID = GEMCORESIMPRO;
+	else if (0 == strcasecmp(reader_name,"GemPCPinPad"))
+		readerID = GEMPCPINPAD;
+
+	/* check if the same channel is not already used to manage multi-slots readers*/
+	for (i = 0; i < CCID_DRIVER_MAX_READERS; i++)
+	{
+		if (serialDevice[i].device
+			&& strcmp(serialDevice[i].device, dev_name) == 0)
+		{
+			already_used = TRUE;
+
+			DEBUG_COMM2("%s already used. Multi-slot reader?", dev_name);
+			break;
+		}
+	}
+
+	/* this reader is already managed by us */
+	if (already_used)
+	{
+		if ((previous_reader_index != -1)
+			&& serialDevice[previous_reader_index].device
+			&& (strcmp(serialDevice[previous_reader_index].device, dev_name) == 0)
+			&& serialDevice[previous_reader_index].ccid.bCurrentSlotIndex < serialDevice[previous_reader_index].ccid.bMaxSlotIndex)
+		{
+			/* we reuse the same device and the reader is multi-slot */
+			serialDevice[reader_index] = serialDevice[previous_reader_index];
+
+			*serialDevice[reader_index].nb_opened_slots += 1;
+			serialDevice[reader_index].ccid.bCurrentSlotIndex++;
+			DEBUG_INFO2("Opening slot: %d",
+					serialDevice[reader_index].ccid.bCurrentSlotIndex);
+			switch (readerID)
+			{
+				case GEMCOREPOSPRO:
+				case GEMCORESIMPRO:
+					serialDevice[reader_index].ccid.arrayOfSupportedDataRates = SerialCustomDataRates;
+					serialDevice[reader_index].ccid.dwMaxDataRate = 125000;
+					break;
+
+				/* GemPC Twin or GemPC Card */
+				default:
+					serialDevice[reader_index].ccid.arrayOfSupportedDataRates = SerialTwinDataRates;
+					serialDevice[reader_index].ccid.dwMaxDataRate = 344086;
+					break;
+			}
+			goto end;
+		}
+		else
+		{
+			DEBUG_CRITICAL2("Trying to open too many slots on %s", dev_name);
+			return STATUS_UNSUCCESSFUL;
+		}
+
+	}
+
+	/* Common to all readers */
+	serialDevice[reader_index].ccid.real_bSeq = 0;
+	serialDevice[reader_index].ccid.pbSeq = &serialDevice[reader_index].ccid.real_bSeq;
+	serialDevice[reader_index].real_nb_opened_slots = 1;
+	serialDevice[reader_index].nb_opened_slots = &serialDevice[reader_index].real_nb_opened_slots;
+	serialDevice[reader_index].ccid.bCurrentSlotIndex = 0;
+
+	serialDevice[reader_index].ccid.dwMaxCCIDMessageLength = 271;
+	serialDevice[reader_index].ccid.dwMaxIFSD = 254;
+	serialDevice[reader_index].ccid.dwFeatures = 0x00010230;
+	serialDevice[reader_index].ccid.dwDefaultClock = 4000;
+
+	serialDevice[reader_index].buffer_offset = 0;
+	serialDevice[reader_index].buffer_offset_last = 0;
+
+	serialDevice[reader_index].ccid.readerID = readerID;
+	serialDevice[reader_index].ccid.bPINSupport = 0x0;
+	serialDevice[reader_index].ccid.dwMaxDataRate = 344086;
+	serialDevice[reader_index].ccid.bMaxSlotIndex = 0;
+	serialDevice[reader_index].ccid.arrayOfSupportedDataRates = SerialTwinDataRates;
+	serialDevice[reader_index].echo = TRUE;
+
+	/* change some values depending on the reader */
+	switch (readerID)
+	{
+		case GEMCOREPOSPRO:
+			serialDevice[reader_index].ccid.bMaxSlotIndex = 4;	/* 5 slots */
+			serialDevice[reader_index].ccid.arrayOfSupportedDataRates = SerialExtendedDataRates;
+			serialDevice[reader_index].echo = FALSE;
+			serialDevice[reader_index].ccid.dwMaxDataRate = 500000;
+			break;
+
+		case GEMCORESIMPRO:
+			serialDevice[reader_index].ccid.bMaxSlotIndex = 1; /* 2 slots */
+			serialDevice[reader_index].ccid.arrayOfSupportedDataRates = SerialExtendedDataRates;
+			serialDevice[reader_index].echo = FALSE;
+			serialDevice[reader_index].ccid.dwMaxDataRate = 500000;
+			break;
+
+		case GEMPCPINPAD:
+			serialDevice[reader_index].ccid.bPINSupport = 0x03;
+			serialDevice[reader_index].ccid.arrayOfSupportedDataRates = SerialExtendedDataRates;
+			serialDevice[reader_index].ccid.dwMaxDataRate = 500000;
+			break;
+	}
+
+end:
+	/* memorise the current reader_index so we can detect
+	 * a new OpenSerialByName on a multi slot reader */
+	previous_reader_index = reader_index;
+
+	/* we just created a secondary slot on a multi-slot reader */
+	if (already_used)
+		return STATUS_SECONDARY_SLOT;
+
+	return STATUS_SUCCESS;
+} /* set_ccid_descriptor  */
+
+
+/*****************************************************************************
+ * 
  *				OpenSerialByName: open the port
  *
  *****************************************************************************/
 status_t OpenSerialByName(unsigned int reader_index, char *dev_name)
 {
 	struct termios current_termios;
-	int i;
 	unsigned int reader = reader_index;
+	char reader_name[TOKEN_MAX_VALUE_SIZE] = "GemPCTwin";
+	char *p;
+	status_t ret;
 
 	DEBUG_COMM3("Reader index: %X, Device: %s", reader_index, dev_name);
 
-	/* check if the same channel is not already used */
-	for (i=0; i<CCID_DRIVER_MAX_READERS; i++)
+	/* parse dev_name using the pattern "device:name" */
+	p = strchr(dev_name, ':');
+	if (p)
 	{
-		if (serialDevice[i].device &&
-			strcmp(serialDevice[i].device, dev_name) == 0)
-		{
-			DEBUG_CRITICAL2("Device %s already in use", dev_name);
-			return STATUS_UNSUCCESSFUL;
-		}
+		/* copy the second part of the string */
+		strncpy(reader_name, p+1, sizeof(reader_name));
+
+		/* replace ':' by '\0' so that dev_name only contains the device name */
+		*p = '\0';
 	}
 
+	ret = set_ccid_descriptor(reader_index, reader_name, dev_name);
+	if (STATUS_UNSUCCESSFUL == ret)
+		return STATUS_UNSUCCESSFUL;
+
+	/* secondary slot so do not physically open the device */
+	if (STATUS_SECONDARY_SLOT == ret)
+		return STATUS_SUCCESS;
+
 	serialDevice[reader].fd = open(dev_name, O_RDWR | O_NOCTTY);
 
 	if (-1 == serialDevice[reader].fd)
@@ -610,23 +734,7 @@
 		return STATUS_UNSUCCESSFUL;
 	}
 
-	serialDevice[reader].ccid.real_bSeq = 0;
-	serialDevice[reader].ccid.pbSeq = &serialDevice[reader].ccid.real_bSeq;
-	serialDevice[reader].ccid.readerID = GEMPCTWIN;
-	serialDevice[reader].ccid.dwMaxCCIDMessageLength = 271;
-	serialDevice[reader].ccid.dwMaxIFSD = 254;
-	serialDevice[reader].ccid.dwFeatures = 0x00010230;
-	serialDevice[reader].ccid.bPINSupport = 0x0;
-	serialDevice[reader].ccid.dwDefaultClock = 4000;
-	serialDevice[reader].ccid.dwMaxDataRate = 344086;
-	serialDevice[reader].ccid.bMaxSlotIndex = 0;
-	serialDevice[reader].ccid.bCurrentSlotIndex = 0;
-	serialDevice[reader].ccid.arrayOfSupportedDataRates = SerialDataRates;
-
-	serialDevice[reader].buffer_offset = 0;
-	serialDevice[reader].buffer_offset_last = 0;
-
-	/* perform a command to be sure a GemPC Twin reader is connected
+	/* perform a command to be sure a Gemplus reader is connected
 	 * get the reader firmware */
 	{
 		unsigned char tx_buffer[] = { 0x02 };
@@ -681,12 +789,27 @@
 {
 	unsigned int reader = reader_index;
 
-	close(serialDevice[reader].fd);
-	serialDevice[reader].fd = -1;
+	/* device not opened */
+	if (NULL == serialDevice[reader_index].device)
+		return STATUS_UNSUCCESSFUL;
 
-	free(serialDevice[reader].device);
-	serialDevice[reader].device = NULL;
+	DEBUG_COMM2("Closing serial device: %s", serialDevice[reader_index].device);
 
+	/* Decrement number of opened slot */
+	(*serialDevice[reader_index].nb_opened_slots)--;
+
+	/* release the allocated ressources for the last slot only */
+	if (0 == *serialDevice[reader_index].nb_opened_slots)
+	{
+		DEBUG_COMM("Last slot closed. Release resources");
+
+		close(serialDevice[reader].fd);
+		serialDevice[reader].fd = -1;
+
+		free(serialDevice[reader].device);
+		serialDevice[reader].device = NULL;
+	}
+
 	return STATUS_SUCCESS;
 } /* CloseSerial */
 

Modified: trunk/Drivers/ccid/src/ccid_usb.c
===================================================================
--- trunk/Drivers/ccid/src/ccid_usb.c	2006-01-18 10:24:09 UTC (rev 1807)
+++ trunk/Drivers/ccid/src/ccid_usb.c	2006-01-18 10:25:34 UTC (rev 1808)
@@ -115,7 +115,10 @@
 	{ 0x0D46, 0x3002, 0x0037 },	/* KAAN Advanced */
 };
 
+/* data rates supported by the secondary slots on the GemCore Pos Pro & SIM Pro */
+unsigned int SerialCustomDataRates[] = { GEMPLUS_CUSTOM_DATA_RATES, 0 };
 
+
 /*****************************************************************************
  *
  *					OpenUSB
@@ -313,6 +316,14 @@
 							/* we reuse the same device
 							 * and the reader is multi-slot */
 							usbDevice[reader_index] = usbDevice[previous_reader_index];
+							/* the other slots do not have the same data rates */
+							if ((GEMCOREPOSPRO == usbDevice[reader_index].ccid.readerID)
+								|| (GEMCORESIMPRO == usbDevice[reader_index].ccid.readerID))
+							{
+								usbDevice[reader_index].ccid.arrayOfSupportedDataRates = SerialCustomDataRates;
+								usbDevice[reader_index].ccid.dwMaxDataRate = 125000;
+							}
+
 							*usbDevice[reader_index].nb_opened_slots += 1;
 							usbDevice[reader_index].ccid.bCurrentSlotIndex++;
 							DEBUG_INFO2("Opening slot: %d",

Modified: trunk/Drivers/ccid/src/defs.h
===================================================================
--- trunk/Drivers/ccid/src/defs.h	2006-01-18 10:24:09 UTC (rev 1807)
+++ trunk/Drivers/ccid/src/defs.h	2006-01-18 10:25:34 UTC (rev 1808)
@@ -49,7 +49,8 @@
 	STATUS_UNSUCCESSFUL          = 0xFB,
 	STATUS_COMM_ERROR            = 0xFC,
 	STATUS_DEVICE_PROTOCOL_ERROR = 0xFD,
-	STATUS_COMM_NAK              = 0xFE
+	STATUS_COMM_NAK              = 0xFE,
+	STATUS_SECONDARY_SLOT        = 0xFF
 } status_t;
 
 /* Powerflag (used to detect quick insertion removals unnoticed by the 

Modified: trunk/Drivers/ccid/src/reader.conf.in
===================================================================
--- trunk/Drivers/ccid/src/reader.conf.in	2006-01-18 10:24:09 UTC (rev 1807)
+++ trunk/Drivers/ccid/src/reader.conf.in	2006-01-18 10:25:34 UTC (rev 1808)
@@ -1,7 +1,10 @@
-
-# Gemplus GemPCTwin reader with serial communication
-# n is the serial port to use n in [1..4]
-FRIENDLYNAME      "GemPCTwin serial"
-DEVICENAME        /dev/pcsc/n
-LIBPATH           TARGET
-CHANNELID         n
+# Gemplus reader with serial communication
+#  - n is the serial port to use n in [0..3]
+#  - reader is the reader name. It is needed for multi-slot readers.
+#    Possible reader values are: GemPCPinPad, GemCorePOSPro, GemCoreSIMPro,
+#    GemPCTwin (default value)
+# example: /dev/ttyS0:GemPCPinPad
+#FRIENDLYNAME      "GemPCTwin serial"
+#DEVICENAME        /dev/ttySn[:reader]
+#LIBPATH           TARGET
+#CHANNELID         n




More information about the Pcsclite-cvs-commit mailing list