]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
Merge branch 'master' into topaz. Update Changelog. 142/head
authorpwpiwi <pwpiwi@users.noreply.github.com>
Tue, 27 Oct 2015 19:44:48 +0000 (20:44 +0100)
committerpwpiwi <pwpiwi@users.noreply.github.com>
Tue, 27 Oct 2015 19:57:16 +0000 (20:57 +0100)
1  2 
CHANGELOG.md
armsrc/iso14443a.c

diff --combined CHANGELOG.md
index e2196a39afb8ed1c1d54fdf2311d4bb813cae4db,e2196a39afb8ed1c1d54fdf2311d4bb813cae4db..33824bbb32a0969602c3e2e01af386c53c179f3b
@@@ -10,6 -10,6 +10,9 @@@ This project uses the changelog in acco
  - Added 'hw status'. This command makes the ARM print out some runtime information. (holiman) 
  - Added 'hw ping'. This command just sends a usb packets and checks if the pm3 is responsive. Can be used to abort certain operations which supports abort over usb. (holiman)
  - Added `data hex2bin` and `data bin2hex` for command line conversion between binary and hexadecimal (holiman)
++- Added Topaz (NFC type 1) protocol support ('hf topaz reader', 'hf list topaz', 'hf 14a raw -T', 'hf topaz snoop'). (piwi)
++- Added option c to 'hf list' (mark CRC bytes) (piwi)
++
  
  ### Changed
  - Revised workflow for StandAloneMode14a (Craig Young)
diff --combined armsrc/iso14443a.c
index 9fa9fe4ff61d8724036feeebeaa182a98b84a341,bb7ab015e65da6d3ba1770f33a607db9311891cb..27574dad2601cceda2f59b785445a1915a958892
@@@ -213,12 -213,6 +213,12 @@@ void AppendCrc14443a(uint8_t* data, in
        ComputeCrc14443(CRC_14443_A,data,len,data+len,data+len+1);
  }
  
 +void AppendCrc14443b(uint8_t* data, int len)
 +{
 +      ComputeCrc14443(CRC_14443_B,data,len,data+len,data+len+1);
 +}
 +
 +
  //=============================================================================
  // ISO 14443 Type A - Miller decoder
  //=============================================================================
  static tUart Uart;
  
  // Lookup-Table to decide if 4 raw bits are a modulation.
 -// We accept two or three consecutive "0" in any position with the rest "1"
 +// We accept the following:
 +// 0001  -   a 3 tick wide pause
 +// 0011  -   a 2 tick wide pause, or a three tick wide pause shifted left
 +// 0111  -   a 2 tick wide pause shifted left
 +// 1001  -   a 2 tick wide pause shifted right
  const bool Mod_Miller_LUT[] = {
 -      TRUE,  TRUE,  FALSE, TRUE,  FALSE, FALSE, FALSE, FALSE,
 -      TRUE,  TRUE,  FALSE, FALSE, TRUE,  FALSE, FALSE, FALSE
 +      FALSE,  TRUE, FALSE, TRUE,  FALSE, FALSE, FALSE, TRUE,
 +      FALSE,  TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE
  };
 -#define IsMillerModulationNibble1(b) (Mod_Miller_LUT[(b & 0x00F0) >> 4])
 -#define IsMillerModulationNibble2(b) (Mod_Miller_LUT[(b & 0x000F)])
 +#define IsMillerModulationNibble1(b) (Mod_Miller_LUT[(b & 0x000000F0) >> 4])
 +#define IsMillerModulationNibble2(b) (Mod_Miller_LUT[(b & 0x0000000F)])
  
  void UartReset()
  {
        Uart.parityLen = 0;                                     // number of decoded parity bytes
        Uart.shiftReg = 0;                                      // shiftreg to hold decoded data bits
        Uart.parityBits = 0;                            // holds 8 parity bits
 -      Uart.twoBits = 0x0000;                          // buffer for 2 Bits
 -      Uart.highCnt = 0;
        Uart.startTime = 0;
        Uart.endTime = 0;
  }
@@@ -266,7 -258,6 +266,7 @@@ void UartInit(uint8_t *data, uint8_t *p
  {
        Uart.output = data;
        Uart.parity = parity;
 +      Uart.fourBits = 0x00000000;                     // clear the buffer for 4 Bits
        UartReset();
  }
  
  static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
  {
  
 -      Uart.twoBits = (Uart.twoBits << 8) | bit;
 +      Uart.fourBits = (Uart.fourBits << 8) | bit;
        
        if (Uart.state == STATE_UNSYNCD) {                                                                                      // not yet synced
        
 -              if (Uart.highCnt < 2) {                                                                                                 // wait for a stable unmodulated signal
 -                      if (Uart.twoBits == 0xffff) {
 -                              Uart.highCnt++;
 -                      } else {
 -                              Uart.highCnt = 0;
 -                      }
 -              } else {        
 -                      Uart.syncBit = 0xFFFF;                                                                                          // not set
 -                                                                                                                                                              // we look for a ...1111111100x11111xxxxxx pattern (the start bit)
 -                      if              ((Uart.twoBits & 0xDF00) == 0x1F00) Uart.syncBit = 8;           // mask is   11x11111 xxxxxxxx, 
 -                                                                                                                                                              // check for 00x11111 xxxxxxxx
 -                      else if ((Uart.twoBits & 0xEF80) == 0x8F80) Uart.syncBit = 7;           // both masks shifted right one bit, left padded with '1'
 -                      else if ((Uart.twoBits & 0xF7C0) == 0xC7C0) Uart.syncBit = 6;           // ...
 -                      else if ((Uart.twoBits & 0xFBE0) == 0xE3E0) Uart.syncBit = 5;
 -                      else if ((Uart.twoBits & 0xFDF0) == 0xF1F0) Uart.syncBit = 4;
 -                      else if ((Uart.twoBits & 0xFEF8) == 0xF8F8) Uart.syncBit = 3;
 -                      else if ((Uart.twoBits & 0xFF7C) == 0xFC7C) Uart.syncBit = 2;
 -                      else if ((Uart.twoBits & 0xFFBE) == 0xFE3E) Uart.syncBit = 1;
 -                      if (Uart.syncBit != 0xFFFF) {                                                                           // found a sync bit
 -                              Uart.startTime = non_real_time?non_real_time:(GetCountSspClk() & 0xfffffff8);
 -                              Uart.startTime -= Uart.syncBit;
 -                              Uart.endTime = Uart.startTime;
 -                              Uart.state = STATE_START_OF_COMMUNICATION;
 -                      }
 +              Uart.syncBit = 9999;                                                                                                    // not set
 +              // The start bit is one ore more Sequence Y followed by a Sequence Z (... 11111111 00x11111). We need to distinguish from
 +              // Sequence X followed by Sequence Y followed by Sequence Z (111100x1 11111111 00x11111)
 +              // we therefore look for a ...xx11111111111100x11111xxxxxx... pattern 
 +              // (12 '1's followed by 2 '0's, eventually followed by another '0', followed by 5 '1's)
 +              #define ISO14443A_STARTBIT_MASK         0x07FFEF80                                                      // mask is    00000111 11111111 11101111 10000000
 +              #define ISO14443A_STARTBIT_PATTERN      0x07FF8F80                                                      // pattern is 00000111 11111111 10001111 10000000
 +              if              ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 0)) == ISO14443A_STARTBIT_PATTERN >> 0) Uart.syncBit = 7;
 +              else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 1)) == ISO14443A_STARTBIT_PATTERN >> 1) Uart.syncBit = 6;
 +              else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 2)) == ISO14443A_STARTBIT_PATTERN >> 2) Uart.syncBit = 5;
 +              else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 3)) == ISO14443A_STARTBIT_PATTERN >> 3) Uart.syncBit = 4;
 +              else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 4)) == ISO14443A_STARTBIT_PATTERN >> 4) Uart.syncBit = 3;
 +              else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 5)) == ISO14443A_STARTBIT_PATTERN >> 5) Uart.syncBit = 2;
 +              else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 6)) == ISO14443A_STARTBIT_PATTERN >> 6) Uart.syncBit = 1;
 +              else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 7)) == ISO14443A_STARTBIT_PATTERN >> 7) Uart.syncBit = 0;
 +
 +              if (Uart.syncBit != 9999) {                                                                                             // found a sync bit
 +                      Uart.startTime = non_real_time?non_real_time:(GetCountSspClk() & 0xfffffff8);
 +                      Uart.startTime -= Uart.syncBit;
 +                      Uart.endTime = Uart.startTime;
 +                      Uart.state = STATE_START_OF_COMMUNICATION;
                }
  
        } else {
  
 -              if (IsMillerModulationNibble1(Uart.twoBits >> Uart.syncBit)) {                  
 -                      if (IsMillerModulationNibble2(Uart.twoBits >> Uart.syncBit)) {          // Modulation in both halves - error
 +              if (IsMillerModulationNibble1(Uart.fourBits >> Uart.syncBit)) {                 
 +                      if (IsMillerModulationNibble2(Uart.fourBits >> Uart.syncBit)) {         // Modulation in both halves - error
                                UartReset();
                        } else {                                                                                                                        // Modulation in first half = Sequence Z = logic "0"
                                if (Uart.state == STATE_MILLER_X) {                                                             // error - must not follow after X
                                }
                        }
                } else {
 -                      if (IsMillerModulationNibble2(Uart.twoBits >> Uart.syncBit)) {          // Modulation second half = Sequence X = logic "1"
 +                      if (IsMillerModulationNibble2(Uart.fourBits >> Uart.syncBit)) {         // Modulation second half = Sequence X = logic "1"
                                Uart.bitCount++;
                                Uart.shiftReg = (Uart.shiftReg >> 1) | 0x100;                                   // add a 1 to the shiftreg
                                Uart.state = STATE_MILLER_X;
                                                return TRUE;                                                                                    // we are finished with decoding the raw data sequence
                                        } else {
                                                UartReset();                                                                                    // Nothing received - start over
 -                                              Uart.highCnt = 1;
                                        }
                                }
                                if (Uart.state == STATE_START_OF_COMMUNICATION) {                               // error - must not follow directly after SOC
                                        UartReset();
 -                                      Uart.highCnt = 1;
                                } else {                                                                                                                // a logic "0"
                                        Uart.bitCount++;
                                        Uart.shiftReg = (Uart.shiftReg >> 1);                                           // add a 0 to the shiftreg
@@@ -684,9 -680,6 +684,9 @@@ void RAMFUNC SnoopIso14443a(uint8_t par
  
                                        // And ready to receive another response.
                                        DemodReset();
 +                                      // And reset the Miller decoder including itS (now outdated) input buffer
 +                                      UartInit(receivedCmd, receivedCmdPar);
 +
                                        LED_C_OFF();
                                } 
                                TagIsActive = (Demod.state != DEMOD_UNSYNCD);
@@@ -1343,7 -1336,7 +1343,7 @@@ void CodeIso14443aBitsAsReaderPar(cons
                }
  
                // Only transmit parity bit if we transmitted a complete byte
 -              if (j == 8) {
 +              if (j == 8 && parity != NULL) {
                        // Get the parity bit
                        if (parity[i>>3] & (0x80 >> (i&0x0007))) {
                                // Sequence X
@@@ -1637,7 -1630,6 +1637,7 @@@ static int GetIso14443aAnswerFromTag(ui
        }
  }
  
 +
  void ReaderTransmitBitsPar(uint8_t* frame, uint16_t bits, uint8_t *par, uint32_t *timing)
  {
        CodeIso14443aBitsAsReaderPar(frame, bits, par);
        }
  }
  
 +
  void ReaderTransmitPar(uint8_t* frame, uint16_t len, uint8_t *par, uint32_t *timing)
  {
    ReaderTransmitBitsPar(frame, len*8, par, timing);
  }
  
 +
  void ReaderTransmitBits(uint8_t* frame, uint16_t len, uint32_t *timing)
  {
    // Generate parity and redirect
    ReaderTransmitBitsPar(frame, len, par, timing);
  }
  
 +
  void ReaderTransmit(uint8_t* frame, uint16_t len, uint32_t *timing)
  {
    // Generate parity and redirect
@@@ -1729,11 -1718,6 +1729,11 @@@ int iso14443a_select_card(byte_t *uid_p
                memset(uid_ptr,0,10);
        }
  
 +      // check for proprietary anticollision:
 +      if ((resp[0] & 0x1F) == 0) {
 +              return 3;
 +      }
 +      
        // OK we will select at least at cascade 1, lets see if first byte of UID was 0x88 in
        // which case we need to make a cascade 2 request and select - this is a long UID
        // While the UID is not complete, the 3nd bit (from the right) is set in the SAK.
@@@ -1942,38 -1926,15 +1942,38 @@@ void ReaderIso14443a(UsbCommand *c
  
        if(param & ISO14A_RAW) {
                if(param & ISO14A_APPEND_CRC) {
 -                      AppendCrc14443a(cmd,len);
 +                      if(param & ISO14A_TOPAZMODE) {
 +                              AppendCrc14443b(cmd,len);
 +                      } else {
 +                              AppendCrc14443a(cmd,len);
 +                      }
                        len += 2;
                        if (lenbits) lenbits += 16;
                }
 -              if(lenbits>0) {
 -                      GetParity(cmd, lenbits/8, par);
 -                      ReaderTransmitBitsPar(cmd, lenbits, par, NULL);
 -              } else {
 -                      ReaderTransmit(cmd,len, NULL);
 +              if(lenbits>0) {                         // want to send a specific number of bits (e.g. short commands)
 +                      if(param & ISO14A_TOPAZMODE) {
 +                              int bits_to_send = lenbits;
 +                              uint16_t i = 0;
 +                              ReaderTransmitBitsPar(&cmd[i++], MIN(bits_to_send, 7), NULL, NULL);             // first byte is always short (7bits) and no parity
 +                              bits_to_send -= 7;
 +                              while (bits_to_send > 0) {
 +                                      ReaderTransmitBitsPar(&cmd[i++], MIN(bits_to_send, 8), NULL, NULL);     // following bytes are 8 bit and no parity
 +                                      bits_to_send -= 8;
 +                              }
 +                      } else {
 +                              GetParity(cmd, lenbits/8, par);
 +                              ReaderTransmitBitsPar(cmd, lenbits, par, NULL);                                                 // bytes are 8 bit with odd parity
 +                      }
 +              } else {                                        // want to send complete bytes only
 +                      if(param & ISO14A_TOPAZMODE) {
 +                              uint16_t i = 0;
 +                              ReaderTransmitBitsPar(&cmd[i++], 7, NULL, NULL);                                                // first byte: 7 bits, no paritiy
 +                              while (i < len) {
 +                                      ReaderTransmitBitsPar(&cmd[i++], 8, NULL, NULL);                                        // following bytes: 8 bits, no paritiy
 +                              }
 +                      } else {
 +                              ReaderTransmit(cmd,len, NULL);                                                                                  // 8 bits, odd parity
 +                      }
                }
                arg0 = ReaderReceive(buf, par);
                cmd_send(CMD_ACK,arg0,0,0,buf,sizeof(buf));
@@@ -2055,19 -2016,20 +2055,20 @@@ void ReaderMifare(bool first_try
        byte_t par_list[8] = {0x00};
        byte_t ks_list[8] = {0x00};
  
+       #define PRNG_SEQUENCE_LENGTH  (1 << 16);
        static uint32_t sync_time;
-       static uint32_t sync_cycles;
+       static int32_t sync_cycles;
        int catch_up_cycles = 0;
        int last_catch_up = 0;
+       uint16_t elapsed_prng_sequences;
        uint16_t consecutive_resyncs = 0;
        int isOK = 0;
  
        if (first_try) { 
                mf_nr_ar3 = 0;
                sync_time = GetCountSspClk() & 0xfffffff8;
-               sync_cycles = 65536;                                                                    // theory: Mifare Classic's random generator repeats every 2^16 cycles (and so do the nonces).
+               sync_cycles = PRNG_SEQUENCE_LENGTH;                                                     // theory: Mifare Classic's random generator repeats every 2^16 cycles (and so do the tag nonces).
                nt_attacked = 0;
-               nt = 0;
                par[0] = 0;
        }
        else {
        LED_C_OFF();
        
  
-       #define DARKSIDE_MAX_TRIES      32              // number of tries to sync on PRNG cycle. Then give up.
-       uint16_t unsuccessfull_tries = 0;
+       #define MAX_UNEXPECTED_RANDOM   4               // maximum number of unexpected (i.e. real) random numbers when trying to sync. Then give up.
+       #define MAX_SYNC_TRIES                  32
+       #define NUM_DEBUG_INFOS                 8               // per strategy
+       #define MAX_STRATEGY                    3
+       uint16_t unexpected_random = 0;
+       uint16_t sync_tries = 0;
+       int16_t debug_info_nr = -1;
+       uint16_t strategy = 0;
+       int32_t debug_info[MAX_STRATEGY][NUM_DEBUG_INFOS];
+       uint32_t select_time;
+       uint32_t halt_time;
        
        for(uint16_t i = 0; TRUE; i++) {
                
                        break;
                }
                
+               if (strategy == 2) {
+                       // test with additional hlt command
+                       halt_time = 0;
+                       int len = mifare_sendcmd_short(NULL, false, 0x50, 0x00, receivedAnswer, receivedAnswerPar, &halt_time);
+                       if (len && MF_DBGLEVEL >= 3) {
+                               Dbprintf("Unexpected response of %d bytes to hlt command (additional debugging).", len);
+                       }
+               }
+               if (strategy == 3) {
+                       // test with FPGA power off/on
+                       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+                       SpinDelay(200);
+                       iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
+                       SpinDelay(100);
+               }
+               
                if(!iso14443a_select_card(uid, NULL, &cuid)) {
                        if (MF_DBGLEVEL >= 1)   Dbprintf("Mifare: Can't select card");
                        continue;
                }
+               select_time = GetCountSspClk();
  
-               sync_time = (sync_time & 0xfffffff8) + sync_cycles + catch_up_cycles;
-               catch_up_cycles = 0;
+               elapsed_prng_sequences = 1;
+               if (debug_info_nr == -1) {
+                       sync_time = (sync_time & 0xfffffff8) + sync_cycles + catch_up_cycles;
+                       catch_up_cycles = 0;
  
-               // if we missed the sync time already, advance to the next nonce repeat
-               while(GetCountSspClk() > sync_time) {
-                       sync_time = (sync_time & 0xfffffff8) + sync_cycles;
-               }
+                       // if we missed the sync time already, advance to the next nonce repeat
+                       while(GetCountSspClk() > sync_time) {
+                               elapsed_prng_sequences++;
+                               sync_time = (sync_time & 0xfffffff8) + sync_cycles;
+                       }
  
-               // Transmit MIFARE_CLASSIC_AUTH at synctime. Should result in returning the same tag nonce (== nt_attacked) 
-               ReaderTransmit(mf_auth, sizeof(mf_auth), &sync_time);
+                       // Transmit MIFARE_CLASSIC_AUTH at synctime. Should result in returning the same tag nonce (== nt_attacked) 
+                       ReaderTransmit(mf_auth, sizeof(mf_auth), &sync_time);
+               } else {
+                       // collect some information on tag nonces for debugging:
+                       #define DEBUG_FIXED_SYNC_CYCLES PRNG_SEQUENCE_LENGTH
+                       if (strategy == 0) {
+                               // nonce distances at fixed time after card select:
+                               sync_time = select_time + DEBUG_FIXED_SYNC_CYCLES;
+                       } else if (strategy == 1) {
+                               // nonce distances at fixed time between authentications:
+                               sync_time = sync_time + DEBUG_FIXED_SYNC_CYCLES;
+                       } else if (strategy == 2) {
+                               // nonce distances at fixed time after halt:
+                               sync_time = halt_time + DEBUG_FIXED_SYNC_CYCLES;
+                       } else {
+                               // nonce_distances at fixed time after power on
+                               sync_time = DEBUG_FIXED_SYNC_CYCLES;
+                       }
+                       ReaderTransmit(mf_auth, sizeof(mf_auth), &sync_time);
+               }                       
  
                // Receive the (4 Byte) "random" nonce
                if (!ReaderReceive(receivedAnswer, receivedAnswerPar)) {
                        int nt_distance = dist_nt(previous_nt, nt);
                        if (nt_distance == 0) {
                                nt_attacked = nt;
-                       }
-                       else {
+                       } else {
                                if (nt_distance == -99999) { // invalid nonce received
-                                       unsuccessfull_tries++;
-                                       if (!nt_attacked && unsuccessfull_tries > DARKSIDE_MAX_TRIES) {
+                                       unexpected_random++;
+                                       if (unexpected_random > MAX_UNEXPECTED_RANDOM) {
                                                isOK = -3;              // Card has an unpredictable PRNG. Give up      
                                                break;
                                        } else {
                                                continue;               // continue trying...
                                        }
                                }
-                               sync_cycles = (sync_cycles - nt_distance);
-                               if (MF_DBGLEVEL >= 3) Dbprintf("calibrating in cycle %d. nt_distance=%d, Sync_cycles: %d\n", i, nt_distance, sync_cycles);
+                               if (++sync_tries > MAX_SYNC_TRIES) {
+                                       if (strategy > MAX_STRATEGY || MF_DBGLEVEL < 3) {
+                                               isOK = -4;                      // Card's PRNG runs at an unexpected frequency or resets unexpectedly
+                                               break;
+                                       } else {                                // continue for a while, just to collect some debug info
+                                               debug_info[strategy][debug_info_nr] = nt_distance;
+                                               debug_info_nr++;
+                                               if (debug_info_nr == NUM_DEBUG_INFOS) {
+                                                       strategy++;
+                                                       debug_info_nr = 0;
+                                               }
+                                               continue;
+                                       }
+                               }
+                               sync_cycles = (sync_cycles - nt_distance/elapsed_prng_sequences);
+                               if (sync_cycles <= 0) {
+                                       sync_cycles += PRNG_SEQUENCE_LENGTH;
+                               }
+                               if (MF_DBGLEVEL >= 3) {
+                                       Dbprintf("calibrating in cycle %d. nt_distance=%d, elapsed_prng_sequences=%d, new sync_cycles: %d\n", i, nt_distance, elapsed_prng_sequences, sync_cycles);
+                               }
                                continue;
                        }
                }
                                catch_up_cycles = 0;
                                continue;
                        }
+                       catch_up_cycles /= elapsed_prng_sequences;
                        if (catch_up_cycles == last_catch_up) {
                                consecutive_resyncs++;
                        }
                        else {  
                                sync_cycles = sync_cycles + catch_up_cycles;
                                if (MF_DBGLEVEL >= 3) Dbprintf("Lost sync in cycle %d for the fourth time consecutively (nt_distance = %d). Adjusting sync_cycles to %d.\n", i, -catch_up_cycles, sync_cycles);
+                               last_catch_up = 0;
+                               catch_up_cycles = 0;
+                               consecutive_resyncs = 0;
                        }
                        continue;
                }
                consecutive_resyncs = 0;
                
                // Receive answer. This will be a 4 Bit NACK when the 8 parity bits are OK after decoding
-               if (ReaderReceive(receivedAnswer, receivedAnswerPar))
-               {
+               if (ReaderReceive(receivedAnswer, receivedAnswerPar)) {
                        catch_up_cycles = 8;    // the PRNG is delayed by 8 cycles due to the NAC (4Bits = 0x05 encrypted) transfer
        
-                       if (nt_diff == 0)
-                       {
+                       if (nt_diff == 0) {
                                par_low = par[0] & 0xE0; // there is no need to check all parities for other nt_diff. Parity Bits for mf_nr_ar[0..2] won't change
                        }
  
  
  
        mf_nr_ar[3] &= 0x1F;
+       if (isOK == -4) {
+               if (MF_DBGLEVEL >= 3) {
+                       for (uint16_t i = 0; i <= MAX_STRATEGY; i++) {
+                               for(uint16_t j = 0; j < NUM_DEBUG_INFOS; j++) {
+                                       Dbprintf("collected debug info[%d][%d] = %d", i, j, debug_info[i][j]);
+                               }
+                       }
+               }
+       }
        
        byte_t buf[28];
        memcpy(buf + 0,  uid, 4);
@@@ -2853,7 -2893,7 +2932,7 @@@ void RAMFUNC SniffMifare(uint8_t param
                                        if (MfSniffLogic(receivedCmd, Uart.len, Uart.parity, Uart.bitCount, TRUE)) break;
  
                                        /* And ready to receive another command. */
 -                                      UartReset();
 +                                      UartInit(receivedCmd, receivedCmdPar);
                                        
                                        /* And also reset the demod code */
                                        DemodReset();
  
                                        // 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);
                        }
Impressum, Datenschutz