Blame SOURCES/ccid-1.4.10-omnikey-3121.patch

ee67d4
diff -up ./src/ccid.c.omnikey ./src/ccid.c
ee67d4
--- ./src/ccid.c.omnikey	2012-06-08 07:17:11.000000000 -0700
ee67d4
+++ ./src/ccid.c	2014-09-26 16:40:54.279531436 -0700
ee67d4
@@ -47,8 +47,13 @@ int ccid_open_hack_pre(unsigned int read
ee67d4
 {
ee67d4
 	_ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
ee67d4
 
ee67d4
+	ccid_descriptor->dwNonStandardFlags = 0;
ee67d4
+
ee67d4
 	switch (ccid_descriptor->readerID)
ee67d4
 	{
ee67d4
+		case CARDMAN3121:
ee67d4
+			ccid_descriptor->dwNonStandardFlags = CCID_NON_STAND_OMK_3121_T1;
ee67d4
+			/* fall through */
ee67d4
 		case CARDMAN3121+1:
ee67d4
 			/* Reader announces APDU but is in fact TPDU */
ee67d4
 			ccid_descriptor->dwFeatures &= ~CCID_CLASS_EXCHANGE_MASK;
ee67d4
diff -up ./src/ccid.h.omnikey ./src/ccid.h
ee67d4
--- ./src/ccid.h.omnikey	2012-06-08 07:17:11.000000000 -0700
ee67d4
+++ ./src/ccid.h	2014-09-26 16:40:54.279531436 -0700
ee67d4
@@ -141,6 +141,7 @@ typedef struct
ee67d4
 	 * Gemalto extra features, if any
ee67d4
 	 */
ee67d4
 	struct GEMALTO_FIRMWARE_FEATURES *gemalto_firmware_features;
ee67d4
+	unsigned int dwNonStandardFlags;
ee67d4
 } _ccid_descriptor;
ee67d4
 
ee67d4
 /* Features from dwFeatures */
ee67d4
@@ -156,6 +157,9 @@ typedef struct
ee67d4
 #define CCID_CLASS_EXTENDED_APDU	0x00040000
ee67d4
 #define CCID_CLASS_EXCHANGE_MASK	0x00070000
ee67d4
 
ee67d4
+/* Features from the swNonStandardFlags */
ee67d4
+#define CCID_NON_STAND_OMK_3121_T1	0x00000001
ee67d4
+
ee67d4
 /* Features from bPINSupport */
ee67d4
 #define CCID_CLASS_PIN_VERIFY		0x01
ee67d4
 #define CCID_CLASS_PIN_MODIFY		0x02
ee67d4
diff -up ./src/commands.c.omnikey ./src/commands.c
ee67d4
--- ./src/commands.c.omnikey	2014-09-26 16:40:54.276531385 -0700
ee67d4
+++ ./src/commands.c	2014-09-26 16:41:39.463293364 -0700
ee67d4
@@ -1186,6 +1186,39 @@ RESPONSECODE CmdXfrBlock(unsigned int re
ee67d4
 	return return_value;
ee67d4
 } /* CmdXfrBlock */
ee67d4
 
ee67d4
+static RESPONSECODE omnikey_transmit_tpdu(unsigned int reader_index,
ee67d4
+        _ccid_descriptor *ccid_descriptor, unsigned int tx_length,
ee67d4
+        const unsigned char *tx_buffer)
ee67d4
+{
ee67d4
+	unsigned char cmd[11+CMD_BUF_SIZE];	 /* CCID + APDU buffer */
ee67d4
+	status_t ret;
ee67d4
+
ee67d4
+	cmd[0] = 0x6B; 				/* 3121 escape */
ee67d4
+	i2dw(tx_length+1, cmd+1); 	/* APDU length */
ee67d4
+	cmd[5] = ccid_descriptor->bCurrentSlotIndex;	/* slot number */
ee67d4
+	cmd[6] = (*ccid_descriptor->pbSeq)++;
ee67d4
+	cmd[7] = 0;
ee67d4
+	cmd[8] = 0;
ee67d4
+	cmd[9] = 0;
ee67d4
+	cmd[10] = 0x1A;
ee67d4
+
ee67d4
+	/* check that the command is not too large */
ee67d4
+	if (tx_length > CMD_BUF_SIZE)
ee67d4
+	{
ee67d4
+		DEBUG_CRITICAL2("TX Length too big: %d", tx_length);
ee67d4
+		return IFD_NOT_SUPPORTED;
ee67d4
+	}
ee67d4
+
ee67d4
+	memcpy(cmd+11, tx_buffer, tx_length);
ee67d4
+
ee67d4
+	ret = WritePort(reader_index, 11+tx_length, cmd);
ee67d4
+	if (STATUS_NO_SUCH_DEVICE == ret)
ee67d4
+		return IFD_NO_SUCH_DEVICE;
ee67d4
+	if (ret != STATUS_SUCCESS)
ee67d4
+		return IFD_COMMUNICATION_ERROR;
ee67d4
+
ee67d4
+	return IFD_SUCCESS;
ee67d4
+} /* omnikey_transmit_tpdu */
ee67d4
 
ee67d4
 /*****************************************************************************
ee67d4
  *
ee67d4
@@ -1242,6 +1275,13 @@ RESPONSECODE CCID_Transmit(unsigned int
ee67d4
 	}
ee67d4
 #endif
ee67d4
 
ee67d4
+	/* hack for Onmikey 3121 */
ee67d4
+	if ((ccid_descriptor->dwNonStandardFlags & CCID_NON_STAND_OMK_3121_T1) &&
ee67d4
+		(ccid_descriptor->cardProtocol == SCARD_PROTOCOL_T1)) {
ee67d4
+		return omnikey_transmit_tpdu(reader_index, ccid_descriptor, tx_length, 
ee67d4
+				tx_buffer);
ee67d4
+	}
ee67d4
+
ee67d4
 	cmd[0] = 0x6F; /* XfrBlock */
ee67d4
 	i2dw(tx_length, cmd+1);	/* APDU length */
ee67d4
 	cmd[5] = ccid_descriptor->bCurrentSlotIndex;	/* slot number */
ee67d4
@@ -1267,13 +1307,14 @@ RESPONSECODE CCID_Transmit(unsigned int
ee67d4
 RESPONSECODE CCID_Receive(unsigned int reader_index, unsigned int *rx_length,
ee67d4
 	unsigned char rx_buffer[], unsigned char *chain_parameter)
ee67d4
 {
ee67d4
-	unsigned char cmd[10+CMD_BUF_SIZE];	/* CCID + APDU buffer */
ee67d4
+	unsigned char cmd[11+CMD_BUF_SIZE];	/* CCID + APDU buffer */
ee67d4
 	unsigned int length;
ee67d4
+	unsigned char *rx_ptr = cmd+10;
ee67d4
 	RESPONSECODE return_value = IFD_SUCCESS;
ee67d4
 	status_t ret;
ee67d4
+	_ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
ee67d4
 
ee67d4
 #ifndef TWIN_SERIAL
ee67d4
-	_ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
ee67d4
 
ee67d4
 	if (PROTOCOL_ICCD_A == ccid_descriptor->bInterfaceProtocol)
ee67d4
 	{
ee67d4
@@ -1447,6 +1488,14 @@ time_request:
ee67d4
 	}
ee67d4
 
ee67d4
 	length = dw2i(cmd, 1);
ee67d4
+
ee67d4
+	if (length && 
ee67d4
+	  (ccid_descriptor->dwNonStandardFlags & CCID_NON_STAND_OMK_3121_T1) &&
ee67d4
+	  (ccid_descriptor->cardProtocol == SCARD_PROTOCOL_T1)) {
ee67d4
+		length--;
ee67d4
+		rx_ptr = cmd+11;
ee67d4
+	}
ee67d4
+
ee67d4
 	if (length <= *rx_length)
ee67d4
 		*rx_length = length;
ee67d4
 	else
ee67d4
@@ -1463,7 +1512,7 @@ time_request:
ee67d4
 		return_value = IFD_COMMUNICATION_ERROR;
ee67d4
 	}
ee67d4
 	else
ee67d4
-		memcpy(rx_buffer, cmd+10, length);
ee67d4
+		memcpy(rx_buffer, rx_ptr, length);
ee67d4
 
ee67d4
 	/* Extended case?
ee67d4
 	 * Only valid for RDR_to_PC_DataBlock frames */