SpinDelay(300);
}
}
- if (!iso14443a_select_card(uid, &hi14a_card[selected], &cuid, true, 0))
+ if (!iso14443a_select_card(uid, &hi14a_card[selected], &cuid, true, 0, true))
continue;
else
{
// power up the field
iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
// select the card
- return_code = iso14443a_select_card(uid, &card_select_info, NULL, true, 0);
+ return_code = iso14443a_select_card(uid, &card_select_info, NULL, true, 0, false);
if (return_code == 1) {
// send the PPS request
ReaderTransmit((uint8_t *)pps, sizeof(pps), NULL);
// fills the card info record unless NULL
// if anticollision is false, then the UID must be provided in uid_ptr[]
// and num_cascades must be set (1: 4 Byte UID, 2: 7 Byte UID, 3: 10 Byte UID)
-int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades) {
+// requests ATS unless no_rats is true
+int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades, bool no_rats) {
uint8_t wupa[] = { 0x52 }; // 0x26 - REQA 0x52 - WAKE-UP
uint8_t sel_all[] = { 0x93,0x20 };
uint8_t sel_uid[] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
// non iso14443a compliant tag
if( (sak & 0x20) == 0) return 2;
- // Request for answer to select
- AppendCrc14443a(rats, 2);
- ReaderTransmit(rats, sizeof(rats), NULL);
+ if (!no_rats) {
+ // Request for answer to select
+ 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, sizeof(p_hi14a_card->ats));
- p_hi14a_card->ats_len = len;
- }
-
- // reset the PCB block number
- iso14_pcb_blocknum = 0;
+ if(p_hi14a_card) {
+ memcpy(p_hi14a_card->ats, resp, len);
+ p_hi14a_card->ats_len = len;
+ }
- // set default timeout based on ATS
- iso14a_set_ATS_timeout(resp);
+ // reset the PCB block number
+ iso14_pcb_blocknum = 0;
+ // set default timeout based on ATS
+ iso14a_set_ATS_timeout(resp);
+ }
return 1;
}
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
if(!(param & ISO14A_NO_SELECT)) {
iso14a_card_select_t *card = (iso14a_card_select_t*)buf;
- arg0 = iso14443a_select_card(NULL, card, NULL, true, 0);
+ arg0 = iso14443a_select_card(NULL, card, NULL, true, 0, param & ISO14A_NO_RATS);
cmd_send(CMD_ACK,arg0,card->uidlen,0,buf,sizeof(iso14a_card_select_t));
}
}
SpinDelay(100);
}
- if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {
+ if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Mifare: Can't select card");
continue;
}
extern void iso14443a_setup(uint8_t fpga_minor_mode);
extern int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data);
-extern int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *resp_data, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades);
+extern int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *resp_data, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades, bool no_rats);
extern void iso14a_set_trigger(bool enable);
#endif /* __ISO14443A_H */
LED_C_OFF();\r
\r
while (true) {\r
- if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {\r
+ if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
break;\r
};\r
\r
clear_trace();\r
\r
- if(!iso14443a_select_card(NULL, NULL, NULL, true, 0)) {\r
+ if(!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) {\r
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");\r
OnError(0);\r
return;\r
\r
clear_trace();\r
\r
- int len = iso14443a_select_card(NULL, NULL, NULL, true, 0);\r
+ int len = iso14443a_select_card(NULL, NULL, NULL, true, 0, true);\r
if(!len) {\r
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%02X)",len);\r
OnError(1);\r
LED_C_OFF();\r
\r
isOK = 1;\r
- if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {\r
+ if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {\r
isOK = 0;\r
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
}\r
return;\r
}\r
\r
- int len = iso14443a_select_card(NULL, NULL, NULL, true, 0);\r
+ int len = iso14443a_select_card(NULL, NULL, NULL, true, 0, true);\r
if (!len) {\r
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%d)",len);\r
OnError(1);\r
LED_C_OFF();\r
\r
while (true) {\r
- if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {\r
+ if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
break;\r
};\r
\r
clear_trace();\r
\r
- if(!iso14443a_select_card(NULL, NULL, NULL, true, 0)) {\r
+ if(!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
OnError(0);\r
return;\r
\r
clear_trace();\r
\r
- if(!iso14443a_select_card(NULL, NULL, NULL, true, 0)) {\r
+ if(!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
OnError(0);\r
return;\r
\r
if (!have_uid) { // need a full select cycle to get the uid first\r
iso14a_card_select_t card_info;\r
- if(!iso14443a_select_card(uid, &card_info, &cuid, true, 0)) {\r
+ if(!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("AcquireNonces: Can't select card (ALL)");\r
continue;\r
}\r
}\r
have_uid = true;\r
} else { // no need for anticollision. We can directly select the card\r
- if(!iso14443a_select_card(uid, NULL, NULL, false, cascade_levels)) {\r
+ if(!iso14443a_select_card(uid, NULL, NULL, false, cascade_levels, true)) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("AcquireNonces: Can't select card (UID)");\r
continue;\r
}\r
continue;\r
}\r
\r
- if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {\r
+ if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Can't select card");\r
rtr--;\r
continue;\r
continue;\r
}\r
\r
- if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {\r
+ if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Can't select card");\r
continue;\r
};\r
// Iceman: use piwi's faster nonce collecting part in hardnested.\r
if (!have_uid) { // need a full select cycle to get the uid first\r
iso14a_card_select_t card_info;\r
- if(!iso14443a_select_card(uid, &card_info, &cuid, true, 0)) {\r
+ if(!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) {\r
if (OLD_MF_DBGLEVEL >= 1) Dbprintf("ChkKeys: Can't select card");\r
--i; // try same key once again\r
continue;\r
}\r
have_uid = true;\r
} else { // no need for anticollision. We can directly select the card\r
- if(!iso14443a_select_card(uid, NULL, NULL, false, cascade_levels)) {\r
+ if(!iso14443a_select_card(uid, NULL, NULL, false, cascade_levels, true)) {\r
if (OLD_MF_DBGLEVEL >= 1) Dbprintf("ChkKeys: Can't select card (UID)");\r
--i; // try same key once again\r
continue;\r
\r
bool isOK = true;\r
\r
- if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {\r
+ if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {\r
isOK = false;\r
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
}\r
\r
// get UID from chip\r
if (workFlags & 0x01) {\r
- if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {\r
+ if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
// Continue, if we set wrong UID or wrong UID checksum or some ATQA or SAK we will can't select card. But we need to write block 0 to make card work.\r
//break;\r
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
clear_trace();\r
\r
- int len = iso14443a_select_card(uid, NULL, &cuid, true, 0);\r
+ int len = iso14443a_select_card(uid, NULL, &cuid, true, 0, true);\r
if(!len) {\r
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");\r
OnError(1);\r
// repeat n times
for (int i = 0; i < n; i++) {
// execute anticollision procedure
- UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT, 0, 0}};
+ UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_RATS, 0, 0}};
SendCommand(&c);
UsbCommand resp;
bool power = false;
bool active = false;
bool active_select = false;
+ bool no_rats = false;
uint16_t numbits = 0;
bool bTimeout = false;
uint32_t timeout = 0;
PrintAndLog(" -b number of bits to send. Useful for send partial byte");
PrintAndLog(" -t timeout in ms");
PrintAndLog(" -T use Topaz protocol to send command");
+ PrintAndLog(" -3 ISO14443-3 select only (skip RATS)");
return 0;
}
case 'T':
topazmode = true;
break;
+ case '3':
+ no_rats = true;
+ break;
default:
PrintAndLog("Invalid option");
return 0;
c.arg[0] |= ISO14A_TOPAZMODE;
}
+ if(no_rats) {
+ c.arg[0] |= ISO14A_NO_RATS;
+ }
+
// Max buffer is USB_CMD_DATA_SIZE (512)
c.arg[1] = (datalen & 0xFFFF) | ((uint32_t)numbits << 16);
memcpy(c.d.asBytes,data,datalen);
}
static void ul_switch_on_field(void) {
- UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0}};
+ UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT | ISO14A_NO_RATS, 0, 0}};
clearCommandBuffer();
SendCommand(&c);
}
UsbCommand resp;\r
WaitForResponse(CMD_ACK,&resp);\r
\r
- iso14a_card_select_t card;\r
- memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t));\r
-\r
- uint64_t select_status = resp.arg[0]; // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision\r
-\r
- if(select_status != 0) {\r
- uint8_t rats[] = { 0xE0, 0x80 }; // FSDI=8 (FSD=256), CID=0\r
- c.arg[0] = ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT;\r
- c.arg[1] = 2;\r
- c.arg[2] = 0;\r
- memcpy(c.d.asBytes, rats, 2);\r
- SendCommand(&c);\r
- WaitForResponse(CMD_ACK,&resp);\r
- }\r
+ // iso14a_card_select_t card;\r
+ // memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t));\r
+\r
+ // uint64_t select_status = resp.arg[0]; // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision\r
+\r
+ // if(select_status != 0) {\r
+ // uint8_t rats[] = { 0xE0, 0x80 }; // FSDI=8 (FSD=256), CID=0\r
+ // c.arg[0] = ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT;\r
+ // c.arg[1] = 2;\r
+ // c.arg[2] = 0;\r
+ // memcpy(c.d.asBytes, rats, 2);\r
+ // SendCommand(&c);\r
+ // WaitForResponse(CMD_ACK,&resp);\r
+ // }\r
\r
c.cmd = CMD_MIFARE_CIDENT;\r
c.arg[0] = 0;\r
ISO14A_APPEND_CRC = (1 << 5),
ISO14A_SET_TIMEOUT = (1 << 6),
ISO14A_NO_SELECT = (1 << 7),
- ISO14A_TOPAZMODE = (1 << 8)
+ ISO14A_TOPAZMODE = (1 << 8),
+ ISO14A_NO_RATS = (1 << 9)
} iso14a_command_t;
typedef struct {