diff --git a/armsrc/appmain.c b/armsrc/appmain.c index fe947ce08..f8b675fa0 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -884,12 +884,27 @@ static void PacketReceived(PacketCommandNG *packet) { packet->oldarg[2] ); break; - case CMD_EM4X_READ_WORD: - EM4xReadWord(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2]); + case CMD_EM4X_READ_WORD: { + struct p { + uint32_t password; + uint8_t address; + uint8_t usepwd; + } PACKED; + struct p* payload = (struct p*) packet->data.asBytes; + EM4xReadWord(payload->address, payload->password, payload->usepwd); break; - case CMD_EM4X_WRITE_WORD: - EM4xWriteWord(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2]); + } + case CMD_EM4X_WRITE_WORD: { + struct p { + uint32_t password; + uint32_t data; + uint8_t address; + uint8_t usepwd; + } PACKED; + struct p* payload = (struct p*) packet->data.asBytes; + EM4xWriteWord(payload->address, payload->data, payload->password, payload->usepwd); break; + } case CMD_AWID_DEMOD_FSK: { uint32_t high, low; // Set realtime AWID demodulation diff --git a/armsrc/apps.h b/armsrc/apps.h index de307f6b9..a5866ebd5 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -110,8 +110,10 @@ void T55xxWakeUp(uint32_t Pwd); void T55xx_ChkPwds(void); void TurnReadLFOn(uint32_t delay); + void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd); -void EM4xWriteWord(uint32_t flag, uint32_t data, uint32_t pwd); +void EM4xWriteWord(uint8_t addr, uint32_t data, uint32_t pwd, uint8_t usepwd); + void Cotag(uint32_t arg0); void setT55xxConfig(uint8_t arg0, t55xx_config *c); t55xx_config *getT55xxConfig(void); diff --git a/armsrc/lfops.c b/armsrc/lfops.c index f52226181..a45c20d16 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -901,6 +901,12 @@ static void stAskSimBit(int *n, uint8_t clock) { memset(dest + (*n) + clock * 3, 1, clock); *n += clock * 4; } +static void leadingZeroAskSimBits(int *n, uint8_t clock) { + uint8_t *dest = BigBuf_get_addr(); + memset(dest + (*n), 0, clock * 8); + *n += clock * 8; +} + // args clock, ask/man or askraw, invert, transmission separator void CmdASKsimTAG(uint8_t encoding, uint8_t invert, uint8_t separator, uint8_t clk, uint16_t size, uint8_t *bits, bool ledcontrol) { @@ -909,23 +915,25 @@ void CmdASKsimTAG(uint8_t encoding, uint8_t invert, uint8_t separator, uint8_t c int n = 0, i = 0; + leadingZeroAskSimBits(&n, clk); + if (encoding == 2) { //biphase uint8_t phase = 0; for (i = 0; i < size; i++) { - biphaseSimBit(bits[i]^invert, &n, clk, &phase); + biphaseSimBit(bits[i] ^ invert, &n, clk, &phase); } if (phase == 1) { //run a second set inverted to keep phase in check for (i = 0; i < size; i++) { - biphaseSimBit(bits[i]^invert, &n, clk, &phase); + biphaseSimBit(bits[i] ^ invert, &n, clk, &phase); } } } else { // ask/manchester || ask/raw for (i = 0; i < size; i++) { - askSimBit(bits[i]^invert, &n, clk, encoding); + askSimBit(bits[i] ^ invert, &n, clk, encoding); } if (encoding == 0 && bits[0] == bits[size - 1]) { //run a second set inverted (for ask/raw || biphase phase) for (i = 0; i < size; i++) { - askSimBit(bits[i]^invert ^ 1, &n, clk, encoding); + askSimBit(bits[i] ^ invert ^ 1, &n, clk, encoding); } } } @@ -1202,7 +1210,7 @@ void CmdEM410xdemod(int findone, uint32_t *high, uint64_t *low, int ledcontrol) errCnt = askdemod(dest, &size, &clk, &invert, maxErr, 0, 1); WDT_HIT(); - if (errCnt < 0) continue; + if (errCnt > 50) continue; errCnt = Em410xDecode(dest, &size, &idx, &hi, &lo); if (errCnt == 1) { @@ -2030,16 +2038,13 @@ void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd) { DoPartialAcquisition(20, true, 6000, 1000); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - reply_old(CMD_ACK, 0, 0, 0, 0, 0); + reply_ng(CMD_EM4X_READ_WORD, PM3_SUCCESS, NULL, 0); LED_A_OFF(); } -void EM4xWriteWord(uint32_t flag, uint32_t data, uint32_t pwd) { +void EM4xWriteWord(uint8_t addr, uint32_t data, uint32_t pwd, uint8_t usepwd) { LED_A_ON(); - - bool usePwd = (flag & 0xF); - uint8_t addr = (flag >> 8) & 0xFF; uint8_t len; //clear buffer now so it does not interfere with timing later @@ -2051,7 +2056,7 @@ void EM4xWriteWord(uint32_t flag, uint32_t data, uint32_t pwd) { * 0000 1010 ok. * 0000 0001 fail **/ - if (usePwd) EM4xLogin(pwd); + if (usepwd) EM4xLogin(pwd); forward_ptr = forwardLink_data; len = Prepare_Cmd(FWD_CMD_WRITE); @@ -2066,7 +2071,7 @@ void EM4xWriteWord(uint32_t flag, uint32_t data, uint32_t pwd) { DoPartialAcquisition(20, true, 6000, 1000); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - reply_old(CMD_ACK, 0, 0, 0, 0, 0); + reply_ng(CMD_EM4X_WRITE_WORD, PM3_SUCCESS, NULL, 0); LED_A_OFF(); } diff --git a/client/cmddata.c b/client/cmddata.c index 59558c621..caeca4d3e 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -532,7 +532,7 @@ int ASKDemod_ext(const char *Cmd, bool verbose, bool emSearch, uint8_t askType, return PM3_ESOFT; } - if (verbose) PrintAndLogEx(DEBUG, "DEBUG: (ASKDemod_ext) Using clock:%d, invert:%d, bits found:%d", clk, invert, BitLen); + if (verbose) PrintAndLogEx(DEBUG, "DEBUG: (ASKDemod_ext) Using clock:%d, invert:%d, bits found:%d, start index %d", clk, invert, BitLen, startIdx); //output setDemodBuff(bits, BitLen, 0); @@ -684,7 +684,7 @@ static int CmdBiphaseDecodeRaw(const char *Cmd) { // - ASK Demod then Biphase decode GraphBuffer samples int ASKbiphaseDemod(const char *Cmd, bool verbose) { //ask raw demod GraphBuffer first - int offset = 0, clk = 0, invert = 0, maxErr = 100; + int offset = 0, clk = 0, invert = 0, maxErr = 50; sscanf(Cmd, "%i %i %i %i", &offset, &clk, &invert, &maxErr); uint8_t BitStream[MAX_DEMOD_BUF_LEN]; @@ -711,11 +711,12 @@ int ASKbiphaseDemod(const char *Cmd, bool verbose) { if (g_debugMode || verbose) PrintAndLogEx(DEBUG, "DEBUG: Error BiphaseRawDecode too many errors: %d", errCnt); return PM3_ESOFT; } + //success set DemodBuffer and return setDemodBuff(BitStream, size, 0); setClockGrid(clk, startIdx + clk * offset / 2); if (g_debugMode || verbose) { - PrintAndLogEx(NORMAL, "Biphase Decoded using offset: %d - clock: %d - # errors:%d - data:", offset, clk, errCnt); + PrintAndLogEx(NORMAL, "Biphase Decoded using offset %d | clock %d | #errors %d | start index %d\ndata\n", offset, clk, errCnt, (startIdx + clk * offset / 2) ); printDemodBuff(); } return PM3_SUCCESS; diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index a5e304a86..9b175f212 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -702,6 +702,7 @@ static bool EM_ByteParityTest(uint8_t *bs, size_t size, uint8_t rows, uint8_t co //c012345678| 0 // |- must be zero +/* static int EMwordparitytest(uint8_t *bits) { // last row/col parity must be 0 @@ -728,6 +729,7 @@ static int EMwordparitytest(uint8_t *bits) { // all checks ok. return PM3_SUCCESS; } +*/ //////////////// 4050 / 4450 commands @@ -1095,8 +1097,8 @@ static int setDemodBufferEM(uint32_t *word, size_t idx) { //test for even parity bits. uint8_t parity[45] = {0}; memcpy(parity, DemodBuffer, 45); - if (EMwordparitytest(parity) != PM3_SUCCESS) { - PrintAndLogEx(DEBUG, "DEBUG: Error - EM Parity tests failed"); + if (!EM_EndParityTest(DemodBuffer + idx + EM_PREAMBLE_LEN, 45, 5, 9, 0)) { + PrintAndLogEx(DEBUG, "DEBUG: Error - End Parity check failed"); return PM3_ESOFT; } @@ -1138,10 +1140,21 @@ static int demodEM4x05resp(uint32_t *word) { //////////////// 4205 / 4305 commands static int EM4x05ReadWord_ext(uint8_t addr, uint32_t pwd, bool usePwd, uint32_t *word) { + + struct { + uint32_t password; + uint8_t address; + uint8_t usepwd; + } PACKED payload; + + payload.password = pwd; + payload.address = addr; + payload.usepwd = usePwd; + clearCommandBuffer(); - SendCommandMIX(CMD_EM4X_READ_WORD, addr, pwd, usePwd, NULL, 0); + SendCommandNG(CMD_EM4X_READ_WORD, (uint8_t *)&payload, sizeof(payload)); PacketResponseNG resp; - if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) { + if (!WaitForResponseTimeout(CMD_EM4X_READ_WORD, &resp, 2500)) { PrintAndLogEx(DEBUG, "timeout while waiting for reply."); return PM3_ETIMEOUT; } @@ -1165,7 +1178,7 @@ static int CmdEM4x05Dump(const char *Cmd) { if (pwd != 1) usePwd = true; - int success = 1; + int success = PM3_SUCCESS; uint32_t word = 0; PrintAndLogEx(NORMAL, "Addr | data | ascii"); PrintAndLogEx(NORMAL, "-----+--------+------"); @@ -1193,13 +1206,13 @@ static int CmdEM4x05Read(const char *Cmd) { if (strlen(Cmd) == 0 || ctmp == 'h') return usage_lf_em4x05_read(); addr = param_get8ex(Cmd, 0, 50, 10); - pwd = param_get32ex(Cmd, 1, 1, 16); + pwd = param_get32ex(Cmd, 1, 0xFFFFFFFF, 16); if (addr > 15) { PrintAndLogEx(NORMAL, "Address must be between 0 and 15"); - return 1; + return PM3_ESOFT; } - if (pwd == 1) { + if (pwd == 0xFFFFFFFF) { PrintAndLogEx(NORMAL, "Reading address %02u", addr); } else { usePwd = true; @@ -1207,12 +1220,12 @@ static int CmdEM4x05Read(const char *Cmd) { } uint32_t word = 0; - int isOk = EM4x05ReadWord_ext(addr, pwd, usePwd, &word); - if (isOk) + int status = EM4x05ReadWord_ext(addr, pwd, usePwd, &word); + if (status == PM3_SUCCESS) PrintAndLogEx(NORMAL, "Address %02d | %08X - %s", addr, word, (addr > 13) ? "Lock" : ""); else PrintAndLogEx(NORMAL, "Read Address %02d | " _RED_("Fail"), addr); - return isOk; + return status; } static int CmdEM4x05Write(const char *Cmd) { @@ -1225,25 +1238,35 @@ static int CmdEM4x05Write(const char *Cmd) { addr = param_get8ex(Cmd, 0, 50, 10); data = param_get32ex(Cmd, 1, 0, 16); - pwd = param_get32ex(Cmd, 2, 1, 16); + pwd = param_get32ex(Cmd, 2, 0xFFFFFFFF, 16); if (addr > 15) { PrintAndLogEx(NORMAL, "Address must be between 0 and 15"); return PM3_EINVARG; } - if (pwd == 1) + if (pwd == 0xFFFFFFFF) PrintAndLogEx(NORMAL, "Writing address %d data %08X", addr, data); else { usePwd = true; PrintAndLogEx(NORMAL, "Writing address %d data %08X using password %08X", addr, data, pwd); } - uint16_t flag = (addr << 8) | (usePwd); - + struct { + uint32_t password; + uint32_t data; + uint8_t address; + uint8_t usepwd; + } PACKED payload; + + payload.password = pwd; + payload.data = data; + payload.address = addr; + payload.usepwd = usePwd; + clearCommandBuffer(); - SendCommandMIX(CMD_EM4X_WRITE_WORD, flag, data, pwd, NULL, 0); + SendCommandNG(CMD_EM4X_WRITE_WORD, (uint8_t*)&payload, sizeof(payload)); PacketResponseNG resp; - if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + if (!WaitForResponseTimeout(CMD_EM4X_WRITE_WORD, &resp, 2000)) { PrintAndLogEx(WARNING, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } @@ -1253,12 +1276,12 @@ static int CmdEM4x05Write(const char *Cmd) { //need 0 bits demoded (after preamble) to verify write cmd uint32_t dummy = 0; - int isOk = demodEM4x05resp(&dummy); - if (isOk) + int status = demodEM4x05resp(&dummy); + if (status == PM3_SUCCESS) PrintAndLogEx(NORMAL, "Write " _GREEN_("Verified")); else PrintAndLogEx(NORMAL, "Write could " _RED_("not") "be verified"); - return isOk; + return status; } static void printEM4x05config(uint32_t wordData) { @@ -1438,9 +1461,9 @@ static int CmdEM4x05Info(const char *Cmd) { if (ctmp == 'h') return usage_lf_em4x05_info(); // for now use default input of 1 as invalid (unlikely 1 will be a valid password...) - pwd = param_get32ex(Cmd, 0, 1, 16); + pwd = param_get32ex(Cmd, 0, 0xFFFFFFFF, 16); - if (pwd != 1) + if (pwd != 0xFFFFFFFF) usePwd = true; // read word 0 (chip info) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 8bf6ede8b..3bccd79ba 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -1585,28 +1585,28 @@ char *GetBitRateStr(uint32_t id, bool xmode) { } else { switch (id) { case 0: - snprintf(retStr, sizeof(buf), "%u - RF/8", id); + snprintf(retStr, sizeof(buf), "%u - "_GREEN_("RF/8"), id); break; case 1: - snprintf(retStr, sizeof(buf), "%u - RF/16", id); + snprintf(retStr, sizeof(buf), "%u - "_GREEN_("RF/16"), id); break; case 2: - snprintf(retStr, sizeof(buf), "%u - RF/32", id); + snprintf(retStr, sizeof(buf), "%u - "_GREEN_("RF/32"), id); break; case 3: - snprintf(retStr, sizeof(buf), "%u - RF/40", id); + snprintf(retStr, sizeof(buf), "%u - "_GREEN_("RF/40"), id); break; case 4: - snprintf(retStr, sizeof(buf), "%u - RF/50", id); + snprintf(retStr, sizeof(buf), "%u - "_GREEN_("RF/50"), id); break; case 5: - snprintf(retStr, sizeof(buf), "%u - RF/64", id); + snprintf(retStr, sizeof(buf), "%u - "_GREEN_("RF/64"), id); break; case 6: - snprintf(retStr, sizeof(buf), "%u - RF/100", id); + snprintf(retStr, sizeof(buf), "%u - "_GREEN_("RF/100"), id); break; case 7: - snprintf(retStr, sizeof(buf), "%u - RF/128", id); + snprintf(retStr, sizeof(buf), "%u - "_GREEN_("RF/128"), id); break; default: snprintf(retStr, sizeof(buf), "%u - " _RED_("(Unknown)"), id); diff --git a/common/lfdemod.c b/common/lfdemod.c index f7cc0fc31..f27c26931 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -41,7 +41,7 @@ #include // for uint_32+ #include // for bool #include "parity.h" // for parity test - +#include "commonutil.h" // colors //********************************************************************************************** //---------------------------------Utilities Section-------------------------------------------- //********************************************************************************************** @@ -82,7 +82,7 @@ static void printSignal(void) { prnt(" low...........%d", signalprop.low); prnt(" mean..........%d", signalprop.mean); prnt(" amplitude.....%d", signalprop.amplitude); - prnt(" is Noise......%s", (signalprop.isnoise) ? "Yes" : "No"); + prnt(" is Noise......%s", (signalprop.isnoise) ? _RED_("Yes") : _GREEN_("No")); prnt(" THRESHOLD noise amplitude......%d", NOISE_AMPLITUDE_THRESHOLD); } @@ -567,7 +567,7 @@ int DetectStrongAskClock(uint8_t *src, size_t size, int high, int low, int *cloc int DetectASKClock(uint8_t *dest, size_t size, int *clock, int maxErr) { //don't need to loop through entire array. (cotag has clock of 384) - uint16_t loopCnt = 1500; + uint16_t loopCnt = 2000; // not enough samples if (size <= loopCnt + 60) { @@ -1459,6 +1459,7 @@ static uint16_t cleanAskRawDemod(uint8_t *bits, size_t *size, int clk, int inver bool waveHigh = true; getNextHigh(bits, *size, high, &pos); +// getNextLow(bits, *size, low, &pos); // sample counts, like clock = 32.. it tries to find 32/4 = 8, 32/2 = 16 for (size_t i = pos; i < *size; i++) { @@ -1488,8 +1489,10 @@ static uint16_t cleanAskRawDemod(uint8_t *bits, size_t *size, int clk, int inver bits[bitCnt++] = invert ^ 1; bits[bitCnt++] = invert ^ 1; } - if (*startIdx == 0) + if (*startIdx == 0) { *startIdx = i - clk; + prnt("DEBUG ASK: cleanAskRawDemod minus clock [%d]", *startIdx); + } waveHigh = !waveHigh; smplCnt = 0; @@ -1507,8 +1510,10 @@ static uint16_t cleanAskRawDemod(uint8_t *bits, size_t *size, int clk, int inver } else if (!waveHigh) { bits[bitCnt++] = invert ^ 1; } - if (*startIdx == 0) + if (*startIdx == 0) { *startIdx = i - cl_2; + prnt("DEBUG ASK: cleanAskRawDemod minus half clock [%d]", *startIdx); + } waveHigh = !waveHigh; smplCnt = 0; } else { @@ -1523,10 +1528,12 @@ static uint16_t cleanAskRawDemod(uint8_t *bits, size_t *size, int clk, int inver *size = bitCnt; +/* if (*startIdx < 0) *startIdx = 0; +*/ - if (g_debugMode == 2) prnt("DEBUG ASK: cleanAskRawDemod Startidx %u ", *startIdx); + if (g_debugMode == 2) prnt("DEBUG ASK: cleanAskRawDemod Startidx %d", *startIdx); return errCnt; } @@ -1553,30 +1560,26 @@ int askdemod_ext(uint8_t *bits, size_t *size, int *clk, int *invert, int maxErr, if (g_debugMode == 2) prnt("DEBUG (askdemod_ext) clk %d, beststart %d, amp %d", *clk, start, amp); - //start pos from detect ask clock is 1/2 clock offset - // NOTE: can be negative (demod assumes rest of wave was there) - *startIdx = start - (*clk / 2); - uint16_t initLoopMax = 1024; - if (initLoopMax > *size) initLoopMax = *size; - // Detect high and lows //25% clip in case highs and lows aren't clipped [marshmellow] int high, low; - //getHiLo(bits, initLoopMax, &high, &low, 75, 75); getHiLo(&high, &low, 75, 75); size_t errCnt = 0; // if clean clipped waves detected run alternate demod if (DetectCleanAskWave(bits, *size, high, low)) { - if (g_debugMode == 2) prnt("DEBUG: (askdemod_ext) Clean wave detected"); + //start pos from detect ask clock is 1/2 clock offset + // NOTE: can be negative (demod assumes rest of wave was there) + *startIdx = start - (*clk / 2); + if (g_debugMode == 2) prnt("DEBUG: (askdemod_ext) Clean wave detected --- startindex %d", *startIdx); errCnt = cleanAskRawDemod(bits, size, *clk, *invert, high, low, startIdx); if (askType) { //ask/manchester uint8_t alignPos = 0; errCnt = manrawdecode(bits, size, 0, &alignPos); - *startIdx += *clk / 2 * alignPos; + *startIdx += ((*clk / 2) * alignPos); if (g_debugMode) prnt("DEBUG: (askdemod_ext) CLEAN: startIdx %i, alignPos %u , bestError %u", *startIdx, alignPos, errCnt); diff --git a/common/lfdemod.h b/common/lfdemod.h index 47a0c4e5e..4c9671ed4 100644 --- a/common/lfdemod.h +++ b/common/lfdemod.h @@ -21,7 +21,7 @@ #include "parity.h" // for parity test //might not be high enough for noisy environments -#define NOISE_AMPLITUDE_THRESHOLD 15 +#define NOISE_AMPLITUDE_THRESHOLD 8 //ignore buffer with less than x samples #define SIGNAL_MIN_SAMPLES 100 //ignore first x samples of the buffer