]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
Merge branch 'master' of https://github.com/Proxmark/proxmark3
authoriceman1001 <iceman@iuse.se>
Tue, 10 Feb 2015 20:53:16 +0000 (21:53 +0100)
committericeman1001 <iceman@iuse.se>
Tue, 10 Feb 2015 20:53:16 +0000 (21:53 +0100)
Conflicts:
armsrc/appmain.c
armsrc/iclass.c

1  2 
armsrc/appmain.c
armsrc/apps.h
armsrc/hitag2.c
armsrc/iclass.c
armsrc/iso14443.c
armsrc/iso14443a.h
armsrc/util.c
client/cmdlft55xx.c
client/ui.c

diff --combined armsrc/appmain.c
index 31e17e880a5c12eed13aaa5d2d569090ba360654,43f1df0203151d94c0c6864819e479b9459ef4a3..f19840b8e13edfd9b6df80ceaa06cff2023b803d
  // executes.
  //-----------------------------------------------------------------------------
  
 -#include "usb_cdc.h"
 -#include "cmd.h"
 +#include "../common/usb_cdc.h"
 +#include "../common/cmd.h"
  
 -#include "proxmark3.h"
 +#include "../include/proxmark3.h"
  #include "apps.h"
  #include "util.h"
  #include "printf.h"
  #include "string.h"
 -
  #include <stdarg.h>
  
  #include "legicrf.h"
 -#include <hitag2.h>
 +#include "../include/hitag2.h"
  #include "lfsampling.h"
+ #include "BigBuf.h"
  #ifdef WITH_LCD
   #include "LCD.h"
  #endif
@@@ -179,7 -180,7 +179,7 @@@ void MeasureAntennaTuning(void
        int i, adcval = 0, peak = 0, peakv = 0, peakf = 0; //ptr = 0 
        int vLf125 = 0, vLf134 = 0, vHf = 0;    // in mV
  
 -      LED_B_ON();
 +  LED_B_ON();
  
  /*
   * Sweeps the useful LF range of the proxmark from
  
        for (i=18; i >= 0; i--) LF_Results[i] = 0;
        
 -      LED_A_ON();
 +  LED_A_ON();
        // Let the FPGA drive the high-frequency antenna around 13.56 MHz.
        FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
        FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
  
        cmd_send(CMD_MEASURED_ANTENNA_TUNING, vLf125 | (vLf134<<16), vHf, peakf | (peakv<<16), LF_Results, 256);
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
 -      LED_A_OFF();
 -      LED_B_OFF();
 -      return;
 +  LED_A_OFF();
 +  LED_B_OFF();
 +  return;
  }
  
  void MeasureAntennaTuningHf(void)
@@@ -369,7 -370,7 +369,7 @@@ void SamyRun(
        for (;;)
        {
                usb_poll();
 -    WDT_HIT();
 +              WDT_HIT();
  
                // Was our button held down or pressed?
                int button_pressed = BUTTON_HELD(1000);
@@@ -639,7 -640,7 +639,7 @@@ void UsbPacketReceived(uint8_t *packet
  {
        UsbCommand *c = (UsbCommand *)packet;
  
 -//  Dbprintf("received %d bytes, with command: 0x%04x and args: %d %d %d",len,c->cmd,c->arg[0],c->arg[1],c->arg[2]);
 +  //Dbprintf("received %d bytes, with command: 0x%04x and args: %d %d %d",len,c->cmd,c->arg[0],c->arg[1],c->arg[2]);
    
        switch(c->cmd) {
  #ifdef WITH_LF
                        WriteTItag(c->arg[0],c->arg[1],c->arg[2]);
                        break;
                case CMD_SIMULATE_TAG_125K:
 -                      LED_A_ON();
 -                      SimulateTagLowFrequency(c->arg[0], c->arg[1], 1);
 -                      LED_A_OFF();
 +                      SimulateTagLowFrequency(c->arg[0], c->arg[1], 0);
 +                      //SimulateTagLowFrequencyA(c->arg[0], c->arg[1]);
                        break;
                case CMD_LF_SIMULATE_BIDIR:
                        SimulateTagLowFrequencyBidir(c->arg[0], c->arg[1]);
                        EPA_PACE_Collect_Nonce(c);
                        break;
                        
 +              // case CMD_EPA_:
 +              //      EpaFoo(c);
 +              // break;
 +                      
                case CMD_READER_MIFARE:
              ReaderMifare(c->arg[0]);
                        break;
                        break;
                case CMD_MIFAREU_READCARD:
                        MifareUReadCard(c->arg[0], c->arg[1], c->d.asBytes);
 -                      break;
 +                        break;
                case CMD_MIFAREUC_READCARD:
                        MifareUReadCard(c->arg[0], c->arg[1], c->d.asBytes);
                        break;
                        ReaderIClass(c->arg[0]);
                        break;
                case CMD_READER_ICLASS_REPLAY:
 -                  ReaderIClass_Replay(c->arg[0], c->d.asBytes);
 +                      ReaderIClass_Replay(c->arg[0], c->d.asBytes);
                        break;
  #endif
  
                        uint8_t *BigBuf = BigBuf_get_addr();
                        for(size_t i=0; i<c->arg[1]; i += USB_CMD_DATA_SIZE) {
                                size_t len = MIN((c->arg[1] - i),USB_CMD_DATA_SIZE);
-                               cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,i,len,traceLen,BigBuf+c->arg[0]+i,len);
+                               cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,i,len,BigBuf_get_traceLen(),BigBuf+c->arg[0]+i,len);
                        }
                        // Trigger a finish downloading signal with an ACK frame
-                       cmd_send(CMD_ACK,1,0,traceLen,getSamplingConfig(),sizeof(sample_config));
+                       cmd_send(CMD_ACK,1,0,BigBuf_get_traceLen(),getSamplingConfig(),sizeof(sample_config));
                        LED_B_OFF();
                        break;
  
  void  __attribute__((noreturn)) AppMain(void)
  {
        SpinDelay(100);
+       clear_trace();
        if(common_area.magic != COMMON_AREA_MAGIC || common_area.version != 1) {
                /* Initialize common area */
                memset(&common_area, 0, sizeof(common_area));
        LED_A_OFF();
  
        // Init USB device
 -  usb_enable();
 +      usb_enable();
  
        // The FPGA gets its clock from us from PCK0 output, so set that up.
        AT91C_BASE_PIOA->PIO_BSR = GPIO_PCK0;
        size_t rx_len;
    
        for(;;) {
 -    if (usb_poll()) {
 -      rx_len = usb_read(rx,sizeof(UsbCommand));
 -      if (rx_len) {
 -        UsbPacketReceived(rx,rx_len);
 -      }
 -    }
 +              if (usb_poll()) {
 +                      rx_len = usb_read(rx,sizeof(UsbCommand));
 +                      if (rx_len) {
 +                              UsbPacketReceived(rx,rx_len);
 +                      }
 +              }
                WDT_HIT();
  
  #ifdef WITH_LF
diff --combined armsrc/apps.h
index 22ec97b86843feeabb0df7baf45d5e401e197756,a506f4150889d3163a214e43e0aff98e80a56791..dc8a9c935f29a569f34de3877e010e7fdcba19ef
  
  #include <stdint.h>
  #include <stddef.h>
 -#include "common.h"
 -#include "hitag2.h"
 -#include "mifare.h"
 +#include <stdlib.h>
 +#include <sys/types.h>
 +#include <string.h>
 +#include <strings.h>
  #include "../common/crc32.h"
  #include "BigBuf.h"
 +#include "../include/hitag2.h"
  
  extern const uint8_t OddByteParity[256];
  extern int rsamples;   // = 0;
@@@ -118,9 -116,7 +118,9 @@@ void ReadTItag(void)
  void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc);
  void AcquireTiType(void);
  void AcquireRawBitsTI(void);
 -void SimulateTagLowFrequency(int period, int gap, int ledcontrol);
 +void SimulateTagLowFrequency( uint16_t period, uint32_t gap, uint8_t ledcontrol);
 +//void SimulateTagLowFrequencyA(int period, int gap);
 +
  void CmdHIDsimTAG(int hi, int lo, int ledcontrol);
  void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol);
  void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol);
@@@ -134,7 -130,6 +134,7 @@@ void CopyIndala224toT55x7(int uid1, in
  void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode);
  void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode );
  void T55xxReadTrace(void);
 +void TurnReadLFOn();
  int DemodPCF7931(uint8_t **outBlocks);
  int IsBlock0PCF7931(uint8_t *Block);
  int IsBlock1PCF7931(uint8_t *Block);
@@@ -157,8 -152,7 +157,7 @@@ void ReaderIso14443a(UsbCommand * c)
  bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t len, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag);
  void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *parity);
  void iso14a_set_trigger(bool enable);
- void iso14a_clear_trace();
- void iso14a_set_tracing(bool enable);
  void RAMFUNC SniffMifare(uint8_t param);
  
  /// epa.h
diff --combined armsrc/hitag2.c
index f9005c7176bcfe412526dca28e5a9bc221b89598,4b173d6f223845620eeb47e96e35c89ffb78f628..2d0645658c2dc2d2b68cf35f8f295308cf364925
  // (c) 2012 Roel Verdult
  //-----------------------------------------------------------------------------
  
 -#include "proxmark3.h"
 +#include "../include/proxmark3.h"
  #include "apps.h"
  #include "util.h"
 -#include "hitag2.h"
 +#include "../include/hitag2.h"
  #include "string.h"
+ #include "BigBuf.h"
  
  static bool bQuiet;
  
@@@ -30,32 -31,6 +31,6 @@@ static bool bPwd
  static bool bSuccessful;
  
  
- static int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int bReader)
- {
-   static uint16_t traceLen = 0;
-   uint8_t *trace = BigBuf_get_addr();
-   // Return when trace is full
-   if (traceLen + sizeof(rsamples) + sizeof(dwParity) + sizeof(iBits) + nbytes(iBits) > BigBuf_max_traceLen()) return FALSE;
-   
-   // Trace the random, i'm curious
-   rsamples += iSamples;
-   trace[traceLen++] = ((rsamples >> 0) & 0xff);
-   trace[traceLen++] = ((rsamples >> 8) & 0xff);
-   trace[traceLen++] = ((rsamples >> 16) & 0xff);
-   trace[traceLen++] = ((rsamples >> 24) & 0xff);
-   if (!bReader) {
-     trace[traceLen - 1] |= 0x80;
-   }
-   trace[traceLen++] = ((dwParity >> 0) & 0xff);
-   trace[traceLen++] = ((dwParity >> 8) & 0xff);
-   trace[traceLen++] = ((dwParity >> 16) & 0xff);
-   trace[traceLen++] = ((dwParity >> 24) & 0xff);
-   trace[traceLen++] = iBits;
-   memcpy(trace + traceLen, btBytes, nbytes(iBits));
-   traceLen += nbytes(iBits);
-   return TRUE;
- }
  
  struct hitag2_tag {
        uint32_t uid;
@@@ -742,8 -717,8 +717,8 @@@ void SnoopHitag(uint32_t type) 
        memset(auth_table, 0x00, AUTH_TABLE_LENGTH);
  
        // Clean up trace and prepare it for storing frames
-       iso14a_set_tracing(TRUE);
-       iso14a_clear_trace();
+       set_tracing(TRUE);
+       clear_trace();
        
        DbpString("Starting Hitag2 snoop");
        LED_D_ON();
@@@ -955,8 -930,8 +930,8 @@@ void SimulateHitagTag(bool tag_mem_supp
        memset(auth_table, 0x00, AUTH_TABLE_LENGTH);
  
        // Clean up trace and prepare it for storing frames
-       iso14a_set_tracing(TRUE);
-       iso14a_clear_trace();
+       set_tracing(TRUE);
+       clear_trace();
  
        DbpString("Starting Hitag2 simulation");
        LED_D_ON();
        AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1);
        AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME;
        
 -  // Disable timer during configuration       
 +    // Disable timer during configuration     
        AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
  
        // Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger,
@@@ -1142,8 -1117,8 +1117,8 @@@ void ReaderHitag(hitag_function htf, hi
        bSuccessful = false;
    
        // Clean up trace and prepare it for storing frames
-       iso14a_set_tracing(TRUE);
-       iso14a_clear_trace();
+       set_tracing(TRUE);
+       clear_trace();
  
        DbpString("Starting Hitag reader family");
  
diff --combined armsrc/iclass.c
index c0edc1e08db6156c57060a94961efcf93f8d69d6,41c9b8b51e6b700771e17ff1bd31de5c077e3c4d..67130804910a13428772e31189182d3874d1c7af
@@@ -36,7 -36,7 +36,7 @@@
  //
  //-----------------------------------------------------------------------------
  
 -#include "proxmark3.h"
 +#include "../include/proxmark3.h"
  #include "apps.h"
  #include "util.h"
  #include "string.h"
  // Needed for CRC in emulation mode;
  // same construction as in ISO 14443;
  // different initial value (CRC_ICLASS)
 -#include "iso14443crc.h"
 -#include "iso15693tools.h"
 +#include "../common/iso14443crc.h"
 +#include "../common/iso15693tools.h"
 +//#include "iso15693tools.h"
 +
  
  static int timeout = 4096;
  
@@@ -353,7 -351,7 +353,7 @@@ static struct 
                SUB_SECOND_HALF,
                SUB_BOTH
        }               sub;
 -    uint8_t *output;
 +    uint8_t   *output;
  } Demod;
  
  static RAMFUNC int ManchesterDecoding(int v)
@@@ -654,12 -652,11 +654,11 @@@ void RAMFUNC SnoopIClass(void
      // The DMA buffer, used to stream samples from the FPGA
      uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
   
-     // reset traceLen to 0
-     iso14a_set_tracing(TRUE);
-     iso14a_clear_trace();
+       set_tracing(TRUE);
+       clear_trace();
      iso14a_set_trigger(FALSE);
  
 -      int lastRxCounter;
 +    int lastRxCounter;
      uint8_t *upTo;
      int smpl;
      int maxBehindBy = 0;
                if(ManchesterDecoding(smpl & 0x0F)) {
                        time_stop = (GetCountSspClk()-time_0) << 4;
  
 -                      rsamples = samples - Demod.samples;
 +                  rsamples = samples - Demod.samples;
                    LED_B_ON();
  
                        if(tracing)     {
      DbpString("COMMAND FINISHED");
  
      Dbprintf("%x %x %x", maxBehindBy, Uart.state, Uart.byteCnt);
-     Dbprintf("%x %x %x", Uart.byteCntMax, traceLen, (int)Uart.output[0]);
+       Dbprintf("%x %x %x", Uart.byteCntMax, BigBuf_get_traceLen(), (int)Uart.output[0]);
  
  done:
      AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
      Dbprintf("%x %x %x", maxBehindBy, Uart.state, Uart.byteCnt);
-     Dbprintf("%x %x %x", Uart.byteCntMax, traceLen, (int)Uart.output[0]);
+       Dbprintf("%x %x %x", Uart.byteCntMax, BigBuf_get_traceLen(), (int)Uart.output[0]);
      LED_A_OFF();
      LED_B_OFF();
      LED_C_OFF();
@@@ -945,7 -942,7 +944,7 @@@ static void CodeIClassTagAnswer(const u
                uint8_t b = cmd[i];
                ToSend[++ToSendMax] = encode4Bits(b & 0xF); //Least significant half
                ToSend[++ToSendMax] = encode4Bits((b >>4) & 0xF);//Most significant half
 -      }
 +                      }
  
        // Send EOF
        ToSend[++ToSendMax] = 0xB8;
@@@ -989,8 -986,8 +988,8 @@@ void SimulateIClass(uint32_t arg0, uint
        FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
  
        // Enable and clear the trace
-       iso14a_set_tracing(TRUE);
-       iso14a_clear_trace();
+       set_tracing(TRUE);
+       clear_trace();
  
        uint8_t csn_crc[] = { 0x03, 0x1f, 0xec, 0x8a, 0xf7, 0xff, 0x12, 0xe0, 0x00, 0x00 };
        if(simType == 0) {
@@@ -1312,17 -1309,17 +1311,17 @@@ static void TransmitIClassCommand(cons
     {
       if(*wait < 10) *wait = 10;
       
 -     for(c = 0; c < *wait;) {
 -       if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
 -         AT91C_BASE_SSC->SSC_THR = 0x00;              // For exact timing!
 -         c++;
 -       }
 -       if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
 -         volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR;
 -         (void)r;
 -       }
 -       WDT_HIT();
 -     }
 +  for(c = 0; c < *wait;) {
 +    if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
 +      AT91C_BASE_SSC->SSC_THR = 0x00;         // For exact timing!
 +      c++;
 +    }
 +    if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
 +      volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR;
 +      (void)r;
 +    }
 +    WDT_HIT();
 +  }
  
     }
  
@@@ -1405,18 -1402,18 +1404,18 @@@ void CodeIClassCommand(const uint8_t * 
  
  void ReaderTransmitIClass(uint8_t* frame, int len)
  {
 -      int wait = 0;
 -      int samples = 0;
 +  int wait = 0;
 +  int samples = 0;
  
 -      // This is tied to other size changes
 -      CodeIClassCommand(frame,len);
 +  // This is tied to other size changes
 +  CodeIClassCommand(frame,len);
  
 -      // Select the card
 -      TransmitIClassCommand(ToSend, ToSendMax, &samples, &wait);
 -      if(trigger)
 -              LED_A_ON();
 +  // Select the card
 +  TransmitIClassCommand(ToSend, ToSendMax, &samples, &wait);
 +  if(trigger)
 +      LED_A_ON();
  
 -      // Store reader command in buffer
 +  // Store reader command in buffer
        if (tracing) {
                uint8_t par[MAX_PARITY_SIZE];
                GetParity(frame, len, par);
@@@ -1452,7 -1449,7 +1451,7 @@@ static int GetIClassAnswer(uint8_t *rec
        for(;;) {
                WDT_HIT();
  
 -              if(BUTTON_PRESS()) return FALSE;
 +          if(BUTTON_PRESS()) return FALSE;
  
                if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
                        AT91C_BASE_SSC->SSC_THR = 0x00;  // To make use of exact timing of next command from reader!!
@@@ -1490,8 -1487,8 +1489,8 @@@ void setupIclassReader(
  {
      FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
      // Reset trace buffer
-     iso14a_set_tracing(TRUE);
-     iso14a_clear_trace();
+       set_tracing(TRUE);
+       clear_trace();
  
      // Setup SSC
      FpgaSetupSsc();
@@@ -1587,14 -1584,14 +1586,14 @@@ void ReaderIClass(uint8_t arg0) 
      int read_status= 0;
      bool abort_after_read = arg0 & FLAG_ICLASS_READER_ONLY_ONCE;
        bool get_cc = arg0 & FLAG_ICLASS_READER_GET_CC;
+       set_tracing(TRUE);
      setupIclassReader();
  
      size_t datasize = 0;
      while(!BUTTON_PRESS())
      {
  
-               if(traceLen > BigBuf_max_traceLen()) {
+               if(!tracing) {
                        DbpString("Trace full");
                        break;
                }
                if(read_status == 1) datasize = 8;
                if(read_status == 2) datasize = 16;
  
 -              LED_B_ON();
 -              //Send back to client, but don't bother if we already sent this
 -              if(memcmp(last_csn, card_data, 8) != 0)
 +                    LED_B_ON();
 +                    //Send back to client, but don't bother if we already sent this
 +                    if(memcmp(last_csn, card_data, 8) != 0)
                {
  
                        if(!get_cc || (get_cc && read_status == 2))
                        {
 -                              cmd_send(CMD_ACK,read_status,0,0,card_data,datasize);
 +                        cmd_send(CMD_ACK,read_status,0,0,card_data,datasize);
                                if(abort_after_read) {
                                        LED_A_OFF();
                                        return;
                                }
 -                              //Save that we already sent this....
 -                              memcpy(last_csn, card_data, 8);
 +                    //Save that we already sent this....
 +                        memcpy(last_csn, card_data, 8);
                        }
                        //If 'get_cc' was specified and we didn't get a CC, we'll just keep trying...
                }
@@@ -1660,13 -1657,13 +1659,13 @@@ void ReaderIClass_Replay(uint8_t arg0, 
        uint8_t resp[ICLASS_BUFFER_SIZE];
        
      setupIclassReader();
+       set_tracing(TRUE);
  
        while(!BUTTON_PRESS()) {
        
                WDT_HIT();
  
-               if(traceLen > BigBuf_max_traceLen()) {
+               if(!tracing) {
                        DbpString("Trace full");
                        break;
                }
                uint8_t read_status = handshakeIclassTag(card_data);
                if(read_status < 2) continue;
  
 -              //for now replay captured auth (as cc not updated)
 -              memcpy(check+5,MAC,4);
 +                              //for now replay captured auth (as cc not updated)
 +                              memcpy(check+5,MAC,4);
  
                if(sendCmdGetResponseWithRetries(check, sizeof(check),resp, 4, 5))
                {
 -                      Dbprintf("Error: Authentication Fail!");
 +                                Dbprintf("Error: Authentication Fail!");
                        continue;
 -              }
 +                              }
  
                //first get configuration block (block 1)
                crc = block_crc_LUT[1];
 -              read[1]=1;
 -              read[2] = crc >> 8;
 -              read[3] = crc & 0xff;
 +                              read[1]=1;
 +                              read[2] = crc >> 8;
 +                              read[3] = crc & 0xff;
  
                if(sendCmdGetResponseWithRetries(read, sizeof(read),resp, 10, 10))
                {
                        continue;
                }
  
 -              mem=resp[5];
 -              memory.k16= (mem & 0x80);
 -              memory.book= (mem & 0x20);
 -              memory.k2= (mem & 0x8);
 -              memory.lockauth= (mem & 0x2);
 -              memory.keyaccess= (mem & 0x1);
 +                                       mem=resp[5];
 +                                       memory.k16= (mem & 0x80);
 +                                       memory.book= (mem & 0x20);
 +                                       memory.k2= (mem & 0x8);
 +                                       memory.lockauth= (mem & 0x2);
 +                                       memory.keyaccess= (mem & 0x1);
  
                cardsize = memory.k16 ? 255 : 32;
                WDT_HIT();
                memset(card_data,0x0,USB_CMD_DATA_SIZE);
                uint8_t failedRead =0;
                uint8_t stored_data_length =0;
 -              //then loop around remaining blocks
 +                              //then loop around remaining blocks
                for(int block=0; block < cardsize; block++){
  
                        read[1]= block;
                        crc = block_crc_LUT[block];
 -                      read[2] = crc >> 8;
 -                      read[3] = crc & 0xff;
 +                                  read[2] = crc >> 8;
 +                                  read[3] = crc & 0xff;
  
                        if(!sendCmdGetResponseWithRetries(read, sizeof(read), resp, 10, 10))
                        {
 -                              Dbprintf("     %02x: %02x %02x %02x %02x %02x %02x %02x %02x",
 +                                       Dbprintf("     %02x: %02x %02x %02x %02x %02x %02x %02x %02x",
                                                 block, resp[0], resp[1], resp[2],
 -                                              resp[3], resp[4], resp[5],
 -                                              resp[6], resp[7]);
 +                                        resp[3], resp[4], resp[5],
 +                                        resp[6], resp[7]);
  
                                //Fill up the buffer
                                memcpy(card_data+stored_data_length,resp,8);
@@@ -1785,7 -1782,7 +1784,7 @@@ void IClass_iso14443A_write(uint8_t arg
        uint8_t* resp = (((uint8_t *)BigBuf) + 3560);
  
        // Reset trace buffer
 -    memset(trace, 0x44, RECV_CMD_OFFSET);
 +      memset(trace, 0x44, RECV_CMD_OFFSET);
        traceLen = 0;
  
        // Setup SSC
diff --combined armsrc/iso14443.c
index 48a32b1024db8ef59e024421c938715a0b4be246,c7f49f14059293dc46e5a8c845175b5c03d8e6a9..d570bf2d000c6cc97e37f8dc9464f9fa0e09cad3
  // supported.
  //-----------------------------------------------------------------------------
  
 -#include "proxmark3.h"
 +#include "../include/proxmark3.h"
  #include "apps.h"
  #include "util.h"
  #include "string.h"
  
 -#include "iso14443crc.h"
 +#include "../common/iso14443crc.h"
  
  //static void GetSamplesFor14443(int weTx, int n);
  
- #define DEMOD_TRACE_SIZE 4096
/*#define DEMOD_TRACE_SIZE 4096
  #define READER_TAG_BUFFER_SIZE 2048
  #define TAG_READER_BUFFER_SIZE 2048
  #define DEMOD_DMA_BUFFER_SIZE 1024
+ */
  //=============================================================================
  // An ISO 14443 Type B tag. We listen for commands from the reader, using
  // a UART kind of thing that's implemented in software. When we get a
  //-----------------------------------------------------------------------------
  static void CodeIso14443bAsTag(const uint8_t *cmd, int len)
  {
-     int i;
-     ToSendReset();
-     // Transmit a burst of ones, as the initial thing that lets the
-     // reader get phase sync. This (TR1) must be > 80/fs, per spec,
-     // but tag that I've tried (a Paypass) exceeds that by a fair bit,
-     // so I will too.
-     for(i = 0; i < 20; i++) {
-         ToSendStuffBit(1);
-         ToSendStuffBit(1);
-         ToSendStuffBit(1);
-         ToSendStuffBit(1);
-     }
-     // Send SOF.
-     for(i = 0; i < 10; i++) {
-         ToSendStuffBit(0);
-         ToSendStuffBit(0);
-         ToSendStuffBit(0);
-         ToSendStuffBit(0);
-     }
-     for(i = 0; i < 2; i++) {
-         ToSendStuffBit(1);
-         ToSendStuffBit(1);
-         ToSendStuffBit(1);
-         ToSendStuffBit(1);
-     }
-     for(i = 0; i < len; i++) {
-         int j;
-         uint8_t b = cmd[i];
-         // Start bit
-         ToSendStuffBit(0);
-         ToSendStuffBit(0);
-         ToSendStuffBit(0);
-         ToSendStuffBit(0);
-         // Data bits
-         for(j = 0; j < 8; j++) {
-             if(b & 1) {
-                 ToSendStuffBit(1);
-                 ToSendStuffBit(1);
-                 ToSendStuffBit(1);
-                 ToSendStuffBit(1);
-             } else {
-                 ToSendStuffBit(0);
-                 ToSendStuffBit(0);
-                 ToSendStuffBit(0);
-                 ToSendStuffBit(0);
-             }
-             b >>= 1;
-         }
-         // Stop bit
-         ToSendStuffBit(1);
-         ToSendStuffBit(1);
-         ToSendStuffBit(1);
-         ToSendStuffBit(1);
-     }
-     // Send SOF.
-     for(i = 0; i < 10; i++) {
-         ToSendStuffBit(0);
-         ToSendStuffBit(0);
-         ToSendStuffBit(0);
-         ToSendStuffBit(0);
-     }
-     for(i = 0; i < 10; i++) {
-         ToSendStuffBit(1);
-         ToSendStuffBit(1);
-         ToSendStuffBit(1);
-         ToSendStuffBit(1);
-     }
-     // Convert from last byte pos to length
-     ToSendMax++;
-     // Add a few more for slop
-     ToSendMax += 2;
+       int i;
+       ToSendReset();
+       // Transmit a burst of ones, as the initial thing that lets the
+       // reader get phase sync. This (TR1) must be > 80/fs, per spec,
+       // but tag that I've tried (a Paypass) exceeds that by a fair bit,
+       // so I will too.
+       for(i = 0; i < 20; i++) {
+               ToSendStuffBit(1);
+               ToSendStuffBit(1);
+               ToSendStuffBit(1);
+               ToSendStuffBit(1);
+       }
+       // Send SOF.
+       for(i = 0; i < 10; i++) {
+               ToSendStuffBit(0);
+               ToSendStuffBit(0);
+               ToSendStuffBit(0);
+               ToSendStuffBit(0);
+       }
+       for(i = 0; i < 2; i++) {
+               ToSendStuffBit(1);
+               ToSendStuffBit(1);
+               ToSendStuffBit(1);
+               ToSendStuffBit(1);
+       }
+       for(i = 0; i < len; i++) {
+               int j;
+               uint8_t b = cmd[i];
+               // Start bit
+               ToSendStuffBit(0);
+               ToSendStuffBit(0);
+               ToSendStuffBit(0);
+               ToSendStuffBit(0);
+               // Data bits
+               for(j = 0; j < 8; j++) {
+                       if(b & 1) {
+                               ToSendStuffBit(1);
+                               ToSendStuffBit(1);
+                               ToSendStuffBit(1);
+                               ToSendStuffBit(1);
+                       } else {
+                               ToSendStuffBit(0);
+                               ToSendStuffBit(0);
+                               ToSendStuffBit(0);
+                               ToSendStuffBit(0);
+                       }
+                       b >>= 1;
+               }
+               // Stop bit
+               ToSendStuffBit(1);
+               ToSendStuffBit(1);
+               ToSendStuffBit(1);
+               ToSendStuffBit(1);
+       }
+       // Send SOF.
+       for(i = 0; i < 10; i++) {
+               ToSendStuffBit(0);
+               ToSendStuffBit(0);
+               ToSendStuffBit(0);
+               ToSendStuffBit(0);
+       }
+       for(i = 0; i < 10; i++) {
+               ToSendStuffBit(1);
+               ToSendStuffBit(1);
+               ToSendStuffBit(1);
+               ToSendStuffBit(1);
+       }
+       // Convert from last byte pos to length
+       ToSendMax++;
+       // Add a few more for slop
+       ToSendMax += 2;
  }
  
  //-----------------------------------------------------------------------------
  // variables.
  //-----------------------------------------------------------------------------
  static struct {
-     enum {
-         STATE_UNSYNCD,
-         STATE_GOT_FALLING_EDGE_OF_SOF,
-         STATE_AWAITING_START_BIT,
-         STATE_RECEIVING_DATA,
-         STATE_ERROR_WAIT
-     }       state;
-     uint16_t    shiftReg;
-     int     bitCnt;
-     int     byteCnt;
-     int     byteCntMax;
-     int     posCnt;
-     uint8_t   *output;
+       enum {
+               STATE_UNSYNCD,
+               STATE_GOT_FALLING_EDGE_OF_SOF,
+               STATE_AWAITING_START_BIT,
+               STATE_RECEIVING_DATA,
+               STATE_ERROR_WAIT
+       }       state;
+       uint16_t    shiftReg;
+       int     bitCnt;
+       int     byteCnt;
+       int     byteCntMax;
+       int     posCnt;
+       uint8_t   *output;
  } Uart;
  
  /* Receive & handle a bit coming from the reader.
   */
  static int Handle14443UartBit(int bit)
  {
-     switch(Uart.state) {
-         case STATE_UNSYNCD:
-               LED_A_OFF();
-             if(!bit) {
-                 // we went low, so this could be the beginning
-                 // of an SOF
-                 Uart.state = STATE_GOT_FALLING_EDGE_OF_SOF;
-                 Uart.posCnt = 0;
-                 Uart.bitCnt = 0;
-             }
-             break;
-         case STATE_GOT_FALLING_EDGE_OF_SOF:
-             Uart.posCnt++;
-             if(Uart.posCnt == 2) {
-                 if(bit) {
-                     if(Uart.bitCnt >= 10) {
-                         // we've seen enough consecutive
-                         // zeros that it's a valid SOF
-                         Uart.posCnt = 0;
-                         Uart.byteCnt = 0;
-                         Uart.state = STATE_AWAITING_START_BIT;
-                         LED_A_ON(); // Indicate we got a valid SOF
-                     } else {
-                         // didn't stay down long enough
-                         // before going high, error
-                         Uart.state = STATE_ERROR_WAIT;
-                     }
-                 } else {
-                     // do nothing, keep waiting
-                 }
-                 Uart.bitCnt++;
-             }
-             if(Uart.posCnt >= 4) Uart.posCnt = 0;
-             if(Uart.bitCnt > 14) {
-                 // Give up if we see too many zeros without
-                 // a one, too.
-                 Uart.state = STATE_ERROR_WAIT;
-             }
-             break;
-         case STATE_AWAITING_START_BIT:
-             Uart.posCnt++;
-             if(bit) {
-                 if(Uart.posCnt > 25) {
-                     // stayed high for too long between
-                     // characters, error
-                     Uart.state = STATE_ERROR_WAIT;
-                 }
-             } else {
-                 // falling edge, this starts the data byte
-                 Uart.posCnt = 0;
-                 Uart.bitCnt = 0;
-                 Uart.shiftReg = 0;
-                 Uart.state = STATE_RECEIVING_DATA;
-                 LED_A_ON(); // Indicate we're receiving
-             }
-             break;
-         case STATE_RECEIVING_DATA:
-             Uart.posCnt++;
-             if(Uart.posCnt == 2) {
-                 // time to sample a bit
-                 Uart.shiftReg >>= 1;
-                 if(bit) {
-                     Uart.shiftReg |= 0x200;
-                 }
-                 Uart.bitCnt++;
-             }
-             if(Uart.posCnt >= 4) {
-                 Uart.posCnt = 0;
-             }
-             if(Uart.bitCnt == 10) {
-                 if((Uart.shiftReg & 0x200) && !(Uart.shiftReg & 0x001))
-                 {
-                     // this is a data byte, with correct
-                     // start and stop bits
-                     Uart.output[Uart.byteCnt] = (Uart.shiftReg >> 1) & 0xff;
-                     Uart.byteCnt++;
-                     if(Uart.byteCnt >= Uart.byteCntMax) {
-                         // Buffer overflowed, give up
-                         Uart.posCnt = 0;
-                         Uart.state = STATE_ERROR_WAIT;
-                     } else {
-                         // so get the next byte now
-                         Uart.posCnt = 0;
-                         Uart.state = STATE_AWAITING_START_BIT;
-                     }
-                 } else if(Uart.shiftReg == 0x000) {
-                     // this is an EOF byte
-                       LED_A_OFF(); // Finished receiving
-                     return TRUE;
-                 } else {
-                     // this is an error
-                     Uart.posCnt = 0;
-                     Uart.state = STATE_ERROR_WAIT;
-                 }
-             }
-             break;
-         case STATE_ERROR_WAIT:
-             // We're all screwed up, so wait a little while
-             // for whatever went wrong to finish, and then
-             // start over.
-             Uart.posCnt++;
-             if(Uart.posCnt > 10) {
-                 Uart.state = STATE_UNSYNCD;
-             }
-             break;
-         default:
-             Uart.state = STATE_UNSYNCD;
-             break;
-     }
-     // This row make the error blew circular buffer in hf 14b snoop
-     //if (Uart.state == STATE_ERROR_WAIT) LED_A_OFF(); // Error
-     return FALSE;
+       switch(Uart.state) {
+               case STATE_UNSYNCD:
+                       LED_A_OFF();
+                       if(!bit) {
+                               // we went low, so this could be the beginning
+                               // of an SOF
+                               Uart.state = STATE_GOT_FALLING_EDGE_OF_SOF;
+                               Uart.posCnt = 0;
+                               Uart.bitCnt = 0;
+                       }
+                       break;
+               case STATE_GOT_FALLING_EDGE_OF_SOF:
+                       Uart.posCnt++;
+                       if(Uart.posCnt == 2) {
+                               if(bit) {
+                                       if(Uart.bitCnt >= 10) {
+                                               // we've seen enough consecutive
+                                               // zeros that it's a valid SOF
+                                               Uart.posCnt = 0;
+                                               Uart.byteCnt = 0;
+                                               Uart.state = STATE_AWAITING_START_BIT;
+                                               LED_A_ON(); // Indicate we got a valid SOF
+                                       } else {
+                                               // didn't stay down long enough
+                                               // before going high, error
+                                               Uart.state = STATE_ERROR_WAIT;
+                                       }
+                               } else {
+                                       // do nothing, keep waiting
+                               }
+                               Uart.bitCnt++;
+                       }
+                       if(Uart.posCnt >= 4) Uart.posCnt = 0;
+                       if(Uart.bitCnt > 14) {
+                               // Give up if we see too many zeros without
+                               // a one, too.
+                               Uart.state = STATE_ERROR_WAIT;
+                       }
+                       break;
+               case STATE_AWAITING_START_BIT:
+                       Uart.posCnt++;
+                       if(bit) {
+                               if(Uart.posCnt > 25) {
+                                       // stayed high for too long between
+                                       // characters, error
+                                       Uart.state = STATE_ERROR_WAIT;
+                               }
+                       } else {
+                               // falling edge, this starts the data byte
+                               Uart.posCnt = 0;
+                               Uart.bitCnt = 0;
+                               Uart.shiftReg = 0;
+                               Uart.state = STATE_RECEIVING_DATA;
+                               LED_A_ON(); // Indicate we're receiving
+                       }
+                       break;
+               case STATE_RECEIVING_DATA:
+                       Uart.posCnt++;
+                       if(Uart.posCnt == 2) {
+                               // time to sample a bit
+                               Uart.shiftReg >>= 1;
+                               if(bit) {
+                                       Uart.shiftReg |= 0x200;
+                               }
+                               Uart.bitCnt++;
+                       }
+                       if(Uart.posCnt >= 4) {
+                               Uart.posCnt = 0;
+                       }
+                       if(Uart.bitCnt == 10) {
+                               if((Uart.shiftReg & 0x200) && !(Uart.shiftReg & 0x001))
+                               {
+                                       // this is a data byte, with correct
+                                       // start and stop bits
+                                       Uart.output[Uart.byteCnt] = (Uart.shiftReg >> 1) & 0xff;
+                                       Uart.byteCnt++;
+                                       if(Uart.byteCnt >= Uart.byteCntMax) {
+                                               // Buffer overflowed, give up
+                                               Uart.posCnt = 0;
+                                               Uart.state = STATE_ERROR_WAIT;
+                                       } else {
+                                               // so get the next byte now
+                                               Uart.posCnt = 0;
+                                               Uart.state = STATE_AWAITING_START_BIT;
+                                       }
+                               } else if(Uart.shiftReg == 0x000) {
+                                       // this is an EOF byte
+                                       LED_A_OFF(); // Finished receiving
+                                       return TRUE;
+                               } else {
+                                       // this is an error
+                                       Uart.posCnt = 0;
+                                       Uart.state = STATE_ERROR_WAIT;
+                               }
+                       }
+                       break;
+               case STATE_ERROR_WAIT:
+                       // We're all screwed up, so wait a little while
+                       // for whatever went wrong to finish, and then
+                       // start over.
+                       Uart.posCnt++;
+                       if(Uart.posCnt > 10) {
+                               Uart.state = STATE_UNSYNCD;
+                       }
+                       break;
+               default:
+                       Uart.state = STATE_UNSYNCD;
+                       break;
+       }
+       // This row make the error blew circular buffer in hf 14b snoop
+       //if (Uart.state == STATE_ERROR_WAIT) LED_A_OFF(); // Error
+       return FALSE;
  }
  
  //-----------------------------------------------------------------------------
  //-----------------------------------------------------------------------------
  static int GetIso14443CommandFromReader(uint8_t *received, int *len, int maxLen)
  {
-     uint8_t mask;
-     int i, bit;
-     // Set FPGA mode to "simulated ISO 14443 tag", no modulation (listen
-     // only, since we are receiving, not transmitting).
-     // Signal field is off with the appropriate LED
-     LED_D_OFF();
-     FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION);
-     // Now run a `software UART' on the stream of incoming samples.
-     Uart.output = received;
-     Uart.byteCntMax = maxLen;
-     Uart.state = STATE_UNSYNCD;
-     for(;;) {
-         WDT_HIT();
-         if(BUTTON_PRESS()) return FALSE;
-         if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
-             AT91C_BASE_SSC->SSC_THR = 0x00;
-         }
-         if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
-             uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
-             mask = 0x80;
-             for(i = 0; i < 8; i++, mask >>= 1) {
-                 bit = (b & mask);
-                 if(Handle14443UartBit(bit)) {
-                     *len = Uart.byteCnt;
-                     return TRUE;
-                 }
-             }
-         }
-     }
+       uint8_t mask;
+       int i, bit;
+       // Set FPGA mode to "simulated ISO 14443 tag", no modulation (listen
+       // only, since we are receiving, not transmitting).
+       // Signal field is off with the appropriate LED
+       LED_D_OFF();
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION);
+       // Now run a `software UART' on the stream of incoming samples.
+       Uart.output = received;
+       Uart.byteCntMax = maxLen;
+       Uart.state = STATE_UNSYNCD;
+       for(;;) {
+               WDT_HIT();
+               if(BUTTON_PRESS()) return FALSE;
+               if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
+                       AT91C_BASE_SSC->SSC_THR = 0x00;
+               }
+               if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
+                       uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
+                       mask = 0x80;
+                       for(i = 0; i < 8; i++, mask >>= 1) {
+                               bit = (b & mask);
+                               if(Handle14443UartBit(bit)) {
+                                       *len = Uart.byteCnt;
+                                       return TRUE;
+                               }
+                       }
+               }
+       }
  }
  
  //-----------------------------------------------------------------------------
  //-----------------------------------------------------------------------------
  void SimulateIso14443Tag(void)
  {
-     static const uint8_t cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 };
-     static const uint8_t response1[] = {
-         0x50, 0x82, 0x0d, 0xe1, 0x74, 0x20, 0x38, 0x19, 0x22,
-         0x00, 0x21, 0x85, 0x5e, 0xd7
-     };
+       static const uint8_t cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 };
+       static const uint8_t response1[] = {
+               0x50, 0x82, 0x0d, 0xe1, 0x74, 0x20, 0x38, 0x19, 0x22,
+               0x00, 0x21, 0x85, 0x5e, 0xd7
+       };
  
-     uint8_t *resp;
-     int respLen;
+       uint8_t *resp;
+       int respLen;
  
-     uint8_t *resp1 = BigBuf_get_addr() + 800;
-     int resp1Len;
+       uint8_t *resp1 = BigBuf_get_addr() + 800;
+       int resp1Len;
  
-     uint8_t *receivedCmd = BigBuf_get_addr();
-     int len;
+       uint8_t *receivedCmd = BigBuf_get_addr();
+       int len;
  
-     int i;
+       int i;
  
-     int cmdsRecvd = 0;
+       int cmdsRecvd = 0;
  
-     FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
-     memset(receivedCmd, 0x44, 400);
+       FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
+       memset(receivedCmd, 0x44, 400);
  
-     CodeIso14443bAsTag(response1, sizeof(response1));
-     memcpy(resp1, ToSend, ToSendMax); resp1Len = ToSendMax;
+       CodeIso14443bAsTag(response1, sizeof(response1));
+       memcpy(resp1, ToSend, ToSendMax); resp1Len = ToSendMax;
  
-     // We need to listen to the high-frequency, peak-detected path.
-     SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
-     FpgaSetupSsc();
+       // We need to listen to the high-frequency, peak-detected path.
+       SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
+       FpgaSetupSsc();
  
-     cmdsRecvd = 0;
+       cmdsRecvd = 0;
  
-     for(;;) {
-         uint8_t b1, b2;
+       for(;;) {
+               uint8_t b1, b2;
  
-         if(!GetIso14443CommandFromReader(receivedCmd, &len, 100)) {
+               if(!GetIso14443CommandFromReader(receivedCmd, &len, 100)) {
                Dbprintf("button pressed, received %d commands", cmdsRecvd);
                break;
-         }
-         // Good, look at the command now.
-         if(len == sizeof(cmd1) && memcmp(receivedCmd, cmd1, len)==0) {
-             resp = resp1; respLen = resp1Len;
-         } else {
-             Dbprintf("new cmd from reader: len=%d, cmdsRecvd=%d", len, cmdsRecvd);
-             // And print whether the CRC fails, just for good measure
-             ComputeCrc14443(CRC_14443_B, receivedCmd, len-2, &b1, &b2);
-             if(b1 != receivedCmd[len-2] || b2 != receivedCmd[len-1]) {
-                 // Not so good, try again.
-                 DbpString("+++CRC fail");
-             } else {
-                 DbpString("CRC passes");
-             }
-             break;
-         }
-         memset(receivedCmd, 0x44, 32);
-         cmdsRecvd++;
-         if(cmdsRecvd > 0x30) {
-             DbpString("many commands later...");
-             break;
-         }
-         if(respLen <= 0) continue;
-         // Modulate BPSK
-         // Signal field is off with the appropriate LED
-         LED_D_OFF();
-         FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_BPSK);
-         AT91C_BASE_SSC->SSC_THR = 0xff;
-         FpgaSetupSsc();
-         // Transmit the response.
-         i = 0;
-         for(;;) {
-             if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
-                 uint8_t b = resp[i];
-                 AT91C_BASE_SSC->SSC_THR = b;
-                 i++;
-                 if(i > respLen) {
-                     break;
-                 }
-             }
-             if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
-                 volatile uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
-                 (void)b;
-             }
-         }
-     }
+               }
+               // Good, look at the command now.
+               if(len == sizeof(cmd1) && memcmp(receivedCmd, cmd1, len)==0) {
+                       resp = resp1; respLen = resp1Len;
+               } else {
+                       Dbprintf("new cmd from reader: len=%d, cmdsRecvd=%d", len, cmdsRecvd);
+                       // And print whether the CRC fails, just for good measure
+                       ComputeCrc14443(CRC_14443_B, receivedCmd, len-2, &b1, &b2);
+                       if(b1 != receivedCmd[len-2] || b2 != receivedCmd[len-1]) {
+                               // Not so good, try again.
+                               DbpString("+++CRC fail");
+                       } else {
+                               DbpString("CRC passes");
+                       }
+                       break;
+               }
+               memset(receivedCmd, 0x44, 32);
+               cmdsRecvd++;
+               if(cmdsRecvd > 0x30) {
+                       DbpString("many commands later...");
+                       break;
+               }
+               if(respLen <= 0) continue;
+               // Modulate BPSK
+               // Signal field is off with the appropriate LED
+               LED_D_OFF();
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_BPSK);
+               AT91C_BASE_SSC->SSC_THR = 0xff;
+               FpgaSetupSsc();
+               // Transmit the response.
+               i = 0;
+               for(;;) {
+                       if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
+                               uint8_t b = resp[i];
+                               AT91C_BASE_SSC->SSC_THR = b;
+                               i++;
+                               if(i > respLen) {
+                                       break;
+                               }
+                       }
+                       if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
+                               volatile uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
+                               (void)b;
+                       }
+               }
+       }
  }
  
  //=============================================================================
  //=============================================================================
  
  static struct {
-     enum {
-         DEMOD_UNSYNCD,
-         DEMOD_PHASE_REF_TRAINING,
-         DEMOD_AWAITING_FALLING_EDGE_OF_SOF,
-         DEMOD_GOT_FALLING_EDGE_OF_SOF,
-         DEMOD_AWAITING_START_BIT,
-         DEMOD_RECEIVING_DATA,
-         DEMOD_ERROR_WAIT
-     }       state;
-     int     bitCount;
-     int     posCount;
-     int     thisBit;
-     int     metric;
-     int     metricN;
-     uint16_t    shiftReg;
-     uint8_t   *output;
-     int     len;
-     int     sumI;
-     int     sumQ;
+       enum {
+               DEMOD_UNSYNCD,
+               DEMOD_PHASE_REF_TRAINING,
+               DEMOD_AWAITING_FALLING_EDGE_OF_SOF,
+               DEMOD_GOT_FALLING_EDGE_OF_SOF,
+               DEMOD_AWAITING_START_BIT,
+               DEMOD_RECEIVING_DATA,
+               DEMOD_ERROR_WAIT
+       }       state;
+       int     bitCount;
+       int     posCount;
+       int     thisBit;
+       int     metric;
+       int     metricN;
+       uint16_t    shiftReg;
+       uint8_t   *output;
+       int     len;
+       int     sumI;
+       int     sumQ;
  } Demod;
  
  /*
   */
  static RAMFUNC int Handle14443SamplesDemod(int ci, int cq)
  {
-     int v;
+       int v;
  
-     // The soft decision on the bit uses an estimate of just the
-     // quadrant of the reference angle, not the exact angle.
+       // The soft decision on the bit uses an estimate of just the
+       // quadrant of the reference angle, not the exact angle.
  #define MAKE_SOFT_DECISION() { \
-         if(Demod.sumI > 0) { \
-             v = ci; \
-         } else { \
-             v = -ci; \
-         } \
-         if(Demod.sumQ > 0) { \
-             v += cq; \
-         } else { \
-             v -= cq; \
-         } \
-     }
-     switch(Demod.state) {
-         case DEMOD_UNSYNCD:
-             v = ci;
-             if(v < 0) v = -v;
-             if(cq > 0) {
-                 v += cq;
-             } else {
-                 v -= cq;
-             }
-             if(v > 40) {
-                 Demod.posCount = 0;
-                 Demod.state = DEMOD_PHASE_REF_TRAINING;
-                 Demod.sumI = 0;
-                 Demod.sumQ = 0;
-             }
-             break;
-         case DEMOD_PHASE_REF_TRAINING:
-             if(Demod.posCount < 8) {
-                 Demod.sumI += ci;
-                 Demod.sumQ += cq;
-             } else if(Demod.posCount > 100) {
-                 // error, waited too long
-                 Demod.state = DEMOD_UNSYNCD;
-             } else {
-                 MAKE_SOFT_DECISION();
-                 if(v < 0) {
-                     Demod.state = DEMOD_AWAITING_FALLING_EDGE_OF_SOF;
-                     Demod.posCount = 0;
-                 }
-             }
-             Demod.posCount++;
-             break;
-         case DEMOD_AWAITING_FALLING_EDGE_OF_SOF:
-             MAKE_SOFT_DECISION();
-             if(v < 0) {
-                 Demod.state = DEMOD_GOT_FALLING_EDGE_OF_SOF;
-                 Demod.posCount = 0;
-             } else {
-                 if(Demod.posCount > 100) {
-                     Demod.state = DEMOD_UNSYNCD;
-                 }
-             }
-             Demod.posCount++;
-             break;
-         case DEMOD_GOT_FALLING_EDGE_OF_SOF:
-             MAKE_SOFT_DECISION();
-             if(v > 0) {
-                 if(Demod.posCount < 12) {
-                     Demod.state = DEMOD_UNSYNCD;
-                 } else {
-                     LED_C_ON(); // Got SOF
-                     Demod.state = DEMOD_AWAITING_START_BIT;
-                     Demod.posCount = 0;
-                     Demod.len = 0;
-                     Demod.metricN = 0;
-                     Demod.metric = 0;
-                 }
-             } else {
-                 if(Demod.posCount > 100) {
-                     Demod.state = DEMOD_UNSYNCD;
-                 }
-             }
-             Demod.posCount++;
-             break;
-         case DEMOD_AWAITING_START_BIT:
-             MAKE_SOFT_DECISION();
-             if(v > 0) {
-                 if(Demod.posCount > 10) {
-                     Demod.state = DEMOD_UNSYNCD;
-                 }
-             } else {
-                 Demod.bitCount = 0;
-                 Demod.posCount = 1;
-                 Demod.thisBit = v;
-                 Demod.shiftReg = 0;
-                 Demod.state = DEMOD_RECEIVING_DATA;
-             }
-             break;
-         case DEMOD_RECEIVING_DATA:
-             MAKE_SOFT_DECISION();
-             if(Demod.posCount == 0) {
-                 Demod.thisBit = v;
-                 Demod.posCount = 1;
-             } else {
-                 Demod.thisBit += v;
-                 if(Demod.thisBit > 0) {
-                     Demod.metric += Demod.thisBit;
-                 } else {
-                     Demod.metric -= Demod.thisBit;
-                 }
-                 (Demod.metricN)++;
-                 Demod.shiftReg >>= 1;
-                 if(Demod.thisBit > 0) {
-                     Demod.shiftReg |= 0x200;
-                 }
-                 Demod.bitCount++;
-                 if(Demod.bitCount == 10) {
-                     uint16_t s = Demod.shiftReg;
-                     if((s & 0x200) && !(s & 0x001)) {
-                         uint8_t b = (s >> 1);
-                         Demod.output[Demod.len] = b;
-                         Demod.len++;
-                         Demod.state = DEMOD_AWAITING_START_BIT;
-                     } else if(s == 0x000) {
-                         // This is EOF
-                       LED_C_OFF();
-                         Demod.state = DEMOD_UNSYNCD;
-                         return TRUE;
-                     } else {
-                         Demod.state = DEMOD_UNSYNCD;
-                     }
-                 }
-                 Demod.posCount = 0;
-             }
-             break;
-         default:
-             Demod.state = DEMOD_UNSYNCD;
-             break;
-     }
-     if (Demod.state == DEMOD_UNSYNCD) LED_C_OFF(); // Not synchronized...
-     return FALSE;
+               if(Demod.sumI > 0) { \
+                       v = ci; \
+               } else { \
+                       v = -ci; \
+               } \
+               if(Demod.sumQ > 0) { \
+                       v += cq; \
+               } else { \
+                       v -= cq; \
+               } \
+       }
+       switch(Demod.state) {
+               case DEMOD_UNSYNCD:
+                       v = ci;
+                       if(v < 0) v = -v;
+                       if(cq > 0) {
+                               v += cq;
+                       } else {
+                               v -= cq;
+                       }
+                       if(v > 40) {
+                               Demod.posCount = 0;
+                               Demod.state = DEMOD_PHASE_REF_TRAINING;
+                               Demod.sumI = 0;
+                               Demod.sumQ = 0;
+                       }
+                       break;
+               case DEMOD_PHASE_REF_TRAINING:
+                       if(Demod.posCount < 8) {
+                               Demod.sumI += ci;
+                               Demod.sumQ += cq;
+                       } else if(Demod.posCount > 100) {
+                               // error, waited too long
+                               Demod.state = DEMOD_UNSYNCD;
+                       } else {
+                               MAKE_SOFT_DECISION();
+                               if(v < 0) {
+                                       Demod.state = DEMOD_AWAITING_FALLING_EDGE_OF_SOF;
+                                       Demod.posCount = 0;
+                               }
+                       }
+                       Demod.posCount++;
+                       break;
+               case DEMOD_AWAITING_FALLING_EDGE_OF_SOF:
+                       MAKE_SOFT_DECISION();
+                       if(v < 0) {
+                               Demod.state = DEMOD_GOT_FALLING_EDGE_OF_SOF;
+                               Demod.posCount = 0;
+                       } else {
+                               if(Demod.posCount > 100) {
+                                       Demod.state = DEMOD_UNSYNCD;
+                               }
+                       }
+                       Demod.posCount++;
+                       break;
+               case DEMOD_GOT_FALLING_EDGE_OF_SOF:
+                       MAKE_SOFT_DECISION();
+                       if(v > 0) {
+                               if(Demod.posCount < 12) {
+                                       Demod.state = DEMOD_UNSYNCD;
+                               } else {
+                                       LED_C_ON(); // Got SOF
+                                       Demod.state = DEMOD_AWAITING_START_BIT;
+                                       Demod.posCount = 0;
+                                       Demod.len = 0;
+                                       Demod.metricN = 0;
+                                       Demod.metric = 0;
+                               }
+                       } else {
+                               if(Demod.posCount > 100) {
+                                       Demod.state = DEMOD_UNSYNCD;
+                               }
+                       }
+                       Demod.posCount++;
+                       break;
+               case DEMOD_AWAITING_START_BIT:
+                       MAKE_SOFT_DECISION();
+                       if(v > 0) {
+                               if(Demod.posCount > 10) {
+                                       Demod.state = DEMOD_UNSYNCD;
+                               }
+                       } else {
+                               Demod.bitCount = 0;
+                               Demod.posCount = 1;
+                               Demod.thisBit = v;
+                               Demod.shiftReg = 0;
+                               Demod.state = DEMOD_RECEIVING_DATA;
+                       }
+                       break;
+               case DEMOD_RECEIVING_DATA:
+                       MAKE_SOFT_DECISION();
+                       if(Demod.posCount == 0) {
+                               Demod.thisBit = v;
+                               Demod.posCount = 1;
+                       } else {
+                               Demod.thisBit += v;
+                               if(Demod.thisBit > 0) {
+                                       Demod.metric += Demod.thisBit;
+                               } else {
+                                       Demod.metric -= Demod.thisBit;
+                               }
+                               (Demod.metricN)++;
+                               Demod.shiftReg >>= 1;
+                               if(Demod.thisBit > 0) {
+                                       Demod.shiftReg |= 0x200;
+                               }
+                               Demod.bitCount++;
+                               if(Demod.bitCount == 10) {
+                                       uint16_t s = Demod.shiftReg;
+                                       if((s & 0x200) && !(s & 0x001)) {
+                                               uint8_t b = (s >> 1);
+                                               Demod.output[Demod.len] = b;
+                                               Demod.len++;
+                                               Demod.state = DEMOD_AWAITING_START_BIT;
+                                       } else if(s == 0x000) {
+                                               // This is EOF
+                                               LED_C_OFF();
+                                               Demod.state = DEMOD_UNSYNCD;
+                                               return TRUE;
+                                       } else {
+                                               Demod.state = DEMOD_UNSYNCD;
+                                       }
+                               }
+                               Demod.posCount = 0;
+                       }
+                       break;
+               default:
+                       Demod.state = DEMOD_UNSYNCD;
+                       break;
+       }
+       if (Demod.state == DEMOD_UNSYNCD) LED_C_OFF(); // Not synchronized...
+       return FALSE;
+ }
+ static void DemodReset()
+ {
+       // Clear out the state of the "UART" that receives from the tag.
+       Demod.len = 0;
+       Demod.state = DEMOD_UNSYNCD;
+       memset(Demod.output, 0x00, MAX_FRAME_SIZE);
+ }
+ static void DemodInit(uint8_t *data)
+ {
+       Demod.output = data;
+       DemodReset();
+ }
+ static void UartReset()
+ {
+       Uart.byteCntMax = MAX_FRAME_SIZE;
+       Uart.state = STATE_UNSYNCD;
+       Uart.byteCnt = 0;
+       Uart.bitCnt = 0;
+ }
+ static void UartInit(uint8_t *data)
+ {
+       Uart.output = data;
+       UartReset();
  }
  
  /*
-  *  Demodulate the samples we received from the tag
+  *  Demodulate the samples we received from the tag, also log to tracebuffer
   *  weTx: set to 'TRUE' if we behave like a reader
   *        set to 'FALSE' if we behave like a snooper
   *  quiet: set to 'TRUE' to disable debug output
   */
  static void GetSamplesFor14443Demod(int weTx, int n, int quiet)
  {
-     int max = 0;
-     int gotFrame = FALSE;
- //#   define DMA_BUFFER_SIZE 8
-     uint8_t *dmaBuf;
-     int lastRxCounter;
-     uint8_t *upTo;
-     int ci, cq;
-     int samples = 0;
-     // Clear out the state of the "UART" that receives from the tag.
-       uint8_t *BigBuf = BigBuf_get_addr();
-     memset(BigBuf, 0x00, 400);
-     Demod.output = BigBuf;
-     Demod.len = 0;
-     Demod.state = DEMOD_UNSYNCD;
-     // And the UART that receives from the reader
-     Uart.output = BigBuf + 1024;
-     Uart.byteCntMax = 100;
-     Uart.state = STATE_UNSYNCD;
-     // Setup for the DMA.
-     dmaBuf = BigBuf + 32;
-     upTo = dmaBuf;
-     lastRxCounter = DEMOD_DMA_BUFFER_SIZE;
-     FpgaSetupSscDma(dmaBuf, DEMOD_DMA_BUFFER_SIZE);
-     // Signal field is ON with the appropriate LED:
-     if (weTx) LED_D_ON(); else LED_D_OFF();
-     // And put the FPGA in the appropriate mode
-     FpgaWriteConfWord(
-       FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ |
-       (weTx ? 0 : FPGA_HF_READER_RX_XCORR_SNOOP));
-     for(;;) {
-         int behindBy = lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR;
-         if(behindBy > max) max = behindBy;
-         while(((lastRxCounter-AT91C_BASE_PDC_SSC->PDC_RCR) & (DEMOD_DMA_BUFFER_SIZE-1))
-                     > 2)
-         {
-             ci = upTo[0];
-             cq = upTo[1];
-             upTo += 2;
-             if(upTo - dmaBuf > DEMOD_DMA_BUFFER_SIZE) {
-                 upTo -= DEMOD_DMA_BUFFER_SIZE;
-                 AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo;
-                 AT91C_BASE_PDC_SSC->PDC_RNCR = DEMOD_DMA_BUFFER_SIZE;
-             }
-             lastRxCounter -= 2;
-             if(lastRxCounter <= 0) {
-                 lastRxCounter += DEMOD_DMA_BUFFER_SIZE;
-             }
-             samples += 2;
-             Handle14443UartBit(1);
-             Handle14443UartBit(1);
-             if(Handle14443SamplesDemod(ci, cq)) {
-                 gotFrame = 1;
-             }
-         }
-         if(samples > 2000) {
-             break;
-         }
-     }
-     AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
-     if (!quiet) Dbprintf("%x %x %x", max, gotFrame, Demod.len);
+       int max = 0;
+       int gotFrame = FALSE;
+       int lastRxCounter, ci, cq, samples = 0;
+       // Allocate memory from BigBuf for some buffers
+       // free all previous allocations first
+       BigBuf_free();
+       
+       // The command (reader -> tag) that we're receiving.
+       uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
+       
+       // The response (tag -> reader) that we're receiving.
+       uint8_t *receivedResponse = BigBuf_malloc(MAX_FRAME_SIZE);
+       
+       // The DMA buffer, used to stream samples from the FPGA
+       uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
+       // Set up the demodulator for tag -> reader responses.
+       DemodInit(receivedResponse);
+       // Set up the demodulator for the reader -> tag commands
+       UartInit(receivedCmd);
+       // Setup and start DMA.
+       FpgaSetupSscDma(dmaBuf, DMA_BUFFER_SIZE);
+       uint8_t *upTo= dmaBuf;
+       lastRxCounter = DMA_BUFFER_SIZE;
+       // Signal field is ON with the appropriate LED:
+       if (weTx) LED_D_ON(); else LED_D_OFF();
+       // And put the FPGA in the appropriate mode
+       FpgaWriteConfWord(
+               FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ |
+               (weTx ? 0 : FPGA_HF_READER_RX_XCORR_SNOOP));
+       for(;;) {
+               int behindBy = lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR;
+               if(behindBy > max) max = behindBy;
+               while(((lastRxCounter-AT91C_BASE_PDC_SSC->PDC_RCR) & (DMA_BUFFER_SIZE-1))
+                                       > 2)
+               {
+                       ci = upTo[0];
+                       cq = upTo[1];
+                       upTo += 2;
+                       if(upTo - dmaBuf > DMA_BUFFER_SIZE) {
+                               upTo -= DMA_BUFFER_SIZE;
+                               AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo;
+                               AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
+                       }
+                       lastRxCounter -= 2;
+                       if(lastRxCounter <= 0) {
+                               lastRxCounter += DMA_BUFFER_SIZE;
+                       }
+                       samples += 2;
+                       Handle14443UartBit(1);
+                       Handle14443UartBit(1);
+                       if(Handle14443SamplesDemod(ci, cq)) {
+                               gotFrame = 1;
+                       }
+               }
+               if(samples > 2000) {
+                       break;
+               }
+       }
+       AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
+       if (!quiet) Dbprintf("%x %x %x", max, gotFrame, Demod.len);
+       //Tracing
+       if (tracing && Demod.len > 0) {
+               uint8_t parity[MAX_PARITY_SIZE];
+               GetParity(Demod.output , Demod.len, parity);
+               LogTrace(Demod.output,Demod.len, 0, 0, parity, FALSE);
+       }
  }
  
  //-----------------------------------------------------------------------------
  //-----------------------------------------------------------------------------
  /*static void GetSamplesFor14443(int weTx, int n)
  {
-     uint8_t *dest = (uint8_t *)BigBuf;
-     int c;
-     FpgaWriteConfWord(
-       FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ |
-       (weTx ? 0 : FPGA_HF_READER_RX_XCORR_SNOOP));
-     c = 0;
-     for(;;) {
-         if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
-             AT91C_BASE_SSC->SSC_THR = 0x43;
-         }
-         if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
-             int8_t b;
-             b = (int8_t)AT91C_BASE_SSC->SSC_RHR;
-             dest[c++] = (uint8_t)b;
-             if(c >= n) {
-                 break;
-             }
-         }
-     }
+       uint8_t *dest = (uint8_t *)BigBuf;
+       int c;
+       FpgaWriteConfWord(
+               FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ |
+               (weTx ? 0 : FPGA_HF_READER_RX_XCORR_SNOOP));
+       c = 0;
+       for(;;) {
+               if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
+                       AT91C_BASE_SSC->SSC_THR = 0x43;
+               }
+               if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
+                       int8_t b;
+                       b = (int8_t)AT91C_BASE_SSC->SSC_RHR;
+                       dest[c++] = (uint8_t)b;
+                       if(c >= n) {
+                               break;
+                       }
+               }
+       }
  }*/
  
  //-----------------------------------------------------------------------------
  //-----------------------------------------------------------------------------
  static void TransmitFor14443(void)
  {
-     int c;
+       int c;
  
-     FpgaSetupSsc();
+       FpgaSetupSsc();
  
-     while(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
-         AT91C_BASE_SSC->SSC_THR = 0xff;
-     }
+       while(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
+               AT91C_BASE_SSC->SSC_THR = 0xff;
+       }
  
-     // Signal field is ON with the appropriate Red LED
+       // Signal field is ON with the appropriate Red LED
        LED_D_ON();
        // Signal we are transmitting with the Green LED
        LED_B_ON();
        FpgaWriteConfWord(
-       FPGA_MAJOR_MODE_HF_READER_TX | FPGA_HF_READER_TX_SHALLOW_MOD);
-     for(c = 0; c < 10;) {
-         if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
-             AT91C_BASE_SSC->SSC_THR = 0xff;
-             c++;
-         }
-         if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
-             volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR;
-             (void)r;
-         }
-         WDT_HIT();
-     }
-     c = 0;
-     for(;;) {
-         if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
-             AT91C_BASE_SSC->SSC_THR = ToSend[c];
-             c++;
-             if(c >= ToSendMax) {
-                 break;
-             }
-         }
-         if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
-             volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR;
-             (void)r;
-         }
-         WDT_HIT();
-     }
-     LED_B_OFF(); // Finished sending
+               FPGA_MAJOR_MODE_HF_READER_TX | FPGA_HF_READER_TX_SHALLOW_MOD);
+       for(c = 0; c < 10;) {
+               if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
+                       AT91C_BASE_SSC->SSC_THR = 0xff;
+                       c++;
+               }
+               if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
+                       volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR;
+                       (void)r;
+               }
+               WDT_HIT();
+       }
+       c = 0;
+       for(;;) {
+               if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
+                       AT91C_BASE_SSC->SSC_THR = ToSend[c];
+                       c++;
+                       if(c >= ToSendMax) {
+                               break;
+                       }
+               }
+               if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
+                       volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR;
+                       (void)r;
+               }
+               WDT_HIT();
+       }
+       LED_B_OFF(); // Finished sending
  }
  
  //-----------------------------------------------------------------------------
  //-----------------------------------------------------------------------------
  static void CodeIso14443bAsReader(const uint8_t *cmd, int len)
  {
-     int i, j;
-     uint8_t b;
-     ToSendReset();
-     // Establish initial reference level
-     for(i = 0; i < 40; i++) {
-         ToSendStuffBit(1);
-     }
-     // Send SOF
-     for(i = 0; i < 10; i++) {
-         ToSendStuffBit(0);
-     }
-     for(i = 0; i < len; i++) {
-         // Stop bits/EGT
-         ToSendStuffBit(1);
-         ToSendStuffBit(1);
-         // Start bit
-         ToSendStuffBit(0);
-         // Data bits
-         b = cmd[i];
-         for(j = 0; j < 8; j++) {
-             if(b & 1) {
-                 ToSendStuffBit(1);
-             } else {
-                 ToSendStuffBit(0);
-             }
-             b >>= 1;
-         }
-     }
-     // Send EOF
-     ToSendStuffBit(1);
-     for(i = 0; i < 10; i++) {
-         ToSendStuffBit(0);
-     }
-     for(i = 0; i < 8; i++) {
-         ToSendStuffBit(1);
-     }
-     // And then a little more, to make sure that the last character makes
-     // it out before we switch to rx mode.
-     for(i = 0; i < 24; i++) {
-         ToSendStuffBit(1);
-     }
-     // Convert from last character reference to length
-     ToSendMax++;
+       int i, j;
+       uint8_t b;
+       ToSendReset();
+       // Establish initial reference level
+       for(i = 0; i < 40; i++) {
+               ToSendStuffBit(1);
+       }
+       // Send SOF
+       for(i = 0; i < 10; i++) {
+               ToSendStuffBit(0);
+       }
+       for(i = 0; i < len; i++) {
+               // Stop bits/EGT
+               ToSendStuffBit(1);
+               ToSendStuffBit(1);
+               // Start bit
+               ToSendStuffBit(0);
+               // Data bits
+               b = cmd[i];
+               for(j = 0; j < 8; j++) {
+                       if(b & 1) {
+                               ToSendStuffBit(1);
+                       } else {
+                               ToSendStuffBit(0);
+                       }
+                       b >>= 1;
+               }
+       }
+       // Send EOF
+       ToSendStuffBit(1);
+       for(i = 0; i < 10; i++) {
+               ToSendStuffBit(0);
+       }
+       for(i = 0; i < 8; i++) {
+               ToSendStuffBit(1);
+       }
+       // And then a little more, to make sure that the last character makes
+       // it out before we switch to rx mode.
+       for(i = 0; i < 24; i++) {
+               ToSendStuffBit(1);
+       }
+       // Convert from last character reference to length
+       ToSendMax++;
  }
  
  //-----------------------------------------------------------------------------
  //-----------------------------------------------------------------------------
  void AcquireRawAdcSamplesIso14443(uint32_t parameter)
  {
-     uint8_t cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 };
+       uint8_t cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 };
  
-     SendRawCommand14443B(sizeof(cmd1),1,1,cmd1);
+       SendRawCommand14443B(sizeof(cmd1),1,1,cmd1);
+ }
+ /**
+   Convenience function to encode, transmit and trace iso 14443b comms
+   **/
+ static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len)
+ {
+       CodeIso14443bAsReader(cmd, len);
+       TransmitFor14443();
+       if (tracing) {
+               uint8_t parity[MAX_PARITY_SIZE];
+               GetParity(cmd, len, parity);
+               LogTrace(cmd,len, 0, 0, parity, TRUE);
+       }
  }
  
  //-----------------------------------------------------------------------------
  //-----------------------------------------------------------------------------
  void ReadSTMemoryIso14443(uint32_t dwLast)
  {
-     uint8_t i = 0x00;
-     FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
-     // Make sure that we start from off, since the tags are stateful;
-     // confusing things will happen if we don't reset them between reads.
-     LED_D_OFF();
-     FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-     SpinDelay(200);
-     SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
-     FpgaSetupSsc();
-     // Now give it time to spin up.
-     // Signal field is on with the appropriate LED
-     LED_D_ON();
-     FpgaWriteConfWord(
-       FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ);
-     SpinDelay(200);
-     // First command: wake up the tag using the INITIATE command
-     uint8_t cmd1[] = { 0x06, 0x00, 0x97, 0x5b};
-     CodeIso14443bAsReader(cmd1, sizeof(cmd1));
-     TransmitFor14443();
+       clear_trace();
+       set_tracing(TRUE);
+       uint8_t i = 0x00;
+       FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
+       // Make sure that we start from off, since the tags are stateful;
+       // confusing things will happen if we don't reset them between reads.
+       LED_D_OFF();
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+       SpinDelay(200);
+       SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
+       FpgaSetupSsc();
+       // Now give it time to spin up.
+       // Signal field is on with the appropriate LED
+       LED_D_ON();
+       FpgaWriteConfWord(
+               FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ);
+       SpinDelay(200);
+       // First command: wake up the tag using the INITIATE command
+       uint8_t cmd1[] = { 0x06, 0x00, 0x97, 0x5b};
+       CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1));
  //    LED_A_ON();
-     GetSamplesFor14443Demod(TRUE, 2000,TRUE);
+       GetSamplesFor14443Demod(TRUE, 2000,TRUE);
  //    LED_A_OFF();
  
-     if (Demod.len == 0) {
+       if (Demod.len == 0) {
        DbpString("No response from tag");
        return;
-     } else {
+       } else {
        Dbprintf("Randomly generated UID from tag (+ 2 byte CRC): %x %x %x",
                Demod.output[0], Demod.output[1],Demod.output[2]);
-     }
-     // There is a response, SELECT the uid
-     DbpString("Now SELECT tag:");
-     cmd1[0] = 0x0E; // 0x0E is SELECT
-     cmd1[1] = Demod.output[0];
-     ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]);
-     CodeIso14443bAsReader(cmd1, sizeof(cmd1));
-     TransmitFor14443();
+       }
+       // There is a response, SELECT the uid
+       DbpString("Now SELECT tag:");
+       cmd1[0] = 0x0E; // 0x0E is SELECT
+       cmd1[1] = Demod.output[0];
+       ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]);
+       CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1));
  //    LED_A_ON();
-     GetSamplesFor14443Demod(TRUE, 2000,TRUE);
+       GetSamplesFor14443Demod(TRUE, 2000,TRUE);
  //    LED_A_OFF();
-     if (Demod.len != 3) {
+       if (Demod.len != 3) {
        Dbprintf("Expected 3 bytes from tag, got %d", Demod.len);
        return;
-     }
-     // Check the CRC of the answer:
-     ComputeCrc14443(CRC_14443_B, Demod.output, 1 , &cmd1[2], &cmd1[3]);
-     if(cmd1[2] != Demod.output[1] || cmd1[3] != Demod.output[2]) {
+       }
+       // Check the CRC of the answer:
+       ComputeCrc14443(CRC_14443_B, Demod.output, 1 , &cmd1[2], &cmd1[3]);
+       if(cmd1[2] != Demod.output[1] || cmd1[3] != Demod.output[2]) {
        DbpString("CRC Error reading select response.");
        return;
-     }
-     // Check response from the tag: should be the same UID as the command we just sent:
-     if (cmd1[1] != Demod.output[0]) {
+       }
+       // Check response from the tag: should be the same UID as the command we just sent:
+       if (cmd1[1] != Demod.output[0]) {
        Dbprintf("Bad response to SELECT from Tag, aborting: %x %x", cmd1[1], Demod.output[0]);
        return;
-     }
-     // Tag is now selected,
-     // First get the tag's UID:
-     cmd1[0] = 0x0B;
-     ComputeCrc14443(CRC_14443_B, cmd1, 1 , &cmd1[1], &cmd1[2]);
-     CodeIso14443bAsReader(cmd1, 3); // Only first three bytes for this one
-     TransmitFor14443();
+       }
+       // Tag is now selected,
+       // First get the tag's UID:
+       cmd1[0] = 0x0B;
+       ComputeCrc14443(CRC_14443_B, cmd1, 1 , &cmd1[1], &cmd1[2]);
+       CodeAndTransmit14443bAsReader(cmd1, 3); // Only first three bytes for this one
  //    LED_A_ON();
-     GetSamplesFor14443Demod(TRUE, 2000,TRUE);
+       GetSamplesFor14443Demod(TRUE, 2000,TRUE);
  //    LED_A_OFF();
-     if (Demod.len != 10) {
+       if (Demod.len != 10) {
        Dbprintf("Expected 10 bytes from tag, got %d", Demod.len);
        return;
-     }
-     // The check the CRC of the answer (use cmd1 as temporary variable):
-     ComputeCrc14443(CRC_14443_B, Demod.output, 8, &cmd1[2], &cmd1[3]);
-            if(cmd1[2] != Demod.output[8] || cmd1[3] != Demod.output[9]) {
+       }
+       // The check the CRC of the answer (use cmd1 as temporary variable):
+       ComputeCrc14443(CRC_14443_B, Demod.output, 8, &cmd1[2], &cmd1[3]);
+                  if(cmd1[2] != Demod.output[8] || cmd1[3] != Demod.output[9]) {
        Dbprintf("CRC Error reading block! - Below: expected, got %x %x",
                (cmd1[2]<<8)+cmd1[3], (Demod.output[8]<<8)+Demod.output[9]);
        // Do not return;, let's go on... (we should retry, maybe ?)
-     }
-     Dbprintf("Tag UID (64 bits): %08x %08x",
+       }
+       Dbprintf("Tag UID (64 bits): %08x %08x",
        (Demod.output[7]<<24) + (Demod.output[6]<<16) + (Demod.output[5]<<8) + Demod.output[4],
        (Demod.output[3]<<24) + (Demod.output[2]<<16) + (Demod.output[1]<<8) + Demod.output[0]);
  
-     // Now loop to read all 16 blocks, address from 0 to last block
-     Dbprintf("Tag memory dump, block 0 to %d",dwLast);
-     cmd1[0] = 0x08;
-     i = 0x00;
-     dwLast++;
-     for (;;) {
-            if (i == dwLast) {
-                   DbpString("System area block (0xff):");
-                   i = 0xff;
-           }
-           cmd1[1] = i;
-           ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]);
-           CodeIso14443bAsReader(cmd1, sizeof(cmd1));
-           TransmitFor14443();
+       // Now loop to read all 16 blocks, address from 0 to last block
+       Dbprintf("Tag memory dump, block 0 to %d",dwLast);
+       cmd1[0] = 0x08;
+       i = 0x00;
+       dwLast++;
+       for (;;) {
+                  if (i == dwLast) {
+                       DbpString("System area block (0xff):");
+                       i = 0xff;
+               }
+               cmd1[1] = i;
+               ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]);
+               CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1));
  //        LED_A_ON();
-           GetSamplesFor14443Demod(TRUE, 2000,TRUE);
+               GetSamplesFor14443Demod(TRUE, 2000,TRUE);
  //        LED_A_OFF();
-           if (Demod.len != 6) { // Check if we got an answer from the tag
+               if (Demod.len != 6) { // Check if we got an answer from the tag
                DbpString("Expected 6 bytes from tag, got less...");
                return;
-           }
-           // The check the CRC of the answer (use cmd1 as temporary variable):
-           ComputeCrc14443(CRC_14443_B, Demod.output, 4, &cmd1[2], &cmd1[3]);
-             if(cmd1[2] != Demod.output[4] || cmd1[3] != Demod.output[5]) {
+               }
+               // The check the CRC of the answer (use cmd1 as temporary variable):
+               ComputeCrc14443(CRC_14443_B, Demod.output, 4, &cmd1[2], &cmd1[3]);
+                       if(cmd1[2] != Demod.output[4] || cmd1[3] != Demod.output[5]) {
                Dbprintf("CRC Error reading block! - Below: expected, got %x %x",
                        (cmd1[2]<<8)+cmd1[3], (Demod.output[4]<<8)+Demod.output[5]);
                // Do not return;, let's go on... (we should retry, maybe ?)
-           }
-           // Now print out the memory location:
-           Dbprintf("Address=%x, Contents=%x, CRC=%x", i,
+               }
+               // Now print out the memory location:
+               Dbprintf("Address=%x, Contents=%x, CRC=%x", i,
                (Demod.output[3]<<24) + (Demod.output[2]<<16) + (Demod.output[1]<<8) + Demod.output[0],
                (Demod.output[4]<<8)+Demod.output[5]);
-           if (i == 0xff) {
+               if (i == 0xff) {
                break;
-           }
-           i++;
-     }
+               }
+               i++;
+       }
  }
  
  
   */
  void RAMFUNC SnoopIso14443(void)
  {
-     // We won't start recording the frames that we acquire until we trigger;
-     // a good trigger condition to get started is probably when we see a
-     // response from the tag.
-     int triggered = TRUE;
+       // We won't start recording the frames that we acquire until we trigger;
+       // a good trigger condition to get started is probably when we see a
+       // response from the tag.
+       int triggered = TRUE;
  
-     FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
+       FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
        BigBuf_free();
-     // The command (reader -> tag) that we're working on receiving.
-     uint8_t *receivedCmd = BigBuf_malloc(READER_TAG_BUFFER_SIZE);
-     // The response (tag -> reader) that we're working on receiving.
-     uint8_t *receivedResponse = BigBuf_malloc(TAG_READER_BUFFER_SIZE);
-     // As we receive stuff, we copy it from receivedCmd or receivedResponse
-     // into trace, along with its length and other annotations.
-     uint8_t *trace = BigBuf_get_addr();
-     traceLen = 0;
-     // The DMA buffer, used to stream samples from the FPGA.
-     uint8_t *dmaBuf = BigBuf_malloc(DEMOD_DMA_BUFFER_SIZE);
-     int lastRxCounter;
-     uint8_t *upTo;
-     int ci, cq;
-     int maxBehindBy = 0;
-     // Count of samples received so far, so that we can include timing
-     // information in the trace buffer.
-     int samples = 0;
-     // Initialize the trace buffer
-     memset(trace, 0x44, BigBuf_max_traceLen());
-     // Set up the demodulator for tag -> reader responses.
-     Demod.output = receivedResponse;
-     Demod.len = 0;
-     Demod.state = DEMOD_UNSYNCD;
-     // And the reader -> tag commands
-     memset(&Uart, 0, sizeof(Uart));
-     Uart.output = receivedCmd;
-     Uart.byteCntMax = 100;
-     Uart.state = STATE_UNSYNCD;
-     // Print some debug information about the buffer sizes
-     Dbprintf("Snooping buffers initialized:");
-     Dbprintf("  Trace: %i bytes", BigBuf_max_traceLen());
-     Dbprintf("  Reader -> tag: %i bytes", READER_TAG_BUFFER_SIZE);
-     Dbprintf("  tag -> Reader: %i bytes", TAG_READER_BUFFER_SIZE);
-     Dbprintf("  DMA: %i bytes", DEMOD_DMA_BUFFER_SIZE);
-     // And put the FPGA in the appropriate mode
-     // Signal field is off with the appropriate LED
-     LED_D_OFF();
-     FpgaWriteConfWord(
-       FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ |
-       FPGA_HF_READER_RX_XCORR_SNOOP);
-     SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
-     // Setup for the DMA.
-     FpgaSetupSsc();
-     upTo = dmaBuf;
-     lastRxCounter = DEMOD_DMA_BUFFER_SIZE;
-     FpgaSetupSscDma((uint8_t *)dmaBuf, DEMOD_DMA_BUFFER_SIZE);
-               
-     LED_A_ON();
-               
-     // And now we loop, receiving samples.
-     for(;;) {
-       int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) &
-                                 (DEMOD_DMA_BUFFER_SIZE-1);
-         if(behindBy > maxBehindBy) {
-             maxBehindBy = behindBy;
-             if(behindBy > (9*DEMOD_DMA_BUFFER_SIZE/10)) { // TODO: understand whether we can increase/decrease as we want or not?
-                 Dbprintf("blew circular buffer! behindBy=0x%x", behindBy);
-                 goto done;
-             }
-         }
-         if(behindBy < 2) continue;
-         ci = upTo[0];
-         cq = upTo[1];
-         upTo += 2;
-         lastRxCounter -= 2;
-         if(upTo - dmaBuf > DEMOD_DMA_BUFFER_SIZE) {
-             upTo -= DEMOD_DMA_BUFFER_SIZE;
-             lastRxCounter += DEMOD_DMA_BUFFER_SIZE;
-             AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo;
-             AT91C_BASE_PDC_SSC->PDC_RNCR = DEMOD_DMA_BUFFER_SIZE;
-         }
-         samples += 2;
- #define HANDLE_BIT_IF_BODY \
-             if(triggered) { \
-                 trace[traceLen++] = ((samples >>  0) & 0xff); \
-                 trace[traceLen++] = ((samples >>  8) & 0xff); \
-                 trace[traceLen++] = ((samples >> 16) & 0xff); \
-                 trace[traceLen++] = ((samples >> 24) & 0xff); \
-                 trace[traceLen++] = 0; \
-                 trace[traceLen++] = 0; \
-                 trace[traceLen++] = 0; \
-                 trace[traceLen++] = 0; \
-                 trace[traceLen++] = Uart.byteCnt; \
-                 memcpy(trace+traceLen, receivedCmd, Uart.byteCnt); \
-                 traceLen += Uart.byteCnt; \
-                 if(traceLen > 1000) break; \
-             } \
-             /* And ready to receive another command. */ \
-             memset(&Uart, 0, sizeof(Uart)); \
-             Uart.output = receivedCmd; \
-             Uart.byteCntMax = 100; \
-             Uart.state = STATE_UNSYNCD; \
-             /* And also reset the demod code, which might have been */ \
-             /* false-triggered by the commands from the reader. */ \
-             memset(&Demod, 0, sizeof(Demod)); \
-             Demod.output = receivedResponse; \
-             Demod.state = DEMOD_UNSYNCD; \
-         if(Handle14443UartBit(ci & 1)) {
-             HANDLE_BIT_IF_BODY
-         }
-         if(Handle14443UartBit(cq & 1)) {
-             HANDLE_BIT_IF_BODY
-         }
-         if(Handle14443SamplesDemod(ci, cq)) {
-             // timestamp, as a count of samples
-             trace[traceLen++] = ((samples >>  0) & 0xff);
-             trace[traceLen++] = ((samples >>  8) & 0xff);
-             trace[traceLen++] = ((samples >> 16) & 0xff);
-             trace[traceLen++] = 0x80 | ((samples >> 24) & 0xff);
-             // correlation metric (~signal strength estimate)
-             if(Demod.metricN != 0) {
-                 Demod.metric /= Demod.metricN;
-             }
-             trace[traceLen++] = ((Demod.metric >>  0) & 0xff);
-             trace[traceLen++] = ((Demod.metric >>  8) & 0xff);
-             trace[traceLen++] = ((Demod.metric >> 16) & 0xff);
-             trace[traceLen++] = ((Demod.metric >> 24) & 0xff);
-             // length
-             trace[traceLen++] = Demod.len;
-             memcpy(trace+traceLen, receivedResponse, Demod.len);
-             traceLen += Demod.len;
-             if(traceLen > BigBuf_max_traceLen()) {
-                               DbpString("Reached trace limit");
-                               goto done;
-                       }
  
-             triggered = TRUE;
-             LED_A_OFF();
-             LED_B_ON();
+       clear_trace();
+       set_tracing(TRUE);
+       // The DMA buffer, used to stream samples from the FPGA
+       uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
+       int lastRxCounter;
+       uint8_t *upTo;
+       int ci, cq;
+       int maxBehindBy = 0;
+       // Count of samples received so far, so that we can include timing
+       // information in the trace buffer.
+       int samples = 0;
  
-             // And ready to receive another response.
-             memset(&Demod, 0, sizeof(Demod));
-             Demod.output = receivedResponse;
-             Demod.state = DEMOD_UNSYNCD;
-         }
-       WDT_HIT();
+       DemodInit(BigBuf_malloc(MAX_FRAME_SIZE));
+       UartInit(BigBuf_malloc(MAX_FRAME_SIZE));
  
-         if(BUTTON_PRESS()) {
-             DbpString("cancelled");
-             goto done;
-         }
-     }
+       // Print some debug information about the buffer sizes
+       Dbprintf("Snooping buffers initialized:");
+       Dbprintf("  Trace: %i bytes", BigBuf_max_traceLen());
+       Dbprintf("  Reader -> tag: %i bytes", MAX_FRAME_SIZE);
+       Dbprintf("  tag -> Reader: %i bytes", MAX_FRAME_SIZE);
+       Dbprintf("  DMA: %i bytes", DMA_BUFFER_SIZE);
  
- done:
+       // Signal field is off with the appropriate LED
+       LED_D_OFF();
+       // And put the FPGA in the appropriate mode
+       FpgaWriteConfWord(
+               FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ |
+               FPGA_HF_READER_RX_XCORR_SNOOP);
+       SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
+       // Setup for the DMA.
+       FpgaSetupSsc();
+       upTo = dmaBuf;
+       lastRxCounter = DMA_BUFFER_SIZE;
+       FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE);
+       uint8_t parity[MAX_PARITY_SIZE];
+       LED_A_ON();
+               
+       // And now we loop, receiving samples.
+       for(;;) {
+               int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) &
+                                                               (DMA_BUFFER_SIZE-1);
+               if(behindBy > maxBehindBy) {
+                       maxBehindBy = behindBy;
+                       if(behindBy > (9*DMA_BUFFER_SIZE/10)) { // TODO: understand whether we can increase/decrease as we want or not?
+                               Dbprintf("blew circular buffer! behindBy=0x%x", behindBy);
+                               break;
+                       }
+               }
+               if(behindBy < 2) continue;
+               ci = upTo[0];
+               cq = upTo[1];
+               upTo += 2;
+               lastRxCounter -= 2;
+               if(upTo - dmaBuf > DMA_BUFFER_SIZE) {
+                       upTo -= DMA_BUFFER_SIZE;
+                       lastRxCounter += DMA_BUFFER_SIZE;
+                       AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo;
+                       AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
+               }
+               samples += 2;
+               if(Handle14443UartBit(ci & 1)) {
+                       if(triggered && tracing) {
+                               GetParity(Uart.output, Uart.byteCnt, parity);
+                               LogTrace(Uart.output,Uart.byteCnt,samples, samples,parity,TRUE);
+                       }
+                       if(Uart.byteCnt==0) Dbprintf("[1] Error, Uart.byteCnt==0, Uart.bitCnt=%d", Uart.bitCnt);
+                       /* And ready to receive another command. */
+                       UartReset();
+                       /* And also reset the demod code, which might have been */
+                       /* false-triggered by the commands from the reader. */
+                       DemodReset();
+               }
+               if(Handle14443UartBit(cq & 1)) {
+                       if(triggered && tracing) {
+                               GetParity(Uart.output, Uart.byteCnt, parity);
+                               LogTrace(Uart.output,Uart.byteCnt,samples, samples,parity,TRUE);
+                       }
+                       if(Uart.byteCnt==0) Dbprintf("[2] Error, Uart.byteCnt==0, Uart.bitCnt=%d", Uart.bitCnt);
+                       /* And ready to receive another command. */
+                       UartReset();
+                       /* And also reset the demod code, which might have been */
+                       /* false-triggered by the commands from the reader. */
+                       DemodReset();
+               }
+               if(Handle14443SamplesDemod(ci, cq)) {
+                       //Use samples as a time measurement
+                       if(tracing)
+                       {
+                               uint8_t parity[MAX_PARITY_SIZE];
+                               GetParity(Demod.output, Demod.len, parity);
+                               LogTrace(Demod.output,Demod.len,samples, samples,parity,FALSE);
+                       }
+                       triggered = TRUE;
+                       LED_A_OFF();
+                       LED_B_ON();
+                       // And ready to receive another response.
+                       DemodReset();
+               }
+               WDT_HIT();
+               if(!tracing) {
+                       DbpString("Reached trace limit");
+                       break;
+               }
+               if(BUTTON_PRESS()) {
+                       DbpString("cancelled");
+                       break;
+               }
+       }
+       FpgaDisableSscDma();
        LED_A_OFF();
        LED_B_OFF();
        LED_C_OFF();
        Dbprintf("  Uart State: %x", Uart.state);
        Dbprintf("  Uart ByteCnt: %i", Uart.byteCnt);
        Dbprintf("  Uart ByteCntMax: %i", Uart.byteCntMax);
-       Dbprintf("  Trace length: %i", traceLen);
+       Dbprintf("  Trace length: %i", BigBuf_get_traceLen());
  }
  
  /*
  
  void SendRawCommand14443B(uint32_t datalen, uint32_t recv,uint8_t powerfield, uint8_t data[])
  {
-     FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
-     if(!powerfield)
-     {
-         // Make sure that we start from off, since the tags are stateful;
-         // confusing things will happen if we don't reset them between reads.
-         FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-         LED_D_OFF();
-         SpinDelay(200);
-     }
-     if(!GETBIT(GPIO_LED_D))
-     {
-         SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
-         FpgaSetupSsc();
-         // Now give it time to spin up.
-         // Signal field is on with the appropriate LED
-         LED_D_ON();
-         FpgaWriteConfWord(
-             FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ);
-         SpinDelay(200);
-     }
-     CodeIso14443bAsReader(data, datalen);
-     TransmitFor14443();
-     if(recv)
-     {
-         uint16_t iLen = MIN(Demod.len,USB_CMD_DATA_SIZE);
-         GetSamplesFor14443Demod(TRUE, 2000, TRUE);
-         cmd_send(CMD_ACK,iLen,0,0,Demod.output,iLen);
-     }
-     if(!powerfield)
-     {
-         FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-         LED_D_OFF();
-     }
+       FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
+       if(!powerfield)
+       {
+               // Make sure that we start from off, since the tags are stateful;
+               // confusing things will happen if we don't reset them between reads.
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+               LED_D_OFF();
+               SpinDelay(200);
+       }
+       if(!GETBIT(GPIO_LED_D))
+       {
+               SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
+               FpgaSetupSsc();
+               // Now give it time to spin up.
+               // Signal field is on with the appropriate LED
+               LED_D_ON();
+               FpgaWriteConfWord(
+                       FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ);
+               SpinDelay(200);
+       }
+       CodeAndTransmit14443bAsReader(data, datalen);
+       if(recv)
+       {
+               uint16_t iLen = MIN(Demod.len,USB_CMD_DATA_SIZE);
+               GetSamplesFor14443Demod(TRUE, 2000, TRUE);
+               cmd_send(CMD_ACK,iLen,0,0,Demod.output,iLen);
+       }
+       if(!powerfield)
+       {
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+               LED_D_OFF();
+       }
  }
  
diff --combined armsrc/iso14443a.h
index 026049351319cc476c33b4b8e73d6db830618b0d,c37103886e94b4a2175b9c32ee8325069142db12..7fcad0e06379e7e6232acd08ed7011d6310e2af8
@@@ -12,8 -12,7 +12,8 @@@
  
  #ifndef __ISO14443A_H
  #define __ISO14443A_H
 -#include "common.h"
 +#include "../include/common.h"
 +#include "../include/mifare.h"
  #include "mifaresniff.h"
  
  typedef struct {
@@@ -88,7 -87,4 +88,4 @@@ extern int iso14443a_select_card(uint8_
  extern void iso14a_set_trigger(bool enable);
  extern void iso14a_set_timeout(uint32_t timeout);
  
- extern void iso14a_clear_trace();
- extern void iso14a_set_tracing(bool enable);
  #endif /* __ISO14443A_H */
diff --combined armsrc/util.c
index 0558fb947024e2095d3ad57ad566fb88ba4a506b,74fba94b764db748cf6a377ba23b96f5d06bc304..c3d4d2c621d3d3252dd06415de5f6084204af37e
@@@ -8,10 -8,11 +8,11 @@@
  // Utility functions used in many places, not specific to any piece of code.
  //-----------------------------------------------------------------------------
  
 -#include "proxmark3.h"
 +#include "../include/proxmark3.h"
  #include "util.h"
  #include "string.h"
  #include "apps.h"
+ #include "BigBuf.h"
  
  
  
@@@ -34,7 -35,7 +35,7 @@@ void print_result(char *name, uint8_t *
  }
  
  size_t nbytes(size_t nbits) {
-       return (nbits/8)+((nbits%8)>0);
+       return (nbits >> 3)+((nbits % 8) > 0);
  }
  
  uint32_t SwapBits(uint32_t value, int nrbits) {
@@@ -428,4 -429,3 +429,3 @@@ uint32_t RAMFUNC GetCountSspClk()
        }
  }
  
diff --combined client/cmdlft55xx.c
index c023d57f6a06467bc9ba16e47f303eeda00994b8,a719c7ad7a56e4a6216e910aa4d28cad3069007d..b6b5ea444e49981666a42a9f311671baa7f82f92
  #include "proxmark3.h"\r
  #include "ui.h"\r
  #include "graph.h"\r
 +#include "cmdmain.h"\r
  #include "cmdparser.h"\r
  #include "cmddata.h"\r
  #include "cmdlf.h"\r
  #include "cmdlft55xx.h"\r
 +#include "util.h"\r
 +#include "data.h"\r
 +#include "lfdemod.h"\r
  \r
\r
 -static int CmdHelp(const char *Cmd);\r
 +#define LF_TRACE_BUFF_SIZE 20000 // 32 x 32 x 10  (32 bit times numofblock (7), times clock skip..)\r
 +#define LF_BITSSTREAM_LEN 1000 // more then 1000 bits shouldn't happend..  8block * 4 bytes * 8bits = \r
- static int CmdHelp(const char *Cmd);\r
 +\r
- // int CmdReadBlk(const char *Cmd)\r
- // {\r
-       // int block = -1;\r
-       // sscanf(Cmd, "%d", &block);\r
\r
-       // if ((block > 7) | (block < 0)) {\r
-               // PrintAndLog("Block must be between 0 and 7");\r
-               // return 1;\r
-       // }    \r
\r
-       // UsbCommand c;\r
-       // c.cmd = CMD_T55XX_READ_BLOCK;\r
-       // c.d.asBytes[0] = 0x00;\r
-       // c.arg[0] = 0;\r
-       // c.arg[1] = block;\r
-       // c.arg[2] = 0;\r
-       // SendCommand(&c);\r
-       // WaitForResponse(CMD_ACK, NULL);\r
-       \r
-       // uint8_t data[LF_TRACE_BUFF_SIZE] = {0x00};\r
-       \r
-       // GetFromBigBuf(data,LF_TRACE_BUFF_SIZE,0);  //3560 -- should be offset..\r
-       // WaitForResponseTimeout(CMD_ACK,NULL, 1500);\r
\r
-       // for (int j = 0; j < LF_TRACE_BUFF_SIZE; j++) {\r
-               // GraphBuffer[j] = (int)data[j];\r
-       // }\r
-       // GraphTraceLen = LF_TRACE_BUFF_SIZE;\r
-       // ManchesterDemod(block);\r
-       // RepaintGraphWindow();\r
-   // return 0;\r
- // }\r
++int usage_t55xx_rd(){\r
++      PrintAndLog("Usage:  lf t55xx rd <block> <password>");\r
++    PrintAndLog("     <block>, block number to read. Between 0-7");\r
++    PrintAndLog("     <password>, OPTIONAL password (8 hex characters)");\r
++    PrintAndLog("");\r
++    PrintAndLog("    sample: lf t55xx rd 0           = try reading data from block 0");\r
++      PrintAndLog("          : lf t55xx rd 0 feedbeef  = try reading data from block 0 using password");\r
++      PrintAndLog("");\r
++      return 0;\r
++}\r
++int usage_t55xx_wr(){\r
++      PrintAndLog("Usage:  lf t55xx wr <block> <data> [password]");\r
++    PrintAndLog("     <block>, block number to read. Between 0-7");\r
++      PrintAndLog("     <data>,  4 bytes of data to write (8 hex characters)");\r
++    PrintAndLog("     [password], OPTIONAL password 4bytes (8 hex characters)");\r
++    PrintAndLog("");\r
++    PrintAndLog("    sample: lf t55xx wd 3 11223344  = try writing data 11223344 to block 3");\r
++      PrintAndLog("          : lf t55xx wd 3 11223344 feedbeef  = try writing data 11223344 to block 3 using password feedbeef");\r
++      PrintAndLog("");\r
++      return 0;\r
++}\r
++int usage_t55xx_trace() {\r
++      PrintAndLog("Usage:  lf t55xx trace  [graph buffer data]");\r
++      PrintAndLog("     [graph buffer data], if set, use Graphbuffer otherwise read data from tag.");\r
++      PrintAndLog("");\r
++      PrintAndLog("     sample: lf t55xx trace");\r
++      PrintAndLog("           : lf t55xx trace 1");\r
++      PrintAndLog("");\r
++      return 0;\r
++}\r
++int usage_t55xx_info() {\r
++      PrintAndLog("Usage:  lf t55xx info [graph buffer data]");\r
++      PrintAndLog("     [graph buffer data], if set, use Graphbuffer otherwise read data from tag.");\r
++      PrintAndLog("");\r
++      PrintAndLog("    sample: lf t55xx info");\r
++      PrintAndLog("          : lf t55xx info 1");\r
++      PrintAndLog("");\r
++      return 0;\r
++}\r
\r
++int usage_t55xx_dump(){\r
++      PrintAndLog("Usage:  lf t55xx dump <password>");\r
++    PrintAndLog("     <password>, OPTIONAL password 4bytes (8 hex characters)");\r
++      PrintAndLog("");\r
++      PrintAndLog("        sample: lf t55xx dump");\r
++      PrintAndLog("              : lf t55xx dump feedbeef");\r
++      PrintAndLog("");\r
++      return 0;\r
++}\r
++static int CmdHelp(const char *Cmd);\r
  \r
  int CmdReadBlk(const char *Cmd)\r
  {\r
 -  int Block = 8; //default to invalid block\r
 -  UsbCommand c;\r
 +      int invert = 0;\r
 +      int clk = 0;\r
 +      int block = -1;\r
++      int password = 0xFFFFFFFF; //default to blank Block 7\r
 +      int errCnt;\r
 +      size_t bitlen;\r
-       //int decodedBitlen;\r
++      int maxErr = 100;\r
++    uint8_t askAmp = 0;\r
 +      uint32_t blockData;\r
 +      uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0x00};\r
 +      \r
-       sscanf(Cmd, "%d", &block);\r
 +      \r
-       if ((block > 7) | (block < 0)) {\r
++      char cmdp = param_getchar(Cmd, 0);\r
++      if (cmdp == 'h' || cmdp == 'H') {\r
++              usage_t55xx_rd();\r
++              return 0;\r
++      }\r
\r
 -  sscanf(Cmd, "%d", &Block);\r
++      int res = sscanf(Cmd, "%d %x", &block, &password);\r
\r
 -  if (Block > 7) {\r
 -      PrintAndLog("Block must be between 0 and 7");\r
 -      return 1;\r
 -  }   \r
++      if ( res < 1 || res > 2 ){\r
++              usage_t55xx_rd();\r
++              return 1;\r
++      }\r
++      \r
++      if ((block < 0) | (block > 7)) {\r
 +              PrintAndLog("Block must be between 0 and 7");\r
 +              return 1;\r
++      }       \r
\r
 -  PrintAndLog("Reading block %d", Block);\r
++      UsbCommand c = {CMD_T55XX_READ_BLOCK, {0, block, 0}};\r
++      c.d.asBytes[0] = 0x0; \r
\r
 -  c.cmd = CMD_T55XX_READ_BLOCK;\r
 -  c.d.asBytes[0] = 0x0; //Normal mode\r
 -  c.arg[0] = 0;\r
 -  c.arg[1] = Block;\r
 -  c.arg[2] = 0;\r
 -  SendCommand(&c);\r
 -  return 0;\r
 -}\r
++      //Password mode\r
++      if ( res == 2 ) {\r
++              c.arg[2] = password;\r
++              c.d.asBytes[0] = 0x1; \r
 +      }\r
  \r
-       UsbCommand c = { CMD_T55XX_READ_BLOCK, { 0, block, 0 } };\r
 -int CmdReadBlkPWD(const char *Cmd)\r
 -{\r
 -  int Block = 8; //default to invalid block\r
 -  int Password = 0xFFFFFFFF; //default to blank Block 7\r
 -  UsbCommand c;\r
 +      SendCommand(&c);\r
 +      if ( !WaitForResponseTimeout(CMD_ACK,NULL,1500) ) {\r
 +              PrintAndLog("command execution time out");\r
 +              return 2;\r
 +      }\r
 +      \r
 +      CmdSamples("12000");\r
  \r
 -  sscanf(Cmd, "%d %x", &Block, &Password);\r
 +      bitlen = getFromGraphBuf(bits);\r
 +      \r
-       errCnt = askrawdemod(bits, &bitlen, &clk, &invert);\r
++      errCnt = askrawdemod(bits, &bitlen, &clk, &invert, maxErr, askAmp);\r
 +      \r
 +      //throw away static - allow 1 and -1 (in case of threshold command first)\r
 +      if ( errCnt == -1 || bitlen < 16 ){  \r
 +              PrintAndLog("no data found");\r
 +              if (g_debugMode) \r
 +                      PrintAndLog("errCnt: %d, bitlen: %d, clk: %d, invert: %d", errCnt, bitlen, clk, invert);\r
 +              return 3;\r
 +      }\r
 +      if (g_debugMode) \r
 +              PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d", clk, invert, bitlen);\r
  \r
 -  if (Block > 7) {\r
 -      PrintAndLog("Block must be between 0 and 7");\r
 -      return 1;\r
 -  }   \r
 +      //move bits back to DemodBuffer\r
 +      setDemodBuf(bits, bitlen, 0);\r
 +      printBitStream(bits,bitlen);\r
 +      \r
 +      // bits has the manchester encoded data.\r
 +      errCnt = manrawdecode(bits, &bitlen);   \r
 +      if ( errCnt == -1 || bitlen < 16 ){  \r
 +              PrintAndLog("no data found");\r
 +              if (g_debugMode) \r
 +                      PrintAndLog("errCnt: %d, bitlen: %d, clk: %d, invert: %d", errCnt, bitlen, clk, invert);\r
 +              return 4;\r
 +      }\r
  \r
 -  PrintAndLog("Reading block %d with password %08X", Block, Password);\r
 +      blockData = PackBits(0, 32, bits);\r
  \r
 -  c.cmd = CMD_T55XX_READ_BLOCK;\r
 -  c.d.asBytes[0] = 0x1; //Password mode\r
 -  c.arg[0] = 0;\r
 -  c.arg[1] = Block;\r
 -  c.arg[2] = Password;\r
 -  SendCommand(&c);\r
 -  return 0;\r
 +      if ( block < 0)\r
 +              PrintAndLog(" Decoded     : 0x%08X  %s", blockData, sprint_bin(bits,32) );\r
 +      else\r
 +              PrintAndLog(" Block %d    : 0x%08X  %s", block, blockData, sprint_bin(bits,32) );\r
 +      \r
 +      return 0;\r
  }\r
  \r
- int CmdReadBlkPWD(const char *Cmd)\r
+ int CmdWriteBlk(const char *Cmd)\r
  {\r
-       int Block = -1; //default to invalid block\r
-       int Password = 0xFFFFFFFF; //default to blank Block 7\r
\r
\r
-       sscanf(Cmd, "%d %x", &Block, &Password);\r
 -  int Block = 8; //default to invalid block\r
 -  int Data = 0xFFFFFFFF; //default to blank Block \r
 -  UsbCommand c;\r
++      int block = 8; //default to invalid block\r
++      int data = 0xFFFFFFFF; //default to blank Block \r
++      int password = 0xFFFFFFFF; //default to blank Block 7\r
++      \r
++      char cmdp = param_getchar(Cmd, 0);\r
++      if (cmdp == 'h' || cmdp == 'H') {\r
++              usage_t55xx_wr();\r
++              return 0;\r
++      }\r
++  \r
++      int res = sscanf(Cmd, "%d %x %x",&block, &data, &password);\r
++      \r
++      if ( res < 2 || res > 3) {\r
++              usage_t55xx_wr();\r
++              return 1;\r
++      }\r
  \r
-       if ((Block > 7) | (Block < 0)) {\r
 -  sscanf(Cmd, "%x %d", &Data, &Block);\r
++      if (block > 7) {\r
 +              PrintAndLog("Block must be between 0 and 7");\r
 +              return 1;\r
-       }       \r
\r
-       PrintAndLog("Reading page 0 block %d pwd %08X", Block, Password);\r
\r
-       UsbCommand c = {CMD_T55XX_READ_BLOCK, {0, Block, Password} };\r
-       c.d.asBytes[0] = 0x1; //Password mode\r
-       SendCommand(&c);\r
-       WaitForResponse(CMD_ACK, NULL);\r
-               \r
-       uint8_t data[LF_TRACE_BUFF_SIZE] = {0x00};\r
\r
-       GetFromBigBuf(data,LF_TRACE_BUFF_SIZE,0);\r
-       WaitForResponseTimeout(CMD_ACK,NULL, 1500);\r
\r
-       for (int j = 0; j < LF_TRACE_BUFF_SIZE; j++) {\r
-               GraphBuffer[j] = ((int)data[j]);\r
 +      }\r
-       GraphTraceLen = LF_TRACE_BUFF_SIZE;\r
-       ManchesterDemod(Block); \r
\r
-       RepaintGraphWindow();\r
-   return 0;\r
- }\r
\r
- int CmdWriteBlk(const char *Cmd)\r
- {\r
-   int Block = 8; //default to invalid block\r
-   int Data = 0xFFFFFFFF; //default to blank Block \r
\r
-       sscanf(Cmd, "%d %x", &Block, &Data);\r
\r
-   if (Block > 7) {\r
-       PrintAndLog("Block must be between 0 and 7");\r
-       return 1;\r
-   }   \r
\r
-       PrintAndLog("Writing block %d  data %08X", Block, Data);\r
\r
-       UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {Data, Block, 0}};\r
-   c.d.asBytes[0] = 0x0; //Normal mode\r
-   SendCommand(&c);\r
-   return 0;\r
- }\r
\r
- int CmdWriteBlkPWD(const char *Cmd)\r
- {\r
-   int Block = 8; //default to invalid block\r
-   int Data = 0xFFFFFFFF; //default to blank Block \r
-   int Password = 0xFFFFFFFF; //default to blank Block 7\r
\r
\r
-       sscanf(Cmd, "%d %x %x",&Block, &Data, &Password);\r
\r
-   if (Block > 7) {\r
-       PrintAndLog("Block must be between 0 and 7");\r
-       return 1;\r
-   }   \r
\r
-       PrintAndLog("Writing block %d  data %08X  password %08X", Block, Data, Password);\r
\r
-       UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {Data, Block, Password}};\r
-   c.d.asBytes[0] = 0x1; //Password mode\r
-   SendCommand(&c);\r
-   return 0;\r
++      \r
++      UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {data, block, 0}};\r
++      c.d.asBytes[0] = 0x0; \r
\r
 -  if (Block > 7) {\r
 -      PrintAndLog("Block must be between 0 and 7");\r
 -      return 1;\r
 -  }   \r
++      if (res == 2) {\r
++              PrintAndLog("Writing block %d  data %08X", block, data);\r
++      } else {\r
++              //Password mode\r
++              c.arg[2] = password;\r
++              c.d.asBytes[0] = 0x1; \r
++              PrintAndLog("Writing block %d  data %08X  password %08X", block, data, password);\r
++      }\r
++      \r
++      SendCommand(&c);\r
++      return 0;\r
 +}\r
 +\r
 +int CmdReadTrace(const char *Cmd)\r
 +{\r
 +      char cmdp = param_getchar(Cmd, 0);\r
 +\r
 +      if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') {\r
-               PrintAndLog("Usage:  lf t55xx trace  [use data from Graphbuffer]");\r
-               PrintAndLog("     [use data from Graphbuffer], if not set, try reading data from tag.");\r
-               PrintAndLog("");\r
-               PrintAndLog("     sample: lf t55xx trace");\r
-               PrintAndLog("           : lf t55xx trace 1");\r
++              usage_t55xx_trace();\r
 +              return 0;\r
 +      }\r
 +\r
 +      if ( strlen(Cmd)==0){\r
 +      \r
 +              UsbCommand c = {CMD_T55XX_READ_TRACE, {0, 0, 0}};\r
 +              SendCommand(&c);\r
 +              WaitForResponse(CMD_ACK, NULL);\r
  \r
 -  PrintAndLog("Writting block %d with data %08X", Block, Data);\r
 +              uint8_t data[LF_TRACE_BUFF_SIZE] = {0x00};\r
  \r
 -  c.cmd = CMD_T55XX_WRITE_BLOCK;\r
 -  c.d.asBytes[0] = 0x0; //Normal mode\r
 -  c.arg[0] = Data;\r
 -  c.arg[1] = Block;\r
 -  c.arg[2] = 0;\r
 -  SendCommand(&c);\r
 +              GetFromBigBuf(data,LF_TRACE_BUFF_SIZE,0);  //3560 -- should be offset..\r
 +              WaitForResponseTimeout(CMD_ACK,NULL, 1500);\r
 +\r
 +              for (int j = 0; j < LF_TRACE_BUFF_SIZE; j++) {\r
 +                      GraphBuffer[j] = ((int)data[j]);\r
 +              }\r
 +              GraphTraceLen = LF_TRACE_BUFF_SIZE;\r
 +      }\r
 +      \r
 +      uint8_t bits[LF_BITSSTREAM_LEN] = {0x00};\r
 +      uint8_t * bitstream = bits;\r
 +      \r
 +      manchester_decode(GraphBuffer, LF_TRACE_BUFF_SIZE, bitstream, LF_BITSSTREAM_LEN);\r
 +      RepaintGraphWindow();\r
 +\r
 +      uint8_t si = 5;\r
 +      uint32_t bl0     = PackBits(si, 32, bitstream);\r
 +      uint32_t bl1     = PackBits(si+32, 32, bitstream);\r
 +      \r
 +      uint32_t acl     = PackBits(si,  8, bitstream); si += 8;\r
 +      uint32_t mfc     = PackBits(si, 8, bitstream); si += 8;\r
 +      uint32_t cid     = PackBits(si, 5, bitstream); si += 5;\r
 +      uint32_t icr     = PackBits(si, 3, bitstream); si += 3;\r
 +      uint32_t year    = PackBits(si, 4, bitstream); si += 4;\r
 +      uint32_t quarter = PackBits(si, 2, bitstream); si += 2;\r
 +      uint32_t lotid    = PackBits(si, 12, bitstream); si += 12;\r
 +      uint32_t wafer   = PackBits(si, 5, bitstream); si += 5;\r
 +      uint32_t dw      = PackBits(si, 15, bitstream); \r
 +      \r
 +      PrintAndLog("");\r
 +      PrintAndLog("-- T55xx Trace Information ----------------------------------");\r
 +      PrintAndLog("-------------------------------------------------------------");\r
 +      PrintAndLog(" ACL Allocation class (ISO/IEC 15963-1)  : 0x%02X (%d)", acl, acl);\r
 +      PrintAndLog(" MFC Manufacturer ID (ISO/IEC 7816-6)    : 0x%02X (%d)", mfc, mfc);\r
 +      PrintAndLog(" CID                                     : 0x%02X (%d)", cid, cid);\r
 +      PrintAndLog(" ICR IC Revision                         : %d",icr );\r
 +      PrintAndLog(" Manufactured");\r
 +      PrintAndLog("     Year/Quarter : %d/%d",2000+year, quarter );\r
 +      PrintAndLog("     Lot ID       : %d", lotid );\r
 +      PrintAndLog("     Wafer number : %d", wafer);\r
 +      PrintAndLog("     Die Number   : %d", dw);\r
 +      PrintAndLog("-------------------------------------------------------------");\r
 +      PrintAndLog(" Raw Data - Page 1");\r
 +      PrintAndLog("     Block 0  : 0x%08X  %s", bl0, sprint_bin(bitstream+5,32) );\r
 +      PrintAndLog("     Block 0  : 0x%08X  %s", bl1, sprint_bin(bitstream+37,32) );\r
 +      PrintAndLog("-------------------------------------------------------------");\r
 +      /*\r
 +      TRACE - BLOCK O\r
 +              Bits    Definition                                                              HEX\r
 +              1-8             ACL Allocation class (ISO/IEC 15963-1)  0xE0 \r
 +              9-16    MFC Manufacturer ID (ISO/IEC 7816-6)    0x15 Atmel Corporation\r
 +              17-21   CID                                                                             0x1 = Atmel ATA5577M1  0x2 = Atmel ATA5577M2 \r
 +              22-24   ICR IC revision\r
 +              25-28   YEAR (BCD encoded)                                              9 (= 2009)\r
 +              29-30   QUARTER                                                                 1,2,3,4 \r
 +              31-32   LOT ID\r
 +      \r
 +      TRACE - BLOCK 1\r
 +              1-12    LOT ID  \r
 +              13-17   Wafer number\r
 +              18-32   DW,  die number sequential\r
 +      */\r
 +      \r
    return 0;\r
  }\r
  \r
 -int CmdWriteBlkPWD(const char *Cmd)\r
 -{\r
 -  int Block = 8; //default to invalid block\r
 -  int Data = 0xFFFFFFFF; //default to blank Block \r
 -  int Password = 0xFFFFFFFF; //default to blank Block 7\r
 -  UsbCommand c;\r
 -\r
 -  sscanf(Cmd, "%x %d %x", &Data, &Block, &Password);\r
 -\r
 -  if (Block > 7) {\r
 -      PrintAndLog("Block must be between 0 and 7");\r
 -      return 1;\r
 -  }   \r
 -\r
 -  PrintAndLog("Writting block %d with data %08X and password %08X", Block, Data, Password);\r
 -\r
 -  c.cmd = CMD_T55XX_WRITE_BLOCK;\r
 -  c.d.asBytes[0] = 0x1; //Password mode\r
 -  c.arg[0] = Data;\r
 -  c.arg[1] = Block;\r
 -  c.arg[2] = Password;\r
 -  SendCommand(&c);\r
 -  return 0;\r
 +int CmdInfo(const char *Cmd){\r
 +      /*\r
 +              Page 0 Block 0 Configuration data.\r
 +              Normal mode\r
 +              Extended mode\r
 +      */\r
 +      char cmdp = param_getchar(Cmd, 0);\r
 +\r
 +      if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') {\r
-               PrintAndLog("Usage:  lf t55xx info  [use data from Graphbuffer]");\r
-               PrintAndLog("     [use data from Graphbuffer], if not set, try reading data from tag.");\r
-               PrintAndLog("");\r
-               PrintAndLog("    sample: lf t55xx info");\r
-               PrintAndLog("    sample: lf t55xx info 1");\r
++              usage_t55xx_info();\r
 +              return 0;\r
-       }\r
\r
-       if ( strlen(Cmd) == 0 ){\r
++      } else {\r
 +              CmdReadBlk("0");\r
 +      }       \r
 +\r
 +      uint8_t bits[LF_BITSSTREAM_LEN] = {0x00};\r
 +\r
 +      manchester_decode(GraphBuffer, LF_TRACE_BUFF_SIZE, bits, LF_BITSSTREAM_LEN);\r
 +      \r
 +      uint8_t si = 5;\r
 +      uint32_t bl0      = PackBits(si, 32, bits);\r
 +      \r
 +      uint32_t safer    = PackBits(si, 4, bits); si += 4;     \r
 +      uint32_t resv     = PackBits(si, 7, bits); si += 7;\r
 +      uint32_t dbr      = PackBits(si, 3, bits); si += 3;\r
 +      uint32_t extend   = PackBits(si, 1, bits); si += 1;\r
 +      uint32_t datamodulation   = PackBits(si, 5, bits); si += 5;\r
 +      uint32_t pskcf    = PackBits(si, 2, bits); si += 2;\r
 +      uint32_t aor      = PackBits(si, 1, bits); si += 1;     \r
 +      uint32_t otp      = PackBits(si, 1, bits); si += 1;     \r
 +      uint32_t maxblk   = PackBits(si, 3, bits); si += 3;\r
 +      uint32_t pwd      = PackBits(si, 1, bits); si += 1;     \r
 +      uint32_t sst      = PackBits(si, 1, bits); si += 1;     \r
 +      uint32_t fw       = PackBits(si, 1, bits); si += 1;\r
 +      uint32_t inv      = PackBits(si, 1, bits); si += 1;     \r
 +      uint32_t por      = PackBits(si, 1, bits); si += 1;\r
 +              \r
 +      PrintAndLog("");\r
 +      PrintAndLog("-- T55xx Configuration & Tag Information --------------------");\r
 +      PrintAndLog("-------------------------------------------------------------");\r
 +      PrintAndLog(" Safer key                 : %s", GetSaferStr(safer));\r
 +      PrintAndLog(" reserved                  : %d", resv);\r
 +      PrintAndLog(" Data bit rate             : %s", GetBitRateStr(dbr));\r
 +      PrintAndLog(" eXtended mode             : %s", (extend) ? "Yes - Warning":"No");\r
 +      PrintAndLog(" Modulation                : %s", GetModulationStr(datamodulation) );\r
 +      PrintAndLog(" PSK clock freq            : %d", pskcf);\r
 +      PrintAndLog(" AOR - Answer on Request   : %s", (aor) ? "Yes":"No");\r
 +      PrintAndLog(" OTP - One Time Pad        : %s", (otp) ? "Yes - Warning":"No" );\r
 +      PrintAndLog(" Max block                 : %d", maxblk);\r
 +      PrintAndLog(" Password mode             : %s", (pwd) ? "Yes":"No");\r
 +      PrintAndLog(" Sequence Start Terminator : %s", (sst) ? "Yes":"No");\r
 +      PrintAndLog(" Fast Write                : %s", (fw) ? "Yes":"No");\r
 +      PrintAndLog(" Inverse data              : %s", (inv) ? "Yes":"No");\r
 +      PrintAndLog(" POR-Delay                 : %s", (por) ? "Yes":"No");\r
 +      PrintAndLog("-------------------------------------------------------------");\r
 +      PrintAndLog(" Raw Data - Page 0");\r
 +      PrintAndLog("     Block 0  : 0x%08X  %s", bl0, sprint_bin(bits+5,32) );\r
 +      PrintAndLog("-------------------------------------------------------------");\r
 +      \r
 +      return 0;\r
  }\r
  \r
 -int CmdReadTrace(const char *Cmd)\r
 -{\r
 +int CmdDump(const char *Cmd){\r
  \r
-       char cmdp = param_getchar(Cmd, 0);\r
-       char s[20];\r
 -  PrintAndLog("Reading traceability data");\r
++      char s[20] = {0x00};\r
 +      uint8_t pwd[4] = {0x00};\r
-       bool hasPwd = ( strlen(Cmd) > 0);\r
-       \r
\r
 -  UsbCommand c = {CMD_T55XX_READ_TRACE, {0, 0, 0}};\r
 -  SendCommand(&c);\r
 -  return 0;\r
++      char cmdp = param_getchar(Cmd, 0);\r
 +      if ( cmdp == 'h' || cmdp == 'H') {\r
-               PrintAndLog("Usage:  lf t55xx dump <password>");\r
-               PrintAndLog("        sample: lf t55xx dump FFFFFFFF");\r
++              usage_t55xx_dump();\r
 +              return 0;\r
 +      }\r
-       \r
++\r
++      bool hasPwd = ( strlen(Cmd) > 0);       \r
 +      if ( hasPwd ){\r
 +              if (param_gethex(Cmd, 0, pwd, 8)) {\r
 +                      PrintAndLog("password must include 8 HEX symbols");\r
 +                      return 1;\r
 +              }\r
 +      }\r
 +      \r
 +      for ( int i = 0; i <8; ++i){\r
 +              memset(s,0,sizeof(s));\r
 +              if ( hasPwd ) {\r
 +                      sprintf(s,"%d %02x%02x%02x%02x", i, pwd[0],pwd[1],pwd[2],pwd[3]);\r
-                       CmdReadBlkPWD(s);\r
 +              } else {\r
 +                      sprintf(s,"%d", i);\r
-                       CmdReadBlk(s);\r
 +              }\r
++              CmdReadBlk(s);\r
 +      }\r
 +      return 0;\r
 +}\r
 +\r
 +int CmdIceFsk(const char *Cmd){\r
 +\r
 +      if (!HasGraphData()) return 0;\r
 +\r
 +      iceFsk3(GraphBuffer, LF_TRACE_BUFF_SIZE);\r
 +      RepaintGraphWindow();\r
 +      return 0;\r
 +}\r
 +int CmdIceManchester(const char *Cmd){\r
 +      ManchesterDemod( -1);\r
 +      return 0;\r
 +}\r
 +int ManchesterDemod(int blockNum){\r
 +\r
 +      if (!HasGraphData()) return 0;\r
 +              \r
 +      uint8_t sizebyte = 32;\r
 +      // the value 5 was selected during empirical studies of the decoded data. Some signal noise to skip.\r
 +      uint8_t offset = 5;\r
 +      uint32_t blockData;\r
 +      uint8_t  bits[LF_BITSSTREAM_LEN] = {0x00};\r
 +      uint8_t * bitstream = bits;\r
 +      \r
 +      manchester_decode(GraphBuffer, LF_TRACE_BUFF_SIZE, bits, LF_BITSSTREAM_LEN);    \r
 +      blockData = PackBits(offset, sizebyte, bits);\r
 +\r
 +      if ( blockNum < 0)\r
 +              PrintAndLog(" Decoded     : 0x%08X  %s", blockData, sprint_bin(bitstream+offset,sizebyte) );\r
 +              else\r
 +              PrintAndLog(" Block %d    : 0x%08X  %s", blockNum, blockData, sprint_bin(bitstream+offset,sizebyte) );\r
 +      \r
 +      return 0;\r
 +} \r
 +\r
 +char * GetBitRateStr(uint32_t id){\r
 +      static char buf[40];\r
 +      char *retStr = buf;\r
 +              switch (id){\r
 +              case 0: \r
 +                      sprintf(retStr,"%d - RF/8",id);\r
 +                      break;\r
 +              case 1:\r
 +                      sprintf(retStr,"%d - RF/16",id);\r
 +                      break;\r
 +              case 2:         \r
 +                      sprintf(retStr,"%d - RF/32",id);\r
 +                      break;\r
 +              case 3:\r
 +                      sprintf(retStr,"%d - RF/40",id);\r
 +                      break;\r
 +              case 4:\r
 +                      sprintf(retStr,"%d - RF/50",id);\r
 +                      break;\r
 +              case 5:\r
 +                      sprintf(retStr,"%d - RF/64",id);\r
 +                      break;\r
 +              case 6:\r
 +                      sprintf(retStr,"%d - RF/100",id);\r
 +                      break;\r
 +              case 7:\r
 +                      sprintf(retStr,"%d - RF/128",id);\r
 +                      break;\r
 +              default:\r
 +                      sprintf(retStr,"%d - (Unknown)",id);\r
 +                      break;\r
 +              }\r
 +\r
 +      return buf;\r
 +}\r
 +\r
 +char * GetSaferStr(uint32_t id){\r
 +      static char buf[40];\r
 +      char *retStr = buf;\r
 +      \r
 +      sprintf(retStr,"%d",id);\r
 +      if (id == 6) {\r
 +              sprintf(retStr,"%d - pasdwd",id);\r
 +      }\r
 +      if (id == 9 ){\r
 +              sprintf(retStr,"%d - testmode ",id);\r
 +      }\r
 +      \r
 +      return buf;\r
 +}\r
 +char * GetModulationStr( uint32_t id){\r
 +      static char buf[40];\r
 +      char *retStr = buf;\r
 +      \r
 +      switch (id){\r
 +              case 0: \r
 +                      sprintf(retStr,"%d - DIRECT (ASK/NRZ)",id);\r
 +                      break;\r
 +              case 1:\r
 +                      sprintf(retStr,"%d - PSK 1 phase change when input changes",id);\r
 +                      break;\r
 +              case 2:         \r
 +                      sprintf(retStr,"%d - PSK 2 phase change on bitclk if input high",id);\r
 +                      break;\r
 +              case 3:\r
 +                      sprintf(retStr,"%d - PSK 3 phase change on rising edge of input",id);\r
 +                      break;\r
 +              case 4:\r
 +                      sprintf(retStr,"%d - FSK 1 RF/8  RF/5",id);\r
 +                      break;\r
 +              case 5:\r
 +                      sprintf(retStr,"%d - FSK 2 RF/8  RF/10",id);\r
 +                      break;\r
 +              case 6:\r
 +                      sprintf(retStr,"%d - FSK 1a RF/5  RF/8",id);\r
 +                      break;\r
 +              case 7:\r
 +                      sprintf(retStr,"%d - FSK 2a RF/10  RF/8",id);\r
 +                      break;\r
 +              case 8:\r
 +                      sprintf(retStr,"%d - Manschester",id);\r
 +                      break;\r
 +              case 16:\r
 +                      sprintf(retStr,"%d - Biphase",id);\r
 +                      break;\r
 +              case 17:\r
 +                      sprintf(retStr,"%d - Reserved",id);\r
 +                      break;\r
 +              default:\r
 +                      sprintf(retStr,"0x%02X (Unknown)",id);\r
 +                      break;\r
 +              }\r
 +      return buf;\r
 +}\r
 +\r
 +\r
 +uint32_t PackBits(uint8_t start, uint8_t len, uint8_t* bits){\r
 +      \r
 +      int i = start;\r
 +      int j = len-1;\r
 +      if (len > 32) {\r
 +              return 0;\r
 +      }\r
 +      uint32_t tmp = 0;\r
 +      for (; j >= 0; --j, ++i){\r
 +              tmp     |= bits[i] << j;\r
 +      }\r
 +      return tmp;\r
  }\r
  \r
  static command_t CommandTable[] =\r
  {\r
 -  {"help",          CmdHelp,        1, "This help"},\r
 -  {"readblock",     CmdReadBlk,     1, "<Block> -- Read T55xx block data (page 0)"},\r
 -  {"readblockPWD",  CmdReadBlkPWD,  1, "<Block> <Password> -- Read T55xx block data in password mode(page 0)"},\r
 -  {"writeblock",    CmdWriteBlk,    1, "<Data> <Block> -- Write T55xx block data (page 0)"},\r
 -  {"writeblockPWD", CmdWriteBlkPWD, 1, "<Data> <Block> <Password> -- Write T55xx block data in password mode(page 0)"},\r
 -  {"readtrace",     CmdReadTrace,   1, "Read T55xx traceability data (page 1)"},\r
 +  {"help",   CmdHelp,        1, "This help"},\r
-   {"rd",     CmdReadBlk,     0, "<block> -- Read T55xx block data (page 0)"},\r
-   {"rdpwd",  CmdReadBlkPWD,  0, "<block> <password> -- Read T55xx block data with password mode"},\r
-   {"wr",     CmdWriteBlk,    0, "<block> <data> -- Write T55xx block data (page 0)"},\r
-   {"wrpwd",  CmdWriteBlkPWD, 0, "<block> <password> <data> -- Write T55xx block data with password"},\r
++  {"rd",     CmdReadBlk,     0, "<block> [password] -- Read T55xx block data (page 0) [optional password]"},\r
++  {"wr",     CmdWriteBlk,    0, "<block> <data> [password] -- Write T55xx block data (page 0) [optional password]"},\r
 +  {"trace",  CmdReadTrace,   0, "[1] Read T55xx traceability data (page 1/ blk 0-1)"},\r
 +  {"info",   CmdInfo,        0, "[1] Read T55xx configuration data (page 0/ blk 0)"},\r
-   {"dump",   CmdDump,        0, "[password] Dump T55xx card block 0-7. optional with password"},\r
-   //{"fsk",    CmdIceFsk,      0, "FSK demod"},\r
++  {"dump",   CmdDump,        0, "[password] Dump T55xx card block 0-7. [optional password]"},\r
 +  {"man",    CmdIceManchester,      0, "Manchester demod (with SST)"},\r
    {NULL, NULL, 0, NULL}\r
  };\r
  \r
diff --combined client/ui.c
index 10ae1310692d4ba03c5526a3aa21329fea2bcdbd,c0d01bc32983a2efb313f99640d745ce3af8cde9..6645a99ea5e5f7519380a6d2dc306c1cc9ae879f
  #include <stdarg.h>
  #include <stdlib.h>
  #include <stdio.h>
 +#include <stdbool.h>
  #include <time.h>
  #include <readline/readline.h>
  #include <pthread.h>
 -
 +#include "loclass/cipherutils.h"
  #include "ui.h"
 +#include "cmdmain.h"
 +#include "cmddata.h"
 +#include "graph.h"
 +//#include <liquid/liquid.h>
 +#define M_PI 3.14159265358979323846264338327
  
  double CursorScaleFactor;
  int PlotGridX, PlotGridY, PlotGridXdefault= 64, PlotGridYdefault= 64;
  int offline;
 -int flushAfterWrite = 0;  //buzzy
 +int flushAfterWrite = 0;
  extern pthread_mutex_t print_lock;
  
  static char *logfilename = "proxmark3.log";
@@@ -38,13 -32,13 +38,13 @@@ void PrintAndLog(char *fmt, ...
        int saved_point;
        va_list argptr, argptr2;
        static FILE *logfile = NULL;
 -      static int logging=1;
 +      static int logging = 1;
  
        // lock this section to avoid interlacing prints from different threats
        pthread_mutex_lock(&print_lock);
    
        if (logging && !logfile) {
 -              logfile=fopen(logfilename, "a");
 +              logfile = fopen(logfilename, "a");
                if (!logfile) {
                        fprintf(stderr, "Can't open logfile, logging disabled!\n");
                        logging=0;
        }
        va_end(argptr2);
  
 -      if (flushAfterWrite == 1)  //buzzy
 -      {
 +      if (flushAfterWrite == 1) {
                fflush(NULL);
        }
        //release lock
        pthread_mutex_unlock(&print_lock);  
  }
  
 -
  void SetLogFilename(char *fn)
  {
    logfilename = fn;
  }
-       clock = GetClock("",0, 0);      
 +
 +int manchester_decode( int * data, const size_t len, uint8_t * dataout,  size_t dataoutlen){
 +      
 +      int bitlength = 0;
 +      int clock, high, low, startindex;
 +      low = startindex = 0;
 +      high = 1;
 +      uint8_t * bitStream =  (uint8_t* ) malloc(sizeof(uint8_t) * dataoutlen);        
 +      memset(bitStream, 0x00, dataoutlen);    
 +      
 +      /* Detect high and lows */
 +      DetectHighLowInGraph(&high, &low, TRUE); 
 +
 +      /* get clock */
++      clock = GetAskClock("",false, false);
 +
 +      startindex = DetectFirstTransition(data, len, high);
 +  
 +      if (high != 1)
 +              // decode "raw"
 +              bitlength = ManchesterConvertFrom255(data, len, bitStream, dataoutlen, high, low, clock, startindex);
 +      else
 +              // decode manchester
 +              bitlength = ManchesterConvertFrom1(data, len, bitStream, dataoutlen, clock, startindex);
 +
 +      memcpy(dataout, bitStream, bitlength);
 +      free(bitStream);
 +      return bitlength;
 +}
 + 
 + int DetectFirstTransition(const int * data, const size_t len, int threshold){
 +
 +      int i = 0;
 +      /* now look for the first threshold */
 +      for (; i < len; ++i) {
 +              if (data[i] == threshold) {
 +                      break;
 +              }
 +      }
 +      return i;
 + }
 +
 + int ManchesterConvertFrom255(const int * data, const size_t len, uint8_t * dataout, int dataoutlen, int high, int low, int clock, int startIndex){
 +
 +      int i, j, z, hithigh, hitlow, bitIndex, startType;
 +      i = 0;
 +      bitIndex = 0;
 +      
 +      int isDamp = 0;
 +      int damplimit = (int)((high / 2) * 0.3);
 +      int dampHi =  (high/2)+damplimit;
 +      int dampLow = (high/2)-damplimit;
 +      int firstST = 0;
 +
 +      // i = clock frame of data
 +      for (; i < (int)(len/clock); i++)
 +      {
 +              hithigh = 0;
 +              hitlow = 0;
 +              startType = -1;
 +              z = startIndex + (i*clock);
 +              isDamp = 0;
 +                      
 +              /* Find out if we hit both high and low peaks */
 +              for (j = 0; j < clock; j++)
 +              {               
 +                      if (data[z+j] == high){
 +                              hithigh = 1;
 +                              if ( startType == -1)
 +                                      startType = 1;
 +                      }
 +                      
 +                      if (data[z+j] == low ){
 +                              hitlow = 1;
 +                              if ( startType == -1)
 +                                      startType = 0;
 +                      } 
 +              
 +                      if (hithigh && hitlow)
 +                        break;
 +              }
 +              
 +              // No high value found, are we in a dampening field?
 +              if ( !hithigh ) {
 +                      //PrintAndLog(" # Entering damp test at index : %d (%d)", z+j, j);
 +                      for (j = 0; j < clock; j++) {
 +                              if ( 
 +                                   (data[z+j] <= dampHi && data[z+j] >= dampLow)
 +                                 ){
 +                                 isDamp++;
 +                              }
 +                      }
 +              }
 +
 +              /*  Manchester Switching..
 +                      0: High -> Low   
 +                      1: Low -> High  
 +              */
 +              if (startType == 0)
 +                      dataout[bitIndex++] = 1;
 +              else if (startType == 1) 
 +                      dataout[bitIndex++] = 0;
 +              else
 +                      dataout[bitIndex++] = 2;
 +                      
 +              if ( isDamp > clock/2 ) {
 +                      firstST++;
 +              }
 +              
 +              if ( firstST == 4)
 +                      break;
 +              if ( bitIndex >= dataoutlen-1 )
 +                      break;
 +      }
 +      return bitIndex;
 + }
 + 
 + int ManchesterConvertFrom1(const int * data, const size_t len, uint8_t * dataout,int dataoutlen, int clock, int startIndex){
 +
 +      int i,j, bitindex, lc, tolerance, warnings;
 +      warnings = 0;
 +      int upperlimit = len*2/clock+8;
 +      i = startIndex;
 +      j = 0;
 +      tolerance = clock/4;
 +      uint8_t decodedArr[len];
 +      
 +      /* Detect duration between 2 successive transitions */
 +      for (bitindex = 1; i < len; i++) {
 +      
 +              if (data[i-1] != data[i]) {
 +                      lc = i - startIndex;
 +                      startIndex = i;
 +
 +                      // Error check: if bitindex becomes too large, we do not
 +                      // have a Manchester encoded bitstream or the clock is really wrong!
 +                      if (bitindex > upperlimit ) {
 +                              PrintAndLog("Error: the clock you gave is probably wrong, aborting.");
 +                              return 0;
 +                      }
 +                      // Then switch depending on lc length:
 +                      // Tolerance is 1/4 of clock rate (arbitrary)
 +                      if (abs((lc-clock)/2) < tolerance) {
 +                              // Short pulse : either "1" or "0"
 +                              decodedArr[bitindex++] = data[i-1];
 +                      } else if (abs(lc-clock) < tolerance) {
 +                              // Long pulse: either "11" or "00"
 +                              decodedArr[bitindex++] = data[i-1];
 +                              decodedArr[bitindex++] = data[i-1];
 +                      } else {
 +                              ++warnings;
 +                              PrintAndLog("Warning: Manchester decode error for pulse width detection.");
 +                              if (warnings > 10) {
 +                                      PrintAndLog("Error: too many detection errors, aborting.");
 +                                      return 0; 
 +                              }
 +                      }
 +              }
 +      }
 +      
 +      /* 
 +      * We have a decodedArr of "01" ("1") or "10" ("0")
 +      * parse it into final decoded dataout
 +    */ 
 +    for (i = 0; i < bitindex; i += 2) {
 +
 +          if ((decodedArr[i] == 0) && (decodedArr[i+1] == 1)) {
 +                      dataout[j++] = 1;
 +              } else if ((decodedArr[i] == 1) && (decodedArr[i+1] == 0)) {
 +                      dataout[j++] = 0;
 +              } else {
 +                      i++;
 +                      warnings++;
 +                      PrintAndLog("Unsynchronized, resync...");
 +                      PrintAndLog("(too many of those messages mean the stream is not Manchester encoded)");
 +
 +                      if (warnings > 10) {    
 +                              PrintAndLog("Error: too many decode errors, aborting.");
 +                              return 0;
 +                      }
 +              }
 +    }
 +      
 +      PrintAndLog("%s", sprint_hex(dataout, j));
 +      return j;
 + }
 + 
 + void ManchesterDiffDecodedString(const uint8_t* bitstream, size_t len, uint8_t invert){
 +      /* 
 +      * We have a bitstream of "01" ("1") or "10" ("0")
 +      * parse it into final decoded bitstream
 +    */ 
 +      int i, j, warnings; 
 +      uint8_t decodedArr[(len/2)+1];
 +
 +      j = warnings = 0;
 +      
 +      uint8_t lastbit = 0;
 +      
 +    for (i = 0; i < len; i += 2) {
 +      
 +              uint8_t first = bitstream[i];
 +              uint8_t second = bitstream[i+1];
 +
 +              if ( first == second ) {
 +                      ++i;
 +                      ++warnings;
 +                      if (warnings > 10) {
 +                              PrintAndLog("Error: too many decode errors, aborting.");
 +                              return;
 +                      }
 +              } 
 +              else if ( lastbit != first ) {
 +                      decodedArr[j++] = 0 ^ invert;
 +              }
 +              else {
 +                      decodedArr[j++] = 1 ^ invert;
 +              }
 +              lastbit = second;
 +    }
 +      
 +      PrintAndLog("%s", sprint_hex(decodedArr, j));
 +}
 + 
 +void PrintPaddedManchester( uint8_t* bitStream, size_t len, size_t blocksize){
 +
 +      PrintAndLog(" Manchester decoded  : %d bits", len);
 +        
 +      uint8_t mod = len % blocksize;
 +      uint8_t div = len / blocksize;
 +      int i;
 +  
 +      // Now output the bitstream to the scrollback by line of 16 bits
 +      for (i = 0; i < div*blocksize; i+=blocksize) {
 +              PrintAndLog(" %s", sprint_bin(bitStream+i,blocksize) );
 +      }
 +      
 +      if ( mod > 0 )
 +              PrintAndLog(" %s", sprint_bin(bitStream+i, mod) );      
 +}
 +
 +/* Sliding DFT
 +   Smooths out 
 +*/ 
 +void iceFsk2(int * data, const size_t len){
 +
 +      int i, j;
 +      int * output =  (int* ) malloc(sizeof(int) * len);      
 +      memset(output, 0x00, len);
 +
 +      // for (i=0; i<len-5; ++i){
 +              // for ( j=1; j <=5; ++j) {
 +                      // output[i] += data[i*j];
 +              // }
 +              // output[i] /= 5;
 +      // }
 +      int rest = 127;
 +      int tmp =0;
 +      for (i=0; i<len; ++i){
 +              if ( data[i] < 127)
 +                      output[i] = 0;
 +              else {
 +                      tmp =  (100 * (data[i]-rest)) / rest;
 +                      output[i] = (tmp > 60)? 100:0;
 +              }
 +      }
 +      
 +      for (j=0; j<len; ++j)
 +              data[j] = output[j];
 +              
 +      free(output);
 +}
 +
 +void iceFsk3(int * data, const size_t len){
 +
 +      int i,j;
 +      
 +      int * output =  (int* ) malloc(sizeof(int) * len);      
 +      memset(output, 0x00, len);
 +      float fc           = 0.1125f;          // center frequency
 +      size_t adjustedLen = len;
 +      
 +    // create very simple low-pass filter to remove images (2nd-order Butterworth)
 +    float complex iir_buf[3] = {0,0,0};
 +    float b[3] = {0.003621681514929,  0.007243363029857, 0.003621681514929};
 +    float a[3] = {1.000000000000000, -1.822694925196308, 0.837181651256023};
 +    
 +    float sample           = 0;      // input sample read from file
 +    float complex x_prime  = 1.0f;   // save sample for estimating frequency
 +    float complex x;
 +              
 +      for (i=0; i<adjustedLen; ++i) {
 +
 +              sample = data[i]+128;
 +              
 +        // remove DC offset and mix to complex baseband
 +        x = (sample - 127.5f) * cexpf( _Complex_I * 2 * M_PI * fc * i );
 +
 +        // apply low-pass filter, removing spectral image (IIR using direct-form II)
 +        iir_buf[2] = iir_buf[1];
 +        iir_buf[1] = iir_buf[0];
 +        iir_buf[0] = x - a[1]*iir_buf[1] - a[2]*iir_buf[2];
 +        x          = b[0]*iir_buf[0] +
 +                     b[1]*iir_buf[1] +
 +                     b[2]*iir_buf[2];
 +                                       
 +        // compute instantaneous frequency by looking at phase difference
 +        // between adjacent samples
 +        float freq = cargf(x*conjf(x_prime));
 +        x_prime = x;    // retain this sample for next iteration
 +
 +              output[i] =(freq > 0)? 10 : -10;
 +    } 
 +
 +      // show data
 +      for (j=0; j<adjustedLen; ++j)
 +              data[j] = output[j];
 +              
 +      CmdLtrim("30");
 +      adjustedLen -= 30;
 +      
 +      // zero crossings.
 +      for (j=0; j<adjustedLen; ++j){
 +              if ( data[j] == 10) break;
 +      }
 +      int startOne =j;
 +      
 +      for (;j<adjustedLen; ++j){
 +              if ( data[j] == -10 ) break;
 +      }
 +      int stopOne = j-1;
 +      
 +      int fieldlen = stopOne-startOne;
 +      
 +      fieldlen = (fieldlen == 39 || fieldlen == 41)? 40 : fieldlen;
 +      fieldlen = (fieldlen == 59 || fieldlen == 51)? 50 : fieldlen;
 +      if ( fieldlen != 40 && fieldlen != 50){
 +              printf("Detected field Length: %d \n", fieldlen);
 +              printf("Can only handle 40 or 50.  Aborting...\n");
 +              return;
 +      }
 +      
 +      // FSK sequence start == 000111
 +      int startPos = 0;
 +      for (i =0; i<adjustedLen; ++i){
 +              int dec = 0;
 +              for ( j = 0; j < 6*fieldlen; ++j){
 +                      dec += data[i + j];
 +              }
 +              if (dec == 0) {
 +                      startPos = i;
 +                      break;
 +              }
 +      }
 +      
 +      printf("000111 position: %d \n", startPos);
 +
 +      startPos += 6*fieldlen+5;
 +      
 +      int bit =0;
 +      printf("BINARY\n");
 +      printf("R/40 :  ");
 +      for (i =startPos ; i < adjustedLen; i += 40){
 +              bit = data[i]>0 ? 1:0;
 +              printf("%d", bit );
 +      }
 +      printf("\n");   
 +      
 +      printf("R/50 :  ");
 +      for (i =startPos ; i < adjustedLen; i += 50){
 +              bit = data[i]>0 ? 1:0;
 +              printf("%d", bit );     }
 +      printf("\n");   
 +      
 +      free(output);
 +}
 +
 +float complex cexpf (float complex Z)
 +{
 +  float complex  Res;
 +  double rho = exp (__real__ Z);
 +  __real__ Res = rho * cosf(__imag__ Z);
 +  __imag__ Res = rho * sinf(__imag__ Z);
 +  return Res;
 +}
Impressum, Datenschutz