X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/050aa18b13084b0d57ffcee352bf7a30b828b8f5..6a2bd857195a0fb99342d93859f21150f666a089:/armsrc/iso14443a.c

diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c
index 059db71e..7bf8f5af 100644
--- a/armsrc/iso14443a.c
+++ b/armsrc/iso14443a.c
@@ -1935,15 +1935,21 @@ b8 b7 b6 b5 b4 b3 b2 b1
 b5,b6 = 00 - DESELECT
         11 - WTX 
 */    
-int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data) {
+int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data, uint8_t *res) {
 	uint8_t parity[MAX_PARITY_SIZE];
 	uint8_t real_cmd[cmd_len + 4];
 	
-	// ISO 14443 APDU frame: PCB [CID] [NAD] APDU CRC PCB=0x02
-	real_cmd[0] = 0x02; // bnr,nad,cid,chn=0; i-block(0x00)	
-	// put block number into the PCB
-	real_cmd[0] |= iso14_pcb_blocknum;
-	memcpy(real_cmd + 1, cmd, cmd_len);
+	if (cmd_len) {
+		// ISO 14443 APDU frame: PCB [CID] [NAD] APDU CRC PCB=0x02
+		real_cmd[0] = 0x02; // bnr,nad,cid,chn=0; i-block(0x00)	
+		// put block number into the PCB
+		real_cmd[0] |= iso14_pcb_blocknum;
+		memcpy(real_cmd + 1, cmd, cmd_len);
+	} else {
+		// R-block. ACK
+		real_cmd[0] = 0xA2; // r-block + ACK	
+		real_cmd[0] |= iso14_pcb_blocknum;
+	}
 	AppendCrc14443a(real_cmd, cmd_len + 1);
  
 	ReaderTransmit(real_cmd, cmd_len + 3, NULL);
@@ -1982,9 +1988,13 @@ int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data) {
 		{
 			iso14_pcb_blocknum ^= 1;
 		}
+		
+		// if we received I-block with chaining we need to send ACK and receive another block of data
+		if (res)
+			*res = data_bytes[0];
 
 		// crc check
-		if (len >=3 && !CheckCrc14443(CRC_14443_A, data_bytes, len)) {
+		if (len >= 3 && !CheckCrc14443(CRC_14443_A, data_bytes, len)) {
 			return -1;
 		}
 		
@@ -2050,9 +2060,10 @@ void ReaderIso14443a(UsbCommand *c)
 	}
 
 	if(param & ISO14A_APDU && !cantSELECT) {
-		arg0 = iso14_apdu(cmd, len, buf);
+		uint8_t res;
+		arg0 = iso14_apdu(cmd, len, buf, &res);
 		LED_B_ON();
-		cmd_send(CMD_ACK, arg0, 0, 0, buf, sizeof(buf));
+		cmd_send(CMD_ACK, arg0, res, 0, buf, sizeof(buf));
 		LED_B_OFF();
 	}