#include "BigBuf.h"
#include "protocols.h"
#include "parity.h"
+#include "fpgaloader.h"
typedef struct {
enum {
EmSendPrecompiledCmd(p_response);
}
- if (!tracing) {
+ if (!get_tracing()) {
Dbprintf("Trace Full. Simulation stopped.");
break;
}
LED_A_ON();
// Log reader command in trace buffer
- if (tracing) {
- LogTrace(frame, nbytes(bits), LastTimeProxToAirStart*16 + DELAY_ARM2AIR_AS_READER, (LastTimeProxToAirStart + LastProxToAirDuration)*16 + DELAY_ARM2AIR_AS_READER, par, true);
- }
+ LogTrace(frame, nbytes(bits), LastTimeProxToAirStart*16 + DELAY_ARM2AIR_AS_READER, (LastTimeProxToAirStart + LastProxToAirDuration)*16 + DELAY_ARM2AIR_AS_READER, par, true);
}
static int ReaderReceiveOffset(uint8_t* receivedAnswer, uint16_t offset, uint8_t *parity)
{
if (!GetIso14443aAnswerFromTag(receivedAnswer, parity, offset)) return false;
- if (tracing) {
- LogTrace(receivedAnswer, Demod.len, Demod.startTime*16 - DELAY_AIR2ARM_AS_READER, Demod.endTime*16 - DELAY_AIR2ARM_AS_READER, parity, false);
- }
+ LogTrace(receivedAnswer, Demod.len, Demod.startTime*16 - DELAY_AIR2ARM_AS_READER, Demod.endTime*16 - DELAY_AIR2ARM_AS_READER, parity, false);
return Demod.len;
}
int ReaderReceive(uint8_t *receivedAnswer, uint8_t *parity)
{
if (!GetIso14443aAnswerFromTag(receivedAnswer, parity, 0)) return false;
- if (tracing) {
- LogTrace(receivedAnswer, Demod.len, Demod.startTime*16 - DELAY_AIR2ARM_AS_READER, Demod.endTime*16 - DELAY_AIR2ARM_AS_READER, parity, false);
- }
+ LogTrace(receivedAnswer, Demod.len, Demod.startTime*16 - DELAY_AIR2ARM_AS_READER, Demod.endTime*16 - DELAY_AIR2ARM_AS_READER, parity, false);
return Demod.len;
}
if (anticollision) {
// SELECT_ALL
ReaderTransmit(sel_all, sizeof(sel_all), NULL);
- if (!ReaderReceive(resp, resp_par)) return 0;
+ if (!ReaderReceive(resp, resp_par)) {
+ return 0;
+ }
if (Demod.collisionPos) { // we had a collision and need to construct the UID bit by bit
memset(uid_resp, 0, 4);
}
collision_answer_offset = uid_resp_bits%8;
ReaderTransmitBits(sel_uid, 16 + uid_resp_bits, NULL);
- if (!ReaderReceiveOffset(resp, collision_answer_offset, resp_par)) return 0;
+ if (!ReaderReceiveOffset(resp, collision_answer_offset, resp_par)) {
+ return 0;
+ }
}
// finally, add the last bits and BCC of the UID
for (uint16_t i = collision_answer_offset; i < (Demod.len-1)*8; i++, uid_resp_bits++) {
ReaderTransmit(sel_uid, sizeof(sel_uid), NULL);
// Receive the SAK
- if (!ReaderReceive(resp, resp_par)) return 0;
+ if (!ReaderReceive(resp, resp_par)) {
+ return 0;
+ }
sak = resp[0];
// Test if more parts of the uid are coming
AppendCrc14443a(rats, 2);
ReaderTransmit(rats, sizeof(rats), NULL);
- if (!(len = ReaderReceive(resp, resp_par))) return 0;
+ if (!(len = ReaderReceive(resp, resp_par))) {
+ return 0;
+ }
if(p_hi14a_card) {
memcpy(p_hi14a_card->ats, resp, len);
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);
return 0; //DATA LINK ERROR
} else{
// S-Block WTX
- while((data_bytes[0] & 0xF2) == 0xF2) {
+ while(len && ((data_bytes[0] & 0xF2) == 0xF2)) {
uint32_t save_iso14a_timeout = iso14a_get_timeout();
// temporarily increase timeout
iso14a_set_timeout(MAX((data_bytes[1] & 0x3f) * save_iso14a_timeout, MAX_ISO14A_TIMEOUT));
{
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;
}
}
- // cut frame byte
- len -= 1;
- // memmove(data_bytes, data_bytes + 1, len);
- for (int i = 0; i < len; i++)
- data_bytes[i] = data_bytes[i + 1];
-
+ if (len) {
+ // cut frame byte
+ len -= 1;
+ // memmove(data_bytes, data_bytes + 1, len);
+ for (int i = 0; i < len; i++)
+ data_bytes[i] = data_bytes[i + 1];
+ }
+
return len;
}
// 1 - all is OK with ATS, 2 - without ATS
cantSELECT = true;
}
-
+ FpgaDisableTracing();
LED_B_ON();
cmd_send(CMD_ACK,arg0,card->uidlen,0,buf,sizeof(iso14a_card_select_t));
LED_B_OFF();
}
if(param & ISO14A_APDU && !cantSELECT) {
- arg0 = iso14_apdu(cmd, len, buf);
+ uint8_t res;
+ arg0 = iso14_apdu(cmd, len, buf, &res);
+ FpgaDisableTracing();
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();
}
}
}
arg0 = ReaderReceive(buf, par);
+ FpgaDisableTracing();
LED_B_ON();
cmd_send(CMD_ACK,arg0,0,0,buf,sizeof(buf));
}
}
+ FpgaDisableTracing();
+
uint8_t buf[32];
memcpy(buf + 0, uid, 4);
num_to_bytes(nt, 4, buf + 4);
DbpString("COMMAND FINISHED.");
FpgaDisableSscDma();
+ FpgaDisableTracing();
MfSniffEnd();
Dbprintf("maxDataLen=%x, Uart.state=%x, Uart.len=%x", maxDataLen, Uart.state, Uart.len);