From 1fbf89561686188fa869a10e1251406740238234 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Mon, 23 Mar 2015 16:29:50 -0400 Subject: [PATCH] lf updates applies icemans full ata55x7 read/write settings adds checksum to ioprox (thanks to iceman) adds silent mode for lf read and getSamples fix lf em em410xwatch and lf em410xspoof improve data rawdemod ar - for biphase demods improve detectclock a for strong antennas --- armsrc/appmain.c | 2 +- armsrc/lfops.c | 12 +-- armsrc/lfsampling.c | 12 +-- armsrc/lfsampling.h | 2 +- client/cmddata.c | 117 ++++++++++++++++++------------ client/cmddata.h | 2 + client/cmdlf.c | 11 ++- client/cmdlfem4x.c | 15 ++-- client/cmdlft55xx.c | 6 +- client/scripts/test_t55x7_psk.lua | 65 ++++++++++------- common/lfdemod.c | 75 ++++++++++--------- 11 files changed, 184 insertions(+), 135 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 3e670f0b..6e0b58b3 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -648,7 +648,7 @@ void UsbPacketReceived(uint8_t *packet, int len) setSamplingConfig((sample_config *) c->d.asBytes); break; case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K: - cmd_send(CMD_ACK,SampleLF(),0,0,0,0); + cmd_send(CMD_ACK,SampleLF(c->arg[0]),0,0,0,0); break; case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K: ModThenAcquireRawAdcSamples125k(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes); diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 94cfafdf..7bbc739d 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -1054,15 +1054,11 @@ void T55xxWriteBit(int bit) // Write one card block in page 0, no lock void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode) { - uint32_t i; - - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + uint32_t i = 0; - // Give it a bit of time for the resonant antenna to settle. - // And for the tag to fully power up - //SpinDelay(150); + // Set up FPGA, 125kHz + // Wait for config.. (192+8190xPOW)x8 == 67ms + LFSetupFPGAForADC(0, true); // Now start writting FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 6094bd34..120c0801 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -224,21 +224,21 @@ uint32_t DoAcquisition_config( bool silent) ,silent); } -uint32_t ReadLF(bool activeField) +uint32_t ReadLF(bool activeField, bool silent) { - printConfig(); + if (!silent) printConfig(); LFSetupFPGAForADC(config.divisor, activeField); // Now call the acquisition routine - return DoAcquisition_config(false); + return DoAcquisition_config(silent); } /** * Initializes the FPGA for reader-mode (field on), and acquires the samples. * @return number of bits sampled **/ -uint32_t SampleLF() +uint32_t SampleLF(bool printCfg) { - return ReadLF(true); + return ReadLF(true, printCfg); } /** * Initializes the FPGA for snoop-mode (field off), and acquires the samples. @@ -247,5 +247,5 @@ uint32_t SampleLF() uint32_t SnoopLF() { - return ReadLF(false); + return ReadLF(false, true); } diff --git a/armsrc/lfsampling.h b/armsrc/lfsampling.h index 9ab458f8..6c671ec8 100644 --- a/armsrc/lfsampling.h +++ b/armsrc/lfsampling.h @@ -5,7 +5,7 @@ * Initializes the FPGA for reader-mode (field on), and acquires the samples. * @return number of bits sampled **/ -uint32_t SampleLF(); +uint32_t SampleLF(bool silent); /** * Initializes the FPGA for snoop-mode (field off), and acquires the samples. diff --git a/client/cmddata.c b/client/cmddata.c index 8017d169..a69b5ca7 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -558,6 +558,7 @@ int CmdBiphaseDecodeRaw(const char *Cmd) PrintAndLog("Usage: data biphaserawdecode [offset] [invert] [maxErr]"); PrintAndLog(" Converts 10 or 01 to 1 and 11 or 00 to 0"); PrintAndLog(" --must have binary sequence in demodbuffer (run data askrawdemod first)"); + PrintAndLog(" --invert for Conditional Dephase Encoding (CDP) AKA Differential Manchester"); PrintAndLog(""); PrintAndLog(" [offset <0|1>], set to 0 not to adjust start position or to 1 to adjust decode start position"); PrintAndLog(" [invert <0|1>], set to 1 to invert output"); @@ -720,6 +721,8 @@ int Cmdaskbiphdemod(const char *Cmd) PrintAndLog(" NOTE: can be entered as first, second or last argument"); PrintAndLog(" NOTE: any other arg must have previous args set to work"); PrintAndLog(""); + PrintAndLog(" NOTE: --invert for Conditional Dephase Encoding (CDP) AKA Differential Manchester"); + PrintAndLog(""); PrintAndLog(" sample: data rawdemod ab = demod an ask/biph tag from GraphBuffer"); PrintAndLog(" : data rawdemod ab a = demod an ask/biph tag from GraphBuffer, amplified"); PrintAndLog(" : data rawdemod ab 1 32 = demod an ask/biph tag from GraphBuffer using an offset of 1 and a clock of RF/32"); @@ -1420,7 +1423,20 @@ int CmdFSKdemodIO(const char *Cmd) uint8_t version = bytebits_to_byte(BitStream+idx+27,8); //14,4 uint8_t facilitycode = bytebits_to_byte(BitStream+idx+18,8) ; uint16_t number = (bytebits_to_byte(BitStream+idx+36,8)<<8)|(bytebits_to_byte(BitStream+idx+45,8)); //36,9 - PrintAndLog("IO Prox XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2); + uint8_t crc = bytebits_to_byte(BitStream+idx+54,8); + uint16_t calccrc = 0; + + for (uint8_t i=1; i<6; ++i){ + calccrc += bytebits_to_byte(BitStream+idx+9*i,8); + PrintAndLog("%d", calccrc); + } + calccrc &= 0xff; + calccrc = 0xff - calccrc; + + char *crcStr = (crc == calccrc) ? "crc ok": "!crc"; + + PrintAndLog("IO Prox XSF(%02d)%02x:%05d (%08x%08x) [%02x %s]",version,facilitycode,number,code,code2, crc, crcStr); + //PrintAndLog("IO Prox XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2); setDemodBuf(BitStream,64,idx); if (g_debugMode){ PrintAndLog("DEBUG: idx: %d, Len: %d, Printing demod buffer:",idx,64); @@ -2056,7 +2072,7 @@ int CmdRawDemod(const char *Cmd) PrintAndLog(" as 'h', prints the help for the specific modulation"); PrintAndLog(" see specific modulation help for optional parameters"); PrintAndLog(""); - PrintAndLog(" sample: data rawdemod fs h = print help for ask/raw demod"); + PrintAndLog(" sample: data rawdemod fs h = print help specific to fsk demod"); PrintAndLog(" : data rawdemod fs = demod GraphBuffer using: fsk - autodetect"); PrintAndLog(" : data rawdemod ab = demod GraphBuffer using: ask/biphase - autodetect"); PrintAndLog(" : data rawdemod am = demod GraphBuffer using: ask/manchester - autodetect"); @@ -2185,57 +2201,64 @@ uint8_t getByte(uint8_t bits_per_sample, BitstreamOut* b) return val; } -int CmdSamples(const char *Cmd) +int getSamples(const char *Cmd, bool silent) { - //If we get all but the last byte in bigbuf, - // we don't have to worry about remaining trash - // in the last byte in case the bits-per-sample - // does not line up on byte boundaries - uint8_t got[BIGBUF_SIZE-1] = { 0 }; + //If we get all but the last byte in bigbuf, + // we don't have to worry about remaining trash + // in the last byte in case the bits-per-sample + // does not line up on byte boundaries - int n = strtol(Cmd, NULL, 0); - if (n == 0) - n = sizeof(got); + uint8_t got[BIGBUF_SIZE-1] = { 0 }; - if (n > sizeof(got)) - n = sizeof(got); + int n = strtol(Cmd, NULL, 0); - PrintAndLog("Reading %d bytes from device memory\n", n); - GetFromBigBuf(got,n,0); - PrintAndLog("Data fetched"); - UsbCommand response; - WaitForResponse(CMD_ACK, &response); - uint8_t bits_per_sample = 8; + if (n == 0) + n = sizeof(got); - //Old devices without this feature would send 0 at arg[0] - if(response.arg[0] > 0) - { - sample_config *sc = (sample_config *) response.d.asBytes; - PrintAndLog("Samples @ %d bits/smpl, decimation 1:%d ", sc->bits_per_sample - , sc->decimation); - bits_per_sample = sc->bits_per_sample; - } - if(bits_per_sample < 8) - { - PrintAndLog("Unpacking..."); - BitstreamOut bout = { got, bits_per_sample * n, 0}; - int j =0; - for (j = 0; j * bits_per_sample < n * 8 && j < sizeof(GraphBuffer); j++) { - uint8_t sample = getByte(bits_per_sample, &bout); - GraphBuffer[j] = ((int) sample )- 128; - } - GraphTraceLen = j; - PrintAndLog("Unpacked %d samples" , j ); - }else - { - for (int j = 0; j < n; j++) { - GraphBuffer[j] = ((int)got[j]) - 128; - } - GraphTraceLen = n; - } + if (n > sizeof(got)) + n = sizeof(got); - RepaintGraphWindow(); - return 0; + PrintAndLog("Reading %d bytes from device memory\n", n); + GetFromBigBuf(got,n,0); + PrintAndLog("Data fetched"); + UsbCommand response; + WaitForResponse(CMD_ACK, &response); + uint8_t bits_per_sample = 8; + + //Old devices without this feature would send 0 at arg[0] + if(response.arg[0] > 0) + { + sample_config *sc = (sample_config *) response.d.asBytes; + PrintAndLog("Samples @ %d bits/smpl, decimation 1:%d ", sc->bits_per_sample + , sc->decimation); + bits_per_sample = sc->bits_per_sample; + } + if(bits_per_sample < 8) + { + PrintAndLog("Unpacking..."); + BitstreamOut bout = { got, bits_per_sample * n, 0}; + int j =0; + for (j = 0; j * bits_per_sample < n * 8 && j < sizeof(GraphBuffer); j++) { + uint8_t sample = getByte(bits_per_sample, &bout); + GraphBuffer[j] = ((int) sample )- 128; + } + GraphTraceLen = j; + PrintAndLog("Unpacked %d samples" , j ); + }else + { + for (int j = 0; j < n; j++) { + GraphBuffer[j] = ((int)got[j]) - 128; + } + GraphTraceLen = n; + } + + RepaintGraphWindow(); + return 0; +} + +int CmdSamples(const char *Cmd) +{ + return getSamples(Cmd, false); } int CmdTuneSamples(const char *Cmd) diff --git a/client/cmddata.h b/client/cmddata.h index 052bce06..f6b4b950 100644 --- a/client/cmddata.h +++ b/client/cmddata.h @@ -71,6 +71,8 @@ int FSKrawDemod(const char *Cmd, bool verbose); int PSKDemod(const char *Cmd, bool verbose); int NRZrawDemod(const char *Cmd, bool verbose); void printEM410x(uint32_t hi, uint64_t id); +int getSamples(const char *Cmd, bool silent); + #define MAX_DEMOD_BUF_LEN (1024*128) extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN]; diff --git a/client/cmdlf.c b/client/cmdlf.c index 4a1ee519..0fab2adf 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -362,6 +362,7 @@ int usage_lf_read() PrintAndLog("Usage: lf read"); PrintAndLog("Options: "); PrintAndLog(" h This help"); + PrintAndLog(" s silent run no printout"); PrintAndLog("This function takes no arguments. "); PrintAndLog("Use 'lf config' to set parameters."); return 0; @@ -481,13 +482,15 @@ int CmdLFSetConfig(const char *Cmd) int CmdLFRead(const char *Cmd) { - uint8_t cmdp =0; - if(param_getchar(Cmd, cmdp) == 'h') + uint8_t cmdp = 0; + bool arg1 = false; + if (param_getchar(Cmd, cmdp) == 'h') { return usage_lf_read(); } + if (param_getchar(Cmd, cmdp) == 's') arg1 = true; //suppress print //And ship it to device - UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K}; + UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, {arg1,0,0}}; SendCommand(&c); WaitForResponse(CMD_ACK,NULL); return 0; @@ -1137,7 +1140,7 @@ static command_t CommandTable[] = {"io", CmdLFIO, 1, "{ ioProx tags... }"}, {"indalademod", CmdIndalaDemod, 1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"}, {"indalaclone", CmdIndalaClone, 0, " ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"}, - {"read", CmdLFRead, 0, "Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"}, + {"read", CmdLFRead, 0, "['s' silent] Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"}, {"search", CmdLFfind, 1, "[offline] ['u'] Read and Search for valid known tag (in offline mode it you can load first then search) - 'u' to search for unknown tags"}, {"sim", CmdLFSim, 0, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"}, {"simask", CmdLFaskSim, 0, "[clock] [invert <1|0>] [manchester/raw <'m'|'r'>] [msg separator 's'] [d ] -- Simulate LF ASK tag from demodbuffer or input"}, diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index 5faf4801..b915aa5a 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -53,8 +53,9 @@ int CmdEM410xRead(const char *Cmd) PrintAndLog ("EM410x XL pattern found"); return 0; } - char id[11] = {0x00}; - sprintf(id, "%010x", lo); + char id[12] = {0x00}; + sprintf(id, "%010llx",lo); + global_em410xId = id; return 1; } @@ -148,8 +149,8 @@ int CmdEM410xWatch(const char *Cmd) break; } - CmdLFRead(""); - CmdSamples("6000"); + CmdLFRead("s"); + getSamples("8192",true); //capture enough to get 2 full messages } while (!CmdEM410xRead("")); return 0; @@ -158,9 +159,9 @@ int CmdEM410xWatch(const char *Cmd) int CmdEM410xWatchnSpoof(const char *Cmd) { CmdEM410xWatch(Cmd); - PrintAndLog("# Replaying captured ID: %s",global_em410xId); - CmdLFaskSim(""); - return 0; + PrintAndLog("# Replaying captured ID: %s",global_em410xId); + CmdLFaskSim(""); + return 0; } /* Read the transmitted data of an EM4x50 tag diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 57540bd8..da3ee1a9 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -246,7 +246,7 @@ int CmdT55xxReadBlock(const char *Cmd) { WaitForResponse(CMD_ACK,NULL); setGraphBuf(got, 12000); DemodBufferLen=0; - if (!DecodeT55xxBlock()) return 0; + if (!DecodeT55xxBlock()) return 3; char blk[10]={0}; sprintf(blk,"%d", block); printT55xxBlock(blk); @@ -1009,7 +1009,7 @@ char * GetModulationStr( uint32_t id){ sprintf(retStr,"%d - Biphase",id); break; case 0x18: - sprintf(retStr,"%d - Biphase a",id); + sprintf(retStr,"%d - Biphase a - AKA Conditional Dephase Encoding(CDP)",id); break; case 17: sprintf(retStr,"%d - Reserved",id); @@ -1071,7 +1071,7 @@ char * GetSelectedModulationStr( uint8_t id){ sprintf(retStr,"BIPHASE"); break; case DEMOD_BIa: - sprintf(retStr,"BIPHASEa"); + sprintf(retStr,"BIPHASEa - (CDP)"); break; default: sprintf(retStr,"(Unknown)"); diff --git a/client/scripts/test_t55x7_psk.lua b/client/scripts/test_t55x7_psk.lua index 766d853f..cbd78e87 100644 --- a/client/scripts/test_t55x7_psk.lua +++ b/client/scripts/test_t55x7_psk.lua @@ -42,6 +42,7 @@ Arguments: local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds local DEBUG = true -- the debug flag + -- local procedurecmds = { -- [1] = '%s%s%s%s', @@ -54,11 +55,11 @@ local DEBUG = true -- the debug flag -- } -- --BLOCK 0 = 00 08 80 40 PSK - -- ----------- - -- 08------- bitrate - -- 8----- modulation PSK1 - -- 0---- PSK ClockRate - -- 40 max 2 blocks + -- ----------- + -- 08------- bitrate + -- 8----- modulation PSK1 + -- 0---- PSK ClockRate + -- 40 max 2 blocks local procedurecmds = { [1] = '00%02X%X%X40', @@ -110,26 +111,30 @@ function test(modulation) for bitrate = 0x0, 0x1d, 0x4 do for clockrate = 0,8,4 do - local cmd = procedurecmds[_] - - if #cmd == 0 then - - elseif _ == 1 then - - dbg("Writing to T55x7 TAG") - local config = cmd:format(bitrate, modulation, clockrate) - dbg(('lf t55xx write 0 %s'):format(config)) + for _ = 1, #procedurecmds do + local cmd = procedurecmds[_] - config = tonumber(config,16) - local writecommand = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK, arg1 = config ,arg2 = 0, arg3 = 0} - local err = core.SendCommand(writecommand:getBytes()) - if err then return oops(err) end - local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT) - else - dbg(cmd) - core.console( cmd ) + if #cmd == 0 then + + elseif _ == 1 then + + dbg("Writing to T55x7 TAG") + + local config = cmd:format(bitrate, modulation, clockrate) + dbg(('lf t55xx write 0 %s'):format(config)) + + config = tonumber(config,16) + local writecommand = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK, arg1 = config ,arg2 = 0, arg3 = 0} + local err = core.SendCommand(writecommand:getBytes()) + if err then return oops(err) end + local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT) + else + dbg(cmd) + core.console( cmd ) + end end + core.clearCommandBuffer() end end print( string.rep('--',20) ) @@ -147,10 +152,20 @@ local function main(args) core.clearCommandBuffer() - test(1) --PSK1 - -- test(2) --PSK2 - -- test(3) --PSK3 + test(1) -- PSK1 + --test(2) -- PSK2 + --test(3) -- PSK3 print( string.rep('--',20) ) end main(args) + +-- Where it iterates over + -- xxxx8xxx = PSK RF/2 with Manchester modulation + -- xxxx1xxx = PSK RF/2 with PSK1 modulation (phase change when input changes) + -- xxxx2xxx = PSK RF/2 with PSk2 modulation (phase change on bitclk if input high) + -- xxxx3xxx = PSK RF/2 with PSk3 modulation (phase change on rising edge of input) + + -- XXXXX0XX = PSK RF/2 + -- XXXXX4XX = PSK RF/4 + -- XXXXX8XX = PSK RF/8 diff --git a/common/lfdemod.c b/common/lfdemod.c index 5b0bc29d..c7acb404 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -375,34 +375,39 @@ int cleanAskRawDemod(uint8_t *BinStream, size_t *size, int clk, int invert, int smplCnt++; } else if (BinStream[i] <= low && !waveHigh){ smplCnt++; - } else { //not high or low or a transition - if (smplCnt > clk-(clk/4)) { //full clock - if (smplCnt > clk + (clk/4)) { //too many samples - errCnt++; - BinStream[bitCnt++]=77; - } else if (waveHigh) { - BinStream[bitCnt++] = invert; - BinStream[bitCnt++] = invert; - } else if (!waveHigh) { - BinStream[bitCnt++] = invert ^ 1; - BinStream[bitCnt++] = invert ^ 1; - } - waveHigh ^= 1; - smplCnt = 0; - } else if (smplCnt > (clk/2) - (clk/5)) { - if (waveHigh) { - BinStream[bitCnt++] = invert; - } else if (!waveHigh) { - BinStream[bitCnt++] = invert ^ 1; + } else { //transition + if ((BinStream[i] >= high && !waveHigh) || (BinStream[i] <= low && waveHigh)){ + if (smplCnt > clk-(clk/4)-1) { //full clock + if (smplCnt > clk + (clk/4)+1) { //too many samples + errCnt++; + BinStream[bitCnt++]=77; + } else if (waveHigh) { + BinStream[bitCnt++] = invert; + BinStream[bitCnt++] = invert; + } else if (!waveHigh) { + BinStream[bitCnt++] = invert ^ 1; + BinStream[bitCnt++] = invert ^ 1; + } + waveHigh ^= 1; + smplCnt = 0; + } else if (smplCnt > (clk/2) - (clk/4)-1) { + if (waveHigh) { + BinStream[bitCnt++] = invert; + } else if (!waveHigh) { + BinStream[bitCnt++] = invert ^ 1; + } + waveHigh ^= 1; + smplCnt = 0; + } else if (!bitCnt) { + //first bit + waveHigh = (BinStream[i] >= high); + smplCnt = 1; + } else { + smplCnt++; + //transition bit oops } - waveHigh ^= 1; - smplCnt = 0; - } else if (!bitCnt) { - //first bit - waveHigh = (BinStream[i] >= high); - smplCnt = 1; - } else { - //transition bit? ignore + } else { //haven't hit new high or new low yet + smplCnt++; } } } @@ -888,16 +893,18 @@ int PyramiddemodFSK(uint8_t *dest, size_t *size) uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, int high, int low) { - uint8_t allPeaks=1; + uint16_t allPeaks=1; uint16_t cntPeaks=0; - for (size_t i=30; i<255; i++){ + size_t loopEnd = 572; + if (loopEnd > size) loopEnd = size; + for (size_t i=60; ilow && dest[i]210) return 1; + if (allPeaks == 0){ + if (cntPeaks > 300) return 1; } return allPeaks; } @@ -939,10 +946,12 @@ int DetectStrongAskClock(uint8_t dest[], size_t size) } } } + uint8_t tol; for (idx=8; idx>0; idx--){ - if (clk[idx] >= highCnt && clk[idx] <= highCnt+2) + tol = clk[idx]/8; + if (clk[idx] >= highCnt - tol && clk[idx] <= highCnt + tol) return clk[idx]; - if (clk[idx] >= highCnt2 && clk[idx] <= highCnt2+2) + if (clk[idx] >= highCnt2 - tol && clk[idx] <= highCnt2 + tol) return clk[idx]; } return -1; -- 2.39.5