mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 21:33:47 -07:00
ADD: LF JABLOTRON functionality. with clone/sim and detection in LF SEARCH.
CHG: removed no-existing crc8ja code FIX: a check in ASKbiphaseDemod to make sure graphbuff is not empty.
This commit is contained in:
parent
e92948c60c
commit
6c28395106
12 changed files with 426 additions and 177 deletions
|
@ -130,6 +130,7 @@ CMDSRCS = mifarehost.c \
|
||||||
cmdlfpyramid.c \
|
cmdlfpyramid.c \
|
||||||
cmdlfguard.c \
|
cmdlfguard.c \
|
||||||
cmdlfnedap.c \
|
cmdlfnedap.c \
|
||||||
|
cmdlfjablotron.c \
|
||||||
pm3_binlib.c \
|
pm3_binlib.c \
|
||||||
scripting.c \
|
scripting.c \
|
||||||
cmdscript.c \
|
cmdscript.c \
|
||||||
|
|
|
@ -70,7 +70,7 @@ static uint8_t calcSumCrumbAdd( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
||||||
sum += CRUMB(bytes[i], 4);
|
sum += CRUMB(bytes[i], 4);
|
||||||
sum += CRUMB(bytes[i], 6);
|
sum += CRUMB(bytes[i], 6);
|
||||||
}
|
}
|
||||||
sum ^= mask;
|
sum &= mask;
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
static uint8_t calcSumCrumbAddOnes( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
static uint8_t calcSumCrumbAddOnes( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
||||||
|
@ -82,7 +82,7 @@ static uint8_t calcSumNibbleAdd( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
||||||
sum += NIBBLE_LOW(bytes[i]);
|
sum += NIBBLE_LOW(bytes[i]);
|
||||||
sum += NIBBLE_HIGH(bytes[i]);
|
sum += NIBBLE_HIGH(bytes[i]);
|
||||||
}
|
}
|
||||||
sum ^= mask;
|
sum &= mask;
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
static uint8_t calcSumNibbleAddOnes( uint8_t* bytes, uint8_t len, uint32_t mask){
|
static uint8_t calcSumNibbleAddOnes( uint8_t* bytes, uint8_t len, uint32_t mask){
|
||||||
|
@ -93,7 +93,7 @@ static uint8_t calcSumByteAdd( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
||||||
uint8_t sum = 0;
|
uint8_t sum = 0;
|
||||||
for (uint8_t i = 0; i < len; i++)
|
for (uint8_t i = 0; i < len; i++)
|
||||||
sum += bytes[i];
|
sum += bytes[i];
|
||||||
sum ^= mask;
|
sum &= mask;
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
// Ones complement
|
// Ones complement
|
||||||
|
@ -105,7 +105,7 @@ static uint8_t calcSumByteSub( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
||||||
uint8_t sum = 0;
|
uint8_t sum = 0;
|
||||||
for (uint8_t i = 0; i < len; i++)
|
for (uint8_t i = 0; i < len; i++)
|
||||||
sum -= bytes[i];
|
sum -= bytes[i];
|
||||||
sum ^= mask;
|
sum &= mask;
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
static uint8_t calcSumByteSubOnes( uint8_t* bytes, uint8_t len, uint32_t mask){
|
static uint8_t calcSumByteSubOnes( uint8_t* bytes, uint8_t len, uint32_t mask){
|
||||||
|
@ -117,7 +117,7 @@ static uint8_t calcSumNibbleSub( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
||||||
sum -= NIBBLE_LOW(bytes[i]);
|
sum -= NIBBLE_LOW(bytes[i]);
|
||||||
sum -= NIBBLE_HIGH(bytes[i]);
|
sum -= NIBBLE_HIGH(bytes[i]);
|
||||||
}
|
}
|
||||||
sum ^= mask;
|
sum &= mask;
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
static uint8_t calcSumNibbleSubOnes( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
static uint8_t calcSumNibbleSubOnes( uint8_t* bytes, uint8_t len, uint32_t mask) {
|
||||||
|
@ -155,8 +155,7 @@ int CmdAnalyseCRC(const char *Cmd) {
|
||||||
}
|
}
|
||||||
len >>= 1;
|
len >>= 1;
|
||||||
|
|
||||||
PrintAndLog("\nTests with '%s' hex bytes", sprint_hex(data, len));
|
//PrintAndLog("\nTests with '%s' hex bytes", sprint_hex(data, len));
|
||||||
PrintAndLog(" JA: CRC8: %X (0x6C expected)", CRC8ja(data, len) );
|
|
||||||
|
|
||||||
PrintAndLog("\nTests of reflection. Two current methods in source code");
|
PrintAndLog("\nTests of reflection. Two current methods in source code");
|
||||||
PrintAndLog(" reflect(0x3e23L,3) is %04X == 0x3e26", reflect(0x3e23L,3) );
|
PrintAndLog(" reflect(0x3e23L,3) is %04X == 0x3e26", reflect(0x3e23L,3) );
|
||||||
|
@ -170,7 +169,6 @@ int CmdAnalyseCRC(const char *Cmd) {
|
||||||
uint8_t dataStr[] = { 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39 };
|
uint8_t dataStr[] = { 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39 };
|
||||||
uint8_t legic8 = CRC8Legic(dataStr, sizeof(dataStr));
|
uint8_t legic8 = CRC8Legic(dataStr, sizeof(dataStr));
|
||||||
|
|
||||||
PrintAndLog("JA: CRC8 : %X (0x28 expected)", CRC8ja(dataStr, sizeof(dataStr)) );
|
|
||||||
PrintAndLog("LEGIC: CRC16: %X", CRC16Legic(dataStr, sizeof(dataStr), legic8));
|
PrintAndLog("LEGIC: CRC16: %X", CRC16Legic(dataStr, sizeof(dataStr), legic8));
|
||||||
|
|
||||||
//these below has been tested OK.
|
//these below has been tested OK.
|
||||||
|
|
|
@ -528,6 +528,10 @@ int ASKbiphaseDemod(const char *Cmd, bool verbose)
|
||||||
|
|
||||||
uint8_t BitStream[MAX_DEMOD_BUF_LEN];
|
uint8_t BitStream[MAX_DEMOD_BUF_LEN];
|
||||||
size_t size = getFromGraphBuf(BitStream);
|
size_t size = getFromGraphBuf(BitStream);
|
||||||
|
if (size == 0 ) {
|
||||||
|
if (g_debugMode) PrintAndLog("DEBUG: no data in graphbuf");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
//invert here inverts the ask raw demoded bits which has no effect on the demod, but we need the pointer
|
//invert here inverts the ask raw demoded bits which has no effect on the demod, but we need the pointer
|
||||||
int errCnt = askdemod(BitStream, &size, &clk, &invert, maxErr, 0, 0);
|
int errCnt = askdemod(BitStream, &size, &clk, &invert, maxErr, 0, 0);
|
||||||
if ( errCnt < 0 || errCnt > maxErr ) {
|
if ( errCnt < 0 || errCnt > maxErr ) {
|
||||||
|
|
244
client/cmdlf.c
244
client/cmdlf.c
|
@ -637,115 +637,113 @@ int CmdLFSim(const char *Cmd)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// by marshmellow - sim ask data given clock, fcHigh, fcLow, invert
|
// by marshmellow - sim fsk data given clock, fcHigh, fcLow, invert
|
||||||
// - allow pull data from DemodBuffer
|
// - allow pull data from DemodBuffer
|
||||||
int CmdLFfskSim(const char *Cmd)
|
int CmdLFfskSim(const char *Cmd)
|
||||||
{
|
{
|
||||||
//might be able to autodetect FCs and clock from Graphbuffer if using demod buffer
|
//might be able to autodetect FCs and clock from Graphbuffer if using demod buffer
|
||||||
// otherwise will need FChigh, FClow, Clock, and bitstream
|
// otherwise will need FChigh, FClow, Clock, and bitstream
|
||||||
uint8_t fcHigh=0, fcLow=0, clk=0;
|
uint8_t fcHigh = 0, fcLow = 0, clk = 0;
|
||||||
uint8_t invert=0;
|
uint8_t invert = 0;
|
||||||
bool errors = FALSE;
|
bool errors = FALSE;
|
||||||
char hexData[32] = {0x00}; // store entered hex data
|
char hexData[32] = {0x00}; // store entered hex data
|
||||||
uint8_t data[255] = {0x00};
|
uint8_t data[255] = {0x00};
|
||||||
int dataLen = 0;
|
int dataLen = 0;
|
||||||
uint8_t cmdp = 0;
|
uint8_t cmdp = 0;
|
||||||
while(param_getchar(Cmd, cmdp) != 0x00)
|
|
||||||
{
|
|
||||||
switch(param_getchar(Cmd, cmdp))
|
|
||||||
{
|
|
||||||
case 'h':
|
|
||||||
return usage_lf_simfsk();
|
|
||||||
case 'i':
|
|
||||||
invert = 1;
|
|
||||||
cmdp++;
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
errors |= param_getdec(Cmd,cmdp+1,&clk);
|
|
||||||
cmdp+=2;
|
|
||||||
break;
|
|
||||||
case 'H':
|
|
||||||
errors |= param_getdec(Cmd,cmdp+1,&fcHigh);
|
|
||||||
cmdp+=2;
|
|
||||||
break;
|
|
||||||
case 'L':
|
|
||||||
errors |= param_getdec(Cmd,cmdp+1,&fcLow);
|
|
||||||
cmdp+=2;
|
|
||||||
break;
|
|
||||||
//case 's':
|
|
||||||
// separator=1;
|
|
||||||
// cmdp++;
|
|
||||||
// break;
|
|
||||||
case 'd':
|
|
||||||
dataLen = param_getstr(Cmd, cmdp+1, hexData);
|
|
||||||
if (dataLen==0) {
|
|
||||||
errors=TRUE;
|
|
||||||
} else {
|
|
||||||
dataLen = hextobinarray((char *)data, hexData);
|
|
||||||
}
|
|
||||||
if (dataLen==0) errors=TRUE;
|
|
||||||
if (errors) PrintAndLog ("Error getting hex data");
|
|
||||||
cmdp+=2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
|
||||||
errors = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(errors) break;
|
|
||||||
}
|
|
||||||
if(cmdp == 0 && DemodBufferLen == 0)
|
|
||||||
{
|
|
||||||
errors = TRUE;// No args
|
|
||||||
}
|
|
||||||
|
|
||||||
//Validations
|
while(param_getchar(Cmd, cmdp) != 0x00)
|
||||||
if(errors)
|
{
|
||||||
{
|
switch(param_getchar(Cmd, cmdp))
|
||||||
return usage_lf_simfsk();
|
{
|
||||||
}
|
case 'h':
|
||||||
|
return usage_lf_simfsk();
|
||||||
|
case 'i':
|
||||||
|
invert = 1;
|
||||||
|
cmdp++;
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
errors |= param_getdec(Cmd, cmdp+1, &clk);
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
case 'H':
|
||||||
|
errors |= param_getdec(Cmd, cmdp+1, &fcHigh);
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
case 'L':
|
||||||
|
errors |= param_getdec(Cmd, cmdp+1, &fcLow);
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
//case 's':
|
||||||
|
// separator = 1;
|
||||||
|
// cmdp++;
|
||||||
|
// break;
|
||||||
|
case 'd':
|
||||||
|
dataLen = param_getstr(Cmd, cmdp+1, hexData);
|
||||||
|
if (dataLen == 0)
|
||||||
|
errors = TRUE;
|
||||||
|
else
|
||||||
|
dataLen = hextobinarray((char *)data, hexData);
|
||||||
|
|
||||||
if (dataLen == 0){ //using DemodBuffer
|
if (dataLen == 0) errors = TRUE;
|
||||||
if (clk==0 || fcHigh==0 || fcLow==0){ //manual settings must set them all
|
if (errors) PrintAndLog ("Error getting hex data");
|
||||||
uint8_t ans = fskClocks(&fcHigh, &fcLow, &clk, 0);
|
cmdp+=2;
|
||||||
if (ans==0){
|
break;
|
||||||
if (!fcHigh) fcHigh=10;
|
default:
|
||||||
if (!fcLow) fcLow=8;
|
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||||
if (!clk) clk=50;
|
errors = TRUE;
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
if(errors) break;
|
||||||
setDemodBuf(data, dataLen, 0);
|
}
|
||||||
}
|
|
||||||
|
// No args
|
||||||
|
if(cmdp == 0 && DemodBufferLen == 0)
|
||||||
|
errors = TRUE;
|
||||||
|
|
||||||
|
//Validations
|
||||||
|
if(errors) return usage_lf_simfsk();
|
||||||
|
|
||||||
|
if (dataLen == 0){ //using DemodBuffer
|
||||||
|
if (clk == 0 || fcHigh == 0 || fcLow == 0){ //manual settings must set them all
|
||||||
|
uint8_t ans = fskClocks(&fcHigh, &fcLow, &clk, 0);
|
||||||
|
if (ans==0){
|
||||||
|
if (!fcHigh) fcHigh = 10;
|
||||||
|
if (!fcLow) fcLow = 8;
|
||||||
|
if (!clk) clk = 50;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setDemodBuf(data, dataLen, 0);
|
||||||
|
}
|
||||||
|
|
||||||
//default if not found
|
//default if not found
|
||||||
if (clk == 0) clk = 50;
|
if (clk == 0) clk = 50;
|
||||||
if (fcHigh == 0) fcHigh = 10;
|
if (fcHigh == 0) fcHigh = 10;
|
||||||
if (fcLow == 0) fcLow = 8;
|
if (fcLow == 0) fcLow = 8;
|
||||||
|
|
||||||
uint16_t arg1, arg2;
|
uint16_t arg1, arg2;
|
||||||
arg1 = fcHigh << 8 | fcLow;
|
arg1 = fcHigh << 8 | fcLow;
|
||||||
arg2 = invert << 8 | clk;
|
arg2 = invert << 8 | clk;
|
||||||
size_t size = DemodBufferLen;
|
size_t size = DemodBufferLen;
|
||||||
if (size > USB_CMD_DATA_SIZE) {
|
if (size > USB_CMD_DATA_SIZE) {
|
||||||
PrintAndLog("DemodBuffer too long for current implementation - length: %d - max: %d", size, USB_CMD_DATA_SIZE);
|
PrintAndLog("DemodBuffer too long for current implementation - length: %d - max: %d", size, USB_CMD_DATA_SIZE);
|
||||||
size = USB_CMD_DATA_SIZE;
|
size = USB_CMD_DATA_SIZE;
|
||||||
}
|
}
|
||||||
UsbCommand c = {CMD_FSK_SIM_TAG, {arg1, arg2, size}};
|
UsbCommand c = {CMD_FSK_SIM_TAG, {arg1, arg2, size}};
|
||||||
|
|
||||||
memcpy(c.d.asBytes, DemodBuffer, size);
|
memcpy(c.d.asBytes, DemodBuffer, size);
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// by marshmellow - sim ask data given clock, invert, manchester or raw, separator
|
// by marshmellow - sim ask data given clock, invert, manchester or raw, separator
|
||||||
// - allow pull data from DemodBuffer
|
// - allow pull data from DemodBuffer
|
||||||
int CmdLFaskSim(const char *Cmd)
|
int CmdLFaskSim(const char *Cmd)
|
||||||
{
|
{
|
||||||
//autodetect clock from Graphbuffer if using demod buffer
|
// autodetect clock from Graphbuffer if using demod buffer
|
||||||
// needs 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, clk=0, invert=0;
|
uint8_t encoding = 1, separator = 0, clk = 0, invert = 0;
|
||||||
bool errors = FALSE;
|
bool errors = FALSE;
|
||||||
char hexData[32] = {0x00};
|
char hexData[32] = {0x00};
|
||||||
uint8_t data[255]= {0x00}; // store entered hex data
|
uint8_t data[255]= {0x00}; // store entered hex data
|
||||||
|
@ -760,35 +758,35 @@ int CmdLFaskSim(const char *Cmd)
|
||||||
cmdp++;
|
cmdp++;
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
errors |= param_getdec(Cmd,cmdp+1,&clk);
|
errors |= param_getdec(Cmd, cmdp+1, &clk);
|
||||||
cmdp+=2;
|
cmdp += 2;
|
||||||
break;
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
encoding=2; //biphase
|
encoding = 2; //biphase
|
||||||
cmdp++;
|
cmdp++;
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
encoding=1;
|
encoding = 1; //manchester
|
||||||
cmdp++;
|
cmdp++;
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
encoding=0;
|
encoding = 0; //raw
|
||||||
cmdp++;
|
cmdp++;
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
separator=1;
|
separator = 1;
|
||||||
cmdp++;
|
cmdp++;
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
dataLen = param_getstr(Cmd, cmdp+1, hexData);
|
dataLen = param_getstr(Cmd, cmdp+1, hexData);
|
||||||
if (dataLen==0)
|
if (dataLen == 0)
|
||||||
errors = TRUE;
|
errors = TRUE;
|
||||||
else
|
else
|
||||||
dataLen = hextobinarray((char *)data, hexData);
|
dataLen = hextobinarray((char *)data, hexData);
|
||||||
|
|
||||||
if (dataLen==0) errors = TRUE;
|
if (dataLen == 0) errors = TRUE;
|
||||||
if (errors) PrintAndLog ("Error getting hex data, datalen: %d", dataLen);
|
if (errors) PrintAndLog ("Error getting hex data, datalen: %d", dataLen);
|
||||||
cmdp+=2;
|
cmdp += 2;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||||
|
@ -798,8 +796,9 @@ int CmdLFaskSim(const char *Cmd)
|
||||||
if(errors) break;
|
if(errors) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// No args
|
||||||
if(cmdp == 0 && DemodBufferLen == 0)
|
if(cmdp == 0 && DemodBufferLen == 0)
|
||||||
errors = TRUE;// No args
|
errors = TRUE;
|
||||||
|
|
||||||
//Validations
|
//Validations
|
||||||
if(errors) return usage_lf_simask();
|
if(errors) return usage_lf_simask();
|
||||||
|
@ -1050,75 +1049,69 @@ int CmdLFfind(const char *Cmd) {
|
||||||
|
|
||||||
ans=CmdFSKdemodIO("");
|
ans=CmdFSKdemodIO("");
|
||||||
if (ans>0) {
|
if (ans>0) {
|
||||||
PrintAndLog("\nValid IO Prox ID Found!");
|
PrintAndLog("\nValid IO Prox ID Found!");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ans=CmdFSKdemodPyramid("");
|
ans=CmdFSKdemodPyramid("");
|
||||||
if (ans>0) {
|
if (ans>0) {
|
||||||
PrintAndLog("\nValid Pyramid ID Found!");
|
PrintAndLog("\nValid Pyramid ID Found!");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ans=CmdFSKdemodParadox("");
|
ans=CmdFSKdemodParadox("");
|
||||||
if (ans>0) {
|
if (ans>0) {
|
||||||
PrintAndLog("\nValid Paradox ID Found!");
|
PrintAndLog("\nValid Paradox ID Found!");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ans=CmdFSKdemodAWID("");
|
ans=CmdFSKdemodAWID("");
|
||||||
if (ans>0) {
|
if (ans>0) {
|
||||||
PrintAndLog("\nValid AWID ID Found!");
|
PrintAndLog("\nValid AWID ID Found!");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ans=CmdFSKdemodHID("");
|
ans=CmdFSKdemodHID("");
|
||||||
if (ans>0) {
|
if (ans>0) {
|
||||||
PrintAndLog("\nValid HID Prox ID Found!");
|
PrintAndLog("\nValid HID Prox ID Found!");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ans=CmdAskEM410xDemod("");
|
ans=CmdAskEM410xDemod("");
|
||||||
if (ans>0) {
|
if (ans>0) {
|
||||||
PrintAndLog("\nValid EM410x ID Found!");
|
PrintAndLog("\nValid EM410x ID Found!");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ans=CmdG_Prox_II_Demod("");
|
ans=CmdG_Prox_II_Demod("");
|
||||||
if (ans>0) {
|
if (ans>0) {
|
||||||
PrintAndLog("\nValid Guardall G-Prox II ID Found!");
|
PrintAndLog("\nValid Guardall G-Prox II ID Found!");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ans=CmdFDXBdemodBI("");
|
ans=CmdFDXBdemodBI("");
|
||||||
if (ans>0) {
|
if (ans>0) {
|
||||||
PrintAndLog("\nValid FDX-B ID Found!");
|
PrintAndLog("\nValid FDX-B ID Found!");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ans=EM4x50Read("", false);
|
ans=EM4x50Read("", false);
|
||||||
if (ans>0) {
|
if (ans>0) {
|
||||||
PrintAndLog("\nValid EM4x50 ID Found!");
|
PrintAndLog("\nValid EM4x50 ID Found!");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ans=CmdVikingDemod("");
|
ans=CmdVikingDemod("");
|
||||||
if (ans>0) {
|
if (ans>0) {
|
||||||
PrintAndLog("\nValid Viking ID Found!");
|
PrintAndLog("\nValid Viking ID Found!");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ans=CmdIndalaDecode("");
|
ans=CmdIndalaDecode("");
|
||||||
if (ans>0) {
|
if (ans>0) {
|
||||||
PrintAndLog("\nValid Indala ID Found!");
|
PrintAndLog("\nValid Indala ID Found!");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ans=CmdPSKNexWatch("");
|
ans=CmdPSKNexWatch("");
|
||||||
if (ans>0) {
|
if (ans>0) {
|
||||||
PrintAndLog("\nValid NexWatch ID Found!");
|
PrintAndLog("\nValid NexWatch ID Found!");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
ans=CmdJablotronDemod("");
|
||||||
|
if (ans>0) {
|
||||||
|
PrintAndLog("\nValid Jablotron ID Found!");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
ans=CmdLFNedapDemod("");
|
ans=CmdLFNedapDemod("");
|
||||||
if (ans>0) {
|
if (ans>0) {
|
||||||
PrintAndLog("\nValid NEDAP ID Found!");
|
PrintAndLog("\nValid NEDAP ID Found!");
|
||||||
|
@ -1197,6 +1190,7 @@ static command_t CommandTable[] =
|
||||||
{"hid", CmdLFHID, 1, "{ HID RFIDs... }"},
|
{"hid", CmdLFHID, 1, "{ HID RFIDs... }"},
|
||||||
{"hitag", CmdLFHitag, 1, "{ HITAG RFIDs... }"},
|
{"hitag", CmdLFHitag, 1, "{ HITAG RFIDs... }"},
|
||||||
{"io", CmdLFIO, 1, "{ IOPROX RFIDs... }"},
|
{"io", CmdLFIO, 1, "{ IOPROX RFIDs... }"},
|
||||||
|
{"jablotron", CmdLFJablotron, 1, "{ JABLOTRON RFIDs... }"},
|
||||||
{"nedap", CmdLFNedap, 1, "{ NEDAP RFIDs... }"},
|
{"nedap", CmdLFNedap, 1, "{ NEDAP RFIDs... }"},
|
||||||
{"pcf7931", CmdLFPCF7931, 1, "{ PCF7931 RFIDs... }"},
|
{"pcf7931", CmdLFPCF7931, 1, "{ PCF7931 RFIDs... }"},
|
||||||
{"presco", CmdLFPresco, 1, "{ Presco RFIDs... }"},
|
{"presco", CmdLFPresco, 1, "{ Presco RFIDs... }"},
|
||||||
|
|
|
@ -17,26 +17,27 @@
|
||||||
#include "proxmark3.h"
|
#include "proxmark3.h"
|
||||||
#include "lfdemod.h"
|
#include "lfdemod.h"
|
||||||
|
|
||||||
#include "util.h" // for parsing cli command utils
|
#include "util.h" // for parsing cli command utils
|
||||||
#include "ui.h" // for show graph controls
|
#include "ui.h" // for show graph controls
|
||||||
#include "graph.h" // for graph data
|
#include "graph.h" // for graph data
|
||||||
#include "cmdparser.h" // for getting cli commands included in cmdmain.h
|
#include "cmdparser.h" // for getting cli commands included in cmdmain.h
|
||||||
#include "cmdmain.h" // for sending cmds to device
|
#include "cmdmain.h" // for sending cmds to device
|
||||||
#include "data.h" // for GetFromBigBuf
|
#include "data.h" // for GetFromBigBuf
|
||||||
#include "cmddata.h" // for `lf search`
|
#include "cmddata.h" // for `lf search`
|
||||||
#include "cmdlfawid.h" // for awid menu
|
#include "cmdlfawid.h" // for awid menu
|
||||||
#include "cmdlfem4x.h" // for em4x menu
|
#include "cmdlfem4x.h" // for em4x menu
|
||||||
#include "cmdlfhid.h" // for hid menu
|
#include "cmdlfhid.h" // for hid menu
|
||||||
#include "cmdlfhitag.h" // for hitag menu
|
#include "cmdlfhitag.h" // for hitag menu
|
||||||
#include "cmdlfio.h" // for ioprox menu
|
#include "cmdlfio.h" // for ioprox menu
|
||||||
#include "cmdlft55xx.h" // for t55xx menu
|
#include "cmdlft55xx.h" // for t55xx menu
|
||||||
#include "cmdlfti.h" // for ti menu
|
#include "cmdlfti.h" // for ti menu
|
||||||
#include "cmdlfpresco.h" // for presco menu
|
#include "cmdlfpresco.h" // for presco menu
|
||||||
#include "cmdlfpcf7931.h"// for pcf7931 menu
|
#include "cmdlfpcf7931.h" // for pcf7931 menu
|
||||||
#include "cmdlfpyramid.h"// for pyramid menu
|
#include "cmdlfpyramid.h" // for pyramid menu
|
||||||
#include "cmdlfviking.h" // for viking menu
|
#include "cmdlfviking.h" // for viking menu
|
||||||
#include "cmdlfguard.h" // for GuardAll menu
|
#include "cmdlfguard.h" // for GuardAll menu
|
||||||
#include "cmdlfnedap.h" // for NEDAP menu
|
#include "cmdlfnedap.h" // for NEDAP menu
|
||||||
|
#include "cmdlfjablotron.h" // for JABLOTRON menu
|
||||||
|
|
||||||
int CmdLF(const char *Cmd);
|
int CmdLF(const char *Cmd);
|
||||||
|
|
||||||
|
|
206
client/cmdlfjablotron.c
Normal file
206
client/cmdlfjablotron.c
Normal file
|
@ -0,0 +1,206 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||||
|
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||||
|
// the license.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Low frequency Presco tag commands
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
#include "cmdlfjablotron.h"
|
||||||
|
|
||||||
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
|
int usage_lf_jablotron_clone(void){
|
||||||
|
PrintAndLog("clone a Jablotron tag to a T55x7 tag.");
|
||||||
|
PrintAndLog("Usage: lf jablotron clone d <Card-ID> <Q5>");
|
||||||
|
PrintAndLog("Options :");
|
||||||
|
PrintAndLog(" d <Card-ID> : jablotron card ID");
|
||||||
|
PrintAndLog(" <Q5> : specify write to Q5 (t5555 instead of t55x7)");
|
||||||
|
PrintAndLog("");
|
||||||
|
PrintAndLog("Sample : lf jablotron clone d 123456789");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int usage_lf_jablotron_sim(void) {
|
||||||
|
PrintAndLog("Enables simulation of jablotron card with specified card number.");
|
||||||
|
PrintAndLog("Simulation runs until the button is pressed or another USB command is issued.");
|
||||||
|
PrintAndLog("Per jablotron format, the card number is 9 digit number and can contain *# chars. Larger values are truncated.");
|
||||||
|
PrintAndLog("");
|
||||||
|
PrintAndLog("Usage: lf jablotron sim d <Card-ID> or H <hex-ID>");
|
||||||
|
PrintAndLog("Options :");
|
||||||
|
PrintAndLog(" d <Card-ID> : jablotron card number");
|
||||||
|
// PrintAndLog(" H <hex-ID> : 8 digit hex card number");
|
||||||
|
PrintAndLog("");
|
||||||
|
PrintAndLog("Sample : lf jablotron sim d 123456789");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getJablotronBits(uint64_t fullcode, uint8_t *bits) {
|
||||||
|
//preamp
|
||||||
|
num_to_bytebits(0xFFFF, 16, bits);
|
||||||
|
|
||||||
|
//fullcode
|
||||||
|
num_to_bytebits(fullcode, 40, bits+16);
|
||||||
|
|
||||||
|
//chksum byte
|
||||||
|
uint8_t crc = 0;
|
||||||
|
for (int i=16; i < 56; i += 8) {
|
||||||
|
crc += bytebits_to_byte(bits+i,8);
|
||||||
|
}
|
||||||
|
crc ^= 0x3A;
|
||||||
|
num_to_bytebits(crc, 8, bits+56);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//see ASKDemod for what args are accepted
|
||||||
|
int CmdJablotronDemod(const char *Cmd) {
|
||||||
|
|
||||||
|
//Differential Biphase / di-phase (inverted biphase)
|
||||||
|
//get binary from ask wave
|
||||||
|
if (!ASKbiphaseDemod("0 64 1 0", FALSE)) {
|
||||||
|
if (g_debugMode) PrintAndLog("Error Jablotron: ASKbiphaseDemod failed");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
size_t size = DemodBufferLen;
|
||||||
|
int ans = JablotronDemod(DemodBuffer, &size);
|
||||||
|
if (ans < 0){
|
||||||
|
if (g_debugMode){
|
||||||
|
// if (ans == -5)
|
||||||
|
// PrintAndLog("DEBUG: Error - not enough samples");
|
||||||
|
// else if (ans == -1)
|
||||||
|
// PrintAndLog("DEBUG: Error - only noise found");
|
||||||
|
// else if (ans == -2)
|
||||||
|
// PrintAndLog("DEBUG: Error - problem during ASK/Biphase demod");
|
||||||
|
if (ans == -3)
|
||||||
|
PrintAndLog("DEBUG: Error - Size not correct: %d", size);
|
||||||
|
else if (ans == -4)
|
||||||
|
PrintAndLog("DEBUG: Error - Jablotron preamble not found");
|
||||||
|
else
|
||||||
|
PrintAndLog("DEBUG: Error - ans: %d", ans);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//got a good demod
|
||||||
|
uint32_t raw1 = bytebits_to_byte(DemodBuffer+ans, 32);
|
||||||
|
uint32_t raw2 = bytebits_to_byte(DemodBuffer+ans+32, 32);
|
||||||
|
uint64_t cardid = (raw1 & 0x0000FFFF);
|
||||||
|
cardid <<= 32;
|
||||||
|
cardid |= (raw2 >> 8);
|
||||||
|
|
||||||
|
PrintAndLog("Jablotron Tag Found: Card ID %12X", cardid);
|
||||||
|
PrintAndLog("Raw: %08X%08X", raw1 ,raw2);
|
||||||
|
|
||||||
|
setDemodBuf(DemodBuffer+ans, 64, 0);
|
||||||
|
|
||||||
|
//PrintAndLog("1410-%u-%u-%08X-%02X", fullcode);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CmdJablotronRead(const char *Cmd) {
|
||||||
|
// read lf silently
|
||||||
|
CmdLFRead("s");
|
||||||
|
// get samples silently
|
||||||
|
getSamples("30000",false);
|
||||||
|
// demod and output Presco ID
|
||||||
|
return CmdJablotronDemod(Cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CmdJablotronClone(const char *Cmd) {
|
||||||
|
|
||||||
|
uint64_t fullcode = 0;
|
||||||
|
uint32_t blocks[3] = {T55x7_MODULATION_DIPHASE | T55x7_BITRATE_RF_64 | 2<<T55x7_MAXBLOCK_SHIFT, 0, 0};
|
||||||
|
|
||||||
|
uint8_t bits[64];
|
||||||
|
uint8_t *bs = bits;
|
||||||
|
memset(bs, 0, sizeof(bits));
|
||||||
|
|
||||||
|
char cmdp = param_getchar(Cmd, 0);
|
||||||
|
if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_jablotron_clone();
|
||||||
|
|
||||||
|
fullcode = param_get64ex(Cmd, 1, 0, 16);
|
||||||
|
|
||||||
|
//Q5
|
||||||
|
if (param_getchar(Cmd, 2) == 'Q' || param_getchar(Cmd, 2) == 'q') {
|
||||||
|
//t5555 (Q5) BITRATE = (RF-2)/2 (iceman)
|
||||||
|
blocks[0] = T5555_MODULATION_BIPHASE | T5555_INVERT_OUTPUT | 64<<T5555_BITRATE_SHIFT | 2<<T5555_MAXBLOCK_SHIFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((fullcode & 0xFFFFFFFFFFFF) != fullcode) {
|
||||||
|
fullcode &= 0xFFFFFFFFFFFF;
|
||||||
|
PrintAndLog("Card Number Truncated to 40-bits: %u", fullcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !getJablotronBits(fullcode, bs)) {
|
||||||
|
PrintAndLog("Error with tag bitstream generation.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
blocks[1] = bytebits_to_byte(bs,32);
|
||||||
|
blocks[2] = bytebits_to_byte(bs+32,32);
|
||||||
|
|
||||||
|
PrintAndLog("Preparing to clone Jablotron to T55x7 with FullCode: %12X", fullcode);
|
||||||
|
PrintAndLog("Blk | Data ");
|
||||||
|
PrintAndLog("----+------------");
|
||||||
|
PrintAndLog(" 00 | 0x%08x", blocks[0]);
|
||||||
|
PrintAndLog(" 01 | 0x%08x", blocks[1]);
|
||||||
|
PrintAndLog(" 02 | 0x%08x", blocks[2]);
|
||||||
|
|
||||||
|
UsbCommand resp;
|
||||||
|
UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {0,0,0}};
|
||||||
|
|
||||||
|
for (int i=4; i>=0; i--) {
|
||||||
|
c.arg[0] = blocks[i];
|
||||||
|
c.arg[1] = i;
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommand(&c);
|
||||||
|
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)){
|
||||||
|
PrintAndLog("Error occurred, device did not respond during write operation.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CmdJablotronSim(const char *Cmd) {
|
||||||
|
uint64_t fullcode = 0;
|
||||||
|
|
||||||
|
char cmdp = param_getchar(Cmd, 0);
|
||||||
|
if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_jablotron_sim();
|
||||||
|
|
||||||
|
fullcode = param_get64ex(Cmd, 1, 0, 16);
|
||||||
|
|
||||||
|
uint8_t clk = 64, encoding = 2, separator = 0, invert = 1;
|
||||||
|
uint16_t arg1, arg2;
|
||||||
|
size_t size = 64;
|
||||||
|
arg1 = clk << 8 | encoding;
|
||||||
|
arg2 = invert << 8 | separator;
|
||||||
|
|
||||||
|
PrintAndLog("Simulating Jablotron - FullCode: %12X", fullcode);
|
||||||
|
|
||||||
|
UsbCommand c = {CMD_ASK_SIM_TAG, {arg1, arg2, size}};
|
||||||
|
getJablotronBits(fullcode, c.d.asBytes);
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommand(&c);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static command_t CommandTable[] = {
|
||||||
|
{"help", CmdHelp, 1, "This help"},
|
||||||
|
{"read", CmdJablotronRead, 0, "Attempt to read and Extract tag data"},
|
||||||
|
{"clone", CmdJablotronClone, 0, "h <hex> [Q5] clone jablotron tag"},
|
||||||
|
{"sim", CmdJablotronSim, 0, "h <hex> simulate jablotron tag"},
|
||||||
|
{NULL, NULL, 0, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
int CmdLFJablotron(const char *Cmd) {
|
||||||
|
clearCommandBuffer();
|
||||||
|
CmdsParse(CommandTable, Cmd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CmdHelp(const char *Cmd) {
|
||||||
|
CmdsHelp(CommandTable);
|
||||||
|
return 0;
|
||||||
|
}
|
36
client/cmdlfjablotron.h
Normal file
36
client/cmdlfjablotron.h
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||||
|
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||||
|
// the license.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Low frequency T55xx commands
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
#ifndef CMDLFJABLOTRON_H__
|
||||||
|
#define CMDLFJABLOTRON_H__
|
||||||
|
#include <string.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include "proxmark3.h"
|
||||||
|
#include "ui.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "graph.h"
|
||||||
|
#include "cmdparser.h"
|
||||||
|
#include "cmddata.h"
|
||||||
|
#include "cmdmain.h"
|
||||||
|
#include "cmdlf.h"
|
||||||
|
#include "protocols.h" // for T55xx config register definitions
|
||||||
|
#include "lfdemod.h" // parityTest
|
||||||
|
int CmdLFJablotron(const char *Cmd);
|
||||||
|
int CmdJablotronClone(const char *Cmd);
|
||||||
|
int CmdJablotronSim(const char *Cmd);
|
||||||
|
int CmdJablotronRead(const char *Cmd);
|
||||||
|
int CmdJablotronDemod(const char *Cmd);
|
||||||
|
|
||||||
|
int getJablotronBits(uint64_t fullcode, uint8_t *bits);
|
||||||
|
|
||||||
|
int usage_lf_jablotron_clone(void);
|
||||||
|
int usage_lf_jablotron_sim(void);
|
||||||
|
int usage_lf_jablotron_read(void);
|
||||||
|
int usage_lf_jablotron_demod(void);
|
||||||
|
#endif
|
||||||
|
|
|
@ -82,16 +82,11 @@ int GetNedapBits(uint32_t cn, uint8_t *nedapBits) {
|
||||||
|
|
||||||
int CmdLFNedapDemod(const char *Cmd) {
|
int CmdLFNedapDemod(const char *Cmd) {
|
||||||
//raw ask demod no start bit finding just get binary from wave
|
//raw ask demod no start bit finding just get binary from wave
|
||||||
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
|
|
||||||
size_t size = getFromGraphBuf(BitStream);
|
|
||||||
if (size==0) return 0;
|
|
||||||
|
|
||||||
//get binary from ask wave
|
|
||||||
if (!ASKbiphaseDemod("0 64 0 0", FALSE)) {
|
if (!ASKbiphaseDemod("0 64 0 0", FALSE)) {
|
||||||
if (g_debugMode) PrintAndLog("Error NEDAP: ASKbiphaseDemod failed");
|
if (g_debugMode) PrintAndLog("Error NEDAP: ASKbiphaseDemod failed");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
size = DemodBufferLen;
|
size_t size = DemodBufferLen;
|
||||||
int idx = NedapDemod(DemodBuffer, &size);
|
int idx = NedapDemod(DemodBuffer, &size);
|
||||||
if (idx < 0){
|
if (idx < 0){
|
||||||
if (g_debugMode){
|
if (g_debugMode){
|
||||||
|
@ -143,13 +138,13 @@ int CmdLFNedapDemod(const char *Cmd) {
|
||||||
uint8_t firstParity = GetParity( DemodBuffer, EVEN, 63);
|
uint8_t firstParity = GetParity( DemodBuffer, EVEN, 63);
|
||||||
if ( firstParity != DemodBuffer[63] ) {
|
if ( firstParity != DemodBuffer[63] ) {
|
||||||
PrintAndLog("1st 64bit parity check failed: %d|%d ", DemodBuffer[63], firstParity);
|
PrintAndLog("1st 64bit parity check failed: %d|%d ", DemodBuffer[63], firstParity);
|
||||||
//return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t secondParity = GetParity( DemodBuffer+64, EVEN, 63);
|
uint8_t secondParity = GetParity( DemodBuffer+64, EVEN, 63);
|
||||||
if ( secondParity != DemodBuffer[127] ) {
|
if ( secondParity != DemodBuffer[127] ) {
|
||||||
PrintAndLog("2st 64bit parity check failed: %d|%d ", DemodBuffer[127], secondParity);
|
PrintAndLog("2st 64bit parity check failed: %d|%d ", DemodBuffer[127], secondParity);
|
||||||
//return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ok valid card found!
|
// ok valid card found!
|
||||||
|
|
11
common/crc.c
11
common/crc.c
|
@ -94,17 +94,6 @@ uint32_t CRC8Legic(uint8_t *buff, size_t size) {
|
||||||
return reflect(crc_finish(&crc), 8);
|
return reflect(crc_finish(&crc), 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
// credits to marshmellow
|
|
||||||
// width=8 poly=0xA3, reversed poly=0x8B, init=0xB0 refin=true refout=true xorout=0x00 check=0x28 name="CRC-8/JA"
|
|
||||||
uint32_t CRC8ja(uint8_t *buff, size_t size) {
|
|
||||||
crc_t crc;
|
|
||||||
crc_init_ref(&crc, 8, 0xA3, 0x42, 0x00, TRUE, TRUE);
|
|
||||||
for ( int i=0; i < size; ++i)
|
|
||||||
crc_update(&crc, buff[i], 8);
|
|
||||||
return crc_finish(&crc);
|
|
||||||
//return reflect(crc_finish(&crc), 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This CRC-16 is used in Legic Advant systems.
|
// This CRC-16 is used in Legic Advant systems.
|
||||||
// width=8 poly=0xB400, reversed poly=0x init=depends refin=true refout=true xorout=0x0000 check= name="CRC-16/LEGIC"
|
// width=8 poly=0xB400, reversed poly=0x init=depends refin=true refout=true xorout=0x0000 check= name="CRC-16/LEGIC"
|
||||||
uint32_t CRC16Legic(uint8_t *buff, size_t size, uint8_t uidcrc) {
|
uint32_t CRC16Legic(uint8_t *buff, size_t size, uint8_t uidcrc) {
|
||||||
|
|
|
@ -65,9 +65,6 @@ uint32_t CRC8Legic(uint8_t *buff, size_t size);
|
||||||
// ie: uidcrc = 0x78 then initial_value == 0x7878
|
// ie: uidcrc = 0x78 then initial_value == 0x7878
|
||||||
uint32_t CRC16Legic(uint8_t *buff, size_t size, uint8_t uidcrc);
|
uint32_t CRC16Legic(uint8_t *buff, size_t size, uint8_t uidcrc);
|
||||||
|
|
||||||
// Calculate CRC-8/ja checksum
|
|
||||||
uint32_t CRC8ja(uint8_t *buff, size_t size);
|
|
||||||
|
|
||||||
// test crc 16.
|
// test crc 16.
|
||||||
uint32_t CRC16_DNP(uint8_t *buff, size_t size);
|
uint32_t CRC16_DNP(uint8_t *buff, size_t size);
|
||||||
uint32_t CRC16_CCITT(uint8_t *buff, size_t size);
|
uint32_t CRC16_CCITT(uint8_t *buff, size_t size);
|
||||||
|
|
|
@ -723,6 +723,33 @@ int FDXBdemodBI(uint8_t *dest, size_t *size)
|
||||||
return (int)startIdx;
|
return (int)startIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ASK/Diphase fc/64 (inverted Biphase)
|
||||||
|
// Note: this i s not a demod, this is only a detection
|
||||||
|
// the parameter *dest needs to be demoded before call
|
||||||
|
int JablotronDemod(uint8_t *dest, size_t *size){
|
||||||
|
//make sure buffer has enough data
|
||||||
|
if (*size < 64) return -1;
|
||||||
|
|
||||||
|
size_t startIdx = 0;
|
||||||
|
// 0xFFFF preamble, 64bits
|
||||||
|
uint8_t preamble[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
|
||||||
|
|
||||||
|
uint8_t errChk = preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx);
|
||||||
|
if (errChk == 0) return -4; //preamble not found
|
||||||
|
|
||||||
|
uint8_t checkCalc = 0;
|
||||||
|
for (int i=16; i < 56; i += 8) {
|
||||||
|
checkCalc += bytebits_to_byte(dest+startIdx+i,8);
|
||||||
|
}
|
||||||
|
checkCalc ^= 0x3A;
|
||||||
|
|
||||||
|
uint8_t crc = bytebits_to_byte(dest+startIdx+56,8);
|
||||||
|
|
||||||
|
if ( checkCalc != crc ) return -5;
|
||||||
|
if (*size != 64) return -6;
|
||||||
|
return (int)startIdx;
|
||||||
|
}
|
||||||
|
|
||||||
// by marshmellow
|
// by marshmellow
|
||||||
// FSK Demod then try to locate an AWID ID
|
// FSK Demod then try to locate an AWID ID
|
||||||
int AWIDdemodFSK(uint8_t *dest, size_t *size)
|
int AWIDdemodFSK(uint8_t *dest, size_t *size)
|
||||||
|
|
|
@ -56,4 +56,5 @@ int PyramiddemodFSK(uint8_t *dest, size_t *size);
|
||||||
int VikingDemod_AM(uint8_t *dest, size_t *size);
|
int VikingDemod_AM(uint8_t *dest, size_t *size);
|
||||||
int PrescoDemod(uint8_t *dest, size_t *size);
|
int PrescoDemod(uint8_t *dest, size_t *size);
|
||||||
int NedapDemod(uint8_t *dest, size_t *size);
|
int NedapDemod(uint8_t *dest, size_t *size);
|
||||||
|
int JablotronDemod(uint8_t *dest, size_t *size);
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue