mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-07-12 00:06:09 -07:00
Merge branch 'master' of github.com:Proxmark/proxmark3
This commit is contained in:
commit
a3abb02897
30 changed files with 1848 additions and 2065 deletions
|
@ -4,11 +4,13 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
|||
|
||||
## [Unreleased][unreleased]
|
||||
### Changed
|
||||
- Improved LF manchester and biphase demodulation and ask clock detection especially for reads with heavy clipping. (marshmellow)
|
||||
- Iclass read, `hf iclass read` now also reads tag config and prints configuration. (holiman)
|
||||
- *bootrom* needs to be flashed, due to new address boundaries between os and fpga, after a size optimization (piwi)
|
||||
|
||||
### Fixed
|
||||
- Fixed issue #19, problems with LF T55xx commands (marshmellow)
|
||||
- Fixed EM4x50 read/demod of the tags broadcasted memory blocks. 'lf em4x em4x50read' (not page read) (marshmellow)
|
||||
- Fixed issue #19, problems with LF T55xx commands (iceman1001, marshmellow)
|
||||
|
||||
### Added
|
||||
- Added changelog
|
||||
|
|
|
@ -861,7 +861,7 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
|
|||
size = BigBuf_max_traceLen();
|
||||
//askdemod and manchester decode
|
||||
if (size > 16385) size = 16385; //big enough to catch 2 sequences of largest format
|
||||
errCnt = askmandemod(dest, &size, &clk, &invert, maxErr);
|
||||
errCnt = askdemod(dest, &size, &clk, &invert, maxErr, 0, 1);
|
||||
WDT_HIT();
|
||||
|
||||
if (errCnt<0) continue;
|
||||
|
|
1023
client/cmddata.c
1023
client/cmddata.c
File diff suppressed because it is too large
Load diff
|
@ -15,10 +15,7 @@ command_t * CmdDataCommands();
|
|||
|
||||
int CmdData(const char *Cmd);
|
||||
void printDemodBuff(void);
|
||||
void printBitStream(uint8_t BitStream[], uint32_t bitLen);
|
||||
void setDemodBuf(uint8_t *buff, size_t size, size_t startIdx);
|
||||
int CmdAmp(const char *Cmd);
|
||||
int Cmdaskdemod(const char *Cmd);
|
||||
int CmdAskEM410xDemod(const char *Cmd);
|
||||
int CmdG_Prox_II_Demod(const char *Cmd);
|
||||
int Cmdaskrawdemod(const char *Cmd);
|
||||
|
@ -27,12 +24,10 @@ int AutoCorrelate(int window, bool SaveGrph, bool verbose);
|
|||
int CmdAutoCorr(const char *Cmd);
|
||||
int CmdBiphaseDecodeRaw(const char *Cmd);
|
||||
int CmdBitsamples(const char *Cmd);
|
||||
int CmdBitstream(const char *Cmd);
|
||||
int CmdBuffClear(const char *Cmd);
|
||||
int CmdDec(const char *Cmd);
|
||||
int CmdDetectClockRate(const char *Cmd);
|
||||
int CmdFSKdemodAWID(const char *Cmd);
|
||||
int CmdFSKdemod(const char *Cmd);
|
||||
int CmdFSKdemodHID(const char *Cmd);
|
||||
int CmdFSKdemodIO(const char *Cmd);
|
||||
int CmdFSKdemodParadox(const char *Cmd);
|
||||
|
@ -40,6 +35,7 @@ int CmdFSKdemodPyramid(const char *Cmd);
|
|||
int CmdFSKrawdemod(const char *Cmd);
|
||||
int CmdPSK1rawDemod(const char *Cmd);
|
||||
int CmdPSK2rawDemod(const char *Cmd);
|
||||
int CmdPSKNexWatch(const char *Cmd);
|
||||
int CmdGrid(const char *Cmd);
|
||||
int CmdGetBitStream(const char *Cmd);
|
||||
int CmdHexsamples(const char *Cmd);
|
||||
|
@ -49,24 +45,22 @@ int CmdLoad(const char *Cmd);
|
|||
int CmdLtrim(const char *Cmd);
|
||||
int CmdRtrim(const char *Cmd);
|
||||
int Cmdmandecoderaw(const char *Cmd);
|
||||
int CmdManchesterDemod(const char *Cmd);
|
||||
int CmdManchesterMod(const char *Cmd);
|
||||
int CmdNorm(const char *Cmd);
|
||||
int CmdNRZrawDemod(const char *Cmd);
|
||||
int CmdPlot(const char *Cmd);
|
||||
int CmdPrintDemodBuff(const char *Cmd);
|
||||
int CmdRawDemod(const char *Cmd);
|
||||
int CmdSamples(const char *Cmd);
|
||||
int CmdTuneSamples(const char *Cmd);
|
||||
int CmdSave(const char *Cmd);
|
||||
int CmdScale(const char *Cmd);
|
||||
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 AskEm410xDecode(bool verbose, uint32_t *hi, uint64_t *lo );
|
||||
int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo, bool verbose);
|
||||
int ASKbiphaseDemod(const char *Cmd, bool verbose);
|
||||
int ASKmanDemod(const char *Cmd, bool verbose, bool emSearch);
|
||||
int ASKrawDemod(const char *Cmd, bool verbose);
|
||||
int ASKDemod(const char *Cmd, bool verbose, bool emSearch, uint8_t askType);
|
||||
int FSKrawDemod(const char *Cmd, bool verbose);
|
||||
int PSKDemod(const char *Cmd, bool verbose);
|
||||
int NRZrawDemod(const char *Cmd, bool verbose);
|
||||
|
@ -77,7 +71,7 @@ int getSamples(const char *Cmd, bool silent);
|
|||
#define MAX_DEMOD_BUF_LEN (1024*128)
|
||||
extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
|
||||
extern int DemodBufferLen;
|
||||
|
||||
extern uint8_t g_debugMode;
|
||||
#define BIGBUF_SIZE 40000
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1499,16 +1499,16 @@ int CmdHF14AMfCSetUID(const char *Cmd)
|
|||
|
||||
int CmdHF14AMfCSetBlk(const char *Cmd)
|
||||
{
|
||||
uint8_t uid[8] = {0x00};
|
||||
uint8_t memBlock[16] = {0x00};
|
||||
uint8_t blockNo = 0;
|
||||
bool wipeCard = FALSE;
|
||||
int res;
|
||||
|
||||
if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
|
||||
PrintAndLog("Usage: hf mf csetblk <block number> <block data (32 hex symbols)>");
|
||||
PrintAndLog("Usage: hf mf csetblk <block number> <block data (32 hex symbols)> [w]");
|
||||
PrintAndLog("sample: hf mf csetblk 1 01020304050607080910111213141516");
|
||||
PrintAndLog("Set block data for magic Chinese card (only works with!!!)");
|
||||
PrintAndLog("If you want wipe card then add 'w' into command line. \n");
|
||||
PrintAndLog("Set block data for magic Chinese card (only works with such cards)");
|
||||
PrintAndLog("If you also want wipe the card then add 'w' at the end of the command line");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1519,14 +1519,15 @@ int CmdHF14AMfCSetBlk(const char *Cmd)
|
|||
return 1;
|
||||
}
|
||||
|
||||
char ctmp = param_getchar(Cmd, 2);
|
||||
wipeCard = (ctmp == 'w' || ctmp == 'W');
|
||||
PrintAndLog("--block number:%2d data:%s", blockNo, sprint_hex(memBlock, 16));
|
||||
|
||||
res = mfCSetBlock(blockNo, memBlock, uid, 0, CSETBLOCK_SINGLE_OPER);
|
||||
res = mfCSetBlock(blockNo, memBlock, NULL, wipeCard, CSETBLOCK_SINGLE_OPER);
|
||||
if (res) {
|
||||
PrintAndLog("Can't write block. error=%d", res);
|
||||
return 1;
|
||||
}
|
||||
|
||||
PrintAndLog("Can't write block. error=%d", res);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1637,7 +1638,7 @@ int CmdHF14AMfCGetBlk(const char *Cmd) {
|
|||
if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
|
||||
PrintAndLog("Usage: hf mf cgetblk <block number>");
|
||||
PrintAndLog("sample: hf mf cgetblk 1");
|
||||
PrintAndLog("Get block data from magic Chinese card (only works with!!!)\n");
|
||||
PrintAndLog("Get block data from magic Chinese card (only works with such cards)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1664,7 +1665,7 @@ int CmdHF14AMfCGetSc(const char *Cmd) {
|
|||
if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
|
||||
PrintAndLog("Usage: hf mf cgetsc <sector number>");
|
||||
PrintAndLog("sample: hf mf cgetsc 0");
|
||||
PrintAndLog("Get sector data from magic Chinese card (only works with!!!)\n");
|
||||
PrintAndLog("Get sector data from magic Chinese card (only works with such cards)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -522,7 +522,8 @@ static void ChkBitstream(const char *str)
|
|||
}
|
||||
}
|
||||
}
|
||||
//appears to attempt to simulate manchester
|
||||
//Attempt to simulate any wave in buffer (one bit per output sample)
|
||||
// converts GraphBuffer to bitstream (based on zero crossings) if needed.
|
||||
int CmdLFSim(const char *Cmd)
|
||||
{
|
||||
int i,j;
|
||||
|
@ -530,11 +531,11 @@ int CmdLFSim(const char *Cmd)
|
|||
|
||||
sscanf(Cmd, "%i", &gap);
|
||||
|
||||
/* convert to bitstream if necessary */
|
||||
// convert to bitstream if necessary
|
||||
|
||||
ChkBitstream(Cmd);
|
||||
|
||||
//can send 512 bits at a time (1 byte sent per bit...)
|
||||
//can send only 512 bits at a time (1 byte sent per bit...)
|
||||
printf("Sending [%d bytes]", GraphTraceLen);
|
||||
for (i = 0; i < GraphTraceLen; i += USB_CMD_DATA_SIZE) {
|
||||
UsbCommand c={CMD_DOWNLOADED_SIM_SAMPLES_125K, {i, 0, 0}};
|
||||
|
@ -606,8 +607,8 @@ int usage_lf_simpsk(void)
|
|||
// - allow pull data from DemodBuffer
|
||||
int CmdLFfskSim(const char *Cmd)
|
||||
{
|
||||
//might be able to autodetect FC and clock from Graphbuffer if using demod buffer
|
||||
//will need FChigh, FClow, Clock, and bitstream
|
||||
//might be able to autodetect FCs and clock from Graphbuffer if using demod buffer
|
||||
// otherwise will need FChigh, FClow, Clock, and bitstream
|
||||
uint8_t fcHigh=0, fcLow=0, clk=0;
|
||||
uint8_t invert=0;
|
||||
bool errors = FALSE;
|
||||
|
@ -682,6 +683,8 @@ int CmdLFfskSim(const char *Cmd)
|
|||
} else {
|
||||
setDemodBuf(data, dataLen, 0);
|
||||
}
|
||||
|
||||
//default if not found
|
||||
if (clk == 0) clk = 50;
|
||||
if (fcHigh == 0) fcHigh = 10;
|
||||
if (fcLow == 0) fcLow = 8;
|
||||
|
@ -706,9 +709,8 @@ int CmdLFfskSim(const char *Cmd)
|
|||
int CmdLFaskSim(const char *Cmd)
|
||||
{
|
||||
//autodetect clock from Graphbuffer if using demod buffer
|
||||
//will need clock, invert, manchester/raw as m or r, separator as s, and bitstream
|
||||
// needs clock, invert, manchester/raw as m or r, separator as s, and bitstream
|
||||
uint8_t encoding = 1, separator = 0;
|
||||
//char cmdp = Cmd[0], par3='m', par4=0;
|
||||
uint8_t clk=0, invert=0;
|
||||
bool errors = FALSE;
|
||||
char hexData[32] = {0x00};
|
||||
|
@ -913,30 +915,6 @@ int CmdLFSimBidir(const char *Cmd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* simulate an LF Manchester encoded tag with specified bitstream, clock rate and inter-id gap */
|
||||
/*
|
||||
int CmdLFSimManchester(const char *Cmd)
|
||||
{
|
||||
static int clock, gap;
|
||||
static char data[1024], gapstring[8];
|
||||
|
||||
sscanf(Cmd, "%i %s %i", &clock, &data[0], &gap);
|
||||
|
||||
ClearGraph(0);
|
||||
|
||||
for (int i = 0; i < strlen(data) ; ++i)
|
||||
AppendGraph(0, clock, data[i]- '0');
|
||||
|
||||
CmdManchesterMod("");
|
||||
|
||||
RepaintGraphWindow();
|
||||
|
||||
sprintf(&gapstring[0], "%i", gap);
|
||||
CmdLFSim(gapstring);
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
int CmdVchDemod(const char *Cmd)
|
||||
{
|
||||
// Is this the entire sync pattern, or does this also include some
|
||||
|
@ -1033,8 +1011,8 @@ int CmdLFfind(const char *Cmd)
|
|||
}
|
||||
|
||||
if (!offline && (cmdp != '1')){
|
||||
ans=CmdLFRead("");
|
||||
ans=CmdSamples("20000");
|
||||
CmdLFRead("s");
|
||||
getSamples("30000",false);
|
||||
} else if (GraphTraceLen < 1000) {
|
||||
PrintAndLog("Data in Graphbuffer was too small.");
|
||||
return 0;
|
||||
|
@ -1094,26 +1072,36 @@ int CmdLFfind(const char *Cmd)
|
|||
return 1;
|
||||
}
|
||||
|
||||
ans=EM4x50Read("", false);
|
||||
if (ans>0) {
|
||||
PrintAndLog("\nValid EM4x50 ID Found!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
ans=CmdPSKNexWatch("");
|
||||
if (ans>0) {
|
||||
PrintAndLog("\nValid NexWatch ID Found!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
PrintAndLog("\nNo Known Tags Found!\n");
|
||||
if (testRaw=='u' || testRaw=='U'){
|
||||
//test unknown tag formats (raw mode)
|
||||
PrintAndLog("\nChecking for Unknown tags:\n");
|
||||
ans=AutoCorrelate(4000, FALSE, FALSE);
|
||||
if (ans > 0) PrintAndLog("Possible Auto Correlation of %d repeating samples",ans);
|
||||
ans=GetFskClock("",FALSE,FALSE); //CmdDetectClockRate("F"); //
|
||||
ans=GetFskClock("",FALSE,FALSE);
|
||||
if (ans != 0){ //fsk
|
||||
ans=FSKrawDemod("",FALSE);
|
||||
ans=FSKrawDemod("",TRUE);
|
||||
if (ans>0) {
|
||||
PrintAndLog("\nUnknown FSK Modulated Tag Found!");
|
||||
printDemodBuff();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
ans=ASKmanDemod("",FALSE,FALSE);
|
||||
ans=ASKDemod("0 0 0",TRUE,FALSE,1);
|
||||
if (ans>0) {
|
||||
PrintAndLog("\nUnknown ASK Modulated and Manchester encoded Tag Found!");
|
||||
PrintAndLog("\nif it does not look right it could instead be ASK/Biphase - try 'data rawdemod ab'");
|
||||
printDemodBuff();
|
||||
return 1;
|
||||
}
|
||||
ans=CmdPSK1rawDemod("");
|
||||
|
@ -1121,7 +1109,6 @@ int CmdLFfind(const char *Cmd)
|
|||
PrintAndLog("Possible unknown PSK1 Modulated Tag Found above!\n\nCould also be PSK2 - try 'data rawdemod p2'");
|
||||
PrintAndLog("\nCould also be PSK3 - [currently not supported]");
|
||||
PrintAndLog("\nCould also be NRZ - try 'data nrzrawdemod");
|
||||
printDemodBuff();
|
||||
return 1;
|
||||
}
|
||||
PrintAndLog("\nNo Data Found!\n");
|
||||
|
@ -1147,7 +1134,6 @@ static command_t CommandTable[] =
|
|||
{"simfsk", CmdLFfskSim, 0, "[c <clock>] [i] [H <fcHigh>] [L <fcLow>] [d <hexdata>] -- Simulate LF FSK tag from demodbuffer or input"},
|
||||
{"simpsk", CmdLFpskSim, 0, "[1|2|3] [c <clock>] [i] [r <carrier>] [d <raw hex to sim>] -- Simulate LF PSK tag from demodbuffer or input"},
|
||||
{"simbidir", CmdLFSimBidir, 0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"},
|
||||
//{"simman", CmdLFSimManchester, 0, "<Clock> <Bitstream> [GAP] Simulate arbitrary Manchester LF tag"},
|
||||
{"snoop", CmdLFSnoop, 0, "['l'|'h'|<divisor>] [trigger threshold]-- Snoop LF (l:125khz, h:134khz)"},
|
||||
{"ti", CmdLFTI, 1, "{ TI RFIDs... }"},
|
||||
{"hitag", CmdLFHitag, 1, "{ Hitag tags and transponders... }"},
|
||||
|
|
|
@ -23,7 +23,6 @@ int CmdLFaskSim(const char *Cmd);
|
|||
int CmdLFfskSim(const char *Cmd);
|
||||
int CmdLFpskSim(const char *Cmd);
|
||||
int CmdLFSimBidir(const char *Cmd);
|
||||
//int CmdLFSimManchester(const char *Cmd);
|
||||
int CmdLFSnoop(const char *Cmd);
|
||||
int CmdVchDemod(const char *Cmd);
|
||||
int CmdLFfind(const char *Cmd);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "cmddata.h"
|
||||
#include "cmdlf.h"
|
||||
#include "cmdlfem4x.h"
|
||||
#include "lfdemod.h"
|
||||
char *global_em410xId;
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
@ -27,10 +28,10 @@ int CmdEMdemodASK(const char *Cmd)
|
|||
{
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
int findone = (cmdp == '1') ? 1 : 0;
|
||||
UsbCommand c={CMD_EM410X_DEMOD};
|
||||
c.arg[0]=findone;
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
UsbCommand c={CMD_EM410X_DEMOD};
|
||||
c.arg[0]=findone;
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read the ID of an EM410x tag.
|
||||
|
@ -43,21 +44,21 @@ int CmdEMdemodASK(const char *Cmd)
|
|||
*/
|
||||
int CmdEM410xRead(const char *Cmd)
|
||||
{
|
||||
uint32_t hi=0;
|
||||
uint64_t lo=0;
|
||||
uint32_t hi=0;
|
||||
uint64_t lo=0;
|
||||
|
||||
if(!AskEm410xDemod("", &hi, &lo)) return 0;
|
||||
PrintAndLog("EM410x pattern found: ");
|
||||
printEM410x(hi, lo);
|
||||
if (hi){
|
||||
PrintAndLog ("EM410x XL pattern found");
|
||||
return 0;
|
||||
}
|
||||
char id[12] = {0x00};
|
||||
sprintf(id, "%010llx",lo);
|
||||
if(!AskEm410xDemod("", &hi, &lo, false)) return 0;
|
||||
PrintAndLog("EM410x pattern found: ");
|
||||
printEM410x(hi, lo);
|
||||
if (hi){
|
||||
PrintAndLog ("EM410x XL pattern found");
|
||||
return 0;
|
||||
}
|
||||
char id[12] = {0x00};
|
||||
sprintf(id, "%010llx",lo);
|
||||
|
||||
global_em410xId = id;
|
||||
return 1;
|
||||
global_em410xId = id;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// emulate an EM410X tag
|
||||
|
@ -83,52 +84,52 @@ int CmdEM410xSim(const char *Cmd)
|
|||
PrintAndLog("Starting simulating UID %02X%02X%02X%02X%02X", uid[0],uid[1],uid[2],uid[3],uid[4]);
|
||||
PrintAndLog("Press pm3-button to about simulation");
|
||||
|
||||
/* clock is 64 in EM410x tags */
|
||||
int clock = 64;
|
||||
/* clock is 64 in EM410x tags */
|
||||
int clock = 64;
|
||||
|
||||
/* clear our graph */
|
||||
ClearGraph(0);
|
||||
/* clear our graph */
|
||||
ClearGraph(0);
|
||||
|
||||
/* write 9 start bits */
|
||||
for (i = 0; i < 9; i++)
|
||||
AppendGraph(0, clock, 1);
|
||||
/* write 9 start bits */
|
||||
for (i = 0; i < 9; i++)
|
||||
AppendGraph(0, clock, 1);
|
||||
|
||||
/* for each hex char */
|
||||
parity[0] = parity[1] = parity[2] = parity[3] = 0;
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
/* read each hex char */
|
||||
sscanf(&Cmd[i], "%1x", &n);
|
||||
for (j = 3; j >= 0; j--, n/= 2)
|
||||
binary[j] = n % 2;
|
||||
/* for each hex char */
|
||||
parity[0] = parity[1] = parity[2] = parity[3] = 0;
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
/* read each hex char */
|
||||
sscanf(&Cmd[i], "%1x", &n);
|
||||
for (j = 3; j >= 0; j--, n/= 2)
|
||||
binary[j] = n % 2;
|
||||
|
||||
/* append each bit */
|
||||
AppendGraph(0, clock, binary[0]);
|
||||
AppendGraph(0, clock, binary[1]);
|
||||
AppendGraph(0, clock, binary[2]);
|
||||
AppendGraph(0, clock, binary[3]);
|
||||
/* append each bit */
|
||||
AppendGraph(0, clock, binary[0]);
|
||||
AppendGraph(0, clock, binary[1]);
|
||||
AppendGraph(0, clock, binary[2]);
|
||||
AppendGraph(0, clock, binary[3]);
|
||||
|
||||
/* append parity bit */
|
||||
AppendGraph(0, clock, binary[0] ^ binary[1] ^ binary[2] ^ binary[3]);
|
||||
/* append parity bit */
|
||||
AppendGraph(0, clock, binary[0] ^ binary[1] ^ binary[2] ^ binary[3]);
|
||||
|
||||
/* keep track of column parity */
|
||||
parity[0] ^= binary[0];
|
||||
parity[1] ^= binary[1];
|
||||
parity[2] ^= binary[2];
|
||||
parity[3] ^= binary[3];
|
||||
}
|
||||
/* keep track of column parity */
|
||||
parity[0] ^= binary[0];
|
||||
parity[1] ^= binary[1];
|
||||
parity[2] ^= binary[2];
|
||||
parity[3] ^= binary[3];
|
||||
}
|
||||
|
||||
/* parity columns */
|
||||
AppendGraph(0, clock, parity[0]);
|
||||
AppendGraph(0, clock, parity[1]);
|
||||
AppendGraph(0, clock, parity[2]);
|
||||
AppendGraph(0, clock, parity[3]);
|
||||
/* parity columns */
|
||||
AppendGraph(0, clock, parity[0]);
|
||||
AppendGraph(0, clock, parity[1]);
|
||||
AppendGraph(0, clock, parity[2]);
|
||||
AppendGraph(0, clock, parity[3]);
|
||||
|
||||
/* stop bit */
|
||||
AppendGraph(1, clock, 0);
|
||||
/* stop bit */
|
||||
AppendGraph(1, clock, 0);
|
||||
|
||||
CmdLFSim("0"); //240 start_gap.
|
||||
return 0;
|
||||
CmdLFSim("0"); //240 start_gap.
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Function is equivalent of lf read + data samples + em410xread
|
||||
|
@ -139,7 +140,6 @@ int CmdEM410xSim(const char *Cmd)
|
|||
* rate gets lower, then grow the number of samples
|
||||
* Changed by martin, 4000 x 4 = 16000,
|
||||
* see http://www.proxmark.org/forum/viewtopic.php?pid=7235#p7235
|
||||
|
||||
*/
|
||||
int CmdEM410xWatch(const char *Cmd)
|
||||
{
|
||||
|
@ -150,12 +150,13 @@ int CmdEM410xWatch(const char *Cmd)
|
|||
}
|
||||
|
||||
CmdLFRead("s");
|
||||
getSamples("8192",true); //capture enough to get 2 full messages
|
||||
getSamples("8201",true); //capture enough to get 2 complete preambles (4096*2+9)
|
||||
} while (!CmdEM410xRead(""));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//currently only supports manchester modulations
|
||||
int CmdEM410xWatchnSpoof(const char *Cmd)
|
||||
{
|
||||
CmdEM410xWatch(Cmd);
|
||||
|
@ -164,154 +165,10 @@ int CmdEM410xWatchnSpoof(const char *Cmd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Read the transmitted data of an EM4x50 tag
|
||||
* Format:
|
||||
*
|
||||
* 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
|
||||
* XXXXXXXX [row parity bit (even)] <- 8 bits plus parity
|
||||
* CCCCCCCC <- column parity bits
|
||||
* 0 <- stop bit
|
||||
* LW <- Listen Window
|
||||
*
|
||||
* This pattern repeats for every block of data being transmitted.
|
||||
* Transmission starts with two Listen Windows (LW - a modulated
|
||||
* pattern of 320 cycles each (32/32/128/64/64)).
|
||||
*
|
||||
* Note that this data may or may not be the UID. It is whatever data
|
||||
* is stored in the blocks defined in the control word First and Last
|
||||
* Word Read values. UID is stored in block 32.
|
||||
*/
|
||||
int CmdEM4x50Read(const char *Cmd)
|
||||
{
|
||||
int i, j, startblock, skip, block, start, end, low, high;
|
||||
bool complete= false;
|
||||
int tmpbuff[MAX_GRAPH_TRACE_LEN / 64];
|
||||
char tmp[6];
|
||||
|
||||
high= low= 0;
|
||||
memset(tmpbuff, 0, MAX_GRAPH_TRACE_LEN / 64);
|
||||
|
||||
/* first get high and low values */
|
||||
for (i = 0; i < GraphTraceLen; i++)
|
||||
{
|
||||
if (GraphBuffer[i] > high)
|
||||
high = GraphBuffer[i];
|
||||
else if (GraphBuffer[i] < low)
|
||||
low = GraphBuffer[i];
|
||||
}
|
||||
|
||||
/* populate a buffer with pulse lengths */
|
||||
i= 0;
|
||||
j= 0;
|
||||
while (i < GraphTraceLen)
|
||||
{
|
||||
// measure from low to low
|
||||
while ((GraphBuffer[i] > low) && (i<GraphTraceLen))
|
||||
++i;
|
||||
start= i;
|
||||
while ((GraphBuffer[i] < high) && (i<GraphTraceLen))
|
||||
++i;
|
||||
while ((GraphBuffer[i] > low) && (i<GraphTraceLen))
|
||||
++i;
|
||||
if (j>=(MAX_GRAPH_TRACE_LEN/64)) {
|
||||
break;
|
||||
}
|
||||
tmpbuff[j++]= i - start;
|
||||
}
|
||||
|
||||
/* look for data start - should be 2 pairs of LW (pulses of 192,128) */
|
||||
start= -1;
|
||||
skip= 0;
|
||||
for (i= 0; i < j - 4 ; ++i)
|
||||
{
|
||||
skip += tmpbuff[i];
|
||||
if (tmpbuff[i] >= 190 && tmpbuff[i] <= 194)
|
||||
if (tmpbuff[i+1] >= 126 && tmpbuff[i+1] <= 130)
|
||||
if (tmpbuff[i+2] >= 190 && tmpbuff[i+2] <= 194)
|
||||
if (tmpbuff[i+3] >= 126 && tmpbuff[i+3] <= 130)
|
||||
{
|
||||
start= i + 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
startblock= i + 3;
|
||||
|
||||
/* skip over the remainder of the LW */
|
||||
skip += tmpbuff[i+1]+tmpbuff[i+2];
|
||||
while (skip < MAX_GRAPH_TRACE_LEN && GraphBuffer[skip] > low)
|
||||
++skip;
|
||||
skip += 8;
|
||||
|
||||
/* now do it again to find the end */
|
||||
end= start;
|
||||
for (i += 3; i < j - 4 ; ++i)
|
||||
{
|
||||
end += tmpbuff[i];
|
||||
if (tmpbuff[i] >= 190 && tmpbuff[i] <= 194)
|
||||
if (tmpbuff[i+1] >= 126 && tmpbuff[i+1] <= 130)
|
||||
if (tmpbuff[i+2] >= 190 && tmpbuff[i+2] <= 194)
|
||||
if (tmpbuff[i+3] >= 126 && tmpbuff[i+3] <= 130)
|
||||
{
|
||||
complete= true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (start >= 0)
|
||||
PrintAndLog("Found data at sample: %i",skip);
|
||||
else
|
||||
{
|
||||
PrintAndLog("No data found!");
|
||||
PrintAndLog("Try again with more samples.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!complete)
|
||||
{
|
||||
PrintAndLog("*** Warning!");
|
||||
PrintAndLog("Partial data - no end found!");
|
||||
PrintAndLog("Try again with more samples.");
|
||||
}
|
||||
|
||||
/* get rid of leading crap */
|
||||
sprintf(tmp,"%i",skip);
|
||||
CmdLtrim(tmp);
|
||||
|
||||
/* now work through remaining buffer printing out data blocks */
|
||||
block= 0;
|
||||
i= startblock;
|
||||
while (block < 6)
|
||||
{
|
||||
PrintAndLog("Block %i:", block);
|
||||
// mandemod routine needs to be split so we can call it for data
|
||||
// just print for now for debugging
|
||||
CmdManchesterDemod("i 64");
|
||||
skip= 0;
|
||||
/* look for LW before start of next block */
|
||||
for ( ; i < j - 4 ; ++i)
|
||||
{
|
||||
skip += tmpbuff[i];
|
||||
if (tmpbuff[i] >= 190 && tmpbuff[i] <= 194)
|
||||
if (tmpbuff[i+1] >= 126 && tmpbuff[i+1] <= 130)
|
||||
break;
|
||||
}
|
||||
while (GraphBuffer[skip] > low)
|
||||
++skip;
|
||||
skip += 8;
|
||||
sprintf(tmp,"%i",skip);
|
||||
CmdLtrim(tmp);
|
||||
start += skip;
|
||||
block++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdEM410xWrite(const char *Cmd)
|
||||
{
|
||||
uint64_t id = 0xFFFFFFFFFFFFFFFF; // invalid id value
|
||||
int card = 0xFF; // invalid card value
|
||||
uint64_t id = 0xFFFFFFFFFFFFFFFF; // invalid id value
|
||||
int card = 0xFF; // invalid card value
|
||||
unsigned int clock = 0; // invalid clock value
|
||||
|
||||
sscanf(Cmd, "%" PRIx64 " %d %d", &id, &card, &clock);
|
||||
|
@ -370,133 +227,404 @@ int CmdEM410xWrite(const char *Cmd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
UsbCommand c = {CMD_EM410X_WRITE_TAG, {card, (uint32_t)(id >> 32), (uint32_t)id}};
|
||||
SendCommand(&c);
|
||||
UsbCommand c = {CMD_EM410X_WRITE_TAG, {card, (uint32_t)(id >> 32), (uint32_t)id}};
|
||||
SendCommand(&c);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool EM_EndParityTest(uint8_t *BitStream, 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 ^= BitStream[(rowNum*cols)+colNum];
|
||||
}
|
||||
if (colP != pType) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EM_ByteParityTest(uint8_t *BitStream, 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 ^= BitStream[(rowNum*cols)+colNum];
|
||||
}
|
||||
if (rowP != pType) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t OutputEM4x50_Block(uint8_t *BitStream, size_t size, bool verbose, bool pTest)
|
||||
{
|
||||
if (size<45) return 0;
|
||||
uint32_t code = bytebits_to_byte(BitStream,8);
|
||||
code = code<<8 | bytebits_to_byte(BitStream+9,8);
|
||||
code = code<<8 | bytebits_to_byte(BitStream+18,8);
|
||||
code = code<<8 | bytebits_to_byte(BitStream+27,8);
|
||||
if (verbose || g_debugMode){
|
||||
for (uint8_t i = 0; i<5; i++){
|
||||
if (i == 4) PrintAndLog(""); //parity byte spacer
|
||||
PrintAndLog("%d%d%d%d%d%d%d%d %d -> 0x%02x",
|
||||
BitStream[i*9],
|
||||
BitStream[i*9+1],
|
||||
BitStream[i*9+2],
|
||||
BitStream[i*9+3],
|
||||
BitStream[i*9+4],
|
||||
BitStream[i*9+5],
|
||||
BitStream[i*9+6],
|
||||
BitStream[i*9+7],
|
||||
BitStream[i*9+8],
|
||||
bytebits_to_byte(BitStream+i*9,8)
|
||||
);
|
||||
}
|
||||
if (pTest)
|
||||
PrintAndLog("Parity Passed");
|
||||
else
|
||||
PrintAndLog("Parity Failed");
|
||||
}
|
||||
return code;
|
||||
}
|
||||
/* Read the transmitted data of an EM4x50 tag
|
||||
* Format:
|
||||
*
|
||||
* 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
|
||||
* XXXXXXXX [row parity bit (even)] <- 8 bits plus parity
|
||||
* CCCCCCCC <- column parity bits
|
||||
* 0 <- stop bit
|
||||
* LW <- Listen Window
|
||||
*
|
||||
* This pattern repeats for every block of data being transmitted.
|
||||
* Transmission starts with two Listen Windows (LW - a modulated
|
||||
* pattern of 320 cycles each (32/32/128/64/64)).
|
||||
*
|
||||
* Note that this data may or may not be the UID. It is whatever data
|
||||
* is stored in the blocks defined in the control word First and Last
|
||||
* Word Read values. UID is stored in block 32.
|
||||
*/
|
||||
//completed by Marshmellow
|
||||
int EM4x50Read(const char *Cmd, bool verbose)
|
||||
{
|
||||
uint8_t fndClk[] = {8,16,32,40,50,64,128};
|
||||
int clk = 0;
|
||||
int invert = 0;
|
||||
int tol = 0;
|
||||
int i, j, startblock, skip, block, start, end, low, high, minClk;
|
||||
bool complete = false;
|
||||
int tmpbuff[MAX_GRAPH_TRACE_LEN / 64];
|
||||
uint32_t Code[6];
|
||||
char tmp[6];
|
||||
char tmp2[20];
|
||||
int phaseoff;
|
||||
high = low = 0;
|
||||
memset(tmpbuff, 0, MAX_GRAPH_TRACE_LEN / 64);
|
||||
|
||||
// get user entry if any
|
||||
sscanf(Cmd, "%i %i", &clk, &invert);
|
||||
|
||||
// save GraphBuffer - to restore it later
|
||||
save_restoreGB(1);
|
||||
|
||||
// first get high and low values
|
||||
for (i = 0; i < GraphTraceLen; i++) {
|
||||
if (GraphBuffer[i] > high)
|
||||
high = GraphBuffer[i];
|
||||
else if (GraphBuffer[i] < low)
|
||||
low = GraphBuffer[i];
|
||||
}
|
||||
|
||||
i = 0;
|
||||
j = 0;
|
||||
minClk = 255;
|
||||
// get to first full low to prime loop and skip incomplete first pulse
|
||||
while ((GraphBuffer[i] < high) && (i < GraphTraceLen))
|
||||
++i;
|
||||
while ((GraphBuffer[i] > low) && (i < GraphTraceLen))
|
||||
++i;
|
||||
skip = i;
|
||||
|
||||
// populate tmpbuff buffer with pulse lengths
|
||||
while (i < GraphTraceLen) {
|
||||
// measure from low to low
|
||||
while ((GraphBuffer[i] > low) && (i < GraphTraceLen))
|
||||
++i;
|
||||
start= i;
|
||||
while ((GraphBuffer[i] < high) && (i < GraphTraceLen))
|
||||
++i;
|
||||
while ((GraphBuffer[i] > low) && (i < GraphTraceLen))
|
||||
++i;
|
||||
if (j>=(MAX_GRAPH_TRACE_LEN/64)) {
|
||||
break;
|
||||
}
|
||||
tmpbuff[j++]= i - start;
|
||||
if (i-start < minClk && i < GraphTraceLen) {
|
||||
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) return 0;
|
||||
} else tol = clk/8;
|
||||
|
||||
// look for data start - should be 2 pairs of LW (pulses of clk*3,clk*2)
|
||||
start = -1;
|
||||
for (i= 0; i < j - 4 ; ++i) {
|
||||
skip += tmpbuff[i];
|
||||
if (tmpbuff[i] >= clk*3-tol && tmpbuff[i] <= clk*3+tol) //3 clocks
|
||||
if (tmpbuff[i+1] >= clk*2-tol && tmpbuff[i+1] <= clk*2+tol) //2 clocks
|
||||
if (tmpbuff[i+2] >= clk*3-tol && tmpbuff[i+2] <= clk*3+tol) //3 clocks
|
||||
if (tmpbuff[i+3] >= clk-tol) //1.5 to 2 clocks - depends on bit following
|
||||
{
|
||||
start= i + 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
startblock = i + 4;
|
||||
|
||||
// skip over the remainder of LW
|
||||
skip += tmpbuff[i+1] + tmpbuff[i+2] + clk;
|
||||
if (tmpbuff[i+3]>clk)
|
||||
phaseoff = tmpbuff[i+3]-clk;
|
||||
else
|
||||
phaseoff = 0;
|
||||
// now do it again to find the end
|
||||
end = skip;
|
||||
for (i += 3; i < j - 4 ; ++i) {
|
||||
end += tmpbuff[i];
|
||||
if (tmpbuff[i] >= clk*3-tol && tmpbuff[i] <= clk*3+tol) //3 clocks
|
||||
if (tmpbuff[i+1] >= clk*2-tol && tmpbuff[i+1] <= clk*2+tol) //2 clocks
|
||||
if (tmpbuff[i+2] >= clk*3-tol && tmpbuff[i+2] <= clk*3+tol) //3 clocks
|
||||
if (tmpbuff[i+3] >= clk-tol) //1.5 to 2 clocks - depends on bit following
|
||||
{
|
||||
complete= true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
end = i;
|
||||
// report back
|
||||
if (verbose || g_debugMode) {
|
||||
if (start >= 0) {
|
||||
PrintAndLog("\nNote: one block = 50 bits (32 data, 12 parity, 6 marker)");
|
||||
} else {
|
||||
PrintAndLog("No data found!, clock tried:%d",clk);
|
||||
PrintAndLog("Try again with more samples.");
|
||||
PrintAndLog(" or after a 'data askedge' command to clean up the read");
|
||||
return 0;
|
||||
}
|
||||
} else if (start < 0) return 0;
|
||||
start = skip;
|
||||
snprintf(tmp2, sizeof(tmp2),"%d %d 1000 %d", clk, invert, clk*47);
|
||||
// get rid of leading crap
|
||||
snprintf(tmp, sizeof(tmp), "%i", skip);
|
||||
CmdLtrim(tmp);
|
||||
bool pTest;
|
||||
bool AllPTest = true;
|
||||
// now work through remaining buffer printing out data blocks
|
||||
block = 0;
|
||||
i = startblock;
|
||||
while (block < 6) {
|
||||
if (verbose || g_debugMode) PrintAndLog("\nBlock %i:", block);
|
||||
skip = phaseoff;
|
||||
|
||||
// look for LW before start of next block
|
||||
for ( ; i < j - 4 ; ++i) {
|
||||
skip += tmpbuff[i];
|
||||
if (tmpbuff[i] >= clk*3-tol && tmpbuff[i] <= clk*3+tol)
|
||||
if (tmpbuff[i+1] >= clk-tol)
|
||||
break;
|
||||
}
|
||||
if (i >= j-4) break; //next LW not found
|
||||
skip += clk;
|
||||
if (tmpbuff[i+1]>clk)
|
||||
phaseoff = tmpbuff[i+1]-clk;
|
||||
else
|
||||
phaseoff = 0;
|
||||
i += 2;
|
||||
if (ASKDemod(tmp2, false, false, 1) < 1) {
|
||||
save_restoreGB(0);
|
||||
return 0;
|
||||
}
|
||||
//set DemodBufferLen to just one block
|
||||
DemodBufferLen = skip/clk;
|
||||
//test parities
|
||||
pTest = EM_ByteParityTest(DemodBuffer,DemodBufferLen,5,9,0);
|
||||
pTest &= EM_EndParityTest(DemodBuffer,DemodBufferLen,5,9,0);
|
||||
AllPTest &= pTest;
|
||||
//get output
|
||||
Code[block] = OutputEM4x50_Block(DemodBuffer,DemodBufferLen,verbose, pTest);
|
||||
if (g_debugMode) PrintAndLog("\nskipping %d samples, bits:%d", skip, skip/clk);
|
||||
//skip to start of next block
|
||||
snprintf(tmp,sizeof(tmp),"%i",skip);
|
||||
CmdLtrim(tmp);
|
||||
block++;
|
||||
if (i >= end) break; //in case chip doesn't output 6 blocks
|
||||
}
|
||||
//print full code:
|
||||
if (verbose || g_debugMode || AllPTest){
|
||||
if (!complete) {
|
||||
PrintAndLog("*** Warning!");
|
||||
PrintAndLog("Partial data - no end found!");
|
||||
PrintAndLog("Try again with more samples.");
|
||||
}
|
||||
PrintAndLog("Found data at sample: %i - using clock: %i", start, clk);
|
||||
end = block;
|
||||
for (block=0; block < end; block++){
|
||||
PrintAndLog("Block %d: %08x",block,Code[block]);
|
||||
}
|
||||
if (AllPTest) {
|
||||
PrintAndLog("Parities Passed");
|
||||
} else {
|
||||
PrintAndLog("Parities Failed");
|
||||
PrintAndLog("Try cleaning the read samples with 'data askedge'");
|
||||
}
|
||||
}
|
||||
|
||||
//restore GraphBuffer
|
||||
save_restoreGB(0);
|
||||
return (int)AllPTest;
|
||||
}
|
||||
|
||||
int CmdEM4x50Read(const char *Cmd)
|
||||
{
|
||||
return EM4x50Read(Cmd, true);
|
||||
}
|
||||
|
||||
int CmdReadWord(const char *Cmd)
|
||||
{
|
||||
int Word = -1; //default to invalid word
|
||||
UsbCommand c;
|
||||
UsbCommand c;
|
||||
|
||||
sscanf(Cmd, "%d", &Word);
|
||||
sscanf(Cmd, "%d", &Word);
|
||||
|
||||
if ( (Word > 15) | (Word < 0) ) {
|
||||
PrintAndLog("Word must be between 0 and 15");
|
||||
return 1;
|
||||
}
|
||||
PrintAndLog("Word must be between 0 and 15");
|
||||
return 1;
|
||||
}
|
||||
|
||||
PrintAndLog("Reading word %d", Word);
|
||||
PrintAndLog("Reading word %d", Word);
|
||||
|
||||
c.cmd = CMD_EM4X_READ_WORD;
|
||||
c.d.asBytes[0] = 0x0; //Normal mode
|
||||
c.arg[0] = 0;
|
||||
c.arg[1] = Word;
|
||||
c.arg[2] = 0;
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
c.cmd = CMD_EM4X_READ_WORD;
|
||||
c.d.asBytes[0] = 0x0; //Normal mode
|
||||
c.arg[0] = 0;
|
||||
c.arg[1] = Word;
|
||||
c.arg[2] = 0;
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdReadWordPWD(const char *Cmd)
|
||||
{
|
||||
int Word = -1; //default to invalid word
|
||||
int Password = 0xFFFFFFFF; //default to blank password
|
||||
UsbCommand c;
|
||||
int Password = 0xFFFFFFFF; //default to blank password
|
||||
UsbCommand c;
|
||||
|
||||
sscanf(Cmd, "%d %x", &Word, &Password);
|
||||
sscanf(Cmd, "%d %x", &Word, &Password);
|
||||
|
||||
if ( (Word > 15) | (Word < 0) ) {
|
||||
PrintAndLog("Word must be between 0 and 15");
|
||||
return 1;
|
||||
}
|
||||
PrintAndLog("Word must be between 0 and 15");
|
||||
return 1;
|
||||
}
|
||||
|
||||
PrintAndLog("Reading word %d with password %08X", Word, Password);
|
||||
PrintAndLog("Reading word %d with password %08X", Word, Password);
|
||||
|
||||
c.cmd = CMD_EM4X_READ_WORD;
|
||||
c.d.asBytes[0] = 0x1; //Password mode
|
||||
c.arg[0] = 0;
|
||||
c.arg[1] = Word;
|
||||
c.arg[2] = Password;
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
c.cmd = CMD_EM4X_READ_WORD;
|
||||
c.d.asBytes[0] = 0x1; //Password mode
|
||||
c.arg[0] = 0;
|
||||
c.arg[1] = Word;
|
||||
c.arg[2] = Password;
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdWriteWord(const char *Cmd)
|
||||
{
|
||||
int Word = 16; //default to invalid block
|
||||
int Data = 0xFFFFFFFF; //default to blank data
|
||||
UsbCommand c;
|
||||
int Word = 16; //default to invalid block
|
||||
int Data = 0xFFFFFFFF; //default to blank data
|
||||
UsbCommand c;
|
||||
|
||||
sscanf(Cmd, "%x %d", &Data, &Word);
|
||||
sscanf(Cmd, "%x %d", &Data, &Word);
|
||||
|
||||
if (Word > 15) {
|
||||
PrintAndLog("Word must be between 0 and 15");
|
||||
return 1;
|
||||
}
|
||||
if (Word > 15) {
|
||||
PrintAndLog("Word must be between 0 and 15");
|
||||
return 1;
|
||||
}
|
||||
|
||||
PrintAndLog("Writing word %d with data %08X", Word, Data);
|
||||
PrintAndLog("Writing word %d with data %08X", Word, Data);
|
||||
|
||||
c.cmd = CMD_EM4X_WRITE_WORD;
|
||||
c.d.asBytes[0] = 0x0; //Normal mode
|
||||
c.arg[0] = Data;
|
||||
c.arg[1] = Word;
|
||||
c.arg[2] = 0;
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
c.cmd = CMD_EM4X_WRITE_WORD;
|
||||
c.d.asBytes[0] = 0x0; //Normal mode
|
||||
c.arg[0] = Data;
|
||||
c.arg[1] = Word;
|
||||
c.arg[2] = 0;
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdWriteWordPWD(const char *Cmd)
|
||||
{
|
||||
int Word = 16; //default to invalid word
|
||||
int Data = 0xFFFFFFFF; //default to blank data
|
||||
int Password = 0xFFFFFFFF; //default to blank password
|
||||
UsbCommand c;
|
||||
int Word = 16; //default to invalid word
|
||||
int Data = 0xFFFFFFFF; //default to blank data
|
||||
int Password = 0xFFFFFFFF; //default to blank password
|
||||
UsbCommand c;
|
||||
|
||||
sscanf(Cmd, "%x %d %x", &Data, &Word, &Password);
|
||||
sscanf(Cmd, "%x %d %x", &Data, &Word, &Password);
|
||||
|
||||
if (Word > 15) {
|
||||
PrintAndLog("Word must be between 0 and 15");
|
||||
return 1;
|
||||
}
|
||||
if (Word > 15) {
|
||||
PrintAndLog("Word must be between 0 and 15");
|
||||
return 1;
|
||||
}
|
||||
|
||||
PrintAndLog("Writing word %d with data %08X and password %08X", Word, Data, Password);
|
||||
PrintAndLog("Writing word %d with data %08X and password %08X", Word, Data, Password);
|
||||
|
||||
c.cmd = CMD_EM4X_WRITE_WORD;
|
||||
c.d.asBytes[0] = 0x1; //Password mode
|
||||
c.arg[0] = Data;
|
||||
c.arg[1] = Word;
|
||||
c.arg[2] = Password;
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
c.cmd = CMD_EM4X_WRITE_WORD;
|
||||
c.d.asBytes[0] = 0x1; //Password mode
|
||||
c.arg[0] = Data;
|
||||
c.arg[1] = Word;
|
||||
c.arg[2] = Password;
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static command_t CommandTable[] =
|
||||
{
|
||||
{"help", CmdHelp, 1, "This help"},
|
||||
{"em410xdemod", CmdEMdemodASK, 0, "[findone] -- Extract ID from EM410x tag (option 0 for continuous loop, 1 for only 1 tag)"},
|
||||
{"em410xread", CmdEM410xRead, 1, "[clock rate] -- Extract ID from EM410x tag"},
|
||||
{"em410xsim", CmdEM410xSim, 0, "<UID> -- Simulate EM410x tag"},
|
||||
{"em410xwatch", CmdEM410xWatch, 0, "['h'] -- Watches for EM410x 125/134 kHz tags (option 'h' for 134)"},
|
||||
{"em410xspoof", CmdEM410xWatchnSpoof, 0, "['h'] --- Watches for EM410x 125/134 kHz tags, and replays them. (option 'h' for 134)" },
|
||||
{"em410xwrite", CmdEM410xWrite, 1, "<UID> <'0' T5555> <'1' T55x7> [clock rate] -- Write EM410x UID to T5555(Q5) or T55x7 tag, optionally setting clock rate"},
|
||||
{"em4x50read", CmdEM4x50Read, 1, "Extract data from EM4x50 tag"},
|
||||
{"readword", CmdReadWord, 1, "<Word> -- Read EM4xxx word data"},
|
||||
{"readwordPWD", CmdReadWordPWD, 1, "<Word> <Password> -- Read EM4xxx word data in password mode"},
|
||||
{"writeword", CmdWriteWord, 1, "<Data> <Word> -- Write EM4xxx word data"},
|
||||
{"writewordPWD", CmdWriteWordPWD, 1, "<Data> <Word> <Password> -- Write EM4xxx word data in password mode"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
{"help", CmdHelp, 1, "This help"},
|
||||
{"em410xdemod", CmdEMdemodASK, 0, "[findone] -- Extract ID from EM410x tag (option 0 for continuous loop, 1 for only 1 tag)"},
|
||||
{"em410xread", CmdEM410xRead, 1, "[clock rate] -- Extract ID from EM410x tag in GraphBuffer"},
|
||||
{"em410xsim", CmdEM410xSim, 0, "<UID> -- Simulate EM410x tag"},
|
||||
{"em410xwatch", CmdEM410xWatch, 0, "['h'] -- Watches for EM410x 125/134 kHz tags (option 'h' for 134)"},
|
||||
{"em410xspoof", CmdEM410xWatchnSpoof, 0, "['h'] --- Watches for EM410x 125/134 kHz tags, and replays them. (option 'h' for 134)" },
|
||||
{"em410xwrite", CmdEM410xWrite, 0, "<UID> <'0' T5555> <'1' T55x7> [clock rate] -- Write EM410x UID to T5555(Q5) or T55x7 tag, optionally setting clock rate"},
|
||||
{"em4x50read", CmdEM4x50Read, 1, "Extract data from EM4x50 tag"},
|
||||
{"readword", CmdReadWord, 1, "<Word> -- Read EM4xxx word data"},
|
||||
{"readwordPWD", CmdReadWordPWD, 1, "<Word> <Password> -- Read EM4xxx word data in password mode"},
|
||||
{"writeword", CmdWriteWord, 1, "<Data> <Word> -- Write EM4xxx word data"},
|
||||
{"writewordPWD", CmdWriteWordPWD, 1, "<Data> <Word> <Password> -- Write EM4xxx word data in password mode"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
int CmdLFEM4X(const char *Cmd)
|
||||
{
|
||||
CmdsParse(CommandTable, Cmd);
|
||||
return 0;
|
||||
CmdsParse(CommandTable, Cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHelp(const char *Cmd)
|
||||
{
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#ifndef CMDLFEM4X_H__
|
||||
#define CMDLFEM4X_H__
|
||||
|
||||
int CmdLFEM4X(const char *Cmd);
|
||||
int CmdEMdemodASK(const char *Cmd);
|
||||
int CmdEM410xRead(const char *Cmd);
|
||||
int CmdEM410xSim(const char *Cmd);
|
||||
|
@ -19,9 +18,11 @@ int CmdEM410xWatch(const char *Cmd);
|
|||
int CmdEM410xWatchnSpoof(const char *Cmd);
|
||||
int CmdEM410xWrite(const char *Cmd);
|
||||
int CmdEM4x50Read(const char *Cmd);
|
||||
int CmdLFEM4X(const char *Cmd);
|
||||
int CmdReadWord(const char *Cmd);
|
||||
int CmdReadWordPWD(const char *Cmd);
|
||||
int CmdWriteWord(const char *Cmd);
|
||||
int CmdWriteWordPWD(const char *Cmd);
|
||||
int EM4x50Read(const char *Cmd, bool verbose);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "cmdlfhid.h"
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
/*
|
||||
int CmdHIDDemod(const char *Cmd)
|
||||
{
|
||||
if (GraphTraceLen < 4800) {
|
||||
|
@ -36,7 +36,7 @@ int CmdHIDDemod(const char *Cmd)
|
|||
RepaintGraphWindow();
|
||||
return 0;
|
||||
}
|
||||
|
||||
*/
|
||||
int CmdHIDDemodFSK(const char *Cmd)
|
||||
{
|
||||
int findone=0;
|
||||
|
@ -106,7 +106,7 @@ int CmdHIDClone(const char *Cmd)
|
|||
static command_t CommandTable[] =
|
||||
{
|
||||
{"help", CmdHelp, 1, "This help"},
|
||||
{"demod", CmdHIDDemod, 1, "Demodulate HID Prox Card II (not optimal)"},
|
||||
//{"demod", CmdHIDDemod, 1, "Demodulate HID Prox Card II (not optimal)"},
|
||||
{"fskdemod", CmdHIDDemodFSK, 0, "['1'] Realtime HID FSK demodulator (option '1' for one tag only)"},
|
||||
{"sim", CmdHIDSim, 0, "<ID> -- HID tag simulator"},
|
||||
{"clone", CmdHIDClone, 0, "<ID> ['l'] -- Clone HID to T55x7 (tag must be in antenna)(option 'l' for 84bit ID)"},
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
#define CMDLFHID_H__
|
||||
|
||||
int CmdLFHID(const char *Cmd);
|
||||
|
||||
int CmdHIDDemod(const char *Cmd);
|
||||
//int CmdHIDDemod(const char *Cmd);
|
||||
int CmdHIDDemodFSK(const char *Cmd);
|
||||
int CmdHIDSim(const char *Cmd);
|
||||
int CmdHIDClone(const char *Cmd);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -24,7 +24,7 @@ int CmdIODemodFSK(const char *Cmd)
|
|||
SendCommand(&c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
int CmdIOProxDemod(const char *Cmd){
|
||||
if (GraphTraceLen < 4800) {
|
||||
PrintAndLog("too short; need at least 4800 samples");
|
||||
|
@ -37,7 +37,7 @@ int CmdIOProxDemod(const char *Cmd){
|
|||
RepaintGraphWindow();
|
||||
return 0;
|
||||
}
|
||||
|
||||
*/
|
||||
int CmdIOClone(const char *Cmd)
|
||||
{
|
||||
unsigned int hi = 0, lo = 0;
|
||||
|
@ -67,7 +67,7 @@ int CmdIOClone(const char *Cmd)
|
|||
static command_t CommandTable[] =
|
||||
{
|
||||
{"help", CmdHelp, 1, "This help"},
|
||||
{"demod", CmdIOProxDemod, 1, "Demodulate Stream"},
|
||||
//{"demod", CmdIOProxDemod, 1, "Demodulate Stream"},
|
||||
{"fskdemod", CmdIODemodFSK, 0, "['1'] Realtime IO FSK demodulator (option '1' for one tag only)"},
|
||||
{"clone", CmdIOClone, 0, "Clone ioProx Tag"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <time.h>
|
||||
#include "proxmark3.h"
|
||||
#include "ui.h"
|
||||
#include "graph.h"
|
||||
|
@ -147,31 +148,37 @@ int CmdT55xxSetConfig(const char *Cmd) {
|
|||
param_getstr(Cmd, cmdp+1, modulation);
|
||||
cmdp += 2;
|
||||
|
||||
if ( strcmp(modulation, "FSK" ) == 0)
|
||||
if ( strcmp(modulation, "FSK" ) == 0) {
|
||||
config.modulation = DEMOD_FSK;
|
||||
else if ( strcmp(modulation, "FSK1" ) == 0)
|
||||
} else if ( strcmp(modulation, "FSK1" ) == 0) {
|
||||
config.modulation = DEMOD_FSK1;
|
||||
else if ( strcmp(modulation, "FSK1a" ) == 0)
|
||||
config.inverted=1;
|
||||
} else if ( strcmp(modulation, "FSK1a" ) == 0) {
|
||||
config.modulation = DEMOD_FSK1a;
|
||||
else if ( strcmp(modulation, "FSK2" ) == 0)
|
||||
config.inverted=0;
|
||||
} else if ( strcmp(modulation, "FSK2" ) == 0) {
|
||||
config.modulation = DEMOD_FSK2;
|
||||
else if ( strcmp(modulation, "FSK2a" ) == 0)
|
||||
config.inverted=0;
|
||||
} else if ( strcmp(modulation, "FSK2a" ) == 0) {
|
||||
config.modulation = DEMOD_FSK2a;
|
||||
else if ( strcmp(modulation, "ASK" ) == 0)
|
||||
config.inverted=1;
|
||||
} else if ( strcmp(modulation, "ASK" ) == 0) {
|
||||
config.modulation = DEMOD_ASK;
|
||||
else if ( strcmp(modulation, "NRZ" ) == 0)
|
||||
} else if ( strcmp(modulation, "NRZ" ) == 0) {
|
||||
config.modulation = DEMOD_NRZ;
|
||||
else if ( strcmp(modulation, "PSK1" ) == 0)
|
||||
} else if ( strcmp(modulation, "PSK1" ) == 0) {
|
||||
config.modulation = DEMOD_PSK1;
|
||||
else if ( strcmp(modulation, "PSK2" ) == 0)
|
||||
} else if ( strcmp(modulation, "PSK2" ) == 0) {
|
||||
config.modulation = DEMOD_PSK2;
|
||||
else if ( strcmp(modulation, "PSK3" ) == 0)
|
||||
} else if ( strcmp(modulation, "PSK3" ) == 0) {
|
||||
config.modulation = DEMOD_PSK3;
|
||||
else if ( strcmp(modulation, "BIa" ) == 0)
|
||||
} else if ( strcmp(modulation, "BIa" ) == 0) {
|
||||
config.modulation = DEMOD_BIa;
|
||||
else if ( strcmp(modulation, "BI" ) == 0)
|
||||
config.inverted=1;
|
||||
} else if ( strcmp(modulation, "BI" ) == 0) {
|
||||
config.modulation = DEMOD_BI;
|
||||
else {
|
||||
config.inverted=0;
|
||||
} else {
|
||||
PrintAndLog("Unknown modulation '%s'", modulation);
|
||||
errors = TRUE;
|
||||
}
|
||||
|
@ -255,77 +262,51 @@ int CmdT55xxReadBlock(const char *Cmd) {
|
|||
|
||||
bool DecodeT55xxBlock(){
|
||||
|
||||
char buf[8] = {0x00};
|
||||
char buf[30] = {0x00};
|
||||
char *cmdStr = buf;
|
||||
int ans = 0;
|
||||
uint8_t bitRate[8] = {8,16,32,40,50,64,100,128};
|
||||
|
||||
DemodBufferLen = 0x00;
|
||||
|
||||
//trim 1/2 a clock from beginning
|
||||
snprintf(cmdStr, sizeof(buf),"%d", bitRate[config.bitrate]/2 );
|
||||
CmdLtrim(cmdStr);
|
||||
switch( config.modulation ){
|
||||
case DEMOD_FSK:
|
||||
//CmdLtrim("26");
|
||||
sprintf(cmdStr,"%d", bitRate[config.bitrate]/2 );
|
||||
CmdLtrim(cmdStr);
|
||||
sprintf(cmdStr,"%d %d", bitRate[config.bitrate], config.inverted );
|
||||
snprintf(cmdStr, sizeof(buf),"%d %d", bitRate[config.bitrate], config.inverted );
|
||||
ans = FSKrawDemod(cmdStr, FALSE);
|
||||
break;
|
||||
case DEMOD_FSK1:
|
||||
//CmdLtrim("26");
|
||||
sprintf(cmdStr,"%d", bitRate[config.bitrate]/2 );
|
||||
CmdLtrim(cmdStr);
|
||||
sprintf(cmdStr,"%d 1 8 5", bitRate[config.bitrate] );
|
||||
ans = FSKrawDemod(cmdStr, FALSE);
|
||||
break;
|
||||
case DEMOD_FSK1a:
|
||||
//CmdLtrim("26");
|
||||
sprintf(cmdStr,"%d", bitRate[config.bitrate]/2 );
|
||||
CmdLtrim(cmdStr);
|
||||
sprintf(cmdStr,"%d 0 8 5", bitRate[config.bitrate] );
|
||||
snprintf(cmdStr, sizeof(buf),"%d %d 8 5", bitRate[config.bitrate], config.inverted );
|
||||
ans = FSKrawDemod(cmdStr, FALSE);
|
||||
break;
|
||||
case DEMOD_FSK2:
|
||||
//CmdLtrim("26");
|
||||
sprintf(cmdStr,"%d", bitRate[config.bitrate]/2 );
|
||||
CmdLtrim(cmdStr);
|
||||
sprintf(cmdStr,"%d 0 10 8", bitRate[config.bitrate] );
|
||||
ans = FSKrawDemod(cmdStr, FALSE);
|
||||
break;
|
||||
case DEMOD_FSK2a:
|
||||
//CmdLtrim("26");
|
||||
sprintf(cmdStr,"%d", bitRate[config.bitrate]/2 );
|
||||
CmdLtrim(cmdStr);
|
||||
sprintf(cmdStr,"%d 1 10 8", bitRate[config.bitrate] );
|
||||
snprintf(cmdStr, sizeof(buf),"%d %d 10 8", bitRate[config.bitrate], config.inverted );
|
||||
ans = FSKrawDemod(cmdStr, FALSE);
|
||||
break;
|
||||
case DEMOD_ASK:
|
||||
sprintf(cmdStr,"%d %d 1", bitRate[config.bitrate], config.inverted );
|
||||
ans = ASKmanDemod(cmdStr, FALSE, FALSE);
|
||||
snprintf(cmdStr, sizeof(buf),"%d %d 0", bitRate[config.bitrate], config.inverted );
|
||||
ans = ASKDemod(cmdStr, FALSE, FALSE, 1);
|
||||
break;
|
||||
case DEMOD_PSK1:
|
||||
sprintf(cmdStr,"%d %d 1", bitRate[config.bitrate], config.inverted );
|
||||
snprintf(cmdStr, sizeof(buf),"%d %d 0", bitRate[config.bitrate], config.inverted );
|
||||
ans = PSKDemod(cmdStr, FALSE);
|
||||
break;
|
||||
case DEMOD_PSK2:
|
||||
sprintf(cmdStr,"%d 1", bitRate[config.bitrate] );
|
||||
ans = PSKDemod(cmdStr, FALSE);
|
||||
psk1TOpsk2(DemodBuffer, DemodBufferLen);
|
||||
break;
|
||||
case DEMOD_PSK3:
|
||||
sprintf(cmdStr,"%d %d 1", bitRate[config.bitrate], config.inverted );
|
||||
case DEMOD_PSK2: //inverted won't affect this
|
||||
case DEMOD_PSK3: //not fully implemented
|
||||
snprintf(cmdStr, sizeof(buf),"%d 0 1", bitRate[config.bitrate] );
|
||||
ans = PSKDemod(cmdStr, FALSE);
|
||||
psk1TOpsk2(DemodBuffer, DemodBufferLen);
|
||||
break;
|
||||
case DEMOD_NRZ:
|
||||
sprintf(cmdStr,"%d %d 1", bitRate[config.bitrate], config.inverted );
|
||||
snprintf(cmdStr, sizeof(buf),"%d %d 1", bitRate[config.bitrate], config.inverted );
|
||||
ans = NRZrawDemod(cmdStr, FALSE);
|
||||
break;
|
||||
case DEMOD_BI:
|
||||
sprintf(cmdStr,"0 %d 0 1", bitRate[config.bitrate] );
|
||||
ans = ASKbiphaseDemod(cmdStr, FALSE);
|
||||
break;
|
||||
case DEMOD_BIa:
|
||||
sprintf(cmdStr,"0 %d 1 1", bitRate[config.bitrate] );
|
||||
snprintf(cmdStr, sizeof(buf),"0 %d %d 0", bitRate[config.bitrate], config.inverted );
|
||||
ans = ASKbiphaseDemod(cmdStr, FALSE);
|
||||
break;
|
||||
default:
|
||||
|
@ -354,114 +335,141 @@ bool tryDetectModulation(){
|
|||
char cmdStr[8] = {0};
|
||||
uint8_t hits = 0;
|
||||
t55xx_conf_block_t tests[15];
|
||||
|
||||
int bitRate=0;
|
||||
uint8_t fc1 = 0, fc2 = 0, clk=0;
|
||||
save_restoreGB(1);
|
||||
if (GetFskClock("", FALSE, FALSE)){
|
||||
uint8_t fc1 = 0, fc2 = 0, clk=0;
|
||||
fskClocks(&fc1, &fc2, &clk, FALSE);
|
||||
sprintf(cmdStr,"%d", clk/2);
|
||||
CmdLtrim(cmdStr);
|
||||
if ( FSKrawDemod("0 0", FALSE) && test(DEMOD_FSK, &tests[hits].offset)){
|
||||
if ( FSKrawDemod("0 0", FALSE) && test(DEMOD_FSK, &tests[hits].offset, &bitRate)){
|
||||
tests[hits].modulation = DEMOD_FSK;
|
||||
if (fc1==8 && fc2 == 5)
|
||||
tests[hits].modulation = DEMOD_FSK1a;
|
||||
else if (fc1==10 && fc2 == 8)
|
||||
tests[hits].modulation = DEMOD_FSK2;
|
||||
|
||||
tests[hits].bitrate = bitRate;
|
||||
tests[hits].inverted = FALSE;
|
||||
tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
|
||||
++hits;
|
||||
}
|
||||
if ( FSKrawDemod("0 1", FALSE) && test(DEMOD_FSK, &tests[hits].offset)) {
|
||||
if ( FSKrawDemod("0 1", FALSE) && test(DEMOD_FSK, &tests[hits].offset, &bitRate)) {
|
||||
tests[hits].modulation = DEMOD_FSK;
|
||||
if (fc1==8 && fc2 == 5)
|
||||
if (fc1 == 8 && fc2 == 5)
|
||||
tests[hits].modulation = DEMOD_FSK1;
|
||||
else if (fc1==10 && fc2 == 8)
|
||||
else if (fc1 == 10 && fc2 == 8)
|
||||
tests[hits].modulation = DEMOD_FSK2a;
|
||||
|
||||
tests[hits].bitrate = bitRate;
|
||||
tests[hits].inverted = TRUE;
|
||||
tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
|
||||
++hits;
|
||||
}
|
||||
} else {
|
||||
if ( ASKmanDemod("0 0 1", FALSE, FALSE) && test(DEMOD_ASK, &tests[hits].offset)) {
|
||||
tests[hits].modulation = DEMOD_ASK;
|
||||
tests[hits].inverted = FALSE;
|
||||
tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
|
||||
++hits;
|
||||
}
|
||||
|
||||
if ( ASKmanDemod("0 1 1", FALSE, FALSE) && test(DEMOD_ASK, &tests[hits].offset)) {
|
||||
tests[hits].modulation = DEMOD_ASK;
|
||||
tests[hits].inverted = TRUE;
|
||||
tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
|
||||
++hits;
|
||||
}
|
||||
|
||||
if ( NRZrawDemod("0 0 1", FALSE) && test(DEMOD_NRZ, &tests[hits].offset)) {
|
||||
tests[hits].modulation = DEMOD_NRZ;
|
||||
tests[hits].inverted = FALSE;
|
||||
tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
|
||||
++hits;
|
||||
}
|
||||
|
||||
if ( NRZrawDemod("0 1 1", FALSE) && test(DEMOD_NRZ, &tests[hits].offset)) {
|
||||
tests[hits].modulation = DEMOD_NRZ;
|
||||
tests[hits].inverted = TRUE;
|
||||
tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
|
||||
++hits;
|
||||
}
|
||||
|
||||
if ( PSKDemod("0 0 1", FALSE) && test(DEMOD_PSK1, &tests[hits].offset)) {
|
||||
tests[hits].modulation = DEMOD_PSK1;
|
||||
tests[hits].inverted = FALSE;
|
||||
tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
|
||||
++hits;
|
||||
}
|
||||
|
||||
if ( PSKDemod("0 1 1", FALSE) && test(DEMOD_PSK1, &tests[hits].offset)) {
|
||||
tests[hits].modulation = DEMOD_PSK1;
|
||||
tests[hits].inverted = TRUE;
|
||||
tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
|
||||
++hits;
|
||||
}
|
||||
|
||||
// PSK2 - needs a call to psk1TOpsk2.
|
||||
if ( PSKDemod("0 0 1", FALSE)) {
|
||||
psk1TOpsk2(DemodBuffer, DemodBufferLen);
|
||||
if (test(DEMOD_PSK2, &tests[hits].offset)){
|
||||
tests[hits].modulation = DEMOD_PSK2;
|
||||
clk = GetAskClock("", FALSE, FALSE);
|
||||
if (clk>0) {
|
||||
sprintf(cmdStr,"%d", clk/2);
|
||||
CmdLtrim(cmdStr);
|
||||
if ( ASKDemod("0 0 0", FALSE, FALSE, 1) && test(DEMOD_ASK, &tests[hits].offset, &bitRate)) {
|
||||
tests[hits].modulation = DEMOD_ASK;
|
||||
tests[hits].bitrate = bitRate;
|
||||
tests[hits].inverted = FALSE;
|
||||
tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
|
||||
++hits;
|
||||
}
|
||||
} // inverse waves does not affect this demod
|
||||
|
||||
// PSK3 - needs a call to psk1TOpsk2.
|
||||
if ( PSKDemod("0 0 1", FALSE)) {
|
||||
psk1TOpsk2(DemodBuffer, DemodBufferLen);
|
||||
if (test(DEMOD_PSK3, &tests[hits].offset)){
|
||||
tests[hits].modulation = DEMOD_PSK3;
|
||||
if ( ASKDemod("0 1 0", FALSE, FALSE, 1) && test(DEMOD_ASK, &tests[hits].offset, &bitRate)) {
|
||||
tests[hits].modulation = DEMOD_ASK;
|
||||
tests[hits].bitrate = bitRate;
|
||||
tests[hits].inverted = TRUE;
|
||||
tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
|
||||
++hits;
|
||||
}
|
||||
if ( ASKbiphaseDemod("0 0 0 0", FALSE) && test(DEMOD_BI, &tests[hits].offset, &bitRate) ) {
|
||||
tests[hits].modulation = DEMOD_BI;
|
||||
tests[hits].bitrate = bitRate;
|
||||
tests[hits].inverted = FALSE;
|
||||
tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
|
||||
++hits;
|
||||
}
|
||||
} // inverse waves does not affect this demod
|
||||
|
||||
if ( ASKbiphaseDemod("0 0 0 1", FALSE) && test(DEMOD_BI, &tests[hits].offset) ) {
|
||||
tests[hits].modulation = DEMOD_BI;
|
||||
tests[hits].inverted = FALSE;
|
||||
tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
|
||||
++hits;
|
||||
if ( ASKbiphaseDemod("0 0 1 0", FALSE) && test(DEMOD_BIa, &tests[hits].offset, &bitRate) ) {
|
||||
tests[hits].modulation = DEMOD_BIa;
|
||||
tests[hits].bitrate = bitRate;
|
||||
tests[hits].inverted = TRUE;
|
||||
tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
|
||||
++hits;
|
||||
}
|
||||
}
|
||||
if ( ASKbiphaseDemod("0 0 1 1", FALSE) && test(DEMOD_BIa, &tests[hits].offset) ) {
|
||||
tests[hits].modulation = DEMOD_BIa;
|
||||
tests[hits].inverted = TRUE;
|
||||
tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
|
||||
++hits;
|
||||
//undo trim from ask
|
||||
save_restoreGB(0);
|
||||
clk = GetNrzClock("", FALSE, FALSE);
|
||||
if (clk>0) {
|
||||
sprintf(cmdStr,"%d", clk/2);
|
||||
CmdLtrim(cmdStr);
|
||||
if ( NRZrawDemod("0 0 1", FALSE) && test(DEMOD_NRZ, &tests[hits].offset, &bitRate)) {
|
||||
tests[hits].modulation = DEMOD_NRZ;
|
||||
tests[hits].bitrate = bitRate;
|
||||
tests[hits].inverted = FALSE;
|
||||
tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
|
||||
++hits;
|
||||
}
|
||||
|
||||
if ( NRZrawDemod("0 1 1", FALSE) && test(DEMOD_NRZ, &tests[hits].offset, &bitRate)) {
|
||||
tests[hits].modulation = DEMOD_NRZ;
|
||||
tests[hits].bitrate = bitRate;
|
||||
tests[hits].inverted = TRUE;
|
||||
tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
|
||||
++hits;
|
||||
}
|
||||
}
|
||||
|
||||
//undo trim from nrz
|
||||
save_restoreGB(0);
|
||||
clk = GetPskClock("", FALSE, FALSE);
|
||||
if (clk>0) {
|
||||
PrintAndLog("clk %d",clk);
|
||||
sprintf(cmdStr,"%d", clk/2);
|
||||
CmdLtrim(cmdStr);
|
||||
if ( PSKDemod("0 0 1", FALSE) && test(DEMOD_PSK1, &tests[hits].offset, &bitRate)) {
|
||||
tests[hits].modulation = DEMOD_PSK1;
|
||||
tests[hits].bitrate = bitRate;
|
||||
tests[hits].inverted = FALSE;
|
||||
tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
|
||||
++hits;
|
||||
}
|
||||
if ( PSKDemod("0 1 1", FALSE) && test(DEMOD_PSK1, &tests[hits].offset, &bitRate)) {
|
||||
tests[hits].modulation = DEMOD_PSK1;
|
||||
tests[hits].bitrate = bitRate;
|
||||
tests[hits].inverted = TRUE;
|
||||
tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
|
||||
++hits;
|
||||
}
|
||||
// PSK2 - needs a call to psk1TOpsk2.
|
||||
if ( PSKDemod("0 0 1", FALSE)) {
|
||||
psk1TOpsk2(DemodBuffer, DemodBufferLen);
|
||||
if (test(DEMOD_PSK2, &tests[hits].offset, &bitRate)){
|
||||
tests[hits].modulation = DEMOD_PSK2;
|
||||
tests[hits].bitrate = bitRate;
|
||||
tests[hits].inverted = FALSE;
|
||||
tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
|
||||
++hits;
|
||||
}
|
||||
} // inverse waves does not affect this demod
|
||||
// PSK3 - needs a call to psk1TOpsk2.
|
||||
if ( PSKDemod("0 0 1", FALSE)) {
|
||||
psk1TOpsk2(DemodBuffer, DemodBufferLen);
|
||||
if (test(DEMOD_PSK3, &tests[hits].offset, &bitRate)){
|
||||
tests[hits].modulation = DEMOD_PSK3;
|
||||
tests[hits].bitrate = bitRate;
|
||||
tests[hits].inverted = FALSE;
|
||||
tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
|
||||
++hits;
|
||||
}
|
||||
} // inverse waves does not affect this demod
|
||||
}
|
||||
}
|
||||
if ( hits == 1) {
|
||||
config.modulation = tests[0].modulation;
|
||||
config.bitrate = tests[0].bitrate;
|
||||
config.inverted = tests[0].inverted;
|
||||
config.offset = tests[0].offset;
|
||||
config.block0 = tests[0].block0;
|
||||
|
@ -516,81 +524,32 @@ bool testBitRate(uint8_t readRate, uint8_t mod){
|
|||
uint8_t detRate = 0;
|
||||
switch( mod ){
|
||||
case DEMOD_FSK:
|
||||
detRate = GetFskClock("",FALSE, FALSE);
|
||||
if (expected[readRate] == detRate) {
|
||||
config.bitrate = readRate;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case DEMOD_FSK1:
|
||||
detRate = GetFskClock("",FALSE, FALSE);
|
||||
if (expected[readRate] == detRate) {
|
||||
config.bitrate = readRate;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case DEMOD_FSK1a:
|
||||
detRate = GetFskClock("",FALSE, FALSE);
|
||||
if (expected[readRate] == detRate) {
|
||||
config.bitrate = readRate;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case DEMOD_FSK2:
|
||||
detRate = GetFskClock("",FALSE, FALSE);
|
||||
if (expected[readRate] == detRate) {
|
||||
config.bitrate = readRate;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case DEMOD_FSK2a:
|
||||
detRate = GetFskClock("",FALSE, FALSE);
|
||||
if (expected[readRate] == detRate) {
|
||||
config.bitrate = readRate;
|
||||
if (expected[readRate] == detRate)
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case DEMOD_ASK:
|
||||
case DEMOD_BI:
|
||||
case DEMOD_BIa:
|
||||
detRate = GetAskClock("",FALSE, FALSE);
|
||||
if (expected[readRate] == detRate) {
|
||||
config.bitrate = readRate;
|
||||
if (expected[readRate] == detRate)
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case DEMOD_PSK1:
|
||||
detRate = GetPskClock("",FALSE, FALSE);
|
||||
if (expected[readRate] == detRate) {
|
||||
config.bitrate = readRate;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case DEMOD_PSK2:
|
||||
detRate = GetPskClock("",FALSE, FALSE);
|
||||
if (expected[readRate] == detRate) {
|
||||
config.bitrate = readRate;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case DEMOD_PSK3:
|
||||
detRate = GetPskClock("",FALSE, FALSE);
|
||||
if (expected[readRate] == detRate) {
|
||||
config.bitrate = readRate;
|
||||
if (expected[readRate] == detRate)
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case DEMOD_NRZ:
|
||||
detRate = GetNrzClock("",FALSE, FALSE);
|
||||
if (expected[readRate] == detRate) {
|
||||
config.bitrate = readRate;
|
||||
if (expected[readRate] == detRate)
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case DEMOD_BI:
|
||||
detRate = GetAskClock("",FALSE, FALSE);
|
||||
if (expected[readRate] == detRate) {
|
||||
config.bitrate = readRate;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
|
@ -598,26 +557,27 @@ bool testBitRate(uint8_t readRate, uint8_t mod){
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
bool test(uint8_t mode, uint8_t *offset){
|
||||
bool test(uint8_t mode, uint8_t *offset, int *fndBitRate){
|
||||
|
||||
if ( !DemodBufferLen) return FALSE;
|
||||
if ( DemodBufferLen < 64 ) return FALSE;
|
||||
uint8_t si = 0;
|
||||
for (uint8_t idx = 0; idx < 64; idx++){
|
||||
si = idx;
|
||||
if ( PackBits(si, 32, DemodBuffer) == 0x00 ) continue;
|
||||
|
||||
uint8_t safer = PackBits(si, 4, DemodBuffer); si += 4; //master key
|
||||
uint8_t safer = PackBits(si, 4, DemodBuffer); si += 4; //master key
|
||||
uint8_t resv = PackBits(si, 4, DemodBuffer); si += 4; //was 7 & +=7+3 //should be only 4 bits if extended mode
|
||||
// 2nibble must be zeroed.
|
||||
// moved test to here, since this gets most faults first.
|
||||
if ( resv > 0x00) continue;
|
||||
|
||||
uint8_t xtRate = PackBits(si, 3, DemodBuffer); si += 3; //new
|
||||
uint8_t bitRate = PackBits(si, 3, DemodBuffer); si += 3; //new could check bit rate
|
||||
uint8_t xtRate = PackBits(si, 3, DemodBuffer); si += 3; //extended mode part of rate
|
||||
int bitRate = PackBits(si, 3, DemodBuffer); si += 3; //bit rate
|
||||
if (bitRate > 7) continue;
|
||||
uint8_t extend = PackBits(si, 1, DemodBuffer); si += 1; //bit 15 extended mode
|
||||
uint8_t modread = PackBits(si, 5, DemodBuffer); si += 5+2+1; //new
|
||||
//uint8_t pskcr = PackBits(si, 2, DemodBuffer); si += 2+1; //new could check psk cr
|
||||
uint8_t nml01 = PackBits(si, 1, DemodBuffer); si += 1+5; //bit 24 , 30, 31 could be tested for 0 if not extended mode
|
||||
uint8_t modread = PackBits(si, 5, DemodBuffer); si += 5+2+1;
|
||||
//uint8_t pskcr = PackBits(si, 2, DemodBuffer); si += 2+1; //could check psk cr
|
||||
uint8_t nml01 = PackBits(si, 1, DemodBuffer); si += 1+5; //bit 24, 30, 31 could be tested for 0 if not extended mode
|
||||
uint8_t nml02 = PackBits(si, 2, DemodBuffer); si += 2;
|
||||
|
||||
//if extended mode
|
||||
|
@ -628,15 +588,15 @@ bool test(uint8_t mode, uint8_t *offset){
|
|||
}
|
||||
//test modulation
|
||||
if (!testModulation(mode, modread)) continue;
|
||||
|
||||
*offset = idx;
|
||||
if (!testBitRate(bitRate, mode)) continue;
|
||||
*fndBitRate = bitRate;
|
||||
*offset = idx;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void printT55xxBlock(const char *demodStr){
|
||||
void printT55xxBlock(const char *blockNum){
|
||||
|
||||
uint8_t i = config.offset;
|
||||
uint8_t endpos = 32 + i;
|
||||
|
@ -654,7 +614,7 @@ void printT55xxBlock(const char *demodStr){
|
|||
bits[i - config.offset]=DemodBuffer[i];
|
||||
|
||||
blockData = PackBits(0, 32, bits);
|
||||
PrintAndLog("0x%08X %s [%s]", blockData, sprint_bin(bits,32), demodStr);
|
||||
PrintAndLog("[%s] 0x%08X %s", blockNum, blockData, sprint_bin(bits,32));
|
||||
}
|
||||
|
||||
int special(const char *Cmd) {
|
||||
|
@ -746,16 +706,28 @@ int CmdT55xxReadTrace(const char *Cmd)
|
|||
uint32_t bl0 = PackBits(si, 32, DemodBuffer);
|
||||
uint32_t bl1 = PackBits(si+32, 32, DemodBuffer);
|
||||
|
||||
uint32_t acl = PackBits(si, 8, DemodBuffer); si += 8;
|
||||
uint32_t mfc = PackBits(si, 8, DemodBuffer); si += 8;
|
||||
uint32_t cid = PackBits(si, 5, DemodBuffer); si += 5;
|
||||
uint32_t icr = PackBits(si, 3, DemodBuffer); si += 3;
|
||||
uint32_t year = PackBits(si, 4, DemodBuffer); si += 4;
|
||||
uint32_t quarter = PackBits(si, 2, DemodBuffer); si += 2;
|
||||
uint32_t lotid = PackBits(si, 14, DemodBuffer); si += 14;
|
||||
uint32_t wafer = PackBits(si, 5, DemodBuffer); si += 5;
|
||||
uint32_t acl = PackBits(si, 8, DemodBuffer); si += 8;
|
||||
uint32_t mfc = PackBits(si, 8, DemodBuffer); si += 8;
|
||||
uint32_t cid = PackBits(si, 5, DemodBuffer); si += 5;
|
||||
uint32_t icr = PackBits(si, 3, DemodBuffer); si += 3;
|
||||
uint32_t year = PackBits(si, 4, DemodBuffer); si += 4;
|
||||
uint32_t quarter = PackBits(si, 2, DemodBuffer); si += 2;
|
||||
uint32_t lotid = PackBits(si, 14, DemodBuffer); si += 14;
|
||||
uint32_t wafer = PackBits(si, 5, DemodBuffer); si += 5;
|
||||
uint32_t dw = PackBits(si, 15, DemodBuffer);
|
||||
|
||||
time_t t = time(NULL);
|
||||
struct tm tm = *localtime(&t);
|
||||
if ( year > tm.tm_year-110)
|
||||
year += 2000;
|
||||
else
|
||||
year += 2010;
|
||||
|
||||
if ( acl != 0xE0 ) {
|
||||
PrintAndLog("The modulation is most likely wrong since the ACL is not 0xE0. ");
|
||||
return 1;
|
||||
}
|
||||
|
||||
PrintAndLog("");
|
||||
PrintAndLog("-- T55xx Trace Information ----------------------------------");
|
||||
PrintAndLog("-------------------------------------------------------------");
|
||||
|
@ -764,7 +736,7 @@ int CmdT55xxReadTrace(const char *Cmd)
|
|||
PrintAndLog(" CID : 0x%02X (%d) - %s", cid, cid, GetModelStrFromCID(cid));
|
||||
PrintAndLog(" ICR IC Revision : %d",icr );
|
||||
PrintAndLog(" Manufactured");
|
||||
PrintAndLog(" Year/Quarter : 20?%d/%d",year, quarter);
|
||||
PrintAndLog(" Year/Quarter : %d/%d",year, quarter);
|
||||
PrintAndLog(" Lot ID : %d", lotid );
|
||||
PrintAndLog(" Wafer number : %d", wafer);
|
||||
PrintAndLog(" Die Number : %d", dw);
|
||||
|
@ -774,8 +746,6 @@ int CmdT55xxReadTrace(const char *Cmd)
|
|||
PrintAndLog(" Block 1 : 0x%08X %s", bl1, sprint_bin(DemodBuffer+config.offset+repeat+32,32) );
|
||||
PrintAndLog("-------------------------------------------------------------");
|
||||
|
||||
if ( acl != 0xE0 )
|
||||
PrintAndLog("The modulation is most likely wrong since the ACL is not 0xE0. ");
|
||||
/*
|
||||
TRACE - BLOCK O
|
||||
Bits Definition HEX
|
||||
|
@ -812,7 +782,7 @@ int CmdT55xxInfo(const char *Cmd){
|
|||
|
||||
if (!DecodeT55xxBlock()) return 1;
|
||||
|
||||
if ( !DemodBufferLen) return 1;
|
||||
if ( DemodBufferLen < 32) return 1;
|
||||
|
||||
uint8_t si = config.offset;
|
||||
uint32_t bl0 = PackBits(si, 32, DemodBuffer);
|
||||
|
@ -922,7 +892,8 @@ int AquireData( uint8_t block ){
|
|||
}
|
||||
|
||||
char * GetBitRateStr(uint32_t id){
|
||||
static char buf[40];
|
||||
static char buf[25];
|
||||
|
||||
char *retStr = buf;
|
||||
switch (id){
|
||||
case 0:
|
||||
|
@ -957,7 +928,6 @@ char * GetBitRateStr(uint32_t id){
|
|||
return buf;
|
||||
}
|
||||
|
||||
|
||||
char * GetSaferStr(uint32_t id){
|
||||
static char buf[40];
|
||||
char *retStr = buf;
|
||||
|
@ -974,7 +944,7 @@ char * GetSaferStr(uint32_t id){
|
|||
}
|
||||
|
||||
char * GetModulationStr( uint32_t id){
|
||||
static char buf[40];
|
||||
static char buf[60];
|
||||
char *retStr = buf;
|
||||
|
||||
switch (id){
|
||||
|
@ -1003,7 +973,7 @@ char * GetModulationStr( uint32_t id){
|
|||
snprintf(retStr,sizeof(buf),"%d - FSK 2a RF/10 RF/8",id);
|
||||
break;
|
||||
case 8:
|
||||
snprintf(retStr,sizeof(buf),"%d - Manschester",id);
|
||||
snprintf(retStr,sizeof(buf),"%d - Manchester",id);
|
||||
break;
|
||||
case 16:
|
||||
snprintf(retStr,sizeof(buf),"%d - Biphase",id);
|
||||
|
@ -1026,8 +996,8 @@ char * GetModelStrFromCID(uint32_t cid){
|
|||
static char buf[10];
|
||||
char *retStr = buf;
|
||||
|
||||
if (cid == 1) sprintf(retStr,"ATA5577M1");
|
||||
if (cid == 2) sprintf(retStr,"ATA5577M2");
|
||||
if (cid == 1) snprintf(retStr, sizeof(buf),"ATA5577M1");
|
||||
if (cid == 2) snprintf(retStr, sizeof(buf),"ATA5577M2");
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,13 +53,13 @@ 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);
|
||||
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);
|
||||
bool test(uint8_t mode, uint8_t *offset, int *fndBitRate);
|
||||
int special(const char *Cmd);
|
||||
int AquireData( uint8_t block );
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
int GraphBuffer[MAX_GRAPH_TRACE_LEN];
|
||||
int GraphTraceLen;
|
||||
|
||||
/* write a manchester bit to the graph */
|
||||
void AppendGraph(int redraw, int clock, int bit)
|
||||
{
|
||||
|
@ -46,6 +45,24 @@ int ClearGraph(int redraw)
|
|||
|
||||
return gtl;
|
||||
}
|
||||
// option '1' to save GraphBuffer any other to restore
|
||||
void save_restoreGB(uint8_t saveOpt)
|
||||
{
|
||||
static int SavedGB[MAX_GRAPH_TRACE_LEN];
|
||||
static int SavedGBlen;
|
||||
static bool GB_Saved = false;
|
||||
|
||||
if (saveOpt==1) { //save
|
||||
memcpy(SavedGB, GraphBuffer, sizeof(GraphBuffer));
|
||||
SavedGBlen = GraphTraceLen;
|
||||
GB_Saved=true;
|
||||
} else if (GB_Saved){ //restore
|
||||
memcpy(GraphBuffer, SavedGB, sizeof(GraphBuffer));
|
||||
GraphTraceLen = SavedGBlen;
|
||||
RepaintGraphWindow();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// DETECT CLOCK NOW IN LFDEMOD.C
|
||||
|
||||
|
@ -126,10 +143,10 @@ int GetAskClock(const char str[], bool printAns, bool verbose)
|
|||
PrintAndLog("Failed to copy from graphbuffer");
|
||||
return -1;
|
||||
}
|
||||
DetectASKClock(grph, size, &clock, 20);
|
||||
int start = DetectASKClock(grph, size, &clock, 20);
|
||||
// Only print this message if we're not looping something
|
||||
if (printAns){
|
||||
PrintAndLog("Auto-detected clock rate: %d", clock);
|
||||
PrintAndLog("Auto-detected clock rate: %d, Best Starting Position: %d", clock, start);
|
||||
}
|
||||
return clock;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ uint8_t GetNrzClock(const char str[], bool printAns, bool verbose);
|
|||
uint8_t GetFskClock(const char str[], bool printAns, bool verbose);
|
||||
uint8_t fskClocks(uint8_t *fc1, uint8_t *fc2, uint8_t *rf1, bool verbose);
|
||||
void setGraphBuf(uint8_t *buff, size_t size);
|
||||
void save_restoreGB(uint8_t saveOpt);
|
||||
|
||||
bool HasGraphData();
|
||||
void DetectHighLowInGraph(int *high, int *low, bool addFuzz);
|
||||
|
|
|
@ -138,6 +138,8 @@ local _commands = {
|
|||
CMD_MIFAREUC_AUTH1 = 0x0724,
|
||||
CMD_MIFAREUC_AUTH2 = 0x0725,
|
||||
CMD_MIFAREUC_READCARD = 0x0726,
|
||||
CMD_MIFAREUC_SETPWD = 0x0727,
|
||||
CMD_MIFAREU_SETUID = 0x0728,
|
||||
|
||||
--// mifare desfire
|
||||
CMD_MIFARE_DESFIRE_READBL = 0x0728,
|
||||
|
@ -153,10 +155,10 @@ local _commands = {
|
|||
|
||||
|
||||
local _reverse_lookup,k,v = {}
|
||||
for k, v in pairs(_commands) do
|
||||
_reverse_lookup[v] = k
|
||||
end
|
||||
_commands.tostring = function(command)
|
||||
for k, v in pairs(_commands) do
|
||||
_reverse_lookup[v] = k
|
||||
end
|
||||
_commands.tostring = function(command)
|
||||
if(type(command) == 'number') then
|
||||
return ("%s (%d)"):format(_reverse_lookup[command]or "ERROR UNDEFINED!", command)
|
||||
end
|
||||
|
@ -217,7 +219,6 @@ function Command:getBytes()
|
|||
local data = self.data
|
||||
local cmd = self.cmd
|
||||
local arg1, arg2, arg3 = self.arg1, self.arg2, self.arg3
|
||||
|
||||
return bin.pack("LLLLH",cmd, arg1, arg2, arg3,data);
|
||||
return bin.pack("LLLLH",cmd, arg1, arg2, arg3, data);
|
||||
end
|
||||
return _commands
|
||||
|
|
|
@ -1,196 +1,333 @@
|
|||
local _names = {
|
||||
--[[
|
||||
--[[ decimal, hexadecimal, ccc, elements, group, name
|
||||
--]]
|
||||
["0000"]="WHIRLWIND",
|
||||
["0100"]="SONIC BOOM",
|
||||
["0200"]="WARNADO",
|
||||
["0300"]="LIGHTNINGROD",
|
||||
["0400"]="BASH",
|
||||
["0500"]="TERRAFIN",
|
||||
["0600"]="DINORANG" ,
|
||||
["0700"]="LIGHTCORE PRISM BREAK",
|
||||
["0800"]="SUNBURN",
|
||||
["0900"]="LIGHTCORE ERUPTOR",
|
||||
["0A00"]="IGNITOR",
|
||||
["0B00"]="FLAMESLINGER",
|
||||
["0C00"]="ZAP",
|
||||
["0D00"]="WHAM SHELL",
|
||||
["0E00"]="GILL GRUNT",
|
||||
["0F00"]="SLAMBAM",
|
||||
["1000"]="SPYRO",
|
||||
["1100"]="VOODOOD",
|
||||
["1200"]="DOUBLE TROUBLE",
|
||||
["1300"]="TRIGGER HAPPY",
|
||||
["1400"]="DROBOT",
|
||||
["1500"]="DRILLSERGEANT",
|
||||
["1600"]="BOOMER",
|
||||
["1700"]="WRECKING BALL",
|
||||
["1800"]="CAMO",
|
||||
["1900"]="ZOOK",
|
||||
["1A00"]="STEALTH ELF",
|
||||
["1B00"]="STUMP SMASH",
|
||||
["1D00"]="HEX",
|
||||
["1C00"]="DARK SPYRO",
|
||||
["1E00"]="CHOPCHOP",
|
||||
["1F00"]="GHOST ROASTER",
|
||||
["2000"]="CYNDER",
|
||||
--[[
|
||||
GIANTS
|
||||
--]]
|
||||
["6400"]="GIANT JET-VAC",
|
||||
["6500"]="GIANT SWARM",
|
||||
["6600"]="GIANT CRUSHER",
|
||||
["6700"]="GIANT FLASHWING",
|
||||
["6800"]="GIANT HOTHEAD",
|
||||
["6900"]="GIANT HOTDOG",
|
||||
["6A00"]="GIANT CHILL",
|
||||
["6B00"]="GIANT THUMPBACK",
|
||||
["6C00"]="GIANT POPFIZZ",
|
||||
["6D00"]="GIANT NINJINI",
|
||||
["6E00"]="GIANT BOUNCER",
|
||||
["6F00"]="GIANT SPROCKET",
|
||||
["7000"]="GIANT TREE REX",
|
||||
["7100"]="LIGHTCORE SHROOMBOOM",
|
||||
["7200"]="GIANT EYEBROAWL",
|
||||
["7300"]="GIANT FRIGHTRIDER",
|
||||
{"0", "0000", "0030", "air", "regular", "Whirlwind"},
|
||||
--{"0", "0000", "0030", "air", "regular", "Elite Whirlwind"},
|
||||
--{"0", "0000", "0030", "air", "regular", "Polar Whirlwind"},
|
||||
{"1", "0100", "0030", "air", "regular", "Sonic Boom"},
|
||||
{"2", "0200", "0030", "air", "regular", "Warnado"},
|
||||
{"3", "0300", "0030", "air", "regular", "Lightning Rod"},
|
||||
{"4", "0400", "0030", "earth", "regular", "Bash"},
|
||||
--{"4", "0400", "0030", "earth", "regular", "Birthday Bash"},
|
||||
{"5", "0500", "0030", "earth", "regular", "Terrafin"},
|
||||
--{"5", "0500", "0030", "earth", "regular", "Elite Terrafin"},
|
||||
{"6", "0600", "0030", "earth", "regular", "Dino Rang"},
|
||||
{"7", "0700", "0030", "earth", "regular", "Prism Break"}, --lightcore
|
||||
{"8", "0800", "0030", "fire", "regular", "Sunburn"},
|
||||
{"9", "0900", "0030", "fire", "regular", "Eruptor"}, --lightcore
|
||||
--{"9", "0900", "0030", "fire", "regular", "Elite Eruptor"},
|
||||
--{"9", "0900", "0030", "fire", "regular", "Volcanic Eruptor"},
|
||||
{"10", "0a00", "0030", "fire", "regular", "Ignitor"},
|
||||
{"11", "0b00", "0030", "fire", "regular", "Flameslinger"},
|
||||
--{"11", "0b00", "0030", "fire", "regular", "Cupid Flameslinger"},
|
||||
{"12", "0c00", "0030", "water", "regular", "Zap"},
|
||||
{"13", "0d00", "0030", "water", "regular", "Wham Shell"},
|
||||
{"14", "0e00", "0030", "water", "regular", "Gill Grunt"},
|
||||
--{"14", "0e00", "0030", "water", "regular", "Elite Gill Grunt"},
|
||||
{"15", "0f00", "0030", "water", "regular", "Slam Bam"},
|
||||
--{"15", "0f00", "0030", "water", "regular", "Surfer Slam Bam"},
|
||||
{"16", "1000", "0030", "magic", "regular", "Spyro"},
|
||||
{"17", "1100", "0030", "magic", "regular", "Voodood"},
|
||||
{"18", "1200", "0030", "magic", "regular", "Double Trouble"},
|
||||
--{"18", "1200", "0030", "magic", "regular", "Royal Double Trouble"},
|
||||
{"19", "1300", "0030", "tech", "regular", "Trigger Happy"},
|
||||
--{"19", "1300", "0030", "tech", "regular", "Elite Trigger Happy"},
|
||||
--{"19", "1300", "0030", "tech", "regular", "Springtime Trigger Happy"},
|
||||
{"20", "1400", "0030", "tech", "regular", "Drobot"},
|
||||
{"21", "1500", "0030", "tech", "regular", "Drill Sergeant"},
|
||||
{"22", "1600", "0030", "tech", "regular", "Boomer"},
|
||||
--{"22", "1600", "0030", "tech", "regular", "Lucky Boomer"},
|
||||
{"23", "1700", "0030", "magic", "regular", "Wrecking Ball"},
|
||||
--{"23", "1700", "0030", "magic", "regular", "Buddy Wrecking Ball"},
|
||||
{"24", "1800", "0030", "life", "regular", "Camo"},
|
||||
{"25", "1900", "0030", "life", "regular", "Zook"},
|
||||
{"26", "1a00", "0030", "life", "regular", "Stealth Elf"},
|
||||
--{"26", "1a00", "0030", "life", "regular", "Elite Stealth Elf"},
|
||||
--{"26", "1a00", "0030", "life", "regular", "Dark Stealth Elf"},
|
||||
{"27", "1b00", "0030", "life", "regular", "Stump Smash"},
|
||||
{"27", "1b00", "0118", "life", "regular", "Stump Smash"},
|
||||
--{"27", "1b00", "0030", "life", "regular", "Autumn Stump Smash"},
|
||||
{"28", "1c00", "0030", "magic", "regular", "Dark Spyro"},
|
||||
--{"28", "1c00", "0030", "magic", "regular", "Elite Spyro"},
|
||||
{"29", "1d00", "0030", "undead", "regular", "Hex"},
|
||||
--{"29", "1d00", "0030", "undead", "regular", "Hallows' Eve Hex"},
|
||||
{"30", "1e00", "0030", "undead", "regular", "Chop Chop"},
|
||||
--{"30", "1e00", "0030", "undead", "regular", "Elite Chop Chop"},
|
||||
--{"30", "1e00", "0030", "undead", "regular", "Grill Master Chop Chop"},
|
||||
{"31", "1f00", "0030", "undead", "regular", "Ghost Roaster"},
|
||||
{"32", "2000", "0030", "undead", "regular", "Cynder"},
|
||||
--{"32", "2000", "0030", "undead", "regular", "Skeletal Cynder"},
|
||||
|
||||
--[[
|
||||
ITEM
|
||||
--]]
|
||||
["C800"]="ANVIL",
|
||||
["C900"]="SECRET STASH",
|
||||
["CA00"]="REGENERATION",
|
||||
["CD00"]="SHIELD",
|
||||
["CB00"]="CROSSED SWORDS",
|
||||
["CC00"]="HOURGLASS",
|
||||
["CE00"]="SPEED BOOTS",
|
||||
["CF00"]="SPARX",
|
||||
["D000"]="CANNON",
|
||||
["D100"]="SCORPIONSTRIKER",
|
||||
{"100", "6400", "0030", "air", "giant", "Jet Vac"},
|
||||
{"101", "6500", "0030", "air", "giant", "Swarm"},
|
||||
{"102", "6600", "0030", "earth", "giant", "Crusher"},
|
||||
{"103", "6700", "0030", "earth", "giant", "Flashwing"},
|
||||
--{"103", "6700", "0030", "earth", "giant", "Jade Flashwing"},
|
||||
{"104", "6800", "0030", "fire", "giant", "Hot Head"},
|
||||
{"105", "6900", "0030", "fire", "giant", "Hot Dog"},
|
||||
--{"105", "6900", "0030", "fire", "giant", "Molten Hot Dog"},
|
||||
{"106", "6a00", "0030", "water", "giant", "Chill"},
|
||||
{"107", "6b00", "0030", "water", "giant", "Thumpback"},
|
||||
--{"107", "6b00", "0030", "water", "giant", "Admiral Thumpback"},
|
||||
{"108", "6c00", "0030", "magic", "giant", "Pop Fizz"},
|
||||
--{"108", "6c00", "0030", "magic", "giant", "Hoppity Pop Fizz"},
|
||||
{"108", "6c00", "023c", "magic", "giant", "Love Potion Pop Fizz"},
|
||||
--{"108", "6c00", "0030", "magic", "giant", "Punch Pop Fizz"},
|
||||
{"109", "6d00", "0030", "magic", "giant", "Nin Jini"},
|
||||
{"110", "6e00", "0030", "tech", "giant", "Bouncer"},
|
||||
{"111", "6f00", "0030", "tech", "giant", "Sprocket"},
|
||||
{"112", "7000", "0030", "life", "giant", "Tree Rex"},
|
||||
--{"112", "7000", "0030", "life", "giant", "Gnarly Tree Rex"},
|
||||
{"113", "7100", "0030", "life", "giant", "Shroomboom"}, --lightcore
|
||||
{"114", "7200", "0030", "undead", "giant", "Eye Broawl"},
|
||||
{"115", "7300", "0030", "undead", "giant", "Fright Rider"},
|
||||
|
||||
--[[
|
||||
ITEM TRAPS
|
||||
--]]
|
||||
["D200"]="MAGIC TRAP",
|
||||
["D300"]="WATER TRAP",
|
||||
["D400"]="AIR TRAP",
|
||||
["D500"]="UNDEAD TRAP",
|
||||
["D600"]="TECH TRAP",
|
||||
["D700"]="FIRE TRAP",
|
||||
["D800"]="EARTH TRAP",
|
||||
["D900"]="LIFE TRAP",
|
||||
["DA00"]="DARK TRAP",
|
||||
["DB00"]="LIGHT TRAP",
|
||||
["DC00"]="KAOS TRAP",
|
||||
{"200", "c800", "0030", "", "item", "Anvil Rain"},
|
||||
{"201", "c900", "0030", "", "item", "Platinum Treasure Chest"},
|
||||
{"202", "ca00", "0030", "", "item", "Healing Elixer"},
|
||||
{"203", "cb00", "0030", "", "item", "Ghost Pirate Swords"},
|
||||
{"204", "cc00", "0030", "", "item", "Time Twist Hourglass"},
|
||||
{"205", "cd00", "0030", "", "item", "Sky Iron Shield"},
|
||||
{"206", "ce00", "0030", "", "item", "Winged Boots"},
|
||||
{"207", "cf00", "0030", "", "item", "Sparx"},
|
||||
{"208", "d000", "0030", "", "item", "Cannon"},
|
||||
{"209", "d100", "0030", "", "item", "Scorpion Striker"},
|
||||
|
||||
--[[
|
||||
ITEM
|
||||
--]]
|
||||
["E600"]="HAND OF FATE",
|
||||
["E700"]="PIGGYBANK",
|
||||
["E800"]="ROCKET RAM",
|
||||
["E900"]="TIKI SPEAKY",
|
||||
{"210", "d200", "0230", "magic", "trap", "Biter's Bane"},
|
||||
{"210", "d200", "0830", "magic", "trap", "Sorcerous Skull"},
|
||||
-- legendary Sorcerous Skull?
|
||||
{"210", "d200", "0b30", "magic", "trap", "Axe Of Illusion"},
|
||||
{"210", "d200", "0e30", "magic", "trap", "Arcane Hourglass"},
|
||||
{"210", "d200", "1230", "magic", "trap", "Spell Slapper"},
|
||||
{"210", "d200", "1430", "magic", "trap", "Rune Rocket"},
|
||||
|
||||
{"211", "d300", "0130", "water", "trap", "Tidal Tiki"},
|
||||
{"211", "d300", "0230", "water", "trap", "Wet Walter"},
|
||||
{"211", "d300", "0630", "water", "trap", "Flood Flask"},
|
||||
-- legendary flood flask?
|
||||
{"211", "d300", "0730", "water", "trap", "Soaking Staff"},
|
||||
{"211", "d300", "0b30", "water", "trap", "Aqua Axe"},
|
||||
{"211", "d300", "1630", "water", "trap", "Frost Helm"},
|
||||
|
||||
{"212", "d400", "0330", "air", "trap", "Breezy Bird"},
|
||||
{"212", "d400", "0630", "air", "trap", "Drafty Decanter"},
|
||||
{"212", "d400", "0d30", "air", "trap", "Tempest Timer"},
|
||||
{"212", "d400", "1030", "air", "trap", "Cloudy Cobra"},
|
||||
{"212", "d400", "1130", "air", "trap", "Storm Warning"},
|
||||
{"212", "d400", "1830", "air", "trap", "Cycone Saber"},
|
||||
|
||||
{"213", "d500", "0430", "undead", "trap", "Spirit Sphere"},
|
||||
{"213", "d500", "0830", "undead", "trap", "Spectral Skull"},
|
||||
{"213", "d500", "0b30", "undead", "trap", "Haunted Hatchet"},
|
||||
{"213", "d500", "0c30", "undead", "trap", "Grim Gripper"},
|
||||
{"213", "d500", "1030", "undead", "trap", "Spooky Snake"},
|
||||
{"213", "d500", "1730", "undead", "trap", "Dream Piercer"},
|
||||
|
||||
{"214", "d600", "0030", "tech", "trap", "tech Totem"},
|
||||
{"214", "d600", "0730", "tech", "trap", "Automatic Angel"},
|
||||
{"214", "d600", "0930", "tech", "trap", "Factory Flower"},
|
||||
{"214", "d600", "0c30", "tech", "trap", "Grabbing Gadget"},
|
||||
{"214", "d600", "1630", "tech", "trap", "Makers Mana"},
|
||||
{"214", "d600", "1a30", "tech", "trap", "Topsy techy"},
|
||||
|
||||
{"215", "d700", "0530", "fire", "trap", "Eternal Flame"},
|
||||
{"215", "d700", "0930", "fire", "trap", "fire Flower"},
|
||||
{"215", "d700", "1130", "fire", "trap", "Scorching Stopper"},
|
||||
{"215", "d700", "1230", "fire", "trap", "Searing Spinner"},
|
||||
{"215", "d700", "1730", "fire", "trap", "Spark Spear"},
|
||||
{"215", "d700", "1b30", "fire", "trap", "Blazing Belch"},
|
||||
|
||||
{"216", "d800", "0030", "earth", "trap", "Banded Boulder"},
|
||||
{"216", "d800", "0330", "earth", "trap", "Rock Hawk"},
|
||||
{"216", "d800", "0a30", "earth", "trap", "Slag Hammer"},
|
||||
{"216", "d800", "0e30", "earth", "trap", "Dust Of Time"},
|
||||
{"216", "d800", "1330", "earth", "trap", "Spinning Sandstorm"},
|
||||
{"216", "d800", "1a30", "earth", "trap", "Rubble Trouble"},
|
||||
|
||||
{"217", "d900", "0330", "life", "trap", "Oak Eagle"},
|
||||
{"217", "d900", "0530", "life", "trap", "Emerald Energy"},
|
||||
{"217", "d900", "0a30", "life", "trap", "Weed Whacker"},
|
||||
{"217", "d900", "1030", "life", "trap", "Seed Serpent"},
|
||||
{"217", "d900", "1830", "life", "trap", "Jade Blade"},
|
||||
{"217", "d900", "1b30", "life", "trap", "Shrub Shrieker"},
|
||||
|
||||
{"218", "da00", "0030", "dark", "trap", "dark Dagger"},
|
||||
{"218", "da00", "1430", "dark", "trap", "Shadow Spider"},
|
||||
{"218", "da00", "1a30", "dark", "trap", "Ghastly Grimace"},
|
||||
|
||||
{"219", "db00", "0030", "light", "trap", "Shining Ship"},
|
||||
{"219", "db00", "0f30", "light", "trap", "Heavenly Hawk"},
|
||||
{"219", "db00", "1b30", "light", "trap", "Beam Scream"},
|
||||
|
||||
{"220", "dc00", "3030", "kaos", "trap", "Kaos trap!"},
|
||||
--{"220", "dc00", "3130", "kaos", "trap", "Ultimate Kaos trap!"}, ?
|
||||
|
||||
|
||||
--[[
|
||||
EXPANSION
|
||||
--]]
|
||||
["012C"]="DRAGONS PEAK",
|
||||
["012D"]="EMPIRE OF ICE",
|
||||
["012E"]="PIRATE SEAS",
|
||||
["012F"]="DARKLIGHT CRYPT",
|
||||
["0130"]="VOLCANIC VAULT",
|
||||
["0131"]="MIRROR OF MYSTERY",
|
||||
["0132"]="NIGHTMARE EXPRESS",
|
||||
["0133"]="SUNSCRAPER SPIRE",
|
||||
["0134"]="MIDNIGHT MUSEUM",
|
||||
{"230", "e600", "0030", "none", "item", "Hand Of Fate"},
|
||||
{"231", "e700", "0030", "none", "item", "Piggy Bank"},
|
||||
{"232", "e800", "0030", "none", "item", "Rocket Ram"},
|
||||
{"233", "e900", "0030", "none", "item", "Tiki Speaky"},
|
||||
|
||||
--[[
|
||||
LEGENDARY
|
||||
--]]
|
||||
["0194"]="LEGENDARY BASH",
|
||||
["01A0"]="LEGENDARY SPYRO",
|
||||
["01A3"]="LEGENDARY TRIGGER HAPPY",
|
||||
["01AE"]="LEGENDARY CHOPCHOP",
|
||||
{"300", "2c01", "0030", "none", "location", "Dragons Peak"},
|
||||
{"301", "2d01", "0030", "none", "location", "Empire Of Ice"},
|
||||
{"302", "2e01", "0030", "none", "location", "Pirate Seas"},
|
||||
{"303", "2f01", "0030", "none", "location", "darklight Crypt"},
|
||||
{"304", "3001", "0030", "none", "location", "Volcanic Vault"},
|
||||
{"305", "3101", "0030", "none", "location", "Mirror Of Mystery"},
|
||||
{"306", "3201", "0030", "none", "location", "Nightmare Express"},
|
||||
{"307", "3301", "0030", "light", "location", "Sunscraper Spire"},
|
||||
{"308", "3401", "0030", "dark", "location", "Midnight Museum"},
|
||||
|
||||
--[[
|
||||
TRAPTEAM
|
||||
--]]
|
||||
["01C2"]="TRAPTEAM GUSTO",
|
||||
["01C3"]="TRAPTEAM THUNDERBOLT",
|
||||
["01C4"]="TRAPTEAM FLING KONG",
|
||||
["01C5"]="TRAPTEAM BLADES",
|
||||
["01C6"]="TRAPTEAM WALLOP",
|
||||
["01C7"]="TRAPTEAM HEAD RUSH",
|
||||
["01C8"]="TRAPTEAM FIST BUMP",
|
||||
["01C9"]="TRAPTEAM ROCKY ROLL",
|
||||
["01CA"]="TRAPTEAM WILDFIRE",
|
||||
["01CB"]="TRAPTEAM KA BOOM",
|
||||
["01CC"]="TRAPTEAM TRAIL BLAZER",
|
||||
["01CD"]="TRAPTEAM TORCH",
|
||||
["01CE"]="TRAPTEAM SNAP SHOT",
|
||||
["01CF"]="TRAPTEAM LOB STAR",
|
||||
["01D0"]="TRAPTEAM FLIP WRECK",
|
||||
["01D1"]="TRAPTEAM ECHO",
|
||||
["01D2"]="TRAPTEAM BLASTERMIND",
|
||||
["01D3"]="TRAPTEAM ENIGMA",
|
||||
["01D4"]="TRAPTEAM DEJA VU",
|
||||
["01D5"]="TRAPTEAM COBRA CADABRA",
|
||||
["01D6"]="TRAPTEAM JAWBREAKER",
|
||||
["01D7"]="TRAPTEAM GEARSHIFT",
|
||||
["01D8"]="TRAPTEAM CHOPPER",
|
||||
["01D9"]="TRAPTEAM TREAD HEAD",
|
||||
["01DA"]="TRAPTEAM BUSHWHACK",
|
||||
["01DB"]="TRAPTEAM TUFF LUCK",
|
||||
["01DC"]="TRAPTEAM FOOD FIGHT",
|
||||
["01DD"]="TRAPTEAM HIGH FIVE",
|
||||
["01DE"]="TRAPTEAM NITRO KRYPT KING",
|
||||
["01DF"]="TRAPTEAM SHORT CUT",
|
||||
["01E0"]="TRAPTEAM BAT SPIN",
|
||||
["01E1"]="TRAPTEAM FUNNY BONE",
|
||||
["01E2"]="TRAPTEAM KNIGHT LIGHT",
|
||||
["01E3"]="TRAPTEAM SPOTLIGHT",
|
||||
["01E4"]="TRAPTEAM KNIGHT MARE",
|
||||
["01E5"]="TRAPTEAM BLACKOUT",
|
||||
{"404", "9401", "0030", "earth", "legendary","Bash"},
|
||||
{"416", "a001", "0030", "magic", "legendary", "Spyro"},
|
||||
--{"", "", "0030", "magic", "legendary", "Deja Vu"},
|
||||
{"419", "a301", "0030", "tech", "legendary", "Trigger Happy"},
|
||||
--{"", "", "0030", "tech", "legendary", "bouncer"},
|
||||
--{"", "", "0030", "tech", "legendary", "jawbreaker"},
|
||||
{"430", "ae01", "0030", "undead", "legendary", "Chop Chop"},
|
||||
--{"", "", "0030", "undead", "legendary", "grim creeper"},
|
||||
--{"", "", "0030", "undead", "legendary", "night shift"},
|
||||
|
||||
--[[
|
||||
PET
|
||||
--]]
|
||||
["01F6"]="PET BOP",
|
||||
["01F7"]="PET SPRY",
|
||||
["01F8"]="PET HIJINX",
|
||||
["01F9"]="PET TERRAFIN",
|
||||
["01FA"]="PET BREEZE",
|
||||
["01FB"]="PET WEERUPTOR",
|
||||
["01FC"]="PET PET VAC",
|
||||
["01FD"]="PET SMALL FRY",
|
||||
["01FE"]="PET DROBIT",
|
||||
["0202"]="PET GILL GRUNT",
|
||||
["0207"]="PET TRIGGER SNAPPY",
|
||||
["020E"]="PET WHISPER ELF",
|
||||
["021C"]="PET BARKLEY",
|
||||
["021D"]="PET THUMPLING",
|
||||
["021E"]="PET MINI JINI",
|
||||
["021F"]="PET EYE SMALL",
|
||||
--{"", "", "0030", "air", "legendary", "blades"},
|
||||
--{"", "", "0030", "air", "legendary", "jet vac"},
|
||||
--{"", "", "0030", "air", "legendary", "Free Ranger"},
|
||||
--{"", "", "0030", "life", "legendary", "stealth elf"},
|
||||
--{"", "", "0030", "life", "legendary", "Bushwhack"},
|
||||
--{"", "", "0030", "fire", "legendary", "ignitor"},
|
||||
--{"", "", "0030", "water", "legendary", "slam bam"},
|
||||
--{"", "", "0030", "water", "legendary", "chill"},
|
||||
|
||||
--[[
|
||||
SWAP FORCE
|
||||
--]]
|
||||
["0BB8"]="SWAPFORCE SCRATCH",
|
||||
["0BB9"]="SWAPFORCE POPTHORN",
|
||||
["0BBA"]="SWAPFORCE SLOBBER TOOTH",
|
||||
["0BBB"]="SWAPFORCE SCORP",
|
||||
["0BBC"]="SWAPFORCE HOG WILD FRYNO",
|
||||
["0BBD"]="SWAPFORCE SMOLDER DASH",
|
||||
["0BBE"]="SWAPFORCE BUMBLE BLAST",
|
||||
["0BBF"]="SWAPFORCE ZOO LOU",
|
||||
["0BC0"]="SWAPFORCE DUNE BUG",
|
||||
["0BC1"]="SWAPFORCE STAR STRIKE",
|
||||
["0BC2"]="SWAPFORCE COUNTDOWN",
|
||||
["0BC3"]="SWAPFORCE WIND UP",
|
||||
["0BC4"]="SWAPFORCE ROLLER BRAWL",
|
||||
["0BC5"]="SWAPFORCE GRIM CREEPER",
|
||||
["0BC6"]="SWAPFORCE RIP TIDE",
|
||||
["0BC7"]="SWAPFORCE PUNK SHOCK",
|
||||
--{"", "", "0030", "", "legendary", "zoo lou"},
|
||||
|
||||
{"450", "c201", "0030", "air", "trapmaster", "Gusto"},
|
||||
--{"450", "c201", "0234", "air", "trapmaster", "Special Gusto"},
|
||||
{"451", "c301", "0030", "air", "trapmaster", "Thunderbolt"},
|
||||
--{"451", "c301", "0234", "air", "trapmaster", "Special Thunderbolt"},
|
||||
{"452", "c401", "0030", "air", "regular", "Fling Kong"},
|
||||
{"453", "c501", "0030", "air", "regular", "Blades"},
|
||||
{"454", "c601", "0030", "earth", "trapmaster", "Wallop"},
|
||||
--{"454", "c601", "0234", "earth", "trapmaster", "Special Wallop"},
|
||||
{"455", "c701", "0030", "earth", "trapmaster", "Head Rush"},
|
||||
{"455", "c701", "0234", "earth", "trapmaster", "Nitro Head Rush"},
|
||||
{"456", "c801", "0030", "earth", "regular", "Fist Bump"},
|
||||
{"457", "c901", "0030", "earth", "regular", "Rocky Roll"},
|
||||
--{"457", "c901", "0030", "earth", "regular", "Rocky Egg Roll"},
|
||||
{"458", "ca01", "0030", "fire", "trapmaster", "Wildfire"},
|
||||
{"458", "ca01", "0234", "fire", "trapmaster", "Dark Wildfire"},
|
||||
{"459", "cb01", "0030", "fire", "trapmaster", "Ka Boom"},
|
||||
--{"459", "cb01", "0234", "fire", "trapmaster", "Special Ka Boom"},
|
||||
{"460", "cc01", "0030", "fire", "regular", "Trail Blazer"},
|
||||
{"461", "cd01", "0030", "fire", "regular", "Torch"},
|
||||
{"462", "ce01", "0030", "water", "trapmaster", "Snap Shot"},
|
||||
{"462", "ce01", "0234", "water", "trapmaster", "Dark Snap Shot"},
|
||||
{"462", "6c00", "023c", "water", "trapmaster", "Instant Snap Shot"},
|
||||
--, "water", "trapmaster", "Merry Snap Shot"},
|
||||
{"463", "cf01", "0030", "water", "trapmaster", "Lob Star"},
|
||||
{"463", "cf01", "0234", "water", "trapmaster", "Winterfest Lob Star"},
|
||||
{"464", "d001", "0030", "water", "regular", "Flip Wreck"},
|
||||
{"465", "d101", "0030", "water", "regular", "Echo"},
|
||||
{"466", "d201", "0030", "magic", "trapmaster", "Blastermind"},
|
||||
--{"466", "d201", "0234", "magic", "trapmaster", "Special Blastermind"},
|
||||
{"467", "d301", "0030", "magic", "trapmaster", "Enigma"},
|
||||
--{"467", "d301", "0234", "magic", "trapmaster", "Special Enigma"},
|
||||
{"468", "d401", "0030", "magic", "regular", "Deja Vu"},
|
||||
{"469", "d501", "0030", "magic", "regular", "Cobra Cadabra"},
|
||||
--{"469", "d501", "0030", "magic", "regular", "Charming Cobra Cadabra"},
|
||||
--{"469", "d501", "0030", "magic", "regular", "King Cobra Cadabra"},
|
||||
{"470", "d601", "0030", "tech", "trapmaster", "Jawbreaker"},
|
||||
--{"470", "d601", "0234", "tech", "trapmaster", "Special Jawbreaker"},
|
||||
--{"470", "d601", "0234", "tech", "trapmaster", "Knockout Jawbreaker"},
|
||||
{"471", "d701", "0030", "tech", "trapmaster", "Gearshift"},
|
||||
--{"471", "d701", "0234", "tech", "trapmaster", "Special Gearshift"},
|
||||
{"472", "d801", "0030", "tech", "regular", "Chopper"},
|
||||
{"473", "d901", "0030", "tech", "regular", "Tread Head"},
|
||||
{"474", "da01", "0030", "life", "trapmaster", "Bushwhack"},
|
||||
--{"474", "da01", "0234", "life", "trapmaster", "Special Bushwhack"},
|
||||
{"475", "db01", "0030", "life", "trapmaster", "Tuff Luck"},
|
||||
--{"475", "db01", "0234", "life", "trapmaster", "Special Tuff Luck"},
|
||||
{"476", "dc01", "0030", "life", "regular", "Food Fight"},
|
||||
{"476", "dc01", "0612", "life", "regular", "LightCore Food Fight"},
|
||||
--{"476", "dc01", "0030", "life", "regular", "Dark Food Fight"},
|
||||
--{"476", "dc01", "0030", "life", "regular", "Frosted Food Fight"},
|
||||
--{"476", "dc01", "0030", "life", "regular", "Instant Food Fight"},
|
||||
{"477", "dd01", "0030", "life", "regular", "High Five"},
|
||||
{"478", "de01", "0030", "undead", "trapmaster", "Krypt King"},
|
||||
{"478", "de01", "0234", "undead", "trapmaster", "Nitro Krypt King"},
|
||||
{"479", "df01", "0030", "undead", "trapmaster", "Short Cut"},
|
||||
--{"479", "df01", "0234", "undead", "trapmaster", "Special Short Cut"},
|
||||
{"480", "e001", "0030", "undead", "regular", "Bat Spin"},
|
||||
{"481", "e101", "0030", "undead", "regular", "Funny Bone"},
|
||||
{"481", "e101", "0612", "undead", "regular", "LightCore Funny Bone"},
|
||||
--{"481", "e101", "0030", "undead", "regular", "Fortune Funny Bone"},
|
||||
{"482", "e201", "0030", "light", "trapmaster", "Knight light"},
|
||||
--{"482", "e201", "0234", "light", "trapmaster", "Special Knight light"},
|
||||
{"483", "e301", "0030", "light", "regular", "Spotlight"},
|
||||
--{"483", "e301", "0234", "light", "regular", "Special Spotlight"},
|
||||
{"484", "e401", "0030", "dark", "trapmaster", "Knight Mare"},
|
||||
--{"484", "e401", "0234", "dark", "trapmaster", "Special Knight Mare"},
|
||||
{"485", "e501", "0030", "dark", "regular", "Blackout"},
|
||||
--{"485", "e501", "0234", "dark", "regular", "Special Blackout"},
|
||||
|
||||
{"502", "f601", "0030", "earth", "mini", "Bop"},
|
||||
{"503", "f701", "0030", "magic", "mini", "Spry"},
|
||||
{"504", "f801", "0030", "undead", "mini", "Hijinx"},
|
||||
{"505", "f901", "0030", "earth", "mini", "Terrabite"},
|
||||
{"506", "fa01", "0030", "air", "mini", "Breeze"},
|
||||
{"507", "fb01", "0030", "fire", "mini", "Weeruptor"},
|
||||
--{"507", "fb01", "0030", "fire", "mini", "Eggsellent Weeruptor"},
|
||||
{"508", "fc01", "0030", "air", "mini", "Pet Vac"},
|
||||
--{"508", "fc01", "0030", "air", "mini", "Power Punch Pet Vac"},
|
||||
{"509", "fd01", "0030", "fire", "mini", "Small Fry"},
|
||||
{"510", "fe01", "0030", "tech", "mini", "Drobit"},
|
||||
{"514", "0202", "0030", "water", "mini", "Gill Runt"},
|
||||
{"519", "0702", "0030", "tech", "mini", "Trigger Snappy"},
|
||||
{"526", "0e02", "0030", "life", "mini", "Whisper Elf"},
|
||||
{"540", "1c02", "0030", "life", "mini", "Barkley"},
|
||||
--{"540", "1c02", "0030", "life", "mini", "Gnarly Barkley"},
|
||||
{"541", "1d02", "0030", "water", "mini", "Thumpling"},
|
||||
{"542", "1e02", "0030", "magic", "mini", "mini Jini"},
|
||||
{"543", "1f02", "0030", "undead", "mini", "Eye Small"},
|
||||
|
||||
{"3000", "b80b", "0030", "air", "SWAPFORCE", "Scratch"},
|
||||
{"3001", "b90b", "0030", "air", "SWAPFORCE", "Pop Thorn"},
|
||||
--{"3001", "b90b", "0030", "air", "SWAPFORCE", "Buttered Pop Thorn"},
|
||||
{"3002", "ba0b", "0030", "earth", "SWAPFORCE", "Slobber Tooth"},
|
||||
--{"3002", "ba0b", "0030", "earth", "SWAPFORCE", "Dark Slobber Tooth"},
|
||||
--{"3002", "ba0b", "0030", "earth", "SWAPFORCE", "Sundae Slobber Tooth"},
|
||||
{"3003", "bb0b", "0030", "earth", "SWAPFORCE", "Scorp"},
|
||||
{"3004", "bc0b", "0030", "fire", "SWAPFORCE", "Fryno"},
|
||||
{"3004", "bc0b", "0138", "fire", "SWAPFORCE", "Hog Wild Fryno"},
|
||||
--{"3004", "bc0b", "0138", "fire", "SWAPFORCE", "Flip flop Fryno"},
|
||||
{"3005", "bd0b", "0030", "fire", "SWAPFORCE", "Smolderdash"},
|
||||
{"3006", "be0b", "0030", "life", "SWAPFORCE", "Bumble Blast"},
|
||||
--{"3006", "be0b", "0030", "life", "SWAPFORCE", "Jolly Bumble Blast"},
|
||||
{"3007", "bf0b", "0030", "life", "SWAPFORCE", "Zoo Lou"},
|
||||
{"3008", "c00b", "0030", "magic", "SWAPFORCE", "Dune Bug"},
|
||||
{"3009", "c10b", "0030", "magic", "SWAPFORCE", "Star Strike"},
|
||||
--{"3009", "c10b", "0030", "magic", "SWAPFORCE", "Enchanted Star Strike"},
|
||||
--{"3009", "c10b", "0030", "magic", "SWAPFORCE", "Mystic Star Strike"},
|
||||
{"3010", "c20b", "0030", "tech", "SWAPFORCE", "Countdown"},
|
||||
--{"3010", "c20b", "0030", "tech", "SWAPFORCE", "Kickoff Countdown"},
|
||||
--{"3010", "c20b", "0030", "tech", "SWAPFORCE", "New Year's Countdown"},
|
||||
{"3011", "c30b", "0030", "tech", "SWAPFORCE", "Wind Up"},
|
||||
{"3012", "c40b", "0030", "undead", "SWAPFORCE", "Roller Brawl"},
|
||||
--{"3012", "c40b", "0030", "undead", "SWAPFORCE", "Snowler Roller Brawl"},
|
||||
{"3013", "c50b", "0030", "undead", "SWAPFORCE", "Grim Creeper"},
|
||||
{"3014", "c60b", "0030", "water", "SWAPFORCE", "Rip Tide"},
|
||||
{"3015", "c70b", "0030", "water", "SWAPFORCE", "Punk Shock"},
|
||||
}
|
||||
|
||||
local function find( main, sub)
|
||||
main = main:lower()
|
||||
sub = sub:lower()
|
||||
for k, v in pairs(_names) do
|
||||
if ( v[2]:lower() == main and v[3]:lower() == sub) then
|
||||
return v
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
return {
|
||||
Find = find,
|
||||
}
|
||||
return _names
|
||||
|
|
|
@ -205,7 +205,7 @@ local function main( args)
|
|||
|
||||
-- NDEF compliant?
|
||||
if b3chars[1] ~= 0xE1 then
|
||||
return oops("This tag is not NDEF-Complian")
|
||||
return oops("This tag is not NDEF-Compliant")
|
||||
end
|
||||
|
||||
local ndefVersion = b3chars[2]
|
||||
|
|
|
@ -95,6 +95,7 @@ end
|
|||
|
||||
function test()
|
||||
local y
|
||||
local block = "00"
|
||||
for y = 0x0, 0x1d, 0x4 do
|
||||
for _ = 1, #procedurecmds do
|
||||
local pcmd = procedurecmds[_]
|
||||
|
@ -107,7 +108,7 @@ function test()
|
|||
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 writecmd = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK,arg1 = config, arg2 = block, arg3 = "00", data = "00"}
|
||||
local err = core.SendCommand(writecmd:getBytes())
|
||||
if err then return oops(err) end
|
||||
local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
|
||||
|
|
|
@ -89,6 +89,7 @@ end
|
|||
|
||||
function test()
|
||||
local y
|
||||
local block = "00"
|
||||
for y = 1, 0x1D, 4 do
|
||||
for _ = 1, #procedurecmds do
|
||||
local pcmd = procedurecmds[_]
|
||||
|
@ -98,10 +99,10 @@ function test()
|
|||
elseif _ == 1 then
|
||||
|
||||
local config = pcmd:format(config1, y, config2)
|
||||
dbg(('lf t55xx wr 0 %s'):format(config))
|
||||
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 writecmd = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK,arg1 = config, arg2 = block, arg3 = "00", data = "00"}
|
||||
local err = core.SendCommand(writecmd:getBytes())
|
||||
if err then return oops(err) end
|
||||
local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
|
||||
|
|
|
@ -92,6 +92,7 @@ end
|
|||
|
||||
function test(modulation)
|
||||
local y
|
||||
local block = "00"
|
||||
for y = 0x0, 0x1d, 0x4 do
|
||||
for _ = 1, #procedurecmds do
|
||||
local pcmd = procedurecmds[_]
|
||||
|
@ -104,7 +105,7 @@ function test(modulation)
|
|||
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 writecmd = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK,arg1 = config, arg2 = block, arg3 = "00", data = "00"}
|
||||
local err = core.SendCommand(writecmd:getBytes())
|
||||
if err then return oops(err) end
|
||||
local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
|
||||
|
|
|
@ -108,6 +108,7 @@ end
|
|||
function test(modulation)
|
||||
local bitrate
|
||||
local clockrate
|
||||
local block = "00"
|
||||
for bitrate = 0x0, 0x1d, 0x4 do
|
||||
|
||||
for clockrate = 0,8,4 do
|
||||
|
@ -125,8 +126,8 @@ function test(modulation)
|
|||
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())
|
||||
local writecmd = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK,arg1 = config, arg2 = block, arg3 = "00", data = "00"}
|
||||
local err = core.SendCommand(writecmd:getBytes())
|
||||
if err then return oops(err) end
|
||||
local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
|
||||
else
|
||||
|
|
161
client/scripts/tnp3clone.lua
Normal file
161
client/scripts/tnp3clone.lua
Normal file
|
@ -0,0 +1,161 @@
|
|||
local cmds = require('commands')
|
||||
local getopt = require('getopt')
|
||||
local lib14a = require('read14a')
|
||||
local utils = require('utils')
|
||||
local pre = require('precalc')
|
||||
local toys = require('default_toys')
|
||||
|
||||
local lsh = bit32.lshift
|
||||
local rsh = bit32.rshift
|
||||
local bor = bit32.bor
|
||||
local band = bit32.band
|
||||
|
||||
example =[[
|
||||
script run tnp3clone
|
||||
script run tnp3clone -h
|
||||
script run tnp3clone -t aa00 -s 0030
|
||||
|
||||
]]
|
||||
author = "Iceman"
|
||||
usage = "script run tnp3clone -t <toytype> -s <subtype>"
|
||||
desc =[[
|
||||
This script will try making a barebone clone of a tnp3 tag on to a magic generation1 card.
|
||||
|
||||
Arguments:
|
||||
-h : this help
|
||||
-t <data> : toytype id, 4hex symbols.
|
||||
-s <data> : subtype id, 4hex symbols
|
||||
|
||||
For fun, try the following subtype id:
|
||||
0612 - Lightcore
|
||||
0118 - Series 1
|
||||
0138 - Series 2
|
||||
0234 - Special
|
||||
023c - Special
|
||||
|
||||
]]
|
||||
|
||||
|
||||
-- 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
|
||||
|
||||
local function waitCmd()
|
||||
local response = core.WaitForResponseTimeout(cmds.CMD_ACK,2000)
|
||||
if response then
|
||||
local count,cmd,arg0 = bin.unpack('LL',response)
|
||||
if(arg0==1) then
|
||||
local count,arg1,arg2,data = bin.unpack('LLH511',response,count)
|
||||
return data:sub(1,32)
|
||||
else
|
||||
return nil, "Couldn't read block."
|
||||
end
|
||||
end
|
||||
return nil, "No response from device"
|
||||
end
|
||||
|
||||
local function readblock( blocknum, keyA )
|
||||
-- Read block 0
|
||||
cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = blocknum, arg2 = 0, arg3 = 0, data = keyA}
|
||||
err = core.SendCommand(cmd:getBytes())
|
||||
if err then return nil, err end
|
||||
local block0, err = waitCmd()
|
||||
if err then return nil, err end
|
||||
return block0
|
||||
end
|
||||
local function readmagicblock( blocknum )
|
||||
-- Read block 0
|
||||
local CSETBLOCK_SINGLE_OPERATION = 0x1F
|
||||
cmd = Command:new{cmd = cmds.CMD_MIFARE_CGETBLOCK, arg1 = CSETBLOCK_SINGLE_OPERATION, arg2 = 0, arg3 = blocknum}
|
||||
err = core.SendCommand(cmd:getBytes())
|
||||
if err then return nil, err end
|
||||
local block0, err = waitCmd()
|
||||
if err then return nil, err end
|
||||
return block0
|
||||
end
|
||||
|
||||
local function main(args)
|
||||
|
||||
print( string.rep('--',20) )
|
||||
print( string.rep('--',20) )
|
||||
|
||||
local numBlocks = 64
|
||||
local cset = 'hf mf csetbl '
|
||||
local csetuid = 'hf mf csetuid '
|
||||
local cget = 'hf mf cgetbl '
|
||||
local empty = '00000000000000000000000000000000'
|
||||
local AccAndKeyB = '7F078869000000000000'
|
||||
-- Defaults to Gusto
|
||||
local toytype = 'C201'
|
||||
local subtype = '0030'
|
||||
local DEBUG = true
|
||||
|
||||
-- Arguments for the script
|
||||
for o, a in getopt.getopt(args, 'ht:s:') do
|
||||
if o == "h" then return help() end
|
||||
if o == "t" then toytype = a end
|
||||
if o == "s" then subtype = a end
|
||||
end
|
||||
|
||||
if #toytype ~= 4 then return oops('Wrong size - toytype. (4hex symbols)') end
|
||||
if #subtype ~= 4 then return oops('Wrong size - subtype. (4hex symbols)') end
|
||||
|
||||
-- look up type, find & validate types
|
||||
local item = toys.Find( toytype, subtype)
|
||||
if item then
|
||||
print( (' Looking up input: Found %s - %s (%s)'):format(item[6],item[5], item[4]) )
|
||||
else
|
||||
print('Didn\'t find item type. If you are sure about it, report it in')
|
||||
end
|
||||
--15,16
|
||||
--13-14
|
||||
|
||||
|
||||
-- find tag
|
||||
result, err = lib14a.read1443a(false)
|
||||
if not result then return oops(err) end
|
||||
|
||||
-- load keys
|
||||
local akeys = pre.GetAll(result.uid)
|
||||
local keyA = akeys:sub(1, 12 )
|
||||
|
||||
local b0 = readblock(0,keyA)
|
||||
if not b0 then
|
||||
print('failed reading block with factorydefault key. Trying chinese magic read.')
|
||||
b0, err = readmagicblock(0)
|
||||
if not b0 then
|
||||
oops(err)
|
||||
return oops('failed reading block with chinese magic command. quitting...')
|
||||
end
|
||||
end
|
||||
|
||||
-- wipe card.
|
||||
local cmd = (csetuid..'%s 0004 08 w'):format(result.uid)
|
||||
core.console(cmd)
|
||||
|
||||
local b1 = toytype..'00000000000000000000'..subtype
|
||||
local calc = utils.Crc16(b0..b1)
|
||||
local calcEndian = bor(rsh(calc,8), lsh(band(calc, 0xff), 8))
|
||||
|
||||
local cmd = (cset..'1 %s%04x'):format( b1, calcEndian)
|
||||
core.console(cmd)
|
||||
|
||||
local pos, key
|
||||
for blockNo = 2, numBlocks-1, 1 do
|
||||
pos = (math.floor( blockNo / 4 ) * 12)+1
|
||||
key = akeys:sub(pos, pos + 11 )
|
||||
if blockNo%4 == 3 then
|
||||
cmd = ('%s %d %s%s'):format(cset,blockNo,key,AccAndKeyB)
|
||||
core.console(cmd)
|
||||
end
|
||||
end
|
||||
core.clearCommandBuffer()
|
||||
end
|
||||
main(args)
|
|
@ -5,19 +5,21 @@ local lib14a = require('read14a')
|
|||
local utils = require('utils')
|
||||
local md5 = require('md5')
|
||||
local dumplib = require('html_dumplib')
|
||||
local toyNames = require('default_toys')
|
||||
local toys = require('default_toys')
|
||||
|
||||
example =[[
|
||||
1. script run tnp3dump
|
||||
2. script run tnp3dump -n
|
||||
3. script run tnp3dump -k aabbccddeeff
|
||||
4. script run tnp3dump -k aabbccddeeff -n
|
||||
5. script run tnp3dump -o myfile
|
||||
6. script run tnp3dump -n -o myfile
|
||||
7. script run tnp3dump -k aabbccddeeff -n -o myfile
|
||||
script run tnp3dump
|
||||
script run tnp3dump -n
|
||||
script run tnp3dump -p
|
||||
script run tnp3dump -k aabbccddeeff
|
||||
script run tnp3dump -k aabbccddeeff -n
|
||||
script run tnp3dump -o myfile
|
||||
script run tnp3dump -n -o myfile
|
||||
script run tnp3dump -p -o myfile
|
||||
script run tnp3dump -k aabbccddeeff -n -o myfile
|
||||
]]
|
||||
author = "Iceman"
|
||||
usage = "script run tnp3dump -k <key> -n -o <filename>"
|
||||
usage = "script run tnp3dump -k <key> -n -p -o <filename>"
|
||||
desc =[[
|
||||
This script will try to dump the contents of a Mifare TNP3xxx card.
|
||||
It will need a valid KeyA in order to find the other keys and decode the card.
|
||||
|
@ -25,11 +27,10 @@ Arguments:
|
|||
-h : this help
|
||||
-k <key> : Sector 0 Key A.
|
||||
-n : Use the nested cmd to find all keys
|
||||
-p : Use the precalc to find all keys
|
||||
-o : filename for the saved dumps
|
||||
]]
|
||||
|
||||
local HASHCONSTANT = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20'
|
||||
|
||||
local RANDOM = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20'
|
||||
local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
|
||||
local DEBUG = false -- the debug flag
|
||||
local numBlocks = 64
|
||||
|
@ -93,16 +94,6 @@ local function waitCmd()
|
|||
return nil, "No response from device"
|
||||
end
|
||||
|
||||
local function computeCrc16(s)
|
||||
local hash = core.crc16(utils.ConvertHexToAscii(s))
|
||||
return hash
|
||||
end
|
||||
|
||||
local function reverseCrcBytes(crc)
|
||||
crc2 = crc:sub(3,4)..crc:sub(1,2)
|
||||
return tonumber(crc2,16)
|
||||
end
|
||||
|
||||
local function main(args)
|
||||
|
||||
print( string.rep('--',20) )
|
||||
|
@ -112,15 +103,17 @@ local function main(args)
|
|||
local cmd
|
||||
local err
|
||||
local useNested = false
|
||||
local usePreCalc = false
|
||||
local cmdReadBlockString = 'hf mf rdbl %d A %s'
|
||||
local input = "dumpkeys.bin"
|
||||
local outputTemplate = os.date("toydump_%Y-%m-%d_%H%M%S");
|
||||
|
||||
-- Arguments for the script
|
||||
for o, a in getopt.getopt(args, 'hk:no:') do
|
||||
for o, a in getopt.getopt(args, 'hk:npo:') do
|
||||
if o == "h" then return help() end
|
||||
if o == "k" then keyA = a end
|
||||
if o == "n" then useNested = true end
|
||||
if o == "p" then usePreCalc = true end
|
||||
if o == "o" then outputTemplate = a end
|
||||
end
|
||||
|
||||
|
@ -141,13 +134,10 @@ local function main(args)
|
|||
|
||||
core.clearCommandBuffer()
|
||||
|
||||
if 0x01 ~= result.sak then -- NXP MIFARE TNP3xxx
|
||||
return oops('This is not a TNP3xxx tag. aborting.')
|
||||
end
|
||||
|
||||
-- Show tag info
|
||||
print((' Found tag : %s'):format(result.name))
|
||||
print(('Using keyA : %s'):format(keyA))
|
||||
print((' Found tag %s'):format(result.name))
|
||||
|
||||
dbg(('Using keyA : %s'):format(keyA))
|
||||
|
||||
--Trying to find the other keys
|
||||
if useNested then
|
||||
|
@ -156,15 +146,19 @@ local function main(args)
|
|||
|
||||
core.clearCommandBuffer()
|
||||
|
||||
-- Loading keyfile
|
||||
print('Loading dumpkeys.bin')
|
||||
local hex, err = utils.ReadDumpFile(input)
|
||||
if not hex then
|
||||
return oops(err)
|
||||
local akeys = ''
|
||||
if usePreCalc then
|
||||
local pre = require('precalc')
|
||||
akeys = pre.GetAll(result.uid)
|
||||
else
|
||||
print('Loading dumpkeys.bin')
|
||||
local hex, err = utils.ReadDumpFile(input)
|
||||
if not hex then
|
||||
return oops(err)
|
||||
end
|
||||
akeys = hex:sub(0,12*16)
|
||||
end
|
||||
|
||||
local akeys = hex:sub(0,12*16)
|
||||
|
||||
-- Read block 0
|
||||
cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = 0,arg2 = 0,arg3 = 0, data = keyA}
|
||||
err = core.SendCommand(cmd:getBytes())
|
||||
|
@ -179,6 +173,8 @@ local function main(args)
|
|||
local block1, err = waitCmd()
|
||||
if err then return oops(err) end
|
||||
|
||||
local tmpHash = block0..block1..'%02x'..RANDOM
|
||||
|
||||
local key
|
||||
local pos = 0
|
||||
local blockNo
|
||||
|
@ -188,7 +184,7 @@ local function main(args)
|
|||
core.clearCommandBuffer()
|
||||
|
||||
-- main loop
|
||||
io.write('Decrypting blocks > ')
|
||||
io.write('Reading blocks > ')
|
||||
for blockNo = 0, numBlocks-1, 1 do
|
||||
|
||||
if core.ukbhit() then
|
||||
|
@ -204,25 +200,23 @@ local function main(args)
|
|||
local blockdata, err = waitCmd()
|
||||
if err then return oops(err) end
|
||||
|
||||
|
||||
if blockNo%4 ~= 3 then
|
||||
|
||||
if blockNo < 8 then
|
||||
-- Block 0-7 not encrypted
|
||||
blocks[blockNo+1] = ('%02d :: %s'):format(blockNo,blockdata)
|
||||
else
|
||||
local base = ('%s%s%02x%s'):format(block0, block1, blockNo, HASHCONSTANT)
|
||||
local baseStr = utils.ConvertHexToAscii(base)
|
||||
local md5hash = md5.sumhexa(baseStr)
|
||||
local aestest = core.aes(md5hash, blockdata)
|
||||
|
||||
local hex = utils.ConvertAsciiToBytes(aestest)
|
||||
hex = utils.ConvertBytesToHex(hex)
|
||||
|
||||
-- blocks with zero not encrypted.
|
||||
if string.find(blockdata, '^0+$') then
|
||||
blocks[blockNo+1] = ('%02d :: %s'):format(blockNo,blockdata)
|
||||
else
|
||||
local baseStr = utils.ConvertHexToAscii(tmpHash:format(blockNo))
|
||||
local key = md5.sumhexa(baseStr)
|
||||
local aestest = core.aes128_decrypt(key, blockdata)
|
||||
local hex = utils.ConvertAsciiToBytes(aestest)
|
||||
hex = utils.ConvertBytesToHex(hex)
|
||||
blocks[blockNo+1] = ('%02d :: %s'):format(blockNo,hex)
|
||||
io.write( blockNo..',')
|
||||
end
|
||||
end
|
||||
else
|
||||
|
@ -249,28 +243,35 @@ local function main(args)
|
|||
end
|
||||
end
|
||||
|
||||
print( string.rep('--',20) )
|
||||
|
||||
local uid = block0:sub(1,8)
|
||||
local itemtype = block1:sub(1,4)
|
||||
local toytype = block1:sub(1,4)
|
||||
local cardidLsw = block1:sub(9,16)
|
||||
local cardidMsw = block1:sub(16,24)
|
||||
local cardid = block1:sub(9,24)
|
||||
local traptype = block1:sub(25,28)
|
||||
local subtype = block1:sub(25,28)
|
||||
|
||||
-- Write dump to files
|
||||
if not DEBUG then
|
||||
local foo = dumplib.SaveAsBinary(bindata, outputTemplate..'_uid_'..uid..'.bin')
|
||||
print(("Wrote a BIN dump to the file %s"):format(foo))
|
||||
local bar = dumplib.SaveAsText(emldata, outputTemplate..'_uid_'..uid..'.eml')
|
||||
print(("Wrote a EML dump to the file %s"):format(bar))
|
||||
local foo = dumplib.SaveAsBinary(bindata, outputTemplate..'-'..uid..'.bin')
|
||||
print(("Wrote a BIN dump to: %s"):format(foo))
|
||||
local bar = dumplib.SaveAsText(emldata, outputTemplate..'-'..uid..'.eml')
|
||||
print(("Wrote a EML dump to: %s"):format(bar))
|
||||
end
|
||||
|
||||
-- Show info
|
||||
print( string.rep('--',20) )
|
||||
print( (' ITEM TYPE : 0x%s - %s'):format(itemtype, toyNames[itemtype]) )
|
||||
print( (' Alter ego / traptype : 0x%s'):format(traptype) )
|
||||
-- Show info
|
||||
|
||||
local item = toys.Find(toytype, subtype)
|
||||
if item then
|
||||
print((' ITEM TYPE : %s - %s (%s)'):format(item[6],item[5], item[4]) )
|
||||
else
|
||||
print((' ITEM TYPE : 0x%s 0x%s'):format(toytype, subtype))
|
||||
end
|
||||
|
||||
print( (' UID : 0x%s'):format(uid) )
|
||||
print( (' CARDID : 0x%s'):format(cardid ) )
|
||||
|
||||
print( string.rep('--',20) )
|
||||
|
||||
end
|
||||
main(args)
|
|
@ -4,7 +4,7 @@ local bin = require('bin')
|
|||
local lib14a = require('read14a')
|
||||
local utils = require('utils')
|
||||
local md5 = require('md5')
|
||||
local toyNames = require('default_toys')
|
||||
local toys = require('default_toys')
|
||||
|
||||
example =[[
|
||||
1. script run tnp3sim
|
||||
|
@ -27,6 +27,17 @@ Arguments:
|
|||
|
||||
local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
|
||||
local DEBUG = true -- the debug flag
|
||||
|
||||
|
||||
local band = bit32.band
|
||||
local bor = bit32.bor
|
||||
local lshift = bit32.lshift
|
||||
local rshift = bit32.rshift
|
||||
local byte = string.byte
|
||||
local char = string.char
|
||||
local sub = string.sub
|
||||
local format = string.format
|
||||
|
||||
---
|
||||
-- A debug printout-function
|
||||
function dbg(args)
|
||||
|
@ -65,7 +76,6 @@ function ExitMsg(msg)
|
|||
print()
|
||||
end
|
||||
|
||||
|
||||
local function writedumpfile(infile)
|
||||
t = infile:read("*all")
|
||||
len = string.len(t)
|
||||
|
@ -187,7 +197,6 @@ local function ValidateCheckSums(blocks)
|
|||
io.write( ('TYPE 3 area 2: %04x = %04x -- %s\n'):format(crc,calc,isOk))
|
||||
end
|
||||
|
||||
|
||||
local function LoadEmulator(blocks)
|
||||
local HASHCONSTANT = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20'
|
||||
local cmd
|
||||
|
@ -219,6 +228,102 @@ local function LoadEmulator(blocks)
|
|||
io.write('\n')
|
||||
end
|
||||
|
||||
local function Num2Card(m, l)
|
||||
|
||||
local k = {
|
||||
0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,0x42, 0x43, 0x44, 0x46, 0x47, 0x48, 0x4A, 0x4B,
|
||||
0x4C, 0x4D, 0x4E, 0x50, 0x51, 0x52, 0x53, 0x54,0x56, 0x57, 0x58, 0x59, 0x5A, 0x00
|
||||
}
|
||||
local msw = tonumber(utils.SwapEndiannessStr(m,32),16)
|
||||
local lsw = tonumber(utils.SwapEndiannessStr(l,32),16)
|
||||
|
||||
if msw > 0x17ea1 then
|
||||
return "too big"
|
||||
end
|
||||
|
||||
if msw == 0x17ea1 and lsw > 0x8931fee8 then
|
||||
return "out of range"
|
||||
end
|
||||
|
||||
local s = ""
|
||||
local index
|
||||
for i = 1,10 do
|
||||
index, msw, lsw = DivideByK( msw, lsw)
|
||||
if ( index <= 1 ) then
|
||||
s = char(k[index]) .. s
|
||||
else
|
||||
s = char(k[index-1]) .. s
|
||||
end
|
||||
print (index-1, msw, lsw)
|
||||
end
|
||||
return s
|
||||
end
|
||||
--33LRT-LM9Q9
|
||||
--7, 122, 3474858630
|
||||
--20, 4, 1008436634
|
||||
--7, 0, 627182959
|
||||
--17, 0, 21626998
|
||||
--16, 0, 745758
|
||||
--23, 0, 25715
|
||||
--21, 0, 886
|
||||
--16, 0, 30
|
||||
--1, 0, 1
|
||||
--1, 0, 0
|
||||
|
||||
function DivideByK(msw, lsw)
|
||||
|
||||
local lowLSW
|
||||
local highLSW
|
||||
local remainder = 0
|
||||
local RADIX = 29
|
||||
|
||||
--local num = 0 | band( rshift(msw,16), 0xffff)
|
||||
local num = band( rshift(msw, 16), 0xffff)
|
||||
|
||||
--highLSW = 0 | lshift( (num / RADIX) , 16)
|
||||
highLSW = lshift( (num / RADIX) , 16)
|
||||
remainder = num % RADIX
|
||||
|
||||
num = bor( lshift(remainder,16), band(msw, 0xffff))
|
||||
|
||||
--highLSW |= num / RADIX
|
||||
highLSW = highLSW or (num / RADIX)
|
||||
remainder = num % RADIX
|
||||
|
||||
num = bor( lshift(remainder,16), ( band(rshift(lsw,16), 0xffff)))
|
||||
|
||||
--lowLSW = 0 | (num / RADIX) << 16
|
||||
lowLSW = 0 or (lshift( (num / RADIX), 16))
|
||||
remainder = num % RADIX
|
||||
|
||||
num = bor( lshift(remainder,16) , band(lsw, 0xffff) )
|
||||
|
||||
lowLSW = bor(lowLSW, (num / RADIX))
|
||||
remainder = num % RADIX
|
||||
return remainder, highLSW, lowLSW
|
||||
|
||||
-- uint num = 0 | (msw >> 16) & 0xffff;
|
||||
|
||||
-- highLSW = 0 | (num / RADIX) << 16;
|
||||
-- remainder = num % RADIX;
|
||||
|
||||
-- num = (remainder << 16) | (msw & 0xffff);
|
||||
|
||||
-- highLSW |= num / RADIX;
|
||||
-- remainder = num % RADIX;
|
||||
|
||||
-- num = (remainder << 16) | ((lsw >> 16) & 0xffff);
|
||||
|
||||
-- lowLSW = 0 | (num / RADIX) << 16;
|
||||
-- remainder = num % RADIX;
|
||||
|
||||
-- num = (remainder << 16) | (lsw & 0xffff);
|
||||
|
||||
-- lowLSW |= num / RADIX;
|
||||
-- remainder = num % RADIX;
|
||||
|
||||
end
|
||||
|
||||
local function main(args)
|
||||
|
||||
print( string.rep('--',20) )
|
||||
|
@ -277,16 +382,31 @@ local function main(args)
|
|||
print( string.rep('--',20) )
|
||||
print(' Gathering info')
|
||||
local uid = blocks[0]:sub(1,8)
|
||||
local itemtype = blocks[1]:sub(1,4)
|
||||
local cardid = blocks[1]:sub(9,24)
|
||||
local toytype = blocks[1]:sub(1,4)
|
||||
local cardidLsw = blocks[1]:sub(9,16)
|
||||
local cardidMsw = blocks[1]:sub(17,24)
|
||||
local subtype = blocks[1]:sub(25,28)
|
||||
|
||||
-- Show info
|
||||
print( string.rep('--',20) )
|
||||
print( (' ITEM TYPE : 0x%s - %s'):format(itemtype, toyNames[itemtype]) )
|
||||
|
||||
local item = toys.Find( toytype, subtype)
|
||||
if item then
|
||||
local itemStr = ('%s - %s (%s)'):format(item[6],item[5], item[4])
|
||||
print(' ITEM TYPE :'..itemStr )
|
||||
else
|
||||
print( (' ITEM TYPE : 0x%s 0x%s'):format(toytype, subtype) )
|
||||
end
|
||||
|
||||
print( (' UID : 0x%s'):format(uid) )
|
||||
print( (' CARDID : 0x%s'):format(cardid ) )
|
||||
print( (' CARDID : 0x%s %s [%s]'):format(
|
||||
cardidMsw,cardidLsw,
|
||||
--Num2Card(cardidMsw, cardidLsw))
|
||||
'')
|
||||
)
|
||||
print( string.rep('--',20) )
|
||||
|
||||
|
||||
-- lets do something.
|
||||
--
|
||||
local experience = blocks[8]:sub(1,6)
|
||||
|
@ -351,7 +471,7 @@ local function main(args)
|
|||
err = LoadEmulator(blocks)
|
||||
if err then return oops(err) end
|
||||
core.clearCommandBuffer()
|
||||
print('The simulation is now prepared.\n --> run \"hf mf sim u '..uid..' x\" <--')
|
||||
print('The simulation is now prepared.\n --> run \"hf mf sim u '..uid..'\" <--')
|
||||
end
|
||||
end
|
||||
main(args)
|
|
@ -121,19 +121,24 @@ char * sprint_hex(const uint8_t * data, const size_t len) {
|
|||
return buf;
|
||||
}
|
||||
|
||||
char * sprint_bin(const uint8_t * data, const size_t len) {
|
||||
char *sprint_bin_break(const uint8_t *data, const size_t len, const uint8_t breaks) {
|
||||
|
||||
int maxLen = ( len > 1024) ? 1024 : len;
|
||||
static char buf[1024];
|
||||
char * tmp = buf;
|
||||
size_t i;
|
||||
char *tmp = buf;
|
||||
|
||||
for (i=0; i < maxLen; ++i, ++tmp)
|
||||
sprintf(tmp, "%u", data[i]);
|
||||
for (size_t i=0; i < maxLen; ++i){
|
||||
sprintf(tmp++, "%u", data[i]);
|
||||
if (breaks > 0 && !((i+1) % breaks))
|
||||
sprintf(tmp++, "%s","\n");
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *sprint_bin(const uint8_t *data, const size_t len) {
|
||||
return sprint_bin_break(data, len, 0);
|
||||
}
|
||||
void num_to_bytes(uint64_t n, size_t len, uint8_t* dest)
|
||||
{
|
||||
while (len--) {
|
||||
|
|
|
@ -39,6 +39,7 @@ void FillFileNameByUID(char *fileName, uint8_t * uid, char *ext, int byteCount);
|
|||
void print_hex(const uint8_t * data, const size_t len);
|
||||
char * sprint_hex(const uint8_t * data, const size_t len);
|
||||
char * sprint_bin(const uint8_t * data, const size_t len);
|
||||
char * sprint_bin_break(const uint8_t *data, const size_t len, const uint8_t breaks);
|
||||
|
||||
void num_to_bytes(uint64_t n, size_t len, uint8_t* dest);
|
||||
uint64_t bytes_to_num(uint8_t* src, size_t len);
|
||||
|
|
568
common/lfdemod.c
568
common/lfdemod.c
|
@ -81,10 +81,8 @@ uint8_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx, uint32_
|
|||
// otherwise could be a void with no arguments
|
||||
//set defaults
|
||||
uint32_t i = 0;
|
||||
if (BitStream[1]>1){ //allow only 1s and 0s
|
||||
// PrintAndLog("no data found");
|
||||
return 0;
|
||||
}
|
||||
if (BitStream[1]>1) return 0; //allow only 1s and 0s
|
||||
|
||||
// 111111111 bit pattern represent start of frame
|
||||
// include 0 in front to help get start pos
|
||||
uint8_t preamble[] = {0,1,1,1,1,1,1,1,1,1};
|
||||
|
@ -115,216 +113,11 @@ uint8_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx, uint32_
|
|||
}
|
||||
|
||||
//by marshmellow
|
||||
//takes 3 arguments - clock, invert, maxErr as integers
|
||||
//attempts to demodulate ask while decoding manchester
|
||||
//prints binary found and saves in graphbuffer for further commands
|
||||
int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr)
|
||||
{
|
||||
size_t i;
|
||||
int start = DetectASKClock(BinStream, *size, clk, 20); //clock default
|
||||
if (*clk==0 || start < 0) return -3;
|
||||
if (*invert != 1) *invert=0;
|
||||
uint8_t initLoopMax = 255;
|
||||
if (initLoopMax > *size) initLoopMax = *size;
|
||||
// Detect high and lows
|
||||
// 25% fuzz in case highs and lows aren't clipped [marshmellow]
|
||||
int high, low;
|
||||
if (getHiLo(BinStream, initLoopMax, &high, &low, 75, 75) < 1) return -2; //just noise
|
||||
|
||||
// PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low);
|
||||
int lastBit = 0; //set first clock check
|
||||
uint16_t bitnum = 0; //output counter
|
||||
uint8_t tol = 0; //clock tolerance adjust - waves will be accepted as within the clock if they fall + or - this value + clock from last valid wave
|
||||
if (*clk <= 32) tol=1; //clock tolerance may not be needed anymore currently set to + or - 1 but could be increased for poor waves or removed entirely
|
||||
size_t iii = 0;
|
||||
//if 0 errors allowed then only try first 2 clock cycles as we want a low tolerance
|
||||
if (!maxErr) initLoopMax = *clk * 2;
|
||||
uint16_t errCnt = 0, MaxBits = 512;
|
||||
uint16_t bestStart = start;
|
||||
uint16_t bestErrCnt = 0;
|
||||
// PrintAndLog("DEBUG - lastbit - %d",lastBit);
|
||||
// if best start position not already found by detect clock then
|
||||
if (start <= 0 || start > initLoopMax){
|
||||
bestErrCnt = maxErr+1;
|
||||
// loop to find first wave that works
|
||||
for (iii=0; iii < initLoopMax; ++iii){
|
||||
// if no peak skip
|
||||
if (BinStream[iii] < high && BinStream[iii] > low) continue;
|
||||
|
||||
lastBit = iii - *clk;
|
||||
// loop through to see if this start location works
|
||||
for (i = iii; i < *size; ++i) {
|
||||
if ((i-lastBit) > (*clk-tol) && (BinStream[i] >= high || BinStream[i] <= low)) {
|
||||
lastBit += *clk;
|
||||
} else if ((i-lastBit) > (*clk+tol)) {
|
||||
errCnt++;
|
||||
lastBit += *clk;
|
||||
}
|
||||
if ((i-iii) > (MaxBits * *clk) || errCnt > maxErr) break; //got plenty of bits or too many errors
|
||||
}
|
||||
//we got more than 64 good bits and not all errors
|
||||
if ((((i-iii)/ *clk) > (64)) && (errCnt<=maxErr)) {
|
||||
//possible good read
|
||||
if (!errCnt || errCnt < bestErrCnt){
|
||||
bestStart = iii; //set this as new best run
|
||||
bestErrCnt = errCnt;
|
||||
if (!errCnt) break; //great read - finish
|
||||
}
|
||||
}
|
||||
errCnt = 0;
|
||||
}
|
||||
}
|
||||
if (bestErrCnt > maxErr){
|
||||
*invert = bestStart;
|
||||
*clk = iii;
|
||||
return -1;
|
||||
}
|
||||
//best run is good enough set to best run and set overwrite BinStream
|
||||
lastBit = bestStart - *clk;
|
||||
errCnt = 0;
|
||||
for (i = bestStart; i < *size; ++i) {
|
||||
if ((BinStream[i] >= high) && ((i-lastBit) > (*clk-tol))){
|
||||
//high found and we are expecting a bar
|
||||
lastBit += *clk;
|
||||
BinStream[bitnum++] = *invert;
|
||||
} else if ((BinStream[i] <= low) && ((i-lastBit) > (*clk-tol))){
|
||||
//low found and we are expecting a bar
|
||||
lastBit += *clk;
|
||||
BinStream[bitnum++] = *invert ^ 1;
|
||||
} else if ((i-lastBit)>(*clk+tol)){
|
||||
//should have hit a high or low based on clock!!
|
||||
//PrintAndLog("DEBUG - no wave in expected area - location: %d, expected: %d-%d, lastBit: %d - resetting search",i,(lastBit+(clk-((int)(tol)))),(lastBit+(clk+((int)(tol)))),lastBit);
|
||||
if (bitnum > 0) {
|
||||
BinStream[bitnum++] = 77;
|
||||
errCnt++;
|
||||
}
|
||||
lastBit += *clk;//skip over error
|
||||
}
|
||||
if (bitnum >= MaxBits) break;
|
||||
}
|
||||
*size = bitnum;
|
||||
return bestErrCnt;
|
||||
}
|
||||
|
||||
//by marshmellow
|
||||
//encode binary data into binary manchester
|
||||
int ManchesterEncode(uint8_t *BitStream, size_t size)
|
||||
{
|
||||
size_t modIdx=20000, i=0;
|
||||
if (size>modIdx) return -1;
|
||||
for (size_t idx=0; idx < size; idx++){
|
||||
BitStream[idx+modIdx++] = BitStream[idx];
|
||||
BitStream[idx+modIdx++] = BitStream[idx]^1;
|
||||
}
|
||||
for (; i<(size*2); i++){
|
||||
BitStream[i] = BitStream[i+20000];
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
//by marshmellow
|
||||
//take 10 and 01 and manchester decode
|
||||
//run through 2 times and take least errCnt
|
||||
int manrawdecode(uint8_t * BitStream, size_t *size)
|
||||
{
|
||||
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=0;ii<2;++ii){
|
||||
for (i=ii; i<*size-2; i+=2)
|
||||
if (BitStream[i]==BitStream[i+1])
|
||||
errCnt++;
|
||||
|
||||
if (bestErr>errCnt){
|
||||
bestErr=errCnt;
|
||||
bestRun=ii;
|
||||
}
|
||||
errCnt=0;
|
||||
}
|
||||
if (bestErr<20){
|
||||
for (i=bestRun; i < *size-2; i+=2){
|
||||
if(BitStream[i] == 1 && (BitStream[i+1] == 0)){
|
||||
BitStream[bitnum++]=0;
|
||||
} else if((BitStream[i] == 0) && BitStream[i+1] == 1){
|
||||
BitStream[bitnum++]=1;
|
||||
} else {
|
||||
BitStream[bitnum++]=77;
|
||||
}
|
||||
if(bitnum>MaxBits) break;
|
||||
}
|
||||
*size=bitnum;
|
||||
}
|
||||
return bestErr;
|
||||
}
|
||||
|
||||
//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;
|
||||
uint16_t errCnt = 0;
|
||||
size_t i = offset;
|
||||
uint16_t MaxBits=512;
|
||||
//if not enough samples - error
|
||||
if (*size < 51) return -1;
|
||||
//check for phase change faults - skip one sample if faulty
|
||||
uint8_t offsetA = 1, offsetB = 1;
|
||||
for (; i<48; i+=2){
|
||||
if (BitStream[i+1]==BitStream[i+2]) offsetA=0;
|
||||
if (BitStream[i+2]==BitStream[i+3]) offsetB=0;
|
||||
}
|
||||
if (!offsetA && offsetB) offset++;
|
||||
for (i=offset; i<*size-3; i+=2){
|
||||
//check for phase error
|
||||
if (BitStream[i+1]==BitStream[i+2]) {
|
||||
BitStream[bitnum++]=77;
|
||||
errCnt++;
|
||||
}
|
||||
if((BitStream[i]==1 && BitStream[i+1]==0) || (BitStream[i]==0 && BitStream[i+1]==1)){
|
||||
BitStream[bitnum++]=1^invert;
|
||||
} else if((BitStream[i]==0 && BitStream[i+1]==0) || (BitStream[i]==1 && BitStream[i+1]==1)){
|
||||
BitStream[bitnum++]=invert;
|
||||
} else {
|
||||
BitStream[bitnum++]=77;
|
||||
errCnt++;
|
||||
}
|
||||
if(bitnum>MaxBits) break;
|
||||
}
|
||||
*size=bitnum;
|
||||
return errCnt;
|
||||
}
|
||||
|
||||
//by marshmellow
|
||||
void askAmp(uint8_t *BitStream, size_t size)
|
||||
{
|
||||
int shift = 127;
|
||||
int shiftedVal=0;
|
||||
for(size_t i = 1; i<size; i++){
|
||||
if (BitStream[i]-BitStream[i-1]>=30) //large jump up
|
||||
shift=127;
|
||||
else if(BitStream[i]-BitStream[i-1]<=-20) //large jump down
|
||||
shift=-127;
|
||||
|
||||
shiftedVal=BitStream[i]+shift;
|
||||
|
||||
if (shiftedVal>255)
|
||||
shiftedVal=255;
|
||||
else if (shiftedVal<0)
|
||||
shiftedVal=0;
|
||||
BitStream[i-1] = shiftedVal;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// demodulates strong heavily clipped samples
|
||||
//demodulates strong heavily clipped samples
|
||||
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++;
|
||||
|
@ -335,7 +128,7 @@ int cleanAskRawDemod(uint8_t *BinStream, size_t *size, int clk, int invert, int
|
|||
if (smplCnt > clk-(clk/4)-1) { //full clock
|
||||
if (smplCnt > clk + (clk/4)+1) { //too many samples
|
||||
errCnt++;
|
||||
BinStream[bitCnt++]=77;
|
||||
BinStream[bitCnt++]=7;
|
||||
} else if (waveHigh) {
|
||||
BinStream[bitCnt++] = invert;
|
||||
BinStream[bitCnt++] = invert;
|
||||
|
@ -371,111 +164,79 @@ int cleanAskRawDemod(uint8_t *BinStream, size_t *size, int clk, int invert, int
|
|||
}
|
||||
|
||||
//by marshmellow
|
||||
//takes 3 arguments - clock, invert and maxErr as integers
|
||||
//attempts to demodulate ask only
|
||||
int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr, uint8_t amp)
|
||||
void askAmp(uint8_t *BitStream, size_t size)
|
||||
{
|
||||
for(size_t i = 1; i<size; i++){
|
||||
if (BitStream[i]-BitStream[i-1]>=30) //large jump up
|
||||
BitStream[i]=127;
|
||||
else if(BitStream[i]-BitStream[i-1]<=-20) //large jump down
|
||||
BitStream[i]=-127;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//by marshmellow
|
||||
//attempts to demodulate ask modulations, askType == 0 for ask/raw, askType==1 for ask/manchester
|
||||
int askdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr, uint8_t amp, uint8_t askType)
|
||||
{
|
||||
if (*size==0) return -1;
|
||||
int start = DetectASKClock(BinStream, *size, clk, 20); //clock default
|
||||
if (*clk==0 || start < 0) return -1;
|
||||
int start = DetectASKClock(BinStream, *size, clk, maxErr); //clock default
|
||||
if (*clk==0 || start < 0) return -3;
|
||||
if (*invert != 1) *invert = 0;
|
||||
if (amp==1) askAmp(BinStream, *size);
|
||||
|
||||
uint8_t initLoopMax = 255;
|
||||
if (initLoopMax > *size) initLoopMax=*size;
|
||||
if (initLoopMax > *size) initLoopMax = *size;
|
||||
// Detect high and lows
|
||||
//25% clip in case highs and lows aren't clipped [marshmellow]
|
||||
int high, low;
|
||||
if (getHiLo(BinStream, initLoopMax, &high, &low, 75, 75) < 1)
|
||||
return -1; //just noise
|
||||
return -2; //just noise
|
||||
|
||||
size_t errCnt = 0;
|
||||
// if clean clipped waves detected run alternate demod
|
||||
if (DetectCleanAskWave(BinStream, *size, high, low))
|
||||
return cleanAskRawDemod(BinStream, size, *clk, *invert, high, low);
|
||||
if (DetectCleanAskWave(BinStream, *size, high, low)) {
|
||||
errCnt = cleanAskRawDemod(BinStream, size, *clk, *invert, high, low);
|
||||
if (askType) //askman
|
||||
return manrawdecode(BinStream, size, 0);
|
||||
else //askraw
|
||||
return errCnt;
|
||||
}
|
||||
|
||||
int lastBit = 0; //set first clock check - can go negative
|
||||
size_t i, iii = 0;
|
||||
size_t errCnt = 0, bitnum = 0; //output counter
|
||||
int lastBit; //set first clock check - can go negative
|
||||
size_t i, bitnum = 0; //output counter
|
||||
uint8_t midBit = 0;
|
||||
size_t bestStart = start, bestErrCnt = 0; //(*size/1000);
|
||||
uint8_t tol = 0; //clock tolerance adjust - waves will be accepted as within the clock if they fall + or - this value + clock from last valid wave
|
||||
if (*clk <= 32) tol = 1; //clock tolerance may not be needed anymore currently set to + or - 1 but could be increased for poor waves or removed entirely
|
||||
size_t MaxBits = 1024;
|
||||
lastBit = start - *clk;
|
||||
|
||||
//if 0 errors allowed then only try first 2 clock cycles as we want a low tolerance
|
||||
if (!maxErr) initLoopMax = *clk * 2;
|
||||
//if best start not already found by detectclock
|
||||
if (start <= 0 || start > initLoopMax){
|
||||
bestErrCnt = maxErr+1;
|
||||
//PrintAndLog("DEBUG - lastbit - %d",lastBit);
|
||||
//loop to find first wave that works
|
||||
for (iii=0; iii < initLoopMax; ++iii){
|
||||
if ((BinStream[iii] >= high) || (BinStream[iii] <= low)){
|
||||
lastBit = iii - *clk;
|
||||
//loop through to see if this start location works
|
||||
for (i = iii; i < *size; ++i) {
|
||||
if (i-lastBit > *clk && (BinStream[i] >= high || BinStream[i] <= low)){
|
||||
lastBit += *clk;
|
||||
midBit = 0;
|
||||
} else if (i-lastBit > (*clk/2) && midBit == 0) {
|
||||
midBit = 1;
|
||||
} else if ((i-lastBit) > *clk) {
|
||||
//should have hit a high or low based on clock!!
|
||||
//PrintAndLog("DEBUG - no wave in expected area - location: %d, expected: %d-%d, lastBit: %d - resetting search",i,(lastBit+(clk-((int)(tol)))),(lastBit+(clk+((int)(tol)))),lastBit);
|
||||
errCnt++;
|
||||
lastBit += *clk;//skip over until hit too many errors
|
||||
if (errCnt > maxErr)
|
||||
break;
|
||||
}
|
||||
if ((i-iii)>(MaxBits * *clk)) break; //got enough bits
|
||||
}
|
||||
//we got more than 64 good bits and not all errors
|
||||
if ((((i-iii)/ *clk) > 64) && (errCnt<=maxErr)) {
|
||||
//possible good read
|
||||
if (errCnt==0){
|
||||
bestStart=iii;
|
||||
bestErrCnt=errCnt;
|
||||
break; //great read - finish
|
||||
}
|
||||
if (errCnt<bestErrCnt){ //set this as new best run
|
||||
bestErrCnt=errCnt;
|
||||
bestStart = iii;
|
||||
}
|
||||
}
|
||||
errCnt=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bestErrCnt > maxErr){
|
||||
*invert = bestStart;
|
||||
*clk = iii;
|
||||
return -1;
|
||||
}
|
||||
//best run is good enough - set to best run and overwrite BinStream
|
||||
lastBit = bestStart - *clk - 1;
|
||||
errCnt = 0;
|
||||
|
||||
for (i = bestStart; i < *size; ++i) {
|
||||
if (i - lastBit > *clk){
|
||||
for (i = start; i < *size; ++i) {
|
||||
if (i-lastBit >= *clk-tol){
|
||||
if (BinStream[i] >= high) {
|
||||
BinStream[bitnum++] = *invert;
|
||||
} else if (BinStream[i] <= low) {
|
||||
BinStream[bitnum++] = *invert ^ 1;
|
||||
} else {
|
||||
} else if (i-lastBit >= *clk+tol) {
|
||||
if (bitnum > 0) {
|
||||
BinStream[bitnum++]=77;
|
||||
BinStream[bitnum++]=7;
|
||||
errCnt++;
|
||||
}
|
||||
} else { //in tolerance - looking for peak
|
||||
continue;
|
||||
}
|
||||
midBit = 0;
|
||||
lastBit += *clk;
|
||||
} else if (i-lastBit > (*clk/2) && midBit == 0){
|
||||
} else if (i-lastBit >= (*clk/2-tol) && !midBit && !askType){
|
||||
if (BinStream[i] >= high) {
|
||||
BinStream[bitnum++] = *invert;
|
||||
} else if (BinStream[i] <= low) {
|
||||
BinStream[bitnum++] = *invert ^ 1;
|
||||
} else {
|
||||
|
||||
} else if (i-lastBit >= *clk/2+tol) {
|
||||
BinStream[bitnum] = BinStream[bitnum-1];
|
||||
bitnum++;
|
||||
} else { //in tolerance - looking for peak
|
||||
continue;
|
||||
}
|
||||
midBit = 1;
|
||||
}
|
||||
|
@ -485,6 +246,98 @@ int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int max
|
|||
return errCnt;
|
||||
}
|
||||
|
||||
//by marshmellow
|
||||
//take 10 and 01 and manchester decode
|
||||
//run through 2 times and take least errCnt
|
||||
int manrawdecode(uint8_t * BitStream, size_t *size, uint8_t invert)
|
||||
{
|
||||
uint16_t bitnum=0, MaxBits = 512, errCnt = 0;
|
||||
size_t i, ii;
|
||||
uint16_t bestErr = 1000, bestRun = 0;
|
||||
if (*size < 16) return -1;
|
||||
//find correct start position [alignment]
|
||||
for (ii=0;ii<2;++ii){
|
||||
for (i=ii; i<*size-3; i+=2)
|
||||
if (BitStream[i]==BitStream[i+1])
|
||||
errCnt++;
|
||||
|
||||
if (bestErr>errCnt){
|
||||
bestErr=errCnt;
|
||||
bestRun=ii;
|
||||
}
|
||||
errCnt=0;
|
||||
}
|
||||
//decode
|
||||
for (i=bestRun; i < *size-3; i+=2){
|
||||
if(BitStream[i] == 1 && (BitStream[i+1] == 0)){
|
||||
BitStream[bitnum++]=invert;
|
||||
} else if((BitStream[i] == 0) && BitStream[i+1] == 1){
|
||||
BitStream[bitnum++]=invert^1;
|
||||
} else {
|
||||
BitStream[bitnum++]=7;
|
||||
}
|
||||
if(bitnum>MaxBits) break;
|
||||
}
|
||||
*size=bitnum;
|
||||
return bestErr;
|
||||
}
|
||||
|
||||
//by marshmellow
|
||||
//encode binary data into binary manchester
|
||||
int ManchesterEncode(uint8_t *BitStream, size_t size)
|
||||
{
|
||||
size_t modIdx=20000, i=0;
|
||||
if (size>modIdx) return -1;
|
||||
for (size_t idx=0; idx < size; idx++){
|
||||
BitStream[idx+modIdx++] = BitStream[idx];
|
||||
BitStream[idx+modIdx++] = BitStream[idx]^1;
|
||||
}
|
||||
for (; i<(size*2); i++){
|
||||
BitStream[i] = BitStream[i+20000];
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
//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;
|
||||
uint16_t errCnt = 0;
|
||||
size_t i = offset;
|
||||
uint16_t MaxBits=512;
|
||||
//if not enough samples - error
|
||||
if (*size < 51) return -1;
|
||||
//check for phase change faults - skip one sample if faulty
|
||||
uint8_t offsetA = 1, offsetB = 1;
|
||||
for (; i<48; i+=2){
|
||||
if (BitStream[i+1]==BitStream[i+2]) offsetA=0;
|
||||
if (BitStream[i+2]==BitStream[i+3]) offsetB=0;
|
||||
}
|
||||
if (!offsetA && offsetB) offset++;
|
||||
for (i=offset; i<*size-3; i+=2){
|
||||
//check for phase error
|
||||
if (BitStream[i+1]==BitStream[i+2]) {
|
||||
BitStream[bitnum++]=7;
|
||||
errCnt++;
|
||||
}
|
||||
if((BitStream[i]==1 && BitStream[i+1]==0) || (BitStream[i]==0 && BitStream[i+1]==1)){
|
||||
BitStream[bitnum++]=1^invert;
|
||||
} else if((BitStream[i]==0 && BitStream[i+1]==0) || (BitStream[i]==1 && BitStream[i+1]==1)){
|
||||
BitStream[bitnum++]=invert;
|
||||
} else {
|
||||
BitStream[bitnum++]=7;
|
||||
errCnt++;
|
||||
}
|
||||
if(bitnum>MaxBits) break;
|
||||
}
|
||||
*size=bitnum;
|
||||
return errCnt;
|
||||
}
|
||||
|
||||
// by marshmellow
|
||||
// demod gProxIIDemod
|
||||
// error returns as -x
|
||||
// success returns start position in BitStream
|
||||
|
@ -780,12 +633,13 @@ int PyramiddemodFSK(uint8_t *dest, size_t *size)
|
|||
return (int)startIdx;
|
||||
}
|
||||
|
||||
|
||||
uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, int high, int low)
|
||||
// by marshmellow
|
||||
// to detect a wave that has heavily clipped (clean) samples
|
||||
uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, uint8_t high, uint8_t low)
|
||||
{
|
||||
uint16_t allPeaks=1;
|
||||
uint16_t cntPeaks=0;
|
||||
size_t loopEnd = 572;
|
||||
size_t loopEnd = 512+60;
|
||||
if (loopEnd > size) loopEnd = size;
|
||||
for (size_t i=60; i<loopEnd; i++){
|
||||
if (dest[i]>low && dest[i]<high)
|
||||
|
@ -801,53 +655,39 @@ uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, int high, int low)
|
|||
|
||||
// by marshmellow
|
||||
// to help detect clocks on heavily clipped samples
|
||||
// based on counts between zero crossings
|
||||
int DetectStrongAskClock(uint8_t dest[], size_t size)
|
||||
// based on count of low to low
|
||||
int DetectStrongAskClock(uint8_t dest[], size_t size, uint8_t high, uint8_t low)
|
||||
{
|
||||
int clk[]={0,8,16,32,40,50,64,100,128};
|
||||
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++;
|
||||
}
|
||||
}
|
||||
uint8_t fndClk[] = {8,16,32,40,50,64,128};
|
||||
size_t startwave;
|
||||
size_t i = 0;
|
||||
size_t minClk = 255;
|
||||
// get to first full low to prime loop and skip incomplete first pulse
|
||||
while ((dest[i] < high) && (i < size))
|
||||
++i;
|
||||
while ((dest[i] > low) && (i < size))
|
||||
++i;
|
||||
|
||||
// loop through all samples
|
||||
while (i < size) {
|
||||
// measure from low to low
|
||||
while ((dest[i] > low) && (i < size))
|
||||
++i;
|
||||
startwave= i;
|
||||
while ((dest[i] < high) && (i < size))
|
||||
++i;
|
||||
while ((dest[i] > low) && (i < size))
|
||||
++i;
|
||||
//get minimum measured distance
|
||||
if (i-startwave < minClk && i < size)
|
||||
minClk = i - startwave;
|
||||
}
|
||||
uint8_t tol;
|
||||
for (idx=8; idx>0; idx--){
|
||||
tol = clk[idx]/8;
|
||||
if (clk[idx] >= highCnt - tol && clk[idx] <= highCnt + tol)
|
||||
return clk[idx];
|
||||
if (clk[idx] >= highCnt2 - tol && clk[idx] <= highCnt2 + tol)
|
||||
return clk[idx];
|
||||
// set clock
|
||||
for (uint8_t clkCnt = 0; clkCnt<7; clkCnt++) {
|
||||
if (minClk >= fndClk[clkCnt]-(fndClk[clkCnt]/8) && minClk <= fndClk[clkCnt]+1)
|
||||
return fndClk[clkCnt];
|
||||
}
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// by marshmellow
|
||||
|
@ -856,45 +696,61 @@ int DetectStrongAskClock(uint8_t dest[], size_t size)
|
|||
// return start index of best starting position for that clock and return clock (by reference)
|
||||
int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr)
|
||||
{
|
||||
size_t i=0;
|
||||
uint8_t clk[]={8,16,32,40,50,64,100,128,255};
|
||||
size_t i=1;
|
||||
uint8_t clk[] = {255,8,16,32,40,50,64,100,128,255};
|
||||
uint8_t clkEnd = 9;
|
||||
uint8_t loopCnt = 255; //don't need to loop through entire array...
|
||||
if (size <= loopCnt) return -1; //not enough samples
|
||||
//if we already have a valid clock quit
|
||||
|
||||
for (;i<8;++i)
|
||||
if (clk[i] == *clock) return 0;
|
||||
//if we already have a valid clock
|
||||
uint8_t clockFnd=0;
|
||||
for (;i<clkEnd;++i)
|
||||
if (clk[i] == *clock) clockFnd = i;
|
||||
//clock found but continue to find best startpos
|
||||
|
||||
//get high and low peak
|
||||
int peak, low;
|
||||
if (getHiLo(dest, loopCnt, &peak, &low, 75, 75) < 1) return -1;
|
||||
|
||||
//test for large clean peaks
|
||||
if (DetectCleanAskWave(dest, size, peak, low)==1){
|
||||
int ans = DetectStrongAskClock(dest, size);
|
||||
for (i=7; i>0; i--){
|
||||
if (clk[i] == ans) {
|
||||
*clock = ans;
|
||||
return 0;
|
||||
if (!clockFnd){
|
||||
if (DetectCleanAskWave(dest, size, peak, low)==1){
|
||||
int ans = DetectStrongAskClock(dest, size, peak, low);
|
||||
for (i=clkEnd-1; i>0; i--){
|
||||
if (clk[i] == ans) {
|
||||
*clock = ans;
|
||||
//clockFnd = i;
|
||||
return 0; // for strong waves i don't use the 'best start position' yet...
|
||||
//break; //clock found but continue to find best startpos [not yet]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ii;
|
||||
uint8_t clkCnt, tol = 0;
|
||||
uint16_t bestErr[]={1000,1000,1000,1000,1000,1000,1000,1000,1000};
|
||||
uint8_t bestStart[]={0,0,0,0,0,0,0,0,0};
|
||||
size_t errCnt = 0;
|
||||
size_t arrLoc, loopEnd;
|
||||
|
||||
if (clockFnd>0) {
|
||||
clkCnt = clockFnd;
|
||||
clkEnd = clockFnd+1;
|
||||
}
|
||||
else clkCnt=1;
|
||||
|
||||
//test each valid clock from smallest to greatest to see which lines up
|
||||
for(clkCnt=0; clkCnt < 8; clkCnt++){
|
||||
if (clk[clkCnt] == 32){
|
||||
for(; clkCnt < clkEnd; clkCnt++){
|
||||
if (clk[clkCnt] <= 32){
|
||||
tol=1;
|
||||
}else{
|
||||
tol=0;
|
||||
}
|
||||
if (!maxErr) loopCnt=clk[clkCnt]*2;
|
||||
//if no errors allowed - keep start within the first clock
|
||||
if (!maxErr && size > clk[clkCnt]*2 + tol && clk[clkCnt]<128) loopCnt=clk[clkCnt]*2;
|
||||
bestErr[clkCnt]=1000;
|
||||
//try lining up the peaks by moving starting point (try first 256)
|
||||
//try lining up the peaks by moving starting point (try first few clocks)
|
||||
for (ii=0; ii < loopCnt; ii++){
|
||||
if (dest[ii] < peak && dest[ii] > low) continue;
|
||||
|
||||
|
@ -910,11 +766,11 @@ int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr)
|
|||
errCnt++;
|
||||
}
|
||||
}
|
||||
//if we found no errors then we can stop here
|
||||
//if we found no errors then we can stop here and a low clock (common clocks)
|
||||
// this is correct one - return this clock
|
||||
//PrintAndLog("DEBUG: clk %d, err %d, ii %d, i %d",clk[clkCnt],errCnt,ii,i);
|
||||
if(errCnt==0 && clkCnt<6) {
|
||||
*clock = clk[clkCnt];
|
||||
if(errCnt==0 && clkCnt<7) {
|
||||
if (!clockFnd) *clock = clk[clkCnt];
|
||||
return ii;
|
||||
}
|
||||
//if we found errors see if it is lowest so far and save it as best run
|
||||
|
@ -924,9 +780,9 @@ int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr)
|
|||
}
|
||||
}
|
||||
}
|
||||
uint8_t iii=0;
|
||||
uint8_t iii;
|
||||
uint8_t best=0;
|
||||
for (iii=0; iii<8; ++iii){
|
||||
for (iii=1; iii<clkEnd; ++iii){
|
||||
if (bestErr[iii] < bestErr[best]){
|
||||
if (bestErr[iii] == 0) bestErr[iii]=1;
|
||||
// current best bit to error ratio vs new bit to error ratio
|
||||
|
@ -935,8 +791,8 @@ int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr)
|
|||
}
|
||||
}
|
||||
}
|
||||
if (bestErr[best] > maxErr) return -1;
|
||||
*clock = clk[best];
|
||||
//if (bestErr[best] > maxErr) return -1;
|
||||
if (!clockFnd) *clock = clk[best];
|
||||
return bestStart[best];
|
||||
}
|
||||
|
||||
|
@ -1115,7 +971,7 @@ void psk1TOpsk2(uint8_t *BitStream, size_t size)
|
|||
size_t i=1;
|
||||
uint8_t lastBit=BitStream[0];
|
||||
for (; i<size; i++){
|
||||
if (BitStream[i]==77){
|
||||
if (BitStream[i]==7){
|
||||
//ignore errors
|
||||
} else if (lastBit!=BitStream[i]){
|
||||
lastBit=BitStream[i];
|
||||
|
@ -1308,7 +1164,7 @@ int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr)
|
|||
if (ignoreCnt == 0){
|
||||
bitHigh = 0;
|
||||
if (errBitHigh == 1){
|
||||
dest[bitnum++] = 77;
|
||||
dest[bitnum++] = 7;
|
||||
errCnt++;
|
||||
}
|
||||
errBitHigh=0;
|
||||
|
@ -1583,7 +1439,7 @@ int pskRawDemod(uint8_t dest[], size_t *size, int *clock, int *invert)
|
|||
//noise after a phase shift - ignore
|
||||
} else { //phase shift before supposed to based on clock
|
||||
errCnt++;
|
||||
dest[numBits++] = 77;
|
||||
dest[numBits++] = 7;
|
||||
}
|
||||
} else if (i+1 > lastClkBit + *clock + tol + fc){
|
||||
lastClkBit += *clock; //no phase shift but clock bit
|
||||
|
|
|
@ -15,34 +15,37 @@
|
|||
#define LFDEMOD_H__
|
||||
#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);
|
||||
int ManchesterEncode(uint8_t *BitStream, size_t size);
|
||||
int manrawdecode(uint8_t *BitStream, size_t *size);
|
||||
int BiphaseRawDecode(uint8_t * BitStream, size_t *size, int offset, int invert);
|
||||
int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr, uint8_t amp);
|
||||
//generic
|
||||
int askdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr, uint8_t amp, uint8_t askType);
|
||||
int BiphaseRawDecode(uint8_t * BitStream, size_t *size, int offset, int invert);
|
||||
uint32_t bytebits_to_byte(uint8_t* src, size_t numbits);
|
||||
uint16_t countFC(uint8_t *BitStream, size_t size, uint8_t fskAdj);
|
||||
int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr);
|
||||
uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, uint8_t high, uint8_t low);
|
||||
uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fcLow);
|
||||
int DetectNRZClock(uint8_t dest[], size_t size, int clock);
|
||||
int DetectPSKClock(uint8_t dest[], size_t size, int clock);
|
||||
int DetectStrongAskClock(uint8_t dest[], size_t size, uint8_t high, uint8_t low);
|
||||
uint8_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx, uint32_t *hi, uint64_t *lo);
|
||||
int fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uint8_t fchigh, uint8_t fclow);
|
||||
int getHiLo(uint8_t *BitStream, size_t size, int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo);
|
||||
int ManchesterEncode(uint8_t *BitStream, size_t size);
|
||||
int manrawdecode(uint8_t *BitStream, size_t *size, uint8_t invert);
|
||||
int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr);
|
||||
uint8_t parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType);
|
||||
uint8_t preambleSearch(uint8_t *BitStream, uint8_t *preamble, size_t pLen, size_t *size, size_t *startIdx);
|
||||
int pskRawDemod(uint8_t dest[], size_t *size, int *clock, int *invert);
|
||||
void psk2TOpsk1(uint8_t *BitStream, size_t size);
|
||||
void psk1TOpsk2(uint8_t *BitStream, size_t size);
|
||||
size_t removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t pType, size_t bLen);
|
||||
|
||||
//tag specific
|
||||
int AWIDdemodFSK(uint8_t *dest, size_t *size);
|
||||
int gProxII_Demod(uint8_t BitStream[], size_t *size);
|
||||
int HIDdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo);
|
||||
int IOdemodFSK(uint8_t *dest, size_t size);
|
||||
int fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uint8_t fchigh, uint8_t fclow);
|
||||
uint32_t bytebits_to_byte(uint8_t* src, size_t numbits);
|
||||
int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr);
|
||||
void psk1TOpsk2(uint8_t *BitStream, size_t size);
|
||||
void psk2TOpsk1(uint8_t *BitStream, size_t size);
|
||||
int DetectNRZClock(uint8_t dest[], size_t size, int clock);
|
||||
int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert);
|
||||
int PyramiddemodFSK(uint8_t *dest, size_t *size);
|
||||
int AWIDdemodFSK(uint8_t *dest, size_t *size);
|
||||
size_t removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t pType, size_t bLen);
|
||||
uint16_t countFC(uint8_t *BitStream, size_t size, uint8_t fskAdj);
|
||||
uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fcLow);
|
||||
int getHiLo(uint8_t *BitStream, size_t size, int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo);
|
||||
int ParadoxdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo);
|
||||
uint8_t preambleSearch(uint8_t *BitStream, uint8_t *preamble, size_t pLen, size_t *size, size_t *startIdx);
|
||||
uint8_t parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType);
|
||||
int pskRawDemod(uint8_t dest[], size_t *size, int *clock, int *invert);
|
||||
int DetectPSKClock(uint8_t dest[], size_t size, int clock);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue