X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/664e132f882e04cf8aafe9a6d8fc137d57816ab8..39cc1c879e3d75b3cafd79e4e139a7f6673dd349:/armsrc/iso14443a.c diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index a8273e5e..7bf8f5af 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1405,7 +1405,7 @@ int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *parity) ADC_MODE_PRESCALE(63) | ADC_MODE_STARTUP_TIME(1) | ADC_MODE_SAMPLE_HOLD_TIME(15); - AT91C_BASE_ADC->ADC_CHER = ADC_CHANNEL(ADC_CHAN_HF); + AT91C_BASE_ADC->ADC_CHER = ADC_CHANNEL(ADC_CHAN_HF_LOW); // start ADC AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START; @@ -1432,12 +1432,12 @@ int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *parity) if (BUTTON_PRESS()) return 1; // test if the field exists - if (AT91C_BASE_ADC->ADC_SR & ADC_END_OF_CONVERSION(ADC_CHAN_HF)) { + if (AT91C_BASE_ADC->ADC_SR & ADC_END_OF_CONVERSION(ADC_CHAN_HF_LOW)) { analogCnt++; - analogAVG += AT91C_BASE_ADC->ADC_CDR[ADC_CHAN_HF]; + analogAVG += AT91C_BASE_ADC->ADC_CDR[ADC_CHAN_HF_LOW]; AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START; if (analogCnt >= 32) { - if ((MAX_ADC_HF_VOLTAGE * (analogAVG / analogCnt) >> 10) < MF_MINFIELDV) { + if ((MAX_ADC_HF_VOLTAGE_LOW * (analogAVG / analogCnt) >> 10) < MF_MINFIELDV) { vtime = GetTickCount(); if (!timer) timer = vtime; // 50ms no field --> card to idle state @@ -1889,7 +1889,7 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u void iso14443a_setup(uint8_t fpga_minor_mode) { FpgaDownloadAndGo(FPGA_BITSTREAM_HF); // Set up the synchronous serial port - FpgaSetupSsc(); + FpgaSetupSsc(FPGA_MAJOR_MODE_HF_ISO14443A); // connect Demodulated Signal to ADC: SetAdcMuxFor(GPIO_MUXSEL_HIPKD); @@ -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(); }