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);
// 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);
,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.
uint32_t SnoopLF()
{
- return ReadLF(false);
+ return ReadLF(false, true);
}
* 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.
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");
PrintAndLog(" NOTE: <amplify> 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");
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);
PrintAndLog(" <help> as 'h', prints the help for the specific modulation");
PrintAndLog(" <options> 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");
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)
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];
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;
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;
{"io", CmdLFIO, 1, "{ ioProx tags... }"},
{"indalademod", CmdIndalaDemod, 1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"},
{"indalaclone", CmdIndalaClone, 0, "<UID> ['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 <hexdata>] -- Simulate LF ASK tag from demodbuffer or input"},
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;
}
break;
}
- CmdLFRead("");
- CmdSamples("6000");
+ CmdLFRead("s");
+ getSamples("8192",true); //capture enough to get 2 full messages
} while (!CmdEM410xRead(""));
return 0;
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
WaitForResponse(CMD_ACK,NULL);\r
setGraphBuf(got, 12000);\r
DemodBufferLen=0;\r
- if (!DecodeT55xxBlock()) return 0;\r
+ if (!DecodeT55xxBlock()) return 3;\r
char blk[10]={0};\r
sprintf(blk,"%d", block);\r
printT55xxBlock(blk);\r
sprintf(retStr,"%d - Biphase",id);\r
break;\r
case 0x18:\r
- sprintf(retStr,"%d - Biphase a",id);\r
+ sprintf(retStr,"%d - Biphase a - AKA Conditional Dephase Encoding(CDP)",id);\r
break;\r
case 17:\r
sprintf(retStr,"%d - Reserved",id);\r
sprintf(retStr,"BIPHASE");\r
break;\r
case DEMOD_BIa:\r
- sprintf(retStr,"BIPHASEa");\r
+ sprintf(retStr,"BIPHASEa - (CDP)");\r
break;\r
default:\r
sprintf(retStr,"(Unknown)");\r
local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
local DEBUG = true -- the debug flag
+
-- local procedurecmds = {
-- [1] = '%s%s%s%s',
-- }
-- --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',
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) )
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
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++;
}
}
}
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; i<loopEnd; i++){
if (dest[i]>low && dest[i]<high)
allPeaks=0;
else
cntPeaks++;
}
- if (allPeaks==0){
- if (cntPeaks>210) return 1;
+ if (allPeaks == 0){
+ if (cntPeaks > 300) return 1;
}
return allPeaks;
}
}
}
}
+ 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;