#include "crc.h" // for pyramid checksum maxim
#include "crc16.h" // for FDXB demod checksum
#include "loclass/cipherutils.h" // for decimating samples in getsamples
+#include "cmdlfem4x.h"// for em410x demod
uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
uint8_t g_debugMode=0;
size_t DemodBufferLen=0;
+//size_t g_demodStartIdx=0;
+//uint8_t g_demodClock=0;
+
static int CmdHelp(const char *Cmd);
//set the demod buffer with given array of binary (one bit per byte)
return 0;
}
-//by marshmellow
-//print 64 bit EM410x ID in multiple formats
-void printEM410x(uint32_t hi, uint64_t id)
-{
- if (id || hi){
- uint64_t iii=1;
- uint64_t id2lo=0;
- uint32_t ii=0;
- uint32_t i=0;
- for (ii=5; ii>0;ii--){
- for (i=0;i<8;i++){
- id2lo=(id2lo<<1LL) | ((id & (iii << (i+((ii-1)*8)))) >> (i+((ii-1)*8)));
- }
- }
- if (hi){
- //output 88 bit em id
- PrintAndLog("\nEM TAG ID : %06X%016" PRIX64, hi, id);
- } else{
- //output 40 bit em id
- PrintAndLog("\nEM TAG ID : %010" PRIX64, id);
- PrintAndLog("\nPossible de-scramble patterns");
- PrintAndLog("Unique TAG ID : %010" PRIX64, id2lo);
- PrintAndLog("HoneyWell IdentKey {");
- PrintAndLog("DEZ 8 : %08" PRIu64,id & 0xFFFFFF);
- PrintAndLog("DEZ 10 : %010" PRIu64,id & 0xFFFFFFFF);
- PrintAndLog("DEZ 5.5 : %05lld.%05" PRIu64,(id>>16LL) & 0xFFFF,(id & 0xFFFF));
- PrintAndLog("DEZ 3.5A : %03lld.%05" PRIu64,(id>>32ll),(id & 0xFFFF));
- PrintAndLog("DEZ 3.5B : %03lld.%05" PRIu64,(id & 0xFF000000) >> 24,(id & 0xFFFF));
- PrintAndLog("DEZ 3.5C : %03lld.%05" PRIu64,(id & 0xFF0000) >> 16,(id & 0xFFFF));
- PrintAndLog("DEZ 14/IK2 : %014" PRIu64,id);
- PrintAndLog("DEZ 15/IK3 : %015" PRIu64,id2lo);
- PrintAndLog("DEZ 20/ZK : %02" PRIu64 "%02" PRIu64 "%02" PRIu64 "%02" PRIu64 "%02" PRIu64 "%02" PRIu64 "%02" PRIu64 "%02" PRIu64 "%02" PRIu64 "%02" PRIu64,
- (id2lo & 0xf000000000) >> 36,
- (id2lo & 0x0f00000000) >> 32,
- (id2lo & 0x00f0000000) >> 28,
- (id2lo & 0x000f000000) >> 24,
- (id2lo & 0x0000f00000) >> 20,
- (id2lo & 0x00000f0000) >> 16,
- (id2lo & 0x000000f000) >> 12,
- (id2lo & 0x0000000f00) >> 8,
- (id2lo & 0x00000000f0) >> 4,
- (id2lo & 0x000000000f)
- );
- uint64_t paxton = (((id>>32) << 24) | (id & 0xffffff)) + 0x143e00;
- PrintAndLog("}\nOther : %05" PRIu64 "_%03" PRIu64 "_%08" PRIu64 "",(id&0xFFFF),((id>>16LL) & 0xFF),(id & 0xFFFFFF));
- PrintAndLog("Pattern Paxton : %" PRIu64 " [0x%" PRIX64 "]", paxton, paxton);
-
- uint32_t p1id = (id & 0xFFFFFF);
- uint8_t arr[32] = {0x00};
- int i =0;
- int j = 23;
- for (; i < 24; ++i, --j ){
- arr[i] = (p1id >> i) & 1;
- }
-
- uint32_t p1 = 0;
-
- p1 |= arr[23] << 21;
- p1 |= arr[22] << 23;
- p1 |= arr[21] << 20;
- p1 |= arr[20] << 22;
-
- p1 |= arr[19] << 18;
- p1 |= arr[18] << 16;
- p1 |= arr[17] << 19;
- p1 |= arr[16] << 17;
-
- p1 |= arr[15] << 13;
- p1 |= arr[14] << 15;
- p1 |= arr[13] << 12;
- p1 |= arr[12] << 14;
-
- p1 |= arr[11] << 6;
- p1 |= arr[10] << 2;
- p1 |= arr[9] << 7;
- p1 |= arr[8] << 1;
-
- p1 |= arr[7] << 0;
- p1 |= arr[6] << 8;
- p1 |= arr[5] << 11;
- p1 |= arr[4] << 3;
-
- p1 |= arr[3] << 10;
- p1 |= arr[2] << 4;
- p1 |= arr[1] << 5;
- p1 |= arr[0] << 9;
- PrintAndLog("Pattern 1 : %d [0x%X]", p1, p1);
-
- uint16_t sebury1 = id & 0xFFFF;
- uint8_t sebury2 = (id >> 16) & 0x7F;
- uint32_t sebury3 = id & 0x7FFFFF;
- PrintAndLog("Pattern Sebury : %d %d %d [0x%X 0x%X 0x%X]", sebury1, sebury2, sebury3, sebury1, sebury2, sebury3);
- }
- }
- return;
-}
-
-int AskEm410xDecode(bool verbose, uint32_t *hi, uint64_t *lo )
-{
- size_t idx = 0;
- size_t BitLen = DemodBufferLen;
- uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
- memcpy(BitStream, DemodBuffer, BitLen);
- if (Em410xDecode(BitStream, &BitLen, &idx, hi, lo)){
- //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();
- }
- if (verbose){
- PrintAndLog("EM410x pattern found: ");
- printEM410x(*hi, *lo);
- }
- return 1;
- }
- return 0;
-}
-
-int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo, bool verbose)
-{
- bool st = TRUE;
- if (!ASKDemod_ext(Cmd, FALSE, FALSE, 1, &st)) return 0;
- return AskEm410xDecode(verbose, hi, lo);
-}
-
-//by marshmellow
-//takes 3 arguments - clock, invert and maxErr as integers
-//attempts to demodulate ask while decoding manchester
-//prints binary found and saves in graphbuffer for further commands
-int CmdAskEM410xDemod(const char *Cmd)
-{
- char cmdp = param_getchar(Cmd, 0);
- if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') {
- PrintAndLog("Usage: data askem410xdemod [clock] <0|1> [maxError]");
- PrintAndLog(" [set clock as integer] optional, if not set, autodetect.");
- PrintAndLog(" <invert>, 1 for invert output");
- PrintAndLog(" [set maximum allowed errors], default = 100.");
- PrintAndLog("");
- PrintAndLog(" sample: data askem410xdemod = demod an EM410x Tag ID from GraphBuffer");
- PrintAndLog(" : data askem410xdemod 32 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/32");
- PrintAndLog(" : data askem410xdemod 32 1 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/32 and inverting data");
- PrintAndLog(" : data askem410xdemod 1 = demod an EM410x Tag ID from GraphBuffer while inverting data");
- PrintAndLog(" : data askem410xdemod 64 1 0 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/64 and inverting data and allowing 0 demod errors");
- return 0;
- }
- uint64_t lo = 0;
- uint32_t hi = 0;
- return AskEm410xDemod(Cmd, &hi, &lo, true);
-}
-
//by marshmellow
//Cmd Args: Clock, invert, maxErr, maxLen as integers and amplify as char == 'a'
// (amp may not be needed anymore)
PrintAndLog(" : data rawdemod am 64 1 0 = demod an ask/manchester tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors");
return 0;
}
- bool st = TRUE;
+ bool st = true;
if (Cmd[0]=='s')
- return ASKDemod_ext(Cmd++, TRUE, TRUE, 1, &st);
+ return ASKDemod_ext(Cmd++, true, true, 1, &st);
else if (Cmd[1] == 's')
- return ASKDemod_ext(Cmd+=2, TRUE, TRUE, 1, &st);
+ return ASKDemod_ext(Cmd+=2, true, true, 1, &st);
else
- return ASKDemod(Cmd, TRUE, TRUE, 1);
+ return ASKDemod(Cmd, true, true, 1);
}
//by marshmellow
sscanf(Cmd, "%i %i", &invert, &maxErr);
size=i;
- errCnt=manrawdecode(BitStream, &size, invert);
+ uint8_t alignPos = 0;
+ errCnt=manrawdecode(BitStream, &size, invert, &alignPos);
if (errCnt>=maxErr){
PrintAndLog("Too many errors: %d",errCnt);
return 0;
PrintAndLog(" : data rawdemod ab 0 64 1 0 0 a = demod an ask/biph tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors, and amp");
return 0;
}
- return ASKbiphaseDemod(Cmd, TRUE);
+ return ASKbiphaseDemod(Cmd, true);
}
+//could be split to a gProxII file
//by marshmellow
//attempts to demodulate and identify a G_Prox_II verex/chubb card
//WARNING: if it fails during some points it will destroy the DemodBuffer data
//if successful it will push askraw data back to demod buffer ready for emulation
int CmdG_Prox_II_Demod(const char *Cmd)
{
- if (!ASKbiphaseDemod(Cmd, FALSE)){
+ if (!ASKbiphaseDemod(Cmd, false)){
if (g_debugMode) PrintAndLog("Error gProxII: ASKbiphaseDemod failed 1st try");
return 0;
}
return 1;
}
+//could be moved to a viking file
//by marshmellow
//see ASKDemod for what args are accepted
int CmdVikingDemod(const char *Cmd)
PrintAndLog(" : data rawdemod ar 64 1 0 0 a = demod an ask tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors, and amp");
return 0;
}
- return ASKDemod(Cmd, TRUE, FALSE, 0);
+ return ASKDemod(Cmd, true, false, 0);
}
int AutoCorrelate(int window, bool SaveGrph, bool verbose)
return usage_data_autocorr();
int window = 4000; //set default
char grph=0;
- bool updateGrph = FALSE;
+ bool updateGrph = false;
sscanf(Cmd, "%i %c", &window, &grph);
if (window >= GraphTraceLen) {
GraphTraceLen);
return 0;
}
- if (grph == 'g') updateGrph=TRUE;
- return AutoCorrelate(window, updateGrph, TRUE);
+ if (grph == 'g') updateGrph=true;
+ return AutoCorrelate(window, updateGrph, true);
}
int CmdBitsamples(const char *Cmd)
PrintAndLog(" : data rawdemod fs 50 1 10 8 = demod an fsk2a RF/50 tag from GraphBuffer");
return 0;
}
- return FSKrawDemod(Cmd, TRUE);
-}
-
-//by marshmellow (based on existing demod + holiman's refactor)
-//HID Prox demod - FSK RF/50 with preamble of 00011101 (then manchester encoded)
-//print full HID Prox ID and some bit format details if found
-int CmdFSKdemodHID(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);
- if (BitLen==0) return 0;
- //get binary from fsk wave
- int idx = HIDdemodFSK(BitStream,&BitLen,&hi2,&hi,&lo);
- if (idx<0){
- if (g_debugMode){
- if (idx==-1){
- PrintAndLog("DEBUG: Just Noise Detected");
- } else if (idx == -2) {
- PrintAndLog("DEBUG: Error demoding fsk");
- } else if (idx == -3) {
- PrintAndLog("DEBUG: Preamble not found");
- } else if (idx == -4) {
- PrintAndLog("DEBUG: Error in Manchester data, SIZE: %d", BitLen);
- } else {
- PrintAndLog("DEBUG: Error demoding fsk %d", idx);
- }
- }
- return 0;
- }
- if (hi2==0 && hi==0 && lo==0) {
- if (g_debugMode) PrintAndLog("DEBUG: Error - no values found");
- 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);
- }
- else { //standard HID tags <38 bits
- uint8_t fmtLen = 0;
- uint32_t fc = 0;
- uint32_t cardnum = 0;
- if (((hi>>5)&1)==1){//if bit 38 is set then < 37 bit format is used
- uint32_t lo2=0;
- lo2=(((hi & 31) << 12) | (lo>>20)); //get bits 21-37 to check for format len bit
- uint8_t idx3 = 1;
- while(lo2>1){ //find last bit set to 1 (format len bit)
- lo2=lo2>>1;
- idx3++;
- }
- fmtLen =idx3+19;
- fc =0;
- cardnum=0;
- if(fmtLen==26){
- cardnum = (lo>>1)&0xFFFF;
- fc = (lo>>17)&0xFF;
- }
- if(fmtLen==34){
- cardnum = (lo>>1)&0xFFFF;
- fc= ((hi&1)<<15)|(lo>>17);
- }
- if(fmtLen==35){
- cardnum = (lo>>1)&0xFFFFF;
- fc = ((hi&1)<<11)|(lo>>21);
- }
- }
- else { //if bit 38 is not set then 37 bit format is used
- fmtLen = 37;
- fc = 0;
- cardnum = 0;
- if(fmtLen == 37){
- cardnum = (lo>>1)&0x7FFFF;
- fc = ((hi&0xF)<<12)|(lo>>20);
- }
- }
- 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,idx);
- if (g_debugMode){
- PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, BitLen);
- printDemodBuff();
- }
- return 1;
+ return FSKrawDemod(Cmd, true);
}
//by marshmellow
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)
-{
- uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
- size_t size = getFromGraphBuf(BitStream);
- if (size==0) return 0;
-
- //get binary from fsk wave
- int idx = AWIDdemodFSK(BitStream, &size);
- if (idx<=0){
- if (g_debugMode){
- if (idx == -1)
- PrintAndLog("DEBUG: Error - not enough samples");
- else if (idx == -2)
- PrintAndLog("DEBUG: Error - only noise found");
- else if (idx == -3)
- PrintAndLog("DEBUG: Error - problem during FSK demod");
- else if (idx == -4)
- PrintAndLog("DEBUG: Error - AWID preamble not found");
- else if (idx == -5)
- PrintAndLog("DEBUG: Error - Size not correct: %d", size);
- 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) 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: %08x%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: %08x%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: %08x%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
size_t BitLen = getFromGraphBuf(BitStream);
if (BitLen==0) return 0;
int errCnt=0;
- errCnt = nrzRawDemod(BitStream, &BitLen, &clk, &invert);
+ int clkStartIdx = 0;
+ errCnt = nrzRawDemod(BitStream, &BitLen, &clk, &invert, &clkStartIdx);
if (errCnt > maxErr){
if (g_debugMode) PrintAndLog("Too many errors found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt);
return 0;
PrintAndLog(" : data rawdemod nr 64 1 0 = demod a nrz/direct tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors");
return 0;
}
- return NRZrawDemod(Cmd, TRUE);
+ return NRZrawDemod(Cmd, true);
}
// by marshmellow
PrintAndLog(" : data rawdemod p1 64 1 0 = demod a psk1 tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors");
return 0;
}
- ans = PSKDemod(Cmd, TRUE);
+ ans = PSKDemod(Cmd, true);
//output
if (!ans){
if (g_debugMode) PrintAndLog("Error demoding: %d",ans);
PrintAndLog(" : data rawdemod p2 64 1 0 = demod a psk2 tag from GraphBuffer using a clock of RF/64, inverting output and allowing 0 demod errors");
return 0;
}
- ans=PSKDemod(Cmd, TRUE);
+ ans=PSKDemod(Cmd, true);
if (!ans){
if (g_debugMode) PrintAndLog("Error demoding: %d",ans);
return 0;
if (GraphBuffer[i] >= upThres && GraphBuffer[i] > lastValue)
{
lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it.
- GraphBuffer[i] = 1;
+ GraphBuffer[i] = 127;
}
// Apply second threshold to samples heading down
else if (GraphBuffer[i] <= downThres && GraphBuffer[i] < lastValue)
{
lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it.
- GraphBuffer[i] = -1;
+ GraphBuffer[i] = -127;
}
else
{
{
{"help", CmdHelp, 1, "This help"},
{"askedgedetect", CmdAskEdgeDetect, 1, "[threshold] Adjust Graph for manual ask demod using the length of sample differences to detect the edge of a wave (use 20-45, def:25)"},
- {"askem410xdemod", CmdAskEM410xDemod, 1, "[clock] [invert<0|1>] [maxErr] -- Demodulate an EM410x tag from GraphBuffer (args optional)"},
{"askgproxiidemod", CmdG_Prox_II_Demod, 1, "Demodulate a G Prox II tag from GraphBuffer"},
{"askvikingdemod", CmdVikingDemod, 1, "Demodulate a Viking tag from GraphBuffer"},
{"autocorr", CmdAutoCorr, 1, "[window length] [g] -- Autocorrelation over window - g to save back to GraphBuffer (overwrite)"},
{"dec", CmdDec, 1, "Decimate samples"},
{"detectclock", CmdDetectClockRate, 1, "[modulation] Detect clock rate of wave in GraphBuffer (options: 'a','f','n','p' for ask, fsk, nrz, psk respectively)"},
{"fdxbdemod", CmdFDXBdemodBI , 1, "Demodulate a FDX-B ISO11784/85 Biphase tag from GraphBuffer"},
- {"fskawiddemod", CmdFSKdemodAWID, 1, "Demodulate an AWID FSK tag from GraphBuffer"},
//{"fskfcdetect", CmdFSKfcDetect, 1, "Try to detect the Field Clock of an FSK wave"},
- {"fskhiddemod", CmdFSKdemodHID, 1, "Demodulate a HID FSK tag from GraphBuffer"},
{"fskiodemod", CmdFSKdemodIO, 1, "Demodulate an IO Prox FSK tag from GraphBuffer"},
{"fskpyramiddemod", CmdFSKdemodPyramid, 1, "Demodulate a Pyramid FSK tag from GraphBuffer"},
{"fskparadoxdemod", CmdFSKdemodParadox, 1, "Demodulate a Paradox FSK tag from GraphBuffer"},