]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
lf demod additions
authormarshmellow42 <marshmellowrf@gmail.com>
Sun, 18 Jan 2015 23:13:32 +0000 (18:13 -0500)
committermarshmellow42 <marshmellowrf@gmail.com>
Sun, 18 Jan 2015 23:13:32 +0000 (18:13 -0500)
data fskfcdetect (field clock and bit clock detect for FSK)
data fskdemodawid -AWID demod/decode
data fskdemodpyramid - AWID demod/decode

client/cmddata.c
client/cmddata.h
client/cmdlf.c
common/lfdemod.c
common/lfdemod.h

index a88fa4e1074f46b89f40336fcb08ffd0374ff75f..60d0d8752a59d6b5ee43652efce76b99c1e20d73 100644 (file)
@@ -327,7 +327,8 @@ int Cmdmandecoderaw(const char *Cmd)
 //by marshmellow
 //biphase decode
 //take 01 or 10 = 0 and 11 or 00 = 1
 //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
 //  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 +340,9 @@ int CmdBiphaseDecodeRaw(const char *Cmd)
   int errCnt=0;
        size_t size=0;
   int offset=0;
   int errCnt=0;
        size_t size=0;
   int offset=0;
+  int invert=0;
   int high=0, low=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){
   uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
   //get graphbuffer & high and low
        for (;i<DemodBufferLen;++i){
@@ -353,7 +355,7 @@ int CmdBiphaseDecodeRaw(const char *Cmd)
     return 0;
   }
        size=i;
     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;
   if (errCnt>=20){
     PrintAndLog("Too many errors attempting to decode: %d",errCnt);
     return 0;
@@ -714,6 +716,228 @@ int CmdFSKdemodIO(const char *Cmd)
        DemodBufferLen=64;
   return 1;
 }
        DemodBufferLen=64;
   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);
+
+  //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 (verbose){
+      if (idx == -1)
+        PrintAndLog("Error: not enough samples");
+      else if (idx == -2)
+        PrintAndLog("Error: only noise found - no waves");
+      else if (idx == -3)
+        PrintAndLog("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("Error: AWID preamble not found");
+    }
+    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);
+  size = removeParity(BitStream, idx+8, 4, 1, 88);
+  if (size != 66){
+    if (verbose) PrintAndLog("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);
+    }
+  }
+
+  //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)
+{
+
+  int verbose=1;
+  sscanf(Cmd, "%i", &verbose);
+
+  //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 (verbose){
+      if (idx == -5)
+        PrintAndLog("Error: not enough samples");
+      else if (idx == -1)
+        PrintAndLog("Error: only noise found - no waves");
+      else if (idx == -2)
+        PrintAndLog("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("Error: AWID preamble not found");
+    }
+    PrintAndLog("idx: %d",idx);
+    return 0;
+  }
+  //PrintAndLog("DEBUG: idx: %d",idx);
+  // 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);
+  size = removeParity(BitStream, idx+8, 8, 1, 120);
+  if (size != 105){
+    if (verbose) PrintAndLog("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
+  idx = 0;
+  int j;
+  for (j=0; j<size; j++){
+    if(BitStream[idx+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("AWID 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("AWID 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("AWID 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("AWID 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
+
+  return 1;
+}
+
 int CmdFSKdemod(const char *Cmd) //old CmdFSKdemod needs updating
 {
   static const int LowTone[]  = {
 int CmdFSKdemod(const char *Cmd) //old CmdFSKdemod needs updating
 {
   static const int LowTone[]  = {
@@ -833,6 +1057,21 @@ int CmdFSKdemod(const char *Cmd) //old CmdFSKdemod needs updating
   return 0;
 }
 
   return 0;
 }
 
+int CmdFSKfcDetect(const char *Cmd)
+{
+  uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
+  size_t size = getFromGraphBuf(BitStream);
+
+
+  uint32_t ans = countFC(BitStream, size);
+  int fc1, fc2, rf1;
+  fc1 = (ans >> 8) & 0xFF;
+  fc2 = ans & 0xFF;
+  rf1 = (ans >>16) & 0xFF;
+  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);
 int CmdDetectNRZpskClockRate(const char *Cmd)
 {
        GetNRZpskClock("",0,0);
@@ -1560,19 +1799,22 @@ 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"},
   {"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"},
   {"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"},
   {"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"},
+  {"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"},
   {"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"},
@@ -1587,8 +1829,8 @@ 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"},
   {"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"},
   {"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"},
index 8723b847ae1b2aaea0d3bfc255ba6139d41487e9..ffd6b983a041be2b58eb33a1d5ebbc1ef62b8c02 100644 (file)
@@ -26,9 +26,11 @@ int CmdBitstream(const char *Cmd);
 int CmdBuffClear(const char *Cmd);
 int CmdDec(const char *Cmd);
 int CmdDetectClockRate(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 CmdFSKdemod(const char *Cmd);
 int CmdFSKdemodHID(const char *Cmd);
 int CmdFSKdemodIO(const char *Cmd);
+int CmdFSKdemodPyramid(const char *Cmd);
 int CmdFSKrawdemod(const char *Cmd);
 int CmdDetectNRZpskClockRate(const char *Cmd);
 int CmdpskNRZrawDemod(const char *Cmd);
 int CmdFSKrawdemod(const char *Cmd);
 int CmdDetectNRZpskClockRate(const char *Cmd);
 int CmdpskNRZrawDemod(const char *Cmd);
index e3361cb50b3b33e38aebd540dbe505405d543173..945b45578bdd109a12b6a5d8b15379c45dcc6079 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;
 int CmdLFSim(const char *Cmd)
 {
        int i,j;
@@ -581,6 +581,16 @@ int CmdLFfind(const char *Cmd)
     PrintAndLog("Valid IO Prox ID Found!");
     return 1;
   }
     PrintAndLog("Valid IO Prox ID Found!");
     return 1;
   }
+  ans=CmdFSKdemodPyramid("0");
+  if (ans>0) {
+    PrintAndLog("Valid Pyramid ID Found!");
+    return 1;
+  }
+  ans=CmdFSKdemodAWID("0");
+  if (ans>0) {
+    PrintAndLog("Valid AWID ID Found!");
+    return 1;
+  }
   ans=CmdFSKdemodHID("");
   if (ans>0) {
     PrintAndLog("Valid HID Prox ID Found!");
   ans=CmdFSKdemodHID("");
   if (ans>0) {
     PrintAndLog("Valid HID Prox ID Found!");
index 062818ef45a62f1dfda102035b8e4fea39f9a545..4a80a10c7b715341648d4014e746d11ca8fa6fbf 100644 (file)
@@ -5,13 +5,30 @@
 // at your option, any later version. See the LICENSE.txt file for the text of
 // the license.
 //-----------------------------------------------------------------------------
 // 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"
 
 //-----------------------------------------------------------------------------
 
 #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)
 //by marshmellow
 //takes 1s and 0s and searches for EM410x format - output EM ID
 uint64_t Em410xDecode(uint8_t *BitStream, size_t size)
@@ -72,7 +89,6 @@ uint64_t Em410xDecode(uint8_t *BitStream, size_t size)
 int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert)
 {
        int i;
 int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert)
 {
        int i;
-       int high = 0, low = 255;
        *clk=DetectASKClock(BinStream, *size, *clk); //clock default
 
        if (*clk<8) *clk =64;
        *clk=DetectASKClock(BinStream, *size, *clk); //clock default
 
        if (*clk<8) *clk =64;
@@ -81,22 +97,12 @@ int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert)
        uint32_t initLoopMax = 200;
        if (initLoopMax > *size) initLoopMax=*size;
        // Detect high and lows
        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
        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
@@ -108,13 +114,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);
        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;
        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;
                        for (i = iii; i < *size; ++i) {
                                if ((BinStream[i] >= high) && ((i-lastBit) > (*clk-tol))){
                                        lastBit+=*clk;
@@ -242,17 +248,17 @@ int manrawdecode(uint8_t * BitStream, size_t *size)
 
 //by marshmellow
 //take 01 or 10 = 0 and 11 or 00 = 1
 
 //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;
 {
        uint8_t bitnum=0;
        uint32_t errCnt =0;
-       uint32_t i=1;
+       uint32_t i;
        i=offset;
        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)){
                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)){
                } 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++;
                } else {
                        BitStream[bitnum++]=77;
                        errCnt++;
@@ -271,31 +277,21 @@ int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert)
 {
        uint32_t i;
        // int invert=0;  //invert default
 {
        uint32_t i;
        // int invert=0;  //invert default
-       int high = 0, low = 255;
+       int clk2 = *clk;
        *clk=DetectASKClock(BinStream, *size, *clk); //clock default
        *clk=DetectASKClock(BinStream, *size, *clk); //clock default
-       uint8_t BitStream[502] = {0};
+       //uint8_t BitStream[502] = {0};
 
 
+       //HACK: if clock not detected correctly - default
        if (*clk<8) *clk =64;
        if (*clk<8) *clk =64;
-       if (*clk<32) *clk=32;
+       if (*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
        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]
        //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
 
        //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low);
        int lastBit = 0;  //set first clock check
@@ -310,6 +306,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);
        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
        uint8_t midBit=0;
        //PrintAndLog("DEBUG - lastbit - %d",lastBit);
        //loop to find first wave that works
@@ -320,30 +317,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;
                        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;
                                        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;
                                        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;
                                } 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;
                                } 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
 
                                } else {
                                        //mid value found or no bar supposed to be here
 
@@ -351,45 +348,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);
                                                //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;
 
                                                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;
                                                }
                                        }
                                }
                                                        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
                        }
                        //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
                                //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 (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;
                }
                *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)
 }
 //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)
@@ -589,37 +635,128 @@ int IOdemodFSK(uint8_t *dest, size_t size)
        return 0;
 }
 
        return 0;
 }
 
+// by marshmellow
+// 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
+int parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType)
+{
+       uint8_t ans = 0;
+       for (int i = 0; i < bitLen; i++){
+               ans ^= ((bits >> i) & 1);
+       }
+  //PrintAndLog("DEBUG: ans: %d, ptype: %d",ans,pType);
+       return (ans == pType);
+}
+
+// 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;
+       }
+       // 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;
+       //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;
+       }
+       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 and size
+                       return idx;  
+                       //size should always be 96
+               }
+       }
+       //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;
+ // 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
+      return idx;
+    }
+  }
+  //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;
 // 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 peak=0;
-       int low=255;
-       int clk[]={16,32,40,50,64,100,128,256};
+       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
        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
        for (;i<8;++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);
+       
        int ii;
        int clkCnt;
        int tol = 0;
        int ii;
        int clkCnt;
        int tol = 0;
-       int bestErr[]={1000,1000,1000,1000,1000,1000,1000,1000};
+       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 < 6; ++clkCnt){
        int errCnt=0;
        //test each valid clock from smallest to greatest to see which lines up
        for(clkCnt=0; clkCnt < 6; ++clkCnt){
@@ -651,7 +788,7 @@ int DetectASKClock(uint8_t dest[], size_t size, int clock)
        }
        int iii=0;
        int best=0;
        }
        int iii=0;
        int best=0;
-       for (iii=0; iii<7;++iii){
+       for (iii=0; iii<8;++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]) ){
                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]) ){
@@ -667,8 +804,6 @@ int DetectASKClock(uint8_t dest[], size_t size, int clock)
 int DetectpskNRZClock(uint8_t dest[], size_t size, int clock)
 {
        int i=0;
 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;
        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;
@@ -678,16 +813,9 @@ int DetectpskNRZClock(uint8_t dest[], size_t size, int clock)
                if (clk[i] == clock) return clock;
 
        //get high and low peak
                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;
        //PrintAndLog("DEBUG: peak: %d, low: %d",peak,low);
        int ii;
        uint8_t clkCnt;
@@ -698,7 +826,7 @@ int DetectpskNRZClock(uint8_t dest[], size_t size, int clock)
        int peaksdet[]={0,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){
        int peaksdet[]={0,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){
+               if (clk[clkCnt] >= 32){
                        tol=1;
                }else{
                        tol=0;
                        tol=1;
                }else{
                        tol=0;
@@ -749,40 +877,37 @@ int DetectpskNRZClock(uint8_t dest[], size_t size, int clock)
 }
 
 //by marshmellow (attempt to get rid of high immediately after a low)
 }
 
 //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 i;
-       int low=255;
-       int high=0;
        int gap = 4;
        int gap = 4;
- // int loopMax = 2048;
-       int newLow=0;
+       int newLow=0;
        int newHigh=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){
                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){
                        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 (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;
 }
        }
        return;
 }
@@ -853,7 +978,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)
 {
 //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 +986,14 @@ int pskNRZrawDemod(uint8_t *dest, size_t *size, int *clk, int *invert)
        int clk2 = DetectpskNRZClock(dest, *size, *clk);
        *clk=clk2;
        uint32_t i;
        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;
        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
        //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;
        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 +1048,6 @@ int pskNRZrawDemod(uint8_t *dest, size_t *size, int *clk, int *invert)
                                        bestErrCnt = errCnt;
                                        break;  //great read - finish
                                }
                                        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;
                                if (errCnt < bestErrCnt){  //set this as new best run
                                        bestErrCnt = errCnt;
                                        bestStart = iii;
@@ -995,3 +1111,169 @@ int pskNRZrawDemod(uint8_t *dest, size_t *size, int *clk, int *invert)
        return errCnt;
 }
 
        return errCnt;
 }
 
+
+//by marshmellow
+//countFC is to detect the field clock and bit clock rates.
+//for fsk or ask not psk or nrz
+uint32_t countFC(uint8_t *BitStream, size_t size)
+{
+  // get high/low thresholds
+  int high, low;
+  getHiLo(BitStream,10, &high, &low, 100, 100);
+  // get zero crossing
+  uint8_t zeroC = (high-low)/2+low;
+  uint8_t clk[]={8,16,32,40,50,64,100,128};
+  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 rfLens[] = {0,0,0,0,0,0,0,0,0,0,0};
+  // uint8_t rfCnts[] = {0,0,0,0,0,0,0,0,0,0};
+  uint8_t fcLensFnd = 0;
+  uint8_t rfLensFnd = 0;
+  uint8_t lastBit=0;
+  uint8_t curBit=0;
+  uint8_t lastFCcnt=0;
+  uint32_t errCnt=0;
+  uint32_t fcCounter = 0;
+  uint32_t rfCounter = 0;
+  uint8_t firstBitFnd = 0;
+  int i;
+  
+  // prime i to first up transition
+  for (i = 1; i < size; i++)
+    if (BitStream[i]>=zeroC && BitStream[i-1]<zeroC)
+      break;
+
+  for (; i < size; i++){
+    curBit = BitStream[i];
+    lastBit = BitStream[i-1];
+    if (lastBit<zeroC && curBit >= zeroC){
+      // new up transition
+      fcCounter++;
+      rfCounter++;
+      if (fcCounter > 3 && fcCounter < 256){ 
+        //we've counted enough that it could be a valid field clock
+  
+        //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++;
+     
+        //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<10; ii++){
+              if (rfLens[ii]==rfCounter){
+                //rfCnts[ii]++;
+                rfCounter=0;
+                break;
+              }
+            }
+            if (rfCounter>0 && rfLensFnd<10){
+              //PrintAndLog("DEBUG: rfCntr %d, fcCntr %d",rfCounter,fcCounter);
+              //rfCnts[rfLensFnd]++;
+              rfLens[rfLensFnd++]=rfCounter;
+            }
+          } else {
+            //PrintAndLog("DEBUG i: %d",i);
+            firstBitFnd++;
+          }
+          rfCounter=0;
+          lastFCcnt=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 
+          //PrintAndLog("FCCntr %d",fcCounter);
+          fcCnts[fcLensFnd]++;
+          fcLens[fcLensFnd++]=fcCounter;
+        }
+      } else{
+        // hmmm this should not happen often - count them
+        errCnt++;
+      }
+      // reset counter
+      fcCounter=0;
+    } else {
+      // count sample
+      fcCounter++;
+      rfCounter++;
+    }
+  }
+  // if too many errors return errors as negative number (IS THIS NEEDED?)
+  if (errCnt>100) return -1*errCnt;
+  
+  uint8_t maxCnt1=0, best1=9, best2=9, best3=9, rfHighest=10, rfHighest2=10, rfHighest3=10;
+
+  // go through fclens and find which ones are bigest 2  
+  for (i=0; i<10; i++){
+    // PrintAndLog("DEBUG: FC %d, Cnt %d, Errs %d, RF %d",fcLens[i],fcCnts[i],errCnt,rfLens[i]);
+    
+    // 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;
+    }
+    //get highest 2 RF values  (might need to get more values to compare or compare all?)
+    if (rfLens[i]>rfLens[rfHighest]){
+      rfHighest3=rfHighest2;
+      rfHighest2=rfHighest;
+      rfHighest=i;
+    } else if(rfLens[i]>rfLens[rfHighest2]){
+      rfHighest3=rfHighest2;
+      rfHighest2=i;
+    } else if(rfLens[i]>rfLens[rfHighest3]){
+      rfHighest3=i;
+    }
+  }
+
+  // set allowed clock remainder tolerance to be 1 large field clock length 
+  //   we could have mistakenly made a 9 a 10 instead of an 8 or visa versa so rfLens could be 1 FC off
+  int tol1 = (fcLens[best1]>fcLens[best2]) ? fcLens[best1] : fcLens[best2]; 
+  
+  // 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) ii=7; // oops we went too far
+
+  // TODO: take top 3 answers and compare to known Field clocks to get top 2
+
+  uint32_t fcs=0;
+  // PrintAndLog("DEBUG: Best %d  best2 %d best3 %d, clk %d, clk2 %d",fcLens[best1],fcLens[best2],fcLens[best3],clk[i],clk[ii]);
+  //
+
+  if (fcLens[best1]>fcLens[best2]){
+    fcs = (((uint32_t)clk[ii])<<16) | (((uint32_t)fcLens[best1])<<8) | ((fcLens[best2]));
+  } else {
+    fcs = (((uint32_t)clk[ii])<<16) | (((uint32_t)fcLens[best2])<<8) | ((fcLens[best1]));    
+  }
+
+  return fcs;
+}
index b0feff04311d704de07488c479393a1c13532122..ae04bc2fa259fe35c8262d5049a76f09dec0be31 100644 (file)
@@ -4,7 +4,11 @@
 // at your option, any later version. See the LICENSE.txt file for the text of
 // the license.
 //-----------------------------------------------------------------------------
 // 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__
 //-----------------------------------------------------------------------------
 
 #ifndef LFDEMOD_H__
@@ -15,7 +19,7 @@ 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);
 int manrawdecode(uint8_t *BitStream, size_t *size);
 int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert);
 uint64_t Em410xDecode(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 IOdemodFSK(uint8_t *dest, size_t size);
 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 IOdemodFSK(uint8_t *dest, size_t size);
@@ -25,5 +29,10 @@ 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 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);
+uint32_t countFC(uint8_t *BitStream, size_t size);
+int getHiLo(uint8_t *BitStream, size_t size, int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo);
 
 #endif
 
 #endif
Impressum, Datenschutz