+
+ return 0;
+}
+
+int CmdHF14AAPDU(const char *cmd) {
+ uint8_t data[USB_CMD_DATA_SIZE];
+ int datalen = 0;
+ bool activateField = false;
+ bool leaveSignalON = false;
+ bool decodeTLV = false;
+
+ if (strlen(cmd) < 2) {
+ PrintAndLog("Usage: hf 14a apdu [-s] [-k] [-t] <APDU (hex)>");
+ PrintAndLog(" -s activate field and select card");
+ PrintAndLog(" -k leave the signal field ON after receive response");
+ PrintAndLog(" -t executes TLV decoder if it possible");
+ return 0;
+ }
+
+ int cmdp = 0;
+ while(param_getchar(cmd, cmdp) != 0x00) {
+ char c = param_getchar(cmd, cmdp);
+ if ((c == '-') && (param_getlength(cmd, cmdp) == 2))
+ switch (param_getchar_indx(cmd, 1, cmdp)) {
+ case 's':
+ case 'S':
+ activateField = true;
+ break;
+ case 'k':
+ case 'K':
+ leaveSignalON = true;
+ break;
+ case 't':
+ case 'T':
+ decodeTLV = true;
+ break;
+ default:
+ PrintAndLog("Unknown parameter '%c'", param_getchar_indx(cmd, 1, cmdp));
+ return 1;
+ }
+
+ if (isxdigit(c)) {
+ // len = data + PCB(1b) + CRC(2b)
+ switch(param_gethex_to_eol(cmd, cmdp, data, sizeof(data) - 1 - 2, &datalen)) {
+ case 1:
+ PrintAndLog("Invalid HEX value.");
+ return 1;
+ case 2:
+ PrintAndLog("APDU too large.");
+ return 1;
+ case 3:
+ PrintAndLog("Hex must have even number of digits.");
+ return 1;
+ }
+
+ // we get all the hex to end of line with spaces
+ break;
+ }
+
+ cmdp++;
+ }
+
+ PrintAndLog("--%s %s %s >>>> %s", activateField ? "sel": "", leaveSignalON ? "keep": "", decodeTLV ? "TLV": "", sprint_hex(data, datalen));
+
+ switch(ExchangeAPDU14a(data, datalen, activateField, leaveSignalON, data, &datalen)) {
+ case 0:
+ break;
+ case 1:
+ PrintAndLog("APDU ERROR: Send APDU error.");
+ return 1;
+ case 2:
+ return 2;
+ case 3:
+ return 3;
+ case 4:
+ return 4;
+ default:
+ return 5;
+ }
+
+ PrintAndLog("<<<< %s", sprint_hex(data, datalen));
+
+ PrintAndLog("APDU response: %02x %02x", data[datalen - 2], data[datalen - 1]); // TODO add APDU descriptions
+
+ // here TLV decoder...
+ if (decodeTLV) {
+ PrintAndLog("--- TLV decoded:");
+ }
+
+ return 0;
+}
+
+int CmdHF14ACmdRaw(const char *cmd) {
+ UsbCommand c = {CMD_READER_ISO_14443a, {0, 0, 0}};
+ bool reply=1;
+ bool crc = false;
+ 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;
+ bool topazmode = false;
+ char buf[5]="";
+ int i = 0;
+ uint8_t data[USB_CMD_DATA_SIZE];
+ uint16_t datalen = 0;
+ uint32_t temp;
+
+ if (strlen(cmd)<2) {
+ PrintAndLog("Usage: hf 14a raw [-r] [-c] [-p] [-f] [-b] [-t] <number of bits> <0A 0B 0C ... hex>");
+ PrintAndLog(" -r do not read response");
+ PrintAndLog(" -c calculate and append CRC");
+ PrintAndLog(" -p leave the signal field ON after receive");
+ PrintAndLog(" -a active signal field ON without select");
+ PrintAndLog(" -s active signal field ON with select");
+ 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;
+ }
+
+
+ // strip
+ while (*cmd==' ' || *cmd=='\t') cmd++;