+static int SelectCard14443_4(bool disconnect, iso14a_card_select_t *card) {
+ UsbCommand resp;
+
+ frameLength = 0;
+
+ if (card)
+ memset(card, 0, sizeof(iso14a_card_select_t));
+
+ DropField();
+
+ // Anticollision + SELECT card
+ UsbCommand ca = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0}};
+ SendCommand(&ca);
+ if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
+ PrintAndLogEx(ERR, "Proxmark connection timeout.");
+ return 1;
+ }
+
+ // check result
+ if (resp.arg[0] == 0) {
+ PrintAndLogEx(ERR, "No card in field.");
+ return 1;
+ }
+
+ if (resp.arg[0] != 1 && resp.arg[0] != 2) {
+ PrintAndLogEx(ERR, "Card not in iso14443-4. res=%d.", resp.arg[0]);
+ return 1;
+ }
+
+ if (resp.arg[0] == 2) { // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision
+ // try to get ATS although SAK indicated that it is not ISO14443-4 compliant
+ UsbCommand cr = {CMD_READER_ISO_14443a, {ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT, 2, 0}};
+ uint8_t rats[] = { 0xE0, 0x80 }; // FSDI=8 (FSD=256), CID=0
+ memcpy(cr.d.asBytes, rats, 2);
+ SendCommand(&cr);
+ if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
+ PrintAndLogEx(ERR, "Proxmark connection timeout.");
+ return 1;
+ }
+
+ if (resp.arg[0] <= 0) { // ats_len
+ PrintAndLogEx(ERR, "Can't get ATS.");
+ return 1;
+ }
+ }
+
+ // get frame length from ATS
+ iso14a_card_select_t *vcard = (iso14a_card_select_t *) resp.d.asBytes;
+ if (vcard->ats_len > 1) {
+ uint8_t fsci = vcard->ats[1] & 0x0f;
+ if (fsci < sizeof(atsFSC))
+ frameLength = atsFSC[fsci];
+ }
+
+ if (card) {
+ memcpy(card, vcard, sizeof(iso14a_card_select_t));
+ }
+
+ if (disconnect) {
+ DropField();
+ }
+
+ return 0;
+}
+
+
+static int ExchangeAPDU(bool chainingin, uint8_t *datain, int datainlen, bool activateField, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool *chainingout)
+{
+ *chainingout = false;
+