fix - parites needs to be reset between iterations, and resuse standard functions for clock

This commit is contained in:
iceman1001 2019-09-24 15:27:20 +02:00
parent 7352c19a72
commit 6ffae0e156

View file

@ -690,39 +690,43 @@ static int CmdEM410xWrite(const char *Cmd) {
}
//**************** Start of EM4x50 Code ************************
static bool EM_EndParityTest(uint8_t *bs, size_t size, uint8_t rows, uint8_t cols, uint8_t pType) {
// even parity COLUMN
static bool EM_ColParityTest(uint8_t *bs, size_t size, uint8_t rows, uint8_t cols, uint8_t pType) {
if (rows * cols > size) return false;
uint8_t colP = 0;
//assume last col is a parity and do not test
for (uint8_t colNum = 0; colNum < cols - 1; colNum++) {
for (uint8_t rowNum = 0; rowNum < rows; rowNum++) {
colP ^= bs[(rowNum * cols) + colNum];
for (uint8_t c = 0; c < cols - 1; c++) {
for (uint8_t r = 0; r < rows; r++) {
colP ^= bs[(r * cols) + c];
}
if (colP != pType) return false;
colP = 0;
}
return true;
}
static bool EM_ByteParityTest(uint8_t *bs, size_t size, uint8_t rows, uint8_t cols, uint8_t pType) {
// even parity ROW
static bool EM_RowParityTest(uint8_t *bs, size_t size, uint8_t rows, uint8_t cols, uint8_t pType) {
if (rows * cols > size) return false;
uint8_t rowP = 0;
//assume last row is a parity row and do not test
for (uint8_t rowNum = 0; rowNum < rows - 1; rowNum++) {
for (uint8_t colNum = 0; colNum < cols; colNum++) {
rowP ^= bs[(rowNum * cols) + colNum];
for (uint8_t r = 0; r < rows - 1; r++) {
for (uint8_t c = 0; c < cols; c++) {
rowP ^= bs[(r * cols) + c];
}
if (rowP != pType) return false;
rowP = 0;
}
return true;
}
// EM word parity test.
// 9*5 = 45 bits in total
// 012345678|r0
// 012345678|r1
// 012345678|r2
// 012345678|r3
// 012345678|r4
// ------------
//c012345678| 0
// |- must be zero
@ -795,7 +799,7 @@ static uint32_t OutputEM4x50_Block(uint8_t *BitStream, size_t size, bool verbose
* XXXXXXXX [row parity bit (even)] <- 8 bits plus parity
* XXXXXXXX [row parity bit (even)] <- 8 bits plus parity
* XXXXXXXX [row parity bit (even)] <- 8 bits plus parity
* CCCCCCCC <- column parity bits
* CCCCCCC0 <- column parity bits
* 0 <- stop bit
* LW <- Listen Window
*
@ -809,9 +813,8 @@ static uint32_t OutputEM4x50_Block(uint8_t *BitStream, size_t size, bool verbose
*/
//completed by Marshmellow
int EM4x50Read(const char *Cmd, bool verbose) {
uint8_t fndClk[] = {8, 16, 32, 40, 50, 64, 128};
int clk = 0, invert = 0, tol = 0, phaseoff;
int i = 0, j = 0, startblock, skip, block, start, end, low = 0, high = 0, minClk = 255;
int i = 0, j = 0, startblock, skip, block, start, end, low = 0, high = 0;
uint32_t Code[6];
char tmp[6];
char tmp2[20];
@ -833,16 +836,28 @@ int EM4x50Read(const char *Cmd, bool verbose) {
computeSignalProperties(bits, size);
signal_t *sp = getSignalProperties();
high = sp->high;
low = sp->low;
// get fuzzed HI / LOW limits in signal
getHiLo( &high, &low, 75, 75);
// get to first full low to prime loop and skip incomplete first pulse
while ((i < size) && (bits[i] < high))
++i;
while ((i < size) && (bits[i] > low))
++i;
skip = i;
size_t offset = 0;
getNextHigh(bits, size, high, &offset);
getNextLow(bits, size, low, &offset);
i = (int)offset;
skip = offset;
// set clock
if (clk == 0) {
DetectASKClock(bits, size, &clk, 0);
PrintAndLogEx(INFO, " ICE CLOCK %d", clk);
if (clk == 0) {
if (verbose || g_debugMode) PrintAndLogEx(ERR, "Error: EM4x50 - didn't find a clock");
return PM3_ESOFT;
}
}
// tolerance
tol = clk / 8;
// populate tmpbuff buffer with pulse lengths
while (i < size) {
@ -850,32 +865,18 @@ int EM4x50Read(const char *Cmd, bool verbose) {
while ((i < size) && (bits[i] > low))
++i;
start = i;
while ((i < size) && (bits[i] < high))
++i;
while ((i < size) && (bits[i] > low))
++i;
if (j >= (MAX_GRAPH_TRACE_LEN / 64)) {
break;
}
tmpbuff[j++] = i - start;
if (i - start < minClk && i < size) {
minClk = i - start;
}
}
// set clock
if (!clk) {
for (uint8_t clkCnt = 0; clkCnt < 7; clkCnt++) {
tol = fndClk[clkCnt] / 8;
if (minClk >= fndClk[clkCnt] - tol && minClk <= fndClk[clkCnt] + 1) {
clk = fndClk[clkCnt];
break;
}
}
if (!clk) {
if (verbose || g_debugMode) PrintAndLogEx(ERR, "Error: EM4x50 - didn't find a clock");
return PM3_ESOFT;
}
} else tol = clk / 8;
// look for data start - should be 2 pairs of LW (pulses of clk*3,clk*2)
start = -1;
@ -910,6 +911,7 @@ int EM4x50Read(const char *Cmd, bool verbose) {
}
}
end = i;
// report back
if (verbose || g_debugMode) {
if (start >= 0) {
@ -920,16 +922,23 @@ int EM4x50Read(const char *Cmd, bool verbose) {
PrintAndLogEx(NORMAL, " or after a " _YELLOW_("'data askedge'") " command to clean up the read");
return PM3_ESOFT;
}
} else if (start < 0) return PM3_ESOFT;
} else if (start < 0) {
return PM3_ESOFT;
}
start = skip;
snprintf(tmp2, sizeof(tmp2), "%d %d 1000 %d", clk, invert, clk * 47);
// save GraphBuffer - to restore it later
save_restoreGB(GRAPH_SAVE);
// get rid of leading crap
snprintf(tmp, sizeof(tmp), "%i", skip);
CmdLtrim(tmp);
bool AllPTest = true;
// now work through remaining buffer printing out data blocks
block = 0;
i = startblock;
@ -957,11 +966,12 @@ int EM4x50Read(const char *Cmd, bool verbose) {
save_restoreGB(GRAPH_RESTORE);
return PM3_ESOFT;
}
//set DemodBufferLen to just one block
DemodBufferLen = skip / clk;
//test parities
bool pTest = EM_ByteParityTest(DemodBuffer, DemodBufferLen, 5, 9, 0);
pTest &= EM_EndParityTest(DemodBuffer, DemodBufferLen, 5, 9, 0);
bool pTest = EM_RowParityTest(DemodBuffer, DemodBufferLen, 5, 9, 0);
pTest &= EM_ColParityTest(DemodBuffer, DemodBufferLen, 5, 9, 0);
AllPTest &= pTest;
//get output
Code[block] = OutputEM4x50_Block(DemodBuffer, DemodBufferLen, verbose, pTest);
@ -972,6 +982,7 @@ int EM4x50Read(const char *Cmd, bool verbose) {
block++;
if (i >= end) break; //in case chip doesn't output 6 blocks
}
//print full code:
if (verbose || g_debugMode || AllPTest) {
if (!complete) {
@ -1135,7 +1146,7 @@ static int setDemodBufferEM(uint32_t *word, size_t idx) {
//test for even parity bits.
uint8_t parity[45] = {0};
memcpy(parity, DemodBuffer, 45);
if (!EM_EndParityTest(DemodBuffer + idx + EM_PREAMBLE_LEN, 45, 5, 9, 0)) {
if (!EM_ColParityTest(DemodBuffer + idx + EM_PREAMBLE_LEN, 45, 5, 9, 0)) {
PrintAndLogEx(DEBUG, "DEBUG: Error - End Parity check failed");
return PM3_ESOFT;
}