]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
Merge remote-tracking branch 'upstream/master'
authormarshmellow42 <marshmellowrf@gmail.com>
Mon, 26 Jan 2015 22:07:49 +0000 (17:07 -0500)
committermarshmellow42 <marshmellowrf@gmail.com>
Mon, 26 Jan 2015 22:07:49 +0000 (17:07 -0500)
armsrc/lfops.c
client/cmddata.c
client/cmddata.h
client/cmdlf.c
client/graph.c
common/lfdemod.c
common/lfdemod.h

index f5040850c50cd2b1f93dfdf979bdbd74b463cfe2..8ea9b317fc00d6374016f6871e2ece5e9a5cf310 100644 (file)
@@ -633,7 +633,7 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
 {
     uint8_t *dest = (uint8_t *)BigBuf;
 
-    size_t size=0; //, found=0;
+    size_t size=sizeof(BigBuf), idx=0; //, found=0;
     uint32_t hi2=0, hi=0, lo=0;
 
     // Configure to go in 125Khz listen mode
@@ -646,11 +646,11 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
 
         DoAcquisition125k_internal(-1,true);
         // FSK demodulator
-               size = HIDdemodFSK(dest, sizeof(BigBuf), &hi2, &hi, &lo);
+               idx = HIDdemodFSK(dest, &size, &hi2, &hi, &lo);
 
         WDT_HIT();
 
-               if (size>0 && lo>0){
+               if (idx>0 && lo>0){
             // final loop, go over previously decoded manchester data and decode into usable tag ID
             // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0
             if (hi2 != 0){ //extra large HID tags
@@ -721,7 +721,7 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
 {
     uint8_t *dest = (uint8_t *)BigBuf;
 
-       size_t size=0;
+       size_t size=0, idx=0;
     int clk=0, invert=0, errCnt=0;
     uint64_t lo=0;
     // Configure to go in 125Khz listen mode
@@ -741,7 +741,7 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
         WDT_HIT();
 
         if (errCnt>=0){
-                       lo = Em410xDecode(dest,size);
+                       lo = Em410xDecode(dest, &size, &idx);
             //Dbprintf("DEBUG: EM GOT");
             if (lo>0){
                                Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)",
index 820e44e2c8d319799256e6d30c1253bf469112c2..0a1841bf4df994573bf6a1277c877b922d1d9413 100644 (file)
 #include "cmddata.h"
 #include "lfdemod.h"
 uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
+uint8_t g_debugMode;
 int DemodBufferLen;
 static int CmdHelp(const char *Cmd);
 
 //set the demod buffer with given array of binary (one bit per byte)
 //by marshmellow
-void setDemodBuf(uint8_t *buff,int size)
+void setDemodBuf(uint8_t *buff, size_t size, size_t startIdx)
 {
-       int i=0;
-       for (; i < size; ++i){
-               DemodBuffer[i]=buff[i];
+       size_t i = 0;
+       for (; i < size; i++){
+               DemodBuffer[i]=buff[startIdx++];
        }
        DemodBufferLen=size;
        return;
 }
 
+int CmdSetDebugMode(const char *Cmd)
+{
+  int demod=0;
+  sscanf(Cmd, "%i", &demod);
+  g_debugMode=(uint8_t)demod;
+  return 1;
+}
+
 //by marshmellow
 void printDemodBuff()
 {
@@ -206,7 +215,7 @@ void printEM410x(uint64_t id)
 {
   if (id !=0){
       uint64_t iii=1;
-      uint64_t id2lo=0; //id2hi=0,
+      uint64_t id2lo=0;
       uint32_t ii=0;
       uint32_t i=0;
       for (ii=5; ii>0;ii--){
@@ -216,7 +225,7 @@ void printEM410x(uint64_t id)
       }
       //output em id
       PrintAndLog("EM TAG ID    : %010llx", id);
-      PrintAndLog("Unique TAG ID: %010llx",  id2lo); //id2hi,
+      PrintAndLog("Unique TAG ID: %010llx",  id2lo);
       PrintAndLog("DEZ 8        : %08lld",id & 0xFFFFFF);
       PrintAndLog("DEZ 10       : %010lld",id & 0xFFFFFF);
       PrintAndLog("DEZ 5.5      : %05lld.%05lld",(id>>16LL) & 0xFFFF,(id & 0xFFFF));
@@ -233,12 +242,17 @@ void printEM410x(uint64_t id)
 int CmdEm410xDecode(const char *Cmd)
 {
   uint64_t id=0;
- // uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
- // uint32_t i=0;
- // i=getFromGraphBuf(BitStream);
-       id = Em410xDecode(DemodBuffer,DemodBufferLen);
-  printEM410x(id);
-  if (id>0) return 1;
+  size_t size = DemodBufferLen, idx=0;
+       id = Em410xDecode(DemodBuffer, &size, &idx);
+  if (id>0){
+    setDemodBuf(DemodBuffer, size, idx);
+    if (g_debugMode){
+      PrintAndLog("DEBUG: Printing demod buffer:");
+      printDemodBuff();
+    }
+    printEM410x(id);
+    return 1; 
+  }
   return 0;
 }
 
@@ -249,7 +263,7 @@ int CmdEm410xDecode(const char *Cmd)
 //prints binary found and saves in graphbuffer for further commands
 int Cmdaskmandemod(const char *Cmd)
 {
-       int invert=0;
+  int invert=0;
        int clk=0;
   uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
        sscanf(Cmd, "%i %i", &clk, &invert);
@@ -259,11 +273,11 @@ int Cmdaskmandemod(const char *Cmd)
   }
 
        size_t BitLen = getFromGraphBuf(BitStream);
-  //  PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen);
+  if (g_debugMode==1) PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen);
   int errCnt=0;
    errCnt = askmandemod(BitStream, &BitLen,&clk,&invert);
        if (errCnt<0||BitLen<16){  //if fatal error (or -1)
-               // PrintAndLog("no data found %d, errors:%d, bitlen:%d, clock:%d",errCnt,invert,BitLen,clk);
+               if (g_debugMode==1) PrintAndLog("no data found %d, errors:%d, bitlen:%d, clock:%d",errCnt,invert,BitLen,clk);
     return 0;
        }
   PrintAndLog("\nUsing Clock: %d - Invert: %d - Bits Found: %d",clk,invert,BitLen);
@@ -274,17 +288,22 @@ int Cmdaskmandemod(const char *Cmd)
   }
   PrintAndLog("ASK/Manchester decoded bitstream:");
   // Now output the bitstream to the scrollback by line of 16 bits
-       setDemodBuf(BitStream,BitLen);
+       setDemodBuf(BitStream,BitLen,0);
        printDemodBuff();
   uint64_t lo =0;
-  lo = Em410xDecode(BitStream,BitLen);
+  size_t idx=0;
+  lo = Em410xDecode(BitStream, &BitLen, &idx);
   if (lo>0){
     //set GraphBuffer for clone or sim command
+    setDemodBuf(BitStream, BitLen, idx);
+    if (g_debugMode){
+      PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, BitLen);
+      printDemodBuff();
+    }
     PrintAndLog("EM410x pattern found: ");
     printEM410x(lo);
     return 1;
   }
-  //if (BitLen>16) return 1;
   return 0;
 }
 
@@ -317,9 +336,14 @@ int Cmdmandecoderaw(const char *Cmd)
        printBitStream(BitStream, size);
   if (errCnt==0){
                uint64_t id = 0;
-               id = Em410xDecode(BitStream, size);
-               if (id>0) setDemodBuf(BitStream, size);
-               printEM410x(id);
+    size_t idx=0;
+               id = Em410xDecode(BitStream, &size, &idx);
+               if (id>0){
+      //need to adjust to set bitstream back to manchester encoded data
+      //setDemodBuf(BitStream, size, idx);
+
+      printEM410x(id);
+    }
   }
   return 1;
 }
@@ -327,7 +351,8 @@ int Cmdmandecoderaw(const char *Cmd)
 //by marshmellow
 //biphase decode
 //take 01 or 10 = 0 and 11 or 00 = 1
-//takes 1 argument "offset" default = 0 if 1 it will shift the decode by one bit
+//takes 2 arguments "offset" default = 0 if 1 it will shift the decode by one bit
+// and "invert" default = 0 if 1 it will invert output
 //  since it is not like manchester and doesn't have an incorrect bit pattern we
 //  cannot determine if our decode is correct or if it should be shifted by one bit
 //  the argument offset allows us to manually shift if the output is incorrect
@@ -339,8 +364,9 @@ int CmdBiphaseDecodeRaw(const char *Cmd)
   int errCnt=0;
        size_t size=0;
   int offset=0;
+  int invert=0;
   int high=0, low=0;
-       sscanf(Cmd, "%i", &offset);
+       sscanf(Cmd, "%i %i", &offset, &invert);
   uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
   //get graphbuffer & high and low
        for (;i<DemodBufferLen;++i){
@@ -353,7 +379,7 @@ int CmdBiphaseDecodeRaw(const char *Cmd)
     return 0;
   }
        size=i;
-       errCnt=BiphaseRawDecode(BitStream, &size, offset);
+       errCnt=BiphaseRawDecode(BitStream, &size, offset, invert);
   if (errCnt>=20){
     PrintAndLog("Too many errors attempting to decode: %d",errCnt);
     return 0;
@@ -364,7 +390,6 @@ int CmdBiphaseDecodeRaw(const char *Cmd)
   return 1;
 }
 
-
 //by marshmellow
 //takes 2 arguments - clock and invert both as integers
 //attempts to demodulate ask only
@@ -384,14 +409,15 @@ int Cmdaskrawdemod(const char *Cmd)
        errCnt = askrawdemod(BitStream, &BitLen,&clk,&invert);
        if (errCnt==-1||BitLen<16){  //throw away static - allow 1 and -1 (in case of threshold command first)
                PrintAndLog("no data found");
+    if (g_debugMode==1) PrintAndLog("errCnt: %d, BitLen: %d, clk: %d, invert: %d", errCnt, BitLen, clk, invert);
     return 0;
        }
   PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen);
-    //PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum);
-               //move BitStream back to DemodBuffer
-       setDemodBuf(BitStream,BitLen);
+  
+  //move BitStream back to DemodBuffer
+       setDemodBuf(BitStream,BitLen,0);
 
-               //output
+       //output
   if (errCnt>0){
     PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
   }
@@ -535,6 +561,27 @@ int CmdDec(const char *Cmd)
   return 0;
 }
 
+//by marshmellow
+//shift graph zero up or down based on input + or -
+int CmdGraphShiftZero(const char *Cmd)
+{
+
+  int shift=0;
+  //set options from parameters entered with the command
+  sscanf(Cmd, "%i", &shift);
+  int shiftedVal=0;
+  for(int i = 0; i<GraphTraceLen; i++){
+    shiftedVal=GraphBuffer[i]+shift;
+    if (shiftedVal>127) 
+      shiftedVal=127;
+    else if (shiftedVal<-127) 
+      shiftedVal=-127;
+    GraphBuffer[i]= shiftedVal;
+  }
+  CmdNorm("");
+  return 0;
+}
+
 /* Print our clock rate */
 // uses data from graphbuffer
 int CmdDetectClockRate(const char *Cmd)
@@ -553,27 +600,44 @@ int CmdFSKrawdemod(const char *Cmd)
 {
   //raw fsk demod  no manchester decoding no start bit finding just get binary from wave
   //set defaults
-  int rfLen = 50;
+  int rfLen = 0;
   int invert=0;
-  int fchigh=10;
-  int fclow=8;
+  int fchigh=0;
+  int fclow=0;
   //set options from parameters entered with the command
        sscanf(Cmd, "%i %i %i %i", &rfLen, &invert, &fchigh, &fclow);
 
   if (strlen(Cmd)>0 && strlen(Cmd)<=2) {
-     //rfLen=param_get8(Cmd, 0); //if rfLen option only is used
      if (rfLen==1){
       invert=1;   //if invert option only is used
-      rfLen = 50;
-     } else if(rfLen==0) rfLen=50;
+      rfLen = 0;
+     }
        }
-  PrintAndLog("Args invert: %d - Clock:%d - fchigh:%d - fclow: %d",invert,rfLen,fchigh, fclow);
+
   uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
        size_t BitLen = getFromGraphBuf(BitStream);
+  //get field clock lengths
+  uint16_t fcs=0;
+  if (fchigh==0 || fclow == 0){
+    fcs=countFC(BitStream, BitLen);
+    if (fcs==0){
+      fchigh=10;
+      fclow=8;
+    }else{
+      fchigh = (fcs >> 8) & 0xFF;
+      fclow = fcs & 0xFF;
+    }
+  }
+  //get bit clock length
+  if (rfLen==0){
+    rfLen = detectFSKClk(BitStream, BitLen, fchigh, fclow);
+    if (rfLen == 0) rfLen = 50;
+  }
+  PrintAndLog("Args invert: %d - Clock:%d - fchigh:%d - fclow: %d",invert,rfLen,fchigh, fclow);
        int size  = fskdemod(BitStream,BitLen,(uint8_t)rfLen,(uint8_t)invert,(uint8_t)fchigh,(uint8_t)fclow);
   if (size>0){
     PrintAndLog("FSK decoded bitstream:");
-               setDemodBuf(BitStream,size);
+               setDemodBuf(BitStream,size,0);
 
     // Now output the bitstream to the scrollback by line of 16 bits
     if(size > (8*32)+2) size = (8*32)+2; //only output a max of 8 blocks of 32 bits  most tags will have full bit stream inside that sample size
@@ -595,20 +659,20 @@ int CmdFSKdemodHID(const char *Cmd)
   uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
        size_t BitLen = getFromGraphBuf(BitStream);
   //get binary from fsk wave
-       size_t size  = HIDdemodFSK(BitStream,BitLen,&hi2,&hi,&lo);
-  if (size<0){
-    PrintAndLog("Error demoding fsk");
+       size_t idx  = HIDdemodFSK(BitStream,&BitLen,&hi2,&hi,&lo);
+  if (idx<0){
+    if (g_debugMode) PrintAndLog("DEBUG: Error demoding fsk");
+    return 0;
+  }
+  if (hi2==0 && hi==0 && lo==0) {
+    if (g_debugMode) PrintAndLog("DEBUG: Error - no values found");
     return 0;
   }
-  if (hi2==0 && hi==0 && lo==0) return 0;
   if (hi2 != 0){ //extra large HID tags
                PrintAndLog("HID Prox TAG ID: %x%08x%08x (%d)",
        (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
-               setDemodBuf(BitStream,BitLen);
-    return 1;
   }
   else {  //standard HID tags <38 bits
-    //Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd
     uint8_t fmtLen = 0;
     uint32_t fc = 0;
     uint32_t cardnum = 0;
@@ -648,12 +712,49 @@ int CmdFSKdemodHID(const char *Cmd)
                PrintAndLog("HID Prox TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d",
       (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF,
       (unsigned int) fmtLen, (unsigned int) fc, (unsigned int) cardnum);
-               setDemodBuf(BitStream,BitLen);
-    return 1;
   }
-  return 0;
+  setDemodBuf(BitStream,BitLen,idx);
+  if (g_debugMode){ 
+    PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, BitLen);
+    printDemodBuff();
+  }
+  return 1;
 }
 
+//by marshmellow (based on existing demod + holiman's refactor)
+//Paradox Prox demod - FSK RF/50 with preamble of 00011101 (then manchester encoded)
+//print full Paradox Prox ID and some bit format details if found
+int CmdFSKdemodParadox(const char *Cmd)
+{
+  //raw fsk demod no manchester decoding no start bit finding just get binary from wave
+  uint32_t hi2=0, hi=0, lo=0;
+
+  uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
+  size_t BitLen = getFromGraphBuf(BitStream);
+  //get binary from fsk wave
+  size_t idx = ParadoxdemodFSK(BitStream,&BitLen,&hi2,&hi,&lo);
+  if (idx<0){
+    if (g_debugMode) PrintAndLog("DEBUG: Error demoding fsk");
+    return 0;
+  }
+  if (hi2==0 && hi==0 && lo==0){
+    if (g_debugMode) PrintAndLog("DEBUG: Error - no value found");
+    return 0;
+  }
+  uint32_t fc = ((hi & 0x3)<<6) | (lo>>26);
+  uint32_t cardnum = (lo>>10)&0xFFFF;
+  
+  PrintAndLog("Paradox TAG ID: %x%08x - FC: %d - Card: %d - Checksum: %02x",
+    hi>>10, (hi & 0x3)<<26 | (lo>>10), fc, cardnum, (lo>>2) & 0xFF );
+  setDemodBuf(BitStream,BitLen,idx);
+  if (g_debugMode){ 
+    PrintAndLog("DEBUG: idx: %d, len: %d, Printing Demod Buffer:", idx, BitLen);
+    printDemodBuff();
+  }
+  return 1;
+}
+
+
 //by marshmellow
 //IO-Prox demod - FSK RF/64 with preamble of 000000001
 //print ioprox ID and some format details
@@ -662,21 +763,25 @@ int CmdFSKdemodIO(const char *Cmd)
   //raw fsk demod no manchester decoding no start bit finding just get binary from wave
   //set defaults
        int idx=0;
-  //something in graphbuffer
-  if (GraphTraceLen < 65) return 0;
+  //something in graphbuffer?
+  if (GraphTraceLen < 65) {
+    if (g_debugMode)PrintAndLog("DEBUG: not enough samples in GraphBuffer");
+    return 0;
+  }
   uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
        size_t BitLen = getFromGraphBuf(BitStream);
+
   //get binary from fsk wave
- // PrintAndLog("DEBUG: got buff");
        idx = IOdemodFSK(BitStream,BitLen);
   if (idx<0){
-    //PrintAndLog("Error demoding fsk");
+    if (g_debugMode==1) PrintAndLog("DEBUG: demoding fsk error: %d", idx);
     return 0;
   }
- // PrintAndLog("DEBUG: Got IOdemodFSK");
   if (idx==0){
-    //PrintAndLog("IO Prox Data not found - FSK Data:");
-    //if (BitLen > 92) printBitStream(BitStream,92);
+    if (g_debugMode==1){
+      PrintAndLog("DEBUG: IO Prox Data not found - FSK Bits: %d",BitLen);
+      if (BitLen > 92) printBitStream(BitStream,92);
+    } 
     return 0;
   }
     //Index map
@@ -688,7 +793,10 @@ int CmdFSKdemodIO(const char *Cmd)
     //
     //XSF(version)facility:codeone+codetwo (raw)
     //Handle the data
-  if (idx+64>BitLen) return 0;
+  if (idx+64>BitLen) {
+    if (g_debugMode==1) PrintAndLog("not enough bits found - bitlen: %d",BitLen);
+    return 0;
+  }
   PrintAndLog("%d%d%d%d%d%d%d%d %d",BitStream[idx],    BitStream[idx+1],  BitStream[idx+2], BitStream[idx+3], BitStream[idx+4], BitStream[idx+5], BitStream[idx+6], BitStream[idx+7], BitStream[idx+8]);
        PrintAndLog("%d%d%d%d%d%d%d%d %d",BitStream[idx+9],  BitStream[idx+10], BitStream[idx+11],BitStream[idx+12],BitStream[idx+13],BitStream[idx+14],BitStream[idx+15],BitStream[idx+16],BitStream[idx+17]);
   PrintAndLog("%d%d%d%d%d%d%d%d %d facility",BitStream[idx+18], BitStream[idx+19], BitStream[idx+20],BitStream[idx+21],BitStream[idx+22],BitStream[idx+23],BitStream[idx+24],BitStream[idx+25],BitStream[idx+26]);
@@ -703,13 +811,242 @@ int CmdFSKdemodIO(const char *Cmd)
   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);
-       int i;
-       for (i=0;i<64;++i)
-               DemodBuffer[i]=BitStream[idx++];
+  setDemodBuf(BitStream,64,idx);
+       if (g_debugMode){
+    PrintAndLog("DEBUG: idx: %d, Len: %d, Printing demod buffer:",idx,64);
+    printDemodBuff();
+  }
+       return 1;
+}
+
+
+//by marshmellow
+//AWID Prox demod - FSK RF/50 with preamble of 00000001  (always a 96 bit data stream)
+//print full AWID Prox ID and some bit format details if found
+int CmdFSKdemodAWID(const char *Cmd)
+{
+
+  //int verbose=1;
+  //sscanf(Cmd, "%i", &verbose);
 
-       DemodBufferLen=64;
+  //raw fsk demod no manchester decoding no start bit finding just get binary from wave
+  uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
+  size_t size = getFromGraphBuf(BitStream);
+
+  //get binary from fsk wave
+  int idx = AWIDdemodFSK(BitStream, size);
+  if (idx<=0){
+    if (g_debugMode==1){
+      if (idx == -1)
+        PrintAndLog("DEBUG: Error - not enough samples");
+      else if (idx == -2)
+        PrintAndLog("DEBUG: Error - only noise found - no waves");
+      else if (idx == -3)
+        PrintAndLog("DEBUG: Error - problem during FSK demod");
+    //  else if (idx == -3)
+    //    PrintAndLog("Error: thought we had a tag but the parity failed");
+      else if (idx == -4)
+        PrintAndLog("DEBUG: Error - AWID preamble not found");
+      else if (idx == -5)
+        PrintAndLog("DEBUG: Error - Second AWID preamble not found");
+      else
+        PrintAndLog("DEBUG: Error %d",idx);
+    }
+    return 0;
+  }
+
+  // Index map
+  // 0            10            20            30              40            50              60
+  // |            |             |             |               |             |               |
+  // 01234567 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 - to 96
+  // -----------------------------------------------------------------------------
+  // 00000001 000 1 110 1 101 1 011 1 101 1 010 0 000 1 000 1 010 0 001 0 110 1 100 0 000 1 000 1
+  // premable bbb o bbb o bbw o fff o fff o ffc o ccc o ccc o ccc o ccc o ccc o wxx o xxx o xxx o - to 96
+  //          |---26 bit---|    |-----117----||-------------142-------------|
+  // b = format bit len, o = odd parity of last 3 bits
+  // f = facility code, c = card number
+  // w = wiegand parity
+  // (26 bit format shown)
+  //get raw ID before removing parities
+  uint32_t rawLo = bytebits_to_byte(BitStream+idx+64,32);
+  uint32_t rawHi = bytebits_to_byte(BitStream+idx+32,32);
+  uint32_t rawHi2 = bytebits_to_byte(BitStream+idx,32);
+  setDemodBuf(BitStream,96,idx);
+
+  size = removeParity(BitStream, idx+8, 4, 1, 88);
+  if (size != 66){
+    if (g_debugMode==1) PrintAndLog("DEBUG: Error - at parity check-tag size does not match AWID format");
+    return 0;
+  }
+  // ok valid card found!
+
+  // Index map
+  // 0           10         20        30          40        50        60
+  // |           |          |         |           |         |         |
+  // 01234567 8 90123456 7890123456789012 3 456789012345678901234567890123456
+  // -----------------------------------------------------------------------------
+  // 00011010 1 01110101 0000000010001110 1 000000000000000000000000000000000
+  // bbbbbbbb w ffffffff cccccccccccccccc w xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+  // |26 bit|   |-117--| |-----142------|
+  // b = format bit len, o = odd parity of last 3 bits
+  // f = facility code, c = card number
+  // w = wiegand parity
+  // (26 bit format shown)
+
+  uint32_t fc = 0;
+  uint32_t cardnum = 0;
+  uint32_t code1 = 0;
+  uint32_t code2 = 0;
+  uint8_t fmtLen = bytebits_to_byte(BitStream,8);
+  if (fmtLen==26){
+    fc = bytebits_to_byte(BitStream+9, 8);
+    cardnum = bytebits_to_byte(BitStream+17, 16);
+    code1 = bytebits_to_byte(BitStream+8,fmtLen);
+    PrintAndLog("AWID Found - BitLength: %d, FC: %d, Card: %d - Wiegand: %x, Raw: %x%08x%08x", fmtLen, fc, cardnum, code1, rawHi2, rawHi, rawLo);
+  } else {
+    cardnum = bytebits_to_byte(BitStream+8+(fmtLen-17), 16);
+    if (fmtLen>32){
+      code1 = bytebits_to_byte(BitStream+8,fmtLen-32);
+      code2 = bytebits_to_byte(BitStream+8+(fmtLen-32),32);
+      PrintAndLog("AWID Found - BitLength: %d -unknown BitLength- (%d) - Wiegand: %x%08x, Raw: %x%08x%08x", fmtLen, cardnum, code1, code2, rawHi2, rawHi, rawLo);
+    } else{
+      code1 = bytebits_to_byte(BitStream+8,fmtLen);
+      PrintAndLog("AWID Found - BitLength: %d -unknown BitLength- (%d) - Wiegand: %x, Raw: %x%08x%08x", fmtLen, cardnum, code1, rawHi2, rawHi, rawLo);
+    }
+  }
+  if (g_debugMode){
+    PrintAndLog("DEBUG: idx: %d, Len: %d Printing Demod Buffer:", idx, 96);
+    printDemodBuff();
+  }
+  //todo - convert hi2, hi, lo to demodbuffer for future sim/clone commands
   return 1;
 }
+
+//by marshmellow
+//Pyramid Prox demod - FSK RF/50 with preamble of 0000000000000001  (always a 128 bit data stream)
+//print full Farpointe Data/Pyramid Prox ID and some bit format details if found
+int CmdFSKdemodPyramid(const char *Cmd)
+{
+  //raw fsk demod no manchester decoding no start bit finding just get binary from wave
+  uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
+  size_t size = getFromGraphBuf(BitStream);
+
+  //get binary from fsk wave
+  int idx = PyramiddemodFSK(BitStream, size);
+  if (idx < 0){
+    if (g_debugMode==1){
+      if (idx == -5)
+        PrintAndLog("DEBUG: Error - not enough samples");
+      else if (idx == -1)
+        PrintAndLog("DEBUG: Error - only noise found - no waves");
+      else if (idx == -2)
+        PrintAndLog("DEBUG: Error - problem during FSK demod");
+      else if (idx == -3)
+        PrintAndLog("DEBUG: Error - Second Pyramid preamble not found");
+      else if (idx == -4)
+        PrintAndLog("DEBUG: Error - Pyramid preamble not found");
+      else
+        PrintAndLog("DEBUG: Error - idx: %d",idx);
+    }
+    return 0;
+  }
+  // Index map
+  // 0           10          20          30            40          50          60
+  // |           |           |           |             |           |           |
+  // 0123456 7 8901234 5 6789012 3 4567890 1 2345678 9 0123456 7 8901234 5 6789012 3
+  // -----------------------------------------------------------------------------
+  // 0000000 0 0000000 1 0000000 1 0000000 1 0000000 1 0000000 1 0000000 1 0000000 1
+  // premable  xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o
+
+  // 64    70            80          90          100         110           120
+  // |     |             |           |           |           |             |
+  // 4567890 1 2345678 9 0123456 7 8901234 5 6789012 3 4567890 1 2345678 9 0123456 7
+  // -----------------------------------------------------------------------------
+  // 0000000 1 0000000 1 0000000 1 0110111 0 0011000 1 0000001 0 0001100 1 1001010 0
+  // xxxxxxx o xxxxxxx o xxxxxxx o xswffff o ffffccc o ccccccc o ccccccw o ppppppp o
+  //                                  |---115---||---------71---------|
+  // s = format start bit, o = odd parity of last 7 bits
+  // f = facility code, c = card number
+  // w = wiegand parity, x = extra space for other formats
+  // p = unknown checksum
+  // (26 bit format shown)
+  
+  //get raw ID before removing parities
+  uint32_t rawLo = bytebits_to_byte(BitStream+idx+96,32);
+  uint32_t rawHi = bytebits_to_byte(BitStream+idx+64,32);
+  uint32_t rawHi2 = bytebits_to_byte(BitStream+idx+32,32);
+  uint32_t rawHi3 = bytebits_to_byte(BitStream+idx,32);
+  setDemodBuf(BitStream,128,idx);
+
+  size = removeParity(BitStream, idx+8, 8, 1, 120);
+  if (size != 105){
+    if (g_debugMode==1) PrintAndLog("DEBUG: Error at parity check-tag size does not match Pyramid format, SIZE: %d, IDX: %d, hi3: %x",size, idx, rawHi3);
+    return 0;
+  }
+
+  // ok valid card found!
+
+  // Index map
+  // 0         10        20        30        40        50        60        70
+  // |         |         |         |         |         |         |         |
+  // 01234567890123456789012345678901234567890123456789012345678901234567890
+  // -----------------------------------------------------------------------
+  // 00000000000000000000000000000000000000000000000000000000000000000000000
+  // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+
+  // 71         80         90          100
+  // |          |          |           |
+  // 1 2 34567890 1234567890123456 7 8901234
+  // ---------------------------------------
+  // 1 1 01110011 0000000001000110 0 1001010
+  // s w ffffffff cccccccccccccccc w ppppppp
+  //     |--115-| |------71------|
+  // s = format start bit, o = odd parity of last 7 bits
+  // f = facility code, c = card number
+  // w = wiegand parity, x = extra space for other formats
+  // p = unknown checksum
+  // (26 bit format shown)
+
+  //find start bit to get fmtLen
+  int j;
+  for (j=0; j<size; j++){
+    if(BitStream[j]) break;
+  }
+  uint8_t fmtLen = size-j-8;
+  uint32_t fc = 0;
+  uint32_t cardnum = 0;
+  uint32_t code1 = 0;
+  //uint32_t code2 = 0;
+  if (fmtLen==26){
+    fc = bytebits_to_byte(BitStream+73, 8);
+    cardnum = bytebits_to_byte(BitStream+81, 16);
+    code1 = bytebits_to_byte(BitStream+72,fmtLen);
+    PrintAndLog("Pyramid ID Found - BitLength: %d, FC: %d, Card: %d - Wiegand: %x, Raw: %x%08x%08x%08x", fmtLen, fc, cardnum, code1, rawHi3, rawHi2, rawHi, rawLo);
+  } else if (fmtLen==45){
+    fmtLen=42; //end = 10 bits not 7 like 26 bit fmt
+    fc = bytebits_to_byte(BitStream+53, 10);
+    cardnum = bytebits_to_byte(BitStream+63, 32);
+    PrintAndLog("Pyramid ID Found - BitLength: %d, FC: %d, Card: %d - Raw: %x%08x%08x%08x", fmtLen, fc, cardnum, rawHi3, rawHi2, rawHi, rawLo);
+  } else {
+    cardnum = bytebits_to_byte(BitStream+81, 16);
+    if (fmtLen>32){
+      //code1 = bytebits_to_byte(BitStream+(size-fmtLen),fmtLen-32);
+      //code2 = bytebits_to_byte(BitStream+(size-32),32);
+      PrintAndLog("Pyramid ID Found - BitLength: %d -unknown BitLength- (%d), Raw: %x%08x%08x%08x", fmtLen, cardnum, rawHi3, rawHi2, rawHi, rawLo);
+    } else{
+      //code1 = bytebits_to_byte(BitStream+(size-fmtLen),fmtLen);
+      PrintAndLog("Pyramid ID Found - BitLength: %d -unknown BitLength- (%d), Raw: %x%08x%08x%08x", fmtLen, cardnum, rawHi3, rawHi2, rawHi, rawLo);
+    }
+  }
+  //todo - convert hi2, hi, lo to demodbuffer for future sim/clone commands
+  if (g_debugMode){
+    PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, 128);
+    printDemodBuff();
+  }
+  return 1;
+}
+
 int CmdFSKdemod(const char *Cmd) //old CmdFSKdemod needs updating
 {
   static const int LowTone[]  = {
@@ -828,13 +1165,39 @@ int CmdFSKdemod(const char *Cmd) //old CmdFSKdemod needs updating
   return 0;
 }
 
+//by marshmellow
+//attempt to detect the field clock and bit clock for FSK
+int CmdFSKfcDetect(const char *Cmd)
+{
+  uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
+  size_t size = getFromGraphBuf(BitStream);
+
+  uint16_t ans = countFC(BitStream, size); 
+  if (ans==0) {
+    if (g_debugMode) PrintAndLog("DEBUG: No data found");
+    return 0;
+  }
+  uint8_t fc1, fc2;
+  fc1 = (ans >> 8) & 0xFF;
+  fc2 = ans & 0xFF;
+
+  uint8_t rf1 = detectFSKClk(BitStream, size, fc1, fc2);
+  if (rf1==0) {
+    if (g_debugMode) PrintAndLog("DEBUG: Clock detect error");
+    return 0;
+  }
+  PrintAndLog("Detected Field Clocks: FC/%d, FC/%d - Bit Clock: RF/%d", fc1, fc2, rf1);
+  return 1;
+}
+
 int CmdDetectNRZpskClockRate(const char *Cmd)
 {
        GetNRZpskClock("",0,0);
        return 0;
 }
 
-int PSKnrzDemod(const char *Cmd){
+int PSKnrzDemod(const char *Cmd)
+{
        int invert=0;
        int clk=0;
        sscanf(Cmd, "%i %i", &clk, &invert);
@@ -847,13 +1210,13 @@ int PSKnrzDemod(const char *Cmd){
        int errCnt=0;
        errCnt = pskNRZrawDemod(BitStream, &BitLen,&clk,&invert);
        if (errCnt<0|| BitLen<16){  //throw away static - allow 1 and -1 (in case of threshold command first)
-               //PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt);
+               if (g_debugMode==1) PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt);
                return -1;
        }
        PrintAndLog("Tried PSK/NRZ Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen);
 
        //prime demod buffer for output
-       setDemodBuf(BitStream,BitLen);
+       setDemodBuf(BitStream,BitLen,0);
        return errCnt;
 }
 // Indala 26 bit decode
@@ -861,35 +1224,30 @@ int PSKnrzDemod(const char *Cmd){
 // optional arguments - same as CmdpskNRZrawDemod (clock & invert)
 int CmdIndalaDecode(const char *Cmd)
 {
-  uint8_t verbose = 1;
   int ans;
   if (strlen(Cmd)>0){
-    if (Cmd[0]=='0'){
-      verbose=0;
-      ans = PSKnrzDemod("32");
-    }else{
-      ans = PSKnrzDemod(Cmd);
-    }
+    ans = PSKnrzDemod(Cmd);
   } else{ //default to RF/32
     ans = PSKnrzDemod("32");
   }
 
        if (ans < 0){
-               if (verbose
+               if (g_debugMode==1
       PrintAndLog("Error1: %d",ans);
                return 0;
        }
        uint8_t invert=0;
        ans = indala26decode(DemodBuffer,(size_t *) &DemodBufferLen, &invert);
        if (ans < 1) {
-               if (verbose)
+               if (g_debugMode==1)
       PrintAndLog("Error2: %d",ans);
                return -1;
        }
        char showbits[251];
        if (invert)
-    if (verbose)
+    if (g_debugMode==1)
       PrintAndLog("Had to invert bits");
+
        //convert UID to HEX
        uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7;
        int idx;
@@ -953,25 +1311,28 @@ int CmdPskClean(const char *Cmd)
 //prints binary found and saves in graphbuffer for further commands
 int CmdpskNRZrawDemod(const char *Cmd)
 {
-  uint8_t verbose = 1;
   int errCnt;
-  if (strlen(Cmd)>0){
-    if (Cmd[0]=='0')
-      verbose=0;
-  }
-
   errCnt = PSKnrzDemod(Cmd);
        //output
-       if (errCnt<0) return 0;
+       if (errCnt<0){
+    if (g_debugMode) PrintAndLog("Error demoding: %d",errCnt);  
+    return 0;
+  } 
        if (errCnt>0){
-               if (verbose)
+               if (g_debugMode){
       PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
-       }
-       PrintAndLog("PSK or NRZ demoded bitstream:");
-       // Now output the bitstream to the scrollback by line of 16 bits
-       printDemodBuff();
-
-       return 1;
+      PrintAndLog("PSK or NRZ demoded bitstream:");
+      // Now output the bitstream to the scrollback by line of 16 bits
+      printDemodBuff();
+    }
+       }else{
+    PrintAndLog("PSK or NRZ demoded bitstream:");
+    // Now output the bitstream to the scrollback by line of 16 bits
+    printDemodBuff();  
+    return 1;
+  }
+  return 0;
 }
 
 int CmdGrid(const char *Cmd)
@@ -1123,14 +1484,14 @@ int CmdTuneSamples(const char *Cmd)
 
 int CmdLoad(const char *Cmd)
 {
-   char filename[FILE_PATH_SIZE] = {0x00};
-   int len = 0;
+  char filename[FILE_PATH_SIZE] = {0x00};
+  int len = 0;
 
-   len = strlen(Cmd);
-   if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
-   memcpy(filename, Cmd, len);
+  len = strlen(Cmd);
+  if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
+  memcpy(filename, Cmd, len);
        
-   FILE *f = fopen(filename, "r");
+  FILE *f = fopen(filename, "r");
   if (!f) {
      PrintAndLog("couldn't open '%s'", filename);
     return 0;
@@ -1159,6 +1520,8 @@ int CmdLtrim(const char *Cmd)
   RepaintGraphWindow();
   return 0;
 }
+
+// trim graph to input argument length
 int CmdRtrim(const char *Cmd)
 {
   int ds = atoi(Cmd);
@@ -1439,12 +1802,12 @@ int CmdPlot(const char *Cmd)
 
 int CmdSave(const char *Cmd)
 {
-   char filename[FILE_PATH_SIZE] = {0x00};
-   int len = 0;
+  char filename[FILE_PATH_SIZE] = {0x00};
+  int len = 0;
 
-   len = strlen(Cmd);
-   if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
-   memcpy(filename, Cmd, len);
+  len = strlen(Cmd);
+  if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
+  memcpy(filename, Cmd, len);
    
 
   FILE *f = fopen(filename, "w");
@@ -1555,19 +1918,23 @@ static command_t CommandTable[] =
   {"help",          CmdHelp,            1, "This help"},
   {"amp",           CmdAmp,             1, "Amplify peaks"},
   {"askdemod",      Cmdaskdemod,        1, "<0 or 1> -- Attempt to demodulate simple ASK tags"},
-       {"askmandemod",   Cmdaskmandemod,     1, "[clock] [invert<0|1>] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional[clock will try Auto-detect])"},
-       {"askrawdemod",   Cmdaskrawdemod,     1, "[clock] [invert<0|1>] -- Attempt to demodulate ASK tags and output binary (args optional[clock will try Auto-detect])"},
+       {"askmandemod",   Cmdaskmandemod,     1, "[clock] [invert<0|1>] -- 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> -- Autocorrelation over window"},
-  {"biphaserawdecode",CmdBiphaseDecodeRaw,1,"[offset] Biphase decode binary stream already in graph buffer (offset = bit to start decode from)"},
+  {"biphaserawdecode",CmdBiphaseDecodeRaw,1,"[offset] [invert<0|1>] Biphase decode bin stream in demod buffer (offset = 0|1 bits to shift the decode start)"},
   {"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, "Detect ASK clock rate"},
   {"fskdemod",      CmdFSKdemod,        1, "Demodulate graph window as a HID FSK"},
-  {"fskhiddemod",   CmdFSKdemodHID,     1, "Demodulate graph window as a HID FSK using raw"},
-  {"fskiodemod",    CmdFSKdemodIO,      1, "Demodulate graph window as an IO Prox FSK using raw"},
-       {"fskrawdemod",   CmdFSKrawdemod,     1, "[clock rate] [invert] [rchigh] [rclow] Demodulate graph window from FSK to binary (clock = 50)(invert = 1|0)(rchigh = 10)(rclow=8)"},
+  {"fskawiddemod",  CmdFSKdemodAWID,    1, "Demodulate graph window as an AWID FSK tag using raw"},
+  {"fskfcdetect",   CmdFSKfcDetect,     1, "Try to detect the Field Clock of an FSK wave"},
+  {"fskhiddemod",   CmdFSKdemodHID,     1, "Demodulate graph window as a HID FSK tag using raw"},
+  {"fskiodemod",    CmdFSKdemodIO,      1, "Demodulate graph window as an IO Prox tag FSK using raw"},
+  {"fskpyramiddemod",CmdFSKdemodPyramid,1, "Demodulate graph window as a Pyramid FSK tag using raw"},
+  {"fskparadoxdemod",CmdFSKdemodParadox,1, "Demodulate graph window as a Paradox FSK tag using raw"},
+  {"fskrawdemod",   CmdFSKrawdemod,     1, "[clock rate] [invert] [rchigh] [rclow] Demodulate graph window from FSK to bin (clock = 50)(invert = 1|0)(rchigh = 10)(rclow=8)"},
   {"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"},
@@ -1582,11 +1949,13 @@ static command_t CommandTable[] =
   {"plot",          CmdPlot,            1, "Show graph window (hit 'h' in window for keystroke help)"},
        {"pskclean",      CmdPskClean,        1, "Attempt to clean psk wave"},
        {"pskdetectclock",CmdDetectNRZpskClockRate, 1, "Detect ASK, PSK, or NRZ clock rate"},
-       {"pskindalademod",CmdIndalaDecode,    1, "[clock] [invert<0|1>] -- Attempt to demodulate psk indala tags and output ID binary & hex (args optional[clock will try Auto-detect])"},
-       {"psknrzrawdemod",CmdpskNRZrawDemod,  1, "[clock] [invert<0|1>] -- Attempt to demodulate psk or nrz tags and output binary (args optional[clock will try Auto-detect])"},
+       {"pskindalademod",CmdIndalaDecode,    1, "[clock] [invert<0|1>] -- Attempt to demodulate psk indala tags and output ID binary & hex (args optional)"},
+       {"psknrzrawdemod",CmdpskNRZrawDemod,  1, "[clock] [invert<0|1>] -- Attempt to demodulate psk or nrz tags and output binary (args optional)"},
   {"samples",       CmdSamples,         0, "[512 - 40000] -- Get raw samples for graph window"},
   {"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"},
index 8723b847ae1b2aaea0d3bfc255ba6139d41487e9..d87c8b82e3abdac24b4425b763fc06e1e9a6f0b9 100644 (file)
@@ -26,9 +26,12 @@ int CmdBitstream(const char *Cmd);
 int CmdBuffClear(const char *Cmd);
 int CmdDec(const char *Cmd);
 int CmdDetectClockRate(const char *Cmd);
+int CmdFSKdemodAWID(const char *Cmd);
 int CmdFSKdemod(const char *Cmd);
 int CmdFSKdemodHID(const char *Cmd);
 int CmdFSKdemodIO(const char *Cmd);
+int CmdFSKdemodParadox(const char *Cmd);
+int CmdFSKdemodPyramid(const char *Cmd);
 int CmdFSKrawdemod(const char *Cmd);
 int CmdDetectNRZpskClockRate(const char *Cmd);
 int CmdpskNRZrawDemod(const char *Cmd);
index 729a387527a1f10d8802bce474c829b50723fdc5..07a8750f7d20e3b9a3131003276136892ed7824a 100644 (file)
@@ -388,7 +388,7 @@ static void ChkBitstream(const char *str)
     }
   }
 }
-
+//appears to attempt to simulate manchester
 int CmdLFSim(const char *Cmd)
 {
        int i,j;
@@ -578,26 +578,41 @@ int CmdLFfind(const char *Cmd)
   }
 
   PrintAndLog("NOTE: some demods output possible binary\n  if it finds something that looks like a tag");
-  PrintAndLog("Checking for known tags:");
+  PrintAndLog("\nChecking for known tags:\n");
   ans=CmdFSKdemodIO("");
   if (ans>0) {
-    PrintAndLog("Valid IO Prox ID Found!");
+    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("Valid HID Prox ID Found!");
+    PrintAndLog("\nValid HID Prox ID Found!");
     return 1;
   }
   //add psk and indala
-  ans=CmdIndalaDecode("0");
+  ans=CmdIndalaDecode("");
   if (ans>0) {
-    PrintAndLog("Valid Indala ID Found!");
+    PrintAndLog("\nValid Indala ID Found!");
     return 1;
   }
   ans=Cmdaskmandemod("");
   if (ans>0) {
-    PrintAndLog("Valid EM410x ID Found!");
+    PrintAndLog("\nValid EM410x ID Found!");
     return 1;
   }
   PrintAndLog("No Known Tags Found!\n");
index 94d6054fe7500653d0b47da3379030dbb4efe612..95050f558c169078e96a4d7aaad1a91e7419869b 100644 (file)
@@ -76,6 +76,8 @@ size_t getFromGraphBuf(uint8_t *buff)
   }
   return i;
 }
+
+
 // Get or auto-detect clock rate
 int GetClock(const char *str, int peak, int verbose)
 {
@@ -157,4 +159,4 @@ int GetNRZpskClock(const char *str, int peak, int verbose)
                }
        }
        return clock;
-}
\ No newline at end of file
+}
index 062818ef45a62f1dfda102035b8e4fea39f9a545..34194394deea0ded2029bbe3e173a7261c36fc7e 100644 (file)
@@ -5,16 +5,33 @@
 // at your option, any later version. See the LICENSE.txt file for the text of
 // the license.
 //-----------------------------------------------------------------------------
-// Low frequency commands
+// Low frequency demod/decode commands
 //-----------------------------------------------------------------------------
 
 #include <stdlib.h>
 #include <string.h>
 #include "lfdemod.h"
 
+//by marshmellow
+//get high and low with passed in fuzz factor. also return noise test = 1 for passed or 0 for only noise
+int getHiLo(uint8_t *BitStream, size_t size, int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo)
+{
+       *high=0;
+       *low=255;
+       // get high and low thresholds 
+       for (int i=0; i < size; i++){
+               if (BitStream[i] > *high) *high = BitStream[i];
+               if (BitStream[i] < *low) *low = BitStream[i];
+       }
+       if (*high < 123) return -1; // just noise
+       *high = (int)(((*high-128)*(((float)fuzzHi)/100))+128);
+       *low = (int)(((*low-128)*(((float)fuzzLo)/100))+128);
+       return 1;
+}
+
 //by marshmellow
 //takes 1s and 0s and searches for EM410x format - output EM ID
-uint64_t Em410xDecode(uint8_t *BitStream, size_t size)
+uint64_t Em410xDecode(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
@@ -31,17 +48,18 @@ uint64_t Em410xDecode(uint8_t *BitStream, size_t size)
        uint32_t idx = 0;
        uint32_t ii=0;
        uint8_t resetCnt = 0;
-       while( (idx + 64) < size) {
+       while( (idx + 64) < *size) {
  restart:
                // search for a start of frame marker
                if ( memcmp(BitStream+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0)
                { // frame marker found
+                       *startIdx=idx;
                        idx+=9;
                        for (i=0; i<10;i++){
                                for(ii=0; ii<5; ++ii){
                                        parityTest ^= BitStream[(i*5)+ii+idx];
                                }
-                               if (!parityTest){
+                               if (!parityTest){ //even parity
                                        parityTest=0;
                                        for (ii=0; ii<4;++ii){
                                                lo=(lo<<1LL)|(BitStream[(i*5)+ii+idx]);
@@ -57,6 +75,7 @@ uint64_t Em410xDecode(uint8_t *BitStream, size_t size)
                                }
                        }
                        //skip last 5 bit parity test for simplicity.
+                       *size = 64;
                        return lo;
                }else{
                        idx++;
@@ -72,35 +91,26 @@ uint64_t Em410xDecode(uint8_t *BitStream, size_t size)
 int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert)
 {
        int i;
-       int high = 0, low = 255;
+       int clk2=*clk;
        *clk=DetectASKClock(BinStream, *size, *clk); //clock default
 
-       if (*clk<8) *clk =64;
-       if (*clk<32) *clk=32;
+       // if autodetected too low then adjust  //MAY NEED ADJUSTMENT
+       if (clk2==0 && *clk<8) *clk =64;
+       if (clk2==0 && *clk<32) *clk=32;
        if (*invert != 0 && *invert != 1) *invert=0;
        uint32_t initLoopMax = 200;
        if (initLoopMax > *size) initLoopMax=*size;
        // Detect high and lows
-       for (i = 0; i < initLoopMax; ++i) //200 samples should be enough to find high and low values
-       {
-               if (BinStream[i] > high)
-                       high = BinStream[i];
-               else if (BinStream[i] < low)
-                       low = BinStream[i];
-       }
-       if ((high < 129) ){  //throw away static (anything < 1 graph)
-               //PrintAndLog("no data found");
-               return -2;
-       }
-       //25% fuzz in case highs and lows aren't clipped [marshmellow]
-       high=(int)(((high-128)*.75)+128);
-       low= (int)(((low-128)*.75)+128);
+       // 25% fuzz in case highs and lows aren't clipped [marshmellow]
+       int high, low, ans;
+       ans = getHiLo(BinStream, initLoopMax, &high, &low, 75, 75);
+       if (ans<1) return -2; //just noise
 
-       //PrintAndLog("DEBUG - valid high: %d - valid low: %d",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
        int tol = 0;  //clock tolerance adjust - waves will be accepted as within the clock if they fall + or - this value + clock from last valid wave
-       if (*clk==32)tol=1;    //clock tolerance may not be needed anymore currently set to + or - 1 but could be increased for poor waves or removed entirely
+       if (*clk<=32)tol=1;    //clock tolerance may not be needed anymore currently set to + or - 1 but could be increased for poor waves or removed entirely
        int iii = 0;
        uint32_t gLen = *size;
        if (gLen > 3000) gLen=3000;
@@ -108,13 +118,13 @@ int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert)
        uint32_t bestStart = *size;
        uint32_t bestErrCnt = (*size/1000);
        uint32_t maxErr = (*size/1000);
-       //PrintAndLog("DEBUG - lastbit - %d",lastBit);
-       //loop to find first wave that works
+       // PrintAndLog("DEBUG - lastbit - %d",lastBit);
+       // loop to find first wave that works
        for (iii=0; iii < gLen; ++iii){
                if ((BinStream[iii] >= high) || (BinStream[iii] <= low)){
                        lastBit=iii-*clk;
                        errCnt=0;
-                       //loop through to see if this start location works
+                       // loop through to see if this start location works
                        for (i = iii; i < *size; ++i) {
                                if ((BinStream[i] >= high) && ((i-lastBit) > (*clk-tol))){
                                        lastBit+=*clk;
@@ -192,6 +202,22 @@ int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert)
        return bestErrCnt;
 }
 
+//by marshmellow
+//encode binary data into binary manchester 
+int ManchesterEncode(uint8_t *BitStream, size_t size)
+{
+       size_t modIdx=20000, i=0;
+       if (size>modIdx) return -1;
+  for (size_t idx=0; idx < size; idx++){
+       BitStream[idx+modIdx++] = BitStream[idx];
+       BitStream[idx+modIdx++] = BitStream[idx]^1;
+  }
+  for (; i<(size*2); i++){
+       BitStream[i] = BitStream[i+20000];
+  }
+  return i;
+}
+
 //by marshmellow
 //take 10 and 01 and manchester decode
 //run through 2 times and take least errCnt
@@ -239,20 +265,19 @@ int manrawdecode(uint8_t * BitStream, size_t *size)
        return errCnt;
 }
 
-
 //by marshmellow
 //take 01 or 10 = 0 and 11 or 00 = 1
-int BiphaseRawDecode(uint8_t *BitStream, size_t *size, int offset)
+int BiphaseRawDecode(uint8_t *BitStream, size_t *size, int offset, int invert)
 {
        uint8_t bitnum=0;
        uint32_t errCnt =0;
-       uint32_t i=1;
+       uint32_t i;
        i=offset;
-       for (;i<*size-2;i+=2){
+       for (;i<*size-2; i+=2){
                if((BitStream[i]==1 && BitStream[i+1]==0) || (BitStream[i]==0 && BitStream[i+1]==1)){
-                       BitStream[bitnum++]=1;
+                       BitStream[bitnum++]=1^invert;
                } else if((BitStream[i]==0 && BitStream[i+1]==0) || (BitStream[i]==1 && BitStream[i+1]==1)){
-                       BitStream[bitnum++]=0;
+                       BitStream[bitnum++]=invert;
                } else {
                        BitStream[bitnum++]=77;
                        errCnt++;
@@ -271,31 +296,21 @@ int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert)
 {
        uint32_t i;
        // int invert=0;  //invert default
-       int high = 0, low = 255;
+       int clk2 = *clk;
        *clk=DetectASKClock(BinStream, *size, *clk); //clock default
-       uint8_t BitStream[502] = {0};
+       //uint8_t BitStream[502] = {0};
 
-       if (*clk<8) *clk =64;
-       if (*clk<32) *clk=32;
+       //HACK: if clock not detected correctly - default
+       if (clk2==0 && *clk<8) *clk =64;
+       if (clk2==0 && *clk<32 && clk2==0) *clk=32;
        if (*invert != 0 && *invert != 1) *invert =0;
        uint32_t initLoopMax = 200;
        if (initLoopMax > *size) initLoopMax=*size;
        // Detect high and lows
-       for (i = 0; i < initLoopMax; ++i) //200 samples should be plenty to find high and low values
-       {
-               if (BinStream[i] > high)
-                       high = BinStream[i];
-               else if (BinStream[i] < low)
-                       low = BinStream[i];
-       }
-       if ((high < 129)){  //throw away static  high has to be more than 0 on graph. 
-                                                                                                       //noise <= -10 here
-               //   PrintAndLog("no data found");
-               return -2;
-       }
        //25% fuzz in case highs and lows aren't clipped [marshmellow]
-       high=(int)(((high-128)*.75)+128);
-       low= (int)(((low-128)*.75)+128);
+       int high, low, ans;
+       ans = getHiLo(BinStream, initLoopMax, &high, &low, 75, 75);
+       if (ans<1) return -2; //just noise
 
        //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low);
        int lastBit = 0;  //set first clock check
@@ -310,6 +325,7 @@ int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert)
        uint8_t errCnt =0;
        uint32_t bestStart = *size;
        uint32_t bestErrCnt = (*size/1000);
+       uint32_t maxErr = bestErrCnt;
        uint8_t midBit=0;
        //PrintAndLog("DEBUG - lastbit - %d",lastBit);
        //loop to find first wave that works
@@ -320,30 +336,30 @@ int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert)
                        for (i = iii; i < *size; ++i) {
                                if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){
                                        lastBit+=*clk;
-                                       BitStream[bitnum] = *invert;
-                                       bitnum++;
+                                       //BitStream[bitnum] = *invert;
+                                       //bitnum++;
                                        midBit=0;
                                } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){
                                        //low found and we are expecting a bar
                                        lastBit+=*clk;
-                                       BitStream[bitnum] = 1- *invert;
-                                       bitnum++;
+                                       //BitStream[bitnum] = 1- *invert;
+                                       //bitnum++;
                                        midBit=0;
                                } else if ((BinStream[i]<=low) && (midBit==0) && ((i-lastBit)>((*clk/2)-tol))){
                                        //mid bar?
                                        midBit=1;
-                                       BitStream[bitnum]= 1- *invert;
-                                       bitnum++;
+                                       //BitStream[bitnum]= 1- *invert;
+                                       //bitnum++;
                                } else if ((BinStream[i]>=high) && (midBit==0) && ((i-lastBit)>((*clk/2)-tol))){
                                        //mid bar?
                                        midBit=1;
-                                       BitStream[bitnum]= *invert;
-                                       bitnum++;
+                                       //BitStream[bitnum]= *invert;
+                                       //bitnum++;
                                } else if ((i-lastBit)>((*clk/2)+tol) && (midBit==0)){
                                        //no mid bar found
                                        midBit=1;
-                                       BitStream[bitnum]= BitStream[bitnum-1];
-                                       bitnum++;
+                                       //BitStream[bitnum]= BitStream[bitnum-1];
+                                       //bitnum++;
                                } else {
                                        //mid value found or no bar supposed to be here
 
@@ -351,45 +367,94 @@ int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert)
                                                //should have hit a high or low based on clock!!
                                                //debug
                                                //PrintAndLog("DEBUG - no wave in expected area - location: %d, expected: %d-%d, lastBit: %d - resetting search",i,(lastBit+(clk-((int)(tol)))),(lastBit+(clk+((int)(tol)))),lastBit);
-                                               if (bitnum > 0){
-                                                       BitStream[bitnum]=77;
-                                                       bitnum++;
-                                               }
+                                               //if (bitnum > 0){
+                                               //      BitStream[bitnum]=77;
+                                               //      bitnum++;
+                                               //}
 
                                                errCnt++;
                                                lastBit+=*clk;//skip over until hit too many errors
                                                if (errCnt > ((*size/1000))){  //allow 1 error for every 1000 samples else start over
                                                        errCnt=0;
-                                                       bitnum=0;//start over
+                                                       //      bitnum=0;//start over
                                                        break;
                                                }
                                        }
                                }
-                               if (bitnum>500) break;
+                               if ((i-iii)>(500 * *clk)) break; //got enough bits
                        }
                        //we got more than 64 good bits and not all errors
-                       if ((bitnum > (64+errCnt)) && (errCnt<(*size/1000))) {
+                       if ((((i-iii)/ *clk) > (64+errCnt)) && (errCnt<(*size/1000))) {
                                //possible good read
-                               if (errCnt==0) break;  //great read - finish
-                               if (bestStart == iii) break;  //if current run == bestErrCnt run (after exhausted testing) then finish
+                               if (errCnt==0){
+                                       bestStart=iii;
+                                       bestErrCnt=errCnt;
+                                       break;  //great read - finish
+                               } 
                                if (errCnt<bestErrCnt){  //set this as new best run
                                        bestErrCnt=errCnt;
                                        bestStart = iii;
                                }
                        }
                }
-               if (iii>=gLen){ //exhausted test
-                       //if there was a ok test go back to that one and re-run the best run (then dump after that run)
-                       if (bestErrCnt < (*size/1000)) iii=bestStart;
-               }
        }
-       if (bitnum>16){
-               for (i=0; i < bitnum; ++i){
-                       BinStream[i]=BitStream[i];
+       if (bestErrCnt<maxErr){
+               //best run is good enough - set to best run and overwrite BinStream
+               iii=bestStart;
+               lastBit = bestStart - *clk;
+               bitnum=0;
+               for (i = iii; i < *size; ++i) {
+                       if ((BinStream[i] >= high) && ((i-lastBit) > (*clk-tol))){
+                               lastBit += *clk;
+                               BinStream[bitnum] = *invert;
+                               bitnum++;
+                               midBit=0;
+                       } else if ((BinStream[i] <= low) && ((i-lastBit) > (*clk-tol))){
+                               //low found and we are expecting a bar
+                               lastBit+=*clk;
+                               BinStream[bitnum] = 1-*invert;
+                               bitnum++;
+                               midBit=0;
+                       } else if ((BinStream[i]<=low) && (midBit==0) && ((i-lastBit)>((*clk/2)-tol))){
+                               //mid bar?
+                               midBit=1;
+                               BinStream[bitnum] = 1 - *invert;
+                               bitnum++;
+                       } else if ((BinStream[i]>=high) && (midBit==0) && ((i-lastBit)>((*clk/2)-tol))){
+                               //mid bar?
+                               midBit=1;
+                               BinStream[bitnum] = *invert;
+                               bitnum++;
+                       } else if ((i-lastBit)>((*clk/2)+tol) && (midBit==0)){
+                               //no mid bar found
+                               midBit=1;
+                               if (bitnum!=0) BinStream[bitnum] = BinStream[bitnum-1];
+                               bitnum++;
+                               
+                       } else {
+                               //mid value found or no bar supposed to be here
+                               if ((i-lastBit)>(*clk+tol)){
+                                       //should have hit a high or low based on clock!!
+
+                                       //debug
+                                       //PrintAndLog("DEBUG - no wave in expected area - location: %d, expected: %d-%d, lastBit: %d - resetting search",i,(lastBit+(clk-((int)(tol)))),(lastBit+(clk+((int)(tol)))),lastBit);
+                                       if (bitnum > 0){
+                                               BinStream[bitnum]=77;
+                                               bitnum++;
+                                       }
+
+                                       lastBit+=*clk;//skip over error
+                               }
+                       }
+                       if (bitnum >=400) break;
                }
                *size=bitnum;
-       } else return -1;
-       return errCnt;
+       } else{
+               *invert=bestStart;
+               *clk=iii;
+               return -1;
+       }
+       return bestErrCnt;
 }
 //translate wave to 11111100000 (1 for each short wave 0 for each long wave)
 size_t fsk_wave_demod(uint8_t * dest, size_t size, uint8_t fchigh, uint8_t fclow)
@@ -488,12 +553,13 @@ int fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uint8_t
        return size;
 }
 // loop to get raw HID waveform then FSK demodulate the TAG ID from it
-int HIDdemodFSK(uint8_t *dest, size_t size, uint32_t *hi2, uint32_t *hi, uint32_t *lo)
+int HIDdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo)
 {
 
-       size_t idx=0; //, found=0; //size=0,
+       size_t idx=0, size2=*size, startIdx=0; 
        // FSK demodulator
-       size = fskdemod(dest, size,50,0,10,8);
+
+       *size = fskdemod(dest, size2,50,0,10,8);
 
        // final loop, go over previously decoded manchester data and decode into usable tag ID
        // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0
@@ -501,12 +567,13 @@ int HIDdemodFSK(uint8_t *dest, size_t size, uint32_t *hi2, uint32_t *hi, uint32_
        int numshifts = 0;
        idx = 0;
        //one scan
-       while( idx + sizeof(frame_marker_mask) < size) {
+       while( idx + sizeof(frame_marker_mask) < *size) {
                // search for a start of frame marker
                if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0)
                { // frame marker found
+                       startIdx=idx;
                        idx+=sizeof(frame_marker_mask);
-                       while(dest[idx] != dest[idx+1] && idx < size-2)
+                       while(dest[idx] != dest[idx+1] && idx < *size-2)
                        {
                                // Keep going until next frame marker (or error)
                                // Shift in a bit. Start by shifting high registers
@@ -521,12 +588,13 @@ int HIDdemodFSK(uint8_t *dest, size_t size, uint32_t *hi2, uint32_t *hi, uint32_
                                idx += 2;
                        }
                        // Hopefully, we read a tag and  hit upon the next frame marker
-                       if(idx + sizeof(frame_marker_mask) < size)
+                       if(idx + sizeof(frame_marker_mask) < *size)
                        {
                                if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0)
                                {
                                        //good return
-                                       return idx;
+                                       *size=idx-startIdx;
+                                       return startIdx;
                                }
                        }
                        // reset
@@ -539,6 +607,61 @@ int HIDdemodFSK(uint8_t *dest, size_t size, uint32_t *hi2, uint32_t *hi, uint32_
        return -1;
 }
 
+// loop to get raw paradox waveform then FSK demodulate the TAG ID from it
+size_t ParadoxdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo)
+{
+
+       size_t idx=0, size2=*size;
+       // FSK demodulator
+
+       *size = fskdemod(dest, size2,50,1,10,8);
+
+       // final loop, go over previously decoded manchester data and decode into usable tag ID
+       // 00001111 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0
+       uint8_t frame_marker_mask[] = {0,0,0,0,1,1,1,1};
+       uint16_t numshifts = 0;
+       idx = 0;
+       //one scan
+       while( idx + sizeof(frame_marker_mask) < *size) {
+               // search for a start of frame marker
+               if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0)
+               { // frame marker found
+                       size2=idx;
+                       idx+=sizeof(frame_marker_mask);
+                       while(dest[idx] != dest[idx+1] && idx < *size-2)
+                       {
+                               // Keep going until next frame marker (or error)
+                               // Shift in a bit. Start by shifting high registers
+                               *hi2 = (*hi2<<1)|(*hi>>31);
+                               *hi = (*hi<<1)|(*lo>>31);
+                               //Then, shift in a 0 or one into low
+                               if (dest[idx] && !dest[idx+1])  // 1 0
+                                       *lo=(*lo<<1)|1;
+                               else // 0 1
+                                       *lo=(*lo<<1)|0;
+                               numshifts++;
+                               idx += 2;
+                       }
+                       // Hopefully, we read a tag and  hit upon the next frame marker and got enough bits
+                       if(idx + sizeof(frame_marker_mask) < *size && numshifts > 40)
+                       {
+                               if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0)
+                               {
+                                       //good return - return start grid position and bits found
+                                       *size = ((numshifts*2)+8);
+                                       return size2;
+                               }
+                       }
+                       // reset
+                       *hi2 = *hi = *lo = 0;
+                       numshifts = 0;
+               }else   {
+                       idx++;
+               }
+       }
+       return 0;
+}
+
 uint32_t bytebits_to_byte(uint8_t* src, size_t numbits)
 {
        uint32_t num = 0;
@@ -590,115 +713,207 @@ int IOdemodFSK(uint8_t *dest, size_t size)
 }
 
 // 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?
-int DetectASKClock(uint8_t dest[], size_t size, int clock)
+// pass bits to be tested in bits, length bits passed in bitLen, and parity type (even=0 | odd=1) in pType
+// returns 1 if passed
+uint8_t parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType)
 {
-       int i=0;
-       int peak=0;
-       int low=255;
-       int clk[]={16,32,40,50,64,100,128,256};
-       int loopCnt = 256;  //don't need to loop through entire array...
-       if (size<loopCnt) loopCnt = size;
-
-       //if we already have a valid clock quit
-       for (;i<8;++i)
-               if (clk[i] == clock) return clock;
+       uint8_t ans = 0;
+       for (uint8_t i = 0; i < bitLen; i++){
+               ans ^= ((bits >> i) & 1);
+       }
+  //PrintAndLog("DEBUG: ans: %d, ptype: %d",ans,pType);
+       return (ans == pType);
+}
 
-       //get high and low peak
-       for (i=0; i < loopCnt; ++i){
-               if(dest[i] > peak){
-                       peak = dest[i];
-               }
-               if(dest[i] < low){
-                       low = dest[i];
+// by marshmellow
+// takes a array of binary values, start position, length of bits per parity (includes parity bit),
+//   Parity Type (1 for odd 0 for even), and binary Length (length to run) 
+size_t removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t pType, size_t bLen)
+{
+       uint32_t parityWd = 0;
+       size_t j = 0, bitCnt = 0;
+       for (int word = 0; word < (bLen); word+=pLen){
+               for (int bit=0; bit < pLen; bit++){
+                       parityWd = (parityWd << 1) | BitStream[startIdx+word+bit];
+      BitStream[j++] = (BitStream[startIdx+word+bit]);
                }
+               j--;
+               // if parity fails then return 0
+               if (parityTest(parityWd, pLen, pType) == 0) return -1;
+               bitCnt+=(pLen-1);
+               parityWd = 0;
        }
-       peak=(int)(((peak-128)*.75)+128);
-       low= (int)(((low-128)*.75)+128);
-       int ii;
-       int clkCnt;
-       int tol = 0;
-       int bestErr[]={1000,1000,1000,1000,1000,1000,1000,1000};
-       int errCnt=0;
-       //test each valid clock from smallest to greatest to see which lines up
-       for(clkCnt=0; clkCnt < 6; ++clkCnt){
-               if (clk[clkCnt] == 32){
-                       tol=1;
-               }else{
-                       tol=0;
-               }
-               bestErr[clkCnt]=1000;
-               //try lining up the peaks by moving starting point (try first 256)
-               for (ii=0; ii< loopCnt; ++ii){
-                       if ((dest[ii] >= peak) || (dest[ii] <= low)){
-                               errCnt=0;
-                               // now that we have the first one lined up test rest of wave array
-                               for (i=0; i<((int)(size/clk[clkCnt])-1); ++i){
-                                       if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){
-                                       }else if(dest[ii+(i*clk[clkCnt])-tol]>=peak || dest[ii+(i*clk[clkCnt])-tol]<=low){
-                                       }else if(dest[ii+(i*clk[clkCnt])+tol]>=peak || dest[ii+(i*clk[clkCnt])+tol]<=low){
-                                       }else{  //error no peak detected
-                                               errCnt++;
-                                       }
-                               }
-                               //if we found no errors this is correct one - return this clock
-                               if(errCnt==0) return clk[clkCnt];
-                               //if we found errors see if it is lowest so far and save it as best run
-                               if(errCnt<bestErr[clkCnt]) bestErr[clkCnt]=errCnt;
-                       }
-               }
+       // if we got here then all the parities passed
+       //return ID start index and size
+       return bitCnt;
+}
+
+// by marshmellow
+// FSK Demod then try to locate an AWID ID
+int AWIDdemodFSK(uint8_t *dest, size_t size)
+{
+       static const uint8_t THRESHOLD = 123;
+       uint32_t idx=0, idx2=0;
+       //make sure buffer has data
+       if (size < 96*50) return -1;
+       //test samples are not just noise
+       uint8_t justNoise = 1;
+       for(idx=0; idx < size && justNoise ;idx++){
+               justNoise = dest[idx] < THRESHOLD;
        }
-       int iii=0;
-       int best=0;
-       for (iii=0; iii<7;++iii){
-               if (bestErr[iii]<bestErr[best]){
-                       //                current best bit to error ratio     vs  new bit to error ratio
-                       if (((size/clk[best])/bestErr[best] < (size/clk[iii])/bestErr[iii]) ){
-                               best = iii;
-                       }
+       if(justNoise) return -2;
+
+       // FSK demodulator
+       size = fskdemod(dest, size, 50, 1, 10, 8);  //  RF/64 and invert
+       if (size < 96) return -3;  //did we get a good demod?
+
+       uint8_t mask[] = {0,0,0,0,0,0,0,1};
+       for( idx=0; idx < (size - 96); idx++) {
+               if ( memcmp(dest + idx, mask, sizeof(mask))==0) {
+                       // frame marker found
+                       //return ID start index
+                       if (idx2 == 0) idx2=idx;
+                       else if(idx-idx2==96) return idx2;
+                       else return -5;
+
+                       // should always get 96 bits if it is awid
                }
        }
-       return clk[best];
+       //never found mask
+       return -4;
+}
+
+// by marshmellow
+// FSK Demod then try to locate an Farpointe Data (pyramid) ID
+int PyramiddemodFSK(uint8_t *dest, size_t size)
+{
+  static const uint8_t THRESHOLD = 123;
+  uint32_t idx=0, idx2=0;
+  // size_t size2 = size;
+  //make sure buffer has data
+  if (size < 128*50) return -5;
+  //test samples are not just noise
+  uint8_t justNoise = 1;
+  for(idx=0; idx < size && justNoise ;idx++){
+    justNoise = dest[idx] < THRESHOLD;
+  }
+  if(justNoise) return -1;
+
+  // FSK demodulator
+  size = fskdemod(dest, size, 50, 1, 10, 8);  //  RF/64 and invert
+  if (size < 128) return -2;  //did we get a good demod?
+
+  uint8_t mask[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
+  for( idx=0; idx < (size - 128); idx++) {
+    if ( memcmp(dest + idx, mask, sizeof(mask))==0) {
+      // frame marker found
+      if (idx2==0) idx2=idx;
+      else if (idx-idx2==128) return idx2;
+      else return -3;
+    }
+  }
+  //never found mask
+  return -4;
+}
+
+
+// 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?
+int DetectASKClock(uint8_t dest[], size_t size, int clock)
+{
+  int i=0;
+  int clk[]={8,16,32,40,50,64,100,128,256};
+  int loopCnt = 256;  //don't need to loop through entire array...
+  if (size<loopCnt) loopCnt = size;
+
+  //if we already have a valid clock quit
+  
+  for (;i<8;++i)
+    if (clk[i] == clock) return clock;
+
+  //get high and low peak
+  int peak, low;
+  getHiLo(dest, loopCnt, &peak, &low, 75, 75);
+  
+  int ii;
+  int clkCnt;
+  int tol = 0;
+  int bestErr[]={1000,1000,1000,1000,1000,1000,1000,1000,1000};
+  int errCnt=0;
+  //test each valid clock from smallest to greatest to see which lines up
+  for(clkCnt=0; clkCnt < 8; ++clkCnt){
+    if (clk[clkCnt] == 32){
+      tol=1;
+    }else{
+      tol=0;
+    }
+    bestErr[clkCnt]=1000;
+    //try lining up the peaks by moving starting point (try first 256)
+    for (ii=0; ii < loopCnt; ++ii){
+      if ((dest[ii] >= peak) || (dest[ii] <= low)){
+        errCnt=0;
+        // now that we have the first one lined up test rest of wave array
+        for (i=0; i<((int)((size-ii-tol)/clk[clkCnt])-1); ++i){
+          if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){
+          }else if(dest[ii+(i*clk[clkCnt])-tol]>=peak || dest[ii+(i*clk[clkCnt])-tol]<=low){
+          }else if(dest[ii+(i*clk[clkCnt])+tol]>=peak || dest[ii+(i*clk[clkCnt])+tol]<=low){
+          }else{  //error no peak detected
+            errCnt++;
+          }
+        }
+        //if we found no errors then we can stop here
+        //  this is correct one - return this clock
+            //PrintAndLog("DEBUG: clk %d, err %d, ii %d, i %d",clk[clkCnt],errCnt,ii,i);
+        if(errCnt==0 && clkCnt<6) return clk[clkCnt];
+        //if we found errors see if it is lowest so far and save it as best run
+        if(errCnt<bestErr[clkCnt]) bestErr[clkCnt]=errCnt;
+      }
+    }
+  }
+  uint8_t iii=0;
+  uint8_t best=0;
+  for (iii=0; iii<8; ++iii){
+    if (bestErr[iii]<bestErr[best]){
+      if (bestErr[iii]==0) bestErr[iii]=1;
+      // current best bit to error ratio     vs  new bit to error ratio
+      if (((size/clk[best])/bestErr[best] < (size/clk[iii])/bestErr[iii]) ){
+        best = iii;
+      }
+    }
+  }
+  return clk[best];
 }
 
+
 //by marshmellow
 //detect psk clock by reading #peaks vs no peaks(or errors)
 int DetectpskNRZClock(uint8_t dest[], size_t size, int clock)
 {
        int i=0;
-       int peak=0;
-       int low=255;
        int clk[]={16,32,40,50,64,100,128,256};
        int loopCnt = 2048;  //don't need to loop through entire array...
        if (size<loopCnt) loopCnt = size;
 
        //if we already have a valid clock quit
-       for (; i < 8; ++i)
+       for (; i < 7; ++i)
                if (clk[i] == clock) return clock;
 
        //get high and low peak
-       for (i=0; i < loopCnt; ++i){
-               if(dest[i] > peak){
-                       peak = dest[i];
-               }
-               if(dest[i] < low){
-                       low = dest[i];
-               }
-       }
-       peak=(int)(((peak-128)*.75)+128);
-       low= (int)(((low-128)*.75)+128);
+       int peak, low;
+       getHiLo(dest, loopCnt, &peak, &low, 75, 75);
+
        //PrintAndLog("DEBUG: peak: %d, low: %d",peak,low);
        int ii;
        uint8_t clkCnt;
        uint8_t tol = 0;
        int peakcnt=0;
        int errCnt=0;
-       int bestErr[]={1000,1000,1000,1000,1000,1000,1000,1000,1000};
-       int peaksdet[]={0,0,0,0,0,0,0,0,0};
+       int bestErr[]={1000,1000,1000,1000,1000,1000,1000,1000};
+       int peaksdet[]={0,0,0,0,0,0,0,0};
        //test each valid clock from smallest to greatest to see which lines up
-       for(clkCnt=0; clkCnt < 6; ++clkCnt){
-               if (clk[clkCnt] == 32){
+       for(clkCnt=0; clkCnt < 7; ++clkCnt){
+               if (clk[clkCnt] <= 32){
                        tol=1;
                }else{
                        tol=0;
@@ -709,7 +924,7 @@ int DetectpskNRZClock(uint8_t dest[], size_t size, int clock)
                                errCnt=0;
                                peakcnt=0;
                                // now that we have the first one lined up test rest of wave array
-                               for (i=0; i < ((int)(size/clk[clkCnt])-1); ++i){
+                               for (i=0; i < ((int)((size-ii-tol)/clk[clkCnt])-1); ++i){
                                        if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){
                                                peakcnt++;
                                        }else if(dest[ii+(i*clk[clkCnt])-tol]>=peak || dest[ii+(i*clk[clkCnt])-tol]<=low){
@@ -749,40 +964,37 @@ int DetectpskNRZClock(uint8_t dest[], size_t size, int clock)
 }
 
 //by marshmellow (attempt to get rid of high immediately after a low)
-void pskCleanWave(uint8_t *bitStream, size_t size)
+void pskCleanWave(uint8_t *BitStream, size_t size)
 {
        int i;
-       int low=255;
-       int high=0;
        int gap = 4;
- // int loopMax = 2048;
-       int newLow=0;
+       int newLow=0;
        int newHigh=0;
-       for (i=0; i < size; ++i){
-               if (bitStream[i] < low) low=bitStream[i];
-               if (bitStream[i] > high) high=bitStream[i];
-       }
-       high = (int)(((high-128)*.80)+128);
-       low = (int)(((low-128)*.90)+128);
-       //low = (uint8_t)(((int)(low)-128)*.80)+128;
-       for (i=0; i < size; ++i){
+       int high, low;
+       getHiLo(BitStream, size, &high, &low, 80, 90);
+       for (i=0; i < size; ++i){
                if (newLow == 1){
-                       bitStream[i]=low+8;
-                       gap--;
+                       if (BitStream[i]>low){
+                               BitStream[i]=low+8;
+                               gap--;
+                       }
                        if (gap == 0){
                                newLow=0;
                                gap=4;
                        }
                }else if (newHigh == 1){
-                       bitStream[i]=high-8;
-                       gap--;
+                       if (BitStream[i]<high){
+                               BitStream[i]=high-8;
+                               gap--;
+                       }
                        if (gap == 0){
                                newHigh=0;
                                gap=4;
                        }
                }
-               if (bitStream[i] <= low) newLow=1;
-               if (bitStream[i] >= high) newHigh=1;
+               if (BitStream[i] <= low) newLow=1;
+               if (BitStream[i] >= high) newHigh=1;
        }
        return;
 }
@@ -853,7 +1065,7 @@ int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert)
 }
 
 
-//by marshmellow - demodulate PSK wave or NRZ wave (both similar enough)
+//by marshmellow - demodulate PSK1 wave or NRZ wave (both similar enough)
 //peaks switch bit (high=1 low=0) each clock cycle = 1 bit determined by last peak
 int pskNRZrawDemod(uint8_t *dest, size_t *size, int *clk, int *invert)
 {
@@ -861,22 +1073,14 @@ int pskNRZrawDemod(uint8_t *dest, size_t *size, int *clk, int *invert)
        int clk2 = DetectpskNRZClock(dest, *size, *clk);
        *clk=clk2;
        uint32_t i;
-       uint8_t high=0, low=255;
+       int high, low, ans;
+       ans = getHiLo(dest, 1260, &high, &low, 75, 80); //25% fuzz on high 20% fuzz on low
+       if (ans<1) return -2; //just noise
        uint32_t gLen = *size;
-       if (gLen > 1280) gLen=1280;
-       // get high
-       for (i=0; i < gLen; ++i){
-               if (dest[i] > high) high = dest[i];
-               if (dest[i] < low) low = dest[i];
-       }
-       //fudge high/low bars by 25%
-       high = (uint8_t)((((int)(high)-128)*.75)+128);
-       low = (uint8_t)((((int)(low)-128)*.80)+128);
-
        //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low);
        int lastBit = 0;  //set first clock check
        uint32_t bitnum = 0;     //output counter
-       uint8_t tol = 0;  //clock tolerance adjust - waves will be accepted as within the clock if they fall + or - this value + clock from last valid wave
+       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
        if (*clk==32) tol = 2;    //clock tolerance may not be needed anymore currently set to + or - 1 but could be increased for poor waves or removed entirely
        uint32_t iii = 0;
        uint8_t errCnt =0;
@@ -931,7 +1135,6 @@ int pskNRZrawDemod(uint8_t *dest, size_t *size, int *clk, int *invert)
                                        bestErrCnt = errCnt;
                                        break;  //great read - finish
                                }
-                               if (bestStart == iii) break;  //if current run == bestErrCnt run (after exhausted testing) then finish
                                if (errCnt < bestErrCnt){  //set this as new best run
                                        bestErrCnt = errCnt;
                                        bestStart = iii;
@@ -995,3 +1198,192 @@ int pskNRZrawDemod(uint8_t *dest, size_t *size, int *clk, int *invert)
        return errCnt;
 }
 
+
+//by marshmellow
+//detects the bit clock for FSK given the high and low Field Clocks
+uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fcLow)
+{
+  uint8_t clk[] = {8,16,32,40,50,64,100,128,0};
+  uint16_t rfLens[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+  uint8_t rfCnts[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+  uint8_t rfLensFnd = 0;
+  uint8_t lastFCcnt=0;
+  uint32_t fcCounter = 0;
+  uint16_t rfCounter = 0;
+  uint8_t firstBitFnd = 0;
+  size_t i;
+
+  uint8_t fcTol = (uint8_t)(0.5+(float)(fcHigh-fcLow)/2);
+  rfLensFnd=0;
+  fcCounter=0;
+  rfCounter=0;
+  firstBitFnd=0;
+  //PrintAndLog("DEBUG: fcTol: %d",fcTol);
+  // prime i to first up transition
+  for (i = 1; i < size-1; i++)
+    if (BitStream[i] > BitStream[i-1] && BitStream[i]>=BitStream[i+1])
+      break;
+
+  for (; i < size-1; i++){
+    if (BitStream[i] > BitStream[i-1] && BitStream[i]>=BitStream[i+1]){
+      // new peak 
+      fcCounter++;
+      rfCounter++;
+      // if we got less than the small fc + tolerance then set it to the small fc
+      if (fcCounter < fcLow+fcTol) 
+        fcCounter = fcLow;
+      else //set it to the large fc
+        fcCounter = fcHigh;
+     
+      //look for bit clock  (rf/xx)
+      if ((fcCounter<lastFCcnt || fcCounter>lastFCcnt)){
+        //not the same size as the last wave - start of new bit sequence
+
+        if (firstBitFnd>1){ //skip first wave change - probably not a complete bit
+          for (int ii=0; ii<15; ii++){
+            if (rfLens[ii]==rfCounter){
+              rfCnts[ii]++;
+              rfCounter=0;
+              break;
+            }
+          }
+          if (rfCounter>0 && rfLensFnd<15){
+            //PrintAndLog("DEBUG: rfCntr %d, fcCntr %d",rfCounter,fcCounter);
+            rfCnts[rfLensFnd]++;
+            rfLens[rfLensFnd++]=rfCounter;
+          }
+        } else {
+          firstBitFnd++;
+        }
+        rfCounter=0;
+        lastFCcnt=fcCounter;
+      }
+      fcCounter=0;
+    } else {
+      // count sample
+      fcCounter++;
+      rfCounter++;
+    }
+  }
+  uint8_t rfHighest=15, rfHighest2=15, rfHighest3=15;
+
+  for (i=0; i<15; i++){
+    //PrintAndLog("DEBUG: RF %d, cnts %d",rfLens[i], rfCnts[i]);
+    //get highest 2 RF values  (might need to get more values to compare or compare all?)
+    if (rfCnts[i]>rfCnts[rfHighest]){
+      rfHighest3=rfHighest2;
+      rfHighest2=rfHighest;
+      rfHighest=i;
+    } else if(rfCnts[i]>rfCnts[rfHighest2]){
+      rfHighest3=rfHighest2;
+      rfHighest2=i;
+    } else if(rfCnts[i]>rfCnts[rfHighest3]){
+      rfHighest3=i;
+    }
+  }  
+  // set allowed clock remainder tolerance to be 1 large field clock length+1 
+  //   we could have mistakenly made a 9 a 10 instead of an 8 or visa versa so rfLens could be 1 FC off  
+  uint8_t tol1 = fcHigh+1; 
+  
+  //PrintAndLog("DEBUG: hightest: 1 %d, 2 %d, 3 %d",rfLens[rfHighest],rfLens[rfHighest2],rfLens[rfHighest3]);
+
+  // loop to find the highest clock that has a remainder less than the tolerance
+  //   compare samples counted divided by
+  int ii=7;
+  for (; ii>=0; ii--){
+    if (rfLens[rfHighest] % clk[ii] < tol1 || rfLens[rfHighest] % clk[ii] > clk[ii]-tol1){
+      if (rfLens[rfHighest2] % clk[ii] < tol1 || rfLens[rfHighest2] % clk[ii] > clk[ii]-tol1){
+        if (rfLens[rfHighest3] % clk[ii] < tol1 || rfLens[rfHighest3] % clk[ii] > clk[ii]-tol1){
+          break;
+        }
+      }
+    }
+  }
+
+  if (ii<0) return 0; // oops we went too far
+
+  return clk[ii];
+}
+
+//by marshmellow
+//countFC is to detect the field clock lengths.
+//counts and returns the 2 most common wave lengths
+uint16_t countFC(uint8_t *BitStream, size_t size)
+{
+  uint8_t fcLens[] = {0,0,0,0,0,0,0,0,0,0};
+  uint16_t fcCnts[] = {0,0,0,0,0,0,0,0,0,0};
+  uint8_t fcLensFnd = 0;
+  uint8_t lastFCcnt=0;
+  uint32_t fcCounter = 0;
+  size_t i;
+  
+  // prime i to first up transition
+  for (i = 1; i < size-1; i++)
+    if (BitStream[i] > BitStream[i-1] && BitStream[i] >= BitStream[i+1])
+      break;
+
+  for (; i < size-1; i++){
+    if (BitStream[i] > BitStream[i-1] && BitStream[i] >= BitStream[i+1]){
+       // new up transition
+       fcCounter++;
+       
+      //if we had 5 and now have 9 then go back to 8 (for when we get a fc 9 instead of an 8)
+      if (lastFCcnt==5 && fcCounter==9) fcCounter--;
+      //if odd and not rc/5 add one (for when we get a fc 9 instead of 10)
+      if ((fcCounter==9 && fcCounter & 1) || fcCounter==4) fcCounter++;
+
+      // save last field clock count  (fc/xx)
+      // find which fcLens to save it to:
+      for (int ii=0; ii<10; ii++){
+        if (fcLens[ii]==fcCounter){
+          fcCnts[ii]++;
+          fcCounter=0;
+          break;
+        }
+      }
+      if (fcCounter>0 && fcLensFnd<10){
+        //add new fc length 
+        fcCnts[fcLensFnd]++;
+        fcLens[fcLensFnd++]=fcCounter;
+      }
+      fcCounter=0;
+    } else {
+      // count sample
+      fcCounter++;
+    }
+  }
+  
+  uint8_t best1=9, best2=9, best3=9;
+  uint16_t maxCnt1=0;
+  // go through fclens and find which ones are bigest 2  
+  for (i=0; i<10; i++){
+    // PrintAndLog("DEBUG: FC %d, Cnt %d, Errs %d",fcLens[i],fcCnts[i],errCnt);    
+    // get the 3 best FC values
+    if (fcCnts[i]>maxCnt1) {
+      best3=best2;
+      best2=best1;
+      maxCnt1=fcCnts[i];
+      best1=i;
+    } else if(fcCnts[i]>fcCnts[best2]){
+      best3=best2;
+      best2=i;
+    } else if(fcCnts[i]>fcCnts[best3]){
+      best3=i;
+    }
+  }
+  uint8_t fcH=0, fcL=0;
+  if (fcLens[best1]>fcLens[best2]){
+    fcH=fcLens[best1];
+    fcL=fcLens[best2];
+  } else{
+    fcH=fcLens[best2];
+    fcL=fcLens[best1];
+  }
+  // TODO: take top 3 answers and compare to known Field clocks to get top 2
+
+  uint16_t fcs = (((uint16_t)fcH)<<8) | fcL;
+  // PrintAndLog("DEBUG: Best %d  best2 %d best3 %d",fcLens[best1],fcLens[best2],fcLens[best3]);
+  
+  return fcs;
+}
index b0feff04311d704de07488c479393a1c13532122..ca50d4f222d7b6b80ab8d0eaac82f3f62a3e2cae 100644 (file)
@@ -4,7 +4,11 @@
 // at your option, any later version. See the LICENSE.txt file for the text of
 // the license.
 //-----------------------------------------------------------------------------
-// Low frequency commands
+// Low frequency demod related commands
+// marshmellow
+// note that many of these demods are not the slickest code and they often rely
+//   on peaks and clock instead of converting to clean signal. 
+//   
 //-----------------------------------------------------------------------------
 
 #ifndef LFDEMOD_H__
 
 int DetectASKClock(uint8_t dest[], size_t size, int clock);
 int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert);
-uint64_t Em410xDecode(uint8_t *BitStream,size_t size);
+uint64_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx);
+int ManchesterEncode(uint8_t *BitStream, size_t size);
 int manrawdecode(uint8_t *BitStream, size_t *size);
-int BiphaseRawDecode(uint8_t * BitStream, size_t *size, int offset);
+int BiphaseRawDecode(uint8_t * BitStream, size_t *size, int offset, int invert);
 int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert);
-int HIDdemodFSK(uint8_t *dest, size_t size, uint32_t *hi2, uint32_t *hi, uint32_t *lo);
+int HIDdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo);
 int IOdemodFSK(uint8_t *dest, size_t size);
 int fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uint8_t fchigh, uint8_t fclow);
 uint32_t bytebits_to_byte(uint8_t* src, size_t numbits);
@@ -25,5 +30,12 @@ int pskNRZrawDemod(uint8_t *dest, size_t *size, int *clk, int *invert);
 int DetectpskNRZClock(uint8_t dest[], size_t size, int clock);
 int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert);
 void pskCleanWave(uint8_t *bitStream, size_t size);
+int PyramiddemodFSK(uint8_t *dest, size_t size);
+int AWIDdemodFSK(uint8_t *dest, size_t size);
+size_t removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t pType, size_t bLen);
+uint16_t countFC(uint8_t *BitStream, size_t size);
+uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fcLow);
+int getHiLo(uint8_t *BitStream, size_t size, int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo);
+size_t ParadoxdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo);
 
 #endif
Impressum, Datenschutz