+\r
+static bool isBlockTrailer(int blockN) {\r
+ if (blockN >= 0 && blockN < 128) {\r
+ return ((blockN & 0x03) == 0x03);\r
+ }\r
+ if (blockN >= 128 && blockN <= 256) {\r
+ return ((blockN & 0x0F) == 0x0F);\r
+ }\r
+ return false;\r
+}\r
+\r
+void MifareCWipe(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
+ // var\r
+ byte_t isOK = 0;\r
+ uint32_t numBlocks = arg0;\r
+ // cmdParams:\r
+ // bit 0 - wipe gen1a\r
+ // bit 1 - fill card with default data\r
+ // bit 2 - gen1a = 0, gen1b = 1\r
+ uint8_t cmdParams = arg1;\r
+ bool needWipe = cmdParams & 0x01;\r
+ bool needFill = cmdParams & 0x02;\r
+ bool gen1b = cmdParams & 0x04;\r
+\r
+ uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
+ uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
+\r
+ uint8_t block0[16] = {0x01, 0x02, 0x03, 0x04, 0x04, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xAF};\r
+ uint8_t block1[16] = {0x00};\r
+ uint8_t blockK[16] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x08, 0x77, 0x8F, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};\r
+ uint8_t d_block[18] = {0x00};\r
+\r
+ // card commands\r
+ uint8_t wupC1[] = { 0x40 };\r
+ uint8_t wupC2[] = { 0x43 };\r
+ uint8_t wipeC[] = { 0x41 };\r
+\r
+ // iso14443 setup\r
+ LED_A_ON();\r
+ LED_B_OFF();\r
+ LED_C_OFF();\r
+ iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
+\r
+ // tracing\r
+ clear_trace();\r
+ set_tracing(true);\r
+\r
+ while (true){\r
+ // wipe\r
+ if (needWipe){\r
+ ReaderTransmitBitsPar(wupC1,7,0, NULL);\r
+ if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != CARD_ACK)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");\r
+ break;\r
+ };\r
+\r
+ ReaderTransmit(wipeC, sizeof(wipeC), NULL);\r
+ if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != CARD_ACK)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("wipeC error");\r
+ break;\r
+ };\r
+\r
+ if(mifare_classic_halt(NULL, 0)) {\r
+ if (MF_DBGLEVEL > 2) Dbprintf("Halt error");\r
+ };\r
+ };\r
+\r
+ // put default data\r
+ if (needFill){\r
+ // select commands\r
+ ReaderTransmitBitsPar(wupC1, 7, 0, NULL);\r
+\r
+ // gen1b magic tag : do no issue wupC2 and don't expect CARD_ACK response after SELECT_UID (after getting UID from chip in 'hf mf csetuid' command)\r
+ if (!gen1b) {\r
+\r
+ if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != CARD_ACK)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");\r
+ break;\r
+ };\r
+\r
+ ReaderTransmit(wupC2, sizeof(wupC2), NULL);\r
+ if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != CARD_ACK)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("wupC2 error");\r
+ break;\r
+ };\r
+ }\r
+\r
+ // send blocks command\r
+ for (int blockNo = 0; blockNo < numBlocks; blockNo++) {\r
+ if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != CARD_ACK)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("write block send command error");\r
+ break;\r
+ };\r
+\r
+ // check type of block and add crc\r
+ if (!isBlockTrailer(blockNo)){\r
+ memcpy(d_block, block1, 16);\r
+ } else {\r
+ memcpy(d_block, blockK, 16);\r
+ }\r
+ if (blockNo == 0) {\r
+ memcpy(d_block, block0, 16);\r
+ }\r
+ AppendCrc14443a(d_block, 16);\r
+\r
+ // send write command\r
+ ReaderTransmit(d_block, sizeof(d_block), NULL);\r
+ if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != CARD_ACK)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("write block send data error");\r
+ break;\r
+ };\r
+ }\r
+\r
+ // halt\r
+ // do no issue halt command for gen1b\r
+ if (!gen1b) {\r
+ if (mifare_classic_halt(NULL, 0)) {\r
+ if (MF_DBGLEVEL > 2) Dbprintf("Halt error");\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ break;\r
+ }\r
+\r
+ // send USB response\r
+ LED_B_ON();\r
+ cmd_send(CMD_ACK,isOK,0,0,NULL,0);\r
+ LED_B_OFF();\r
+\r
+ // reset fpga\r
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+ LEDsoff();\r
+\r
+ return;\r
+}\r
+\r