]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
Merge pull request #82 from marshmellow42/master show v2.0.0
authorMartin Holst Swende <martin@swende.se>
Tue, 24 Mar 2015 10:10:16 +0000 (11:10 +0100)
committerMartin Holst Swende <martin@swende.se>
Tue, 24 Mar 2015 10:10:16 +0000 (11:10 +0100)
lf ata55x7 commands and more

17 files changed:
armsrc/appmain.c
armsrc/lfops.c
armsrc/lfsampling.c
armsrc/lfsampling.h
client/cmddata.c
client/cmddata.h
client/cmdlf.c
client/cmdlfem4x.c
client/cmdlft55xx.c
client/cmdlft55xx.h
client/scripts/test_t55x7_ask.lua [new file with mode: 0644]
client/scripts/test_t55x7_bi.lua [new file with mode: 0644]
client/scripts/test_t55x7_fsk.lua [new file with mode: 0644]
client/scripts/test_t55x7_psk.lua
client/scripts/tracetest.lua
common/lfdemod.c
common/lfdemod.h

index 3e670f0be9ef004f8cbf668074f14a7b2b479623..6e0b58b3da84fa7bc3e2463c47fd10bc285a9eb8 100644 (file)
@@ -648,7 +648,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
                        setSamplingConfig((sample_config *) c->d.asBytes);
                        break;
                case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K:
-                       cmd_send(CMD_ACK,SampleLF(),0,0,0,0);
+                       cmd_send(CMD_ACK,SampleLF(c->arg[0]),0,0,0,0);
                        break;
                case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K:
                        ModThenAcquireRawAdcSamples125k(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes);
index 2a5573d1cf156a6125c872bc16f19072fa5b8020..7bbc739d45991e063fd40980112f457c11481a1b 100644 (file)
@@ -1030,10 +1030,12 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
  * To compensate antenna falling times shorten the write times
  * and enlarge the gap ones.
  */
-#define START_GAP 250
-#define WRITE_GAP 160
-#define WRITE_0   144 // 192
-#define WRITE_1   400 // 432 for T55x7; 448 for E5550
+#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 T55xx_SAMPLES_SIZE      12000 // 32 x 32 x 10  (32 bit times numofblock (7), times clock skip..)
 
 // Write one bit to card
 void T55xxWriteBit(int bit)
@@ -1052,16 +1054,11 @@ void T55xxWriteBit(int bit)
 // Write one card block in page 0, no lock
 void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
 {
-    //unsigned int i;  //enio adjustment 12/10/14
-    uint32_t i;
-
-    FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
-    FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
-    FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
+    uint32_t i = 0;
 
-    // Give it a bit of time for the resonant antenna to settle.
-    // And for the tag to fully power up
-    SpinDelay(150);
+    // Set up FPGA, 125kHz
+    // Wait for config.. (192+8190xPOW)x8 == 67ms
+    LFSetupFPGAForADC(0, true);
 
     // Now start writting
     FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
@@ -1094,30 +1091,28 @@ void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMod
     FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
 }
 
+void TurnReadLFOn(){
+    FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
+    // Give it a bit of time for the resonant antenna to settle.
+    SpinDelayUs(8*150);
+}
+
+
 // Read one card block in page 0
 void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
 {
+    uint32_t i = 0;
     uint8_t *dest = BigBuf_get_addr();
-    //int m=0, i=0; //enio adjustment 12/10/14
-    uint32_t m=0, i=0;
-    FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
-    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.
-    FpgaSetupSsc();
-
-    LED_D_ON();
-    FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
-    FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
+    uint16_t bufferlength = BigBuf_max_traceLen();
+    if ( bufferlength > T55xx_SAMPLES_SIZE )
+        bufferlength = T55xx_SAMPLES_SIZE;
 
-    // Give it a bit of time for the resonant antenna to settle.
-    // And for the tag to fully power up
-    SpinDelay(150);
+    // Clear destination buffer before sending the command
+    memset(dest, 0x80, bufferlength);
 
-    // Now start writting
+    // Set up FPGA, 125kHz
+    // Wait for config.. (192+8190xPOW)x8 == 67ms
+    LFSetupFPGAForADC(0, true);
     FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
     SpinDelayUs(START_GAP);
 
@@ -1136,53 +1131,40 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
         T55xxWriteBit(Block & i);
 
     // Turn field on to read the response
-    FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
-    FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
-
+    TurnReadLFOn();
     // Now do the acquisition
     i = 0;
     for(;;) {
         if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
             AT91C_BASE_SSC->SSC_THR = 0x43;
+            LED_D_ON();
         }
         if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
             dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
-            // we don't care about actual value, only if it's more or less than a
-            // threshold essentially we capture zero crossings for later analysis
-            //                 if(dest[i] < 127) dest[i] = 0; else dest[i] = 1;
             i++;
-            if (i >= m) break;
+            LED_D_OFF();
+            if (i >= bufferlength) break;
         }
     }
 
+    cmd_send(CMD_ACK,0,0,0,0,0);    
     FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
     LED_D_OFF();
-    DbpString("DONE!");
 }
 
 // Read card traceability data (page 1)
 void T55xxReadTrace(void){
+    
+    uint32_t i = 0;
     uint8_t *dest = BigBuf_get_addr();
-    int m=0, i=0;
+    uint16_t bufferlength = BigBuf_max_traceLen();
+    if ( bufferlength > T55xx_SAMPLES_SIZE )
+        bufferlength= T55xx_SAMPLES_SIZE;
 
-    FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
-    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.
-    FpgaSetupSsc();
+    memset(dest, 0x80, bufferlength);
 
-    LED_D_ON();
-    FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
-    FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
-
-    // Give it a bit of time for the resonant antenna to settle.
-    // And for the tag to fully power up
-    SpinDelay(150);
-
-    // Now start writting
+    LFSetupFPGAForADC(0, true);
     FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
     SpinDelayUs(START_GAP);
 
@@ -1191,25 +1173,26 @@ void T55xxReadTrace(void){
     T55xxWriteBit(1); //Page 1
 
     // Turn field on to read the response
-    FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
-    FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
+    TurnReadLFOn();
 
     // Now do the acquisition
-    i = 0;
     for(;;) {
         if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
             AT91C_BASE_SSC->SSC_THR = 0x43;
+            LED_D_ON();
         }
         if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
             dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
             i++;
-            if (i >= m) break;
+            LED_D_OFF();
+
+            if (i >= bufferlength) break;
         }
     }
 
+    cmd_send(CMD_ACK,0,0,0,0,0);
     FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
     LED_D_OFF();
-    DbpString("DONE!");
 }
 
 /*-------------- Cloning routines -----------*/
index 6094bd34878c3367133ce8f24ccb4be4ccaeade0..120c0801de6ccecc3e7e558e10c078e3b187c980 100644 (file)
@@ -224,21 +224,21 @@ uint32_t DoAcquisition_config( bool silent)
                                  ,silent);
 }
 
-uint32_t ReadLF(bool activeField)
+uint32_t ReadLF(bool activeField, bool silent)
 {
-       printConfig();
+       if (!silent) printConfig();
        LFSetupFPGAForADC(config.divisor, activeField);
        // Now call the acquisition routine
-       return DoAcquisition_config(false);
+       return DoAcquisition_config(silent);
 }
 
 /**
 * Initializes the FPGA for reader-mode (field on), and acquires the samples.
 * @return number of bits sampled
 **/
-uint32_t SampleLF()
+uint32_t SampleLF(bool printCfg)
 {
-       return ReadLF(true);
+       return ReadLF(true, printCfg);
 }
 /**
 * Initializes the FPGA for snoop-mode (field off), and acquires the samples.
@@ -247,5 +247,5 @@ uint32_t SampleLF()
 
 uint32_t SnoopLF()
 {
-       return ReadLF(false);
+       return ReadLF(false, true);
 }
index 9ab458f8129e8ce5f307ca40d240bb8939554aac..6c671ec8ca7a295b49a2d9200401a3ca69d49753 100644 (file)
@@ -5,7 +5,7 @@
 * Initializes the FPGA for reader-mode (field on), and acquires the samples.
 * @return number of bits sampled
 **/
-uint32_t SampleLF();
+uint32_t SampleLF(bool silent);
 
 /**
 * Initializes the FPGA for snoop-mode (field off), and acquires the samples.
index a3d58523ff2d610540eedb31d6aa497b4d458e96..7854fa51d743191c2c2c297810f9f927cc7b0161 100644 (file)
@@ -33,6 +33,12 @@ static int CmdHelp(const char *Cmd);
 //by marshmellow
 void setDemodBuf(uint8_t *buff, size_t size, size_t startIdx)
 {
+       if (buff == NULL) 
+               return;
+
+       if ( size >= MAX_DEMOD_BUF_LEN)
+               size = MAX_DEMOD_BUF_LEN;
+
        size_t i = 0;
        for (; i < size; i++){
                DemodBuffer[i]=buff[startIdx++];
@@ -279,18 +285,101 @@ void printEM410x(uint32_t hi, uint64_t id)
       //output 40 bit em id
       PrintAndLog("EM TAG ID    : %010llx", id);
       PrintAndLog("Unique TAG ID: %010llx",  id2lo);
+      PrintAndLog("");
+      PrintAndLog("Possible de-scramble patterns");
+      PrintAndLog("HoneyWell IdentKey");
       PrintAndLog("DEZ 8        : %08lld",id & 0xFFFFFF);
-      PrintAndLog("DEZ 10       : %010lld",id & 0xFFFFFF);
+      PrintAndLog("DEZ 10       : %010lld",id & 0xFFFFFFFF);
       PrintAndLog("DEZ 5.5      : %05lld.%05lld",(id>>16LL) & 0xFFFF,(id & 0xFFFF));
       PrintAndLog("DEZ 3.5A     : %03lld.%05lld",(id>>32ll),(id & 0xFFFF));
+      PrintAndLog("DEZ 3.5B     : %03lld.%05lld",(id & 0xFF000000) >> 24,(id & 0xFFFF));
+      PrintAndLog("DEZ 3.5C     : %03lld.%05lld",(id & 0xFF0000) >> 16,(id & 0xFFFF));
       PrintAndLog("DEZ 14/IK2   : %014lld",id);
       PrintAndLog("DEZ 15/IK3   : %015lld",id2lo);
       PrintAndLog("Other        : %05lld_%03lld_%08lld",(id&0xFFFF),((id>>16LL) & 0xFF),(id & 0xFFFFFF));  
+      PrintAndLog("DEZ 20/ZK    : %02lld%02lld%02lld%02lld%02lld%02lld%02lld%02lld%02lld%02lld",
+        (id2lo & 0xf000000000) >> 36,
+        (id2lo & 0x0f00000000) >> 32,
+        (id2lo & 0x00f0000000) >> 28,
+        (id2lo & 0x000f000000) >> 24,
+        (id2lo & 0x0000f00000) >> 20,
+        (id2lo & 0x00000f0000) >> 16,
+        (id2lo & 0x000000f000) >> 12,
+        (id2lo & 0x0000000f00) >> 8,
+        (id2lo & 0x00000000f0) >> 4,
+        (id2lo & 0x000000000f)
+      );
+
+      PrintAndLog("");                 
+      uint64_t paxton = (((id>>32) << 24) | (id & 0xffffff))  + 0x143e00;
+      PrintAndLog("Pattern Paxton  : %0d", paxton);    
+
+      uint32_t p1id = (id & 0xFFFFFF);
+      uint8_t arr[32] = {0x00};
+      int i =0; 
+      int j = 23;
+      for (; i < 24; ++i, --j  ){
+       arr[i] = (p1id >> i) & 1;
+      }
+
+      uint32_t p1  = 0;        
+
+      p1 |= arr[23] << 21;
+      p1 |= arr[22] << 23;
+      p1 |= arr[21] << 20;
+      p1 |= arr[20] << 22;
+       
+      p1 |= arr[19] << 18;
+      p1 |= arr[18] << 16;
+      p1 |= arr[17] << 19;
+      p1 |= arr[16] << 17;
+       
+      p1 |= arr[15] << 13;
+      p1 |= arr[14] << 15;
+      p1 |= arr[13] << 12;
+      p1 |= arr[12] << 14;     
+
+      p1 |= arr[11] << 6;
+      p1 |= arr[10] << 2;
+      p1 |= arr[9]  << 7;
+      p1 |= arr[8]  << 1;
+
+      p1 |= arr[7]  << 0;
+      p1 |= arr[6]  << 8;
+      p1 |= arr[5]  << 11;
+      p1 |= arr[4]  << 3;      
+
+      p1 |= arr[3]  << 10;
+      p1 |= arr[2]  << 4;
+      p1 |= arr[1]  << 5;
+      p1 |= arr[0]  << 9;      
+      PrintAndLog("Pattern 1       : 0x%X - %d", p1, p1);
+
+      uint16_t sebury1 = id & 0xFFFF;
+      uint8_t  sebury2 = (id >> 16) & 0x7F;
+      uint32_t sebury3 = id & 0x7FFFFF;
+      PrintAndLog("Pattern Sebury  : %d %d %d  (hex: %X %X %X)", sebury1, sebury2, sebury3, sebury1, sebury2, sebury3);
     }
   }
   return;
 }
 
+
+int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo)
+{
+  int ans = ASKmanDemod(Cmd, FALSE, FALSE);
+  if (!ans) return 0;
+
+  size_t idx=0;
+  if (Em410xDecode(DemodBuffer,(size_t *) &DemodBufferLen, &idx, hi, lo)){
+    if (g_debugMode){
+      PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, DemodBufferLen);
+      printDemodBuff();
+    }
+    return 1;
+  }
+  return 0;    
+}
 //by marshmellow
 //takes 3 arguments - clock, invert and maxErr as integers
 //attempts to demodulate ask while decoding manchester
@@ -311,17 +400,9 @@ int CmdAskEM410xDemod(const char *Cmd)
     PrintAndLog("          : data askem410xdemod 64 1 0 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/64 and inverting data and allowing 0 demod errors");
     return 0;
   }
-  int ans = ASKmanDemod(Cmd, FALSE, FALSE);
-  if (!ans) return 0;
-
-  uint64_t lo =0;
-  uint32_t hi =0;
-  size_t idx=0;
-  if (Em410xDecode(DemodBuffer,(size_t *) &DemodBufferLen, &idx, &hi, &lo)){
-    if (g_debugMode){
-      PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, DemodBufferLen);
-      printDemodBuff();
-    }
+  uint32_t hi;
+  uint64_t lo;
+  if (AskEm410xDemod(Cmd, &hi, &lo)) {
     PrintAndLog("EM410x pattern found: ");
     printEM410x(hi, lo);
     return 1;
@@ -477,6 +558,7 @@ int CmdBiphaseDecodeRaw(const char *Cmd)
                PrintAndLog("Usage:  data biphaserawdecode [offset] [invert] [maxErr]");
                PrintAndLog("     Converts 10 or 01 to 1 and 11 or 00 to 0");
                PrintAndLog("     --must have binary sequence in demodbuffer (run data askrawdemod first)");
+    PrintAndLog("     --invert for Conditional Dephase Encoding (CDP) AKA Differential Manchester");
                PrintAndLog("");
                PrintAndLog("     [offset <0|1>], set to 0 not to adjust start position or to 1 to adjust decode start position");
                PrintAndLog("     [invert <0|1>], set to 1 to invert output");
@@ -639,6 +721,8 @@ int Cmdaskbiphdemod(const char *Cmd)
     PrintAndLog("     NOTE: <amplify> can be entered as first, second or last argument");
     PrintAndLog("     NOTE: any other arg must have previous args set to work");
     PrintAndLog("");
+    PrintAndLog("     NOTE: --invert for Conditional Dephase Encoding (CDP) AKA Differential Manchester");
+    PrintAndLog("");
     PrintAndLog("    sample: data rawdemod ab            = demod an ask/biph tag from GraphBuffer");
     PrintAndLog("          : data rawdemod ab a          = demod an ask/biph tag from GraphBuffer, amplified");
     PrintAndLog("          : data rawdemod ab 1 32       = demod an ask/biph tag from GraphBuffer using an offset of 1 and a clock of RF/32");
@@ -1339,7 +1423,19 @@ int CmdFSKdemodIO(const char *Cmd)
   uint8_t version = bytebits_to_byte(BitStream+idx+27,8); //14,4
   uint8_t facilitycode = bytebits_to_byte(BitStream+idx+18,8) ;
   uint16_t number = (bytebits_to_byte(BitStream+idx+36,8)<<8)|(bytebits_to_byte(BitStream+idx+45,8)); //36,9
-  PrintAndLog("IO Prox XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2);
+  uint8_t crc = bytebits_to_byte(BitStream+idx+54,8);
+  uint16_t calccrc = 0;
+
+  for (uint8_t i=1; i<6; ++i){
+    calccrc += bytebits_to_byte(BitStream+idx+9*i,8);
+    //PrintAndLog("%d", calccrc);
+  }
+  calccrc &= 0xff;
+  calccrc = 0xff - calccrc;
+
+  char *crcStr = (crc == calccrc) ? "crc ok": "!crc";
+
+  PrintAndLog("IO Prox XSF(%02d)%02x:%05d (%08x%08x) [%02x %s]",version,facilitycode,number,code,code2, crc, crcStr);
   setDemodBuf(BitStream,64,idx);
   if (g_debugMode){
     PrintAndLog("DEBUG: idx: %d, Len: %d, Printing demod buffer:",idx,64);
@@ -1859,21 +1955,19 @@ int NRZrawDemod(const char *Cmd, bool verbose)
   int errCnt=0;
   errCnt = nrzRawDemod(BitStream, &BitLen, &clk, &invert, maxErr);
   if (errCnt > maxErr){
-    if (g_debugMode==1 && verbose) PrintAndLog("Too many errors found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt);
+    if (g_debugMode) PrintAndLog("Too many errors found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt);
     return 0;
   } 
   if (errCnt<0|| BitLen<16){  //throw away static - allow 1 and -1 (in case of threshold command first)
-    if (g_debugMode==1 && verbose) PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt);
+    if (g_debugMode) PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt);
     return 0;
   }
-  PrintAndLog("Tried NRZ Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen);
+  if (verbose || g_debugMode) PrintAndLog("Tried NRZ Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen);
   //prime demod buffer for output
   setDemodBuf(BitStream,BitLen,0);
 
-  if (errCnt>0 && verbose){
-    PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
-  }
-  if (verbose) {
+  if (errCnt>0 && (verbose || g_debugMode)) PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
+  if (verbose || g_debugMode) {
     PrintAndLog("NRZ demoded bitstream:");
     // Now output the bitstream to the scrollback by line of 16 bits
     printDemodBuff();
@@ -1977,7 +2071,7 @@ int CmdRawDemod(const char *Cmd)
                PrintAndLog("   <help> as 'h', prints the help for the specific modulation");   
                PrintAndLog("   <options> see specific modulation help for optional parameters");                               
                PrintAndLog("");
-               PrintAndLog("    sample: data rawdemod fs h         = print help for ask/raw demod");
+               PrintAndLog("    sample: data rawdemod fs h         = print help specific to fsk demod");
                PrintAndLog("          : data rawdemod fs           = demod GraphBuffer using: fsk - autodetect");
                PrintAndLog("          : data rawdemod ab           = demod GraphBuffer using: ask/biphase - autodetect");
                PrintAndLog("          : data rawdemod am           = demod GraphBuffer using: ask/manchester - autodetect");
@@ -2106,57 +2200,64 @@ uint8_t getByte(uint8_t bits_per_sample, BitstreamOut* b)
        return val;
 }
 
-int CmdSamples(const char *Cmd)
+int getSamples(const char *Cmd, bool silent)
 {
-       //If we get all but the last byte in bigbuf,
-       // we don't have to worry about remaining trash
-       // in the last byte in case the bits-per-sample
-       // does not line up on byte boundaries
-       uint8_t got[BIGBUF_SIZE-1] = { 0 };
+  //If we get all but the last byte in bigbuf,
+  // we don't have to worry about remaining trash
+  // in the last byte in case the bits-per-sample
+  // does not line up on byte boundaries
 
-       int n = strtol(Cmd, NULL, 0);
-       if (n == 0)
-               n = sizeof(got);
+  uint8_t got[BIGBUF_SIZE-1] = { 0 };
 
-       if (n > sizeof(got))
-               n = sizeof(got);
+  int n = strtol(Cmd, NULL, 0);
 
-       PrintAndLog("Reading %d bytes from device memory\n", n);
-       GetFromBigBuf(got,n,0);
-       PrintAndLog("Data fetched");
-       UsbCommand response;
-       WaitForResponse(CMD_ACK, &response);
-       uint8_t bits_per_sample = 8;
+  if (n == 0)
+    n = sizeof(got);
 
-       //Old devices without this feature would send 0 at arg[0]
-       if(response.arg[0] > 0)
-       {
-               sample_config *sc = (sample_config *) response.d.asBytes;
-               PrintAndLog("Samples @ %d bits/smpl, decimation 1:%d ", sc->bits_per_sample
-                                       , sc->decimation);
-               bits_per_sample = sc->bits_per_sample;
-       }
-       if(bits_per_sample < 8)
-       {
-               PrintAndLog("Unpacking...");
-               BitstreamOut bout = { got, bits_per_sample * n,  0};
-               int j =0;
-               for (j = 0; j * bits_per_sample < n * 8 && j < sizeof(GraphBuffer); j++) {
-                       uint8_t sample = getByte(bits_per_sample, &bout);
-                       GraphBuffer[j] = ((int) sample )- 128;
-               }
-               GraphTraceLen = j;
-               PrintAndLog("Unpacked %d samples" , j );
-       }else
-       {
-               for (int j = 0; j < n; j++) {
-                       GraphBuffer[j] = ((int)got[j]) - 128;
-               }
-               GraphTraceLen = n;
-       }
+  if (n > sizeof(got))
+    n = sizeof(got);
 
-       RepaintGraphWindow();
-       return 0;
+  PrintAndLog("Reading %d bytes from device memory\n", n);
+  GetFromBigBuf(got,n,0);
+  PrintAndLog("Data fetched");
+  UsbCommand response;
+  WaitForResponse(CMD_ACK, &response);
+  uint8_t bits_per_sample = 8;
+
+  //Old devices without this feature would send 0 at arg[0]
+  if(response.arg[0] > 0)
+  {
+    sample_config *sc = (sample_config *) response.d.asBytes;
+    PrintAndLog("Samples @ %d bits/smpl, decimation 1:%d ", sc->bits_per_sample
+          , sc->decimation);
+    bits_per_sample = sc->bits_per_sample;
+  }
+  if(bits_per_sample < 8)
+  {
+    PrintAndLog("Unpacking...");
+    BitstreamOut bout = { got, bits_per_sample * n,  0};
+    int j =0;
+    for (j = 0; j * bits_per_sample < n * 8 && j < sizeof(GraphBuffer); j++) {
+      uint8_t sample = getByte(bits_per_sample, &bout);
+      GraphBuffer[j] = ((int) sample )- 128;
+    }
+    GraphTraceLen = j;
+    PrintAndLog("Unpacked %d samples" , j );
+  }else
+  {
+    for (int j = 0; j < n; j++) {
+      GraphBuffer[j] = ((int)got[j]) - 128;
+    }
+    GraphTraceLen = n;
+  }
+
+  RepaintGraphWindow();
+  return 0;
+}
+
+int CmdSamples(const char *Cmd)
+{
+  return getSamples(Cmd, false);
 }
 
 int CmdTuneSamples(const char *Cmd)
@@ -2652,60 +2753,52 @@ int CmdZerocrossings(const char *Cmd)
 
 static command_t CommandTable[] =
 {
-  {"help",          CmdHelp,            1, "This help"},
-  {"amp",           CmdAmp,             1, "Amplify peaks"},
+  {"help",            CmdHelp,            1, "This help"},
+  {"amp",             CmdAmp,             1, "Amplify peaks"},
   //{"askdemod",      Cmdaskdemod,        1, "<0 or 1> -- Attempt to demodulate simple ASK tags"},
-  {"askedgedetect", CmdAskEdgeDetect,   1, "[threshold] Adjust Graph for manual ask demod using length of sample differences to detect the edge of a wave (default = 25)"},
-  {"askem410xdemod",CmdAskEM410xDemod,  1, "[clock] [invert<0|1>] [maxErr] -- Demodulate an EM410x tag from GraphBuffer (args optional)"},
-  {"askgproxiidemod",CmdG_Prox_II_Demod,1, "Demodulate a G Prox II tag from GraphBuffer"},
-  //{"askmandemod",   Cmdaskmandemod,     1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional)"},
-  //{"askrawdemod",   Cmdaskrawdemod,     1, "[clock] [invert<0|1>] -- Attempt to demodulate ASK tags and output bin (args optional)"},
-  {"autocorr",      CmdAutoCorr,        1, "[window length] [g] -- Autocorrelation over window - g to save back to GraphBuffer (overwrite)"},
+  {"askedgedetect",   CmdAskEdgeDetect,   1, "[threshold] Adjust Graph for manual ask demod using length of sample differences to detect the edge of a wave (default = 25)"},
+  {"askem410xdemod",  CmdAskEM410xDemod,  1, "[clock] [invert<0|1>] [maxErr] -- Demodulate an EM410x tag from GraphBuffer (args optional)"},
+  {"askgproxiidemod", CmdG_Prox_II_Demod, 1, "Demodulate a G Prox II tag from GraphBuffer"},
+  {"autocorr",        CmdAutoCorr,        1, "[window length] [g] -- Autocorrelation over window - g to save back to GraphBuffer (overwrite)"},
   {"biphaserawdecode",CmdBiphaseDecodeRaw,1,"[offset] [invert<0|1>] Biphase decode bin stream in DemodBuffer (offset = 0|1 bits to shift the decode start)"},
-  {"bitsamples",    CmdBitsamples,      0, "Get raw samples as bitstring"},
+  {"bitsamples",      CmdBitsamples,      0, "Get raw samples as bitstring"},
   //{"bitstream",     CmdBitstream,       1, "[clock rate] -- Convert waveform into a bitstream"},
-  {"buffclear",     CmdBuffClear,       1, "Clear sample buffer and graph window"},
-  {"dec",           CmdDec,             1, "Decimate samples"},
-  {"detectclock",   CmdDetectClockRate, 1, "[modulation] Detect clock rate of wave in GraphBuffer (options: 'a','f','n','p' for ask, fsk, nrz, psk respectively)"},
+  {"buffclear",       CmdBuffClear,       1, "Clear sample buffer and graph window"},
+  {"dec",             CmdDec,             1, "Decimate samples"},
+  {"detectclock",     CmdDetectClockRate, 1, "[modulation] Detect clock rate of wave in GraphBuffer (options: 'a','f','n','p' for ask, fsk, nrz, psk respectively)"},
   //{"fskdemod",      CmdFSKdemod,        1, "Demodulate graph window as a HID FSK"},
-  {"fskawiddemod",  CmdFSKdemodAWID,    1, "Demodulate an AWID FSK tag from GraphBuffer"},
+  {"fskawiddemod",    CmdFSKdemodAWID,    1, "Demodulate an AWID FSK tag from GraphBuffer"},
   //{"fskfcdetect",   CmdFSKfcDetect,     1, "Try to detect the Field Clock of an FSK wave"},
-  {"fskhiddemod",   CmdFSKdemodHID,     1, "Demodulate a HID FSK tag from GraphBuffer"},
-  {"fskiodemod",    CmdFSKdemodIO,      1, "Demodulate an IO Prox FSK tag from GraphBuffer"},
-  {"fskpyramiddemod",CmdFSKdemodPyramid,1, "Demodulate a Pyramid FSK tag from GraphBuffer"},
-  {"fskparadoxdemod",CmdFSKdemodParadox,1, "Demodulate a Paradox FSK tag from GraphBuffer"},
-  //{"fskrawdemod",   CmdFSKrawdemod,     1, "[clock rate] [invert] [rchigh] [rclow] Demodulate graph window from FSK to bin (clock = 50)(invert = 1|0)(rchigh = 10)(rclow=8)"},
-  {"getbitstream",  CmdGetBitStream,    1, "Convert GraphBuffer's >=1 values to 1 and <1 to 0"},
-  {"grid",          CmdGrid,            1, "<x> <y> -- overlay grid on graph window, use zero value to turn off either"},
-  {"hexsamples",    CmdHexsamples,      0, "<bytes> [<offset>] -- Dump big buffer as hex bytes"},
-  {"hide",          CmdHide,            1, "Hide graph window"},
-  {"hpf",           CmdHpf,             1, "Remove DC offset from trace"},
-  {"load",          CmdLoad,            1, "<filename> -- Load trace (to graph window"},
-  {"ltrim",         CmdLtrim,           1, "<samples> -- Trim samples from left of trace"},
-  {"rtrim",         CmdRtrim,           1, "<location to end trace> -- Trim samples from right of trace"},
+  {"fskhiddemod",     CmdFSKdemodHID,     1, "Demodulate a HID FSK tag from GraphBuffer"},
+  {"fskiodemod",      CmdFSKdemodIO,      1, "Demodulate an IO Prox FSK tag from GraphBuffer"},
+  {"fskpyramiddemod", CmdFSKdemodPyramid, 1, "Demodulate a Pyramid FSK tag from GraphBuffer"},
+  {"fskparadoxdemod", CmdFSKdemodParadox, 1, "Demodulate a Paradox FSK tag from GraphBuffer"},
+  {"getbitstream",    CmdGetBitStream,    1, "Convert GraphBuffer's >=1 values to 1 and <1 to 0"},
+  {"grid",            CmdGrid,            1, "<x> <y> -- overlay grid on graph window, use zero value to turn off either"},
+  {"hexsamples",      CmdHexsamples,      0, "<bytes> [<offset>] -- Dump big buffer as hex bytes"},
+  {"hide",            CmdHide,            1, "Hide graph window"},
+  {"hpf",             CmdHpf,             1, "Remove DC offset from trace"},
+  {"load",            CmdLoad,            1, "<filename> -- Load trace (to graph window"},
+  {"ltrim",           CmdLtrim,           1, "<samples> -- Trim samples from left of trace"},
+  {"rtrim",           CmdRtrim,           1, "<location to end trace> -- Trim samples from right of trace"},
   //{"mandemod",      CmdManchesterDemod, 1, "[i] [clock rate] -- Manchester demodulate binary stream (option 'i' to invert output)"},
-  {"manrawdecode",  Cmdmandecoderaw,    1, "Manchester decode binary stream in DemodBuffer"},
-  {"manmod",        CmdManchesterMod,   1, "[clock rate] -- Manchester modulate a binary stream"},
-  {"norm",          CmdNorm,            1, "Normalize max/min to +/-128"},
-  //{"nrzdetectclock",CmdDetectNRZClockRate, 1, "Detect ASK, PSK, or NRZ clock rate"},
-  //{"nrzrawdemod",   CmdNRZrawDemod,     1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate nrz tags and output binary (args optional)"},
-  {"plot",          CmdPlot,            1, "Show graph window (hit 'h' in window for keystroke help)"},
-  //{"pskdetectclock",CmdDetectPSKClockRate, 1, "Detect ASK, PSK, or NRZ clock rate"},
-  {"printdemodbuffer",CmdPrintDemodBuff,1, "[x] -- print the data in the DemodBuffer - 'x' for hex output"},
-  {"pskindalademod",CmdIndalaDecode,    1, "[clock] [invert<0|1>] -- Demodulate an indala tag (PSK1) from GraphBuffer (args optional)"},
-  //{"psk1rawdemod",  CmdPSK1rawDemod,    1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate psk1 tags and output binary (args optional)"},
-  //{"psk2rawdemod",  CmdPSK2rawDemod,    1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate psk2 tags and output binary (args optional)"},
-  {"rawdemod",      CmdRawDemod,        1, "[modulation] ... <options> -see help (h option) -- Demodulate the data in the GraphBuffer and output binary"},  
-  {"samples",       CmdSamples,         0, "[512 - 40000] -- Get raw samples for graph window (GraphBuffer)"},
-  {"save",          CmdSave,            1, "<filename> -- Save trace (from graph window)"},
-  {"scale",         CmdScale,           1, "<int> -- Set cursor display scale"},
-  {"setdebugmode",  CmdSetDebugMode,    1, "<0|1> -- Turn on or off Debugging Mode for demods"},
-  {"shiftgraphzero",CmdGraphShiftZero,  1, "<shift> -- Shift 0 for Graphed wave + or - shift value"},
+  {"manrawdecode",    Cmdmandecoderaw,    1, "Manchester decode binary stream in DemodBuffer"},
+  {"manmod",          CmdManchesterMod,   1, "[clock rate] -- Manchester modulate a binary stream"},
+  {"norm",            CmdNorm,            1, "Normalize max/min to +/-128"},
+  {"plot",            CmdPlot,            1, "Show graph window (hit 'h' in window for keystroke help)"},
+  {"printdemodbuffer",CmdPrintDemodBuff,  1, "[x] -- print the data in the DemodBuffer - 'x' for hex output"},
+  {"pskindalademod",  CmdIndalaDecode,    1, "[clock] [invert<0|1>] -- Demodulate an indala tag (PSK1) from GraphBuffer (args optional)"},
+  {"rawdemod",        CmdRawDemod,        1, "[modulation] ... <options> -see help (h option) -- Demodulate the data in the GraphBuffer and output binary"},  
+  {"samples",         CmdSamples,         0, "[512 - 40000] -- Get raw samples for graph window (GraphBuffer)"},
+  {"save",            CmdSave,            1, "<filename> -- Save trace (from graph window)"},
+  {"scale",           CmdScale,           1, "<int> -- Set cursor display scale"},
+  {"setdebugmode",    CmdSetDebugMode,    1, "<0|1> -- Turn on or off Debugging Mode for demods"},
+  {"shiftgraphzero",  CmdGraphShiftZero,  1, "<shift> -- Shift 0 for Graphed wave + or - shift value"},
   //{"threshold",     CmdThreshold,       1, "<threshold> -- Maximize/minimize every value in the graph window depending on threshold"},
-  {"dirthreshold",  CmdDirectionalThreshold,   1, "<thres up> <thres down> -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev."},
-  {"tune",          CmdTuneSamples,     0, "Get hw tune samples for graph window"},
-  {"undec",         CmdUndec,           1, "Un-decimate samples by 2"},
-  {"zerocrossings", CmdZerocrossings,   1, "Count time between zero-crossings"},
+  {"dirthreshold",    CmdDirectionalThreshold,   1, "<thres up> <thres down> -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev."},
+  {"tune",            CmdTuneSamples,     0, "Get hw tune samples for graph window"},
+  {"undec",           CmdUndec,           1, "Un-decimate samples by 2"},
+  {"zerocrossings",   CmdZerocrossings,   1, "Count time between zero-crossings"},
   {NULL, NULL, 0, NULL}
 };
 
index 831d35f3737671efa8c8ce37802dbbb3b3fbf383..f6b4b950a53933f44bf97973d4552146b878488c 100644 (file)
@@ -63,12 +63,16 @@ int CmdThreshold(const char *Cmd);
 int CmdDirectionalThreshold(const char *Cmd);
 int CmdZerocrossings(const char *Cmd);
 int CmdIndalaDecode(const char *Cmd);
+int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo);
 int ASKbiphaseDemod(const char *Cmd, bool verbose);
 int ASKmanDemod(const char *Cmd, bool verbose, bool emSearch);
 int ASKrawDemod(const char *Cmd, bool verbose);
 int FSKrawDemod(const char *Cmd, bool verbose);
 int PSKDemod(const char *Cmd, bool verbose);
 int NRZrawDemod(const char *Cmd, bool verbose);
+void printEM410x(uint32_t hi, uint64_t id);
+int getSamples(const char *Cmd, bool silent);
+
 
 #define MAX_DEMOD_BUF_LEN (1024*128)
 extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
index 039a33d55640e6c602e6dd6a600a326816e6bf2a..0fab2adfa562fa75db73d507086f422c066e9510 100644 (file)
@@ -362,6 +362,7 @@ int usage_lf_read()
        PrintAndLog("Usage: lf read");
        PrintAndLog("Options:        ");
        PrintAndLog("       h            This help");
+       PrintAndLog("       s            silent run no printout");
        PrintAndLog("This function takes no arguments. ");
        PrintAndLog("Use 'lf config' to set parameters.");
        return 0;
@@ -481,13 +482,15 @@ int CmdLFSetConfig(const char *Cmd)
 int CmdLFRead(const char *Cmd)
 {
 
-       uint8_t cmdp =0;
-       if(param_getchar(Cmd, cmdp) == 'h')
+       uint8_t cmdp = 0;
+       bool arg1 = false;
+       if (param_getchar(Cmd, cmdp) == 'h')
        {
                return usage_lf_read();
        }
+       if (param_getchar(Cmd, cmdp) == 's') arg1 = true; //suppress print
        //And ship it to device
-       UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K};
+       UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, {arg1,0,0}};
        SendCommand(&c);
        WaitForResponse(CMD_ACK,NULL);
        return 0;
@@ -1016,7 +1019,7 @@ int CmdLFfind(const char *Cmd)
   int ans=0;
   char cmdp = param_getchar(Cmd, 0);
   char testRaw = param_getchar(Cmd, 1);
-  if (strlen(Cmd) > 2 || cmdp == 'h' || cmdp == 'H') {
+  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.");
@@ -1037,50 +1040,60 @@ int CmdLFfind(const char *Cmd)
     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)
@@ -1127,7 +1140,7 @@ static command_t CommandTable[] =
   {"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, "Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"},
+  {"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"},
index f6671bcdb27586eb376e147d9df30ed27cdaf17a..b915aa5aac5f62f63e7d35a70f6bd23a61cf78cd 100644 (file)
@@ -43,163 +43,24 @@ int CmdEMdemodASK(const char *Cmd)
  */
 int CmdEM410xRead(const char *Cmd)
 {
-  int i, j, clock, header, rows, bit, hithigh, hitlow, first, bit2idx, high, low;
-  int parity[4];
-  char id[11] = {0x00};
-  char id2[11] = {0x00};
-  int retested = 0;
-  uint8_t BitStream[MAX_GRAPH_TRACE_LEN];
-  high = low = 0;
-
-  /* Detect high and lows and clock */
-  for (i = 0; i < GraphTraceLen; i++)
-  {
-    if (GraphBuffer[i] > high)
-      high = GraphBuffer[i];
-    else if (GraphBuffer[i] < low)
-      low = GraphBuffer[i];
-  }
-
-  /* get clock */
-  clock = GetAskClock(Cmd, false, false);
-
-  /* parity for our 4 columns */
-  parity[0] = parity[1] = parity[2] = parity[3] = 0;
-  header = rows = 0;
-
-  // manchester demodulate
-  bit = bit2idx = 0;
-  for (i = 0; i < (int)(GraphTraceLen / clock); i++)
-  {
-    hithigh = 0;
-    hitlow = 0;
-    first = 1;
-
-    /* Find out if we hit both high and low peaks */
-    for (j = 0; j < clock; j++)
-    {
-      if (GraphBuffer[(i * clock) + j] >= high)
-        hithigh = 1;
-      else if (GraphBuffer[(i * clock) + j] <= low)
-        hitlow = 1;
-
-      /* it doesn't count if it's the first part of our read
-       because it's really just trailing from the last sequence */
-      if (first && (hithigh || hitlow))
-        hithigh = hitlow = 0;
-      else
-        first = 0;
-
-      if (hithigh && hitlow)
-        break;
-    }
-
-    /* If we didn't hit both high and low peaks, we had a bit transition */
-    if (!hithigh || !hitlow)
-      bit ^= 1;
-
-    BitStream[bit2idx++] = bit;
-  }
-
-retest:
-  /* We go till 5 before the graph ends because we'll get that far below */
-  for (i = 1; i < bit2idx - 5; i++)
-  {
-    /* Step 2: We have our header but need our tag ID */
-    if (header == 9 && rows < 10)
-    {
-      /* Confirm parity is correct */
-      if ((BitStream[i] ^ BitStream[i+1] ^ BitStream[i+2] ^ BitStream[i+3]) == BitStream[i+4])
-      {
-        /* Read another byte! */
-        sprintf(id+rows, "%x", (8 * BitStream[i]) + (4 * BitStream[i+1]) + (2 * BitStream[i+2]) + (1 * BitStream[i+3]));
-        sprintf(id2+rows, "%x", (8 * BitStream[i+3]) + (4 * BitStream[i+2]) + (2 * BitStream[i+1]) + (1 * BitStream[i]));
-        rows++;
-
-        /* Keep parity info */
-        parity[0] ^= BitStream[i];
-        parity[1] ^= BitStream[i+1];
-        parity[2] ^= BitStream[i+2];
-        parity[3] ^= BitStream[i+3];
-
-        /* Move 4 bits ahead */
-        i += 4;
-      }
-
-      /* Damn, something wrong! reset */
-      else
-      {
-        PrintAndLog("Thought we had a valid tag but failed at word %d (i=%d)", rows + 1, i);
-
-        /* Start back rows * 5 + 9 header bits, -1 to not start at same place */
-        i -= 9 + (5 * rows) - 5;
-
-        rows = header = 0;
-      }
-    }
-
-    /* Step 3: Got our 40 bits! confirm column parity */
-    else if (rows == 10)
-    {
-      /* We need to make sure our 4 bits of parity are correct and we have a stop bit */
-      if (BitStream[i] == parity[0] && BitStream[i+1] == parity[1] &&
-        BitStream[i+2] == parity[2] && BitStream[i+3] == parity[3] &&
-        BitStream[i+4] == 0)
-      {
-        /* Sweet! */
-        PrintAndLog("EM410x Tag ID: %s", id);
-        PrintAndLog("Unique Tag ID: %s", id2);
-
-               global_em410xId = id;
-               
-        /* Stop any loops */
-        return 1;
-      }
-
-      /* Crap! Incorrect parity or no stop bit, start all over */
-      else
-      {
-        rows = header = 0;
-
-        /* Go back 59 bits (9 header bits + 10 rows at 4+1 parity) */
-        i -= 59;
-      }
-    }
-
-    /* Step 1: get our header */
-    else if (header < 9)
-    {
-      /* Need 9 consecutive 1's */
-      if (BitStream[i] == 1)
-        header++;
-
-      /* We don't have a header, not enough consecutive 1 bits */
-      else
-        header = 0;
-    }
-  }
-
-  /* if we've already retested after flipping bits, return */
-       if (retested++){
-               PrintAndLog("Failed to decode");
+  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;
-       }
-
-  /* if this didn't work, try flipping bits */
-  for (i = 0; i < bit2idx; i++)
-    BitStream[i] ^= 1;
-
-  goto retest;
+  }
+  char id[12] = {0x00};
+  sprintf(id, "%010llx",lo);
+  
+  global_em410xId = id;
+  return 1;
 }
 
-/* emulate an EM410X tag
- * Format:
- *   1111 1111 1           <-- standard non-repeatable header
- *   XXXX [row parity bit] <-- 10 rows of 5 bits for our 40 bit tag ID
- *   ....
- *   CCCC                  <-- each bit here is parity for the 10 bits above in corresponding column
- *   0                     <-- stop bit, end of tag
- */
+// emulate an EM410X tag
 int CmdEM410xSim(const char *Cmd)
 {
        int i, n, j, binary[4], parity[4];
@@ -282,28 +143,25 @@ int CmdEM410xSim(const char *Cmd)
 */
 int CmdEM410xWatch(const char *Cmd)
 {
-       char cmdp = param_getchar(Cmd, 0);
-       int read_h = (cmdp == 'h');
        do {
                if (ukbhit()) {
                        printf("\naborted via keyboard!\n");
                        break;
                }
                
-               CmdLFRead(read_h ? "h" : "");
-               CmdSamples("6000");             
-       } while (
-               !CmdEM410xRead("") 
-       );
+               CmdLFRead("s");
+               getSamples("8192",true); //capture enough to get 2 full messages                
+       } while (!CmdEM410xRead(""));
+
        return 0;
 }
 
 int CmdEM410xWatchnSpoof(const char *Cmd)
 {
        CmdEM410xWatch(Cmd);
-    PrintAndLog("# Replaying : %s",global_em410xId);
-    CmdEM410xSim(global_em410xId);
-  return 0;
+       PrintAndLog("# Replaying captured ID: %s",global_em410xId);
+       CmdLFaskSim("");
+       return 0;
 }
 
 /* Read the transmitted data of an EM4x50 tag
index a719c7ad7a56e4a6216e910aa4d28cad3069007d..da3ee1a9f04b3f4612d69e30946a341665e9f84c 100644 (file)
 #include "proxmark3.h"\r
 #include "ui.h"\r
 #include "graph.h"\r
+#include "cmdmain.h"\r
 #include "cmdparser.h"\r
 #include "cmddata.h"\r
 #include "cmdlf.h"\r
 #include "cmdlft55xx.h"\r
+#include "util.h"\r
+#include "data.h"\r
+#include "lfdemod.h"\r
+#include "../common/crc.h"\r
+#include "../common/iso14443crc.h"\r
+#include "cmdhf14a.h"\r
+\r
+#define CONFIGURATION_BLOCK 0x00\r
+#define TRACE_BLOCK 0x01\r
+\r
+// Default configuration\r
+t55xx_conf_block_t config = { .modulation = DEMOD_ASK, .inverted = FALSE, .offset = 0x00, .block0 = 0x00};\r
+\r
+int usage_t55xx_config(){\r
+       PrintAndLog("Usage: lf t55xx config [d <demodulation>] [i 1] [o <offset>]");\r
+       PrintAndLog("Options:        ");\r
+       PrintAndLog("       h                        This help");\r
+       PrintAndLog("       b <8|16|32|40|50|64|100|128>     Set bitrate");\r
+       PrintAndLog("       d <FSK|FSK1|FSK1a|FSK2|FSK2a|ASK|PSK1|PSK2|NZ|BI|BIa>  Set demodulation FSK / ASK / PSK / NZ / Biphase / Biphase A");\r
+       PrintAndLog("       i [1]                            Invert data signal, defaults to normal");\r
+       PrintAndLog("       o [offset]                       Set offset, where data should start decode in bitstream");\r
+       PrintAndLog("");\r
+       PrintAndLog("Examples:");\r
+       PrintAndLog("      lf t55xx config d FSK          - FSK demodulation");\r
+       PrintAndLog("      lf t55xx config d FSK i 1      - FSK demodulation, inverse data");\r
+       PrintAndLog("      lf t55xx config d FSK i 1 o 3  - FSK demodulation, inverse data, offset=3,start from position 3 to decode data");\r
+       PrintAndLog("");\r
+       return 0;\r
+}\r
+int usage_t55xx_read(){\r
+       PrintAndLog("Usage:  lf t55xx read <block> <password>");\r
+    PrintAndLog("     <block>, block number to read. Between 0-7");\r
+    PrintAndLog("     <password>, OPTIONAL password (8 hex characters)");\r
+    PrintAndLog("");\r
+       PrintAndLog("Examples:");\r
+    PrintAndLog("      lf t55xx read 0           - read data from block 0");\r
+       PrintAndLog("      lf t55xx read 0 feedbeef  - read data from block 0 password feedbeef");\r
+       PrintAndLog("");\r
+       return 0;\r
+}\r
+int usage_t55xx_write(){\r
+       PrintAndLog("Usage:  lf t55xx wr <block> <data> [password]");\r
+    PrintAndLog("     <block>, block number to read. Between 0-7");\r
+       PrintAndLog("     <data>,  4 bytes of data to write (8 hex characters)");\r
+    PrintAndLog("     [password], OPTIONAL password 4bytes (8 hex characters)");\r
+    PrintAndLog("");\r
+       PrintAndLog("Examples:");\r
+    PrintAndLog("      lf t55xx wd 3 11223344           - write 11223344 to block 3");\r
+       PrintAndLog("      lf t55xx wd 3 11223344 feedbeef  - write 11223344 to block 3 password feedbeef");\r
+       PrintAndLog("");\r
+       return 0;\r
+}\r
+int usage_t55xx_trace() {\r
+       PrintAndLog("Usage:  lf t55xx trace [1]");\r
+       PrintAndLog("     [graph buffer data], if set, use Graphbuffer otherwise read data from tag.");\r
+       PrintAndLog("");\r
+       PrintAndLog("Examples:");\r
+       PrintAndLog("      lf t55xx trace");\r
+       PrintAndLog("      lf t55xx trace 1");\r
+       PrintAndLog("");\r
+       return 0;\r
+}\r
+int usage_t55xx_info() {\r
+       PrintAndLog("Usage:  lf t55xx info [1]");\r
+       PrintAndLog("     [graph buffer data], if set, use Graphbuffer otherwise read data from tag.");\r
+       PrintAndLog("");\r
+       PrintAndLog("Examples:");\r
+       PrintAndLog("      lf t55xx info");\r
+       PrintAndLog("      lf t55xx info 1");\r
+       PrintAndLog("");\r
+       return 0;\r
+}\r
+int usage_t55xx_dump(){\r
+       PrintAndLog("Usage:  lf t55xx dump <password>");\r
+    PrintAndLog("     <password>, OPTIONAL password 4bytes (8 hex symbols)");\r
+       PrintAndLog("");\r
+       PrintAndLog("Examples:");\r
+       PrintAndLog("      lf t55xx dump");\r
+       PrintAndLog("      lf t55xx dump feedbeef");\r
+       PrintAndLog("");\r
+       return 0;\r
+}\r
+int usage_t55xx_detect(){\r
+       PrintAndLog("Usage:  lf t55xx detect");\r
+       PrintAndLog("");\r
+       PrintAndLog("Examples:");\r
+       PrintAndLog("      lf t55xx detect");\r
+       PrintAndLog("      lf t55xx detect 1");\r
+       PrintAndLog("");\r
+       return 0;\r
+}\r
 \r
 static int CmdHelp(const char *Cmd);\r
 \r
+int CmdT55xxSetConfig(const char *Cmd) {\r
 \r
-int CmdReadBlk(const char *Cmd)\r
-{\r
-  int Block = 8; //default to invalid block\r
-  UsbCommand c;\r
+       uint8_t offset = 0;\r
+       bool errors = FALSE;\r
+       uint8_t cmdp = 0;\r
+       char modulation[5] = {0x00};\r
+       char tmp = 0x00;\r
+       uint8_t bitRate = 0;\r
+       uint8_t rates[9] = {8,16,32,40,50,64,100,128,0};\r
+       while(param_getchar(Cmd, cmdp) != 0x00 && !errors)\r
+       {\r
+               tmp = param_getchar(Cmd, cmdp);\r
+               switch(tmp)\r
+               {\r
+               case 'h':\r
+               case 'H':\r
+                       return usage_t55xx_config();\r
+               case 'b':\r
+                       errors |= param_getdec(Cmd, cmdp+1, &bitRate);\r
+                       if ( !errors){\r
+                               uint8_t i = 0;\r
+                               for (; i < 9; i++){\r
+                                       if (rates[i]==bitRate) {\r
+                                               config.bitrate = i;\r
+                                               break;\r
+                                       }\r
+                               }\r
+                               if (i==9) errors = TRUE;\r
+                       }\r
+                       cmdp+=2;\r
+                       break;\r
+               case 'd':\r
+                       param_getstr(Cmd, cmdp+1, modulation);\r
+                       cmdp += 2;\r
 \r
-  sscanf(Cmd, "%d", &Block);\r
+                       if ( strcmp(modulation, "FSK" ) == 0)\r
+                               config.modulation = DEMOD_FSK;\r
+                       else if ( strcmp(modulation, "FSK1" ) == 0)\r
+                               config.modulation = DEMOD_FSK1;\r
+                       else if ( strcmp(modulation, "FSK1a" ) == 0)\r
+                               config.modulation = DEMOD_FSK1a;\r
+                       else if ( strcmp(modulation, "FSK2" ) == 0)\r
+                               config.modulation = DEMOD_FSK2;\r
+                       else if ( strcmp(modulation, "FSK2a" ) == 0)\r
+                               config.modulation = DEMOD_FSK2a;\r
+                       else if ( strcmp(modulation, "ASK" ) == 0)\r
+                               config.modulation = DEMOD_ASK;\r
+                       else if ( strcmp(modulation, "NRZ" ) == 0)\r
+                               config.modulation = DEMOD_NRZ;\r
+                       else if ( strcmp(modulation, "PSK1" ) == 0)\r
+                               config.modulation = DEMOD_PSK1;\r
+                       else if ( strcmp(modulation, "PSK2" ) == 0)\r
+                               config.modulation = DEMOD_PSK2;\r
+                       else if ( strcmp(modulation, "PSK3" ) == 0)\r
+                               config.modulation = DEMOD_PSK3;\r
+                       else if ( strcmp(modulation, "BIa" ) == 0)\r
+                               config.modulation = DEMOD_BIa;\r
+                       else if ( strcmp(modulation, "BI" ) == 0)\r
+                               config.modulation = DEMOD_BI;\r
+                       else {\r
+                               PrintAndLog("Unknown modulation '%s'", modulation);\r
+                               errors = TRUE;\r
+                       }\r
+                       break;\r
+               case 'i':\r
+                       config.inverted = param_getchar(Cmd,cmdp+1) == '1';\r
+                       cmdp+=2;\r
+                       break;\r
+               case 'o':\r
+                       errors |= param_getdec(Cmd, cmdp+1, &offset);\r
+                       if ( !errors )\r
+                               config.offset = offset;\r
+                       cmdp+=2;\r
+                       break;\r
+               default:\r
+                       PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));\r
+                       errors = TRUE;\r
+                       break;\r
+               }\r
+       }\r
 \r
-  if (Block > 7) {\r
-       PrintAndLog("Block must be between 0 and 7");\r
-       return 1;\r
-  }    \r
+       // No args\r
+       if (cmdp == 0) {\r
+               printConfiguration( config );\r
+               return 0;\r
+       }\r
+       //Validations\r
+       if (errors)\r
+               return usage_t55xx_config();\r
 \r
-  PrintAndLog("Reading block %d", Block);\r
+       config.block0 = 0;\r
+       printConfiguration ( config );\r
+       return 0;\r
+}\r
 \r
-  c.cmd = CMD_T55XX_READ_BLOCK;\r
-  c.d.asBytes[0] = 0x0; //Normal mode\r
-  c.arg[0] = 0;\r
-  c.arg[1] = Block;\r
-  c.arg[2] = 0;\r
-  SendCommand(&c);\r
-  return 0;\r
+int CmdT55xxReadBlock(const char *Cmd) {\r
+       int block = -1;\r
+       int password = 0xFFFFFFFF; //default to blank Block 7\r
+\r
+       char cmdp = param_getchar(Cmd, 0);\r
+       if (cmdp == 'h' || cmdp == 'H')\r
+               return usage_t55xx_read();\r
+\r
+       int res = sscanf(Cmd, "%d %x", &block, &password);\r
+\r
+       if ( res < 1 || res > 2 )\r
+               return usage_t55xx_read();\r
+\r
+       \r
+       if ((block < 0) | (block > 7)) {\r
+               PrintAndLog("Block must be between 0 and 7");\r
+               return 1;\r
+       }       \r
+\r
+       UsbCommand c = {CMD_T55XX_READ_BLOCK, {0, block, 0}};\r
+       c.d.asBytes[0] = 0x0; \r
+\r
+       //Password mode\r
+       if ( res == 2 ) {\r
+               c.arg[2] = password;\r
+               c.d.asBytes[0] = 0x1; \r
+       }\r
+\r
+       SendCommand(&c);\r
+       if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) {\r
+               PrintAndLog("command execution time out");\r
+               return 2;\r
+       }\r
+       \r
+       uint8_t got[12000];\r
+       GetFromBigBuf(got,sizeof(got),0);\r
+       WaitForResponse(CMD_ACK,NULL);\r
+       setGraphBuf(got, 12000);\r
+       DemodBufferLen=0;\r
+       if (!DecodeT55xxBlock()) return 3;\r
+       char blk[10]={0};\r
+       sprintf(blk,"%d", block);\r
+       printT55xxBlock(blk);\r
+       return 0;\r
 }\r
 \r
-int CmdReadBlkPWD(const char *Cmd)\r
-{\r
-  int Block = 8; //default to invalid block\r
-  int Password = 0xFFFFFFFF; //default to blank Block 7\r
-  UsbCommand c;\r
+bool DecodeT55xxBlock(){\r
+       \r
+       char buf[8] = {0x00};\r
+       char *cmdStr = buf;\r
+       int ans = 0;\r
+       uint8_t bitRate[8] = {8,16,32,40,50,64,100,128};\r
 \r
-  sscanf(Cmd, "%d %x", &Block, &Password);\r
+       DemodBufferLen = 0x00;\r
 \r
-  if (Block > 7) {\r
-       PrintAndLog("Block must be between 0 and 7");\r
-       return 1;\r
-  }    \r
+       switch( config.modulation ){\r
+               case DEMOD_FSK:\r
+                       //CmdLtrim("26");\r
+                       sprintf(cmdStr,"%d", bitRate[config.bitrate]/2 );\r
+                       CmdLtrim(cmdStr);                       \r
+                       sprintf(cmdStr,"%d %d", bitRate[config.bitrate], config.inverted );\r
+                       ans = FSKrawDemod(cmdStr, FALSE);\r
+                       break;\r
+               case DEMOD_FSK1:\r
+                       //CmdLtrim("26");\r
+                       sprintf(cmdStr,"%d", bitRate[config.bitrate]/2 );\r
+                       CmdLtrim(cmdStr);                       \r
+                       sprintf(cmdStr,"%d 1 8 5", bitRate[config.bitrate] );\r
+                       ans = FSKrawDemod(cmdStr, FALSE);\r
+                       break;\r
+               case DEMOD_FSK1a:\r
+                       //CmdLtrim("26");\r
+                       sprintf(cmdStr,"%d", bitRate[config.bitrate]/2 );\r
+                       CmdLtrim(cmdStr);                       \r
+                       sprintf(cmdStr,"%d 0 8 5", bitRate[config.bitrate] );\r
+                       ans = FSKrawDemod(cmdStr, FALSE);\r
+                       break;\r
+               case DEMOD_FSK2:\r
+                       //CmdLtrim("26");\r
+                       sprintf(cmdStr,"%d", bitRate[config.bitrate]/2 );\r
+                       CmdLtrim(cmdStr);                       \r
+                       sprintf(cmdStr,"%d 0 10 8", bitRate[config.bitrate] );\r
+                       ans = FSKrawDemod(cmdStr, FALSE);\r
+                       break;\r
+               case DEMOD_FSK2a:\r
+                       //CmdLtrim("26");\r
+                       sprintf(cmdStr,"%d", bitRate[config.bitrate]/2 );\r
+                       CmdLtrim(cmdStr);                       \r
+                       sprintf(cmdStr,"%d 1 10 8", bitRate[config.bitrate] );\r
+                       ans = FSKrawDemod(cmdStr, FALSE);\r
+                       break;\r
+               case DEMOD_ASK:\r
+                       sprintf(cmdStr,"%d %d 1", bitRate[config.bitrate], config.inverted );\r
+                       ans = ASKmanDemod(cmdStr, FALSE, FALSE);\r
+                       break;\r
+               case DEMOD_PSK1:\r
+                       sprintf(cmdStr,"%d %d 1", bitRate[config.bitrate], config.inverted );\r
+                       ans = PSKDemod(cmdStr, FALSE);\r
+                       break;\r
+               case DEMOD_PSK2:\r
+                       sprintf(cmdStr,"%d 1", bitRate[config.bitrate] );\r
+                       ans = PSKDemod(cmdStr, FALSE);\r
+                       psk1TOpsk2(DemodBuffer, DemodBufferLen);\r
+                       break;\r
+               case DEMOD_PSK3:\r
+                       sprintf(cmdStr,"%d %d 1", bitRate[config.bitrate], config.inverted );\r
+                       ans = PSKDemod(cmdStr, FALSE);\r
+                       psk1TOpsk2(DemodBuffer, DemodBufferLen);\r
+                       break;\r
+               case DEMOD_NRZ:\r
+                       sprintf(cmdStr,"%d %d 1", bitRate[config.bitrate], config.inverted );\r
+                       ans = NRZrawDemod(cmdStr, FALSE);\r
+                       break;\r
+               case DEMOD_BI:\r
+                       sprintf(cmdStr,"0 %d 0 1", bitRate[config.bitrate] );\r
+                       ans = ASKbiphaseDemod(cmdStr, FALSE);\r
+                       break;\r
+               case DEMOD_BIa:\r
+                       sprintf(cmdStr,"0 %d 1 1", bitRate[config.bitrate] );\r
+                       ans = ASKbiphaseDemod(cmdStr, FALSE);\r
+                       break;\r
+               default:\r
+                       return FALSE;\r
+       }\r
+       return (bool) ans;\r
+}\r
 \r
-  PrintAndLog("Reading block %d with password %08X", Block, Password);\r
+int CmdT55xxDetect(const char *Cmd){\r
 \r
-  c.cmd = CMD_T55XX_READ_BLOCK;\r
-  c.d.asBytes[0] = 0x1; //Password mode\r
-  c.arg[0] = 0;\r
-  c.arg[1] = Block;\r
-  c.arg[2] = Password;\r
-  SendCommand(&c);\r
-  return 0;\r
+       char cmdp = param_getchar(Cmd, 0);\r
+       if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H')\r
+               return usage_t55xx_detect();\r
+       \r
+       if (strlen(Cmd)==0)\r
+               AquireData( CONFIGURATION_BLOCK );\r
+\r
+       if ( !tryDetectModulation() )\r
+               PrintAndLog("Could not detect modulation automatically. Try setting it manually with \'lf t55xx config\'");\r
+\r
+       return 0;\r
 }\r
 \r
-int CmdWriteBlk(const char *Cmd)\r
-{\r
-  int Block = 8; //default to invalid block\r
-  int Data = 0xFFFFFFFF; //default to blank Block \r
-  UsbCommand c;\r
+// detect configuration?\r
+bool tryDetectModulation(){\r
+       char cmdStr[8] = {0};\r
+       uint8_t hits = 0;\r
+       t55xx_conf_block_t tests[15];\r
+       \r
+       if (GetFskClock("", FALSE, FALSE)){ \r
+               uint8_t fc1 = 0, fc2 = 0, clk=0;\r
+               fskClocks(&fc1, &fc2, &clk, FALSE);\r
+               sprintf(cmdStr,"%d", clk/2);\r
+               CmdLtrim(cmdStr);\r
+               if ( FSKrawDemod("0 0", FALSE) && test(DEMOD_FSK, &tests[hits].offset)){\r
+                       tests[hits].modulation = DEMOD_FSK;\r
+                       if (fc1==8 && fc2 == 5)\r
+                               tests[hits].modulation = DEMOD_FSK1a;\r
+                       else if (fc1==10 && fc2 == 8)\r
+                               tests[hits].modulation = DEMOD_FSK2;\r
 \r
-  sscanf(Cmd, "%x %d", &Data, &Block);\r
+                       tests[hits].inverted = FALSE;\r
+                       tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);\r
+                       ++hits;\r
+               }\r
+               if ( FSKrawDemod("0 1", FALSE) && test(DEMOD_FSK, &tests[hits].offset)) {\r
+                       tests[hits].modulation = DEMOD_FSK;\r
+                       if (fc1==8 && fc2 == 5)\r
+                               tests[hits].modulation = DEMOD_FSK1;\r
+                       else if (fc1==10 && fc2 == 8)\r
+                               tests[hits].modulation = DEMOD_FSK2a;\r
 \r
-  if (Block > 7) {\r
-       PrintAndLog("Block must be between 0 and 7");\r
-       return 1;\r
-  }    \r
+                       tests[hits].inverted = TRUE;\r
+                       tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);\r
+                       ++hits;\r
+               }\r
+       } else {\r
+               if ( ASKmanDemod("0 0 1", FALSE, FALSE) && test(DEMOD_ASK, &tests[hits].offset)) {\r
+                       tests[hits].modulation = DEMOD_ASK;\r
+                       tests[hits].inverted = FALSE;\r
+                       tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);\r
+                       ++hits;\r
+                       }\r
 \r
-  PrintAndLog("Writting block %d with data %08X", Block, Data);\r
+               if ( ASKmanDemod("0 1 1", FALSE, FALSE)  && test(DEMOD_ASK, &tests[hits].offset)) {\r
+                       tests[hits].modulation = DEMOD_ASK;\r
+                       tests[hits].inverted = TRUE;\r
+                       tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);\r
+                       ++hits;\r
+                       }\r
+               \r
+               if ( NRZrawDemod("0 0 1", FALSE)  && test(DEMOD_NRZ, &tests[hits].offset)) {\r
+                       tests[hits].modulation = DEMOD_NRZ;\r
+                       tests[hits].inverted = FALSE;\r
+                       tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);\r
+                       ++hits;\r
+               }\r
 \r
-  c.cmd = CMD_T55XX_WRITE_BLOCK;\r
-  c.d.asBytes[0] = 0x0; //Normal mode\r
-  c.arg[0] = Data;\r
-  c.arg[1] = Block;\r
-  c.arg[2] = 0;\r
-  SendCommand(&c);\r
-  return 0;\r
+               if ( NRZrawDemod("0 1 1", FALSE)  && test(DEMOD_NRZ, &tests[hits].offset)) {\r
+                       tests[hits].modulation = DEMOD_NRZ;\r
+                       tests[hits].inverted = TRUE;\r
+                       tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);\r
+                       ++hits;\r
+                       }\r
+               \r
+               if ( PSKDemod("0 0 1", FALSE) && test(DEMOD_PSK1, &tests[hits].offset)) {\r
+                       tests[hits].modulation = DEMOD_PSK1;\r
+                       tests[hits].inverted = FALSE;\r
+                       tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);\r
+                       ++hits;\r
+               }\r
+               \r
+               if ( PSKDemod("0 1 1", FALSE) && test(DEMOD_PSK1, &tests[hits].offset)) {\r
+                       tests[hits].modulation = DEMOD_PSK1;\r
+                       tests[hits].inverted = TRUE;\r
+                       tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);\r
+                       ++hits;\r
+               }\r
+\r
+               // PSK2 - needs a call to psk1TOpsk2.\r
+               if ( PSKDemod("0 0 1", FALSE)) {\r
+                       psk1TOpsk2(DemodBuffer, DemodBufferLen);\r
+                       if (test(DEMOD_PSK2, &tests[hits].offset)){\r
+                               tests[hits].modulation = DEMOD_PSK2;\r
+                               tests[hits].inverted = FALSE;\r
+                               tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);\r
+                               ++hits;\r
+                       }\r
+               } // inverse waves does not affect this demod\r
+\r
+               // PSK3 - needs a call to psk1TOpsk2.\r
+               if ( PSKDemod("0 0 1", FALSE)) {\r
+                       psk1TOpsk2(DemodBuffer, DemodBufferLen);\r
+                       if (test(DEMOD_PSK3, &tests[hits].offset)){\r
+                               tests[hits].modulation = DEMOD_PSK3;\r
+                               tests[hits].inverted = FALSE;\r
+                               tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);\r
+                               ++hits;\r
+                       }\r
+               } // inverse waves does not affect this demod\r
+       \r
+               if ( ASKbiphaseDemod("0 0 0 1", FALSE) && test(DEMOD_BI, &tests[hits].offset) ) {\r
+                       tests[hits].modulation = DEMOD_BI;\r
+                       tests[hits].inverted = FALSE;\r
+                       tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);\r
+                       ++hits;\r
+               }\r
+               if ( ASKbiphaseDemod("0 0 1 1", FALSE) && test(DEMOD_BIa, &tests[hits].offset) ) {\r
+                       tests[hits].modulation = DEMOD_BIa;\r
+                       tests[hits].inverted = TRUE;\r
+                       tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);\r
+                       ++hits;\r
+               }\r
+       }               \r
+       if ( hits == 1) {\r
+               config.modulation = tests[0].modulation;\r
+               config.inverted = tests[0].inverted;\r
+               config.offset = tests[0].offset;\r
+               config.block0 = tests[0].block0;\r
+               printConfiguration( config );\r
+               return TRUE;\r
+       }\r
+       \r
+       if ( hits > 1) {\r
+               PrintAndLog("Found [%d] possible matches for modulation.",hits);\r
+               for(int i=0; i<hits; ++i){\r
+                       PrintAndLog("--[%d]---------------", i+1);\r
+                       printConfiguration( tests[i] );\r
+               }\r
+       }\r
+       return FALSE;\r
+}\r
+\r
+bool testModulation(uint8_t mode, uint8_t modread){\r
+       switch( mode ){\r
+               case DEMOD_FSK:\r
+                       if (modread > 3 && modread < 8) return TRUE;\r
+                       break;\r
+               case DEMOD_ASK:\r
+                       if (modread == DEMOD_ASK) return TRUE;\r
+                       break;\r
+               case DEMOD_PSK1:\r
+                       if (modread == DEMOD_PSK1) return TRUE;\r
+                       break;\r
+               case DEMOD_PSK2:\r
+                       if (modread == DEMOD_PSK2) return TRUE;\r
+                       break;\r
+               case DEMOD_PSK3:\r
+                       if (modread == DEMOD_PSK3) return TRUE;\r
+                       break;\r
+               case DEMOD_NRZ:\r
+                       if (modread == DEMOD_NRZ) return TRUE;\r
+                       break;\r
+               case DEMOD_BI:\r
+                       if (modread == DEMOD_BI) return TRUE;\r
+                       break;\r
+               case DEMOD_BIa:\r
+                       if (modread == DEMOD_BIa) return TRUE;\r
+                       break;          \r
+               default:\r
+                       return FALSE;\r
+       }\r
+       return FALSE;\r
+}\r
+\r
+bool testBitRate(uint8_t readRate, uint8_t mod){\r
+       uint8_t expected[8] = {8, 16, 32, 40, 50, 64, 100, 128};\r
+       uint8_t detRate = 0;\r
+       switch( mod ){\r
+               case DEMOD_FSK:\r
+                       detRate = GetFskClock("",FALSE, FALSE); \r
+                       if (expected[readRate] == detRate) {\r
+                               config.bitrate = readRate;\r
+                               return TRUE;\r
+                       }\r
+                       break;\r
+               case DEMOD_FSK1:\r
+                       detRate = GetFskClock("",FALSE, FALSE); \r
+                       if (expected[readRate] == detRate) {\r
+                               config.bitrate = readRate;\r
+                               return TRUE;\r
+                       }\r
+                       break;\r
+               case DEMOD_FSK1a:\r
+                       detRate = GetFskClock("",FALSE, FALSE); \r
+                       if (expected[readRate] == detRate) {\r
+                               config.bitrate = readRate;\r
+                               return TRUE;\r
+                       }\r
+                       break;\r
+               case DEMOD_FSK2:\r
+                       detRate = GetFskClock("",FALSE, FALSE); \r
+                       if (expected[readRate] == detRate) {\r
+                               config.bitrate = readRate;\r
+                               return TRUE;\r
+                       }\r
+                       break;\r
+               case DEMOD_FSK2a:\r
+                       detRate = GetFskClock("",FALSE, FALSE); \r
+                       if (expected[readRate] == detRate) {\r
+                               config.bitrate = readRate;\r
+                               return TRUE;\r
+                       }\r
+                       break;\r
+               case DEMOD_ASK:\r
+                       detRate = GetAskClock("",FALSE, FALSE); \r
+                       if (expected[readRate] == detRate) {\r
+                               config.bitrate = readRate;\r
+                               return TRUE;\r
+                       }\r
+                       break;\r
+               case DEMOD_PSK1:\r
+                       detRate = GetPskClock("",FALSE, FALSE); \r
+                       if (expected[readRate] == detRate) {\r
+                               config.bitrate = readRate;\r
+                               return TRUE;\r
+                       }\r
+                       break;\r
+               case DEMOD_PSK2:\r
+                       detRate = GetPskClock("",FALSE, FALSE); \r
+                       if (expected[readRate] == detRate) {\r
+                               config.bitrate = readRate;\r
+                               return TRUE;\r
+                       }\r
+                       break;\r
+               case DEMOD_PSK3:\r
+                       detRate = GetPskClock("",FALSE, FALSE); \r
+                       if (expected[readRate] == detRate) {\r
+                               config.bitrate = readRate;\r
+                               return TRUE;\r
+                       }\r
+                       break;\r
+               case DEMOD_NRZ:\r
+                       detRate = GetNrzClock("",FALSE, FALSE); \r
+                       if (expected[readRate] == detRate) {\r
+                               config.bitrate = readRate;\r
+                               return TRUE;\r
+                       }\r
+                       break;\r
+               case DEMOD_BI:\r
+                       detRate = GetAskClock("",FALSE, FALSE); \r
+                       if (expected[readRate] == detRate) {\r
+                               config.bitrate = readRate;\r
+                               return TRUE;\r
+                       }\r
+                       break;\r
+               default:\r
+                       return FALSE;\r
+       }\r
+       return FALSE;\r
+}\r
+\r
+bool test(uint8_t mode, uint8_t *offset){\r
+\r
+       if ( !DemodBufferLen) return FALSE;\r
+       uint8_t si = 0;\r
+       for (uint8_t idx = 0; idx < 64; idx++){\r
+               si = idx;\r
+               if ( PackBits(si, 32, DemodBuffer) == 0x00 ) continue;\r
+\r
+               uint8_t safer    = PackBits(si, 4, DemodBuffer); si += 4;           //master key\r
+               uint8_t resv     = PackBits(si, 4, DemodBuffer); si += 4;     //was 7 & +=7+3 //should be only 4 bits if extended mode\r
+               // 2nibble must be zeroed.\r
+               // moved test to here, since this gets most faults first.\r
+               if ( resv > 0x00) continue;\r
+\r
+               uint8_t xtRate   = PackBits(si, 3, DemodBuffer); si += 3;   //new\r
+               uint8_t bitRate  = PackBits(si, 3, DemodBuffer); si += 3;   //new  could check bit rate\r
+               uint8_t extend   = PackBits(si, 1, DemodBuffer); si += 1;     //bit 15 extended mode\r
+               uint8_t modread  = PackBits(si, 5, DemodBuffer); si += 5+2+1; //new\r
+               //uint8_t pskcr   = PackBits(si, 2, DemodBuffer); si += 2+1;  //new  could check psk cr\r
+               uint8_t nml01    = PackBits(si, 1, DemodBuffer); si += 1+5;   //bit 24 , 30, 31 could be tested for 0 if not extended mode\r
+               uint8_t nml02    = PackBits(si, 2, DemodBuffer); si += 2;\r
+               \r
+               //if extended mode\r
+               bool extMode =( (safer == 0x6 || safer == 0x9) && extend) ? TRUE : FALSE;\r
+\r
+               if (!extMode){\r
+                       if (nml01 || nml02 || xtRate) continue;\r
+               }\r
+               //test modulation\r
+               if (!testModulation(mode, modread)) continue;\r
+\r
+               *offset = idx;\r
+               if (!testBitRate(bitRate, mode)) continue;\r
+               return TRUE;\r
+       }\r
+       return FALSE;\r
 }\r
 \r
-int CmdWriteBlkPWD(const char *Cmd)\r
+void printT55xxBlock(const char *demodStr){\r
+       \r
+       uint8_t i = config.offset;\r
+       uint8_t endpos = 32 + i;\r
+       uint32_t blockData = 0;\r
+       uint8_t bits[64] = {0x00};\r
+\r
+       if ( !DemodBufferLen) return;\r
+\r
+       if ( endpos > DemodBufferLen){\r
+               PrintAndLog("The configured offset %d is too big. Possible offset: %d)", i, DemodBufferLen-32);\r
+               return;\r
+       }\r
+\r
+       for (; i < endpos; ++i)\r
+               bits[i - config.offset]=DemodBuffer[i];\r
+\r
+       blockData = PackBits(0, 32, bits);\r
+       PrintAndLog("0x%08X  %s [%s]", blockData, sprint_bin(bits,32), demodStr);\r
+}\r
+\r
+int special(const char *Cmd) {\r
+       uint32_t blockData = 0;\r
+       uint8_t bits[32] = {0x00};\r
+\r
+       PrintAndLog("[OFFSET] [DATA] [BINARY]");\r
+       PrintAndLog("----------------------------------------------------");\r
+       int i,j = 0;\r
+       for (; j < 64; ++j){\r
+               \r
+               for (i = 0; i < 32; ++i)\r
+                       bits[i]=DemodBuffer[j+i];\r
+       \r
+               blockData = PackBits(0, 32, bits);\r
+               \r
+               PrintAndLog("[%02d] 0x%08X  %s",j , blockData, sprint_bin(bits,32));    \r
+       }\r
+       return 0;\r
+}\r
+\r
+void printConfiguration( t55xx_conf_block_t b){\r
+       PrintAndLog("Modulation : %s", GetSelectedModulationStr(b.modulation) );\r
+       PrintAndLog("Bit Rate   : %s", GetBitRateStr(b.bitrate) );\r
+       PrintAndLog("Inverted   : %s", (b.inverted) ? "Yes" : "No" );\r
+       PrintAndLog("Offset     : %d", b.offset);\r
+       PrintAndLog("Block0     : 0x%08X", b.block0);\r
+       PrintAndLog("");\r
+}\r
+\r
+int CmdT55xxWriteBlock(const char *Cmd)\r
 {\r
-  int Block = 8; //default to invalid block\r
-  int Data = 0xFFFFFFFF; //default to blank Block \r
-  int Password = 0xFFFFFFFF; //default to blank Block 7\r
-  UsbCommand c;\r
-\r
-  sscanf(Cmd, "%x %d %x", &Data, &Block, &Password);\r
-\r
-  if (Block > 7) {\r
-       PrintAndLog("Block must be between 0 and 7");\r
-       return 1;\r
-  }    \r
-\r
-  PrintAndLog("Writting block %d with data %08X and password %08X", Block, Data, Password);\r
-\r
-  c.cmd = CMD_T55XX_WRITE_BLOCK;\r
-  c.d.asBytes[0] = 0x1; //Password mode\r
-  c.arg[0] = Data;\r
-  c.arg[1] = Block;\r
-  c.arg[2] = Password;\r
-  SendCommand(&c);\r
-  return 0;\r
+       int block = 8; //default to invalid block\r
+       int data = 0xFFFFFFFF; //default to blank Block \r
+       int password = 0xFFFFFFFF; //default to blank Block 7\r
+       \r
+       char cmdp = param_getchar(Cmd, 0);\r
+       if (cmdp == 'h' || cmdp == 'H') {\r
+               usage_t55xx_write();\r
+               return 0;\r
+       }\r
+  \r
+       int res = sscanf(Cmd, "%d %x %x",&block, &data, &password);\r
+       \r
+       if ( res < 2 || res > 3) {\r
+               usage_t55xx_write();\r
+               return 1;\r
+       }\r
+\r
+       if (block > 7) {\r
+               PrintAndLog("Block number must be between 0 and 7");\r
+               return 1;\r
+       }\r
+       \r
+       UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {data, block, 0}};\r
+       c.d.asBytes[0] = 0x0; \r
+\r
+       PrintAndLog("Writing to block: %d  data  : 0x%08X", block, data);\r
+\r
+       //Password mode\r
+       if (res == 3) {\r
+               c.arg[2] = password;\r
+               c.d.asBytes[0] = 0x1; \r
+               PrintAndLog("pwd   : 0x%08X", password);\r
+       }\r
+       SendCommand(&c);\r
+       return 0;\r
 }\r
 \r
-int CmdReadTrace(const char *Cmd)\r
+int CmdT55xxReadTrace(const char *Cmd)\r
 {\r
+       char cmdp = param_getchar(Cmd, 0);\r
+       \r
+       if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') \r
+               return usage_t55xx_trace();\r
+\r
+       if (strlen(Cmd)==0)\r
+               AquireData( TRACE_BLOCK );\r
+       \r
+       if (!DecodeT55xxBlock()) return 1;\r
 \r
-  PrintAndLog("Reading traceability data");\r
+       if ( !DemodBufferLen) return 1;\r
+       \r
+       RepaintGraphWindow();\r
+       uint8_t repeat = 0;\r
+       if (config.offset > 5) \r
+               repeat = 32;\r
+       uint8_t si = config.offset+repeat;\r
+       uint32_t bl0     = PackBits(si, 32, DemodBuffer);\r
+       uint32_t bl1     = PackBits(si+32, 32, DemodBuffer);\r
+       \r
+       uint32_t acl     = PackBits(si,  8, DemodBuffer); si += 8;\r
+       uint32_t mfc     = PackBits(si, 8, DemodBuffer); si += 8;\r
+       uint32_t cid     = PackBits(si, 5, DemodBuffer); si += 5;\r
+       uint32_t icr     = PackBits(si, 3, DemodBuffer); si += 3;\r
+       uint32_t year    = PackBits(si, 4, DemodBuffer); si += 4;\r
+       uint32_t quarter = PackBits(si, 2, DemodBuffer); si += 2;\r
+       uint32_t lotid    = PackBits(si, 12, DemodBuffer); si += 12;\r
+       uint32_t wafer   = PackBits(si, 5, DemodBuffer); si += 5;\r
+       uint32_t dw      = PackBits(si, 15, DemodBuffer); \r
+       \r
+       year += 2000;\r
+       \r
+       PrintAndLog("");\r
+       PrintAndLog("-- T55xx Trace Information ----------------------------------");\r
+       PrintAndLog("-------------------------------------------------------------");\r
+       PrintAndLog(" ACL Allocation class (ISO/IEC 15963-1)  : 0x%02X (%d)", acl, acl);\r
+       PrintAndLog(" MFC Manufacturer ID (ISO/IEC 7816-6)    : 0x%02X (%d) - %s", mfc, mfc, getTagInfo(mfc));\r
+       PrintAndLog(" CID                                     : 0x%02X (%d) - %s", cid, cid, GetModelStrFromCID(cid));\r
+       PrintAndLog(" ICR IC Revision                         : %d",icr );\r
+       PrintAndLog(" Manufactured");\r
+       PrintAndLog("     Year/Quarter : %d/%d",year, quarter );\r
+       PrintAndLog("     Lot ID       : %d", lotid );\r
+       PrintAndLog("     Wafer number : %d", wafer);\r
+       PrintAndLog("     Die Number   : %d", dw);\r
+       PrintAndLog("-------------------------------------------------------------");\r
+       PrintAndLog(" Raw Data - Page 1");\r
+       PrintAndLog("     Block 0  : 0x%08X  %s", bl0, sprint_bin(DemodBuffer+config.offset+repeat,32) );\r
+       PrintAndLog("     Block 1  : 0x%08X  %s", bl1, sprint_bin(DemodBuffer+config.offset+repeat+32,32) );\r
+       PrintAndLog("-------------------------------------------------------------");\r
 \r
-  UsbCommand c = {CMD_T55XX_READ_TRACE, {0, 0, 0}};\r
-  SendCommand(&c);\r
+       if ( acl != 0xE0 )\r
+               PrintAndLog("The modulation is most likely wrong since the ACL is not 0xE0. ");\r
+       /*\r
+       TRACE - BLOCK O\r
+               Bits    Definition                                                              HEX\r
+               1-8             ACL Allocation class (ISO/IEC 15963-1)  0xE0 \r
+               9-16    MFC Manufacturer ID (ISO/IEC 7816-6)    0x15 Atmel Corporation\r
+               17-21   CID                                                                             0x1 = Atmel ATA5577M1  0x2 = Atmel ATA5577M2 \r
+               22-24   ICR IC revision\r
+               25-28   YEAR (BCD encoded)                                              9 (= 2009)\r
+               29-30   QUARTER                                                                 1,2,3,4 \r
+               31-32   LOT ID\r
+       \r
+       TRACE - BLOCK 1\r
+               1-12    LOT ID  \r
+               13-17   Wafer number\r
+               18-32   DW,  die number sequential\r
+       */\r
+       \r
   return 0;\r
 }\r
 \r
+int CmdT55xxInfo(const char *Cmd){\r
+       /*\r
+               Page 0 Block 0 Configuration data.\r
+               Normal mode\r
+               Extended mode\r
+       */\r
+       char cmdp = param_getchar(Cmd, 0);\r
+\r
+       if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H')\r
+               return usage_t55xx_info();\r
+       \r
+       if (strlen(Cmd)==0)\r
+               AquireData( CONFIGURATION_BLOCK );\r
+       \r
+       if (!DecodeT55xxBlock()) return 1;\r
+\r
+       if ( !DemodBufferLen) return 1;\r
+\r
+       uint8_t si = config.offset;\r
+       uint32_t bl0      = PackBits(si, 32, DemodBuffer);\r
+       \r
+       uint32_t safer    = PackBits(si, 4, DemodBuffer); si += 4;      \r
+       uint32_t resv     = PackBits(si, 7, DemodBuffer); si += 7;\r
+       uint32_t dbr      = PackBits(si, 3, DemodBuffer); si += 3;\r
+       uint32_t extend   = PackBits(si, 1, DemodBuffer); si += 1;\r
+       uint32_t datamod  = PackBits(si, 5, DemodBuffer); si += 5;\r
+       uint32_t pskcf    = PackBits(si, 2, DemodBuffer); si += 2;\r
+       uint32_t aor      = PackBits(si, 1, DemodBuffer); si += 1;      \r
+       uint32_t otp      = PackBits(si, 1, DemodBuffer); si += 1;      \r
+       uint32_t maxblk   = PackBits(si, 3, DemodBuffer); si += 3;\r
+       uint32_t pwd      = PackBits(si, 1, DemodBuffer); si += 1;      \r
+       uint32_t sst      = PackBits(si, 1, DemodBuffer); si += 1;      \r
+       uint32_t fw       = PackBits(si, 1, DemodBuffer); si += 1;\r
+       uint32_t inv      = PackBits(si, 1, DemodBuffer); si += 1;      \r
+       uint32_t por      = PackBits(si, 1, DemodBuffer); si += 1;\r
+               \r
+       PrintAndLog("");\r
+       PrintAndLog("-- T55xx Configuration & Tag Information --------------------");\r
+       PrintAndLog("-------------------------------------------------------------");\r
+       PrintAndLog(" Safer key                 : %s", GetSaferStr(safer));\r
+       PrintAndLog(" reserved                  : %d", resv);\r
+       PrintAndLog(" Data bit rate             : %s", GetBitRateStr(dbr));\r
+       PrintAndLog(" eXtended mode             : %s", (extend) ? "Yes - Warning":"No");\r
+       PrintAndLog(" Modulation                : %s", GetModulationStr(datamod));\r
+       PrintAndLog(" PSK clock frequency       : %d", pskcf);\r
+       PrintAndLog(" AOR - Answer on Request   : %s", (aor) ? "Yes":"No");\r
+       PrintAndLog(" OTP - One Time Pad        : %s", (otp) ? "Yes - Warning":"No" );\r
+       PrintAndLog(" Max block                 : %d", maxblk);\r
+       PrintAndLog(" Password mode             : %s", (pwd) ? "Yes":"No");\r
+       PrintAndLog(" Sequence Start Terminator : %s", (sst) ? "Yes":"No");\r
+       PrintAndLog(" Fast Write                : %s", (fw)  ? "Yes":"No");\r
+       PrintAndLog(" Inverse data              : %s", (inv) ? "Yes":"No");\r
+       PrintAndLog(" POR-Delay                 : %s", (por) ? "Yes":"No");\r
+       PrintAndLog("-------------------------------------------------------------");\r
+       PrintAndLog(" Raw Data - Page 0");\r
+       PrintAndLog("     Block 0  : 0x%08X  %s", bl0, sprint_bin(DemodBuffer+config.offset,32) );\r
+       PrintAndLog("-------------------------------------------------------------");\r
+       \r
+       return 0;\r
+}\r
+\r
+int CmdT55xxDump(const char *Cmd){\r
+\r
+       char s[20] = {0x00};\r
+       uint8_t pwd[4] = {0x00};\r
+\r
+       char cmdp = param_getchar(Cmd, 0);\r
+       if ( cmdp == 'h' || cmdp == 'H') {\r
+               usage_t55xx_dump();\r
+               return 0;\r
+       }\r
+\r
+       bool hasPwd = ( strlen(Cmd) > 0);       \r
+       if ( hasPwd ){\r
+               if (param_gethex(Cmd, 0, pwd, 8)) {\r
+                       PrintAndLog("password must include 8 HEX symbols");\r
+                       return 1;\r
+               }\r
+       }\r
+       \r
+       for ( int i = 0; i <8; ++i){\r
+               memset(s,0,sizeof(s));\r
+               if ( hasPwd ) {\r
+                       sprintf(s,"%d %02x%02x%02x%02x", i, pwd[0],pwd[1],pwd[2],pwd[3]);\r
+               } else {\r
+                       sprintf(s,"%d", i);\r
+               }\r
+               CmdT55xxReadBlock(s);\r
+       }\r
+       return 0;\r
+}\r
+\r
+int AquireData( uint8_t block ){\r
+\r
+       UsbCommand c;\r
+       \r
+       if ( block == CONFIGURATION_BLOCK ) \r
+               c.cmd = CMD_T55XX_READ_BLOCK;\r
+       else if (block == TRACE_BLOCK )\r
+               c.cmd = CMD_T55XX_READ_TRACE;\r
+               \r
+       c.arg[0] = 0x00;\r
+       c.arg[1] = 0x00;\r
+       c.arg[2] = 0x00;\r
+       c.d.asBytes[0] = 0x0; \r
+\r
+       //Password mode\r
+       // if ( res == 2 ) {\r
+               // c.arg[2] = password;\r
+               // c.d.asBytes[0] = 0x1; \r
+       // }\r
+\r
+       SendCommand(&c);\r
+       if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) {\r
+               PrintAndLog("command execution time out");\r
+               return 1;\r
+       }\r
+\r
+       uint8_t got[12000];\r
+       GetFromBigBuf(got,sizeof(got),0);\r
+       WaitForResponse(CMD_ACK,NULL);\r
+       setGraphBuf(got, 12000);\r
+       return 0;\r
+}\r
+\r
+char * GetBitRateStr(uint32_t id){\r
+       static char buf[40];\r
+       char *retStr = buf;\r
+               switch (id){\r
+               case 0: \r
+                       sprintf(retStr,"%d - RF/8",id);\r
+                       break;\r
+               case 1:\r
+                       sprintf(retStr,"%d - RF/16",id);\r
+                       break;\r
+               case 2:         \r
+                       sprintf(retStr,"%d - RF/32",id);\r
+                       break;\r
+               case 3:\r
+                       sprintf(retStr,"%d - RF/40",id);\r
+                       break;\r
+               case 4:\r
+                       sprintf(retStr,"%d - RF/50",id);\r
+                       break;\r
+               case 5:\r
+                       sprintf(retStr,"%d - RF/64",id);\r
+                       break;\r
+               case 6:\r
+                       sprintf(retStr,"%d - RF/100",id);\r
+                       break;\r
+               case 7:\r
+                       sprintf(retStr,"%d - RF/128",id);\r
+                       break;\r
+               default:\r
+                       sprintf(retStr,"%d - (Unknown)",id);\r
+                       break;\r
+               }\r
+\r
+       return buf;\r
+}\r
+\r
+char * GetSaferStr(uint32_t id){\r
+       static char buf[40];\r
+       char *retStr = buf;\r
+       \r
+       sprintf(retStr,"%d",id);\r
+       if (id == 6) {\r
+               sprintf(retStr,"%d - passwd",id);\r
+       }\r
+       if (id == 9 ){\r
+               sprintf(retStr,"%d - testmode",id);\r
+       }\r
+       \r
+       return buf;\r
+}\r
+char * GetModulationStr( uint32_t id){\r
+       static char buf[40];\r
+       char *retStr = buf;\r
+       \r
+       switch (id){\r
+               case 0: \r
+                       sprintf(retStr,"%d - DIRECT (ASK/NRZ)",id);\r
+                       break;\r
+               case 1:\r
+                       sprintf(retStr,"%d - PSK 1 phase change when input changes",id);\r
+                       break;\r
+               case 2:         \r
+                       sprintf(retStr,"%d - PSK 2 phase change on bitclk if input high",id);\r
+                       break;\r
+               case 3:\r
+                       sprintf(retStr,"%d - PSK 3 phase change on rising edge of input",id);\r
+                       break;\r
+               case 4:\r
+                       sprintf(retStr,"%d - FSK 1 RF/8  RF/5",id);\r
+                       break;\r
+               case 5:\r
+                       sprintf(retStr,"%d - FSK 2 RF/8  RF/10",id);\r
+                       break;\r
+               case 6:\r
+                       sprintf(retStr,"%d - FSK 1a RF/5  RF/8",id);\r
+                       break;\r
+               case 7:\r
+                       sprintf(retStr,"%d - FSK 2a RF/10  RF/8",id);\r
+                       break;\r
+               case 8:\r
+                       sprintf(retStr,"%d - Manschester",id);\r
+                       break;\r
+               case 16:\r
+                       sprintf(retStr,"%d - Biphase",id);\r
+                       break;\r
+               case 0x18:\r
+                       sprintf(retStr,"%d - Biphase a - AKA Conditional Dephase Encoding(CDP)",id);\r
+                       break;\r
+               case 17:\r
+                       sprintf(retStr,"%d - Reserved",id);\r
+                       break;\r
+               default:\r
+                       sprintf(retStr,"0x%02X (Unknown)",id);\r
+                       break;\r
+               }\r
+       return buf;\r
+}\r
+\r
+char * GetModelStrFromCID(uint32_t cid){\r
+               \r
+       static char buf[10];\r
+       char *retStr = buf;\r
+       \r
+       if (cid == 1) sprintf(retStr,"ATA5577M1");\r
+       if (cid == 2) sprintf(retStr,"ATA5577M2");      \r
+       return buf;\r
+}\r
+\r
+char * GetSelectedModulationStr( uint8_t id){\r
+\r
+       static char buf[16];\r
+       char *retStr = buf;\r
+\r
+       switch (id){\r
+               case DEMOD_FSK:\r
+                       sprintf(retStr,"FSK");\r
+                       break;\r
+               case DEMOD_FSK1:\r
+                       sprintf(retStr,"FSK1");\r
+                       break;\r
+               case DEMOD_FSK1a:\r
+                       sprintf(retStr,"FSK1a");\r
+                       break;\r
+               case DEMOD_FSK2:\r
+                       sprintf(retStr,"FSK2");\r
+                       break;\r
+               case DEMOD_FSK2a:\r
+                       sprintf(retStr,"FSK2a");\r
+                       break;\r
+               case DEMOD_ASK:         \r
+                       sprintf(retStr,"ASK");\r
+                       break;\r
+               case DEMOD_NRZ:\r
+                       sprintf(retStr,"DIRECT/NRZ");\r
+                       break;\r
+               case DEMOD_PSK1:\r
+                       sprintf(retStr,"PSK1");\r
+                       break;\r
+               case DEMOD_PSK2:\r
+                       sprintf(retStr,"PSK2");\r
+                       break;\r
+               case DEMOD_PSK3:\r
+                       sprintf(retStr,"PSK3");\r
+                       break;\r
+               case DEMOD_BI:\r
+                       sprintf(retStr,"BIPHASE");\r
+                       break;\r
+               case DEMOD_BIa:\r
+                       sprintf(retStr,"BIPHASEa - (CDP)");\r
+                       break;\r
+               default:\r
+                       sprintf(retStr,"(Unknown)");\r
+                       break;\r
+               }\r
+       return buf;\r
+}\r
+\r
+uint32_t PackBits(uint8_t start, uint8_t len, uint8_t* bits){\r
+       \r
+       int i = start;\r
+       int j = len-1;\r
+\r
+       if (len > 32) return 0;\r
+\r
+       uint32_t tmp = 0;\r
+       for (; j >= 0; --j, ++i)\r
+               tmp     |= bits[i] << j;\r
+\r
+       return tmp;\r
+}\r
+\r
 static command_t CommandTable[] =\r
 {\r
-  {"help",          CmdHelp,        1, "This help"},\r
-  {"readblock",     CmdReadBlk,     1, "<Block> -- Read T55xx block data (page 0)"},\r
-  {"readblockPWD",  CmdReadBlkPWD,  1, "<Block> <Password> -- Read T55xx block data in password mode(page 0)"},\r
-  {"writeblock",    CmdWriteBlk,    1, "<Data> <Block> -- Write T55xx block data (page 0)"},\r
-  {"writeblockPWD", CmdWriteBlkPWD, 1, "<Data> <Block> <Password> -- Write T55xx block data in password mode(page 0)"},\r
-  {"readtrace",     CmdReadTrace,   1, "Read T55xx traceability data (page 1)"},\r
+  {"help",   CmdHelp,           1, "This help"},\r
+  {"config", CmdT55xxSetConfig, 1, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"},\r
+  {"detect", CmdT55xxDetect,    0, "[1] Try detecting the tag modulation from reading the configuration block."},\r
+  {"read",   CmdT55xxReadBlock, 0, "<block> [password] -- Read T55xx block data (page 0) [optional password]"},\r
+  {"write",  CmdT55xxWriteBlock,0, "<block> <data> [password] -- Write T55xx block data (page 0) [optional password]"},\r
+  {"trace",  CmdT55xxReadTrace, 0, "[1] Show T55xx traceability data (page 1/ blk 0-1)"},\r
+  {"info",   CmdT55xxInfo,      0, "[1] Show T55xx configuration data (page 0/ blk 0)"},\r
+  {"dump",   CmdT55xxDump,      0, "[password] Dump T55xx card block 0-7. [optional password]"},\r
+  {"special", special,          0, "Show block changes with 64 different offsets"},\r
   {NULL, NULL, 0, NULL}\r
 };\r
 \r
index 25503e8708f5c4fc0303e73824071c4451e564b5..a64b1edab6cb27bba05d33c38c83039d33929f60 100644 (file)
 #ifndef CMDLFT55XX_H__\r
 #define CMDLFT55XX_H__\r
 \r
+typedef struct {\r
+       enum {\r
+               DEMOD_NRZ  = 0x00,    \r
+               DEMOD_PSK1 = 0x01,\r
+               DEMOD_PSK2 = 0x02,\r
+               DEMOD_PSK3 = 0x03,\r
+               DEMOD_FSK1  = 0x04,     \r
+               DEMOD_FSK1a = 0x05,     \r
+               DEMOD_FSK2  = 0x06,     \r
+               DEMOD_FSK2a = 0x07, \r
+               DEMOD_FSK   = 0xF0, //generic FSK (auto detect FCs)    \r
+               DEMOD_ASK  = 0x08,\r
+               DEMOD_BI   = 0x10,\r
+               DEMOD_BIa  = 0x18,              \r
+       }  modulation;\r
+       bool inverted;\r
+       uint8_t offset;\r
+       uint32_t block0;\r
+       enum {\r
+               RF_8 = 0x00,\r
+               RF_16 = 0x01,\r
+               RF_32 = 0x02,\r
+               RF_40 = 0x03,\r
+               RF_50 = 0x04,\r
+               RF_64 = 0x05,\r
+               RF_100 = 0x06,\r
+               RF_128 = 0x07,\r
+       } bitrate;\r
+} t55xx_conf_block_t;\r
+\r
 int CmdLFT55XX(const char *Cmd);\r
+int CmdT55xxSetConfig(const char *Cmd);\r
+int CmdT55xxReadBlock(const char *Cmd);\r
+int CmdT55xxWriteBlock(const char *Cmd);\r
+int CmdT55xxReadTrace(const char *Cmd);\r
+int CmdT55xxInfo(const char *Cmd);\r
+int CmdT55xxDetect(const char *Cmd);\r
+\r
+char * GetBitRateStr(uint32_t id);\r
+char * GetSaferStr(uint32_t id);\r
+char * GetModulationStr( uint32_t id);\r
+char * GetModelStrFromCID(uint32_t cid);\r
+char * GetSelectedModulationStr( uint8_t id);\r
+uint32_t PackBits(uint8_t start, uint8_t len, uint8_t* bitstream);\r
+void printT55xxBlock(const char *demodStr);\r
+void printConfiguration( t55xx_conf_block_t b);\r
 \r
-int CmdReadBlk(const char *Cmd);\r
-int CmdReadBlkPWD(const char *Cmd);\r
-int CmdWriteBlk(const char *Cmd);\r
-int CmdWriteBLkPWD(const char *Cmd);\r
-int CmdReadTrace(const char *Cmd);\r
+bool DecodeT55xxBlock();\r
+bool tryDetectModulation();\r
+bool test(uint8_t mode, uint8_t *offset);\r
+int special(const char *Cmd);\r
+int AquireData( uint8_t block );\r
 \r
 #endif\r
diff --git a/client/scripts/test_t55x7_ask.lua b/client/scripts/test_t55x7_ask.lua
new file mode 100644 (file)
index 0000000..569d426
--- /dev/null
@@ -0,0 +1,139 @@
+local cmds = require('commands')
+local getopt = require('getopt')
+local bin = require('bin')
+local utils = require('utils')
+
+local format=string.format
+local floor=math.floor
+
+example =[[
+       1. script run test_t55x7_ask
+]]
+author = "Iceman"
+usage = "script run test_t55x7_ask"
+desc =[[
+This script will program a T55x7 TAG with the configuration: block 0x00 data 0x000100
+The outlined procedure is as following:
+
+--ASK 
+       00 00 80 40
+--           max 2
+--        manchester
+--     bit rate
+"lf t55xx write 0 00008040"
+"lf t55xx detect"
+"lf t55xx info"
+
+Loop:
+       change the configuretion block 0 with:
+    -xx 00 xxxx = RF/8 
+    -xx 04 xxxx = RF/16
+       -xx 08 xxxx = RF/32
+       -xx 0C xxxx = RF/40
+       -xx 10 xxxx = RF/50
+       -xx 14 xxxx = RF/64
+       -xx 18 xxxx = RF/100
+       -xx 1C xxxx = RF/128
+
+
+testsuit for the ASK/MANCHESTER demod
+
+Arguments:
+       -h             : this help
+]]
+
+local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
+local DEBUG = true -- the debug flag
+
+--BLOCK 0 = 00008040 ASK / MAN
+local config1 = '00'
+local config2 = '8040'
+
+local procedurecmds = {
+       [1] = '%s%02X%s',
+       [2] = 'lf t55xx detect',
+       [3] = 'lf t55xx info',
+}
+--- 
+-- A debug printout-function
+function dbg(args)
+       if not DEBUG then
+               return
+       end
+       
+    if type(args) == "table" then
+               local i = 1
+               while args[i] do
+                       dbg(args[i])
+                       i = i+1
+               end
+       else
+               print("###", args)
+       end     
+end    
+--- 
+-- This is only meant to be used when errors occur
+function oops(err)
+       print("ERROR: ",err)
+end
+--- 
+-- Usage help
+function help()
+       print(desc)
+       print("Example usage")
+       print(example)
+end
+--
+-- Exit message
+function ExitMsg(msg)
+       print( string.rep('--',20) )
+       print( string.rep('--',20) )
+       print(msg)
+       print()
+end
+
+function test()
+       local y
+       for y = 0x0, 0x1d, 0x4 do
+               for _ = 1, #procedurecmds do
+                       local pcmd = procedurecmds[_]
+                       
+                       if #pcmd == 0 then  
+                       
+                       elseif _ == 1 then
+
+                               local config = pcmd:format(config1, y, config2)
+                               dbg(('lf t55xx write 0 %s'):format(config))                     
+                               config = tonumber(config,16) 
+                               
+                               local writecmd = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK, arg1 = config}                   
+                               local err = core.SendCommand(writecmd:getBytes())
+                               if err then return oops(err) end
+                               local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
+
+                       else
+                               dbg(pcmd)
+                               core.console( pcmd )
+                       end                     
+               end
+               core.clearCommandBuffer()       
+       end
+       print( string.rep('--',20) )
+end
+
+local function main(args)
+
+       print( string.rep('--',20) )
+       print( string.rep('--',20) )
+
+       -- Arguments for the script
+       for o, arg in getopt.getopt(args, 'h') do
+               if o == "h" then return help() end
+       end
+
+       core.clearCommandBuffer()
+       test()
+       print( string.rep('--',20) )
+end
+main(args)
\ No newline at end of file
diff --git a/client/scripts/test_t55x7_bi.lua b/client/scripts/test_t55x7_bi.lua
new file mode 100644 (file)
index 0000000..a1793ba
--- /dev/null
@@ -0,0 +1,133 @@
+local cmds = require('commands')
+local getopt = require('getopt')
+local bin = require('bin')
+local utils = require('utils')
+
+example =[[
+       1. script run test_t55x7_bi
+]]
+author = "Iceman"
+usage = "script run test_t55x7_bi"
+desc =[[
+This script will program a T55x7 TAG with the configuration: block 0x00 data 0x00010040
+The outlined procedure is as following:
+
+--BIPHASE 00010040
+--
+
+"lf t55xx write 0 00010040"
+"lf t55xx detect"
+"lf t55xx info"
+
+Loop:
+       change the configuretion block 0 with:
+    -xx01xxxx = RF/8 
+    -xx05xxxx = RF/16
+       -xx09xxxx = RF/32
+       -xx0Dxxxx = RF/40
+       -xx11xxxx = RF/50
+       -xx15xxxx = RF/64
+       -xx19xxxx = RF/100
+       -xx1Dxxxx = RF/128
+
+
+testsuit for the BIPHASE demod
+
+Arguments:
+       -h             : this help
+]]
+
+local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
+local DEBUG = true -- the debug flag
+
+--BLOCK 0 = 00010040 BIPHASE
+local config1 = '00'
+local config2 = '0040'
+
+local procedurecmds = {
+       [1] = '%s%02X%s',
+       [2] = 'lf t55xx detect',
+       [3] = 'lf t55xx info',
+}
+--- 
+-- A debug printout-function
+function dbg(args)
+       if not DEBUG then
+               return
+       end
+       
+    if type(args) == "table" then
+               local i = 1
+               while args[i] do
+                       dbg(args[i])
+                       i = i+1
+               end
+       else
+               print("###", args)
+       end     
+end    
+--- 
+-- This is only meant to be used when errors occur
+function oops(err)
+       print("ERROR: ",err)
+end
+--- 
+-- Usage help
+function help()
+       print(desc)
+       print("Example usage")
+       print(example)
+end
+--
+-- Exit message
+function ExitMsg(msg)
+       print( string.rep('--',20) )
+       print( string.rep('--',20) )
+       print(msg)
+       print()
+end
+
+function test()
+       local y
+       for y = 1, 0x1D, 4 do
+               for _ = 1, #procedurecmds do
+                       local pcmd = procedurecmds[_]
+                       
+                       if #pcmd == 0 then  
+                       
+                       elseif _ == 1 then
+
+                               local config = pcmd:format(config1, y, config2)
+                               dbg(('lf t55xx wr 0 %s'):format(config))
+                               
+                               config = tonumber(config,16) 
+                               local writecmd = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK, arg1 = config}
+                               local err = core.SendCommand(writecmd:getBytes())
+                               if err then return oops(err) end
+                               local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
+                       else
+                               dbg(pcmd)
+                               core.console( pcmd )
+                       end
+               end
+               core.clearCommandBuffer()       
+       end
+       print( string.rep('--',20) )
+
+end
+
+local function main(args)
+
+       print( string.rep('--',20) )
+       print( string.rep('--',20) )
+
+       -- Arguments for the script
+       for o, arg in getopt.getopt(args, 'h') do
+               if o == "h" then return help() end
+       end
+
+       core.clearCommandBuffer()
+       test()
+       print( string.rep('--',20) )
+end
+main(args)
diff --git a/client/scripts/test_t55x7_fsk.lua b/client/scripts/test_t55x7_fsk.lua
new file mode 100644 (file)
index 0000000..f42dd14
--- /dev/null
@@ -0,0 +1,139 @@
+local cmds = require('commands')
+local getopt = require('getopt')
+local bin = require('bin')
+local utils = require('utils')
+
+example =[[
+       1. script run test_t55x7_fsk
+]]
+author = "Iceman"
+usage = "script run test_t55x7_fsk"
+desc =[[
+This script will program a T55x7 TAG with the configuration: block 0x00 data 0x000100
+The outlined procedure is as following:
+
+--ASK 
+       00 00 80 40
+--           max 2 blocks
+--        FSK1
+--     bit rate
+"lf t55xx write 0 00007040"
+"lf t55xx detect"
+"lf t55xx info"
+
+Loop:
+       change the configuretion block 0 with:
+    -xx 00 xxxx = RF/8 
+    -xx 04 xxxx = RF/16
+       -xx 08 xxxx = RF/32
+       -xx 0C xxxx = RF/40
+       -xx 10 xxxx = RF/50
+       -xx 14 xxxx = RF/64
+       -xx 18 xxxx = RF/100
+       -xx 1C xxxx = RF/128
+
+
+testsuit for the ASK/MANCHESTER demod
+
+Arguments:
+       -h             : this help
+]]
+
+local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
+local DEBUG = true -- the debug flag
+
+--BLOCK 0 = 00008040 FSK
+local config1 = '00'
+local config2 = '040'
+
+local procedurecmds = {
+       [1] = '%s%02X%X%s',
+       [2] = 'lf t55xx detect',
+       [3] = 'lf t55xx info',
+}
+--- 
+-- A debug printout-function
+function dbg(args)
+       if not DEBUG then
+               return
+       end
+       
+    if type(args) == "table" then
+               local i = 1
+               while args[i] do
+                       dbg(args[i])
+                       i = i+1
+               end
+       else
+               print("###", args)
+       end     
+end    
+--- 
+-- This is only meant to be used when errors occur
+function oops(err)
+       print("ERROR: ",err)
+end
+--- 
+-- Usage help
+function help()
+       print(desc)
+       print("Example usage")
+       print(example)
+end
+--
+-- Exit message
+function ExitMsg(msg)
+       print( string.rep('--',20) )
+       print( string.rep('--',20) )
+       print(msg)
+       print()
+end
+
+function test(modulation)
+       local y
+       for y = 0x0, 0x1d, 0x4 do
+               for _ = 1, #procedurecmds do
+                       local pcmd = procedurecmds[_]
+                       
+                       if #pcmd == 0 then  
+                       
+                       elseif _ == 1 then
+
+                               local config = pcmd:format(config1, y, modulation, config2)
+                               dbg(('lf t55xx write 0 %s'):format(config))
+                               
+                               config = tonumber(config,16) 
+                               local writecmd = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK, arg1 = config}
+                               local err = core.SendCommand(writecmd:getBytes())
+                               if err then return oops(err) end
+                               local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
+
+                       else
+                               dbg(pcmd)
+                               core.console( pcmd )
+                       end                     
+               end
+               core.clearCommandBuffer()       
+       end
+       print( string.rep('--',20) )
+end
+
+local function main(args)
+
+       print( string.rep('--',20) )
+       print( string.rep('--',20) )
+
+       -- Arguments for the script
+       for o, arg in getopt.getopt(args, 'h') do
+               if o == "h" then return help() end
+       end
+
+       core.clearCommandBuffer()
+       test(4)
+       test(5)
+       test(6)
+       test(7)
+       print( string.rep('--',20) )
+end
+main(args)
\ No newline at end of file
index 1b9640944b90aa7c9fab78b15513a196078edb04..cbd78e873599270194f1b407e5c6cbf525fd5966 100644 (file)
@@ -2,15 +2,14 @@ local cmds = require('commands')
 local getopt = require('getopt')
 local bin = require('bin')
 local utils = require('utils')
-local dumplib = require('html_dumplib')
 
 example =[[
-       1. script run tracetest
-       2. script run tracetest -o 
+       1. script run test_t55x7_psk
+       2. script run test_t55x7_psk -o 
 
 ]]
 author = "Iceman"
-usage = "script run test_t55x7_psk -o <filename>"
+usage = "script run test_t55x7_psk"
 desc =[[
 This script will program a T55x7 TAG with the configuration: block 0x00 data 0x00088040
 The outlined procedure is as following:
@@ -39,26 +38,35 @@ In all 12 individual test for the PSK demod
 
 Arguments:
        -h             : this help
-       -o             : logfile name
 ]]
 
 local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
 local DEBUG = true -- the debug flag
 
---BLOCK 0 = 00088040
-local config1 = '0008'
-local config2 = '40'
        
+-- local procedurecmds = {
+       -- [1] = '%s%s%s%s',
+       -- [2] = 'lf read',
+       -- --[3] = '',
+       -- [3] = 'data samples',
+       -- [4] = 'data pskdetectclock',
+       -- [5] = 'data psknrzrawdemod',
+       -- [6] = 'data pskindalademod',
+-- }
+
+-- --BLOCK 0 = 00 08 80 40 PSK
+             -- -----------
+                          -- 08------- bitrate
+                                 -- 8----- modulation PSK1
+                                  -- 0---- PSK ClockRate
+                                     -- 40 max 2 blocks
+
 local procedurecmds = {
-       [1] = '%s%s%s%s',
-       [2] = 'lf read',
+       [1] = '00%02X%X%X40',
+       [2] = 'lf t55xx detect',
        --[3] = '',
-       [3] = 'data samples',
-       [4] = 'data pskdetectclock',
-       [5] = 'data psknrzrawdemod',
-       [6] = 'data pskindalademod',
+       [3] = 'lf t55xx info',
 }
-
 --- 
 -- A debug printout-function
 function dbg(args)
@@ -97,45 +105,39 @@ function ExitMsg(msg)
        print()
 end
 
-function pskTest(modulation)
-       local y
-       for y = 0, 8, 4 do
-               for _ = 1, #procedurecmds do
-                       local cmd = procedurecmds[_]
-                       
-                       if #cmd == 0 then  
-                       
-                       elseif _ == 1 then
-
-                               dbg("Writing to T55x7 TAG")
-               
-                               local configdata = cmd:format( config1, modulation , y, config2)
+function test(modulation)
+       local bitrate
+       local clockrate
+       for bitrate = 0x0, 0x1d, 0x4 do
+       
+               for clockrate = 0,8,4 do
+
+                       for _ = 1, #procedurecmds do
+                               local cmd = procedurecmds[_]
                                
-                               dbg( configdata)
+                               if #cmd == 0 then  
                                
-                               local writecommand = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK, arg1 = configdata ,arg2 = 0, arg3 = 0}
-                               local err = core.SendCommand(writecommand:getBytes())
-                               if err then return oops(err) end
-                               local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
-
-                               if response then
-                                       local count,cmd,arg0 = bin.unpack('LL',response)
-                                       if(arg0==1) then
-                                               dbg("Writing success")
-                                       else
-                                               return nil, "Couldn't read block.." 
-                                       end
+                               elseif _ == 1 then
+
+                                       dbg("Writing to T55x7 TAG")
+
+                                       local config = cmd:format(bitrate, modulation, clockrate)
+                                       dbg(('lf t55xx write 0 %s'):format(config))
+                                       
+                                       config = tonumber(config,16) 
+                                       local writecommand = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK, arg1 = config ,arg2 = 0, arg3 = 0}
+                                       local err = core.SendCommand(writecommand:getBytes())
+                                       if err then return oops(err) end
+                                       local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
+                               else
+                                       dbg(cmd)
+                                       core.console( cmd )
                                end
-
-                       else
-                               dbg(cmd)
-                               core.console( cmd )
                        end
+                       core.clearCommandBuffer()       
                end
-               core.clearCommandBuffer()       
        end
        print( string.rep('--',20) )
-
 end
 
 local function main(args)
@@ -143,20 +145,16 @@ local function main(args)
        print( string.rep('--',20) )
        print( string.rep('--',20) )
 
-       local outputTemplate = os.date("testpsk_%Y-%m-%d_%H%M%S")
-
        -- Arguments for the script
-       for o, arg in getopt.getopt(args, 'ho:') do
+       for o, arg in getopt.getopt(args, 'h') do
                if o == "h" then return help() end
-               if o == "o" then outputTemplate = arg end               
        end
 
        core.clearCommandBuffer()
 
-       pskTest(1)
-       pskTest(2)
-       pskTest(3)
-       pskTest(8)
+       test(1)  -- PSK1
+       --test(2) -- PSK2
+       --test(3) -- PSK3
        
        print( string.rep('--',20) )
 end
@@ -170,4 +168,4 @@ main(args)
 
     -- XXXXX0XX = PSK RF/2
     -- XXXXX4XX = PSK RF/4
-    -- XXXXX8XX = PSK RF/8
\ No newline at end of file
+    -- XXXXX8XX = PSK RF/8
index e4a9215cb0a74bb0c877c0f636c4097a1031c721..ae4055aed40a9a6c891a42b62af7cb42369f2fcc 100644 (file)
@@ -6,19 +6,20 @@ local dumplib = require('html_dumplib')
 
 example =[[
        1. script run tracetest
-       2. script run tracetest -o 
-
 ]]
 author = "Iceman"
-usage = "script run tracetest -o <filename>"
+usage = "script run tracetest"
 desc =[[
 This script will load several traces files in ../traces/ folder and do 
 "data load"
-"lf search" 
+"lf search 1 u" 
+
+The following tracefiles will be loaded:  
+   em*.pm3
+   m*.pm3
 
 Arguments:
        -h             : this help
-       -o             : logfile name
 ]]
 
 local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
@@ -71,14 +72,14 @@ local function main(args)
        local tracesEM = "find '../traces/' -iname 'em*.pm3' -type f"
        local tracesMOD = "find '../traces/' -iname 'm*.pm3' -type f"
 
+       local write2File = false
        local outputTemplate = os.date("testtest_%Y-%m-%d_%H%M%S")
 
        -- Arguments for the script
-       for o, arg in getopt.getopt(args, 'ho:') do
+       for o, arg in getopt.getopt(args, 'h') do
                if o == "h" then return help() end              
-               if o == "o" then outputTemplate = arg end               
        end
-
+       
        core.clearCommandBuffer()
        
        local files = {}
@@ -97,7 +98,7 @@ local function main(args)
        end
        p.close();
        
-       local cmdLFSEARCH = "lf search 1" 
+       local cmdLFSEARCH = "lf search 1 u
        
        -- main loop
        io.write('Starting to test traces > ')
@@ -119,13 +120,6 @@ local function main(args)
        end
        io.write('\n')
 
-       -- Write dump to files
-       if not DEBUG then
-               local bar = dumplib.SaveAsText(emldata, outputTemplate..'.txt')
-               print(("Wrote output to:  %s"):format(bar))
-       end
-
-       -- Show info 
        print( string.rep('--',20) )
 
 end
index 46ac4924247885f9a4028d76f1e379ebf2f57f25..c7acb404bac93319c4176eafb494654200a96cf6 100644 (file)
@@ -75,51 +75,6 @@ uint8_t preambleSearch(uint8_t *BitStream, uint8_t *preamble, size_t pLen, size_
   return 0;
 }
 
-
-//by marshmellow
-//takes 1s and 0s and searches for EM410x format - output EM ID
-uint64_t Em410xDecodeOld(uint8_t *BitStream, size_t *size, size_t *startIdx)
-{
-  //no arguments needed - built this way in case we want this to be a direct call from "data " cmds in the future
-  //  otherwise could be a void with no arguments
-  //set defaults
-  uint64_t lo=0;
-  uint32_t i = 0;
-  if (BitStream[1]>1){  //allow only 1s and 0s
-    // PrintAndLog("no data found");
-    return 0;
-  }
-  // 111111111 bit pattern represent start of frame
-  uint8_t preamble[] = {1,1,1,1,1,1,1,1,1};
-  uint32_t idx = 0;
-  uint32_t parityBits = 0;
-  uint8_t errChk = 0;
-  *startIdx = 0;
-  for (uint8_t extraBitChk=0; extraBitChk<5; extraBitChk++){
-    errChk = preambleSearch(BitStream+extraBitChk+*startIdx, preamble, sizeof(preamble), size, startIdx);
-    if (errChk == 0) return 0;
-    idx = *startIdx + 9;
-    for (i=0; i<10;i++){ //loop through 10 sets of 5 bits (50-10p = 40 bits)
-      parityBits = bytebits_to_byte(BitStream+(i*5)+idx,5);
-      //check even parity
-      if (parityTest(parityBits, 5, 0) == 0){
-        //parity failed try next bit (in the case of 1111111111) but last 9 = preamble
-        startIdx++;
-        errChk = 0;
-        break;
-      }
-      //set uint64 with ID from BitStream
-      for (uint8_t ii=0; ii<4; ii++){
-        lo = (lo << 1LL) | (BitStream[(i*5)+ii+idx]);
-      }
-    }
-    if (errChk != 0) return lo;
-    //skip last 5 bit parity test for simplicity.
-    // *size = 64;
-  }
-  return 0;
-}
-
 //by marshmellow
 //takes 1s and 0s and searches for EM410x format - output EM ID
 uint8_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx, uint32_t *hi, uint64_t *lo)
@@ -143,6 +98,7 @@ uint8_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx, uint32_
     errChk = preambleSearch(BitStream+extraBitChk+*startIdx, preamble, sizeof(preamble), size, startIdx);
     if (errChk == 0) return 0;
     if (*size>64) FmtLen = 22;
+    if (*size<64) return 0;
     idx = *startIdx + 9;
     for (i=0; i<FmtLen; i++){ //loop through 10 or 22 sets of 5 bits (50-10p = 40 bits or 88 bits)
       parityBits = bytebits_to_byte(BitStream+(i*5)+idx,5);
@@ -308,16 +264,12 @@ int ManchesterEncode(uint8_t *BitStream, size_t size)
 //run through 2 times and take least errCnt
 int manrawdecode(uint8_t * BitStream, size_t *size)
 {
-       uint16_t bitnum=0;
-       uint16_t MaxBits = 500;
-       uint16_t errCnt = 0;
-       size_t i=1;
-       uint16_t bestErr = 1000;
-       uint16_t bestRun = 0;
-       size_t ii=1;
+       uint16_t bitnum=0, MaxBits = 512, errCnt = 0;
+       size_t i, ii;
+       uint16_t bestErr = 1000, bestRun = 0;
        if (size == 0) return -1;
-       for (ii=1;ii<3;++ii){
-               i=1;
+       for (ii=0;ii<2;++ii){
+               i=0;
                for (i=i+ii;i<*size-2;i+=2){
                        if(BitStream[i]==1 && (BitStream[i+1]==0)){
                        } else if((BitStream[i]==0)&& BitStream[i+1]==1){
@@ -335,7 +287,7 @@ int manrawdecode(uint8_t * BitStream, size_t *size)
        errCnt=bestErr;
        if (errCnt<20){
                ii=bestRun;
-               i=1;
+               i=0;
                for (i=i+ii; i < *size-2; i+=2){
                        if(BitStream[i] == 1 && (BitStream[i+1] == 0)){
                                BitStream[bitnum++]=0;
@@ -355,6 +307,7 @@ int manrawdecode(uint8_t * BitStream, size_t *size)
 //by marshmellow
 //take 01 or 10 = 1 and 11 or 00 = 0
 //check for phase errors - should never have 111 or 000 should be 01001011 or 10110100 for 1010
+//decodes biphase or if inverted it is AKA conditional dephase encoding AKA differential manchester encoding
 int BiphaseRawDecode(uint8_t *BitStream, size_t *size, int offset, int invert)
 {
        uint16_t bitnum=0;
@@ -372,7 +325,7 @@ int BiphaseRawDecode(uint8_t *BitStream, size_t *size, int offset, int invert)
        if (!offsetA && offsetB) offset++;
        for (i=offset; i<*size-3; i+=2){
                //check for phase error
-               if (i<*size-3 && BitStream[i+1]==BitStream[i+2]) {
+               if (BitStream[i+1]==BitStream[i+2]) {
                        BitStream[bitnum++]=77;
                        errCnt++;
                }
@@ -412,6 +365,56 @@ void askAmp(uint8_t *BitStream, size_t size)
        return;
 }
 
+int cleanAskRawDemod(uint8_t *BinStream, size_t *size, int clk, int invert, int high, int low)
+{
+       size_t bitCnt=0, smplCnt=0, errCnt=0;
+       uint8_t waveHigh = 0;
+       //PrintAndLog("clk: %d", clk);
+       for (size_t i=0; i < *size; i++){
+               if (BinStream[i] >= high && waveHigh){
+                       smplCnt++;
+               } else if (BinStream[i] <= low && !waveHigh){
+                       smplCnt++;
+               } else { //transition
+                       if ((BinStream[i] >= high && !waveHigh) || (BinStream[i] <= low && waveHigh)){
+                               if (smplCnt > clk-(clk/4)-1) { //full clock
+                                       if (smplCnt > clk + (clk/4)+1) { //too many samples
+                                               errCnt++;
+                                               BinStream[bitCnt++]=77;
+                                       } else if (waveHigh) {
+                                               BinStream[bitCnt++] = invert;
+                                               BinStream[bitCnt++] = invert;
+                                       } else if (!waveHigh) {
+                                               BinStream[bitCnt++] = invert ^ 1;
+                                               BinStream[bitCnt++] = invert ^ 1;
+                                       }
+                                       waveHigh ^= 1;  
+                                       smplCnt = 0;
+                               } else if (smplCnt > (clk/2) - (clk/4)-1) {
+                                       if (waveHigh) {
+                                               BinStream[bitCnt++] = invert;
+                                       } else if (!waveHigh) {
+                                               BinStream[bitCnt++] = invert ^ 1;
+                                       }
+                                       waveHigh ^= 1;  
+                                       smplCnt = 0;
+                               } else if (!bitCnt) {
+                                       //first bit
+                                       waveHigh = (BinStream[i] >= high);
+                                       smplCnt = 1;
+                               } else {
+                                       smplCnt++;
+                                       //transition bit oops
+                               }
+                       } else { //haven't hit new high or new low yet
+                               smplCnt++;
+                       }
+               }
+       }
+       *size = bitCnt;
+       return errCnt;
+}
+
 //by marshmellow
 //takes 3 arguments - clock, invert and maxErr as integers
 //attempts to demodulate ask only
@@ -423,15 +426,22 @@ int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int max
        if (*clk==0) return -1;
        if (start<0) return -1;
        if (*invert != 0 && *invert != 1) *invert =0;
+       if (amp==1) askAmp(BinStream, *size);
+
        uint32_t initLoopMax = 200;
        if (initLoopMax > *size) initLoopMax=*size;
        // Detect high and lows
-       //25% fuzz in case highs and lows aren't clipped [marshmellow]
+       //25% clip in case highs and lows aren't clipped [marshmellow]
+       uint8_t clip = 75;
        int high, low, ans;
-       if (amp==1) askAmp(BinStream, *size);
-       ans = getHiLo(BinStream, initLoopMax, &high, &low, 75, 75);
+       ans = getHiLo(BinStream, initLoopMax, &high, &low, clip, clip);
        if (ans<1) return -1; //just noise
 
+       if (DetectCleanAskWave(BinStream, *size, high, low)) {
+               //PrintAndLog("Clean");
+               return cleanAskRawDemod(BinStream, size, *clk, *invert, high, low);
+       }
+
        //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low);
        int lastBit = 0;  //set first clock check
        uint32_t bitnum = 0;     //output counter
@@ -443,12 +453,13 @@ int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int max
        uint32_t gLen = *size;
        if (gLen > 500) gLen=500;
        //if 0 errors allowed then only try first 2 clock cycles as we want a low tolerance
-       if (!maxErr) gLen=*clk*2; 
+       if (!maxErr) gLen = *clk * 2; 
        uint8_t errCnt =0;
        uint32_t bestStart = *size;
        uint32_t bestErrCnt = maxErr; //(*size/1000);
        uint8_t midBit=0;
        uint16_t MaxBits=1000;
+
        //PrintAndLog("DEBUG - lastbit - %d",lastBit);
        //loop to find first wave that works
        for (iii=start; iii < gLen; ++iii){
@@ -619,7 +630,9 @@ size_t fsk_wave_demod(uint8_t * dest, size_t size, uint8_t fchigh, uint8_t fclow
                                //do nothing with extra garbage
                        } else if ((idx-last_transition) < (fchigh-1)) { //6-8 = 8 waves
                                dest[numBits]=1;
-                       } else {                                                        //9+ = 10 waves
+                       } else if ((idx-last_transition) > (fchigh+1) && !numBits) { //12 + and first bit = garbage 
+                               //do nothing with beginning garbage
+                       } else {                                         //9+ = 10 waves
                                dest[numBits]=0;
                        }
                        last_transition = idx;
@@ -643,18 +656,31 @@ size_t aggregate_bits(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t maxCons
        uint32_t idx=0;
        size_t numBits=0;
        uint32_t n=1;
-
+       float lowWaves = (((float)(rfLen))/((float)fclow));
+       float highWaves = (((float)(rfLen))/((float)fchigh));
        for( idx=1; idx < size; idx++) {
 
                if (dest[idx]==lastval) {
                        n++;
                        continue;
                }
+               n++;
                //if lastval was 1, we have a 1->0 crossing
-               if ( dest[idx-1]==1 ) {
-                       n=myround2((float)(n+1)/((float)(rfLen)/(float)fclow));
-               } else {// 0->1 crossing
-                       n=myround2((float)(n+1)/((float)(rfLen-1)/(float)fchigh));  //-1 for fudge factor
+               if (dest[idx-1]==1) {
+                       if (!numBits && n < (uint8_t)lowWaves) {
+                               n=0;
+                               lastval = dest[idx];
+                               continue;
+                       }
+                       n=myround2(((float)n)/lowWaves);
+               } else {// 0->1 crossing 
+                       //test first bitsample too small
+                       if (!numBits && n < (uint8_t)highWaves) {
+                               n=0;
+                               lastval = dest[idx];
+                               continue;
+                       }
+                       n = myround2(((float)n)/highWaves);  //-1 for fudge factor
                }
                if (n == 0) n = 1;
 
@@ -670,6 +696,17 @@ size_t aggregate_bits(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t maxCons
                n=0;
                lastval=dest[idx];
        }//end for
+
+       // if valid extra bits at the end were all the same frequency - add them in
+       if (n > lowWaves && n > highWaves) {
+               if (dest[idx-2]==1) {
+                       n=myround2((float)(n+1)/((float)(rfLen)/(float)fclow));
+               } else {
+                       n=myround2((float)(n+1)/((float)(rfLen-1)/(float)fchigh));  //-1 for fudge factor                       
+               }
+               memset(dest, dest[idx-1]^invert , n);
+               numBits += n;
+       }
        return numBits;
 }
 //by marshmellow  (from holiman's base)
@@ -856,20 +893,70 @@ int PyramiddemodFSK(uint8_t *dest, size_t *size)
 
 uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, int high, int low)
 {
-       uint8_t allPeaks=1;
+       uint16_t allPeaks=1;
        uint16_t cntPeaks=0;
-       for (size_t i=20; i<255; i++){
+       size_t loopEnd = 572;
+       if (loopEnd > size) loopEnd = size;
+       for (size_t i=60; i<loopEnd; i++){
                if (dest[i]>low && dest[i]<high) 
                        allPeaks=0;
                else
                        cntPeaks++;
        }
-       if (allPeaks==0){
-               if (cntPeaks>190) return 1;
+       if (allPeaks == 0){
+               if (cntPeaks > 300) return 1;
        }
        return allPeaks;
 }
 
+int DetectStrongAskClock(uint8_t dest[], size_t size)
+{
+       int clk[]={0,8,16,32,40,50,64,100,128,256};
+  size_t idx = 40;
+       uint8_t high=0;
+       size_t cnt = 0;
+       size_t highCnt = 0;
+       size_t highCnt2 = 0;
+       for (;idx < size; idx++){
+               if (dest[idx]>128) {
+                       if (!high){
+                               high=1;
+                               if (cnt > highCnt){
+                                       if (highCnt != 0) highCnt2 = highCnt;
+                                       highCnt = cnt;
+                               } else if (cnt > highCnt2) {
+                                       highCnt2 = cnt;
+                               }
+                               cnt=1;
+                       } else {
+                               cnt++;
+                       }
+               } else if (dest[idx] <= 128){
+                       if (high) {
+                               high=0;
+                               if (cnt > highCnt) {
+                                       if (highCnt != 0) highCnt2 = highCnt;
+                                       highCnt = cnt;
+                               } else if (cnt > highCnt2) {
+                                       highCnt2 = cnt;
+                               }
+                               cnt=1;
+                       } else {
+                               cnt++;
+                       }
+               }
+       }
+       uint8_t tol;
+       for (idx=8; idx>0; idx--){
+               tol = clk[idx]/8;
+               if (clk[idx] >= highCnt - tol && clk[idx] <= highCnt + tol)
+                       return clk[idx];
+               if (clk[idx] >= highCnt2 - tol && clk[idx] <= highCnt2 + tol)
+                       return clk[idx];
+       }
+       return -1;
+}
+
 // by marshmellow
 // not perfect especially with lower clocks or VERY good antennas (heavy wave clipping)
 // maybe somehow adjust peak trimming value based on samples to fix?
@@ -892,24 +979,14 @@ int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr)
   
   //test for large clean peaks
   if (DetectCleanAskWave(dest, size, peak, low)==1){
-         uint16_t fcTest=0;
-         uint8_t mostFC=0;
-         fcTest=countFC(dest, size, &mostFC);
-         uint8_t fc1 = fcTest >> 8;
-         uint8_t fc2 = fcTest & 0xFF;
-
-         for (i=0; i<8; i++){
-               if (clk[i] == fc1) {
-                       *clock=fc1;
-                       return 0;
-               }
-               if (clk[i] == fc2) {
-                       *clock=fc2;
+       int ans = DetectStrongAskClock(dest, size);
+         for (i=7; i>0; i--){
+               if (clk[i] == ans) {
+                       *clock=ans;
                        return 0;
                }
          }
   }
-  
   int ii;
   int clkCnt;
   int tol = 0;
@@ -923,6 +1000,7 @@ int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr)
     }else{
       tol=0;
     }
+       if (!maxErr) loopCnt=clk[clkCnt]*2;
     bestErr[clkCnt]=1000;
     //try lining up the peaks by moving starting point (try first 256)
     for (ii=0; ii < loopCnt; ii++){
@@ -1242,11 +1320,10 @@ int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr)
   *clk = DetectNRZClock(dest, *size, *clk);
   if (*clk==0) return -2;
   uint32_t i;
-  int high, low, ans;
-  ans = getHiLo(dest, 1260, &high, &low, 75, 75); //25% fuzz on high 25% fuzz on low
-  if (ans<1) return -2; //just noise
-  uint32_t gLen = 256;
+  uint32_t gLen = 4096;
   if (gLen>*size) gLen = *size;
+  int high, low;
+  if (getHiLo(dest, gLen, &high, &low, 75, 75) < 1) return -3; //25% fuzz on high 25% fuzz on low
   int lastBit = 0;  //set first clock check
   uint32_t bitnum = 0;     //output counter
   uint8_t tol = 1;  //clock tolerance adjust - waves will be accepted as within the clock if they fall + or - this value + clock from last valid wave
@@ -1256,6 +1333,8 @@ int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr)
   uint32_t bestErrCnt = maxErr+1;
   uint32_t bestPeakCnt = 0;
   uint32_t bestPeakStart=0;
+  uint8_t bestFirstPeakHigh=0;
+  uint8_t firstPeakHigh=0;
   uint8_t curBit=0;
   uint8_t bitHigh=0;
   uint8_t errBitHigh=0;
@@ -1265,6 +1344,8 @@ int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr)
   //loop to find first wave that works - align to clock
   for (iii=0; iii < gLen; ++iii){
     if ((dest[iii]>=high) || (dest[iii]<=low)){
+      if (dest[iii]>=high) firstPeakHigh=1;
+      else firstPeakHigh=0;
       lastBit=iii-*clk;
       peakCnt=0;
       errCnt=0;
@@ -1315,6 +1396,7 @@ int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr)
         //possible good read
         if (errCnt == 0){
           //bestStart = iii;
+          bestFirstPeakHigh=firstPeakHigh;
           bestErrCnt = errCnt;
           bestPeakCnt = peakCnt;
           bestPeakStart = iii;
@@ -1325,6 +1407,7 @@ int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr)
           //bestStart = iii;
         }
         if (peakCnt > bestPeakCnt){
+          bestFirstPeakHigh=firstPeakHigh;
           bestPeakCnt=peakCnt;
           bestPeakStart=iii;
         } 
@@ -1337,6 +1420,8 @@ int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr)
     iii=bestPeakStart;
     lastBit=bestPeakStart-*clk;
     bitnum=0;
+    memset(dest, bestFirstPeakHigh^1, bestPeakStart / *clk);
+    bitnum += (bestPeakStart / *clk);
     for (i = iii; i < *size; ++i) {
       //if we found a high bar and we are at a clock bit
       if ((dest[i] >= high ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){
@@ -1386,12 +1471,12 @@ int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr)
     *size=bitnum;
   } else{
     *size=bitnum;
-    return -1;
+    return bestErrCnt;
   }
 
   if (bitnum>16){
     *size=bitnum;
-  } else return -1;
+  } else return -5;
   return errCnt;
 }
 
@@ -1689,7 +1774,7 @@ int pskRawDemod(uint8_t dest[], size_t *size, int *clock, int *invert)
   errCnt=0;
   size_t numBits=0;
   //set skipped bits
-  memset(dest+numBits,curPhase^1,firstFullWave / *clock);
+  memset(dest,curPhase^1,firstFullWave / *clock);
   numBits += (firstFullWave / *clock);
   dest[numBits++] = curPhase; //set first read bit
   for (i = firstFullWave+fullWaveLen-1; i < *size-3; i++){
index 8e10a7dfed6c18e05ac6eb3835c9f81d5ae5fd5e..46e2bdd574d040268b2c4950a7d53e108ceca813 100644 (file)
@@ -16,6 +16,7 @@
 #include <stdint.h>
 
 int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr);
+uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, int high, int low);
 int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr);
 uint8_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx, uint32_t *hi, uint64_t *lo);
 //uint64_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx);
@@ -47,5 +48,6 @@ uint8_t justNoise(uint8_t *BitStream, size_t size);
 uint8_t countPSK_FC(uint8_t *BitStream, size_t size);
 int pskRawDemod(uint8_t dest[], size_t *size, int *clock, int *invert);
 int DetectPSKClock(uint8_t dest[], size_t size, int clock);
+void askAmp(uint8_t *BitStream, size_t size);
 
 #endif
Impressum, Datenschutz