mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-07-13 00:33:01 -07:00
lf t5 read plus lf demod adjustments
lf t5xx commands updated from ICEMAN lf em410x commands updated lf search bug fix for 2 args test scripts from iceman lf demod: better ask clock detection with Strong fully clipped waves better ask raw demod with strong fully clipped waves fsk demod add back in skipped bits during demod nrz demod add back in skipped bits during demod
This commit is contained in:
parent
2147c30778
commit
13d77ef964
14 changed files with 1945 additions and 537 deletions
|
@ -1030,10 +1030,12 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
|
|||
* To compensate antenna falling times shorten the write times
|
||||
* and enlarge the gap ones.
|
||||
*/
|
||||
#define START_GAP 250
|
||||
#define WRITE_GAP 160
|
||||
#define WRITE_0 144 // 192
|
||||
#define WRITE_1 400 // 432 for T55x7; 448 for E5550
|
||||
#define START_GAP 50*8 // 10 - 50fc 250
|
||||
#define WRITE_GAP 20*8 // - 30fc 160
|
||||
#define WRITE_0 24*8 // 16 - 63fc 54fc 144
|
||||
#define WRITE_1 54*8 // 48 - 63fc 54fc 432 for T55x7; 448 for E5550 //400
|
||||
|
||||
#define T55xx_SAMPLES_SIZE 12000 // 32 x 32 x 10 (32 bit times numofblock (7), times clock skip..)
|
||||
|
||||
// Write one bit to card
|
||||
void T55xxWriteBit(int bit)
|
||||
|
@ -1052,7 +1054,6 @@ 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)
|
||||
{
|
||||
//unsigned int i; //enio adjustment 12/10/14
|
||||
uint32_t i;
|
||||
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
|
@ -1061,7 +1062,7 @@ void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMod
|
|||
|
||||
// Give it a bit of time for the resonant antenna to settle.
|
||||
// And for the tag to fully power up
|
||||
SpinDelay(150);
|
||||
//SpinDelay(150);
|
||||
|
||||
// Now start writting
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
|
@ -1094,30 +1095,28 @@ void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMod
|
|||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
}
|
||||
|
||||
void TurnReadLFOn(){
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
|
||||
// Give it a bit of time for the resonant antenna to settle.
|
||||
SpinDelayUs(8*150);
|
||||
}
|
||||
|
||||
|
||||
// Read one card block in page 0
|
||||
void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
//int m=0, i=0; //enio adjustment 12/10/14
|
||||
uint32_t m=0, i=0;
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
m = BigBuf_max_traceLen();
|
||||
uint16_t bufferlength = BigBuf_max_traceLen();
|
||||
if ( bufferlength > T55xx_SAMPLES_SIZE )
|
||||
bufferlength = T55xx_SAMPLES_SIZE;
|
||||
|
||||
// Clear destination buffer before sending the command
|
||||
memset(dest, 128, m);
|
||||
// Connect the A/D to the peak-detected low-frequency path.
|
||||
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
||||
// Now set up the SSC to get the ADC samples that are now streaming at us.
|
||||
FpgaSetupSsc();
|
||||
memset(dest, 0x80, bufferlength);
|
||||
|
||||
LED_D_ON();
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
|
||||
|
||||
// Give it a bit of time for the resonant antenna to settle.
|
||||
// And for the tag to fully power up
|
||||
SpinDelay(150);
|
||||
|
||||
// Now start writting
|
||||
// Set up FPGA, 125kHz
|
||||
// Wait for config.. (192+8190xPOW)x8 == 67ms
|
||||
LFSetupFPGAForADC(0, true);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
SpinDelayUs(START_GAP);
|
||||
|
||||
|
@ -1136,53 +1135,40 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
|
|||
T55xxWriteBit(Block & i);
|
||||
|
||||
// Turn field on to read the response
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
|
||||
|
||||
TurnReadLFOn();
|
||||
// Now do the acquisition
|
||||
i = 0;
|
||||
for(;;) {
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
|
||||
AT91C_BASE_SSC->SSC_THR = 0x43;
|
||||
LED_D_ON();
|
||||
}
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||
dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
// we don't care about actual value, only if it's more or less than a
|
||||
// threshold essentially we capture zero crossings for later analysis
|
||||
// if(dest[i] < 127) dest[i] = 0; else dest[i] = 1;
|
||||
i++;
|
||||
if (i >= m) break;
|
||||
LED_D_OFF();
|
||||
if (i >= bufferlength) break;
|
||||
}
|
||||
}
|
||||
|
||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
|
||||
LED_D_OFF();
|
||||
DbpString("DONE!");
|
||||
}
|
||||
|
||||
// Read card traceability data (page 1)
|
||||
void T55xxReadTrace(void){
|
||||
|
||||
uint32_t i = 0;
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
int m=0, i=0;
|
||||
uint16_t bufferlength = BigBuf_max_traceLen();
|
||||
if ( bufferlength > T55xx_SAMPLES_SIZE )
|
||||
bufferlength= T55xx_SAMPLES_SIZE;
|
||||
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
m = BigBuf_max_traceLen();
|
||||
// Clear destination buffer before sending the command
|
||||
memset(dest, 128, m);
|
||||
// Connect the A/D to the peak-detected low-frequency path.
|
||||
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
||||
// Now set up the SSC to get the ADC samples that are now streaming at us.
|
||||
FpgaSetupSsc();
|
||||
memset(dest, 0x80, bufferlength);
|
||||
|
||||
LED_D_ON();
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
|
||||
|
||||
// Give it a bit of time for the resonant antenna to settle.
|
||||
// And for the tag to fully power up
|
||||
SpinDelay(150);
|
||||
|
||||
// Now start writting
|
||||
LFSetupFPGAForADC(0, true);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
SpinDelayUs(START_GAP);
|
||||
|
||||
|
@ -1191,25 +1177,26 @@ void T55xxReadTrace(void){
|
|||
T55xxWriteBit(1); //Page 1
|
||||
|
||||
// Turn field on to read the response
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
|
||||
TurnReadLFOn();
|
||||
|
||||
// Now do the acquisition
|
||||
i = 0;
|
||||
for(;;) {
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
|
||||
AT91C_BASE_SSC->SSC_THR = 0x43;
|
||||
LED_D_ON();
|
||||
}
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||
dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
i++;
|
||||
if (i >= m) break;
|
||||
LED_D_OFF();
|
||||
|
||||
if (i >= bufferlength) break;
|
||||
}
|
||||
}
|
||||
|
||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
|
||||
LED_D_OFF();
|
||||
DbpString("DONE!");
|
||||
}
|
||||
|
||||
/*-------------- Cloning routines -----------*/
|
||||
|
|
139
client/cmddata.c
139
client/cmddata.c
|
@ -33,6 +33,12 @@ static int CmdHelp(const char *Cmd);
|
|||
//by marshmellow
|
||||
void setDemodBuf(uint8_t *buff, size_t size, size_t startIdx)
|
||||
{
|
||||
if (buff == NULL)
|
||||
return;
|
||||
|
||||
if ( size >= MAX_DEMOD_BUF_LEN)
|
||||
size = MAX_DEMOD_BUF_LEN;
|
||||
|
||||
size_t i = 0;
|
||||
for (; i < size; i++){
|
||||
DemodBuffer[i]=buff[startIdx++];
|
||||
|
@ -279,18 +285,101 @@ void printEM410x(uint32_t hi, uint64_t id)
|
|||
//output 40 bit em id
|
||||
PrintAndLog("EM TAG ID : %010llx", id);
|
||||
PrintAndLog("Unique TAG ID: %010llx", id2lo);
|
||||
PrintAndLog("");
|
||||
PrintAndLog("Possible de-scramble patterns");
|
||||
PrintAndLog("HoneyWell IdentKey");
|
||||
PrintAndLog("DEZ 8 : %08lld",id & 0xFFFFFF);
|
||||
PrintAndLog("DEZ 10 : %010lld",id & 0xFFFFFF);
|
||||
PrintAndLog("DEZ 10 : %010lld",id & 0xFFFFFFFF);
|
||||
PrintAndLog("DEZ 5.5 : %05lld.%05lld",(id>>16LL) & 0xFFFF,(id & 0xFFFF));
|
||||
PrintAndLog("DEZ 3.5A : %03lld.%05lld",(id>>32ll),(id & 0xFFFF));
|
||||
PrintAndLog("DEZ 3.5B : %03lld.%05lld",(id & 0xFF000000) >> 24,(id & 0xFFFF));
|
||||
PrintAndLog("DEZ 3.5C : %03lld.%05lld",(id & 0xFF0000) >> 16,(id & 0xFFFF));
|
||||
PrintAndLog("DEZ 14/IK2 : %014lld",id);
|
||||
PrintAndLog("DEZ 15/IK3 : %015lld",id2lo);
|
||||
PrintAndLog("Other : %05lld_%03lld_%08lld",(id&0xFFFF),((id>>16LL) & 0xFF),(id & 0xFFFFFF));
|
||||
PrintAndLog("DEZ 20/ZK : %02lld%02lld%02lld%02lld%02lld%02lld%02lld%02lld%02lld%02lld",
|
||||
(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)
|
||||
);
|
||||
|
||||
PrintAndLog("");
|
||||
uint64_t paxton = (((id>>32) << 24) | (id & 0xffffff)) + 0x143e00;
|
||||
PrintAndLog("Pattern Paxton : %0d", 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 : 0x%X - %d", p1, p1);
|
||||
|
||||
uint16_t sebury1 = id & 0xFFFF;
|
||||
uint8_t sebury2 = (id >> 16) & 0x7F;
|
||||
uint32_t sebury3 = id & 0x7FFFFF;
|
||||
PrintAndLog("Pattern Sebury : %d %d %d (hex: %X %X %X)", sebury1, sebury2, sebury3, sebury1, sebury2, sebury3);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo)
|
||||
{
|
||||
int ans = ASKmanDemod(Cmd, FALSE, FALSE);
|
||||
if (!ans) return 0;
|
||||
|
||||
size_t idx=0;
|
||||
if (Em410xDecode(DemodBuffer,(size_t *) &DemodBufferLen, &idx, hi, lo)){
|
||||
if (g_debugMode){
|
||||
PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, DemodBufferLen);
|
||||
printDemodBuff();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
//by marshmellow
|
||||
//takes 3 arguments - clock, invert and maxErr as integers
|
||||
//attempts to demodulate ask while decoding manchester
|
||||
|
@ -311,17 +400,9 @@ int CmdAskEM410xDemod(const char *Cmd)
|
|||
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;
|
||||
}
|
||||
int ans = ASKmanDemod(Cmd, FALSE, FALSE);
|
||||
if (!ans) return 0;
|
||||
|
||||
uint64_t lo =0;
|
||||
uint32_t hi =0;
|
||||
size_t idx=0;
|
||||
if (Em410xDecode(DemodBuffer,(size_t *) &DemodBufferLen, &idx, &hi, &lo)){
|
||||
if (g_debugMode){
|
||||
PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, DemodBufferLen);
|
||||
printDemodBuff();
|
||||
}
|
||||
uint32_t hi;
|
||||
uint64_t lo;
|
||||
if (AskEm410xDemod(Cmd, &hi, &lo)) {
|
||||
PrintAndLog("EM410x pattern found: ");
|
||||
printEM410x(hi, lo);
|
||||
return 1;
|
||||
|
@ -1859,21 +1940,19 @@ int NRZrawDemod(const char *Cmd, bool verbose)
|
|||
int errCnt=0;
|
||||
errCnt = nrzRawDemod(BitStream, &BitLen, &clk, &invert, maxErr);
|
||||
if (errCnt > maxErr){
|
||||
if (g_debugMode==1 && verbose) PrintAndLog("Too many errors found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt);
|
||||
if (g_debugMode) PrintAndLog("Too many errors found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt);
|
||||
return 0;
|
||||
}
|
||||
if (errCnt<0|| BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first)
|
||||
if (g_debugMode==1 && verbose) PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt);
|
||||
if (g_debugMode) PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt);
|
||||
return 0;
|
||||
}
|
||||
PrintAndLog("Tried NRZ Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen);
|
||||
if (verbose || g_debugMode) PrintAndLog("Tried NRZ Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen);
|
||||
//prime demod buffer for output
|
||||
setDemodBuf(BitStream,BitLen,0);
|
||||
|
||||
if (errCnt>0 && verbose){
|
||||
PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
|
||||
}
|
||||
if (verbose) {
|
||||
if (errCnt>0 && (verbose || g_debugMode)) PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
|
||||
if (verbose || g_debugMode) {
|
||||
PrintAndLog("NRZ demoded bitstream:");
|
||||
// Now output the bitstream to the scrollback by line of 16 bits
|
||||
printDemodBuff();
|
||||
|
@ -2656,10 +2735,8 @@ static command_t CommandTable[] =
|
|||
{"amp", CmdAmp, 1, "Amplify peaks"},
|
||||
//{"askdemod", Cmdaskdemod, 1, "<0 or 1> -- Attempt to demodulate simple ASK tags"},
|
||||
{"askedgedetect", CmdAskEdgeDetect, 1, "[threshold] Adjust Graph for manual ask demod using length of sample differences to detect the edge of a wave (default = 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"},
|
||||
//{"askmandemod", Cmdaskmandemod, 1, "[clock] [invert<0|1>] [maxErr] -- 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)"},
|
||||
{"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"},
|
||||
{"autocorr", CmdAutoCorr, 1, "[window length] [g] -- Autocorrelation over window - g to save back to GraphBuffer (overwrite)"},
|
||||
{"biphaserawdecode",CmdBiphaseDecodeRaw,1,"[offset] [invert<0|1>] Biphase decode bin stream in DemodBuffer (offset = 0|1 bits to shift the decode start)"},
|
||||
{"bitsamples", CmdBitsamples, 0, "Get raw samples as bitstring"},
|
||||
|
@ -2672,9 +2749,8 @@ static command_t CommandTable[] =
|
|||
//{"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"},
|
||||
//{"fskrawdemod", CmdFSKrawdemod, 1, "[clock rate] [invert] [rchigh] [rclow] Demodulate graph window from FSK to bin (clock = 50)(invert = 1|0)(rchigh = 10)(rclow=8)"},
|
||||
{"fskpyramiddemod", CmdFSKdemodPyramid, 1, "Demodulate a Pyramid FSK tag from GraphBuffer"},
|
||||
{"fskparadoxdemod", CmdFSKdemodParadox, 1, "Demodulate a Paradox FSK tag from GraphBuffer"},
|
||||
{"getbitstream", CmdGetBitStream, 1, "Convert GraphBuffer's >=1 values to 1 and <1 to 0"},
|
||||
{"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"},
|
||||
|
@ -2687,20 +2763,15 @@ static command_t CommandTable[] =
|
|||
{"manrawdecode", Cmdmandecoderaw, 1, "Manchester decode binary stream in DemodBuffer"},
|
||||
{"manmod", CmdManchesterMod, 1, "[clock rate] -- Manchester modulate a binary stream"},
|
||||
{"norm", CmdNorm, 1, "Normalize max/min to +/-128"},
|
||||
//{"nrzdetectclock",CmdDetectNRZClockRate, 1, "Detect ASK, PSK, or NRZ clock rate"},
|
||||
//{"nrzrawdemod", CmdNRZrawDemod, 1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate nrz tags and output binary (args optional)"},
|
||||
{"plot", CmdPlot, 1, "Show graph window (hit 'h' in window for keystroke help)"},
|
||||
//{"pskdetectclock",CmdDetectPSKClockRate, 1, "Detect ASK, PSK, or NRZ clock rate"},
|
||||
{"printdemodbuffer",CmdPrintDemodBuff,1, "[x] -- print the data in the DemodBuffer - 'x' for hex output"},
|
||||
{"pskindalademod",CmdIndalaDecode, 1, "[clock] [invert<0|1>] -- Demodulate an indala tag (PSK1) from GraphBuffer (args optional)"},
|
||||
//{"psk1rawdemod", CmdPSK1rawDemod, 1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate psk1 tags and output binary (args optional)"},
|
||||
//{"psk2rawdemod", CmdPSK2rawDemod, 1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate psk2 tags and output binary (args optional)"},
|
||||
{"printdemodbuffer",CmdPrintDemodBuff, 1, "[x] -- print the data in the DemodBuffer - 'x' for hex output"},
|
||||
{"pskindalademod", CmdIndalaDecode, 1, "[clock] [invert<0|1>] -- Demodulate an indala tag (PSK1) from GraphBuffer (args optional)"},
|
||||
{"rawdemod", CmdRawDemod, 1, "[modulation] ... <options> -see help (h option) -- Demodulate the data in the GraphBuffer and output binary"},
|
||||
{"samples", CmdSamples, 0, "[512 - 40000] -- Get raw samples for graph window (GraphBuffer)"},
|
||||
{"save", CmdSave, 1, "<filename> -- Save trace (from graph window)"},
|
||||
{"scale", CmdScale, 1, "<int> -- Set cursor display scale"},
|
||||
{"setdebugmode", CmdSetDebugMode, 1, "<0|1> -- Turn on or off Debugging Mode for demods"},
|
||||
{"shiftgraphzero",CmdGraphShiftZero, 1, "<shift> -- Shift 0 for Graphed wave + or - shift value"},
|
||||
{"shiftgraphzero", CmdGraphShiftZero, 1, "<shift> -- Shift 0 for Graphed wave + or - shift value"},
|
||||
//{"threshold", CmdThreshold, 1, "<threshold> -- Maximize/minimize every value in the graph window depending on threshold"},
|
||||
{"dirthreshold", CmdDirectionalThreshold, 1, "<thres up> <thres down> -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev."},
|
||||
{"tune", CmdTuneSamples, 0, "Get hw tune samples for graph window"},
|
||||
|
|
|
@ -63,12 +63,14 @@ int CmdThreshold(const char *Cmd);
|
|||
int CmdDirectionalThreshold(const char *Cmd);
|
||||
int CmdZerocrossings(const char *Cmd);
|
||||
int CmdIndalaDecode(const char *Cmd);
|
||||
int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo);
|
||||
int ASKbiphaseDemod(const char *Cmd, bool verbose);
|
||||
int ASKmanDemod(const char *Cmd, bool verbose, bool emSearch);
|
||||
int ASKrawDemod(const char *Cmd, bool verbose);
|
||||
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);
|
||||
|
||||
#define MAX_DEMOD_BUF_LEN (1024*128)
|
||||
extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
|
||||
|
|
|
@ -1016,7 +1016,7 @@ int CmdLFfind(const char *Cmd)
|
|||
int ans=0;
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
char testRaw = param_getchar(Cmd, 1);
|
||||
if (strlen(Cmd) > 2 || cmdp == 'h' || cmdp == 'H') {
|
||||
if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') {
|
||||
PrintAndLog("Usage: lf search <0|1> [u]");
|
||||
PrintAndLog(" <use data from Graphbuffer> , if not set, try reading data from tag.");
|
||||
PrintAndLog(" [Search for Unknown tags] , if not set, reads only known tags.");
|
||||
|
@ -1037,50 +1037,60 @@ int CmdLFfind(const char *Cmd)
|
|||
return 0;
|
||||
}
|
||||
if (cmdp == 'u' || cmdp == 'U') testRaw = 'u';
|
||||
|
||||
PrintAndLog("NOTE: some demods output possible binary\n if it finds something that looks like a tag");
|
||||
PrintAndLog("False Positives ARE possible\n");
|
||||
PrintAndLog("\nChecking for known tags:\n");
|
||||
|
||||
ans=CmdFSKdemodIO("");
|
||||
if (ans>0) {
|
||||
PrintAndLog("\nValid IO Prox ID Found!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
ans=CmdFSKdemodPyramid("");
|
||||
if (ans>0) {
|
||||
PrintAndLog("\nValid Pyramid ID Found!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
ans=CmdFSKdemodParadox("");
|
||||
if (ans>0) {
|
||||
PrintAndLog("\nValid Paradox ID Found!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
ans=CmdFSKdemodAWID("");
|
||||
if (ans>0) {
|
||||
PrintAndLog("\nValid AWID ID Found!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
ans=CmdFSKdemodHID("");
|
||||
if (ans>0) {
|
||||
PrintAndLog("\nValid HID Prox ID Found!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
//add psk and indala
|
||||
ans=CmdIndalaDecode("");
|
||||
if (ans>0) {
|
||||
PrintAndLog("\nValid Indala ID Found!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
ans=CmdAskEM410xDemod("");
|
||||
if (ans>0) {
|
||||
PrintAndLog("\nValid EM410x ID Found!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
ans=CmdG_Prox_II_Demod("");
|
||||
if (ans>0) {
|
||||
PrintAndLog("\nValid G Prox II ID Found!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
PrintAndLog("\nNo Known Tags Found!\n");
|
||||
if (testRaw=='u' || testRaw=='U'){
|
||||
//test unknown tag formats (raw mode)
|
||||
|
|
|
@ -43,163 +43,23 @@ int CmdEMdemodASK(const char *Cmd)
|
|||
*/
|
||||
int CmdEM410xRead(const char *Cmd)
|
||||
{
|
||||
int i, j, clock, header, rows, bit, hithigh, hitlow, first, bit2idx, high, low;
|
||||
int parity[4];
|
||||
char id[11] = {0x00};
|
||||
char id2[11] = {0x00};
|
||||
int retested = 0;
|
||||
uint8_t BitStream[MAX_GRAPH_TRACE_LEN];
|
||||
high = low = 0;
|
||||
uint32_t hi=0;
|
||||
uint64_t lo=0;
|
||||
|
||||
/* Detect high and lows and clock */
|
||||
for (i = 0; i < GraphTraceLen; i++)
|
||||
{
|
||||
if (GraphBuffer[i] > high)
|
||||
high = GraphBuffer[i];
|
||||
else if (GraphBuffer[i] < low)
|
||||
low = GraphBuffer[i];
|
||||
}
|
||||
|
||||
/* get clock */
|
||||
clock = GetAskClock(Cmd, false, false);
|
||||
|
||||
/* parity for our 4 columns */
|
||||
parity[0] = parity[1] = parity[2] = parity[3] = 0;
|
||||
header = rows = 0;
|
||||
|
||||
// manchester demodulate
|
||||
bit = bit2idx = 0;
|
||||
for (i = 0; i < (int)(GraphTraceLen / clock); i++)
|
||||
{
|
||||
hithigh = 0;
|
||||
hitlow = 0;
|
||||
first = 1;
|
||||
|
||||
/* Find out if we hit both high and low peaks */
|
||||
for (j = 0; j < clock; j++)
|
||||
{
|
||||
if (GraphBuffer[(i * clock) + j] >= high)
|
||||
hithigh = 1;
|
||||
else if (GraphBuffer[(i * clock) + j] <= low)
|
||||
hitlow = 1;
|
||||
|
||||
/* it doesn't count if it's the first part of our read
|
||||
because it's really just trailing from the last sequence */
|
||||
if (first && (hithigh || hitlow))
|
||||
hithigh = hitlow = 0;
|
||||
else
|
||||
first = 0;
|
||||
|
||||
if (hithigh && hitlow)
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we didn't hit both high and low peaks, we had a bit transition */
|
||||
if (!hithigh || !hitlow)
|
||||
bit ^= 1;
|
||||
|
||||
BitStream[bit2idx++] = bit;
|
||||
}
|
||||
|
||||
retest:
|
||||
/* We go till 5 before the graph ends because we'll get that far below */
|
||||
for (i = 1; i < bit2idx - 5; i++)
|
||||
{
|
||||
/* Step 2: We have our header but need our tag ID */
|
||||
if (header == 9 && rows < 10)
|
||||
{
|
||||
/* Confirm parity is correct */
|
||||
if ((BitStream[i] ^ BitStream[i+1] ^ BitStream[i+2] ^ BitStream[i+3]) == BitStream[i+4])
|
||||
{
|
||||
/* Read another byte! */
|
||||
sprintf(id+rows, "%x", (8 * BitStream[i]) + (4 * BitStream[i+1]) + (2 * BitStream[i+2]) + (1 * BitStream[i+3]));
|
||||
sprintf(id2+rows, "%x", (8 * BitStream[i+3]) + (4 * BitStream[i+2]) + (2 * BitStream[i+1]) + (1 * BitStream[i]));
|
||||
rows++;
|
||||
|
||||
/* Keep parity info */
|
||||
parity[0] ^= BitStream[i];
|
||||
parity[1] ^= BitStream[i+1];
|
||||
parity[2] ^= BitStream[i+2];
|
||||
parity[3] ^= BitStream[i+3];
|
||||
|
||||
/* Move 4 bits ahead */
|
||||
i += 4;
|
||||
}
|
||||
|
||||
/* Damn, something wrong! reset */
|
||||
else
|
||||
{
|
||||
PrintAndLog("Thought we had a valid tag but failed at word %d (i=%d)", rows + 1, i);
|
||||
|
||||
/* Start back rows * 5 + 9 header bits, -1 to not start at same place */
|
||||
i -= 9 + (5 * rows) - 5;
|
||||
|
||||
rows = header = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Step 3: Got our 40 bits! confirm column parity */
|
||||
else if (rows == 10)
|
||||
{
|
||||
/* We need to make sure our 4 bits of parity are correct and we have a stop bit */
|
||||
if (BitStream[i] == parity[0] && BitStream[i+1] == parity[1] &&
|
||||
BitStream[i+2] == parity[2] && BitStream[i+3] == parity[3] &&
|
||||
BitStream[i+4] == 0)
|
||||
{
|
||||
/* Sweet! */
|
||||
PrintAndLog("EM410x Tag ID: %s", id);
|
||||
PrintAndLog("Unique Tag ID: %s", id2);
|
||||
|
||||
global_em410xId = id;
|
||||
|
||||
/* Stop any loops */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Crap! Incorrect parity or no stop bit, start all over */
|
||||
else
|
||||
{
|
||||
rows = header = 0;
|
||||
|
||||
/* Go back 59 bits (9 header bits + 10 rows at 4+1 parity) */
|
||||
i -= 59;
|
||||
}
|
||||
}
|
||||
|
||||
/* Step 1: get our header */
|
||||
else if (header < 9)
|
||||
{
|
||||
/* Need 9 consecutive 1's */
|
||||
if (BitStream[i] == 1)
|
||||
header++;
|
||||
|
||||
/* We don't have a header, not enough consecutive 1 bits */
|
||||
else
|
||||
header = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we've already retested after flipping bits, return */
|
||||
if (retested++){
|
||||
PrintAndLog("Failed to decode");
|
||||
if(!AskEm410xDemod("", &hi, &lo)) return 0;
|
||||
PrintAndLog("EM410x pattern found: ");
|
||||
printEM410x(hi, lo);
|
||||
if (hi){
|
||||
PrintAndLog ("EM410x XL pattern found");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if this didn't work, try flipping bits */
|
||||
for (i = 0; i < bit2idx; i++)
|
||||
BitStream[i] ^= 1;
|
||||
|
||||
goto retest;
|
||||
char id[11] = {0x00};
|
||||
sprintf(id, "%010x", lo);
|
||||
global_em410xId = id;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* emulate an EM410X tag
|
||||
* Format:
|
||||
* 1111 1111 1 <-- standard non-repeatable header
|
||||
* XXXX [row parity bit] <-- 10 rows of 5 bits for our 40 bit tag ID
|
||||
* ....
|
||||
* CCCC <-- each bit here is parity for the 10 bits above in corresponding column
|
||||
* 0 <-- stop bit, end of tag
|
||||
*/
|
||||
// emulate an EM410X tag
|
||||
int CmdEM410xSim(const char *Cmd)
|
||||
{
|
||||
int i, n, j, binary[4], parity[4];
|
||||
|
@ -282,27 +142,24 @@ int CmdEM410xSim(const char *Cmd)
|
|||
*/
|
||||
int CmdEM410xWatch(const char *Cmd)
|
||||
{
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
int read_h = (cmdp == 'h');
|
||||
do {
|
||||
if (ukbhit()) {
|
||||
printf("\naborted via keyboard!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
CmdLFRead(read_h ? "h" : "");
|
||||
CmdLFRead("");
|
||||
CmdSamples("6000");
|
||||
} while (
|
||||
!CmdEM410xRead("")
|
||||
);
|
||||
} while (!CmdEM410xRead(""));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdEM410xWatchnSpoof(const char *Cmd)
|
||||
{
|
||||
CmdEM410xWatch(Cmd);
|
||||
PrintAndLog("# Replaying : %s",global_em410xId);
|
||||
CmdEM410xSim(global_em410xId);
|
||||
PrintAndLog("# Replaying captured ID: %s",global_em410xId);
|
||||
CmdLFaskSim("");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
1134
client/cmdlft55xx.c
1134
client/cmdlft55xx.c
File diff suppressed because it is too large
Load diff
|
@ -10,12 +10,57 @@
|
|||
#ifndef CMDLFT55XX_H__
|
||||
#define CMDLFT55XX_H__
|
||||
|
||||
int CmdLFT55XX(const char *Cmd);
|
||||
typedef struct {
|
||||
enum {
|
||||
DEMOD_NRZ = 0x00,
|
||||
DEMOD_PSK1 = 0x01,
|
||||
DEMOD_PSK2 = 0x02,
|
||||
DEMOD_PSK3 = 0x03,
|
||||
DEMOD_FSK1 = 0x04,
|
||||
DEMOD_FSK1a = 0x05,
|
||||
DEMOD_FSK2 = 0x06,
|
||||
DEMOD_FSK2a = 0x07,
|
||||
DEMOD_FSK = 0xF0, //generic FSK (auto detect FCs)
|
||||
DEMOD_ASK = 0x08,
|
||||
DEMOD_BI = 0x10,
|
||||
DEMOD_BIa = 0x18,
|
||||
} modulation;
|
||||
bool inverted;
|
||||
uint8_t offset;
|
||||
uint32_t block0;
|
||||
enum {
|
||||
RF_8 = 0x00,
|
||||
RF_16 = 0x01,
|
||||
RF_32 = 0x02,
|
||||
RF_40 = 0x03,
|
||||
RF_50 = 0x04,
|
||||
RF_64 = 0x05,
|
||||
RF_100 = 0x06,
|
||||
RF_128 = 0x07,
|
||||
} bitrate;
|
||||
} t55xx_conf_block_t;
|
||||
|
||||
int CmdReadBlk(const char *Cmd);
|
||||
int CmdReadBlkPWD(const char *Cmd);
|
||||
int CmdWriteBlk(const char *Cmd);
|
||||
int CmdWriteBLkPWD(const char *Cmd);
|
||||
int CmdReadTrace(const char *Cmd);
|
||||
int CmdLFT55XX(const char *Cmd);
|
||||
int CmdT55xxSetConfig(const char *Cmd);
|
||||
int CmdT55xxReadBlock(const char *Cmd);
|
||||
int CmdT55xxWriteBlock(const char *Cmd);
|
||||
int CmdT55xxReadTrace(const char *Cmd);
|
||||
int CmdT55xxInfo(const char *Cmd);
|
||||
int CmdT55xxDetect(const char *Cmd);
|
||||
|
||||
char * GetBitRateStr(uint32_t id);
|
||||
char * GetSaferStr(uint32_t id);
|
||||
char * GetModulationStr( uint32_t id);
|
||||
char * GetModelStrFromCID(uint32_t cid);
|
||||
char * GetSelectedModulationStr( uint8_t id);
|
||||
uint32_t PackBits(uint8_t start, uint8_t len, uint8_t* bitstream);
|
||||
void printT55xxBlock(const char *demodStr);
|
||||
void printConfiguration( t55xx_conf_block_t b);
|
||||
|
||||
bool DecodeT55xxBlock();
|
||||
bool tryDetectModulation();
|
||||
bool test(uint8_t mode, uint8_t *offset);
|
||||
int special(const char *Cmd);
|
||||
int AquireData( uint8_t block );
|
||||
|
||||
#endif
|
||||
|
|
139
client/scripts/test_t55x7_ask.lua
Normal file
139
client/scripts/test_t55x7_ask.lua
Normal file
|
@ -0,0 +1,139 @@
|
|||
local cmds = require('commands')
|
||||
local getopt = require('getopt')
|
||||
local bin = require('bin')
|
||||
local utils = require('utils')
|
||||
|
||||
local format=string.format
|
||||
local floor=math.floor
|
||||
|
||||
example =[[
|
||||
1. script run test_t55x7_ask
|
||||
]]
|
||||
author = "Iceman"
|
||||
usage = "script run test_t55x7_ask"
|
||||
desc =[[
|
||||
This script will program a T55x7 TAG with the configuration: block 0x00 data 0x000100
|
||||
The outlined procedure is as following:
|
||||
|
||||
--ASK
|
||||
00 00 80 40
|
||||
-- max 2
|
||||
-- manchester
|
||||
-- bit rate
|
||||
|
||||
"lf t55xx write 0 00008040"
|
||||
"lf t55xx detect"
|
||||
"lf t55xx info"
|
||||
|
||||
Loop:
|
||||
change the configuretion block 0 with:
|
||||
-xx 00 xxxx = RF/8
|
||||
-xx 04 xxxx = RF/16
|
||||
-xx 08 xxxx = RF/32
|
||||
-xx 0C xxxx = RF/40
|
||||
-xx 10 xxxx = RF/50
|
||||
-xx 14 xxxx = RF/64
|
||||
-xx 18 xxxx = RF/100
|
||||
-xx 1C xxxx = RF/128
|
||||
|
||||
|
||||
testsuit for the ASK/MANCHESTER demod
|
||||
|
||||
Arguments:
|
||||
-h : this help
|
||||
]]
|
||||
|
||||
local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
|
||||
local DEBUG = true -- the debug flag
|
||||
|
||||
--BLOCK 0 = 00008040 ASK / MAN
|
||||
local config1 = '00'
|
||||
local config2 = '8040'
|
||||
|
||||
local procedurecmds = {
|
||||
[1] = '%s%02X%s',
|
||||
[2] = 'lf t55xx detect',
|
||||
[3] = 'lf t55xx info',
|
||||
}
|
||||
---
|
||||
-- A debug printout-function
|
||||
function dbg(args)
|
||||
if not DEBUG then
|
||||
return
|
||||
end
|
||||
|
||||
if type(args) == "table" then
|
||||
local i = 1
|
||||
while args[i] do
|
||||
dbg(args[i])
|
||||
i = i+1
|
||||
end
|
||||
else
|
||||
print("###", args)
|
||||
end
|
||||
end
|
||||
---
|
||||
-- This is only meant to be used when errors occur
|
||||
function oops(err)
|
||||
print("ERROR: ",err)
|
||||
end
|
||||
---
|
||||
-- Usage help
|
||||
function help()
|
||||
print(desc)
|
||||
print("Example usage")
|
||||
print(example)
|
||||
end
|
||||
--
|
||||
-- Exit message
|
||||
function ExitMsg(msg)
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
print(msg)
|
||||
print()
|
||||
end
|
||||
|
||||
function test()
|
||||
local y
|
||||
for y = 0x0, 0x1d, 0x4 do
|
||||
for _ = 1, #procedurecmds do
|
||||
local pcmd = procedurecmds[_]
|
||||
|
||||
if #pcmd == 0 then
|
||||
|
||||
elseif _ == 1 then
|
||||
|
||||
local config = pcmd:format(config1, y, config2)
|
||||
dbg(('lf t55xx write 0 %s'):format(config))
|
||||
config = tonumber(config,16)
|
||||
|
||||
local writecmd = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK, arg1 = config}
|
||||
local err = core.SendCommand(writecmd:getBytes())
|
||||
if err then return oops(err) end
|
||||
local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
|
||||
|
||||
else
|
||||
dbg(pcmd)
|
||||
core.console( pcmd )
|
||||
end
|
||||
end
|
||||
core.clearCommandBuffer()
|
||||
end
|
||||
print( string.rep('--',20) )
|
||||
end
|
||||
|
||||
local function main(args)
|
||||
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
|
||||
-- Arguments for the script
|
||||
for o, arg in getopt.getopt(args, 'h') do
|
||||
if o == "h" then return help() end
|
||||
end
|
||||
|
||||
core.clearCommandBuffer()
|
||||
test()
|
||||
print( string.rep('--',20) )
|
||||
end
|
||||
main(args)
|
133
client/scripts/test_t55x7_bi.lua
Normal file
133
client/scripts/test_t55x7_bi.lua
Normal file
|
@ -0,0 +1,133 @@
|
|||
local cmds = require('commands')
|
||||
local getopt = require('getopt')
|
||||
local bin = require('bin')
|
||||
local utils = require('utils')
|
||||
|
||||
example =[[
|
||||
1. script run test_t55x7_bi
|
||||
]]
|
||||
author = "Iceman"
|
||||
usage = "script run test_t55x7_bi"
|
||||
desc =[[
|
||||
This script will program a T55x7 TAG with the configuration: block 0x00 data 0x00010040
|
||||
The outlined procedure is as following:
|
||||
|
||||
--BIPHASE 00010040
|
||||
--
|
||||
|
||||
"lf t55xx write 0 00010040"
|
||||
"lf t55xx detect"
|
||||
"lf t55xx info"
|
||||
|
||||
Loop:
|
||||
change the configuretion block 0 with:
|
||||
-xx01xxxx = RF/8
|
||||
-xx05xxxx = RF/16
|
||||
-xx09xxxx = RF/32
|
||||
-xx0Dxxxx = RF/40
|
||||
-xx11xxxx = RF/50
|
||||
-xx15xxxx = RF/64
|
||||
-xx19xxxx = RF/100
|
||||
-xx1Dxxxx = RF/128
|
||||
|
||||
|
||||
testsuit for the BIPHASE demod
|
||||
|
||||
Arguments:
|
||||
-h : this help
|
||||
]]
|
||||
|
||||
local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
|
||||
local DEBUG = true -- the debug flag
|
||||
|
||||
--BLOCK 0 = 00010040 BIPHASE
|
||||
local config1 = '00'
|
||||
local config2 = '0040'
|
||||
|
||||
local procedurecmds = {
|
||||
[1] = '%s%02X%s',
|
||||
[2] = 'lf t55xx detect',
|
||||
[3] = 'lf t55xx info',
|
||||
}
|
||||
---
|
||||
-- A debug printout-function
|
||||
function dbg(args)
|
||||
if not DEBUG then
|
||||
return
|
||||
end
|
||||
|
||||
if type(args) == "table" then
|
||||
local i = 1
|
||||
while args[i] do
|
||||
dbg(args[i])
|
||||
i = i+1
|
||||
end
|
||||
else
|
||||
print("###", args)
|
||||
end
|
||||
end
|
||||
---
|
||||
-- This is only meant to be used when errors occur
|
||||
function oops(err)
|
||||
print("ERROR: ",err)
|
||||
end
|
||||
---
|
||||
-- Usage help
|
||||
function help()
|
||||
print(desc)
|
||||
print("Example usage")
|
||||
print(example)
|
||||
end
|
||||
--
|
||||
-- Exit message
|
||||
function ExitMsg(msg)
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
print(msg)
|
||||
print()
|
||||
end
|
||||
|
||||
function test()
|
||||
local y
|
||||
for y = 1, 0x1D, 4 do
|
||||
for _ = 1, #procedurecmds do
|
||||
local pcmd = procedurecmds[_]
|
||||
|
||||
if #pcmd == 0 then
|
||||
|
||||
elseif _ == 1 then
|
||||
|
||||
local config = pcmd:format(config1, y, config2)
|
||||
dbg(('lf t55xx wr 0 %s'):format(config))
|
||||
|
||||
config = tonumber(config,16)
|
||||
local writecmd = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK, arg1 = config}
|
||||
local err = core.SendCommand(writecmd:getBytes())
|
||||
if err then return oops(err) end
|
||||
local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
|
||||
else
|
||||
dbg(pcmd)
|
||||
core.console( pcmd )
|
||||
end
|
||||
end
|
||||
core.clearCommandBuffer()
|
||||
end
|
||||
print( string.rep('--',20) )
|
||||
|
||||
end
|
||||
|
||||
local function main(args)
|
||||
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
|
||||
-- Arguments for the script
|
||||
for o, arg in getopt.getopt(args, 'h') do
|
||||
if o == "h" then return help() end
|
||||
end
|
||||
|
||||
core.clearCommandBuffer()
|
||||
test()
|
||||
print( string.rep('--',20) )
|
||||
end
|
||||
main(args)
|
139
client/scripts/test_t55x7_fsk.lua
Normal file
139
client/scripts/test_t55x7_fsk.lua
Normal file
|
@ -0,0 +1,139 @@
|
|||
local cmds = require('commands')
|
||||
local getopt = require('getopt')
|
||||
local bin = require('bin')
|
||||
local utils = require('utils')
|
||||
|
||||
example =[[
|
||||
1. script run test_t55x7_fsk
|
||||
]]
|
||||
author = "Iceman"
|
||||
usage = "script run test_t55x7_fsk"
|
||||
desc =[[
|
||||
This script will program a T55x7 TAG with the configuration: block 0x00 data 0x000100
|
||||
The outlined procedure is as following:
|
||||
|
||||
--ASK
|
||||
00 00 80 40
|
||||
-- max 2 blocks
|
||||
-- FSK1
|
||||
-- bit rate
|
||||
|
||||
"lf t55xx write 0 00007040"
|
||||
"lf t55xx detect"
|
||||
"lf t55xx info"
|
||||
|
||||
Loop:
|
||||
change the configuretion block 0 with:
|
||||
-xx 00 xxxx = RF/8
|
||||
-xx 04 xxxx = RF/16
|
||||
-xx 08 xxxx = RF/32
|
||||
-xx 0C xxxx = RF/40
|
||||
-xx 10 xxxx = RF/50
|
||||
-xx 14 xxxx = RF/64
|
||||
-xx 18 xxxx = RF/100
|
||||
-xx 1C xxxx = RF/128
|
||||
|
||||
|
||||
testsuit for the ASK/MANCHESTER demod
|
||||
|
||||
Arguments:
|
||||
-h : this help
|
||||
]]
|
||||
|
||||
local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
|
||||
local DEBUG = true -- the debug flag
|
||||
|
||||
--BLOCK 0 = 00008040 FSK
|
||||
local config1 = '00'
|
||||
local config2 = '040'
|
||||
|
||||
local procedurecmds = {
|
||||
[1] = '%s%02X%X%s',
|
||||
[2] = 'lf t55xx detect',
|
||||
[3] = 'lf t55xx info',
|
||||
}
|
||||
---
|
||||
-- A debug printout-function
|
||||
function dbg(args)
|
||||
if not DEBUG then
|
||||
return
|
||||
end
|
||||
|
||||
if type(args) == "table" then
|
||||
local i = 1
|
||||
while args[i] do
|
||||
dbg(args[i])
|
||||
i = i+1
|
||||
end
|
||||
else
|
||||
print("###", args)
|
||||
end
|
||||
end
|
||||
---
|
||||
-- This is only meant to be used when errors occur
|
||||
function oops(err)
|
||||
print("ERROR: ",err)
|
||||
end
|
||||
---
|
||||
-- Usage help
|
||||
function help()
|
||||
print(desc)
|
||||
print("Example usage")
|
||||
print(example)
|
||||
end
|
||||
--
|
||||
-- Exit message
|
||||
function ExitMsg(msg)
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
print(msg)
|
||||
print()
|
||||
end
|
||||
|
||||
function test(modulation)
|
||||
local y
|
||||
for y = 0x0, 0x1d, 0x4 do
|
||||
for _ = 1, #procedurecmds do
|
||||
local pcmd = procedurecmds[_]
|
||||
|
||||
if #pcmd == 0 then
|
||||
|
||||
elseif _ == 1 then
|
||||
|
||||
local config = pcmd:format(config1, y, modulation, config2)
|
||||
dbg(('lf t55xx write 0 %s'):format(config))
|
||||
|
||||
config = tonumber(config,16)
|
||||
local writecmd = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK, arg1 = config}
|
||||
local err = core.SendCommand(writecmd:getBytes())
|
||||
if err then return oops(err) end
|
||||
local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
|
||||
|
||||
else
|
||||
dbg(pcmd)
|
||||
core.console( pcmd )
|
||||
end
|
||||
end
|
||||
core.clearCommandBuffer()
|
||||
end
|
||||
print( string.rep('--',20) )
|
||||
end
|
||||
|
||||
local function main(args)
|
||||
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
|
||||
-- Arguments for the script
|
||||
for o, arg in getopt.getopt(args, 'h') do
|
||||
if o == "h" then return help() end
|
||||
end
|
||||
|
||||
core.clearCommandBuffer()
|
||||
test(4)
|
||||
test(5)
|
||||
test(6)
|
||||
test(7)
|
||||
print( string.rep('--',20) )
|
||||
end
|
||||
main(args)
|
|
@ -2,15 +2,14 @@ local cmds = require('commands')
|
|||
local getopt = require('getopt')
|
||||
local bin = require('bin')
|
||||
local utils = require('utils')
|
||||
local dumplib = require('html_dumplib')
|
||||
|
||||
example =[[
|
||||
1. script run tracetest
|
||||
2. script run tracetest -o
|
||||
1. script run test_t55x7_psk
|
||||
2. script run test_t55x7_psk -o
|
||||
|
||||
]]
|
||||
author = "Iceman"
|
||||
usage = "script run test_t55x7_psk -o <filename>"
|
||||
usage = "script run test_t55x7_psk"
|
||||
desc =[[
|
||||
This script will program a T55x7 TAG with the configuration: block 0x00 data 0x00088040
|
||||
The outlined procedure is as following:
|
||||
|
@ -39,26 +38,34 @@ In all 12 individual test for the PSK demod
|
|||
|
||||
Arguments:
|
||||
-h : this help
|
||||
-o : logfile name
|
||||
]]
|
||||
|
||||
local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
|
||||
local DEBUG = true -- the debug flag
|
||||
|
||||
--BLOCK 0 = 00088040
|
||||
local config1 = '0008'
|
||||
local config2 = '40'
|
||||
-- local procedurecmds = {
|
||||
-- [1] = '%s%s%s%s',
|
||||
-- [2] = 'lf read',
|
||||
-- --[3] = '',
|
||||
-- [3] = 'data samples',
|
||||
-- [4] = 'data pskdetectclock',
|
||||
-- [5] = 'data psknrzrawdemod',
|
||||
-- [6] = 'data pskindalademod',
|
||||
-- }
|
||||
|
||||
-- --BLOCK 0 = 00 08 80 40 PSK
|
||||
-- -----------
|
||||
-- 08------- bitrate
|
||||
-- 8----- modulation PSK1
|
||||
-- 0---- PSK ClockRate
|
||||
-- 40 max 2 blocks
|
||||
|
||||
local procedurecmds = {
|
||||
[1] = '%s%s%s%s',
|
||||
[2] = 'lf read',
|
||||
[1] = '00%02X%X%X40',
|
||||
[2] = 'lf t55xx detect',
|
||||
--[3] = '',
|
||||
[3] = 'data samples',
|
||||
[4] = 'data pskdetectclock',
|
||||
[5] = 'data psknrzrawdemod',
|
||||
[6] = 'data pskindalademod',
|
||||
[3] = 'lf t55xx info',
|
||||
}
|
||||
|
||||
---
|
||||
-- A debug printout-function
|
||||
function dbg(args)
|
||||
|
@ -97,10 +104,12 @@ function ExitMsg(msg)
|
|||
print()
|
||||
end
|
||||
|
||||
function pskTest(modulation)
|
||||
local y
|
||||
for y = 0, 8, 4 do
|
||||
for _ = 1, #procedurecmds do
|
||||
function test(modulation)
|
||||
local bitrate
|
||||
local clockrate
|
||||
for bitrate = 0x0, 0x1d, 0x4 do
|
||||
|
||||
for clockrate = 0,8,4 do
|
||||
local cmd = procedurecmds[_]
|
||||
|
||||
if #cmd == 0 then
|
||||
|
@ -109,33 +118,21 @@ function pskTest(modulation)
|
|||
|
||||
dbg("Writing to T55x7 TAG")
|
||||
|
||||
local configdata = cmd:format( config1, modulation , y, config2)
|
||||
local config = cmd:format(bitrate, modulation, clockrate)
|
||||
dbg(('lf t55xx write 0 %s'):format(config))
|
||||
|
||||
dbg( configdata)
|
||||
|
||||
local writecommand = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK, arg1 = configdata ,arg2 = 0, arg3 = 0}
|
||||
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)
|
||||
|
||||
if response then
|
||||
local count,cmd,arg0 = bin.unpack('LL',response)
|
||||
if(arg0==1) then
|
||||
dbg("Writing success")
|
||||
else
|
||||
return nil, "Couldn't read block.."
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
dbg(cmd)
|
||||
core.console( cmd )
|
||||
end
|
||||
end
|
||||
core.clearCommandBuffer()
|
||||
end
|
||||
print( string.rep('--',20) )
|
||||
|
||||
end
|
||||
|
||||
local function main(args)
|
||||
|
@ -143,31 +140,17 @@ local function main(args)
|
|||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
|
||||
local outputTemplate = os.date("testpsk_%Y-%m-%d_%H%M%S")
|
||||
|
||||
-- Arguments for the script
|
||||
for o, arg in getopt.getopt(args, 'ho:') do
|
||||
for o, arg in getopt.getopt(args, 'h') do
|
||||
if o == "h" then return help() end
|
||||
if o == "o" then outputTemplate = arg end
|
||||
end
|
||||
|
||||
core.clearCommandBuffer()
|
||||
|
||||
pskTest(1)
|
||||
pskTest(2)
|
||||
pskTest(3)
|
||||
pskTest(8)
|
||||
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
|
|
@ -6,19 +6,20 @@ local dumplib = require('html_dumplib')
|
|||
|
||||
example =[[
|
||||
1. script run tracetest
|
||||
2. script run tracetest -o
|
||||
|
||||
]]
|
||||
author = "Iceman"
|
||||
usage = "script run tracetest -o <filename>"
|
||||
usage = "script run tracetest"
|
||||
desc =[[
|
||||
This script will load several traces files in ../traces/ folder and do
|
||||
"data load"
|
||||
"lf search"
|
||||
"lf search 1 u"
|
||||
|
||||
The following tracefiles will be loaded:
|
||||
em*.pm3
|
||||
m*.pm3
|
||||
|
||||
Arguments:
|
||||
-h : this help
|
||||
-o : logfile name
|
||||
]]
|
||||
|
||||
local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
|
||||
|
@ -71,12 +72,12 @@ local function main(args)
|
|||
local tracesEM = "find '../traces/' -iname 'em*.pm3' -type f"
|
||||
local tracesMOD = "find '../traces/' -iname 'm*.pm3' -type f"
|
||||
|
||||
local write2File = false
|
||||
local outputTemplate = os.date("testtest_%Y-%m-%d_%H%M%S")
|
||||
|
||||
-- Arguments for the script
|
||||
for o, arg in getopt.getopt(args, 'ho:') do
|
||||
for o, arg in getopt.getopt(args, 'h') do
|
||||
if o == "h" then return help() end
|
||||
if o == "o" then outputTemplate = arg end
|
||||
end
|
||||
|
||||
core.clearCommandBuffer()
|
||||
|
@ -97,7 +98,7 @@ local function main(args)
|
|||
end
|
||||
p.close();
|
||||
|
||||
local cmdLFSEARCH = "lf search 1"
|
||||
local cmdLFSEARCH = "lf search 1 u"
|
||||
|
||||
-- main loop
|
||||
io.write('Starting to test traces > ')
|
||||
|
@ -119,13 +120,6 @@ local function main(args)
|
|||
end
|
||||
io.write('\n')
|
||||
|
||||
-- Write dump to files
|
||||
if not DEBUG then
|
||||
local bar = dumplib.SaveAsText(emldata, outputTemplate..'.txt')
|
||||
print(("Wrote output to: %s"):format(bar))
|
||||
end
|
||||
|
||||
-- Show info
|
||||
print( string.rep('--',20) )
|
||||
|
||||
end
|
||||
|
|
250
common/lfdemod.c
250
common/lfdemod.c
|
@ -75,51 +75,6 @@ uint8_t preambleSearch(uint8_t *BitStream, uint8_t *preamble, size_t pLen, size_
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//by marshmellow
|
||||
//takes 1s and 0s and searches for EM410x format - output EM ID
|
||||
uint64_t Em410xDecodeOld(uint8_t *BitStream, size_t *size, size_t *startIdx)
|
||||
{
|
||||
//no arguments needed - built this way in case we want this to be a direct call from "data " cmds in the future
|
||||
// otherwise could be a void with no arguments
|
||||
//set defaults
|
||||
uint64_t lo=0;
|
||||
uint32_t i = 0;
|
||||
if (BitStream[1]>1){ //allow only 1s and 0s
|
||||
// PrintAndLog("no data found");
|
||||
return 0;
|
||||
}
|
||||
// 111111111 bit pattern represent start of frame
|
||||
uint8_t preamble[] = {1,1,1,1,1,1,1,1,1};
|
||||
uint32_t idx = 0;
|
||||
uint32_t parityBits = 0;
|
||||
uint8_t errChk = 0;
|
||||
*startIdx = 0;
|
||||
for (uint8_t extraBitChk=0; extraBitChk<5; extraBitChk++){
|
||||
errChk = preambleSearch(BitStream+extraBitChk+*startIdx, preamble, sizeof(preamble), size, startIdx);
|
||||
if (errChk == 0) return 0;
|
||||
idx = *startIdx + 9;
|
||||
for (i=0; i<10;i++){ //loop through 10 sets of 5 bits (50-10p = 40 bits)
|
||||
parityBits = bytebits_to_byte(BitStream+(i*5)+idx,5);
|
||||
//check even parity
|
||||
if (parityTest(parityBits, 5, 0) == 0){
|
||||
//parity failed try next bit (in the case of 1111111111) but last 9 = preamble
|
||||
startIdx++;
|
||||
errChk = 0;
|
||||
break;
|
||||
}
|
||||
//set uint64 with ID from BitStream
|
||||
for (uint8_t ii=0; ii<4; ii++){
|
||||
lo = (lo << 1LL) | (BitStream[(i*5)+ii+idx]);
|
||||
}
|
||||
}
|
||||
if (errChk != 0) return lo;
|
||||
//skip last 5 bit parity test for simplicity.
|
||||
// *size = 64;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//by marshmellow
|
||||
//takes 1s and 0s and searches for EM410x format - output EM ID
|
||||
uint8_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx, uint32_t *hi, uint64_t *lo)
|
||||
|
@ -143,6 +98,7 @@ uint8_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx, uint32_
|
|||
errChk = preambleSearch(BitStream+extraBitChk+*startIdx, preamble, sizeof(preamble), size, startIdx);
|
||||
if (errChk == 0) return 0;
|
||||
if (*size>64) FmtLen = 22;
|
||||
if (*size<64) return 0;
|
||||
idx = *startIdx + 9;
|
||||
for (i=0; i<FmtLen; i++){ //loop through 10 or 22 sets of 5 bits (50-10p = 40 bits or 88 bits)
|
||||
parityBits = bytebits_to_byte(BitStream+(i*5)+idx,5);
|
||||
|
@ -308,16 +264,12 @@ int ManchesterEncode(uint8_t *BitStream, size_t size)
|
|||
//run through 2 times and take least errCnt
|
||||
int manrawdecode(uint8_t * BitStream, size_t *size)
|
||||
{
|
||||
uint16_t bitnum=0;
|
||||
uint16_t MaxBits = 500;
|
||||
uint16_t errCnt = 0;
|
||||
size_t i=1;
|
||||
uint16_t bestErr = 1000;
|
||||
uint16_t bestRun = 0;
|
||||
size_t ii=1;
|
||||
uint16_t bitnum=0, MaxBits = 512, errCnt = 0;
|
||||
size_t i, ii;
|
||||
uint16_t bestErr = 1000, bestRun = 0;
|
||||
if (size == 0) return -1;
|
||||
for (ii=1;ii<3;++ii){
|
||||
i=1;
|
||||
for (ii=0;ii<2;++ii){
|
||||
i=0;
|
||||
for (i=i+ii;i<*size-2;i+=2){
|
||||
if(BitStream[i]==1 && (BitStream[i+1]==0)){
|
||||
} else if((BitStream[i]==0)&& BitStream[i+1]==1){
|
||||
|
@ -335,7 +287,7 @@ int manrawdecode(uint8_t * BitStream, size_t *size)
|
|||
errCnt=bestErr;
|
||||
if (errCnt<20){
|
||||
ii=bestRun;
|
||||
i=1;
|
||||
i=0;
|
||||
for (i=i+ii; i < *size-2; i+=2){
|
||||
if(BitStream[i] == 1 && (BitStream[i+1] == 0)){
|
||||
BitStream[bitnum++]=0;
|
||||
|
@ -355,6 +307,7 @@ int manrawdecode(uint8_t * BitStream, size_t *size)
|
|||
//by marshmellow
|
||||
//take 01 or 10 = 1 and 11 or 00 = 0
|
||||
//check for phase errors - should never have 111 or 000 should be 01001011 or 10110100 for 1010
|
||||
//decodes biphase or if inverted it is AKA conditional dephase encoding AKA differential manchester encoding
|
||||
int BiphaseRawDecode(uint8_t *BitStream, size_t *size, int offset, int invert)
|
||||
{
|
||||
uint16_t bitnum=0;
|
||||
|
@ -372,7 +325,7 @@ int BiphaseRawDecode(uint8_t *BitStream, size_t *size, int offset, int invert)
|
|||
if (!offsetA && offsetB) offset++;
|
||||
for (i=offset; i<*size-3; i+=2){
|
||||
//check for phase error
|
||||
if (i<*size-3 && BitStream[i+1]==BitStream[i+2]) {
|
||||
if (BitStream[i+1]==BitStream[i+2]) {
|
||||
BitStream[bitnum++]=77;
|
||||
errCnt++;
|
||||
}
|
||||
|
@ -412,6 +365,51 @@ void askAmp(uint8_t *BitStream, size_t size)
|
|||
return;
|
||||
}
|
||||
|
||||
int cleanAskRawDemod(uint8_t *BinStream, size_t *size, int clk, int invert, int high, int low)
|
||||
{
|
||||
size_t bitCnt=0, smplCnt=0, errCnt=0;
|
||||
uint8_t waveHigh = 0;
|
||||
//PrintAndLog("clk: %d", clk);
|
||||
for (size_t i=0; i < *size; i++){
|
||||
if (BinStream[i] >= high && waveHigh){
|
||||
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;
|
||||
}
|
||||
waveHigh ^= 1;
|
||||
smplCnt = 0;
|
||||
} else if (!bitCnt) {
|
||||
//first bit
|
||||
waveHigh = (BinStream[i] >= high);
|
||||
smplCnt = 1;
|
||||
} else {
|
||||
//transition bit? ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
*size = bitCnt;
|
||||
return errCnt;
|
||||
}
|
||||
|
||||
//by marshmellow
|
||||
//takes 3 arguments - clock, invert and maxErr as integers
|
||||
//attempts to demodulate ask only
|
||||
|
@ -423,15 +421,22 @@ int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int max
|
|||
if (*clk==0) return -1;
|
||||
if (start<0) return -1;
|
||||
if (*invert != 0 && *invert != 1) *invert =0;
|
||||
if (amp==1) askAmp(BinStream, *size);
|
||||
|
||||
uint32_t initLoopMax = 200;
|
||||
if (initLoopMax > *size) initLoopMax=*size;
|
||||
// Detect high and lows
|
||||
//25% fuzz in case highs and lows aren't clipped [marshmellow]
|
||||
//25% clip in case highs and lows aren't clipped [marshmellow]
|
||||
uint8_t clip = 75;
|
||||
int high, low, ans;
|
||||
if (amp==1) askAmp(BinStream, *size);
|
||||
ans = getHiLo(BinStream, initLoopMax, &high, &low, 75, 75);
|
||||
ans = getHiLo(BinStream, initLoopMax, &high, &low, clip, clip);
|
||||
if (ans<1) return -1; //just noise
|
||||
|
||||
if (DetectCleanAskWave(BinStream, *size, high, low)) {
|
||||
//PrintAndLog("Clean");
|
||||
return cleanAskRawDemod(BinStream, size, *clk, *invert, 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
|
||||
|
@ -443,12 +448,13 @@ int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int max
|
|||
uint32_t gLen = *size;
|
||||
if (gLen > 500) gLen=500;
|
||||
//if 0 errors allowed then only try first 2 clock cycles as we want a low tolerance
|
||||
if (!maxErr) gLen=*clk*2;
|
||||
if (!maxErr) gLen = *clk * 2;
|
||||
uint8_t errCnt =0;
|
||||
uint32_t bestStart = *size;
|
||||
uint32_t bestErrCnt = maxErr; //(*size/1000);
|
||||
uint8_t midBit=0;
|
||||
uint16_t MaxBits=1000;
|
||||
|
||||
//PrintAndLog("DEBUG - lastbit - %d",lastBit);
|
||||
//loop to find first wave that works
|
||||
for (iii=start; iii < gLen; ++iii){
|
||||
|
@ -619,6 +625,8 @@ size_t fsk_wave_demod(uint8_t * dest, size_t size, uint8_t fchigh, uint8_t fclow
|
|||
//do nothing with extra garbage
|
||||
} else if ((idx-last_transition) < (fchigh-1)) { //6-8 = 8 waves
|
||||
dest[numBits]=1;
|
||||
} else if ((idx-last_transition) > (fchigh+1) && !numBits) { //12 + and first bit = garbage
|
||||
//do nothing with beginning garbage
|
||||
} else { //9+ = 10 waves
|
||||
dest[numBits]=0;
|
||||
}
|
||||
|
@ -643,18 +651,31 @@ size_t aggregate_bits(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t maxCons
|
|||
uint32_t idx=0;
|
||||
size_t numBits=0;
|
||||
uint32_t n=1;
|
||||
|
||||
float lowWaves = (((float)(rfLen))/((float)fclow));
|
||||
float highWaves = (((float)(rfLen))/((float)fchigh));
|
||||
for( idx=1; idx < size; idx++) {
|
||||
|
||||
if (dest[idx]==lastval) {
|
||||
n++;
|
||||
continue;
|
||||
}
|
||||
n++;
|
||||
//if lastval was 1, we have a 1->0 crossing
|
||||
if ( dest[idx-1]==1 ) {
|
||||
n=myround2((float)(n+1)/((float)(rfLen)/(float)fclow));
|
||||
if (dest[idx-1]==1) {
|
||||
if (!numBits && n < (uint8_t)lowWaves) {
|
||||
n=0;
|
||||
lastval = dest[idx];
|
||||
continue;
|
||||
}
|
||||
n=myround2(((float)n)/lowWaves);
|
||||
} else {// 0->1 crossing
|
||||
n=myround2((float)(n+1)/((float)(rfLen-1)/(float)fchigh)); //-1 for fudge factor
|
||||
//test first bitsample too small
|
||||
if (!numBits && n < (uint8_t)highWaves) {
|
||||
n=0;
|
||||
lastval = dest[idx];
|
||||
continue;
|
||||
}
|
||||
n = myround2(((float)n)/highWaves); //-1 for fudge factor
|
||||
}
|
||||
if (n == 0) n = 1;
|
||||
|
||||
|
@ -670,6 +691,17 @@ size_t aggregate_bits(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t maxCons
|
|||
n=0;
|
||||
lastval=dest[idx];
|
||||
}//end for
|
||||
|
||||
// if valid extra bits at the end were all the same frequency - add them in
|
||||
if (n > lowWaves && n > highWaves) {
|
||||
if (dest[idx-2]==1) {
|
||||
n=myround2((float)(n+1)/((float)(rfLen)/(float)fclow));
|
||||
} else {
|
||||
n=myround2((float)(n+1)/((float)(rfLen-1)/(float)fchigh)); //-1 for fudge factor
|
||||
}
|
||||
memset(dest, dest[idx-1]^invert , n);
|
||||
numBits += n;
|
||||
}
|
||||
return numBits;
|
||||
}
|
||||
//by marshmellow (from holiman's base)
|
||||
|
@ -858,18 +890,64 @@ uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, int high, int low)
|
|||
{
|
||||
uint8_t allPeaks=1;
|
||||
uint16_t cntPeaks=0;
|
||||
for (size_t i=20; i<255; i++){
|
||||
for (size_t i=30; i<255; i++){
|
||||
if (dest[i]>low && dest[i]<high)
|
||||
allPeaks=0;
|
||||
else
|
||||
cntPeaks++;
|
||||
}
|
||||
if (allPeaks==0){
|
||||
if (cntPeaks>190) return 1;
|
||||
if (cntPeaks>210) return 1;
|
||||
}
|
||||
return allPeaks;
|
||||
}
|
||||
|
||||
int DetectStrongAskClock(uint8_t dest[], size_t size)
|
||||
{
|
||||
int clk[]={0,8,16,32,40,50,64,100,128,256};
|
||||
size_t idx = 40;
|
||||
uint8_t high=0;
|
||||
size_t cnt = 0;
|
||||
size_t highCnt = 0;
|
||||
size_t highCnt2 = 0;
|
||||
for (;idx < size; idx++){
|
||||
if (dest[idx]>128) {
|
||||
if (!high){
|
||||
high=1;
|
||||
if (cnt > highCnt){
|
||||
if (highCnt != 0) highCnt2 = highCnt;
|
||||
highCnt = cnt;
|
||||
} else if (cnt > highCnt2) {
|
||||
highCnt2 = cnt;
|
||||
}
|
||||
cnt=1;
|
||||
} else {
|
||||
cnt++;
|
||||
}
|
||||
} else if (dest[idx] <= 128){
|
||||
if (high) {
|
||||
high=0;
|
||||
if (cnt > highCnt) {
|
||||
if (highCnt != 0) highCnt2 = highCnt;
|
||||
highCnt = cnt;
|
||||
} else if (cnt > highCnt2) {
|
||||
highCnt2 = cnt;
|
||||
}
|
||||
cnt=1;
|
||||
} else {
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (idx=8; idx>0; idx--){
|
||||
if (clk[idx] >= highCnt && clk[idx] <= highCnt+2)
|
||||
return clk[idx];
|
||||
if (clk[idx] >= highCnt2 && clk[idx] <= highCnt2+2)
|
||||
return clk[idx];
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 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?
|
||||
|
@ -892,24 +970,14 @@ int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr)
|
|||
|
||||
//test for large clean peaks
|
||||
if (DetectCleanAskWave(dest, size, peak, low)==1){
|
||||
uint16_t fcTest=0;
|
||||
uint8_t mostFC=0;
|
||||
fcTest=countFC(dest, size, &mostFC);
|
||||
uint8_t fc1 = fcTest >> 8;
|
||||
uint8_t fc2 = fcTest & 0xFF;
|
||||
|
||||
for (i=0; i<8; i++){
|
||||
if (clk[i] == fc1) {
|
||||
*clock=fc1;
|
||||
return 0;
|
||||
}
|
||||
if (clk[i] == fc2) {
|
||||
*clock=fc2;
|
||||
int ans = DetectStrongAskClock(dest, size);
|
||||
for (i=7; i>0; i--){
|
||||
if (clk[i] == ans) {
|
||||
*clock=ans;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ii;
|
||||
int clkCnt;
|
||||
int tol = 0;
|
||||
|
@ -923,6 +991,7 @@ int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr)
|
|||
}else{
|
||||
tol=0;
|
||||
}
|
||||
if (!maxErr) loopCnt=clk[clkCnt]*2;
|
||||
bestErr[clkCnt]=1000;
|
||||
//try lining up the peaks by moving starting point (try first 256)
|
||||
for (ii=0; ii < loopCnt; ii++){
|
||||
|
@ -1242,11 +1311,10 @@ int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr)
|
|||
*clk = DetectNRZClock(dest, *size, *clk);
|
||||
if (*clk==0) return -2;
|
||||
uint32_t i;
|
||||
int high, low, ans;
|
||||
ans = getHiLo(dest, 1260, &high, &low, 75, 75); //25% fuzz on high 25% fuzz on low
|
||||
if (ans<1) return -2; //just noise
|
||||
uint32_t gLen = 256;
|
||||
uint32_t gLen = 4096;
|
||||
if (gLen>*size) gLen = *size;
|
||||
int high, low;
|
||||
if (getHiLo(dest, gLen, &high, &low, 75, 75) < 1) return -3; //25% fuzz on high 25% fuzz on low
|
||||
int lastBit = 0; //set first clock check
|
||||
uint32_t bitnum = 0; //output counter
|
||||
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
|
||||
|
@ -1256,6 +1324,8 @@ int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr)
|
|||
uint32_t bestErrCnt = maxErr+1;
|
||||
uint32_t bestPeakCnt = 0;
|
||||
uint32_t bestPeakStart=0;
|
||||
uint8_t bestFirstPeakHigh=0;
|
||||
uint8_t firstPeakHigh=0;
|
||||
uint8_t curBit=0;
|
||||
uint8_t bitHigh=0;
|
||||
uint8_t errBitHigh=0;
|
||||
|
@ -1265,6 +1335,8 @@ int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr)
|
|||
//loop to find first wave that works - align to clock
|
||||
for (iii=0; iii < gLen; ++iii){
|
||||
if ((dest[iii]>=high) || (dest[iii]<=low)){
|
||||
if (dest[iii]>=high) firstPeakHigh=1;
|
||||
else firstPeakHigh=0;
|
||||
lastBit=iii-*clk;
|
||||
peakCnt=0;
|
||||
errCnt=0;
|
||||
|
@ -1315,6 +1387,7 @@ int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr)
|
|||
//possible good read
|
||||
if (errCnt == 0){
|
||||
//bestStart = iii;
|
||||
bestFirstPeakHigh=firstPeakHigh;
|
||||
bestErrCnt = errCnt;
|
||||
bestPeakCnt = peakCnt;
|
||||
bestPeakStart = iii;
|
||||
|
@ -1325,6 +1398,7 @@ int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr)
|
|||
//bestStart = iii;
|
||||
}
|
||||
if (peakCnt > bestPeakCnt){
|
||||
bestFirstPeakHigh=firstPeakHigh;
|
||||
bestPeakCnt=peakCnt;
|
||||
bestPeakStart=iii;
|
||||
}
|
||||
|
@ -1337,6 +1411,8 @@ int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr)
|
|||
iii=bestPeakStart;
|
||||
lastBit=bestPeakStart-*clk;
|
||||
bitnum=0;
|
||||
memset(dest, bestFirstPeakHigh^1, bestPeakStart / *clk);
|
||||
bitnum += (bestPeakStart / *clk);
|
||||
for (i = iii; i < *size; ++i) {
|
||||
//if we found a high bar and we are at a clock bit
|
||||
if ((dest[i] >= high ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){
|
||||
|
@ -1386,12 +1462,12 @@ int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr)
|
|||
*size=bitnum;
|
||||
} else{
|
||||
*size=bitnum;
|
||||
return -1;
|
||||
return bestErrCnt;
|
||||
}
|
||||
|
||||
if (bitnum>16){
|
||||
*size=bitnum;
|
||||
} else return -1;
|
||||
} else return -5;
|
||||
return errCnt;
|
||||
}
|
||||
|
||||
|
@ -1689,7 +1765,7 @@ int pskRawDemod(uint8_t dest[], size_t *size, int *clock, int *invert)
|
|||
errCnt=0;
|
||||
size_t numBits=0;
|
||||
//set skipped bits
|
||||
memset(dest+numBits,curPhase^1,firstFullWave / *clock);
|
||||
memset(dest,curPhase^1,firstFullWave / *clock);
|
||||
numBits += (firstFullWave / *clock);
|
||||
dest[numBits++] = curPhase; //set first read bit
|
||||
for (i = firstFullWave+fullWaveLen-1; i < *size-3; i++){
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <stdint.h>
|
||||
|
||||
int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr);
|
||||
uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, int high, int low);
|
||||
int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr);
|
||||
uint8_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx, uint32_t *hi, uint64_t *lo);
|
||||
//uint64_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx);
|
||||
|
@ -47,5 +48,6 @@ uint8_t justNoise(uint8_t *BitStream, size_t size);
|
|||
uint8_t countPSK_FC(uint8_t *BitStream, size_t size);
|
||||
int pskRawDemod(uint8_t dest[], size_t *size, int *clock, int *invert);
|
||||
int DetectPSKClock(uint8_t dest[], size_t size, int clock);
|
||||
void askAmp(uint8_t *BitStream, size_t size);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue