]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
Merge branch 'master' of https://github.com/Proxmark/proxmark3
authoriceman1001 <iceman@iuse.se>
Fri, 24 Apr 2015 17:04:01 +0000 (19:04 +0200)
committericeman1001 <iceman@iuse.se>
Fri, 24 Apr 2015 17:04:01 +0000 (19:04 +0200)
Conflicts:
client/cmddata.c
client/cmddata.h
client/cmdhfmf.c
client/cmdlf.c
client/cmdlfem4x.h
client/cmdlft55xx.c
client/lualibs/default_toys.lua
client/scripts/tnp3clone.lua
client/scripts/tnp3dump.lua
client/scripts/tnp3sim.lua

1  2 
armsrc/lfops.c
client/cmdlf.c
client/cmdlfem4x.c
client/scripts/tnp3sim.lua

diff --combined armsrc/lfops.c
index d6d686e18279eca0f42eba25131ad1c81659b6b6,e45b55fcb22767111a76ac54c99ea7470b3b51e2..d330fc6c0133d036c9ad1c114c571431259aa600
@@@ -379,10 -379,10 +379,10 @@@ void WriteTItag(uint32_t idhi, uint32_
        AcquireTiType();
  
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
 -      DbpString("Now use tiread to check");
 +      DbpString("Now use 'lf ti read' to check");
  }
  
 -void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
 +void SimulateTagLowFrequency(uint16_t period, uint32_t gap, uint8_t ledcontrol)
  {
        int i;
        uint8_t *tab = BigBuf_get_addr();
@@@ -756,7 -756,7 +756,7 @@@ void CmdHIDdemodFSK(int findone, int *h
  {
        uint8_t *dest = BigBuf_get_addr();
        //const size_t sizeOfBigBuff = BigBuf_max_traceLen();
 -      size_t size; 
 +      size_t size = 0
        uint32_t hi2=0, hi=0, lo=0;
        int idx=0;
        // Configure to go in 125Khz listen mode
@@@ -861,29 -861,29 +861,29 @@@ void CmdEM410xdemod(int findone, int *h
                size  = BigBuf_max_traceLen();
                //askdemod and manchester decode
                if (size > 16385) size = 16385; //big enough to catch 2 sequences of largest format
-               errCnt = askmandemod(dest, &size, &clk, &invert, maxErr);
+               errCnt = askdemod(dest, &size, &clk, &invert, maxErr, 0, 1);
                WDT_HIT();
  
                if (errCnt<0) continue;
        
 -              errCnt = Em410xDecode(dest, &size, &idx, &hi, &lo);
 -              if (errCnt){
 -                      if (size>64){
 -                              Dbprintf("EM XL TAG ID: %06x%08x%08x - (%05d_%03d_%08d)",
 -                                hi,
 -                                (uint32_t)(lo>>32),
 -                                (uint32_t)lo,
 -                                (uint32_t)(lo&0xFFFF),
 -                                (uint32_t)((lo>>16LL) & 0xFF),
 -                                (uint32_t)(lo & 0xFFFFFF));
 -                      } else {
 -                              Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)",
 -                                (uint32_t)(lo>>32),
 -                                (uint32_t)lo,
 -                                (uint32_t)(lo&0xFFFF),
 -                                (uint32_t)((lo>>16LL) & 0xFF),
 -                                (uint32_t)(lo & 0xFFFFFF));
 -                      }
 +                      errCnt = Em410xDecode(dest, &size, &idx, &hi, &lo);
 +                      if (errCnt){
 +                              if (size>64){
 +                                      Dbprintf("EM XL TAG ID: %06x%08x%08x - (%05d_%03d_%08d)",
 +                                        hi,
 +                                        (uint32_t)(lo>>32),
 +                                        (uint32_t)lo,
 +                                        (uint32_t)(lo&0xFFFF),
 +                                        (uint32_t)((lo>>16LL) & 0xFF),
 +                                        (uint32_t)(lo & 0xFFFFFF));
 +                              } else {
 +                                      Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)",
 +                                        (uint32_t)(lo>>32),
 +                                        (uint32_t)lo,
 +                                        (uint32_t)(lo&0xFFFF),
 +                                        (uint32_t)((lo>>16LL) & 0xFF),
 +                                        (uint32_t)(lo & 0xFFFFFF));
 +                              }
  
                        if (findone){
                                if (ledcontrol) LED_A_OFF();
@@@ -908,8 -908,6 +908,8 @@@ void CmdIOdemodFSK(int findone, int *hi
        uint8_t version=0;
        uint8_t facilitycode=0;
        uint16_t number=0;
 +      uint8_t crc = 0;
 +      uint16_t calccrc = 0;
        // Configure to go in 125Khz listen mode
        LFSetupFPGAForADC(95, true);
  
                WDT_HIT();
                idx = IOdemodFSK(dest, BigBuf_max_traceLen());
                if (idx<0) continue;
 -              //valid tag found
 -
 -              //Index map
 -              //0           10          20          30          40          50          60
 -              //|           |           |           |           |           |           |
 -              //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23
 -              //-----------------------------------------------------------------------------
 -              //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11
 -              //
 -              //XSF(version)facility:codeone+codetwo
 -              //Handle the data
 -              if(findone){ //only print binary if we are doing one
 -                      Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx],   dest[idx+1],   dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7],dest[idx+8]);
 -                      Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15],dest[idx+16],dest[idx+17]);
 -                      Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23],dest[idx+24],dest[idx+25],dest[idx+26]);
 -                      Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31],dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35]);
 -                      Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39],dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44]);
 -                      Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+45],dest[idx+46],dest[idx+47],dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53]);
 -                      Dbprintf("%d%d%d%d%d%d%d%d %d%d",dest[idx+54],dest[idx+55],dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]);
 -              }
 -              code = bytebits_to_byte(dest+idx,32);
 -              code2 = bytebits_to_byte(dest+idx+32,32);
 -              version = bytebits_to_byte(dest+idx+27,8); //14,4
 +                      //valid tag found
 +
 +                      //Index map
 +                      //0           10          20          30          40          50          60
 +                      //|           |           |           |           |           |           |
 +                      //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23
 +                      //-----------------------------------------------------------------------------
 +            //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 checksum 11
 +                      //
 +                      //Checksum:  
 +                      //00000000 0 11110000 1 11100000 1 00000001 1 00000011 1 10110110 1 01110101 11
 +                      //preamble      F0         E0         01         03         B6         75
 +                      // How to calc checksum,
 +                      // http://www.proxmark.org/forum/viewtopic.php?id=364&p=6
 +                      //   F0 + E0 + 01 + 03 + B6 = 28A
 +                      //   28A & FF = 8A
 +                      //   FF - 8A = 75
 +                      // Checksum: 0x75
 +                      //XSF(version)facility:codeone+codetwo
 +                      //Handle the data
 +                      if(findone){ //only print binary if we are doing one
 +                              Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx],   dest[idx+1],   dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7],dest[idx+8]);
 +                              Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15],dest[idx+16],dest[idx+17]);
 +                              Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23],dest[idx+24],dest[idx+25],dest[idx+26]);
 +                              Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31],dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35]);
 +                              Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39],dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44]);
 +                              Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+45],dest[idx+46],dest[idx+47],dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53]);
 +                              Dbprintf("%d%d%d%d%d%d%d%d %d%d",dest[idx+54],dest[idx+55],dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]);
 +                      }
 +                      code = bytebits_to_byte(dest+idx,32);
 +                      code2 = bytebits_to_byte(dest+idx+32,32);
 +                      version = bytebits_to_byte(dest+idx+27,8); //14,4
                facilitycode = bytebits_to_byte(dest+idx+18,8);
 -              number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9
 -
 -              Dbprintf("XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2);
 -              // if we're only looking for one tag
 -              if (findone){
 -                      if (ledcontrol) LED_A_OFF();
 -                      //LED_A_OFF();
 -                      *high=code;
 -                      *low=code2;
 -                      return;
 -              }
 -              code=code2=0;
 -              version=facilitycode=0;
 -              number=0;
 -              idx=0;
 +                      number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9
 +
 +                      crc = bytebits_to_byte(dest+idx+54,8);
 +                      for (uint8_t i=1; i<6; ++i)
 +                              calccrc += bytebits_to_byte(dest+idx+9*i,8);
 +                      calccrc &= 0xff;
 +                      calccrc = 0xff - calccrc;
 +                      
 +                      char *crcStr = (crc == calccrc) ? "ok":"!crc";
 +
 +            Dbprintf("IO Prox XSF(%02d)%02x:%05d (%08x%08x)  [%02x %s]",version,facilitycode,number,code,code2, crc, crcStr);
 +                      // if we're only looking for one tag
 +                      if (findone){
 +                              if (ledcontrol) LED_A_OFF();
 +                              //LED_A_OFF();
 +                              *high=code;
 +                              *low=code2;
 +                              return;
 +                      }
 +                      code=code2=0;
 +                      version=facilitycode=0;
 +                      number=0;
 +                      idx=0;
  
                WDT_HIT();
        }
   * and enlarge the gap ones.
   */
  #define START_GAP 50*8 // 10 - 50fc 250
 -#define WRITE_GAP 20*8 //    - 30fc 160
 -#define WRITE_0   24*8 // 16 - 63fc 54fc 144
 -#define WRITE_1   54*8 // 48 - 63fc 54fc 432 for T55x7; 448 for E5550 //400
 +#define WRITE_GAP 20*8 //  8 - 30fc
 +#define WRITE_0   24*8 // 16 - 31fc 24fc 192
 +#define WRITE_1   54*8 // 48 - 63fc 54fc 432 for T55x7; 448 for E5550
 +
 +//  VALUES TAKEN FROM EM4x function: SendForward
 +//  START_GAP = 440;       (55*8) cycles at 125Khz (8us = 1cycle)
 +//  WRITE_GAP = 128;       (16*8)
 +//  WRITE_1   = 256 32*8;  (32*8) 
 +
 +//  These timings work for 4469/4269/4305 (with the 55*8 above)
 +//  WRITE_0 = 23*8 , 9*8  SpinDelayUs(23*8); 
 +
 +// Sam7s has several timers, we will use the source TIMER_CLOCK1 (aka AT91C_TC_CLKS_TIMER_DIV1_CLOCK)
 +// TIMER_CLOCK1 = MCK/2, MCK is running at 48 MHz, Timer is running at 48/2 = 24 MHz
 +// Hitag units (T0) have duration of 8 microseconds (us), which is 1/125000 per second (carrier)
 +// T0 = TIMER_CLOCK1 / 125000 = 192
 +// 1 Cycle = 8 microseconds(us)
  
  #define T55xx_SAMPLES_SIZE      12000 // 32 x 32 x 10  (32 bit times numofblock (7), times clock skip..)
  
@@@ -1070,7 -1037,7 +1070,7 @@@ void T55xxWriteBit(int bit
        FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
        FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
        FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
 -      if (bit == 0)
 +      if (!bit)
                SpinDelayUs(WRITE_0);
        else
                SpinDelayUs(WRITE_1);
@@@ -1524,16 -1491,10 +1524,16 @@@ void CopyIndala224toT55x7(int uid1, in
  #define max(x,y) ( x<y ? y:x)
  
  int DemodPCF7931(uint8_t **outBlocks) {
 -      uint8_t BitStream[256];
 -      uint8_t Blocks[8][16];
 -      uint8_t *GraphBuffer = BigBuf_get_addr();
 +
 +    uint8_t bits[256] = {0x00};
 +      uint8_t blocks[8][16];
 +    uint8_t *dest = BigBuf_get_addr();
 +    
        int GraphTraceLen = BigBuf_max_traceLen();
 +      if (  GraphTraceLen > 18000 )
 +              GraphTraceLen = 18000;
 +      
 +      
        int i, j, lastval, bitidx, half_switch;
        int clock = 64;
        int tolerance = clock / 8;
        uint8_t dir;
  
        LFSetupFPGAForADC(95, true);
 -      DoAcquisition_default(0, 0);
 -
 +      DoAcquisition_default(0, true);
  
        lmin = 64;
        lmax = 192;
        i = 2;
  
        /* Find first local max/min */
 -      if(GraphBuffer[1] > GraphBuffer[0]) {
 +    if(dest[1] > dest[0]) {
                while(i < GraphTraceLen) {
 -                      if( !(GraphBuffer[i] > GraphBuffer[i-1]) && GraphBuffer[i] > lmax)
 +            if( !(dest[i] > dest[i-1]) && dest[i] > lmax)
                                break;
                        i++;
                }
        }
        else {
                while(i < GraphTraceLen) {
 -                      if( !(GraphBuffer[i] < GraphBuffer[i-1]) && GraphBuffer[i] < lmin)
 +            if( !(dest[i] < dest[i-1]) && dest[i] < lmin)
                                break;
                        i++;
                }
  
        for (bitidx = 0; i < GraphTraceLen; i++)
        {
 -              if ( (GraphBuffer[i-1] > GraphBuffer[i] && dir == 1 && GraphBuffer[i] > lmax) || (GraphBuffer[i-1] < GraphBuffer[i] && dir == 0 && GraphBuffer[i] < lmin))
 +        if ( (dest[i-1] > dest[i] && dir == 1 && dest[i] > lmax) || (dest[i-1] < dest[i] && dir == 0 && dest[i] < lmin))
                {
                        lc = i - lastval;
                        lastval = i;
                                        block_done = 1;
                                }
                                else if(half_switch == 1) {
 -                                      BitStream[bitidx++] = 0;
 +                    bits[bitidx++] = 0;
                                        half_switch = 0;
                                }
                                else
                                        half_switch++;
                        } else if (abs(lc-clock) < tolerance) {
                                // 64TO
 -                              BitStream[bitidx++] = 1;
 +                bits[bitidx++] = 1;
                        } else {
                                // Error
                                warnings++;
                        if(block_done == 1) {
                                if(bitidx == 128) {
                                        for(j=0; j<16; j++) {
 -                                              Blocks[num_blocks][j] = 128*BitStream[j*8+7]+
 -                                                              64*BitStream[j*8+6]+
 -                                                              32*BitStream[j*8+5]+
 -                                                              16*BitStream[j*8+4]+
 -                                                              8*BitStream[j*8+3]+
 -                                                              4*BitStream[j*8+2]+
 -                                                              2*BitStream[j*8+1]+
 -                                                              BitStream[j*8];
 +                        blocks[num_blocks][j] = 128*bits[j*8+7]+
 +                                64*bits[j*8+6]+
 +                                32*bits[j*8+5]+
 +                                16*bits[j*8+4]+
 +                                8*bits[j*8+3]+
 +                                4*bits[j*8+2]+
 +                                2*bits[j*8+1]+
 +                                bits[j*8];
 +                                              
                                        }
                                        num_blocks++;
                                }
                                half_switch = 0;
                        }
                        if(i < GraphTraceLen)
 -                      {
 -                              if (GraphBuffer[i-1] > GraphBuffer[i]) dir=0;
 -                              else dir = 1;
 -                      }
 +                dir =(dest[i-1] > dest[i]) ? 0 : 1;
                }
                if(bitidx==255)
                        bitidx=0;
                warnings = 0;
                if(num_blocks == 4) break;
        }
 -      memcpy(outBlocks, Blocks, 16*num_blocks);
 +    memcpy(outBlocks, blocks, 16*num_blocks);
        return num_blocks;
  }
  
@@@ -1948,14 -1912,9 +1948,14 @@@ void EM4xLogin(uint32_t Password) 
  
  void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
  
 -      uint8_t fwd_bit_count;
        uint8_t *dest = BigBuf_get_addr();
 -      int m=0, i=0;
 +      uint16_t bufferlength = BigBuf_max_traceLen();
 +      uint32_t i = 0;
 +
 +      // Clear destination buffer before sending the command  0x80 = average.
 +      memset(dest, 0x80, bufferlength);
 +      
 +    uint8_t fwd_bit_count;
  
        //If password mode do login
        if (PwdMode == 1) EM4xLogin(Pwd);
        fwd_bit_count = Prepare_Cmd( FWD_CMD_READ );
        fwd_bit_count += Prepare_Addr( Address );
  
 -      m = BigBuf_max_traceLen();
 -      // Clear destination buffer before sending the command
 -      memset(dest, 128, m);
        // Connect the A/D to the peak-detected low-frequency path.
        SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
        // Now set up the SSC to get the ADC samples that are now streaming at us.
                }
                if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
                        dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
 -                      i++;
 -                      if (i >= m) break;
 +                      ++i;
 +                      if (i >= bufferlength) break;
                }
        }
 +  
 +      cmd_send(CMD_ACK,0,0,0,0,0);
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
        LED_D_OFF();
  }
diff --combined client/cmdlf.c
index 30c8bb229fa98b6ffe86f73cac00bfcce24b58f3,dfbbe992a76a6a3bdeadb0d01becdc2cb7a051e5..e4fadadc04ab4b930759f13fa3b05f67b9a5a162
@@@ -35,326 -35,326 +35,326 @@@ static int CmdHelp(const char *Cmd)
  /* send a command before reading */
  int CmdLFCommandRead(const char *Cmd)
  {
 -      static char dummy[3];
 +  static char dummy[3];
  
 -      dummy[0]= ' ';
 +  dummy[0]= ' ';
  
 -      UsbCommand c = {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K};
 -      sscanf(Cmd, "%"lli" %"lli" %"lli" %s %s", &c.arg[0], &c.arg[1], &c.arg[2],(char*)(&c.d.asBytes),(char*)(&dummy+1));
 -      // in case they specified 'h'
 -      strcpy((char *)&c.d.asBytes + strlen((char *)c.d.asBytes), dummy);
 -      SendCommand(&c);
 -      return 0;
 +  UsbCommand c = {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K};
 +  sscanf(Cmd, "%"lli" %"lli" %"lli" %s %s", &c.arg[0], &c.arg[1], &c.arg[2],(char*)(&c.d.asBytes),(char*)(&dummy+1));
 +  // in case they specified 'h'
 +  strcpy((char *)&c.d.asBytes + strlen((char *)c.d.asBytes), dummy);
 +  SendCommand(&c);
 +  return 0;
  }
  
  int CmdFlexdemod(const char *Cmd)
  {
 -      int i;
 -      for (i = 0; i < GraphTraceLen; ++i) {
 -              if (GraphBuffer[i] < 0) {
 -                      GraphBuffer[i] = -1;
 -              } else {
 -                      GraphBuffer[i] = 1;
 -              }
 -      }
 +  int i;
 +  for (i = 0; i < GraphTraceLen; ++i) {
 +    if (GraphBuffer[i] < 0) {
 +      GraphBuffer[i] = -1;
 +    } else {
 +      GraphBuffer[i] = 1;
 +    }
 +  }
  
  #define LONG_WAIT 100
 -      int start;
 -      for (start = 0; start < GraphTraceLen - LONG_WAIT; start++) {
 -              int first = GraphBuffer[start];
 -              for (i = start; i < start + LONG_WAIT; i++) {
 -                      if (GraphBuffer[i] != first) {
 -                              break;
 -                      }
 -              }
 -              if (i == (start + LONG_WAIT)) {
 -                      break;
 -              }
 -      }
 -      if (start == GraphTraceLen - LONG_WAIT) {
 -              PrintAndLog("nothing to wait for");
 -              return 0;
 -      }
 -
 -      GraphBuffer[start] = 2;
 -      GraphBuffer[start+1] = -2;
 +  int start;
 +  for (start = 0; start < GraphTraceLen - LONG_WAIT; start++) {
 +    int first = GraphBuffer[start];
 +    for (i = start; i < start + LONG_WAIT; i++) {
 +      if (GraphBuffer[i] != first) {
 +        break;
 +      }
 +    }
 +    if (i == (start + LONG_WAIT)) {
 +      break;
 +    }
 +  }
 +  if (start == GraphTraceLen - LONG_WAIT) {
 +    PrintAndLog("nothing to wait for");
 +    return 0;
 +  }
 +
 +  GraphBuffer[start] = 2;
 +  GraphBuffer[start+1] = -2;
        uint8_t bits[64] = {0x00};
  
        int bit, sum;
 -      i = start;
 -      for (bit = 0; bit < 64; bit++) {
 +  i = start;
 +  for (bit = 0; bit < 64; bit++) {
                sum = 0;
                for (int j = 0; j < 16; j++) {
 -                      sum += GraphBuffer[i++];
 -              }
 +      sum += GraphBuffer[i++];
 +    }
  
                bits[bit] = (sum > 0) ? 1 : 0;
  
 -              PrintAndLog("bit %d sum %d", bit, sum);
 -      }
 -
 -      for (bit = 0; bit < 64; bit++) {
 -              int j;
 -              int sum = 0;
 -              for (j = 0; j < 16; j++) {
 -                      sum += GraphBuffer[i++];
 -              }
 -              if (sum > 0 && bits[bit] != 1) {
 -                      PrintAndLog("oops1 at %d", bit);
 -              }
 -              if (sum < 0 && bits[bit] != 0) {
 -                      PrintAndLog("oops2 at %d", bit);
 -              }
 -      }
 +    PrintAndLog("bit %d sum %d", bit, sum);
 +  }
 +
 +  for (bit = 0; bit < 64; bit++) {
 +    int j;
 +    int sum = 0;
 +    for (j = 0; j < 16; j++) {
 +      sum += GraphBuffer[i++];
 +    }
 +    if (sum > 0 && bits[bit] != 1) {
 +      PrintAndLog("oops1 at %d", bit);
 +    }
 +    if (sum < 0 && bits[bit] != 0) {
 +      PrintAndLog("oops2 at %d", bit);
 +    }
 +  }
  
        // HACK writing back to graphbuffer.
 -      GraphTraceLen = 32*64;
 -      i = 0;
 -      int phase = 0;
 -      for (bit = 0; bit < 64; bit++) {
 +  GraphTraceLen = 32*64;
 +  i = 0;
 +  int phase = 0;
 +  for (bit = 0; bit < 64; bit++) {
        
                phase = (bits[bit] == 0) ? 0 : 1;
                
 -              int j;
 -              for (j = 0; j < 32; j++) {
 -                      GraphBuffer[i++] = phase;
 -                      phase = !phase;
 -              }
 -      }
 -
 -      RepaintGraphWindow();
 -      return 0;
 +    int j;
 +    for (j = 0; j < 32; j++) {
 +      GraphBuffer[i++] = phase;
 +      phase = !phase;
 +    }
 +  }
 +
 +  RepaintGraphWindow();
 +  return 0;
  }
 -      
 +  
  int CmdIndalaDemod(const char *Cmd)
  {
 -      // Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID
 +  // Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID
  
 -      int state = -1;
 -      int count = 0;
 -      int i, j;
 +  int state = -1;
 +  int count = 0;
 +  int i, j;
  
 -      // worst case with GraphTraceLen=64000 is < 4096
 -      // under normal conditions it's < 2048
 +  // worst case with GraphTraceLen=64000 is < 4096
 +  // under normal conditions it's < 2048
  
 -      uint8_t rawbits[4096];
 -      int rawbit = 0;
 -      int worst = 0, worstPos = 0;
 +  uint8_t rawbits[4096];
 +  int rawbit = 0;
 +  int worst = 0, worstPos = 0;
   // PrintAndLog("Expecting a bit less than %d raw bits", GraphTraceLen / 32);
 -      for (i = 0; i < GraphTraceLen-1; i += 2) {
 -              count += 1;
 -              if ((GraphBuffer[i] > GraphBuffer[i + 1]) && (state != 1)) {
 -                      if (state == 0) {
 -                              for (j = 0; j <  count - 8; j += 16) {
 -                                      rawbits[rawbit++] = 0;
 -                              }
 -                              if ((abs(count - j)) > worst) {
 -                                      worst = abs(count - j);
 -                                      worstPos = i;
 -                              }
 -                      }
 -                      state = 1;
 -                      count = 0;
 -              } else if ((GraphBuffer[i] < GraphBuffer[i + 1]) && (state != 0)) {
 -                      if (state == 1) {
 -                              for (j = 0; j <  count - 8; j += 16) {
 -                                      rawbits[rawbit++] = 1;
 -                              }
 -                              if ((abs(count - j)) > worst) {
 -                                      worst = abs(count - j);
 -                                      worstPos = i;
 -                              }
 -                      }
 -                      state = 0;
 -                      count = 0;
 -              }
 -      }
 -      
 -      if (rawbit>0){
 -              PrintAndLog("Recovered %d raw bits, expected: %d", rawbit, GraphTraceLen/32);
 -              PrintAndLog("worst metric (0=best..7=worst): %d at pos %d", worst, worstPos);
 +  for (i = 0; i < GraphTraceLen-1; i += 2) {
 +    count += 1;
 +    if ((GraphBuffer[i] > GraphBuffer[i + 1]) && (state != 1)) {
 +      if (state == 0) {
 +        for (j = 0; j <  count - 8; j += 16) {
 +          rawbits[rawbit++] = 0;
 +        }
 +        if ((abs(count - j)) > worst) {
 +          worst = abs(count - j);
 +          worstPos = i;
 +        }
 +      }
 +      state = 1;
 +      count = 0;
 +    } else if ((GraphBuffer[i] < GraphBuffer[i + 1]) && (state != 0)) {
 +      if (state == 1) {
 +        for (j = 0; j <  count - 8; j += 16) {
 +          rawbits[rawbit++] = 1;
 +        }
 +        if ((abs(count - j)) > worst) {
 +          worst = abs(count - j);
 +          worstPos = i;
 +        }
 +      }
 +      state = 0;
 +      count = 0;
 +    }
 +  }
 +  
 +  if (rawbit>0){
 +    PrintAndLog("Recovered %d raw bits, expected: %d", rawbit, GraphTraceLen/32);
 +    PrintAndLog("worst metric (0=best..7=worst): %d at pos %d", worst, worstPos);
        } else {
                return 0;
        }
  
 -      // Finding the start of a UID
 -      int uidlen, long_wait;
 -      if (strcmp(Cmd, "224") == 0) {
 -              uidlen = 224;
 -              long_wait = 30;
 -      } else {
 -              uidlen = 64;
 -              long_wait = 29;
 -      }
 -
 -      int start;
 -      int first = 0;
 -      for (start = 0; start <= rawbit - uidlen; start++) {
 -              first = rawbits[start];
 -              for (i = start; i < start + long_wait; i++) {
 -                      if (rawbits[i] != first) {
 -                              break;
 -                      }
 -              }
 -              if (i == (start + long_wait)) {
 -                      break;
 -              }
 -      }
 -      
 -      if (start == rawbit - uidlen + 1) {
 -              PrintAndLog("nothing to wait for");
 -              return 0;
 -      }
 -
 -      // Inverting signal if needed
 -      if (first == 1) {
 -              for (i = start; i < rawbit; i++) {
 -                      rawbits[i] = !rawbits[i];
 -              }
 -      }
 -
 -      // Dumping UID
 +  // Finding the start of a UID
 +  int uidlen, long_wait;
 +  if (strcmp(Cmd, "224") == 0) {
 +    uidlen = 224;
 +    long_wait = 30;
 +  } else {
 +    uidlen = 64;
 +    long_wait = 29;
 +  }
 +
 +  int start;
 +  int first = 0;
 +  for (start = 0; start <= rawbit - uidlen; start++) {
 +    first = rawbits[start];
 +    for (i = start; i < start + long_wait; i++) {
 +      if (rawbits[i] != first) {
 +        break;
 +      }
 +    }
 +    if (i == (start + long_wait)) {
 +      break;
 +    }
 +  }
 +  
 +  if (start == rawbit - uidlen + 1) {
 +    PrintAndLog("nothing to wait for");
 +    return 0;
 +  }
 +
 +  // Inverting signal if needed
 +  if (first == 1) {
 +    for (i = start; i < rawbit; i++) {
 +      rawbits[i] = !rawbits[i];
 +    }
 +  }
 +
 +  // Dumping UID
        uint8_t bits[224] = {0x00};
        char showbits[225] = {0x00};
 -      int bit;
 -      i = start;
 -      int times = 0;
 -      
 -      if (uidlen > rawbit) {
 -              PrintAndLog("Warning: not enough raw bits to get a full UID");
 -              for (bit = 0; bit < rawbit; bit++) {
 -                      bits[bit] = rawbits[i++];
 -                      // As we cannot know the parity, let's use "." and "/"
 -                      showbits[bit] = '.' + bits[bit];
 -              }
 -              showbits[bit+1]='\0';
 -              PrintAndLog("Partial UID=%s", showbits);
 -              return 0;
 -      } else {
 -              for (bit = 0; bit < uidlen; bit++) {
 -                      bits[bit] = rawbits[i++];
 -                      showbits[bit] = '0' + bits[bit];
 -              }
 -              times = 1;
 -      }
 +  int bit;
 +  i = start;
 +  int times = 0;
        
 -      //convert UID to HEX
 -      uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7;
 -      int idx;
 +  if (uidlen > rawbit) {
 +    PrintAndLog("Warning: not enough raw bits to get a full UID");
 +    for (bit = 0; bit < rawbit; bit++) {
 +      bits[bit] = rawbits[i++];
 +      // As we cannot know the parity, let's use "." and "/"
 +      showbits[bit] = '.' + bits[bit];
 +    }
 +    showbits[bit+1]='\0';
 +    PrintAndLog("Partial UID=%s", showbits);
 +    return 0;
 +  } else {
 +    for (bit = 0; bit < uidlen; bit++) {
 +      bits[bit] = rawbits[i++];
 +      showbits[bit] = '0' + bits[bit];
 +    }
 +    times = 1;
 +  }
 +  
 +  //convert UID to HEX
 +  uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7;
 +  int idx;
        uid1 = uid2 = 0;
        
 -      if (uidlen==64){
 -              for( idx=0; idx<64; idx++) {
 -                              if (showbits[idx] == '0') {
 -                              uid1=(uid1<<1)|(uid2>>31);
 -                              uid2=(uid2<<1)|0;
 -                              } else {
 -                              uid1=(uid1<<1)|(uid2>>31);
 -                              uid2=(uid2<<1)|1;
 -                              
 -                      }
 -              PrintAndLog("UID=%s (%x%08x)", showbits, uid1, uid2);
 -      }
 -      else {
 +  if (uidlen==64){
 +    for( idx=0; idx<64; idx++) {
 +        if (showbits[idx] == '0') {
 +        uid1=(uid1<<1)|(uid2>>31);
 +        uid2=(uid2<<1)|0;
 +        } else {
 +        uid1=(uid1<<1)|(uid2>>31);
 +        uid2=(uid2<<1)|1;
 +        } 
 +      }
 +    PrintAndLog("UID=%s (%x%08x)", showbits, uid1, uid2);
 +  }
 +  else {
                uid3 = uid4 = uid5 = uid6 = uid7 = 0;
  
 -              for( idx=0; idx<224; idx++) {
 -                              uid1=(uid1<<1)|(uid2>>31);
 -                              uid2=(uid2<<1)|(uid3>>31);
 -                              uid3=(uid3<<1)|(uid4>>31);
 -                              uid4=(uid4<<1)|(uid5>>31);
 -                              uid5=(uid5<<1)|(uid6>>31);
 -                              uid6=(uid6<<1)|(uid7>>31);
 +    for( idx=0; idx<224; idx++) {
 +        uid1=(uid1<<1)|(uid2>>31);
 +        uid2=(uid2<<1)|(uid3>>31);
 +        uid3=(uid3<<1)|(uid4>>31);
 +        uid4=(uid4<<1)|(uid5>>31);
 +        uid5=(uid5<<1)|(uid6>>31);
 +        uid6=(uid6<<1)|(uid7>>31);
                        
                        if (showbits[idx] == '0') 
                                uid7 = (uid7<<1) | 0;
                        else 
                                uid7 = (uid7<<1) | 1;
 -                      }
 -              PrintAndLog("UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7);
 -      }
 +      }
 +    PrintAndLog("UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7);
 +  }
  
 -      // Checking UID against next occurrences
 -              int failed = 0;
 +  // Checking UID against next occurrences
 +    int failed = 0;
        for (; i + uidlen <= rawbit;) {
                failed = 0;
 -              for (bit = 0; bit < uidlen; bit++) {
 -                      if (bits[bit] != rawbits[i++]) {
 -                              failed = 1;
 -                              break;
 -                      }
 -              }
 -              if (failed == 1) {
 -                      break;
 -              }
 -              times += 1;
 -      }
 -
 -      PrintAndLog("Occurrences: %d (expected %d)", times, (rawbit - start) / uidlen);
 -
 -      // Remodulating for tag cloning
 +    for (bit = 0; bit < uidlen; bit++) {
 +      if (bits[bit] != rawbits[i++]) {
 +        failed = 1;
 +        break;
 +      }
 +    }
 +    if (failed == 1) {
 +      break;
 +    }
 +    times += 1;
 +  }
 +
 +  PrintAndLog("Occurrences: %d (expected %d)", times, (rawbit - start) / uidlen);
 +
 +  // Remodulating for tag cloning
        // HACK: 2015-01-04 this will have an impact on our new way of seening lf commands (demod) 
        // since this changes graphbuffer data.
 -      GraphTraceLen = 32*uidlen;
 -      i = 0;
 -      int phase = 0;
 -      for (bit = 0; bit < uidlen; bit++) {
 -              if (bits[bit] == 0) {
 -                      phase = 0;
 -              } else {
 -                      phase = 1;
 -              }
 -              int j;
 -              for (j = 0; j < 32; j++) {
 -                      GraphBuffer[i++] = phase;
 -                      phase = !phase;
 -              }
 -      }
 -
 -      RepaintGraphWindow();
 -      return 1;
 +  GraphTraceLen = 32*uidlen;
 +  i = 0;
 +  int phase = 0;
 +  for (bit = 0; bit < uidlen; bit++) {
 +    if (bits[bit] == 0) {
 +      phase = 0;
 +    } else {
 +      phase = 1;
 +    }
 +    int j;
 +    for (j = 0; j < 32; j++) {
 +      GraphBuffer[i++] = phase;
 +      phase = !phase;
 +    }
 +  }
 +
 +  RepaintGraphWindow();
 +  return 1;
  }
  
  int CmdIndalaClone(const char *Cmd)
  {
 -      UsbCommand c;
 +  UsbCommand c;
        unsigned int uid1, uid2, uid3, uid4, uid5, uid6, uid7;
  
        uid1 =  uid2 = uid3 = uid4 = uid5 = uid6 = uid7 = 0;
 -      int n = 0, i = 0;
 -
 -      if (strchr(Cmd,'l') != 0) {
 -              while (sscanf(&Cmd[i++], "%1x", &n ) == 1) {
 -                      uid1 = (uid1 << 4) | (uid2 >> 28);
 -                      uid2 = (uid2 << 4) | (uid3 >> 28);
 -                      uid3 = (uid3 << 4) | (uid4 >> 28);
 -                      uid4 = (uid4 << 4) | (uid5 >> 28);
 -                      uid5 = (uid5 << 4) | (uid6 >> 28);
 -                      uid6 = (uid6 << 4) | (uid7 >> 28);
 -                      uid7 = (uid7 << 4) | (n & 0xf);
 -              }
 -              PrintAndLog("Cloning 224bit tag with UID %x%08x%08x%08x%08x%08x%08x", uid1, uid2, uid3, uid4, uid5, uid6, uid7);
 -              c.cmd = CMD_INDALA_CLONE_TAG_L;
 -              c.d.asDwords[0] = uid1;
 -              c.d.asDwords[1] = uid2;
 -              c.d.asDwords[2] = uid3;
 -              c.d.asDwords[3] = uid4;
 -              c.d.asDwords[4] = uid5;
 -              c.d.asDwords[5] = uid6;
 -              c.d.asDwords[6] = uid7;
 +  int n = 0, i = 0;
 +
 +  if (strchr(Cmd,'l') != 0) {
 +    while (sscanf(&Cmd[i++], "%1x", &n ) == 1) {
 +      uid1 = (uid1 << 4) | (uid2 >> 28);
 +      uid2 = (uid2 << 4) | (uid3 >> 28);
 +      uid3 = (uid3 << 4) | (uid4 >> 28);
 +      uid4 = (uid4 << 4) | (uid5 >> 28);
 +      uid5 = (uid5 << 4) | (uid6 >> 28);
 +      uid6 = (uid6 << 4) | (uid7 >> 28);
 +      uid7 = (uid7 << 4) | (n & 0xf);
 +    }
 +    PrintAndLog("Cloning 224bit tag with UID %x%08x%08x%08x%08x%08x%08x", uid1, uid2, uid3, uid4, uid5, uid6, uid7);
 +    c.cmd = CMD_INDALA_CLONE_TAG_L;
 +    c.d.asDwords[0] = uid1;
 +    c.d.asDwords[1] = uid2;
 +    c.d.asDwords[2] = uid3;
 +    c.d.asDwords[3] = uid4;
 +    c.d.asDwords[4] = uid5;
 +    c.d.asDwords[5] = uid6;
 +    c.d.asDwords[6] = uid7;
        } else {
 -              while (sscanf(&Cmd[i++], "%1x", &n ) == 1) {
 -                      uid1 = (uid1 << 4) | (uid2 >> 28);
 -                      uid2 = (uid2 << 4) | (n & 0xf);
 -              }
 -              PrintAndLog("Cloning 64bit tag with UID %x%08x", uid1, uid2);
 -              c.cmd = CMD_INDALA_CLONE_TAG;
 -              c.arg[0] = uid1;
 -              c.arg[1] = uid2;
 -      }
 -
 -      SendCommand(&c);
 -      return 0;
 +    while (sscanf(&Cmd[i++], "%1x", &n ) == 1) {
 +      uid1 = (uid1 << 4) | (uid2 >> 28);
 +      uid2 = (uid2 << 4) | (n & 0xf);
 +    }
 +    PrintAndLog("Cloning 64bit tag with UID %x%08x", uid1, uid2);
 +    c.cmd = CMD_INDALA_CLONE_TAG;
 +    c.arg[0] = uid1;
 +    c.arg[1] = uid2;
 +  }
 +
 +  SendCommand(&c);
 +  return 0;
  }
  
  int usage_lf_read()
@@@ -492,12 -492,7 +492,12 @@@ int CmdLFRead(const char *Cmd
        //And ship it to device
        UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, {arg1,0,0}};
        SendCommand(&c);
 -      WaitForResponse(CMD_ACK,NULL);
 +      //WaitForResponse(CMD_ACK,NULL);        
 +      if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) {
 +              PrintAndLog("command execution time out");
 +              return 1;
 +      }
 +
        return 0;
  }
  
@@@ -517,687 -512,645 +517,673 @@@ int CmdLFSnoop(const char *Cmd
  
  static void ChkBitstream(const char *str)
  {
 -      int i;
 +  int i;
   
 -      /* convert to bitstream if necessary */
 +  /* convert to bitstream if necessary */
        for (i = 0; i < (int)(GraphTraceLen / 2); i++){
                if (GraphBuffer[i] > 1 || GraphBuffer[i] < 0) {
 -                      CmdGetBitStream("");
 -                      break;
 -              }
 -      }
 +      CmdGetBitStream("");
 +      break;
 +    }
 +  }
  }
- //appears to attempt to simulate manchester
+ //Attempt to simulate any wave in buffer (one bit per output sample)
+ // converts GraphBuffer to bitstream (based on zero crossings) if needed.
  int CmdLFSim(const char *Cmd)
  {
 -      int i,j;
 -      static int gap;
 +  int i,j;
 +  static int gap;
  
 -      sscanf(Cmd, "%i", &gap);
 +  sscanf(Cmd, "%i", &gap);
  
-   /* convert to bitstream if necessary */
+       // convert to bitstream if necessary 
  
 -      ChkBitstream(Cmd);
 +  ChkBitstream(Cmd);
  
-   //can send 512 bits at a time (1 byte sent per bit...)
+       //can send only 512 bits at a time (1 byte sent per bit...)
 -      printf("Sending [%d bytes]", GraphTraceLen);
 -      for (i = 0; i < GraphTraceLen; i += USB_CMD_DATA_SIZE) {
 -              UsbCommand c={CMD_DOWNLOADED_SIM_SAMPLES_125K, {i, 0, 0}};
 -
 -              for (j = 0; j < USB_CMD_DATA_SIZE; j++) {
 -                      c.d.asBytes[j] = GraphBuffer[i+j];
 -              }
 -              SendCommand(&c);
 -              WaitForResponse(CMD_ACK,NULL);
 -              printf(".");
 -      }
 -
 -      printf("\n");
 -      PrintAndLog("Starting to simulate");
 -      UsbCommand c = {CMD_SIMULATE_TAG_125K, {GraphTraceLen, gap, 0}};
 -      SendCommand(&c);
 -      return 0;
 +  printf("Sending [%d bytes]", GraphTraceLen);
 +  for (i = 0; i < GraphTraceLen; i += USB_CMD_DATA_SIZE) {
 +    UsbCommand c={CMD_DOWNLOADED_SIM_SAMPLES_125K, {i, 0, 0}};
 +
 +    for (j = 0; j < USB_CMD_DATA_SIZE; j++) {
 +      c.d.asBytes[j] = GraphBuffer[i+j];
 +    }
 +    SendCommand(&c);
 +    WaitForResponse(CMD_ACK,NULL);
 +    printf(".");
 +  }
 +
 +  printf("\n");
 +  PrintAndLog("Starting to simulate");
 +  UsbCommand c = {CMD_SIMULATE_TAG_125K, {GraphTraceLen, gap, 0}};
 +  SendCommand(&c);
 +  return 0;
  }
  
  int usage_lf_simfsk(void)
  {
 -      //print help
 -      PrintAndLog("Usage: lf simfsk [c <clock>] [i] [H <fcHigh>] [L <fcLow>] [d <hexdata>]");
 -      PrintAndLog("Options:        ");
 -      PrintAndLog("       h              This help");
 -      PrintAndLog("       c <clock>      Manually set clock - can autodetect if using DemodBuffer");
 -      PrintAndLog("       i              invert data");
 -      PrintAndLog("       H <fcHigh>     Manually set the larger Field Clock");
 -      PrintAndLog("       L <fcLow>      Manually set the smaller Field Clock");
 -      //PrintAndLog("       s              TBD- -to enable a gap between playback repetitions - default: no gap");
 -      PrintAndLog("       d <hexdata>    Data to sim as hex - omit to sim from DemodBuffer");
 -      PrintAndLog("\n  NOTE: if you set one clock manually set them all manually");
 -      return 0;
 +  //print help
 +  PrintAndLog("Usage: lf simfsk [c <clock>] [i] [H <fcHigh>] [L <fcLow>] [d <hexdata>]");
 +  PrintAndLog("Options:        ");
 +  PrintAndLog("       h              This help");
 +  PrintAndLog("       c <clock>      Manually set clock - can autodetect if using DemodBuffer");
 +  PrintAndLog("       i              invert data");
 +  PrintAndLog("       H <fcHigh>     Manually set the larger Field Clock");
 +  PrintAndLog("       L <fcLow>      Manually set the smaller Field Clock");
 +  //PrintAndLog("       s              TBD- -to enable a gap between playback repetitions - default: no gap");
 +  PrintAndLog("       d <hexdata>    Data to sim as hex - omit to sim from DemodBuffer");
 +  PrintAndLog("\n  NOTE: if you set one clock manually set them all manually");
 +  return 0;
  }
  
  int usage_lf_simask(void)
  {
 -      //print help
 -      PrintAndLog("Usage: lf simask [c <clock>] [i] [b|m|r] [s] [d <raw hex to sim>]");
 -      PrintAndLog("Options:        ");
 -      PrintAndLog("       h              This help");
 -      PrintAndLog("       c <clock>      Manually set clock - can autodetect if using DemodBuffer");
 -      PrintAndLog("       i              invert data");
 -      PrintAndLog("       b              sim ask/biphase");
 -      PrintAndLog("       m              sim ask/manchester - Default");
 -      PrintAndLog("       r              sim ask/raw");
 -      PrintAndLog("       s              TBD- -to enable a gap between playback repetitions - default: no gap");
 -      PrintAndLog("       d <hexdata>    Data to sim as hex - omit to sim from DemodBuffer");
 -      return 0;
 +  //print help
 +  PrintAndLog("Usage: lf simask [c <clock>] [i] [b|m|r] [s] [d <raw hex to sim>]");
 +  PrintAndLog("Options:        ");
 +  PrintAndLog("       h              This help");
 +  PrintAndLog("       c <clock>      Manually set clock - can autodetect if using DemodBuffer");
 +  PrintAndLog("       i              invert data");
 +  PrintAndLog("       b              sim ask/biphase");
 +  PrintAndLog("       m              sim ask/manchester - Default");
 +  PrintAndLog("       r              sim ask/raw");
 +  PrintAndLog("       s              TBD- -to enable a gap between playback repetitions - default: no gap");
 +  PrintAndLog("       d <hexdata>    Data to sim as hex - omit to sim from DemodBuffer");
 +  return 0;
  }
  
  int usage_lf_simpsk(void)
  {
 -      //print help
 -      PrintAndLog("Usage: lf simpsk [1|2|3] [c <clock>] [i] [r <carrier>] [d <raw hex to sim>]");
 -      PrintAndLog("Options:        ");
 -      PrintAndLog("       h              This help");
 -      PrintAndLog("       c <clock>      Manually set clock - can autodetect if using DemodBuffer");
 -      PrintAndLog("       i              invert data");
 -      PrintAndLog("       1              set PSK1 (default)");
 -      PrintAndLog("       2              set PSK2");
 -      PrintAndLog("       3              set PSK3");
 -      PrintAndLog("       r <carrier>    2|4|8 are valid carriers: default = 2");
 -      PrintAndLog("       d <hexdata>    Data to sim as hex - omit to sim from DemodBuffer");
 -      return 0;
 +  //print help
 +  PrintAndLog("Usage: lf simpsk [1|2|3] [c <clock>] [i] [r <carrier>] [d <raw hex to sim>]");
 +  PrintAndLog("Options:        ");
 +  PrintAndLog("       h              This help");
 +  PrintAndLog("       c <clock>      Manually set clock - can autodetect if using DemodBuffer");
 +  PrintAndLog("       i              invert data");
 +  PrintAndLog("       1              set PSK1 (default)");
 +  PrintAndLog("       2              set PSK2");
 +  PrintAndLog("       3              set PSK3");
 +  PrintAndLog("       r <carrier>    2|4|8 are valid carriers: default = 2");
 +  PrintAndLog("       d <hexdata>    Data to sim as hex - omit to sim from DemodBuffer");
 +  return 0;
  }
  
  // by marshmellow - sim ask data given clock, fcHigh, fcLow, invert 
  // - allow pull data from DemodBuffer
  int CmdLFfskSim(const char *Cmd)
  {
-   //might be able to autodetect FC and clock from Graphbuffer if using demod buffer
-   //will need FChigh, FClow, Clock, and bitstream
+       //might be able to autodetect FCs and clock from Graphbuffer if using demod buffer
+       // otherwise will need FChigh, FClow, Clock, and bitstream
 -      uint8_t fcHigh=0, fcLow=0, clk=0;
 -      uint8_t invert=0;
 -      bool errors = FALSE;
 -      char hexData[32] = {0x00}; // store entered hex data
 -      uint8_t data[255] = {0x00}; 
 -      int dataLen = 0;
 -      uint8_t cmdp = 0;
 -      while(param_getchar(Cmd, cmdp) != 0x00)
 -      {
 -              switch(param_getchar(Cmd, cmdp))
 -              {
 -              case 'h':
 -                      return usage_lf_simfsk();
 -              case 'i':
 -                      invert = 1;
 -                      cmdp++;
 -                      break;
 -              case 'c':
 -                      errors |= param_getdec(Cmd,cmdp+1,&clk);
 -                      cmdp+=2;
 -                      break;
 -              case 'H':
 -                      errors |= param_getdec(Cmd,cmdp+1,&fcHigh);
 -                      cmdp+=2;
 -                      break;
 -              case 'L':
 -                      errors |= param_getdec(Cmd,cmdp+1,&fcLow);
 -                      cmdp+=2;
 -                      break;
 -              //case 's':
 -              //  separator=1;
 -              //  cmdp++;
 -              //  break;
 -              case 'd':
 -                      dataLen = param_getstr(Cmd, cmdp+1, hexData);
 -                      if (dataLen==0) {
 -                              errors=TRUE; 
 -                      } else {
 -                              dataLen = hextobinarray((char *)data, hexData);
 -                      }   
 -                      if (dataLen==0) errors=TRUE; 
 -                      if (errors) PrintAndLog ("Error getting hex data");
 -                      cmdp+=2;
 -                      break;
 -              default:
 -                      PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
 -                      errors = TRUE;
 -                      break;
 -              }
 -              if(errors) break;
 -      }
 -      if(cmdp == 0 && DemodBufferLen == 0)
 -      {
 -              errors = TRUE;// No args
 -      }
 -
 -      //Validations
 -      if(errors)
 -      {
 -              return usage_lf_simfsk();
 -      }
 -
 -      if (dataLen == 0){ //using DemodBuffer 
 -              if (clk==0 || fcHigh==0 || fcLow==0){ //manual settings must set them all
 -                      uint8_t ans = fskClocks(&fcHigh, &fcLow, &clk, 0);
 -                      if (ans==0){
 -                              if (!fcHigh) fcHigh=10;
 -                              if (!fcLow) fcLow=8;
 -                              if (!clk) clk=50;
 -                      }
 -              }
 -      } else {
 -              setDemodBuf(data, dataLen, 0);
 -      }
 +  uint8_t fcHigh=0, fcLow=0, clk=0;
 +  uint8_t invert=0;
 +  bool errors = FALSE;
 +  char hexData[32] = {0x00}; // store entered hex data
 +  uint8_t data[255] = {0x00}; 
 +  int dataLen = 0;
 +  uint8_t cmdp = 0;
 +  while(param_getchar(Cmd, cmdp) != 0x00)
 +  {
 +    switch(param_getchar(Cmd, cmdp))
 +    {
 +    case 'h':
 +      return usage_lf_simfsk();
 +    case 'i':
 +      invert = 1;
 +      cmdp++;
 +      break;
 +    case 'c':
 +      errors |= param_getdec(Cmd,cmdp+1,&clk);
 +      cmdp+=2;
 +      break;
 +    case 'H':
 +      errors |= param_getdec(Cmd,cmdp+1,&fcHigh);
 +      cmdp+=2;
 +      break;
 +    case 'L':
 +      errors |= param_getdec(Cmd,cmdp+1,&fcLow);
 +      cmdp+=2;
 +      break;
 +    //case 's':
 +    //  separator=1;
 +    //  cmdp++;
 +    //  break;
 +    case 'd':
 +      dataLen = param_getstr(Cmd, cmdp+1, hexData);
 +      if (dataLen==0) {
 +        errors=TRUE; 
 +      } else {
 +        dataLen = hextobinarray((char *)data, hexData);
 +      }   
 +      if (dataLen==0) errors=TRUE; 
 +      if (errors) PrintAndLog ("Error getting hex data");
 +      cmdp+=2;
 +      break;
 +    default:
 +      PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
 +      errors = TRUE;
 +      break;
 +    }
 +    if(errors) break;
 +  }
 +  if(cmdp == 0 && DemodBufferLen == 0)
 +  {
 +    errors = TRUE;// No args
 +  }
 +
 +  //Validations
 +  if(errors)
 +  {
 +    return usage_lf_simfsk();
 +  }
 +
 +  if (dataLen == 0){ //using DemodBuffer 
 +    if (clk==0 || fcHigh==0 || fcLow==0){ //manual settings must set them all
 +      uint8_t ans = fskClocks(&fcHigh, &fcLow, &clk, 0);
 +      if (ans==0){
 +        if (!fcHigh) fcHigh=10;
 +        if (!fcLow) fcLow=8;
 +        if (!clk) clk=50;
 +      }
 +    }
 +  } else {
 +    setDemodBuf(data, dataLen, 0);
 +  }
+       //default if not found
 -      if (clk == 0) clk = 50;
 -      if (fcHigh == 0) fcHigh = 10;
 -      if (fcLow == 0) fcLow = 8;
 -
 -      uint16_t arg1, arg2;
 -      arg1 = fcHigh << 8 | fcLow;
 -      arg2 = invert << 8 | clk;
 -      size_t size = DemodBufferLen;
 -      if (size > USB_CMD_DATA_SIZE) {
 -              PrintAndLog("DemodBuffer too long for current implementation - length: %d - max: %d", size, USB_CMD_DATA_SIZE);
 -              size = USB_CMD_DATA_SIZE;
 -      
 -      UsbCommand c = {CMD_FSK_SIM_TAG, {arg1, arg2, size}};
 -
 -      memcpy(c.d.asBytes, DemodBuffer, size);
 -      SendCommand(&c);
 -      return 0;
 +  if (clk == 0) clk = 50;
 +  if (fcHigh == 0) fcHigh = 10;
 +  if (fcLow == 0) fcLow = 8;
 +
 +  uint16_t arg1, arg2;
 +  arg1 = fcHigh << 8 | fcLow;
 +  arg2 = invert << 8 | clk;
 +  size_t size = DemodBufferLen;
 +  if (size > USB_CMD_DATA_SIZE) {
 +    PrintAndLog("DemodBuffer too long for current implementation - length: %d - max: %d", size, USB_CMD_DATA_SIZE);
 +    size = USB_CMD_DATA_SIZE;
 +  } 
 +  UsbCommand c = {CMD_FSK_SIM_TAG, {arg1, arg2, size}};
 +
 +  memcpy(c.d.asBytes, DemodBuffer, size);
 +  SendCommand(&c);
 +  return 0;
  }
  
  // by marshmellow - sim ask data given clock, invert, manchester or raw, separator 
  // - allow pull data from DemodBuffer
  int CmdLFaskSim(const char *Cmd)
  {
 -      //autodetect clock from Graphbuffer if using demod buffer
 +  //autodetect clock from Graphbuffer if using demod buffer
-   //will need clock, invert, manchester/raw as m or r, separator as s, and bitstream
+       // needs clock, invert, manchester/raw as m or r, separator as s, and bitstream
 -      uint8_t encoding = 1, separator = 0;
 -      uint8_t clk=0, invert=0;
 -      bool errors = FALSE;
 -      char hexData[32] = {0x00}; 
 -      uint8_t data[255]= {0x00}; // store entered hex data
 -      int dataLen = 0;
 -      uint8_t cmdp = 0;
 -      while(param_getchar(Cmd, cmdp) != 0x00)
 -      {
 -              switch(param_getchar(Cmd, cmdp))
 -              {
 -              case 'h':
 -                      return usage_lf_simask();
 -              case 'i':
 -                      invert = 1;
 -                      cmdp++;
 -                      break;
 -              case 'c':
 -                      errors |= param_getdec(Cmd,cmdp+1,&clk);
 -                      cmdp+=2;
 -                      break;
 -              case 'b':
 -                      encoding=2; //biphase
 -                      cmdp++;
 -                      break;
 -              case 'm':
 -                      encoding=1;
 -                      cmdp++;
 -                      break;
 -              case 'r':
 -                      encoding=0;
 -                      cmdp++;
 -                      break;
 -              case 's':
 -                      separator=1;
 -                      cmdp++;
 -                      break;
 -              case 'd':
 -                      dataLen = param_getstr(Cmd, cmdp+1, hexData);
 -                      if (dataLen==0) {
 -                              errors=TRUE; 
 -                      } else {
 -                              dataLen = hextobinarray((char *)data, hexData);
 -                      }
 -                      if (dataLen==0) errors=TRUE; 
 -                      if (errors) PrintAndLog ("Error getting hex data, datalen: %d",dataLen);
 -                              cmdp+=2;
 -                      break;
 -              default:
 -                      PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
 -                      errors = TRUE;
 -                      break;
 -              }
 -              if(errors) break;
 -      }
 -      if(cmdp == 0 && DemodBufferLen == 0)
 -      {
 -              errors = TRUE;// No args
 -      }
 -
 -      //Validations
 -      if(errors)
 -      {
 -              return usage_lf_simask();
 -      }
 -      if (dataLen == 0){ //using DemodBuffer
 -              if (clk == 0) clk = GetAskClock("0", false, false);
 -      } else {
 -              setDemodBuf(data, dataLen, 0);
 -      }
 -      if (clk == 0) clk = 64;
 -      if (encoding == 0) clk = clk/2; //askraw needs to double the clock speed
 -      uint16_t arg1, arg2;
 -      size_t size=DemodBufferLen;
 -      arg1 = clk << 8 | encoding;
 -      arg2 = invert << 8 | separator;
 -      if (size > USB_CMD_DATA_SIZE) {
 -              PrintAndLog("DemodBuffer too long for current implementation - length: %d - max: %d", size, USB_CMD_DATA_SIZE);
 -              size = USB_CMD_DATA_SIZE;
 -      }
 -      UsbCommand c = {CMD_ASK_SIM_TAG, {arg1, arg2, size}};
 -      PrintAndLog("preparing to sim ask data: %d bits", size);
 -      memcpy(c.d.asBytes, DemodBuffer, size);
 -      SendCommand(&c);
 -      return 0;
 +  uint8_t encoding = 1, separator = 0;
-   //char cmdp = Cmd[0], par3='m', par4=0;
 +  uint8_t clk=0, invert=0;
 +  bool errors = FALSE;
 +  char hexData[32] = {0x00}; 
 +  uint8_t data[255]= {0x00}; // store entered hex data
 +  int dataLen = 0;
 +  uint8_t cmdp = 0;
 +  while(param_getchar(Cmd, cmdp) != 0x00)
 +  {
 +    switch(param_getchar(Cmd, cmdp))
 +    {
 +    case 'h':
 +      return usage_lf_simask();
 +    case 'i':
 +      invert = 1;
 +      cmdp++;
 +      break;
 +    case 'c':
 +      errors |= param_getdec(Cmd,cmdp+1,&clk);
 +      cmdp+=2;
 +      break;
 +    case 'b':
 +      encoding=2; //biphase
 +      cmdp++;
 +      break;
 +    case 'm':
 +      encoding=1;
 +      cmdp++;
 +      break;
 +    case 'r':
 +      encoding=0;
 +      cmdp++;
 +      break;
 +    case 's':
 +      separator=1;
 +      cmdp++;
 +      break;
 +    case 'd':
 +      dataLen = param_getstr(Cmd, cmdp+1, hexData);
 +      if (dataLen==0) {
 +        errors=TRUE; 
 +      } else {
 +        dataLen = hextobinarray((char *)data, hexData);
 +      }
 +      if (dataLen==0) errors=TRUE; 
 +      if (errors) PrintAndLog ("Error getting hex data, datalen: %d",dataLen);
 +        cmdp+=2;
 +      break;
 +    default:
 +      PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
 +      errors = TRUE;
 +      break;
 +    }
 +    if(errors) break;
 +  }
 +  if(cmdp == 0 && DemodBufferLen == 0)
 +  {
 +    errors = TRUE;// No args
 +  }
 +
 +  //Validations
 +  if(errors)
 +  {
 +    return usage_lf_simask();
 +  }
 +  if (dataLen == 0){ //using DemodBuffer
 +    if (clk == 0) clk = GetAskClock("0", false, false);
 +  } else {
 +    setDemodBuf(data, dataLen, 0);
 +  }
 +  if (clk == 0) clk = 64;
 +  if (encoding == 0) clk = clk/2; //askraw needs to double the clock speed
 +  uint16_t arg1, arg2;
 +  size_t size=DemodBufferLen;
 +  arg1 = clk << 8 | encoding;
 +  arg2 = invert << 8 | separator;
 +  if (size > USB_CMD_DATA_SIZE) {
 +    PrintAndLog("DemodBuffer too long for current implementation - length: %d - max: %d", size, USB_CMD_DATA_SIZE);
 +    size = USB_CMD_DATA_SIZE;
 +  }
 +  UsbCommand c = {CMD_ASK_SIM_TAG, {arg1, arg2, size}};
 +  PrintAndLog("preparing to sim ask data: %d bits", size);
 +  memcpy(c.d.asBytes, DemodBuffer, size);
 +  SendCommand(&c);
 +  return 0;
  }
  
  // by marshmellow - sim psk data given carrier, clock, invert 
  // - allow pull data from DemodBuffer or parameters
  int CmdLFpskSim(const char *Cmd)
  {
 -      //might be able to autodetect FC and clock from Graphbuffer if using demod buffer
 -      //will need carrier, Clock, and bitstream
 -      uint8_t carrier=0, clk=0;
 -      uint8_t invert=0;
 -      bool errors = FALSE;
 -      char hexData[32] = {0x00}; // store entered hex data
 -      uint8_t data[255] = {0x00}; 
 -      int dataLen = 0;
 -      uint8_t cmdp = 0;
 -      uint8_t pskType = 1;
 -      while(param_getchar(Cmd, cmdp) != 0x00)
 -      {
 -              switch(param_getchar(Cmd, cmdp))
 -              {
 -              case 'h':
 -                      return usage_lf_simpsk();
 -              case 'i':
 -                      invert = 1;
 -                      cmdp++;
 -                      break;
 -              case 'c':
 -                      errors |= param_getdec(Cmd,cmdp+1,&clk);
 -                      cmdp+=2;
 -                      break;
 -              case 'r':
 -                      errors |= param_getdec(Cmd,cmdp+1,&carrier);
 -                      cmdp+=2;
 -                      break;
 -              case '1':
 -                      pskType=1;
 -                      cmdp++;
 -                      break;
 -              case '2':
 -                      pskType=2;
 -                      cmdp++;
 -                      break;
 -              case '3':
 -                      pskType=3;
 -                      cmdp++;
 -                      break;
 -              case 'd':
 -                      dataLen = param_getstr(Cmd, cmdp+1, hexData);
 -                      if (dataLen==0) {
 -                              errors=TRUE; 
 -                      } else {
 -                              dataLen = hextobinarray((char *)data, hexData);
 -                      }    
 -                      if (dataLen==0) errors=TRUE; 
 -                      if (errors) PrintAndLog ("Error getting hex data");
 -                      cmdp+=2;
 -                      break;
 -              default:
 -                      PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
 -                      errors = TRUE;
 -                      break;
 -              }
 -              if (errors) break;
 -      }
 -      if (cmdp == 0 && DemodBufferLen == 0)
 -      {
 -              errors = TRUE;// No args
 -      }
 -
 -      //Validations
 -      if (errors)
 -      {
 -              return usage_lf_simpsk();
 -      }
 -      if (dataLen == 0){ //using DemodBuffer
 -              PrintAndLog("Getting Clocks");
 -              if (clk==0) clk = GetPskClock("", FALSE, FALSE);
 -              PrintAndLog("clk: %d",clk);
 -              if (!carrier) carrier = GetPskCarrier("", FALSE, FALSE); 
 -              PrintAndLog("carrier: %d", carrier);
 -      } else {
 -              setDemodBuf(data, dataLen, 0);
 -      }
 -
 -      if (clk <= 0) clk = 32;
 -      if (carrier == 0) carrier = 2;
 -      if (pskType != 1){
 -              if (pskType == 2){
 -                      //need to convert psk2 to psk1 data before sim
 -                      psk2TOpsk1(DemodBuffer, DemodBufferLen);
 -              } else {
 -                      PrintAndLog("Sorry, PSK3 not yet available");
 -              }
 -      }
 -      uint16_t arg1, arg2;
 -      arg1 = clk << 8 | carrier;
 -      arg2 = invert;
 -      size_t size=DemodBufferLen;
 -      if (size > USB_CMD_DATA_SIZE) {
 -              PrintAndLog("DemodBuffer too long for current implementation - length: %d - max: %d", size, USB_CMD_DATA_SIZE);
 -              size=USB_CMD_DATA_SIZE;
 -      }
 -      UsbCommand c = {CMD_PSK_SIM_TAG, {arg1, arg2, size}};
 -      PrintAndLog("DEBUG: Sending DemodBuffer Length: %d", size);
 -      memcpy(c.d.asBytes, DemodBuffer, size);
 -      SendCommand(&c);
 -      
 -      return 0;
 +  //might be able to autodetect FC and clock from Graphbuffer if using demod buffer
 +  //will need carrier, Clock, and bitstream
 +  uint8_t carrier=0, clk=0;
 +  uint8_t invert=0;
 +  bool errors = FALSE;
 +  char hexData[32] = {0x00}; // store entered hex data
 +  uint8_t data[255] = {0x00}; 
 +  int dataLen = 0;
 +  uint8_t cmdp = 0;
 +  uint8_t pskType = 1;
 +  while(param_getchar(Cmd, cmdp) != 0x00)
 +  {
 +    switch(param_getchar(Cmd, cmdp))
 +    {
 +    case 'h':
 +      return usage_lf_simpsk();
 +    case 'i':
 +      invert = 1;
 +      cmdp++;
 +      break;
 +    case 'c':
 +      errors |= param_getdec(Cmd,cmdp+1,&clk);
 +      cmdp+=2;
 +      break;
 +    case 'r':
 +      errors |= param_getdec(Cmd,cmdp+1,&carrier);
 +      cmdp+=2;
 +      break;
 +    case '1':
 +      pskType=1;
 +      cmdp++;
 +      break;
 +    case '2':
 +      pskType=2;
 +      cmdp++;
 +      break;
 +    case '3':
 +      pskType=3;
 +      cmdp++;
 +      break;
 +    case 'd':
 +      dataLen = param_getstr(Cmd, cmdp+1, hexData);
 +      if (dataLen==0) {
 +        errors=TRUE; 
 +      } else {
 +        dataLen = hextobinarray((char *)data, hexData);
 +      }    
 +      if (dataLen==0) errors=TRUE; 
 +      if (errors) PrintAndLog ("Error getting hex data");
 +      cmdp+=2;
 +      break;
 +    default:
 +      PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
 +      errors = TRUE;
 +      break;
 +    }
 +    if (errors) break;
 +  }
 +  if (cmdp == 0 && DemodBufferLen == 0)
 +  {
 +    errors = TRUE;// No args
 +  }
 +
 +  //Validations
 +  if (errors)
 +  {
 +    return usage_lf_simpsk();
 +  }
 +  if (dataLen == 0){ //using DemodBuffer
 +    PrintAndLog("Getting Clocks");
 +    if (clk==0) clk = GetPskClock("", FALSE, FALSE);
 +    PrintAndLog("clk: %d",clk);
 +    if (!carrier) carrier = GetPskCarrier("", FALSE, FALSE); 
 +    PrintAndLog("carrier: %d", carrier);
 +  } else {
 +    setDemodBuf(data, dataLen, 0);
 +  }
 +
 +  if (clk <= 0) clk = 32;
 +  if (carrier == 0) carrier = 2;
 +  if (pskType != 1){
 +    if (pskType == 2){
 +      //need to convert psk2 to psk1 data before sim
 +      psk2TOpsk1(DemodBuffer, DemodBufferLen);
 +    } else {
 +      PrintAndLog("Sorry, PSK3 not yet available");
 +    }
 +  }
 +  uint16_t arg1, arg2;
 +  arg1 = clk << 8 | carrier;
 +  arg2 = invert;
 +  size_t size=DemodBufferLen;
 +  if (size > USB_CMD_DATA_SIZE) {
 +    PrintAndLog("DemodBuffer too long for current implementation - length: %d - max: %d", size, USB_CMD_DATA_SIZE);
 +    size=USB_CMD_DATA_SIZE;
 +  }
 +  UsbCommand c = {CMD_PSK_SIM_TAG, {arg1, arg2, size}};
 +  PrintAndLog("DEBUG: Sending DemodBuffer Length: %d", size);
 +  memcpy(c.d.asBytes, DemodBuffer, size);
 +  SendCommand(&c);
 +  
 +  return 0;
  }
  
  int CmdLFSimBidir(const char *Cmd)
  {
 -      // Set ADC to twice the carrier for a slight supersampling
 -      // HACK: not implemented in ARMSRC.
 -      PrintAndLog("Not implemented yet.");
 -      UsbCommand c = {CMD_LF_SIMULATE_BIDIR, {47, 384, 0}};
 -      SendCommand(&c);
 -      return 0;
 +  // Set ADC to twice the carrier for a slight supersampling
 +  // HACK: not implemented in ARMSRC.
 +  PrintAndLog("Not implemented yet.");
 +  UsbCommand c = {CMD_LF_SIMULATE_BIDIR, {47, 384, 0}};
 +  SendCommand(&c);
 +  return 0;
  }
  
- /* simulate an LF Manchester encoded tag with specified bitstream, clock rate and inter-id gap */
- /*
- int CmdLFSimManchester(const char *Cmd)
- {
-   static int clock, gap;
-   static char data[1024], gapstring[8];
-   sscanf(Cmd, "%i %s %i", &clock, &data[0], &gap);
-   ClearGraph(0);
-   for (int i = 0; i < strlen(data) ; ++i)
-     AppendGraph(0, clock, data[i]- '0');
-   CmdManchesterMod("");
-   RepaintGraphWindow();
-   sprintf(&gapstring[0], "%i", gap);
-   CmdLFSim(gapstring);
-   return 0;
- }
- */
  int CmdVchDemod(const char *Cmd)
  {
 -      // Is this the entire sync pattern, or does this also include some
 -      // data bits that happen to be the same everywhere? That would be
 -      // lovely to know.
 -      static const int SyncPattern[] = {
 -              1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
 -              1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
 -              1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
 -              1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
 -              1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
 -              1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
 -              1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
 -              1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
 -              1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
 -              1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
 -      };
 -
 -      // So first, we correlate for the sync pattern, and mark that.
 -      int bestCorrel = 0, bestPos = 0;
 -      int i;
 -      // It does us no good to find the sync pattern, with fewer than
 -      // 2048 samples after it...
 -      for (i = 0; i < (GraphTraceLen-2048); i++) {
 -              int sum = 0;
 -              int j;
 -              for (j = 0; j < arraylen(SyncPattern); j++) {
 -                      sum += GraphBuffer[i+j]*SyncPattern[j];
 -              }
 -              if (sum > bestCorrel) {
 -                      bestCorrel = sum;
 -                      bestPos = i;
 -              }
 -      }
 -      PrintAndLog("best sync at %d [metric %d]", bestPos, bestCorrel);
 -
 -      char bits[257];
 -      bits[256] = '\0';
 -
 -      int worst = INT_MAX;
 -      int worstPos = 0;
 -
 -      for (i = 0; i < 2048; i += 8) {
 -              int sum = 0;
 -              int j;
 -              for (j = 0; j < 8; j++) {
 -                      sum += GraphBuffer[bestPos+i+j];
 -              }
 -              if (sum < 0) {
 -                      bits[i/8] = '.';
 -              } else {
 -                      bits[i/8] = '1';
 -              }
 -              if(abs(sum) < worst) {
 -                      worst = abs(sum);
 -                      worstPos = i;
 -              }
 -      }
 -      PrintAndLog("bits:");
 -      PrintAndLog("%s", bits);
 -      PrintAndLog("worst metric: %d at pos %d", worst, worstPos);
 -
 -      if (strcmp(Cmd, "clone")==0) {
 -              GraphTraceLen = 0;
 -              char *s;
 -              for(s = bits; *s; s++) {
 -                      int j;
 -                      for(j = 0; j < 16; j++) {
 -                              GraphBuffer[GraphTraceLen++] = (*s == '1') ? 1 : 0;
 -                      }
 -              }
 -              RepaintGraphWindow();
 -      }
 -      return 0;
 +  // Is this the entire sync pattern, or does this also include some
 +  // data bits that happen to be the same everywhere? That would be
 +  // lovely to know.
 +  static const int SyncPattern[] = {
 +    1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
 +    1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
 +    1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
 +    1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
 +    1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
 +    1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
 +    1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
 +    1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
 +    1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
 +    1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
 +  };
 +
 +  // So first, we correlate for the sync pattern, and mark that.
 +  int bestCorrel = 0, bestPos = 0;
 +  int i;
 +  // It does us no good to find the sync pattern, with fewer than
 +  // 2048 samples after it...
 +  for (i = 0; i < (GraphTraceLen-2048); i++) {
 +    int sum = 0;
 +    int j;
 +    for (j = 0; j < arraylen(SyncPattern); j++) {
 +      sum += GraphBuffer[i+j]*SyncPattern[j];
 +    }
 +    if (sum > bestCorrel) {
 +      bestCorrel = sum;
 +      bestPos = i;
 +    }
 +  }
 +  PrintAndLog("best sync at %d [metric %d]", bestPos, bestCorrel);
 +
 +  char bits[257];
 +  bits[256] = '\0';
 +
 +  int worst = INT_MAX;
 +  int worstPos = 0;
 +
 +  for (i = 0; i < 2048; i += 8) {
 +    int sum = 0;
 +    int j;
 +    for (j = 0; j < 8; j++) {
 +      sum += GraphBuffer[bestPos+i+j];
 +    }
 +    if (sum < 0) {
 +      bits[i/8] = '.';
 +    } else {
 +      bits[i/8] = '1';
 +    }
 +    if(abs(sum) < worst) {
 +      worst = abs(sum);
 +      worstPos = i;
 +    }
 +  }
 +  PrintAndLog("bits:");
 +  PrintAndLog("%s", bits);
 +  PrintAndLog("worst metric: %d at pos %d", worst, worstPos);
 +
 +  if (strcmp(Cmd, "clone")==0) {
 +    GraphTraceLen = 0;
 +    char *s;
 +    for(s = bits; *s; s++) {
 +      int j;
 +      for(j = 0; j < 16; j++) {
 +        GraphBuffer[GraphTraceLen++] = (*s == '1') ? 1 : 0;
 +      }
 +    }
 +    RepaintGraphWindow();
 +  }
 +  return 0;
  }
  
  //by marshmellow
  int CmdLFfind(const char *Cmd)
  {
 -      int ans=0;
 -      char cmdp = param_getchar(Cmd, 0);
 -      char testRaw = param_getchar(Cmd, 1);
 -      if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') {
 -              PrintAndLog("Usage:  lf search <0|1> [u]");
 -              PrintAndLog("     <use data from Graphbuffer> , if not set, try reading data from tag.");
 -              PrintAndLog("     [Search for Unknown tags] , if not set, reads only known tags.");
 -              PrintAndLog("");
 -              PrintAndLog("    sample: lf search     = try reading data from tag & search for known tags");
 -              PrintAndLog("          : lf search 1   = use data from GraphBuffer & search for known tags");
 -              PrintAndLog("          : lf search u   = try reading data from tag & search for known and unknown tags");
 -              PrintAndLog("          : lf search 1 u = use data from GraphBuffer & search for known and unknown tags");
 -
 -              return 0;
 -      }
 -
 -      if (!offline && (cmdp != '1')){
 +  int ans=0;
 +  char cmdp = param_getchar(Cmd, 0);
 +  char testRaw = param_getchar(Cmd, 1);
 +  if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') {
 +    PrintAndLog("Usage:  lf search <0|1> [u]");
 +    PrintAndLog("     <use data from Graphbuffer> , if not set, try reading data from tag.");
 +    PrintAndLog("     [Search for Unknown tags] , if not set, reads only known tags.");
 +    PrintAndLog("");
 +    PrintAndLog("    sample: lf search     = try reading data from tag & search for known tags");
 +    PrintAndLog("          : lf search 1   = use data from GraphBuffer & search for known tags");
 +    PrintAndLog("          : lf search u   = try reading data from tag & search for known and unknown tags");
 +    PrintAndLog("          : lf search 1 u = use data from GraphBuffer & search for known and unknown tags");
 +    return 0;
 +  }
 +
 +  if (!offline && (cmdp != '1')){
-     ans=CmdLFRead("");
-     ans=CmdSamples("20000");
+               CmdLFRead("s");
+               getSamples("30000",false);
 -      } else if (GraphTraceLen < 1000) {
 -              PrintAndLog("Data in Graphbuffer was too small.");
 -              return 0;
 -      }
 -      if (cmdp == 'u' || cmdp == 'U') testRaw = 'u';
 -
 -      PrintAndLog("NOTE: some demods output possible binary\n  if it finds something that looks like a tag");
 -      PrintAndLog("False Positives ARE possible\n");  
 -      PrintAndLog("\nChecking for known tags:\n");
 -
 -      ans=CmdFSKdemodIO("");
 -      if (ans>0) {
 -              PrintAndLog("\nValid IO Prox ID Found!");
 -              return 1;
 -      }
 -
 -      ans=CmdFSKdemodPyramid("");
 -      if (ans>0) {
 -              PrintAndLog("\nValid Pyramid ID Found!");
 -              return 1;
 -      }
 -
 -      ans=CmdFSKdemodParadox("");
 -      if (ans>0) {
 -              PrintAndLog("\nValid Paradox ID Found!");
 -              return 1;
 -      }
 -
 -      ans=CmdFSKdemodAWID("");
 -      if (ans>0) {
 -              PrintAndLog("\nValid AWID ID Found!");
 -              return 1;
 -      }
 -
 -      ans=CmdFSKdemodHID("");
 -      if (ans>0) {
 -              PrintAndLog("\nValid HID Prox ID Found!");
 -              return 1;
 -      }
 -
 -      //add psk and indala
 -      ans=CmdIndalaDecode("");
 -      if (ans>0) {
 -              PrintAndLog("\nValid Indala ID Found!");
 -              return 1;
 -      }
 -
 -      ans=CmdAskEM410xDemod("");
 -      if (ans>0) {
 -              PrintAndLog("\nValid EM410x ID Found!");
 -              return 1;
 -      }
 -
 -      ans=CmdG_Prox_II_Demod("");
 -      if (ans>0) {
 -              PrintAndLog("\nValid G Prox II ID Found!");
 -              return 1;
 -      }
 +  } else if (GraphTraceLen < 1000) {
 +    PrintAndLog("Data in Graphbuffer was too small.");
 +    return 0;
 +  }
 +  if (cmdp == 'u' || cmdp == 'U') testRaw = 'u';
 +
 +  PrintAndLog("NOTE: some demods output possible binary\n  if it finds something that looks like a tag");
 +  PrintAndLog("False Positives ARE possible\n");  
 +  PrintAndLog("\nChecking for known tags:\n");
 +
 +  ans=CmdFSKdemodIO("");
 +  
 +  if (ans>0) {
 +    PrintAndLog("\nValid IO Prox ID Found!");
 +    return 1;
 +  }
 +
 +  ans=CmdFSKdemodPyramid("");
 +  if (ans>0) {
 +    PrintAndLog("\nValid Pyramid ID Found!");
 +    return 1;
 +  }
 +
 +  ans=CmdFSKdemodParadox("");
 +  if (ans>0) {
 +    PrintAndLog("\nValid Paradox ID Found!");
 +    return 1;
 +  }
 +
 +  ans=CmdFSKdemodAWID("");
 +  if (ans>0) {
 +    PrintAndLog("\nValid AWID ID Found!");
 +    return 1;
 +  }
 +
 +  ans=CmdFSKdemodHID("");
 +  if (ans>0) {
 +    PrintAndLog("\nValid HID Prox ID Found!");
 +    return 1;
 +  }
 +
 +  //add psk and indala
 +  ans=CmdIndalaDecode("");
 +  if (ans>0) {
 +    PrintAndLog("\nValid Indala ID Found!");
 +    return 1;
 +  }
 +
 +  ans=CmdAskEM410xDemod("");
 +  if (ans>0) {
 +    PrintAndLog("\nValid EM410x ID Found!");
 +    return 1;
 +  }
 +
 +  ans=CmdG_Prox_II_Demod("");
 +  if (ans>0) {
 +    PrintAndLog("\nValid G Prox II ID Found!");
 +    return 1;
 +  }
  
 -      PrintAndLog("\nNo Known Tags Found!\n");
 -      if (testRaw=='u' || testRaw=='U'){
 -              //test unknown tag formats (raw mode)
 -              PrintAndLog("\nChecking for Unknown tags:\n");
 -              ans=AutoCorrelate(4000, FALSE, FALSE);
 -              if (ans > 0) PrintAndLog("Possible Auto Correlation of %d repeating samples",ans);
 -              ans=GetFskClock("",FALSE,FALSE); 
 -              if (ans != 0){ //fsk
 -                      ans=FSKrawDemod("",TRUE);
 -                      if (ans>0) {
 -                              PrintAndLog("\nUnknown FSK Modulated Tag Found!");
 -                              return 1;
+       ans=EM4x50Read("", false);
+       if (ans>0) {
+               PrintAndLog("\nValid EM4x50 ID Found!");
+               return 1;
+       }       
+       ans=CmdPSKNexWatch("");
+       if (ans>0) {
+               PrintAndLog("\nValid NexWatch ID Found!");
+               return 1;
+       }
 +  PrintAndLog("\nNo Known Tags Found!\n");
 +  if (testRaw=='u' || testRaw=='U'){
 +    //test unknown tag formats (raw mode)
 +    PrintAndLog("\nChecking for Unknown tags:\n");
 +    ans=AutoCorrelate(4000, FALSE, FALSE);
 +      
 +    if (ans > 0) {
 +
 +              PrintAndLog("Possible Auto Correlation of %d repeating samples",ans);
 +
 +              if ( ans % 8 == 0)  {
 +                      int bytes = (ans / 8);
 +                      PrintAndLog("Possible %d bytes", bytes);
 +                      int blocks = 0;
 +                      if ( bytes % 2 == 0) {
 +                              blocks = (bytes / 2);   
 +                              PrintAndLog("Possible  2 blocks, width %d", blocks);
 +                      }
 +                      if ( bytes % 4 == 0) {
 +                              blocks = (bytes / 4);   
 +                              PrintAndLog("Possible  4 blocks, width %d", blocks);
 +                      }
 +                      if ( bytes % 8 == 0) {
 +                              blocks = (bytes / 8);   
 +                              PrintAndLog("Possible  8 blocks, width %d", blocks);
 +                      }
 +                      if ( bytes % 16 == 0) {
 +                              blocks = (bytes / 16);  
 +                              PrintAndLog("Possible 16 blocks, width %d", blocks);
                        }
                }
 -              ans=ASKDemod("0 0 0",TRUE,FALSE,1);
 -              if (ans>0) {
 -                      PrintAndLog("\nUnknown ASK Modulated and Manchester encoded Tag Found!");
 -                      PrintAndLog("\nif it does not look right it could instead be ASK/Biphase - try 'data rawdemod ab'");
 -                      return 1;
 -              }
 -              ans=CmdPSK1rawDemod("");
 -              if (ans>0) {
 -                      PrintAndLog("Possible unknown PSK1 Modulated Tag Found above!\n\nCould also be PSK2 - try 'data rawdemod p2'");
 -                      PrintAndLog("\nCould also be PSK3 - [currently not supported]");
 -                      PrintAndLog("\nCould also be NRZ - try 'data nrzrawdemod");
 -                      return 1;
 -              }
 -              PrintAndLog("\nNo Data Found!\n");
        }
-     ans=GetFskClock("",FALSE,FALSE); //CmdDetectClockRate("F"); //
 -      return 0;
++              ans=GetFskClock("",FALSE,FALSE); 
 +    if (ans != 0){ //fsk
-       ans=FSKrawDemod("",FALSE);
++                      ans=FSKrawDemod("",TRUE);
 +      if (ans>0) {
 +        PrintAndLog("\nUnknown FSK Modulated Tag Found!");
-         printDemodBuff();
 +        return 1;
 +      }
 +    }
-     ans=ASKmanDemod("",FALSE,FALSE);
++              ans=ASKDemod("0 0 0",TRUE,FALSE,1);
 +    if (ans>0) {
 +      PrintAndLog("\nUnknown ASK Modulated and Manchester encoded Tag Found!");
 +      PrintAndLog("\nif it does not look right it could instead be ASK/Biphase - try 'data rawdemod ab'");
-       printDemodBuff();
 +      return 1;
 +    }
 +    ans=CmdPSK1rawDemod("");
 +    if (ans>0) {
 +      PrintAndLog("Possible unknown PSK1 Modulated Tag Found above!\n\nCould also be PSK2 - try 'data rawdemod p2'");
 +      PrintAndLog("\nCould also be PSK3 - [currently not supported]");
 +      PrintAndLog("\nCould also be NRZ - try 'data nrzrawdemod");
-       printDemodBuff();
 +      return 1;
 +    }
 +    PrintAndLog("\nNo Data Found!\n");
 +  }
 +  return 0;
  }
  
  static command_t CommandTable[] = 
  {
 -      {"help",        CmdHelp,            1, "This help"},
 -      {"cmdread",     CmdLFCommandRead,   0, "<off period> <'0' period> <'1' period> <command> ['h'] -- Modulate LF reader field to send command before read (all periods in microseconds) (option 'h' for 134)"},
 -      {"em4x",        CmdLFEM4X,          1, "{ EM4X RFIDs... }"},
 -      {"config",      CmdLFSetConfig,     0, "Set config for LF sampling, bit/sample, decimation, frequency"},
 -      {"flexdemod",   CmdFlexdemod,       1, "Demodulate samples for FlexPass"},
 -      {"hid",         CmdLFHID,           1, "{ HID RFIDs... }"},
 -      {"io",            CmdLFIO,                1, "{ ioProx tags... }"},
 -      {"indalademod", CmdIndalaDemod,     1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"},
 -      {"indalaclone", CmdIndalaClone,     0, "<UID> ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"},
 -      {"read",        CmdLFRead,          0, "['s' silent] Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"},
 -      {"search",      CmdLFfind,          1, "[offline] ['u'] Read and Search for valid known tag (in offline mode it you can load first then search) - 'u' to search for unknown tags"},
 -      {"sim",         CmdLFSim,           0, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"},
 -      {"simask",      CmdLFaskSim,        0, "[clock] [invert <1|0>] [manchester/raw <'m'|'r'>] [msg separator 's'] [d <hexdata>] -- Simulate LF ASK tag from demodbuffer or input"},
 -      {"simfsk",      CmdLFfskSim,        0, "[c <clock>] [i] [H <fcHigh>] [L <fcLow>] [d <hexdata>] -- Simulate LF FSK tag from demodbuffer or input"},
 -      {"simpsk",      CmdLFpskSim,        0, "[1|2|3] [c <clock>] [i] [r <carrier>] [d <raw hex to sim>] -- Simulate LF PSK tag from demodbuffer or input"},
 -      {"simbidir",    CmdLFSimBidir,      0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"},
 -      {"snoop",       CmdLFSnoop,         0, "['l'|'h'|<divisor>] [trigger threshold]-- Snoop LF (l:125khz, h:134khz)"},
 -      {"ti",          CmdLFTI,            1, "{ TI RFIDs... }"},
 -      {"hitag",       CmdLFHitag,         1, "{ Hitag tags and transponders... }"},
 -      {"vchdemod",    CmdVchDemod,        1, "['clone'] -- Demodulate samples for VeriChip"},
 -      {"t55xx",       CmdLFT55XX,         1, "{ T55xx RFIDs... }"},
 -      {"pcf7931",     CmdLFPCF7931,       1, "{PCF7931 RFIDs...}"},
 -      {NULL, NULL, 0, NULL}
 +  {"help",        CmdHelp,            1, "This help"},
 +  {"em4x",        CmdLFEM4X,          1, "{ EM4X RFIDs... }"},
 +  {"hid",         CmdLFHID,           1, "{ HID RFIDs... }"},
 +  {"hitag",       CmdLFHitag,         1, "{ HITAG RFIDs... }"},
 +  {"io",                CmdLFIO,                1, "{ IOPROX RFIDs... }"},
 +  {"pcf7931",     CmdLFPCF7931,       1, "{ PCF7931 RFIDs... }"},
 +  {"ti",          CmdLFTI,            1, "{ TI RFIDs... }"},
 +  {"t55xx",       CmdLFT55XX,         1, "{ T55X7 RFIDs... }"},
 +
 +  {"config",      CmdLFSetConfig,     0, "Set config for LF sampling, bit/sample, decimation, frequency"},
 + 
 +  {"cmdread",     CmdLFCommandRead,   0, "<off period> <'0' period> <'1' period> <command> ['h'] -- Modulate LF reader field to send command before read (all periods in microseconds) (option 'h' for 134)"},
 +  {"flexdemod",   CmdFlexdemod,       1, "Demodulate samples for FlexPass"},
 +  {"indalademod", CmdIndalaDemod,     1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"},
 +  {"indalaclone", CmdIndalaClone,     0, "<UID> ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"},
 +  {"read",        CmdLFRead,          0, "['s' silent] Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"},
 +  {"search",      CmdLFfind,          1, "[offline] ['u'] Read and Search for valid known tag (in offline mode it you can load first then search) - 'u' to search for unknown tags"},
 +  {"sim",         CmdLFSim,           0, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"},
 +  {"simask",      CmdLFaskSim,        0, "[clock] [invert <1|0>] [manchester/raw <'m'|'r'>] [msg separator 's'] [d <hexdata>] -- Simulate LF ASK tag from demodbuffer or input"},
 +  {"simfsk",      CmdLFfskSim,        0, "[c <clock>] [i] [H <fcHigh>] [L <fcLow>] [d <hexdata>] -- Simulate LF FSK tag from demodbuffer or input"},
 +  {"simpsk",      CmdLFpskSim,        0, "[1|2|3] [c <clock>] [i] [r <carrier>] [d <raw hex to sim>] -- Simulate LF PSK tag from demodbuffer or input"},
 +  {"simbidir",    CmdLFSimBidir,      0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"},
-   //{"simman",      CmdLFSimManchester, 0, "<Clock> <Bitstream> [GAP] Simulate arbitrary Manchester LF tag"},
 +  {"snoop",       CmdLFSnoop,         0, "['l'|'h'|<divisor>] [trigger threshold]-- Snoop LF (l:125khz, h:134khz)"},
 +  {"vchdemod",    CmdVchDemod,        1, "['clone'] -- Demodulate samples for VeriChip"},
 +  {NULL, NULL, 0, NULL}
  };
  
  int CmdLF(const char *Cmd)
  {
 -      CmdsParse(CommandTable, Cmd);
 -      return 0; 
 +  CmdsParse(CommandTable, Cmd);
 +  return 0; 
  }
  
  int CmdHelp(const char *Cmd)
  {
 -      CmdsHelp(CommandTable);
 -      return 0;
 +  CmdsHelp(CommandTable);
 +  return 0;
  }
diff --combined client/cmdlfem4x.c
index 22b12aa48ee7b8aea47f56c965aa1980de8d0c55,c492a64d52e5c4e056202302142836a2f893ae80..c167f456f646faa378545697a83fc7ed4533c8ad
@@@ -19,6 -19,7 +19,7 @@@
  #include "cmddata.h"
  #include "cmdlf.h"
  #include "cmdlfem4x.h"
+ #include "lfdemod.h"
  char *global_em410xId;
  
  static int CmdHelp(const char *Cmd);
  int CmdEMdemodASK(const char *Cmd)
  {
        char cmdp = param_getchar(Cmd, 0);
-       int findone = (cmdp == '1') ? 1 : 0;    
-   UsbCommand c={CMD_EM410X_DEMOD};
-   c.arg[0]=findone;
-   SendCommand(&c);
-   return 0;
+       int findone = (cmdp == '1') ? 1 : 0;
+       UsbCommand c={CMD_EM410X_DEMOD};
+       c.arg[0]=findone;
+       SendCommand(&c);
+       return 0;
  }
  
  /* Read the ID of an EM410x tag.
   */
  int CmdEM410xRead(const char *Cmd)
  {
-   uint32_t hi=0;
-   uint64_t lo=0;
-   if(!AskEm410xDemod("", &hi, &lo)) return 0;
-   PrintAndLog("EM410x pattern found: ");
-   printEM410x(hi, lo);
-   if (hi){
-     PrintAndLog ("EM410x XL pattern found");
-     return 0;
-   }
-   char id[12] = {0x00};
-   sprintf(id, "%010llx",lo);
-   
-   global_em410xId = id;
-   return 1;
+       uint32_t hi=0;
+       uint64_t lo=0;
+       if(!AskEm410xDemod("", &hi, &lo, false)) return 0;
+       PrintAndLog("EM410x pattern found: ");
+       printEM410x(hi, lo);
+       if (hi){
+               PrintAndLog ("EM410x XL pattern found");
+               return 0;
+       }
+       char id[12] = {0x00};
+       sprintf(id, "%010llx",lo);
+       
+       global_em410xId = id;
+       return 1;
  }
  
  // emulate an EM410X tag
@@@ -69,9 -70,9 +70,9 @@@ int CmdEM410xSim(const char *Cmd
        uint8_t uid[5] = {0x00};
  
        if (cmdp == 'h' || cmdp == 'H') {
 -              PrintAndLog("Usage:  lf em4x 410xsim <UID>");
 +              PrintAndLog("Usage:  lf em4x em410xsim <UID>");
                PrintAndLog("");
 -              PrintAndLog("     sample: lf em4x 410xsim 0F0368568B");
 +              PrintAndLog("     sample: lf em4x em410xsim 0F0368568B");
                return 0;
        }
  
        PrintAndLog("Starting simulating UID %02X%02X%02X%02X%02X", uid[0],uid[1],uid[2],uid[3],uid[4]);
        PrintAndLog("Press pm3-button to about simulation");
  
-   /* clock is 64 in EM410x tags */
-   int clock = 64;
-   /* clear our graph */
-   ClearGraph(0);
-     /* write 9 start bits */
-     for (i = 0; i < 9; i++)
-       AppendGraph(0, clock, 1);
-     /* for each hex char */
-     parity[0] = parity[1] = parity[2] = parity[3] = 0;
-     for (i = 0; i < 10; i++)
-     {
-       /* read each hex char */
-       sscanf(&Cmd[i], "%1x", &n);
-       for (j = 3; j >= 0; j--, n/= 2)
-         binary[j] = n % 2;
-       /* append each bit */
-       AppendGraph(0, clock, binary[0]);
-       AppendGraph(0, clock, binary[1]);
-       AppendGraph(0, clock, binary[2]);
-       AppendGraph(0, clock, binary[3]);
-       /* append parity bit */
-       AppendGraph(0, clock, binary[0] ^ binary[1] ^ binary[2] ^ binary[3]);
-       /* keep track of column parity */
-       parity[0] ^= binary[0];
-       parity[1] ^= binary[1];
-       parity[2] ^= binary[2];
-       parity[3] ^= binary[3];
-     }
-     /* parity columns */
-     AppendGraph(0, clock, parity[0]);
-     AppendGraph(0, clock, parity[1]);
-     AppendGraph(0, clock, parity[2]);
-     AppendGraph(0, clock, parity[3]);
-     /* stop bit */
-   AppendGraph(1, clock, 0);
+       /* clock is 64 in EM410x tags */
+       int clock = 64;
+       /* clear our graph */
+       ClearGraph(0);
+               /* write 9 start bits */
+               for (i = 0; i < 9; i++)
+                       AppendGraph(0, clock, 1);
+               /* for each hex char */
+               parity[0] = parity[1] = parity[2] = parity[3] = 0;
+               for (i = 0; i < 10; i++)
+               {
+                       /* read each hex char */
+                       sscanf(&Cmd[i], "%1x", &n);
+                       for (j = 3; j >= 0; j--, n/= 2)
+                               binary[j] = n % 2;
+                       /* append each bit */
+                       AppendGraph(0, clock, binary[0]);
+                       AppendGraph(0, clock, binary[1]);
+                       AppendGraph(0, clock, binary[2]);
+                       AppendGraph(0, clock, binary[3]);
+                       /* append parity bit */
+                       AppendGraph(0, clock, binary[0] ^ binary[1] ^ binary[2] ^ binary[3]);
+                       /* keep track of column parity */
+                       parity[0] ^= binary[0];
+                       parity[1] ^= binary[1];
+                       parity[2] ^= binary[2];
+                       parity[3] ^= binary[3];
+               }
+               /* parity columns */
+               AppendGraph(0, clock, parity[0]);
+               AppendGraph(0, clock, parity[1]);
+               AppendGraph(0, clock, parity[2]);
+               AppendGraph(0, clock, parity[3]);
+               /* stop bit */
+       AppendGraph(1, clock, 0);
   
-   CmdLFSim("0"); //240 start_gap.
-   return 0;
+       CmdLFSim("0"); //240 start_gap.
+       return 0;
  }
  
  /* Function is equivalent of lf read + data samples + em410xread
   *       rate gets lower, then grow the number of samples
   *  Changed by martin, 4000 x 4 = 16000, 
   *  see http://www.proxmark.org/forum/viewtopic.php?pid=7235#p7235
  */
  int CmdEM410xWatch(const char *Cmd)
  {
                }
                
                CmdLFRead("s");
-               getSamples("8192",true); //capture enough to get 2 full messages                
+               getSamples("8201",true); //capture enough to get 2 complete preambles (4096*2+9)        
        } while (!CmdEM410xRead(""));
  
        return 0;
  }
  
+ //currently only supports manchester modulations
  int CmdEM410xWatchnSpoof(const char *Cmd)
  {
        CmdEM410xWatch(Cmd);
        return 0;
  }
  
- /* Read the transmitted data of an EM4x50 tag
-  * Format:
-  *
-  *  XXXXXXXX [row parity bit (even)] <- 8 bits plus parity
-  *  XXXXXXXX [row parity bit (even)] <- 8 bits plus parity
-  *  XXXXXXXX [row parity bit (even)] <- 8 bits plus parity
-  *  XXXXXXXX [row parity bit (even)] <- 8 bits plus parity
-  *  CCCCCCCC                         <- column parity bits
-  *  0                                <- stop bit
-  *  LW                               <- Listen Window
-  *
-  * This pattern repeats for every block of data being transmitted.
-  * Transmission starts with two Listen Windows (LW - a modulated
-  * pattern of 320 cycles each (32/32/128/64/64)).
-  *
-  * Note that this data may or may not be the UID. It is whatever data
-  * is stored in the blocks defined in the control word First and Last
-  * Word Read values. UID is stored in block 32.
-  */
- int CmdEM4x50Read(const char *Cmd)
- {
-   int i, j, startblock, skip, block, start, end, low, high;
-   bool complete= false;
-   int tmpbuff[MAX_GRAPH_TRACE_LEN / 64];
-   char tmp[6];
-   high= low= 0;
-   memset(tmpbuff, 0, MAX_GRAPH_TRACE_LEN / 64);
-   /* first get high and low values */
-   for (i = 0; i < GraphTraceLen; i++)
-   {
-     if (GraphBuffer[i] > high)
-       high = GraphBuffer[i];
-     else if (GraphBuffer[i] < low)
-       low = GraphBuffer[i];
-   }
-   /* populate a buffer with pulse lengths */
-   i= 0;
-   j= 0;
-   while (i < GraphTraceLen)
-   {
-     // measure from low to low
-     while ((GraphBuffer[i] > low) && (i<GraphTraceLen))
-       ++i;
-     start= i;
-     while ((GraphBuffer[i] < high) && (i<GraphTraceLen))
-       ++i;
-     while ((GraphBuffer[i] > low) && (i<GraphTraceLen))
-       ++i;
-     if (j>=(MAX_GRAPH_TRACE_LEN/64)) {
-       break;
-     }
-     tmpbuff[j++]= i - start;
-   }
-   /* look for data start - should be 2 pairs of LW (pulses of 192,128) */
-   start= -1;
-   skip= 0;
-   for (i= 0; i < j - 4 ; ++i)
-   {
-     skip += tmpbuff[i];
-     if (tmpbuff[i] >= 190 && tmpbuff[i] <= 194)
-       if (tmpbuff[i+1] >= 126 && tmpbuff[i+1] <= 130)
-         if (tmpbuff[i+2] >= 190 && tmpbuff[i+2] <= 194)
-           if (tmpbuff[i+3] >= 126 && tmpbuff[i+3] <= 130)
-           {
-             start= i + 3;
-             break;
-           }
-   }
-   startblock= i + 3;
-   /* skip over the remainder of the LW */
-   skip += tmpbuff[i+1]+tmpbuff[i+2];
-   while (skip < MAX_GRAPH_TRACE_LEN && GraphBuffer[skip] > low)
-     ++skip;
-   skip += 8;
-   /* now do it again to find the end */
-   end= start;
-   for (i += 3; i < j - 4 ; ++i)
-   {
-     end += tmpbuff[i];
-     if (tmpbuff[i] >= 190 && tmpbuff[i] <= 194)
-       if (tmpbuff[i+1] >= 126 && tmpbuff[i+1] <= 130)
-         if (tmpbuff[i+2] >= 190 && tmpbuff[i+2] <= 194)
-           if (tmpbuff[i+3] >= 126 && tmpbuff[i+3] <= 130)
-           {
-             complete= true;
-             break;
-           }
-   }
-   if (start >= 0)
-     PrintAndLog("Found data at sample: %i",skip);
-   else
-   {
-     PrintAndLog("No data found!");
-     PrintAndLog("Try again with more samples.");
-     return 0;
-   }
-   if (!complete)
-   {
-     PrintAndLog("*** Warning!");
-     PrintAndLog("Partial data - no end found!");
-     PrintAndLog("Try again with more samples.");
-   }
-   /* get rid of leading crap */
-   sprintf(tmp,"%i",skip);
-   CmdLtrim(tmp);
-   /* now work through remaining buffer printing out data blocks */
-   block= 0;
-   i= startblock;
-   while (block < 6)
-   {
-     PrintAndLog("Block %i:", block);
-     // mandemod routine needs to be split so we can call it for data
-     // just print for now for debugging
-     CmdManchesterDemod("i 64");
-     skip= 0;
-     /* look for LW before start of next block */
-     for ( ; i < j - 4 ; ++i)
-     {
-       skip += tmpbuff[i];
-       if (tmpbuff[i] >= 190 && tmpbuff[i] <= 194)
-         if (tmpbuff[i+1] >= 126 && tmpbuff[i+1] <= 130)
-           break;
-     }
-     while (GraphBuffer[skip] > low)
-       ++skip;
-     skip += 8;
-     sprintf(tmp,"%i",skip);
-     CmdLtrim(tmp);
-     start += skip;
-     block++;
-   }
-   return 0;
- }
  int CmdEM410xWrite(const char *Cmd)
  {
-   uint64_t id = 0xFFFFFFFFFFFFFFFF; // invalid id value
-   int card = 0xFF; // invalid card value
+       uint64_t id = 0xFFFFFFFFFFFFFFFF; // invalid id value
+       int card = 0xFF; // invalid card value
        unsigned int clock = 0; // invalid clock value
  
        sscanf(Cmd, "%" PRIx64 " %d %d", &id, &card, &clock);
                return 0;
        }
  
-   UsbCommand c = {CMD_EM410X_WRITE_TAG, {card, (uint32_t)(id >> 32), (uint32_t)id}};
-   SendCommand(&c);
+       UsbCommand c = {CMD_EM410X_WRITE_TAG, {card, (uint32_t)(id >> 32), (uint32_t)id}};
+       SendCommand(&c);
+       return 0;
+ }
  
-   return 0;
+ bool EM_EndParityTest(uint8_t *BitStream, size_t size, uint8_t rows, uint8_t cols, uint8_t pType)
+ {
+       if (rows*cols>size) return false;
+       uint8_t colP=0;
+       //assume last col is a parity and do not test
+       for (uint8_t colNum = 0; colNum < cols-1; colNum++) {
+               for (uint8_t rowNum = 0; rowNum < rows; rowNum++) {
+                       colP ^= BitStream[(rowNum*cols)+colNum];
+               }
+               if (colP != pType) return false;
+       }
+       return true;
+ }
+ bool EM_ByteParityTest(uint8_t *BitStream, size_t size, uint8_t rows, uint8_t cols, uint8_t pType)
+ {
+       if (rows*cols>size) return false;
+       uint8_t rowP=0;
+       //assume last row is a parity row and do not test
+       for (uint8_t rowNum = 0; rowNum < rows-1; rowNum++) {
+               for (uint8_t colNum = 0; colNum < cols; colNum++) {
+                       rowP ^= BitStream[(rowNum*cols)+colNum];
+               }
+               if (rowP != pType) return false;
+       }
+       return true;
+ }
+ uint32_t OutputEM4x50_Block(uint8_t *BitStream, size_t size, bool verbose, bool pTest)
+ {
+       if (size<45) return 0;
+       uint32_t code = bytebits_to_byte(BitStream,8);
+       code = code<<8 | bytebits_to_byte(BitStream+9,8);
+       code = code<<8 | bytebits_to_byte(BitStream+18,8);
+       code = code<<8 | bytebits_to_byte(BitStream+27,8);
+       if (verbose || g_debugMode){
+               for (uint8_t i = 0; i<5; i++){
+                       if (i == 4) PrintAndLog(""); //parity byte spacer
+                       PrintAndLog("%d%d%d%d%d%d%d%d %d -> 0x%02x",
+                           BitStream[i*9],
+                           BitStream[i*9+1],
+                           BitStream[i*9+2],
+                           BitStream[i*9+3],
+                           BitStream[i*9+4],
+                           BitStream[i*9+5],
+                           BitStream[i*9+6],
+                           BitStream[i*9+7],
+                           BitStream[i*9+8],
+                           bytebits_to_byte(BitStream+i*9,8)
+                       );
+               }
+               if (pTest)
+                       PrintAndLog("Parity Passed");
+               else
+                       PrintAndLog("Parity Failed");
+       }
+       return code;
+ }
+ /* Read the transmitted data of an EM4x50 tag
+  * Format:
+  *
+  *  XXXXXXXX [row parity bit (even)] <- 8 bits plus parity
+  *  XXXXXXXX [row parity bit (even)] <- 8 bits plus parity
+  *  XXXXXXXX [row parity bit (even)] <- 8 bits plus parity
+  *  XXXXXXXX [row parity bit (even)] <- 8 bits plus parity
+  *  CCCCCCCC                         <- column parity bits
+  *  0                                <- stop bit
+  *  LW                               <- Listen Window
+  *
+  * This pattern repeats for every block of data being transmitted.
+  * Transmission starts with two Listen Windows (LW - a modulated
+  * pattern of 320 cycles each (32/32/128/64/64)).
+  *
+  * Note that this data may or may not be the UID. It is whatever data
+  * is stored in the blocks defined in the control word First and Last
+  * Word Read values. UID is stored in block 32.
+  */
+  //completed by Marshmellow
+ int EM4x50Read(const char *Cmd, bool verbose)
+ {
+       uint8_t fndClk[] = {8,16,32,40,50,64,128};
+       int clk = 0; 
+       int invert = 0;
+       int tol = 0;
+       int i, j, startblock, skip, block, start, end, low, high, minClk;
+       bool complete = false;
+       int tmpbuff[MAX_GRAPH_TRACE_LEN / 64];
+       uint32_t Code[6];
+       char tmp[6];
+       char tmp2[20];
+       int phaseoff;
+       high = low = 0;
+       memset(tmpbuff, 0, MAX_GRAPH_TRACE_LEN / 64);
+       // get user entry if any
+       sscanf(Cmd, "%i %i", &clk, &invert);
+       
+       // save GraphBuffer - to restore it later       
+       save_restoreGB(1);
+       // first get high and low values
+       for (i = 0; i < GraphTraceLen; i++) {
+               if (GraphBuffer[i] > high)
+                       high = GraphBuffer[i];
+               else if (GraphBuffer[i] < low)
+                       low = GraphBuffer[i];
+       }
+       i = 0;
+       j = 0;
+       minClk = 255;
+       // get to first full low to prime loop and skip incomplete first pulse
+       while ((GraphBuffer[i] < high) && (i < GraphTraceLen))
+               ++i;
+       while ((GraphBuffer[i] > low) && (i < GraphTraceLen))
+               ++i;
+       skip = i;
+       // populate tmpbuff buffer with pulse lengths
+       while (i < GraphTraceLen) {
+               // measure from low to low
+               while ((GraphBuffer[i] > low) && (i < GraphTraceLen))
+                       ++i;
+               start= i;
+               while ((GraphBuffer[i] < high) && (i < GraphTraceLen))
+                       ++i;
+               while ((GraphBuffer[i] > low) && (i < GraphTraceLen))
+                       ++i;
+               if (j>=(MAX_GRAPH_TRACE_LEN/64)) {
+                       break;
+               }
+               tmpbuff[j++]= i - start;
+               if (i-start < minClk && i < GraphTraceLen) {
+                       minClk = i - start;
+               }
+       }
+       // set clock
+       if (!clk) {
+               for (uint8_t clkCnt = 0; clkCnt<7; clkCnt++) {
+                       tol = fndClk[clkCnt]/8;
+                       if (minClk >= fndClk[clkCnt]-tol && minClk <= fndClk[clkCnt]+1) { 
+                               clk=fndClk[clkCnt];
+                               break;
+                       }
+               }
+               if (!clk) return 0;
+       } else tol = clk/8;
+       // look for data start - should be 2 pairs of LW (pulses of clk*3,clk*2)
+       start = -1;
+       for (i= 0; i < j - 4 ; ++i) {
+               skip += tmpbuff[i];
+               if (tmpbuff[i] >= clk*3-tol && tmpbuff[i] <= clk*3+tol)  //3 clocks
+                       if (tmpbuff[i+1] >= clk*2-tol && tmpbuff[i+1] <= clk*2+tol)  //2 clocks
+                               if (tmpbuff[i+2] >= clk*3-tol && tmpbuff[i+2] <= clk*3+tol) //3 clocks
+                                       if (tmpbuff[i+3] >= clk-tol)  //1.5 to 2 clocks - depends on bit following
+                                       {
+                                               start= i + 4;
+                                               break;
+                                       }
+       }
+       startblock = i + 4;
+       // skip over the remainder of LW
+       skip += tmpbuff[i+1] + tmpbuff[i+2] + clk;
+       if (tmpbuff[i+3]>clk) 
+               phaseoff = tmpbuff[i+3]-clk;
+       else
+               phaseoff = 0;
+       // now do it again to find the end
+       end = skip;
+       for (i += 3; i < j - 4 ; ++i) {
+               end += tmpbuff[i];
+               if (tmpbuff[i] >= clk*3-tol && tmpbuff[i] <= clk*3+tol)  //3 clocks
+                       if (tmpbuff[i+1] >= clk*2-tol && tmpbuff[i+1] <= clk*2+tol)  //2 clocks
+                               if (tmpbuff[i+2] >= clk*3-tol && tmpbuff[i+2] <= clk*3+tol) //3 clocks
+                                       if (tmpbuff[i+3] >= clk-tol)  //1.5 to 2 clocks - depends on bit following
+                                       {
+                                               complete= true;
+                                               break;
+                                       }
+       }
+       end = i;
+       // report back
+       if (verbose || g_debugMode) {
+               if (start >= 0) {
+                       PrintAndLog("\nNote: one block = 50 bits (32 data, 12 parity, 6 marker)");
+               }       else {
+                       PrintAndLog("No data found!, clock tried:%d",clk);
+                       PrintAndLog("Try again with more samples.");
+                       PrintAndLog("  or after a 'data askedge' command to clean up the read");
+                       return 0;
+               }
+       } else if (start < 0) return 0;
+       start = skip;
+       snprintf(tmp2, sizeof(tmp2),"%d %d 1000 %d", clk, invert, clk*47);
+       // get rid of leading crap 
+       snprintf(tmp, sizeof(tmp), "%i", skip);
+       CmdLtrim(tmp);
+       bool pTest;
+       bool AllPTest = true;
+       // now work through remaining buffer printing out data blocks
+       block = 0;
+       i = startblock;
+       while (block < 6) {
+               if (verbose || g_debugMode) PrintAndLog("\nBlock %i:", block);
+               skip = phaseoff;
+               
+               // look for LW before start of next block
+               for ( ; i < j - 4 ; ++i) {
+                       skip += tmpbuff[i];
+                       if (tmpbuff[i] >= clk*3-tol && tmpbuff[i] <= clk*3+tol)
+                               if (tmpbuff[i+1] >= clk-tol)
+                                       break;
+               }
+               if (i >= j-4) break; //next LW not found
+               skip += clk;
+               if (tmpbuff[i+1]>clk)
+                       phaseoff = tmpbuff[i+1]-clk;
+               else
+                       phaseoff = 0;
+               i += 2;
+               if (ASKDemod(tmp2, false, false, 1) < 1) {
+                       save_restoreGB(0);
+                       return 0;
+               }
+               //set DemodBufferLen to just one block
+               DemodBufferLen = skip/clk;
+               //test parities
+               pTest = EM_ByteParityTest(DemodBuffer,DemodBufferLen,5,9,0);    
+               pTest &= EM_EndParityTest(DemodBuffer,DemodBufferLen,5,9,0);
+               AllPTest &= pTest;
+               //get output
+               Code[block] = OutputEM4x50_Block(DemodBuffer,DemodBufferLen,verbose, pTest);
+               if (g_debugMode) PrintAndLog("\nskipping %d samples, bits:%d", skip, skip/clk);
+               //skip to start of next block
+               snprintf(tmp,sizeof(tmp),"%i",skip);
+               CmdLtrim(tmp);
+               block++;
+               if (i >= end) break; //in case chip doesn't output 6 blocks
+       }
+       //print full code:
+       if (verbose || g_debugMode || AllPTest){
+               if (!complete) {
+                       PrintAndLog("*** Warning!");
+                       PrintAndLog("Partial data - no end found!");
+                       PrintAndLog("Try again with more samples.");
+               }
+               PrintAndLog("Found data at sample: %i - using clock: %i", start, clk);    
+               end = block;
+               for (block=0; block < end; block++){
+                       PrintAndLog("Block %d: %08x",block,Code[block]);
+               }
+               if (AllPTest) {
+                       PrintAndLog("Parities Passed");
+               } else {
+                       PrintAndLog("Parities Failed");
+                       PrintAndLog("Try cleaning the read samples with 'data askedge'");
+               }
+       }
+       //restore GraphBuffer
+       save_restoreGB(0);
+       return (int)AllPTest;
+ }
+ int CmdEM4x50Read(const char *Cmd)
+ {
+       return EM4x50Read(Cmd, true);
  }
  
  int CmdReadWord(const char *Cmd)
  {
        int Word = -1; //default to invalid word
-   UsbCommand c;
-   
-   sscanf(Cmd, "%d", &Word);
-   
+       UsbCommand c;
+       
+       sscanf(Cmd, "%d", &Word);
+       
        if ( (Word > 15) | (Word < 0) ) {
-     PrintAndLog("Word must be between 0 and 15");
-     return 1;
-   }
-   
-   PrintAndLog("Reading word %d", Word);
-   
-   c.cmd = CMD_EM4X_READ_WORD;
-   c.d.asBytes[0] = 0x0; //Normal mode
-   c.arg[0] = 0;
-   c.arg[1] = Word;
-   c.arg[2] = 0;
-   SendCommand(&c);
-   return 0;
+               PrintAndLog("Word must be between 0 and 15");
+               return 1;
+       }
+       
+       PrintAndLog("Reading word %d", Word);
+       
+       c.cmd = CMD_EM4X_READ_WORD;
+       c.d.asBytes[0] = 0x0; //Normal mode
+       c.arg[0] = 0;
+       c.arg[1] = Word;
+       c.arg[2] = 0;
+       SendCommand(&c);
+       return 0;
  }
  
  int CmdReadWordPWD(const char *Cmd)
  {
        int Word = -1; //default to invalid word
-   int Password = 0xFFFFFFFF; //default to blank password
-   UsbCommand c;
-   
-   sscanf(Cmd, "%d %x", &Word, &Password);
-   
+       int Password = 0xFFFFFFFF; //default to blank password
+       UsbCommand c;
+       
+       sscanf(Cmd, "%d %x", &Word, &Password);
+       
        if ( (Word > 15) | (Word < 0) ) {
-     PrintAndLog("Word must be between 0 and 15");
-     return 1;
-   }
-   
-   PrintAndLog("Reading word %d with password %08X", Word, Password);
-   
-   c.cmd = CMD_EM4X_READ_WORD;
-   c.d.asBytes[0] = 0x1; //Password mode
-   c.arg[0] = 0;
-   c.arg[1] = Word;
-   c.arg[2] = Password;
-   SendCommand(&c);
-   return 0;
+               PrintAndLog("Word must be between 0 and 15");
+               return 1;
+       }
+       
+       PrintAndLog("Reading word %d with password %08X", Word, Password);
+       
+       c.cmd = CMD_EM4X_READ_WORD;
+       c.d.asBytes[0] = 0x1; //Password mode
+       c.arg[0] = 0;
+       c.arg[1] = Word;
+       c.arg[2] = Password;
+       SendCommand(&c);
+       return 0;
  }
  
  int CmdWriteWord(const char *Cmd)
  {
-   int Word = 16; //default to invalid block
-   int Data = 0xFFFFFFFF; //default to blank data
-   UsbCommand c;
-   
-   sscanf(Cmd, "%x %d", &Data, &Word);
-   
-   if (Word > 15) {
-     PrintAndLog("Word must be between 0 and 15");
-     return 1;
-   }
-   
-   PrintAndLog("Writing word %d with data %08X", Word, Data);
-   
-   c.cmd = CMD_EM4X_WRITE_WORD;
-   c.d.asBytes[0] = 0x0; //Normal mode
-   c.arg[0] = Data;
-   c.arg[1] = Word;
-   c.arg[2] = 0;
-   SendCommand(&c);
-   return 0;
+       int Word = 16; //default to invalid block
+       int Data = 0xFFFFFFFF; //default to blank data
+       UsbCommand c;
+       
+       sscanf(Cmd, "%x %d", &Data, &Word);
+       
+       if (Word > 15) {
+               PrintAndLog("Word must be between 0 and 15");
+               return 1;
+       }
+       
+       PrintAndLog("Writing word %d with data %08X", Word, Data);
+       
+       c.cmd = CMD_EM4X_WRITE_WORD;
+       c.d.asBytes[0] = 0x0; //Normal mode
+       c.arg[0] = Data;
+       c.arg[1] = Word;
+       c.arg[2] = 0;
+       SendCommand(&c);
+       return 0;
  }
  
  int CmdWriteWordPWD(const char *Cmd)
  {
-   int Word = 16; //default to invalid word
-   int Data = 0xFFFFFFFF; //default to blank data
-   int Password = 0xFFFFFFFF; //default to blank password
-   UsbCommand c;
-   
-   sscanf(Cmd, "%x %d %x", &Data, &Word, &Password);
-   
-   if (Word > 15) {
-     PrintAndLog("Word must be between 0 and 15");
-     return 1;
-   }
-   
-   PrintAndLog("Writing word %d with data %08X and password %08X", Word, Data, Password);
-   
-   c.cmd = CMD_EM4X_WRITE_WORD;
-   c.d.asBytes[0] = 0x1; //Password mode
-   c.arg[0] = Data;
-   c.arg[1] = Word;
-   c.arg[2] = Password;
-   SendCommand(&c);
-   return 0;
+       int Word = 16; //default to invalid word
+       int Data = 0xFFFFFFFF; //default to blank data
+       int Password = 0xFFFFFFFF; //default to blank password
+       UsbCommand c;
+       
+       sscanf(Cmd, "%x %d %x", &Data, &Word, &Password);
+       
+       if (Word > 15) {
+               PrintAndLog("Word must be between 0 and 15");
+               return 1;
+       }
+       
+       PrintAndLog("Writing word %d with data %08X and password %08X", Word, Data, Password);
+       
+       c.cmd = CMD_EM4X_WRITE_WORD;
+       c.d.asBytes[0] = 0x1; //Password mode
+       c.arg[0] = Data;
+       c.arg[1] = Word;
+       c.arg[2] = Password;
+       SendCommand(&c);
+       return 0;
  }
  
  static command_t CommandTable[] =
  {
-   {"help", CmdHelp, 1, "This help"},
-   {"em410xdemod", CmdEMdemodASK, 0, "[findone] -- Extract ID from EM410x tag (option 0 for continuous loop, 1 for only 1 tag)"},  
-   {"em410xread", CmdEM410xRead, 1, "[clock rate] -- Extract ID from EM410x tag"},
-   {"em410xsim", CmdEM410xSim, 0, "<UID> -- Simulate EM410x tag"},
-   {"em410xwatch", CmdEM410xWatch, 0, "['h'] -- Watches for EM410x 125/134 kHz tags (option 'h' for 134)"},
-   {"em410xspoof", CmdEM410xWatchnSpoof, 0, "['h'] --- Watches for EM410x 125/134 kHz tags, and replays them. (option 'h' for 134)" },
-   {"em410xwrite", CmdEM410xWrite, 1, "<UID> <'0' T5555> <'1' T55x7> [clock rate] -- Write EM410x UID to T5555(Q5) or T55x7 tag, optionally setting clock rate"},
-   {"em4x50read", CmdEM4x50Read, 1, "Extract data from EM4x50 tag"},
-   {"readword", CmdReadWord, 1, "<Word> -- Read EM4xxx word data"},
-   {"readwordPWD", CmdReadWordPWD, 1, "<Word> <Password> -- Read EM4xxx word data in password mode"},
-   {"writeword", CmdWriteWord, 1, "<Data> <Word> -- Write EM4xxx word data"},
-   {"writewordPWD", CmdWriteWordPWD, 1, "<Data> <Word> <Password> -- Write EM4xxx word data in password mode"},
-   {NULL, NULL, 0, NULL}
+       {"help", CmdHelp, 1, "This help"},
+       {"em410xdemod", CmdEMdemodASK, 0, "[findone] -- Extract ID from EM410x tag (option 0 for continuous loop, 1 for only 1 tag)"},  
+       {"em410xread", CmdEM410xRead, 1, "[clock rate] -- Extract ID from EM410x tag in GraphBuffer"},
+       {"em410xsim", CmdEM410xSim, 0, "<UID> -- Simulate EM410x tag"},
+       {"em410xwatch", CmdEM410xWatch, 0, "['h'] -- Watches for EM410x 125/134 kHz tags (option 'h' for 134)"},
+       {"em410xspoof", CmdEM410xWatchnSpoof, 0, "['h'] --- Watches for EM410x 125/134 kHz tags, and replays them. (option 'h' for 134)" },
+       {"em410xwrite", CmdEM410xWrite, 0, "<UID> <'0' T5555> <'1' T55x7> [clock rate] -- Write EM410x UID to T5555(Q5) or T55x7 tag, optionally setting clock rate"},
+       {"em4x50read", CmdEM4x50Read, 1, "Extract data from EM4x50 tag"},
+       {"readword", CmdReadWord, 1, "<Word> -- Read EM4xxx word data"},
+       {"readwordPWD", CmdReadWordPWD, 1, "<Word> <Password> -- Read EM4xxx word data in password mode"},
+       {"writeword", CmdWriteWord, 1, "<Data> <Word> -- Write EM4xxx word data"},
+       {"writewordPWD", CmdWriteWordPWD, 1, "<Data> <Word> <Password> -- Write EM4xxx word data in password mode"},
+       {NULL, NULL, 0, NULL}
  };
  
  int CmdLFEM4X(const char *Cmd)
  {
-   CmdsParse(CommandTable, Cmd);
-   return 0;
+       CmdsParse(CommandTable, Cmd);
+       return 0;
  }
  
  int CmdHelp(const char *Cmd)
  {
-   CmdsHelp(CommandTable);
-   return 0;
+       CmdsHelp(CommandTable);
+       return 0;
  }
index 6d17a09b607e90ad72549380327f452ecc552220,af3d2d4cfeb5a060bd4df6a36e0771b43948c4bf..4e10eb75382ac8b4e05f54b2648fb2eb58dd409f
@@@ -23,13 -23,12 +23,24 @@@ Arguments
        -h             : this help
        -m             : Maxed out items (experimental)
        -i             : filename for the datadump to read (bin)
 -]]
 +
 +      ]]
  
  local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
 -local DEBUG = true -- the debug flag
 +local DEBUG = false -- the debug flag
 +local RANDOM = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20'
 +
++local band = bit32.band
++local bor = bit32.bor
++local lshift = bit32.lshift
++local rshift = bit32.rshift
++local byte = string.byte
++local char = string.char
++local sub = string.sub
++local format = string.format
++
  local band = bit32.band
  local bor = bit32.bor
  local lshift = bit32.lshift
@@@ -198,8 -197,8 +209,6 @@@ local function ValidateCheckSums(blocks
        io.write( ('TYPE 3 area 2: %04x = %04x -- %s\n'):format(crc,calc,isOk))
  end
  
--local function LoadEmulator(blocks)
 -      local HASHCONSTANT = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20'
        local cmd
        local blockdata
        for _,b in pairs(blocks) do 
                
                if  _%4 ~= 3 then
                        if (_ >= 8 and _<=21)  or  (_ >= 36 and _<=49) then
 -                              local base = ('%s%s%02x%s'):format(blocks[0], blocks[1], _ , HASHCONSTANT)      
 +                              local base = ('%s%s%02x%s'):format(blocks[0], blocks[1], _ , RANDOM)    
                                local baseStr = utils.ConvertHexToAscii(base)
                                local key = md5.sumhexa(baseStr)
 -                              local enc = core.aes(key, blockdata)
 +                              local enc = core.aes128_encrypt(key, blockdata)
                                local hex = utils.ConvertAsciiToBytes(enc)
                                hex = utils.ConvertBytesToHex(hex)
                        
@@@ -347,6 -346,21 +356,6 @@@ local function main(args
        local cmdSetDbgOff = "hf mf dbg 0"
        core.console( cmdSetDbgOff) 
        
 -      -- if not loadFromDump then
 -              -- -- Look for tag present on reader,
 -              -- result, err = lib14a.read1443a(false)
 -              -- if not result then return oops(err)  end
 -
 -              -- core.clearCommandBuffer()
 -      
 -              -- if 0x01 ~= result.sak then -- NXP MIFARE TNP3xxx
 -                      -- return oops('This is not a TNP3xxx tag. aborting.')
 -              -- end  
 -
 -              -- -- Show tag info
 -              -- print((' Found tag : %s'):format(result.name))
 -      -- end
 -      
        -- Load dump.bin file
        print( (' Load data from %s'):format(inputTemplate))
        hex, err = utils.ReadDumpFile(inputTemplate)
        end
  
        if DEBUG then
 -              print('Validating checksums in the loaded datadump')
 +              print(' Validating checksums')
                ValidateCheckSums(blocks)
        end
        
        local item = toys.Find( toytype, subtype)
        if item then
                local itemStr = ('%s - %s (%s)'):format(item[6],item[5], item[4])
 -              print(' ITEM TYPE :'..itemStr )
 +              print(' ITEM TYPE : '..itemStr )
        else
                print( (' ITEM TYPE : 0x%s 0x%s'):format(toytype, subtype) )
        end     
        print( string.rep('--',20) )
  
  
 -      -- lets do something.
 -      -- 
 +      -- Experience should be:        
        local experience = blocks[8]:sub(1,6)
 -      print(('Experience  : %d'):format(utils.SwapEndianness(experience,24)))
 +      print(('Experience  : %d'):format(utils.SwapEndianness(experience,16)))
 +      
        local money = blocks[8]:sub(7,10)
        print(('Money       : %d'):format(utils.SwapEndianness(money,16)))
 +
 +      -- 
 +      
 +      -- Sequence number
 +      local seqnum = blocks[8]:sub(18,19)
 +      print(('Sequence number : %d'):format( tonumber(seqnum,16)))
 +      
        local fairy = blocks[9]:sub(1,8)
        --FD0F = Left, FF0F = Right
        local path = 'not choosen'
        
        local hat = blocks[9]:sub(8,11)
        print(('Hat         : %d'):format(utils.SwapEndianness(hat,16)))
-       --hälsa: 667 029b  
 +
 +      local level = blocks[13]:sub(27,28)
 +      print(('LEVEL : %d'):format( tonumber(level,16)))
++      --hälsa: 667 029b  
 +      --local health = blocks[]:sub();
 +      --print(('Health : %d'):format( tonumber(health,16))
        
        --0x0D    0x29    0x0A    0x02    16-bit hero points value. Maximum 100.
        local heropoints = blocks[13]:sub(20,23)
        local challenges = blocks[16]:sub(25,32)
        print(('Finished hero challenges : %d'):format(utils.SwapEndianness(challenges,32)))
        
 +      -- Character Name
 +      local name1 = blocks[10]:sub(1,32)
 +      local name2 = blocks[12]:sub(1,32)
 +      print('Custom name : '..utils.ConvertHexToAscii(name1..name2))
 +      
        if maxed then
                print('Lets try to max out some values')
                -- max out money, experience
Impressum, Datenschutz