+ PrintAndLog("<<<< %s", sprint_hex(data, datalen));
+
+ PrintAndLog("APDU response: %02x %02x - %s", data[datalen - 2], data[datalen - 1], GetAPDUCodeDescription(data[datalen - 2], data[datalen - 1]));
+
+ // TLV decoder
+ if (decodeTLV && datalen > 4) {
+ TLVPrintFromBuffer(data, datalen - 2);
+ }
+
+ 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;
+ uint8_t data[USB_CMD_DATA_SIZE];
+ int datalen = 0;
+
+ // extract parameters
+ CLIParserInit("hf 14a raw", "Send raw hex data to tag",
+ "Sample:\n"\
+ "\thf 14a raw -pa -b7 -t1000 52 -- execute WUPA\n"\
+ "\thf 14a raw -p 9320 -- anticollision\n"\
+ "\thf 14a raw -psc 60 00 -- select and mifare AUTH\n");
+ void* argtable[] = {
+ arg_param_begin,
+ arg_lit0("rR", "nreply", "do not read response"),
+ arg_lit0("cC", "crc", "calculate and append CRC"),
+ arg_lit0("pP", "power", "leave the signal field ON after receive"),
+ arg_lit0("aA", "active", "active signal field ON without select"),
+ arg_lit0("sS", "actives", "active signal field ON with select"),
+ arg_int0("bB", "bits", NULL, "number of bits to send. Useful for send partial byte"),
+ arg_int0("t", "timeout", NULL, "timeout in ms"),
+ arg_lit0("T", "topaz", "use Topaz protocol to send command"),
+ arg_lit0("3", NULL, "ISO14443-3 select only (skip RATS)"),
+ arg_strx1(NULL, NULL, "<data (hex)>", NULL),
+ arg_param_end
+ };
+ // defaults
+ arg_get_int(6) = 0;
+ arg_get_int(7) = 0;
+
+ if (CLIParserParseString(cmd, argtable, arg_getsize(argtable), false)){
+ CLIParserFree();
+ return 0;
+ }
+
+ reply = !arg_get_lit(1);
+ crc = arg_get_lit(2);
+ power = arg_get_lit(3);
+ active = arg_get_lit(4);
+ active_select = arg_get_lit(5);
+ numbits = arg_get_int(6) & 0xFFFF;
+ timeout = arg_get_int(7);
+ bTimeout = (timeout > 0);
+ topazmode = arg_get_lit(8);
+ no_rats = arg_get_lit(9);
+ // len = data + CRC(2b)
+ if (CLIParamHexToBuf(arg_get_str(10), data, sizeof(data) -2, &datalen)) {
+ CLIParserFree();
+ return 1;
+ }
+
+ CLIParserFree();
+
+ // logic
+ if(crc && datalen>0 && datalen<sizeof(data)-2)
+ {
+ uint8_t first, second;