+ if(flags & FLAG_INTERACTIVE)// Interactive mode flag, means we need to send ACK
+ {
+ //May just aswell send the collected ar_nr in the response aswell
+ uint8_t len = ar_nr_collected*5*4;
+ cmd_send(CMD_ACK, CMD_SIMULATE_MIFARE_CARD, len, 0, &ar_nr_responses, len);
+ }
+
+ if(flags & FLAG_NR_AR_ATTACK && MF_DBGLEVEL >= 1 )
+ {
+ if(ar_nr_collected > 1 ) {
+ Dbprintf("Collected two pairs of AR/NR which can be used to extract keys from reader:");
+ Dbprintf("../tools/mfkey/mfkey32 %06x%08x %08x %08x %08x %08x %08x",
+ ar_nr_responses[0], // UID1
+ ar_nr_responses[1], // UID2
+ ar_nr_responses[2], // NT
+ ar_nr_responses[3], // AR1
+ ar_nr_responses[4], // NR1
+ ar_nr_responses[8], // AR2
+ ar_nr_responses[9] // NR2
+ );
+ } else {
+ Dbprintf("Failed to obtain two AR/NR pairs!");
+ if(ar_nr_collected > 0 ) {
+ Dbprintf("Only got these: UID=%07x%08x, nonce=%08x, AR1=%08x, NR1=%08x",
+ ar_nr_responses[0], // UID1
+ ar_nr_responses[1], // UID2
+ ar_nr_responses[2], // NT
+ ar_nr_responses[3], // AR1
+ ar_nr_responses[4] // NR1
+ );
+ }
+ }
+ }
+ if (MF_DBGLEVEL >= 1) Dbprintf("Emulator stopped. Tracing: %d trace length: %d ", tracing, BigBuf_get_traceLen());
+}
+
+
+//-----------------------------------------------------------------------------
+// MIFARE sniffer.
+//
+//-----------------------------------------------------------------------------
+void RAMFUNC SniffMifare(uint8_t param) {
+ // param:
+ // bit 0 - trigger from first card answer
+ // bit 1 - trigger from first reader 7-bit request
+
+ // free eventually allocated BigBuf memory
+ BigBuf_free();
+
+ // C(red) A(yellow) B(green)
+ LEDsoff();
+ // init trace buffer
+ clear_trace();
+ set_tracing(TRUE);
+
+ // The command (reader -> tag) that we're receiving.
+ // The length of a received command will in most cases be no more than 18 bytes.
+ // So 32 should be enough!
+ uint8_t receivedCmd[MAX_MIFARE_FRAME_SIZE];
+ uint8_t receivedCmdPar[MAX_MIFARE_PARITY_SIZE];
+ // The response (tag -> reader) that we're receiving.
+ uint8_t receivedResponse[MAX_MIFARE_FRAME_SIZE];
+ uint8_t receivedResponsePar[MAX_MIFARE_PARITY_SIZE];
+
+ // allocate the DMA buffer, used to stream samples from the FPGA
+ uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
+ uint8_t *data = dmaBuf;
+ uint8_t previous_data = 0;
+ int maxDataLen = 0;
+ int dataLen = 0;
+ bool ReaderIsActive = FALSE;
+ bool TagIsActive = FALSE;
+
+ iso14443a_setup(FPGA_HF_ISO14443A_SNIFFER);
+
+ // Set up the demodulator for tag -> reader responses.
+ DemodInit(receivedResponse, receivedResponsePar);
+
+ // Set up the demodulator for the reader -> tag commands
+ UartInit(receivedCmd, receivedCmdPar);
+
+ // Setup for the DMA.
+ FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE); // set transfer address and number of bytes. Start transfer.
+
+ LED_D_OFF();
+
+ // init sniffer
+ MfSniffInit();
+
+ // And now we loop, receiving samples.
+ for(uint32_t sniffCounter = 0; TRUE; ) {
+
+ if(BUTTON_PRESS()) {
+ DbpString("cancelled by button");
+ break;
+ }
+
+ LED_A_ON();
+ WDT_HIT();
+
+ if ((sniffCounter & 0x0000FFFF) == 0) { // from time to time
+ // check if a transaction is completed (timeout after 2000ms).
+ // if yes, stop the DMA transfer and send what we have so far to the client
+ if (MfSniffSend(2000)) {
+ // Reset everything - we missed some sniffed data anyway while the DMA was stopped
+ sniffCounter = 0;
+ data = dmaBuf;
+ maxDataLen = 0;
+ ReaderIsActive = FALSE;
+ TagIsActive = FALSE;
+ FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE); // set transfer address and number of bytes. Start transfer.
+ }
+ }
+
+ int register readBufDataP = data - dmaBuf; // number of bytes we have processed so far
+ int register dmaBufDataP = DMA_BUFFER_SIZE - AT91C_BASE_PDC_SSC->PDC_RCR; // number of bytes already transferred
+ if (readBufDataP <= dmaBufDataP){ // we are processing the same block of data which is currently being transferred
+ dataLen = dmaBufDataP - readBufDataP; // number of bytes still to be processed
+ } else {
+ dataLen = DMA_BUFFER_SIZE - readBufDataP + dmaBufDataP; // number of bytes still to be processed
+ }
+ // test for length of buffer
+ if(dataLen > maxDataLen) { // we are more behind than ever...
+ maxDataLen = dataLen;
+ if(dataLen > (9 * DMA_BUFFER_SIZE / 10)) {
+ Dbprintf("blew circular buffer! dataLen=0x%x", dataLen);
+ break;
+ }
+ }
+ if(dataLen < 1) continue;
+
+ // primary buffer was stopped ( <-- we lost data!
+ if (!AT91C_BASE_PDC_SSC->PDC_RCR) {
+ AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dmaBuf;
+ AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE;
+ Dbprintf("RxEmpty ERROR!!! data length:%d", dataLen); // temporary
+ }
+ // secondary buffer sets as primary, secondary buffer was stopped
+ if (!AT91C_BASE_PDC_SSC->PDC_RNCR) {
+ AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf;
+ AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
+ }
+
+ LED_A_OFF();
+
+ if (sniffCounter & 0x01) {
+
+ if(!TagIsActive) { // no need to try decoding tag data if the reader is sending
+ uint8_t readerdata = (previous_data & 0xF0) | (*data >> 4);
+ if(MillerDecoding(readerdata, (sniffCounter-1)*4)) {
+ LED_C_INV();
+ if (MfSniffLogic(receivedCmd, Uart.len, Uart.parity, Uart.bitCount, TRUE)) break;
+
+ /* And ready to receive another command. */
+ //UartInit(receivedCmd, receivedCmdPar);
+ UartReset();
+
+ /* And also reset the demod code */
+ DemodReset();
+ }
+ ReaderIsActive = (Uart.state != STATE_UNSYNCD);
+ }
+
+ if(!ReaderIsActive) { // no need to try decoding tag data if the reader is sending
+ uint8_t tagdata = (previous_data << 4) | (*data & 0x0F);
+ if(ManchesterDecoding(tagdata, 0, (sniffCounter-1)*4)) {
+ LED_C_INV();
+
+ if (MfSniffLogic(receivedResponse, Demod.len, Demod.parity, Demod.bitCount, FALSE)) break;
+
+ // And ready to receive another response.
+ DemodReset();
+
+ // And reset the Miller decoder including its (now outdated) input buffer
+ UartInit(receivedCmd, receivedCmdPar);
+ }
+ TagIsActive = (Demod.state != DEMOD_UNSYNCD);
+ }
+ }
+
+ previous_data = *data;
+ sniffCounter++;
+ data++;
+ if(data == dmaBuf + DMA_BUFFER_SIZE) {
+ data = dmaBuf;
+ }