From: iceman1001 Date: Tue, 16 Sep 2014 11:56:06 +0000 (+0200) Subject: LF t55xx and LF em4x commands now should manchester decode data. However t55xx... X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/b44e523300b3fbe0a5d9b3081aaa588be3095b14?hp=35147d51e3961db75a852368fffa31006da90199 LF t55xx and LF em4x commands now should manchester decode data. However t55xx can have other settings and different encodings. --- diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 6f8b0150..9e4b32cd 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -993,7 +993,7 @@ void __attribute__((noreturn)) AppMain(void) LED_B_OFF(); LED_A_OFF(); - // Init USB device` + // Init USB device usb_enable(); // The FPGA gets its clock from us from PCK0 output, so set that up. diff --git a/armsrc/mifaredesfire.c b/armsrc/mifaredesfire.c index d3b04fb0..14c6aa34 100644 --- a/armsrc/mifaredesfire.c +++ b/armsrc/mifaredesfire.c @@ -131,16 +131,15 @@ void MifareDesfireGetInformation(){ void MifareDES_Auth1(uint8_t mode, uint8_t algo, uint8_t keyno, uint8_t *datain){ uint8_t null_key_data[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - uint8_t new_key_data[8] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }; - int res; + //uint8_t new_key_data[8] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }; + int res = 0; - MifareDESFireKey default_key = mifare_desfire_des_key_new_with_version (null_key_data); + desfirekey_t default_key = Desfire_des_key_new_with_version (null_key_data); - res = mifare_desfire_select_application (tags[i], aid); + // res = Desfire_select_application (tags[i], aid); if (res < 0) { - freefare_perror (tags[i], "mifare_desfire_select_application"); - error = EXIT_FAILURE; - break; + print_result("default key: ", default_key->data, 24 ); + return; } return; diff --git a/armsrc/mifaredesfire.h b/armsrc/mifaredesfire.h index 5d490e2e..fc661f22 100644 --- a/armsrc/mifaredesfire.h +++ b/armsrc/mifaredesfire.h @@ -12,5 +12,4 @@ #include "mifareutil.h" #include "../include/common.h" - #endif diff --git a/client/cmddata.c b/client/cmddata.c index fa54d01a..72bc52e6 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -588,13 +588,16 @@ int CmdManchesterDemod(const char *Cmd) } } + PrintAndLog("Clock: %d", clock); + /* If we're not working with 1/0s, demod based off clock */ if (high != 1) { + PrintAndLog("Entering path A"); bit = 0; /* We assume the 1st bit is zero, it may not be * the case: this routine (I think) has an init problem. * Ed. - */ + */ for (; i < (int)(GraphTraceLen / clock); i++) { hithigh = 0; diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index e892b377..8448731e 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -524,7 +524,7 @@ int CmdHF14AMfDump(const char *Cmd) PrintAndLog("Got %d",size); - return; + return 0; if ( size > -1) cmdp = (char)48+size; @@ -1027,6 +1027,18 @@ int CmdHF14AMfNested(const char *Cmd) int CmdHF14AMfChk(const char *Cmd) { + if (strlen(Cmd)<3) { + PrintAndLog("Usage: hf mf chk |<*card memory> [t|d] [] []"); + PrintAndLog(" * - all sectors"); + PrintAndLog("card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, - 1K"); + PrintAndLog("d - write keys to binary file\n"); + PrintAndLog("t - write keys to emulator memory"); + PrintAndLog(" sample: hf mf chk 0 A 1234567890ab keys.dic"); + PrintAndLog(" hf mf chk *1 ? t"); + PrintAndLog(" hf mf chk *1 ? d"); + return 0; + } + FILE * f; char filename[256]={0}; char buf[13]; @@ -1070,16 +1082,6 @@ int CmdHF14AMfChk(const char *Cmd) num_to_bytes(defaultKeys[defaultKeyCounter], 6, (uint8_t*)(keyBlock + defaultKeyCounter * 6)); } - if (strlen(Cmd)<3) { - PrintAndLog("Usage: hf mf chk |<*card memory> [t] [] []"); - PrintAndLog(" * - all sectors"); - PrintAndLog("card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, - 1K"); - PrintAndLog("d - write keys to binary file\n"); - PrintAndLog(" sample: hf mf chk 0 A 1234567890ab keys.dic"); - PrintAndLog(" hf mf chk *1 ? t"); - return 0; - } - if (param_getchar(Cmd, 0)=='*') { blockNo = 3; switch(param_getchar(Cmd+1, 0)) { @@ -2090,49 +2092,56 @@ int GetCardSize() // NXP MIFARE Mini 0.3k - if ( (atqa && 0xff0f == 0x0004) && (sak == 0x09) ) return 0; + if ( ( (atqa & 0xff0f) == 0x0004) && (sak == 0x09) ) return 0; // MIFARE Classic 1K - if ( (atqa && 0xff0f == 0x0004) && (sak == 0x08) ) return 1; + if ( ((atqa & 0xff0f) == 0x0004) && (sak == 0x08) ) return 1; // MIFARE Classik 4K - if ( (atqa && 0xff0f == 0x0002) && (sak == 0x18) ) return 4; + if ( ((atqa & 0xff0f) == 0x0002) && (sak == 0x18) ) return 4; // SmartMX with MIFARE 1K emulation - if ( (atqa && 0xf0ff == 0x0004) ) return 1; + if ( ((atqa & 0xf0ff) == 0x0004) ) return 1; // SmartMX with MIFARE 4K emulation - if ( (atqa && 0xf0ff == 0x0002) ) return 4; + if ( ((atqa & 0xf0ff) == 0x0002) ) return 4; // Infineon MIFARE CLASSIC 1K - if ( (atqa && 0xffff == 0x0004) && (sak == 0x88) ) return 1; + if ( ((atqa & 0xffff) == 0x0004) && (sak == 0x88) ) return 1; // MFC 4K emulated by Nokia 6212 Classic - if ( (atqa && 0xffff == 0x0002) && (sak == 0x38) ) return 4; + if ( ((atqa & 0xffff) == 0x0002) && (sak == 0x38) ) return 4; // MFC 4K emulated by Nokia 6131 NFC - if ( (atqa && 0xffff == 0x0008) && (sak == 0x38) ) return 4; + if ( ((atqa & 0xffff) == 0x0008) && (sak == 0x38) ) return 4; + + PrintAndLog("BEFOOO 1K %02X", (atqa & 0xff0f)); + // MIFARE Plus (4 Byte UID or 4 Byte RID) // MIFARE Plus (7 Byte UID) if ( - (atqa && 0xffff == 0x0002) || - (atqa && 0xffff == 0x0004) || - (atqa && 0xffff == 0x0042) || - (atqa && 0xffff == 0x0044) + ((atqa & 0xffff) == 0x0002) | + ((atqa & 0xffff) == 0x0004) | + ((atqa & 0xffff) == 0x0042) | + ((atqa & 0xffff) == 0x0044) ) { switch(sak){ case 0x08: - case 0x10: + case 0x10: { //case 0x20: + PrintAndLog("2"); return 2; break; + } case 0x11: - case 0x18: + case 0x18:{ //case 0x20: + PrintAndLog("4"); return 4; break; + } } } diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index be31e1ea..3c46d3b1 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -21,6 +21,7 @@ #include "cmdlfem4x.h" #include "util.h" #include "data.h" +#define LF_TRACE_BUFF_SIZE 16000 char *global_em410xId; @@ -506,41 +507,47 @@ int CmdEM410xWrite(const char *Cmd) int CmdReadWord(const char *Cmd) { int Word = -1; //default to invalid word - UsbCommand c; + UsbCommand c; - sscanf(Cmd, "%d", &Word); + sscanf(Cmd, "%d", &Word); if ( (Word > 15) | (Word < 0) ) { - PrintAndLog("Word must be between 0 and 15"); - return 1; - } + PrintAndLog("Word must be between 0 and 15"); + return 1; + } - PrintAndLog("Reading word %d", Word); + PrintAndLog("Reading word %d", Word); - c.cmd = CMD_EM4X_READ_WORD; - c.d.asBytes[0] = 0x0; //Normal mode - c.arg[0] = 0; - c.arg[1] = Word; - c.arg[2] = 0; - SendCommand(&c); + c.cmd = CMD_EM4X_READ_WORD; + c.d.asBytes[0] = 0x0; //Normal mode + c.arg[0] = 0; + c.arg[1] = Word; + c.arg[2] = 0; + SendCommand(&c); WaitForResponse(CMD_ACK, NULL); - size_t bytelength = 4096; - uint8_t data[bytelength]; - memset(data, 0x00, bytelength); + uint8_t data[LF_TRACE_BUFF_SIZE]; + memset(data, 0x00, LF_TRACE_BUFF_SIZE); - GetFromBigBuf(data,bytelength,3560); //3560 -- should be offset.. + GetFromBigBuf(data,LF_TRACE_BUFF_SIZE,3560); //3560 -- should be offset.. WaitForResponseTimeout(CMD_ACK,NULL, 1500); - for (int j = 0; j < bytelength; j++) { + for (int j = 0; j < LF_TRACE_BUFF_SIZE; j++) { GraphBuffer[j] = ((int)data[j]) - 128; } - GraphTraceLen = bytelength; - RepaintGraphWindow(); - - manchester_decode(data, bytelength); - - free(data); + GraphTraceLen = LF_TRACE_BUFF_SIZE; + + // BiDirectional + //CmdDirectionalThreshold("70 -60"); + + // Askdemod + //Cmdaskdemod("1"); + + uint8_t bits[1000]; + uint8_t * bitstream = bits; + memset(bitstream, 0x00, sizeof(bits)); + + manchester_decode(GraphBuffer, LF_TRACE_BUFF_SIZE, bitstream); return 0; } @@ -548,42 +555,48 @@ int CmdReadWord(const char *Cmd) int CmdReadWordPWD(const char *Cmd) { int Word = -1; //default to invalid word - int Password = 0xFFFFFFFF; //default to blank password - UsbCommand c; - - sscanf(Cmd, "%d %x", &Word, &Password); - + int Password = 0xFFFFFFFF; //default to blank password + UsbCommand c; + + sscanf(Cmd, "%d %x", &Word, &Password); + if ( (Word > 15) | (Word < 0) ) { - PrintAndLog("Word must be between 0 and 15"); - return 1; - } - - PrintAndLog("Reading word %d with password %08X", Word, Password); + PrintAndLog("Word must be between 0 and 15"); + return 1; + } - c.cmd = CMD_EM4X_READ_WORD; - c.d.asBytes[0] = 0x1; //Password mode - c.arg[0] = 0; - c.arg[1] = Word; - c.arg[2] = Password; - SendCommand(&c); + PrintAndLog("Reading word %d with password %08X", Word, Password); + + c.cmd = CMD_EM4X_READ_WORD; + c.d.asBytes[0] = 0x1; //Password mode + c.arg[0] = 0; + c.arg[1] = Word; + c.arg[2] = Password; + SendCommand(&c); WaitForResponse(CMD_ACK, NULL); + + uint8_t data[LF_TRACE_BUFF_SIZE]; + memset(data, 0x00, LF_TRACE_BUFF_SIZE); - size_t bytelength = 4096; - uint8_t data[bytelength]; - memset(data, 0x00, bytelength); - - GetFromBigBuf(data,bytelength,3560); //3560 -- should be offset.. + GetFromBigBuf(data,LF_TRACE_BUFF_SIZE,3560); //3560 -- should be offset.. WaitForResponseTimeout(CMD_ACK,NULL, 1500); - for (int j = 0; j < bytelength; j++) { + for (int j = 0; j < LF_TRACE_BUFF_SIZE; j++) { GraphBuffer[j] = ((int)data[j]) - 128; } - GraphTraceLen = bytelength; - RepaintGraphWindow(); + GraphTraceLen = LF_TRACE_BUFF_SIZE; - manchester_decode(data, bytelength); - - free(data); + // BiDirectional + //CmdDirectionalThreshold("70 -60"); + + // Askdemod + //Cmdaskdemod("1"); + + uint8_t bits[1000]; + uint8_t * bitstream = bits; + memset(bitstream, 0x00, sizeof(bits)); + + manchester_decode(GraphBuffer, LF_TRACE_BUFF_SIZE, bitstream); return 0; } @@ -636,8 +649,6 @@ int CmdWriteWordPWD(const char *Cmd) return 0; } - - static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 5a464ddb..a002bf34 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -29,25 +29,25 @@ int CmdReadBlk(const char *Cmd) { //default to invalid block int Block = -1; - UsbCommand c; + UsbCommand c; - sscanf(Cmd, "%d", &Block); + sscanf(Cmd, "%d", &Block); if ((Block > 7) | (Block < 0)) { - PrintAndLog("Block must be between 0 and 7"); - return 1; - } + PrintAndLog("Block must be between 0 and 7"); + return 1; + } PrintAndLog(" Reading page 0 block : %d", Block); // this command fills up BigBuff // - c.cmd = CMD_T55XX_READ_BLOCK; + c.cmd = CMD_T55XX_READ_BLOCK; c.d.asBytes[0] = 0x00; - c.arg[0] = 0; - c.arg[1] = Block; - c.arg[2] = 0; - SendCommand(&c); + c.arg[0] = 0; + c.arg[1] = Block; + c.arg[2] = 0; + SendCommand(&c); WaitForResponse(CMD_ACK, NULL); uint8_t data[LF_TRACE_BUFF_SIZE]; @@ -62,18 +62,17 @@ int CmdReadBlk(const char *Cmd) GraphTraceLen = LF_TRACE_BUFF_SIZE; // BiDirectional - CmdDirectionalThreshold("70 -60"); + //CmdDirectionalThreshold("70 60"); // Askdemod - Cmdaskdemod("1"); + //Cmdaskdemod("1"); uint8_t bits[1000]; uint8_t * bitstream = bits; - uint8_t len = 0; - len = manchester_decode(data, LF_TRACE_BUFF_SIZE, bitstream); - if ( len > 0 ) - PrintPaddedManchester(bitstream, len, 32); - + memset(bitstream, 0x00, sizeof(bits)); + + manchester_decode(GraphBuffer, LF_TRACE_BUFF_SIZE, bitstream); + return 0; } @@ -81,24 +80,24 @@ int CmdReadBlk(const char *Cmd) int CmdReadBlkPWD(const char *Cmd) { int Block = -1; //default to invalid block - int Password = 0xFFFFFFFF; //default to blank Block 7 - UsbCommand c; + int Password = 0xFFFFFFFF; //default to blank Block 7 + UsbCommand c; - sscanf(Cmd, "%d %x", &Block, &Password); + sscanf(Cmd, "%d %x", &Block, &Password); if ((Block > 7) | (Block < 0)) { - PrintAndLog("Block must be between 0 and 7"); - return 1; - } + PrintAndLog("Block must be between 0 and 7"); + return 1; + } PrintAndLog("Reading page 0 block %d pwd %08X", Block, Password); - c.cmd = CMD_T55XX_READ_BLOCK; - c.d.asBytes[0] = 0x1; //Password mode - c.arg[0] = 0; - c.arg[1] = Block; - c.arg[2] = Password; - SendCommand(&c); + c.cmd = CMD_T55XX_READ_BLOCK; + c.d.asBytes[0] = 0x1; //Password mode + c.arg[0] = 0; + c.arg[1] = Block; + c.arg[2] = Password; + SendCommand(&c); WaitForResponse(CMD_ACK, NULL); uint8_t data[LF_TRACE_BUFF_SIZE]; @@ -113,17 +112,16 @@ int CmdReadBlkPWD(const char *Cmd) GraphTraceLen = LF_TRACE_BUFF_SIZE; // BiDirectional - CmdDirectionalThreshold("70 -60"); + //CmdDirectionalThreshold("70 -60"); // Askdemod - Cmdaskdemod("1"); + //Cmdaskdemod("1"); uint8_t bits[1000]; - uint8_t len = 0; - len = manchester_decode(data, LF_TRACE_BUFF_SIZE, bits); - if ( len > 0 ) - PrintPaddedManchester(bits, len, 32); - + uint8_t * bitstream = bits; + memset(bitstream, 0x00, sizeof(bits)); + + manchester_decode(GraphBuffer, LF_TRACE_BUFF_SIZE, bitstream); return 0; } @@ -197,28 +195,29 @@ int CmdReadTrace(const char *Cmd) GraphTraceLen = LF_TRACE_BUFF_SIZE; // BiDirectional - CmdDirectionalThreshold("70 -60"); + //CmdDirectionalThreshold("70 -60"); // Askdemod - Cmdaskdemod("1"); + //Cmdaskdemod("1"); + - uint8_t bits[512]; - uint8_t len = 0; - len = manchester_decode(data,LF_TRACE_BUFF_SIZE,bits); - if ( len > 0 ) - PrintPaddedManchester(bits, len, 64); + uint8_t bits[1000]; + uint8_t * bitstream = bits; + memset(bitstream, 0x00, sizeof(bits)); + manchester_decode(GraphBuffer, LF_TRACE_BUFF_SIZE, bitstream); + return 0; } static command_t CommandTable[] = { - {"help", CmdHelp, 1, "This help"}, - {"readblock", CmdReadBlk, 1, " -- Read T55xx block data (page 0)"}, - {"readblockPWD", CmdReadBlkPWD, 1, " -- Read T55xx block data in password mode(page 0)"}, - {"writeblock", CmdWriteBlk, 1, " -- Write T55xx block data (page 0)"}, - {"writeblockPWD", CmdWriteBlkPWD, 1, " -- Write T55xx block data in password mode(page 0)"}, - {"readtrace", CmdReadTrace, 1, "Read T55xx traceability data (page 1)"}, + {"help", CmdHelp, 1, "This help"}, + {"rd", CmdReadBlk, 0, " -- Read T55xx block data (page 0)"}, + {"rdPWD", CmdReadBlkPWD, 0, " -- Read T55xx block data in password mode(page 0)"}, + {"wr", CmdWriteBlk, 0, " -- Write T55xx block data (page 0)"}, + {"wrPWD", CmdWriteBlkPWD, 0, " -- Write T55xx block data in password mode(page 0)"}, + {"trace", CmdReadTrace, 0, "Read T55xx traceability data (page 1)"}, {NULL, NULL, 0, NULL} }; diff --git a/client/ui.c b/client/ui.c index 6486d524..4f1b5d85 100644 --- a/client/ui.c +++ b/client/ui.c @@ -92,24 +92,18 @@ void SetLogFilename(char *fn) } -uint8_t manchester_decode(const uint8_t * data, const size_t len, uint8_t * dataout){ +int manchester_decode(const int * data, const size_t len, uint8_t * dataout){ - size_t bytelength = len; - - uint8_t bitStream[bytelength]; - memset(bitStream, 0x00, bytelength); - - int clock,high, low, bit, hithigh, hitlow, first, bit2idx, lastpeak; - int i,invert, lastval; - int bitidx = 0; - int lc = 0; - int warnings = 0; + int bitlength = 0; + int i, clock, high, low, startindex; + low = startindex = 0; high = 1; - low = bit = bit2idx = lastpeak = invert = lastval = hithigh = hitlow = first = 0; - clock = 0xFFFF; + uint8_t bitStream[len]; + memset(bitStream, 0x00, len); + /* Detect high and lows */ - for (i = 0; i < bytelength; i++) { + for (i = 0; i < len; i++) { if (data[i] > high) high = data[i]; else if (data[i] < low) @@ -117,47 +111,106 @@ uint8_t manchester_decode(const uint8_t * data, const size_t len, uint8_t * data } /* get clock */ - int j=0; - for (i = 1; i < bytelength; i++) { + clock = GetT55x7Clock( data, len, high ); + startindex = DetectFirstTransition(data, len, high, low); + + PrintAndLog(" Clock : %d", clock); + PrintAndLog(" startindex : %d", startindex); + + if (high != 1) + bitlength = ManchesterConvertFrom255(data, len, bitStream, high, low, clock, startindex); + else + bitlength= ManchesterConvertFrom1(data, len, bitStream, clock, startindex); + + if ( bitlength > 0 ){ + PrintPaddedManchester(bitStream, bitlength, clock); + } + + memcpy(dataout, bitStream, bitlength); + + free(bitStream); + return bitlength; +} + + int GetT55x7Clock( const int * data, const size_t len, int peak ){ + + int i,lastpeak,clock; + clock = 0xFFFF; + lastpeak = 0; + + /* Detect peak if we don't have one */ + if (!peak) { + for (i = 0; i < len; ++i) { + if (data[i] > peak) { + peak = data[i]; + } + } + } + + for (i = 1; i < len; ++i) { /* if this is the beginning of a peak */ - j = i-1; - if ( data[j] != data[i] && - data[i] == high) - { + if ( data[i-1] != data[i] && data[i] == peak) { /* find lowest difference between peaks */ if (lastpeak && i - lastpeak < clock) clock = i - lastpeak; lastpeak = i; } } - - int tolerance = clock/4; - PrintAndLog(" Detected clock: %d",clock); - - /* Detect first transition */ - /* Lo-Hi (arbitrary) */ - /* skip to the first high */ - for (i= 0; i < bytelength; i++) + //return clock; + //defaults clock to precise values. + switch(clock){ + case 8: + case 16: + case 32: + case 40: + case 50: + case 64: + case 100: + case 128: + return clock; + break; + default: break; + } + return 32; + } + + int DetectFirstTransition(const int * data, const size_t len, int high, int low){ + + int i, retval; + retval = 0; + /* + Detect first transition Lo-Hi (arbitrary) + skip to the first high + */ + for (i = 0; i < len; ++i) if (data[i] == high) break; /* now look for the first low */ - for (; i < bytelength; i++) { + for (; i < len; ++i) { if (data[i] == low) { - lastval = i; + retval = i; break; } } - - /* If we're not working with 1/0s, demod based off clock */ - if (high != 1) + return retval; + } + + int ManchesterConvertFrom255(const int * data, const size_t len, uint8_t * dataout, int high, int low, int clock, int startIndex){ + + int i, j, hithigh, hitlow, first, bit, bitIndex; + i = startIndex; + bitIndex = 0; + + /* + * We assume the 1st bit is zero, it may not be + * the case: this routine (I think) has an init problem. + * Ed. + */ + bit = 0; + + for (; i < (int)(len / clock); i++) { - bit = 0; /* We assume the 1st bit is zero, it may not be - * the case: this routine (I think) has an init problem. - * Ed. - */ - for (; i < (int)(bytelength / clock); i++) - { hithigh = 0; hitlow = 0; first = 1; @@ -179,94 +232,125 @@ uint8_t manchester_decode(const uint8_t * data, const size_t len, uint8_t * data if (hithigh && hitlow) break; - } + } - /* If we didn't hit both high and low peaks, we had a bit transition */ - if (!hithigh || !hitlow) + /* If we didn't hit both high and low peaks, we had a bit transition */ + if (!hithigh || !hitlow) bit ^= 1; - bitStream[bit2idx++] = bit ^ invert; - } + dataout[bitIndex++] = bit; } - /* standard 1/0 bitstream */ - else { - /* Then detect duration between 2 successive transitions */ - for (bitidx = 1; i < bytelength; i++) { - - if (data[i-1] != data[i]) { - lc = i-lastval; - lastval = i; - - // Error check: if bitidx becomes too large, we do not - // have a Manchester encoded bitstream or the clock is really - // wrong! - if (bitidx > (bytelength*2/clock+8) ) { - PrintAndLog("Error: the clock you gave is probably wrong, aborting."); - return 0; - } - // Then switch depending on lc length: - // Tolerance is 1/4 of clock rate (arbitrary) - if (abs(lc-clock/2) < tolerance) { - // Short pulse : either "1" or "0" - bitStream[bitidx++] = data[i-1]; - } else if (abs(lc-clock) < tolerance) { - // Long pulse: either "11" or "00" - bitStream[bitidx++] = data[i-1]; - bitStream[bitidx++] = data[i-1]; - } else { - // Error - warnings++; - PrintAndLog("Warning: Manchester decode error for pulse width detection."); - if (warnings > 10) { - PrintAndLog("Error: too many detection errors, aborting."); - return 0; - } + return bitIndex; + } + + int ManchesterConvertFrom1(const int * data, const size_t len, uint8_t * dataout, int clock, int startIndex){ + + int i,j, bitindex, lc, tolerance, warnings; + warnings = 0; + int upperlimit = len*2/clock+8; + i = startIndex; + j = 0; + tolerance = clock/4; + uint8_t decodedArr[len]; + + /* Then detect duration between 2 successive transitions */ + for (bitindex = 1; i < len; i++) { + + if (data[i-1] != data[i]) { + lc = i - startIndex; + startIndex = i; + + // Error check: if bitindex becomes too large, we do not + // have a Manchester encoded bitstream or the clock is really wrong! + if (bitindex > upperlimit ) { + PrintAndLog("Error: the clock you gave is probably wrong, aborting."); + return 0; + } + // Then switch depending on lc length: + // Tolerance is 1/4 of clock rate (arbitrary) + if (abs((lc-clock)/2) < tolerance) { + // Short pulse : either "1" or "0" + decodedArr[bitindex++] = data[i-1]; + } else if (abs(lc-clock) < tolerance) { + // Long pulse: either "11" or "00" + decodedArr[bitindex++] = data[i-1]; + decodedArr[bitindex++] = data[i-1]; + } else { + ++warnings; + PrintAndLog("Warning: Manchester decode error for pulse width detection."); + if (warnings > 10) { + PrintAndLog("Error: too many detection errors, aborting."); + return 0; } } } } - // At this stage, we now have a bitstream of "01" ("1") or "10" ("0"), parse it into final decoded bitstream - // Actually, we overwrite BitStream with the new decoded bitstream, we just need to be careful - // to stop output at the final bitidx2 value, not bitidx - for (i = 0; i < bitidx; i += 2) { - if ((bitStream[i] == 0) && (bitStream[i+1] == 1)) { - bitStream[bit2idx++] = 1 ^ invert; - } - else if ((bitStream[i] == 1) && (bitStream[i+1] == 0)) { - bitStream[bit2idx++] = 0 ^ invert; - } - else { - // We cannot end up in this state, this means we are unsynchronized, - // move up 1 bit: + + /* + * We have a decodedArr of "01" ("1") or "10" ("0") + * parse it into final decoded dataout + */ + for (i = 0; i < bitindex; i += 2) { + + if ((decodedArr[i] == 0) && (decodedArr[i+1] == 1)) { + dataout[j++] = 1; + } else if ((decodedArr[i] == 1) && (decodedArr[i+1] == 0)) { + dataout[j++] = 0; + } else { i++; warnings++; PrintAndLog("Unsynchronized, resync..."); - if (warnings > 10) { + PrintAndLog("(too many of those messages mean the stream is not Manchester encoded)"); + + if (warnings > 10) { PrintAndLog("Error: too many decode errors, aborting."); return 0; } } } + + PrintAndLog("%s", sprint_hex(dataout, j)); + return j; + } + + void ManchesterDiffDecodedString(const uint8_t* bitstream, size_t len, uint8_t invert){ + /* + * We have a bitstream of "01" ("1") or "10" ("0") + * parse it into final decoded bitstream + */ + int i, j, warnings; + uint8_t decodedArr[(len/2)+1]; - // PrintAndLog(" Manchester decoded bitstream : %d bits", (bit2idx-16)); - // uint8_t mod = (bit2idx-16) % blocksize; - // uint8_t div = (bit2idx-16) / blocksize; - - // // Now output the bitstream to the scrollback by line of 16 bits - // for (i = 0; i < div*blocksize; i+=blocksize) { - // PrintAndLog(" %s", sprint_bin(bitStream+i,blocksize) ); - // } - // if ( mod > 0 ){ - // PrintAndLog(" %s", sprint_bin(bitStream+i, mod) ); - // } + j = warnings = 0; - if ( bit2idx > 0 ) - memcpy(dataout, bitStream, bit2idx); + uint8_t lastbit = 0; - free(bitStream); - return bit2idx; -} + for (i = 0; i < len; i += 2) { + + uint8_t first = bitstream[i]; + uint8_t second = bitstream[i+1]; + if ( first == second ) { + ++i; + ++warnings; + if (warnings > 10) { + PrintAndLog("Error: too many decode errors, aborting."); + return; + } + } + else if ( lastbit != first ) { + decodedArr[j++] = 0 ^ invert; + } + else { + decodedArr[j++] = 1 ^ invert; + } + lastbit = second; + } + + PrintAndLog("%s", sprint_hex(decodedArr, j)); +} + + void PrintPaddedManchester( uint8_t* bitStream, size_t len, size_t blocksize){ PrintAndLog(" Manchester decoded bitstream : %d bits", len); diff --git a/client/ui.h b/client/ui.h index 2f2ed189..f599ef3c 100644 --- a/client/ui.h +++ b/client/ui.h @@ -25,6 +25,11 @@ extern int PlotGridX, PlotGridY, PlotGridXdefault, PlotGridYdefault; extern int offline; extern int flushAfterWrite; //buzzy -uint8_t manchester_decode(const uint8_t * data, const size_t len, uint8_t * dataout); +int manchester_decode(const int * data, const size_t len, uint8_t * dataout); +int GetT55x7Clock( const int * data, const size_t len, int high ); +int DetectFirstTransition(const int * data, const size_t len, int high, int low); void PrintPaddedManchester( uint8_t * bitStream, size_t len, size_t blocksize); +void ManchesterDiffDecodedString( const uint8_t *bitStream, size_t len, uint8_t invert ); +int ManchesterConvertFrom255(const int * data, const size_t len, uint8_t * dataout, int high, int low, int clock, int startIndex); +int ManchesterConvertFrom1(const int * data, const size_t len, uint8_t * dataout, int clock, int startIndex); #endif