Conflicts:
	armsrc/lfops.c
	client/cmddata.c
	common/crc.c
	common/crc.h
	common/lfdemod.c
	include/crc.h
	include/crc.h.old
This commit is contained in:
iceman1001 2015-03-16 13:13:18 +01:00
commit 05446d5bc3
9 changed files with 316 additions and 233 deletions

View file

@ -620,7 +620,7 @@ static void askSimBit(uint8_t c, int *n, uint8_t clock, uint8_t manchester)
uint8_t *dest = BigBuf_get_addr();
uint8_t halfClk = clock/2;
// c = current bit 1 or 0
if (manchester){
if (manchester==1){
memset(dest+(*n), c, halfClk);
memset(dest+(*n) + halfClk, c^1, halfClk);
} else {
@ -629,26 +629,54 @@ static void askSimBit(uint8_t c, int *n, uint8_t clock, uint8_t manchester)
*n += clock;
}
static void biphaseSimBit(uint8_t c, int *n, uint8_t clock, uint8_t *phase)
{
uint8_t *dest = BigBuf_get_addr();
uint8_t halfClk = clock/2;
if (c){
memset(dest+(*n), c ^ 1 ^ *phase, halfClk);
memset(dest+(*n) + halfClk, c ^ *phase, halfClk);
} else {
memset(dest+(*n), c ^ *phase, clock);
*phase ^= 1;
}
}
// args clock, ask/man or askraw, invert, transmission separator
void CmdASKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream)
{
int ledcontrol = 1;
int n=0, i=0;
uint8_t clk = (arg1 >> 8) & 0xFF;
uint8_t manchester = arg1 & 1;
uint8_t encoding = arg1 & 1;
uint8_t separator = arg2 & 1;
uint8_t invert = (arg2 >> 8) & 1;
if (encoding==2){ //biphase
uint8_t phase=0;
for (i=0; i<size; i++){
askSimBit(BitStream[i]^invert, &n, clk, manchester);
biphaseSimBit(BitStream[i]^invert, &n, clk, &phase);
}
if (manchester==0 && BitStream[0]==BitStream[size-1]){ //run a second set inverted (for biphase phase)
if (BitStream[0]==BitStream[size-1]){ //run a second set inverted to keep phase in check
for (i=0; i<size; i++){
askSimBit(BitStream[i]^invert^1, &n, clk, manchester);
biphaseSimBit(BitStream[i]^invert, &n, clk, &phase);
}
}
} else { // ask/manchester || ask/raw
for (i=0; i<size; i++){
askSimBit(BitStream[i]^invert, &n, clk, encoding);
}
if (encoding==0 && BitStream[0]==BitStream[size-1]){ //run a second set inverted (for biphase phase)
for (i=0; i<size; i++){
askSimBit(BitStream[i]^invert^1, &n, clk, encoding);
}
}
}
if (separator==1) Dbprintf("sorry but separator option not yet available");
Dbprintf("Simulating with clk: %d, invert: %d, manchester: %d, separator: %d, n: %d",clk, invert, manchester, separator, n);
Dbprintf("Simulating with clk: %d, invert: %d, encoding: %d, separator: %d, n: %d",clk, invert, encoding, separator, n);
//DEBUG
//Dbprintf("First 32:");
//uint8_t *dest = BigBuf_get_addr();
@ -817,6 +845,7 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
size_t size=0, idx=0;
int clk=0, invert=0, errCnt=0, maxErr=20;
uint32_t hi=0;
uint64_t lo=0;
// Configure to go in 125Khz listen mode
LFSetupFPGAForADC(95, true);
@ -835,9 +864,18 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
WDT_HIT();
if (errCnt>=0){
lo = Em410xDecode(dest, &size, &idx);
errCnt = Em410xDecode(dest, &size, &idx, &hi, &lo);
//Dbprintf("DEBUG: EM GOT");
if (lo>0){
if (errCnt){
if (size>64){
Dbprintf("EM XL TAG ID: %06x%08x%08x - (%05d_%03d_%08d)",
hi,
(uint32_t)(lo>>32),
(uint32_t)lo,
(uint32_t)(lo&0xFFFF),
(uint32_t)((lo>>16LL) & 0xFF),
(uint32_t)(lo & 0xFFFFFF));
} else {
Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)",
(uint32_t)(lo>>32),
(uint32_t)lo,
@ -845,6 +883,7 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
(uint32_t)((lo>>16LL) & 0xFF),
(uint32_t)(lo & 0xFFFFFF));
}
}
if (findone){
if (ledcontrol) LED_A_OFF();
*high=lo>>32;

View file

@ -22,6 +22,7 @@
#include "cmddata.h"
#include "lfdemod.h"
#include "usb_cmd.h"
#include "crc.h"
uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
uint8_t g_debugMode;
@ -265,9 +266,9 @@ void printBitStream(uint8_t BitStream[], uint32_t bitLen)
}
//by marshmellow
//print 64 bit EM410x ID in multiple formats
void printEM410x(uint64_t id)
void printEM410x(uint32_t hi, uint64_t id)
{
if (id !=0){
if (id || hi){
uint64_t iii=1;
uint64_t id2lo=0;
uint32_t ii=0;
@ -277,7 +278,11 @@ void printEM410x(uint64_t id)
id2lo=(id2lo<<1LL) | ((id & (iii << (i+((ii-1)*8)))) >> (i+((ii-1)*8)));
}
}
//output em id
if (hi){
//output 88 bit em id
PrintAndLog("EM TAG ID : %06x%016llx", hi, id);
} else{
//output 40 bit em id
PrintAndLog("EM TAG ID : %010llx", id);
PrintAndLog("Unique TAG ID: %010llx", id2lo);
PrintAndLog("DEZ 8 : %08lld",id & 0xFFFFFF);
@ -286,7 +291,8 @@ void printEM410x(uint64_t id)
PrintAndLog("DEZ 3.5A : %03lld.%05lld",(id>>32ll),(id & 0xFFFF));
PrintAndLog("DEZ 14/IK2 : %014lld",id);
PrintAndLog("DEZ 15/IK3 : %015lld",id2lo);
PrintAndLog("Other : %05lld_%03lld_%08lld",(id&0xFFFF),((id>>16LL) & 0xFF),(id & 0xFFFFFF));
PrintAndLog("Other : %05lld_%03lld_%08lld",(id&0xFFFF),((id>>16LL) & 0xFF),(id & 0xFFFFFF));
}
}
return;
}
@ -297,9 +303,6 @@ void printEM410x(uint64_t id)
//prints binary found and saves in graphbuffer for further commands
int CmdAskEM410xDemod(const char *Cmd)
{
int invert=0;
int clk=0;
int maxErr=100;
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: data askem410xdemod [clock] <0|1> [maxError]");
@ -312,50 +315,21 @@ int CmdAskEM410xDemod(const char *Cmd)
PrintAndLog(" : data askem410xdemod 32 1 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/32 and inverting data");
PrintAndLog(" : data askem410xdemod 1 = demod an EM410x Tag ID from GraphBuffer while inverting data");
PrintAndLog(" : data askem410xdemod 64 1 0 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/64 and inverting data and allowing 0 demod errors");
return 0;
}
int ans = ASKmanDemod(Cmd, FALSE, FALSE);
if (!ans) return 0;
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr);
if (invert != 0 && invert != 1) {
PrintAndLog("Invalid argument: %s", Cmd);
return 0;
}
size_t BitLen = getFromGraphBuf(BitStream);
if (g_debugMode==1) PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen);
if (BitLen==0) return 0;
int errCnt=0;
errCnt = askmandemod(BitStream, &BitLen, &clk, &invert, maxErr);
if (errCnt<0||BitLen<16){ //if fatal error (or -1)
if (g_debugMode==1) PrintAndLog("no data found %d, errors:%d, bitlen:%d, clock:%d",errCnt,invert,BitLen,clk);
return 0;
}
PrintAndLog("\nUsing Clock: %d - Invert: %d - Bits Found: %d",clk,invert,BitLen);
//output
if (errCnt>0){
PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
}
//PrintAndLog("ASK/Manchester decoded bitstream:");
// Now output the bitstream to the scrollback by line of 16 bits
setDemodBuf(BitStream,BitLen,0);
//printDemodBuff();
uint64_t lo =0;
uint32_t hi =0;
size_t idx=0;
lo = Em410xDecode(BitStream, &BitLen, &idx);
if (lo>0){
//set GraphBuffer for clone or sim command
setDemodBuf(BitStream, BitLen, idx);
if (Em410xDecode(DemodBuffer,(size_t *) &DemodBufferLen, &idx, &hi, &lo)){
if (g_debugMode){
PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, BitLen);
PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, DemodBufferLen);
printDemodBuff();
}
PrintAndLog("EM410x pattern found: ");
if (BitLen > 64) PrintAndLog("\nWarning! Length not what is expected - Length: %d bits\n",BitLen);
printEM410x(lo);
printEM410x(hi, lo);
return 1;
}
return 0;
@ -386,21 +360,21 @@ int ASKmanDemod(const char *Cmd, bool verbose, bool emSearch)
if (g_debugMode==1) PrintAndLog("no data found %d, errors:%d, bitlen:%d, clock:%d",errCnt,invert,BitLen,clk);
return 0;
}
if (verbose) PrintAndLog("\nUsing Clock: %d - Invert: %d - Bits Found: %d",clk,invert,BitLen);
if (verbose || g_debugMode) PrintAndLog("\nUsing Clock: %d - Invert: %d - Bits Found: %d",clk,invert,BitLen);
//output
if (errCnt>0){
if (verbose) PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
if (verbose || g_debugMode) PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
}
if (verbose) PrintAndLog("ASK/Manchester decoded bitstream:");
if (verbose || g_debugMode) PrintAndLog("ASK/Manchester decoded bitstream:");
// Now output the bitstream to the scrollback by line of 16 bits
setDemodBuf(BitStream,BitLen,0);
if (verbose) printDemodBuff();
if (verbose || g_debugMode) printDemodBuff();
uint64_t lo =0;
uint32_t hi =0;
size_t idx=0;
if (emSearch){
lo = Em410xDecode(BitStream, &BitLen, &idx);
if (lo>0){
if (Em410xDecode(BitStream, &BitLen, &idx, &hi, &lo)){
//set GraphBuffer for clone or sim command
setDemodBuf(BitStream, BitLen, idx);
if (g_debugMode){
@ -408,7 +382,7 @@ int ASKmanDemod(const char *Cmd, bool verbose, bool emSearch)
printDemodBuff();
}
if (verbose) PrintAndLog("EM410x pattern found: ");
if (verbose) printEM410x(lo);
if (verbose) printEM410x(hi, lo);
return 1;
}
}
@ -478,13 +452,13 @@ int Cmdmandecoderaw(const char *Cmd)
printBitStream(BitStream, size);
if (errCnt==0){
uint64_t id = 0;
uint32_t hi = 0;
size_t idx=0;
id = Em410xDecode(BitStream, &size, &idx);
if (id>0){
if (Em410xDecode(BitStream, &size, &idx, &hi, &id)){
//need to adjust to set bitstream back to manchester encoded data
//setDemodBuf(BitStream, size, idx);
printEM410x(id);
printEM410x(hi, id);
}
}
return 1;
@ -502,53 +476,52 @@ int Cmdmandecoderaw(const char *Cmd)
// width waves vs small width waves to help the decode positioning) or askbiphdemod
int CmdBiphaseDecodeRaw(const char *Cmd)
{
int i = 0;
int errCnt=0;
size_t size=0;
int offset=0;
int invert=0;
int high=0, low=0;
int offset=0, invert=0, maxErr=20, errCnt=0;
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: data biphaserawdecode [offset] <invert>");
PrintAndLog(" Converts 10 or 01 to 0 and 11 or 00 to 1");
PrintAndLog("Usage: data biphaserawdecode [offset] [invert] [maxErr]");
PrintAndLog(" Converts 10 or 01 to 1 and 11 or 00 to 0");
PrintAndLog(" --must have binary sequence in demodbuffer (run data askrawdemod first)");
PrintAndLog("");
PrintAndLog(" [offset <0|1>], set to 0 not to adjust start position or to 1 to adjust decode start position");
PrintAndLog(" [invert <0|1>], set to 1 to invert output");
PrintAndLog(" [maxErr int], set max errors tolerated - default=20");
PrintAndLog("");
PrintAndLog(" sample: data biphaserawdecode = decode biphase bitstream from the demodbuffer");
PrintAndLog(" sample: data biphaserawdecode 1 1 = decode biphase bitstream from the demodbuffer, set offset, and invert output");
return 0;
}
sscanf(Cmd, "%i %i", &offset, &invert);
if (DemodBufferLen==0) return 0;
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
//get graphbuffer & high and low
for (;i<DemodBufferLen;++i){
if(DemodBuffer[i]>high)high=DemodBuffer[i];
else if(DemodBuffer[i]<low)low=DemodBuffer[i];
BitStream[i]=DemodBuffer[i];
}
if (high>1 || low <0){
PrintAndLog("Error: please raw demod the wave first then decode");
sscanf(Cmd, "%i %i %i", &offset, &invert, &maxErr);
if (DemodBufferLen==0){
PrintAndLog("DemodBuffer Empty - run 'data rawdemod ar' first");
return 0;
}
size=i;
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
memcpy(BitStream, DemodBuffer, DemodBufferLen);
size = DemodBufferLen;
errCnt=BiphaseRawDecode(BitStream, &size, offset, invert);
if (errCnt>=20){
if (errCnt<0){
PrintAndLog("Error during decode:%d", errCnt);
return 0;
}
if (errCnt>maxErr){
PrintAndLog("Too many errors attempting to decode: %d",errCnt);
return 0;
}
PrintAndLog("Biphase Decoded using offset: %d - # errors:%d - data:",offset,errCnt);
if (errCnt>0){
PrintAndLog("# Errors found during Demod (shown as 77 in bit stream): %d",errCnt);
}
PrintAndLog("Biphase Decoded using offset: %d - # invert:%d - data:",offset,invert);
printBitStream(BitStream, size);
PrintAndLog("\nif bitstream does not look right try offset=1");
if (offset == 1) setDemodBuf(DemodBuffer,DemodBufferLen-1,1); //remove first bit from raw demod
if (offset) setDemodBuf(DemodBuffer,DemodBufferLen-offset, offset); //remove first bit from raw demod
return 1;
}
// set demod buffer back to raw after biphase demod
void setBiphaseDemodBuf(uint8_t *BitStream, size_t size)
void setBiphasetoRawDemodBuf(uint8_t *BitStream, size_t size)
{
uint8_t rawStream[512]={0x00};
size_t i=0;
@ -570,6 +543,7 @@ void setBiphaseDemodBuf(uint8_t *BitStream, size_t size)
setDemodBuf(rawStream,i,0);
return;
}
//by marshmellow
//takes 4 arguments - clock, invert, maxErr as integers and amplify as char
//attempts to demodulate ask only
@ -584,7 +558,7 @@ int ASKrawDemod(const char *Cmd, bool verbose)
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
sscanf(Cmd, "%i %i %i %c", &clk, &invert, &maxErr, &amp);
if (invert != 0 && invert != 1) {
if (verbose) PrintAndLog("Invalid argument: %s", Cmd);
if (verbose || g_debugMode) PrintAndLog("Invalid argument: %s", Cmd);
return 0;
}
if (clk==1){
@ -597,20 +571,20 @@ int ASKrawDemod(const char *Cmd, bool verbose)
int errCnt=0;
errCnt = askrawdemod(BitStream, &BitLen, &clk, &invert, maxErr, askAmp);
if (errCnt==-1||BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first)
if (verbose) PrintAndLog("no data found");
if (g_debugMode==1 && verbose) PrintAndLog("errCnt: %d, BitLen: %d, clk: %d, invert: %d", errCnt, BitLen, clk, invert);
if (verbose || g_debugMode) PrintAndLog("no data found");
if (g_debugMode) PrintAndLog("errCnt: %d, BitLen: %d, clk: %d, invert: %d", errCnt, BitLen, clk, invert);
return 0;
}
if (verbose) PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d", clk, invert, BitLen);
if (verbose || g_debugMode) PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d", clk, invert, BitLen);
//move BitStream back to DemodBuffer
setDemodBuf(BitStream,BitLen,0);
//output
if (errCnt>0 && verbose){
if (errCnt>0 && (verbose || g_debugMode)){
PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d", errCnt);
}
if (verbose){
if (verbose || g_debugMode){
PrintAndLog("ASK demoded bitstream:");
// Now output the bitstream to the scrollback by line of 16 bits
printBitStream(BitStream,BitLen);
@ -618,6 +592,71 @@ int ASKrawDemod(const char *Cmd, bool verbose)
return 1;
}
//by marshmellow
// - ASK Demod then Biphase decode GraphBuffer samples
int ASKbiphaseDemod(const char *Cmd, bool verbose)
{
//ask raw demod GraphBuffer first
int offset=0, clk=0, invert=0, maxErr=0, ans=0;
ans = sscanf(Cmd, "%i %i %i %i", &offset, &clk, &invert, &maxErr);
if (ans>0)
ans = ASKrawDemod(Cmd+2, FALSE);
else
ans = ASKrawDemod(Cmd, FALSE);
if (!ans) {
if (g_debugMode || verbose) PrintAndLog("Error AskrawDemod: %d", ans);
return 0;
}
//attempt to Biphase decode DemodBuffer
size_t size = DemodBufferLen;
uint8_t BitStream[MAX_DEMOD_BUF_LEN];
memcpy(BitStream, DemodBuffer, DemodBufferLen);
int errCnt = BiphaseRawDecode(BitStream, &size, offset, invert);
if (errCnt < 0){
if (g_debugMode || verbose) PrintAndLog("Error BiphaseRawDecode: %d", errCnt);
return 0;
}
if (errCnt > maxErr) {
if (g_debugMode || verbose) PrintAndLog("Error BiphaseRawDecode too many errors: %d", errCnt);
return 0;
}
//success set DemodBuffer and return
setDemodBuf(BitStream, size, 0);
if (g_debugMode || verbose){
PrintAndLog("Biphase Decoded using offset: %d - # errors:%d - data:",offset,errCnt);
printDemodBuff();
}
return 1;
}
//by marshmellow - see ASKbiphaseDemod
int Cmdaskbiphdemod(const char *Cmd)
{
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) > 12 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: data rawdemod ab [offset] [clock] <invert> [maxError] <amplify>");
PrintAndLog(" [offset], offset to begin biphase, default=0");
PrintAndLog(" [set clock as integer] optional, if not set, autodetect");
PrintAndLog(" <invert>, 1 to invert output");
PrintAndLog(" [set maximum allowed errors], default = 100");
PrintAndLog(" <amplify>, 'a' to attempt demod with ask amplification, default = no amp");
PrintAndLog(" NOTE: <invert> can be entered as second or third argument");
PrintAndLog(" NOTE: <amplify> can be entered as first, second or last argument");
PrintAndLog(" NOTE: any other arg must have previous args set to work");
PrintAndLog("");
PrintAndLog(" sample: data rawdemod ab = demod an ask/biph tag from GraphBuffer");
PrintAndLog(" : data rawdemod ab a = demod an ask/biph tag from GraphBuffer, amplified");
PrintAndLog(" : data rawdemod ab 1 32 = demod an ask/biph tag from GraphBuffer using an offset of 1 and a clock of RF/32");
PrintAndLog(" : data rawdemod ab 0 32 1 = demod an ask/biph tag from GraphBuffer using a clock of RF/32 and inverting data");
PrintAndLog(" : data rawdemod ab 0 1 = demod an ask/biph tag from GraphBuffer while inverting data");
PrintAndLog(" : data rawdemod ab 0 64 1 0 = demod an ask/biph tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors");
PrintAndLog(" : data rawdemod ab 0 64 1 0 a = demod an ask/biph tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors, and amp");
return 0;
}
return ASKbiphaseDemod(Cmd, TRUE);
}
//by marshmellow
//attempts to demodulate and identify a G_Prox_II verex/chubb card
//WARNING: if it fails during some points it will destroy the DemodBuffer data
@ -625,33 +664,17 @@ int ASKrawDemod(const char *Cmd, bool verbose)
//if successful it will push askraw data back to demod buffer ready for emulation
int CmdG_Prox_II_Demod(const char *Cmd)
{
int ans = ASKrawDemod(Cmd, FALSE);
if (ans <= 0) {
if (g_debugMode) PrintAndLog("Error AskrawDemod: %d",ans);
return ans;
if (!ASKbiphaseDemod(Cmd, FALSE)){
if (g_debugMode) PrintAndLog("ASKbiphaseDemod failed 1st try");
return 0;
}
size_t size = DemodBufferLen;
ans = BiphaseRawDecode(DemodBuffer, &size, 0, 0);
if (ans !=0) {
if (g_debugMode) PrintAndLog("Error BiphaseRawDecode: %d",ans);
return ans;
}
//call lfdemod.c demod for gProxII
ans = gProxII_Demod(DemodBuffer, &size);
int ans = gProxII_Demod(DemodBuffer, &size);
if (ans < 0){
if (g_debugMode) PrintAndLog("Error gProxII_Demod 1st Try: %d",ans);
//try biphase again
ans = BiphaseRawDecode(DemodBuffer, &size, 1, 0);
if (ans != 0) {
if (g_debugMode) PrintAndLog("Error BiphaseRawDecode: %d",ans);
return ans;
if (g_debugMode) PrintAndLog("Error gProxII_Demod");
return 0;
}
ans = gProxII_Demod(DemodBuffer, &size);
if (ans < 0) {
if (g_debugMode) PrintAndLog("Error gProxII_Demod 1st Try: %d",ans);
return ans;
}
}
//got a good demod
uint32_t ByteStream[65] = {0x00};
uint8_t xorKey=0;
@ -664,7 +687,7 @@ int CmdG_Prox_II_Demod(const char *Cmd)
//spacer bit - should be 0
if (DemodBuffer[startIdx+idx] != 0) {
if (g_debugMode) PrintAndLog("Error spacer not 0: %d, pos: %d",DemodBuffer[startIdx+idx],startIdx+idx);
return -1;
return 0;
}
continue;
}
@ -708,7 +731,7 @@ int CmdG_Prox_II_Demod(const char *Cmd)
PrintAndLog("Unknown G-Prox-II Fmt Found: FmtLen %d",fmtLen);
}
PrintAndLog("Raw: %08x%08x%08x", raw1,raw2,raw3);
setBiphaseDemodBuf(DemodBuffer+ans, 96);
setDemodBuf(DemodBuffer+ans, 96, 0);
return 1;
}
@ -735,38 +758,80 @@ int Cmdaskrawdemod(const char *Cmd)
return ASKrawDemod(Cmd, TRUE);
}
int CmdAutoCorr(const char *Cmd)
int AutoCorrelate(int window, bool SaveGrph, bool verbose)
{
static int CorrelBuffer[MAX_GRAPH_TRACE_LEN];
int window = atoi(Cmd);
if (window == 0) {
PrintAndLog("needs a window");
return 0;
}
if (window >= GraphTraceLen) {
PrintAndLog("window must be smaller than trace (%d samples)",
GraphTraceLen);
return 0;
}
PrintAndLog("performing %d correlations", GraphTraceLen - window);
size_t Correlation = 0;
int maxSum = 0;
int lastMax = 0;
if (verbose) PrintAndLog("performing %d correlations", GraphTraceLen - window);
for (int i = 0; i < GraphTraceLen - window; ++i) {
int sum = 0;
for (int j = 0; j < window; ++j) {
sum += (GraphBuffer[j]*GraphBuffer[i + j]) / 256;
}
CorrelBuffer[i] = sum;
if (sum >= maxSum-100 && sum <= maxSum+100){
//another max
Correlation = i-lastMax;
lastMax = i;
if (sum > maxSum) maxSum = sum;
} else if (sum > maxSum){
maxSum=sum;
lastMax = i;
}
}
if (Correlation==0){
//try again with wider margin
for (int i = 0; i < GraphTraceLen - window; i++){
if (CorrelBuffer[i] >= maxSum-(maxSum*0.05) && CorrelBuffer[i] <= maxSum+(maxSum*0.05)){
//another max
Correlation = i-lastMax;
lastMax = i;
//if (CorrelBuffer[i] > maxSum) maxSum = sum;
}
}
}
if (verbose && Correlation > 0) PrintAndLog("Possible Correlation: %d samples",Correlation);
if (SaveGrph){
GraphTraceLen = GraphTraceLen - window;
memcpy(GraphBuffer, CorrelBuffer, GraphTraceLen * sizeof (int));
RepaintGraphWindow();
}
return Correlation;
}
RepaintGraphWindow();
int usage_data_autocorr(void)
{
//print help
PrintAndLog("Usage: data autocorr [window] [g]");
PrintAndLog("Options: ");
PrintAndLog(" h This help");
PrintAndLog(" [window] window length for correlation - default = 4000");
PrintAndLog(" g save back to GraphBuffer (overwrite)");
return 0;
}
int CmdAutoCorr(const char *Cmd)
{
char cmdp = param_getchar(Cmd, 0);
if (cmdp == 'h' || cmdp == 'H')
return usage_data_autocorr();
int window = 4000; //set default
char grph=0;
bool updateGrph = FALSE;
sscanf(Cmd, "%i %c", &window, &grph);
if (window >= GraphTraceLen) {
PrintAndLog("window must be smaller than trace (%d samples)",
GraphTraceLen);
return 0;
}
if (grph == 'g') updateGrph=TRUE;
return AutoCorrelate(window, updateGrph, TRUE);
}
int CmdBitsamples(const char *Cmd)
{
int cnt = 0;
@ -1440,7 +1505,17 @@ int CmdFSKdemodPyramid(const char *Cmd)
// w = wiegand parity, x = extra space for other formats
// p = unknown checksum
// (26 bit format shown)
//get bytes for checksum calc
uint8_t checksum = bytebits_to_byte(BitStream + idx + 120, 8);
uint8_t csBuff[14] = {0x00};
for (uint8_t i = 0; i < 13; i++){
csBuff[i] = bytebits_to_byte(BitStream + idx + 16 + (i*8), 8);
}
//check checksum calc
//checksum calc thanks to ICEMAN!!
uint32_t checkCS = CRC8Maxim(csBuff,13);
//get raw ID before removing parities
uint32_t rawLo = bytebits_to_byte(BitStream+idx+96,32);
uint32_t rawHi = bytebits_to_byte(BitStream+idx+64,32);
@ -1450,7 +1525,8 @@ int CmdFSKdemodPyramid(const char *Cmd)
size = removeParity(BitStream, idx+8, 8, 1, 120);
if (size != 105){
if (g_debugMode==1) PrintAndLog("DEBUG: Error at parity check-tag size does not match Pyramid format, SIZE: %d, IDX: %d, hi3: %x",size, idx, rawHi3);
if (g_debugMode==1)
PrintAndLog("DEBUG: Error at parity check - tag size does not match Pyramid format, SIZE: %d, IDX: %d, hi3: %x",size, idx, rawHi3);
return 0;
}
@ -1508,6 +1584,11 @@ int CmdFSKdemodPyramid(const char *Cmd)
PrintAndLog("Pyramid ID Found - BitLength: %d -unknown BitLength- (%d), Raw: %08x%08x%08x%08x", fmtLen, cardnum, rawHi3, rawHi2, rawHi, rawLo);
}
}
if (checksum == checkCS)
PrintAndLog("Checksum %02x passed", checksum);
else
PrintAndLog("Checksum %02x failed - should have been %02x", checksum, checkCS);
if (g_debugMode){
PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, 128);
printDemodBuff();
@ -1667,11 +1748,11 @@ int PSKDemod(const char *Cmd, bool verbose)
if (g_debugMode==1 && verbose) PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt);
return 0;
}
if (verbose) {
PrintAndLog("Tried PSK Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen);
if (errCnt>0){
PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
}
if (verbose){
PrintAndLog("Tried PSK Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen);
if (errCnt>0){
PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
}
}
//prime demod buffer for output
setDemodBuf(BitStream,BitLen,0);
@ -1690,7 +1771,7 @@ int CmdIndalaDecode(const char *Cmd)
ans = PSKDemod("32", 0);
}
if ( !ans ){
if (!ans){
if (g_debugMode==1)
PrintAndLog("Error1: %d",ans);
return 0;
@ -1849,10 +1930,11 @@ int CmdPSK1rawDemod(const char *Cmd)
}
ans = PSKDemod(Cmd, TRUE);
//output
if ( !ans){
if (!ans){
if (g_debugMode) PrintAndLog("Error demoding: %d",ans);
return 0;
}
PrintAndLog("PSK demoded bitstream:");
// Now output the bitstream to the scrollback by line of 16 bits
printDemodBuff();
@ -1897,12 +1979,14 @@ int CmdRawDemod(const char *Cmd)
if (strlen(Cmd) > 14 || cmdp == 'h' || cmdp == 'H' || strlen(Cmd)<2) {
PrintAndLog("Usage: data rawdemod [modulation] <help>|<options>");
PrintAndLog(" [modulation] as 2 char, 'am' for ask/manchester, 'ar' for ask/raw, 'fs' for fsk, 'nr' for nrz/direct, 'p1' for psk1, 'p2' for psk2");
PrintAndLog(" [modulation] as 2 char, 'ab' for ask/biphase, 'am' for ask/manchester, 'ar' for ask/raw, 'fs' for fsk, ...");
PrintAndLog(" 'nr' for nrz/direct, 'p1' for psk1, 'p2' for psk2");
PrintAndLog(" <help> as 'h', prints the help for the specific modulation");
PrintAndLog(" <options> see specific modulation help for optional parameters");
PrintAndLog("");
PrintAndLog(" sample: data rawdemod fs h = print help for ask/raw demod");
PrintAndLog(" : data rawdemod fs = demod GraphBuffer using: fsk - autodetect");
PrintAndLog(" : data rawdemod ab = demod GraphBuffer using: ask/biphase - autodetect");
PrintAndLog(" : data rawdemod am = demod GraphBuffer using: ask/manchester - autodetect");
PrintAndLog(" : data rawdemod ar = demod GraphBuffer using: ask/raw - autodetect");
PrintAndLog(" : data rawdemod nr = demod GraphBuffer using: nrz/direct - autodetect");
@ -1914,6 +1998,8 @@ int CmdRawDemod(const char *Cmd)
int ans = 0;
if (cmdp == 'f' && cmdp2 == 's'){
ans = CmdFSKrawdemod(Cmd+3);
} else if(cmdp == 'a' && cmdp2 == 'b'){
ans = Cmdaskbiphdemod(Cmd+3);
} else if(cmdp == 'a' && cmdp2 == 'm'){
ans = Cmdaskmandemod(Cmd+3);
} else if(cmdp == 'a' && cmdp2 == 'r'){
@ -2581,7 +2667,7 @@ static command_t CommandTable[] =
{"askgproxiidemod",CmdG_Prox_II_Demod,1, "Demodulate a G Prox II tag from GraphBuffer"},
//{"askmandemod", Cmdaskmandemod, 1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional)"},
//{"askrawdemod", Cmdaskrawdemod, 1, "[clock] [invert<0|1>] -- Attempt to demodulate ASK tags and output bin (args optional)"},
{"autocorr", CmdAutoCorr, 1, "<window length> -- Autocorrelation over window"},
{"autocorr", CmdAutoCorr, 1, "[window length] [g] -- Autocorrelation over window - g to save back to GraphBuffer (overwrite)"},
{"biphaserawdecode",CmdBiphaseDecodeRaw,1,"[offset] [invert<0|1>] Biphase decode bin stream in DemodBuffer (offset = 0|1 bits to shift the decode start)"},
{"bitsamples", CmdBitsamples, 0, "Get raw samples as bitstring"},
//{"bitstream", CmdBitstream, 1, "[clock rate] -- Convert waveform into a bitstream"},

View file

@ -24,6 +24,7 @@ int CmdAskEM410xDemod(const char *Cmd);
int CmdG_Prox_II_Demod(const char *Cmd);
int Cmdaskrawdemod(const char *Cmd);
int Cmdaskmandemod(const char *Cmd);
int AutoCorrelate(int window, bool SaveGrph, bool verbose);
int CmdAutoCorr(const char *Cmd);
int CmdBiphaseDecodeRaw(const char *Cmd);
int CmdBitsamples(const char *Cmd);
@ -63,6 +64,7 @@ int CmdThreshold(const char *Cmd);
int CmdDirectionalThreshold(const char *Cmd);
int CmdZerocrossings(const char *Cmd);
int CmdIndalaDecode(const char *Cmd);
int ASKbiphaseDemod(const char *Cmd, bool verbose);
int ASKmanDemod(const char *Cmd, bool verbose, bool emSearch);
int ASKrawDemod(const char *Cmd, bool verbose);
int FSKrawDemod(const char *Cmd, bool verbose);

View file

@ -1541,7 +1541,7 @@ int CmdHF14AMfCLoad(const char *Cmd)
char buf[64] = {0x00};
uint8_t buf8[64] = {0x00};
uint8_t fillFromEmulator = 0;
int i, len, blockNum, flags;
int i, len, blockNum, flags=0;
if (param_getchar(Cmd, 0) == 'h' || param_getchar(Cmd, 0)== 0x00) {
PrintAndLog("It loads magic Chinese card from the file `filename.eml`");

View file

@ -575,12 +575,13 @@ int usage_lf_simfsk(void)
int usage_lf_simask(void)
{
//print help
PrintAndLog("Usage: lf simask [c <clock>] [i] [m|r] [s] [d <raw hex to sim>]");
PrintAndLog("Usage: lf simask [c <clock>] [i] [b|m|r] [s] [d <raw hex to sim>]");
PrintAndLog("Options: ");
PrintAndLog(" h This help");
PrintAndLog(" c <clock> Manually set clock - can autodetect if using DemodBuffer");
PrintAndLog(" i invert data");
PrintAndLog(" m sim ask/manchester");
PrintAndLog(" b sim ask/biphase");
PrintAndLog(" m sim ask/manchester - Default");
PrintAndLog(" r sim ask/raw");
PrintAndLog(" s TBD- -to enable a gap between playback repetitions - default: no gap");
PrintAndLog(" d <hexdata> Data to sim as hex - omit to sim from DemodBuffer");
@ -708,7 +709,7 @@ 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
uint8_t manchester = 1, separator = 0;
uint8_t encoding = 1, separator = 0;
//char cmdp = Cmd[0], par3='m', par4=0;
uint8_t clk=0, invert=0;
bool errors = FALSE;
@ -730,12 +731,16 @@ int CmdLFaskSim(const char *Cmd)
errors |= param_getdec(Cmd,cmdp+1,&clk);
cmdp+=2;
break;
case 'b':
encoding=2; //biphase
cmdp++;
break;
case 'm':
manchester=1;
encoding=1;
cmdp++;
break;
case 'r':
manchester=0;
encoding=0;
cmdp++;
break;
case 's':
@ -776,10 +781,10 @@ int CmdLFaskSim(const char *Cmd)
setDemodBuf(data, dataLen, 0);
}
if (clk == 0) clk = 64;
if (manchester == 0) clk = clk/2; //askraw needs to double the clock speed
if (encoding == 0) clk = clk/2; //askraw needs to double the clock speed
uint16_t arg1, arg2;
size_t size=DemodBufferLen;
arg1 = clk << 8 | manchester;
arg1 = clk << 8 | encoding;
arg2 = invert << 8 | separator;
if (size > USB_CMD_DATA_SIZE) {
PrintAndLog("DemodBuffer too long for current implementation - length: %d - max: %d", size, USB_CMD_DATA_SIZE);
@ -1085,24 +1090,30 @@ int CmdLFfind(const char *Cmd)
if (testRaw=='u' || testRaw=='U'){
//test unknown tag formats (raw mode)
PrintAndLog("\nChecking for Unknown tags:\n");
ans=CmdDetectClockRate("f");
ans=AutoCorrelate(4000, FALSE, FALSE);
if (ans > 0) PrintAndLog("Possible Auto Correlation of %d repeating samples",ans);
ans=GetFskClock("",FALSE,FALSE); //CmdDetectClockRate("F"); //
if (ans != 0){ //fsk
ans=CmdFSKrawdemod("");
ans=FSKrawDemod("",FALSE);
if (ans>0) {
PrintAndLog("\nUnknown FSK Modulated Tag Found!");
printDemodBuff();
return 1;
}
}
ans=Cmdaskmandemod("");
ans=ASKmanDemod("",FALSE,FALSE);
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("");
if (ans>0) {
PrintAndLog("Possible unknown PSK1 Modulated Tag Found above!\n\nCould also be PSK2 - try 'data psk2rawdemod'");
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");

View file

@ -42,12 +42,15 @@ uint32_t crc_finish(crc_t *crc)
return ( crc->state ^ crc->final_xor ) & crc->mask;
}
uint32_t CRC8Maxim(uint8_t *buff, size_t size) {
//credits to iceman
uint32_t CRC8Maxim(uint8_t *buff, size_t size)
{
crc_t crc;
crc_init(&crc, 9, 0x8c, 0x00, 0x00);
for ( uint8_t i = 0; i < size; ++i){
crc_clear(&crc);
for (size_t i=0; i < size; ++i){
crc_update(&crc, buff[i], 8);
}
return crc_finish(&crc);
}
}

View file

@ -39,7 +39,6 @@ extern uint32_t crc_finish(crc_t *crc);
// Calculate CRC-8/Maxim checksum
uint32_t CRC8Maxim(uint8_t *buff, size_t size );
/* Static initialization of a crc structure */
#define CRC_INITIALIZER(_order, _polynom, _initial_value, _final_xor) { \
.state = ((_initial_value) & ((1L<<(_order))-1)), \

View file

@ -1079,10 +1079,9 @@ 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 ){
}
else if (lastBit!=BitStream[i]){
if (BitStream[i]==77){
//ignore errors
} else if (lastBit!=BitStream[i]){
lastBit=BitStream[i];
BitStream[i]=1;
} else {
@ -1592,7 +1591,7 @@ int pskRawDemod(uint8_t dest[], size_t *size, int *clock, int *invert)
if (*size<loopCnt) loopCnt = *size;
uint8_t curPhase = *invert;
size_t i, waveStart=0, waveEnd=0, firstFullWave=0, lastClkBit=0;
size_t i, waveStart=1, waveEnd=0, firstFullWave=0, lastClkBit=0;
uint8_t fc=0, fullWaveLen=0, tol=1;
uint16_t errCnt=0, waveLenCnt=0;
fc = countPSK_FC(dest, *size);
@ -1604,37 +1603,32 @@ int pskRawDemod(uint8_t dest[], size_t *size, int *clock, int *invert)
//find first phase shift
for (i=0; i<loopCnt; i++){
if (dest[i]+fc < dest[i+1] && dest[i+1] >= dest[i+2]){
if (waveStart == 0) {
waveStart = i+1;
avgWaveVal=dest[i+1];
//PrintAndLog("DEBUG: waveStart: %d",waveStart);
} else {
waveEnd = i+1;
//PrintAndLog("DEBUG: waveEnd: %d",waveEnd);
waveLenCnt = waveEnd-waveStart;
lastAvgWaveVal = avgWaveVal/waveLenCnt;
if (waveLenCnt > fc){
if (waveLenCnt > fc && waveStart > fc){ //not first peak and is a large wave
lastAvgWaveVal = avgWaveVal/(waveLenCnt);
firstFullWave = waveStart;
fullWaveLen=waveLenCnt;
//if average wave value is > graph 0 then it is an up wave or a 1
if (lastAvgWaveVal > 128) curPhase^=1;
if (lastAvgWaveVal > 123) curPhase^=1; //fudge graph 0 a little 123 vs 128
break;
}
waveStart=0;
avgWaveVal=0;
waveStart = i+1;
avgWaveVal = 0;
}
avgWaveVal+=dest[i+2];
}
avgWaveVal+=dest[i+1];
}
//PrintAndLog("DEBUG: firstFullWave: %d, waveLen: %d",firstFullWave,fullWaveLen);
lastClkBit = firstFullWave; //set start of wave as clock align
//PrintAndLog("DEBUG: clk: %d, lastClkBit: %d", *clock, lastClkBit);
waveStart = 0;
errCnt=0;
size_t numBits=0;
//PrintAndLog("DEBUG: clk: %d, lastClkBit: %d", *clock, lastClkBit);
//set skipped bits
memset(dest+numBits, curPhase^1,firstFullWave / *clock);
memset(dest+numBits,curPhase^1,firstFullWave / *clock);
numBits += (firstFullWave / *clock);
dest[numBits++] = curPhase; //set first read bit
for (i = firstFullWave+fullWaveLen-1; i < *size-3; i++){
//top edge of wave = start of new wave
if (dest[i]+fc < dest[i+1] && dest[i+1] >= dest[i+2]){
@ -1652,20 +1646,17 @@ int pskRawDemod(uint8_t dest[], size_t *size, int *clock, int *invert)
//PrintAndLog("DEBUG: phase shift at: %d, len: %d, nextClk: %d, i: %d, fc: %d",waveStart,waveLenCnt,lastClkBit+*clock-tol,i+1,fc);
if (i+1 >= lastClkBit + *clock - tol){ //should be a clock bit
curPhase^=1;
dest[numBits] = curPhase;
numBits++;
dest[numBits++] = curPhase;
lastClkBit += *clock;
} else if (i<lastClkBit+10){
} else if (i<lastClkBit+10+fc){
//noise after a phase shift - ignore
} else { //phase shift before supposed to based on clock
errCnt++;
dest[numBits] = 77;
numBits++;
dest[numBits++] = 77;
}
} else if (i+1 > lastClkBit + *clock + tol + fc){
lastClkBit += *clock; //no phase shift but clock bit
dest[numBits] = curPhase;
numBits++;
dest[numBits++] = curPhase;
}
avgWaveVal=0;
waveStart=i+1;

View file

@ -1,48 +0,0 @@
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
// Generic CRC calculation code.
//-----------------------------------------------------------------------------
#ifndef __CRC_H
#define __CRC_H
#include <stdint.h>
typedef struct crc {
uint32_t state;
int order;
uint32_t polynom;
uint32_t initial_value;
uint32_t final_xor;
uint32_t mask;
} crc_t;
/* Initialize a crc structure. order is the order of the polynom, e.g. 32 for a CRC-32
* polynom is the CRC polynom. initial_value is the initial value of a clean state.
* final_xor is XORed onto the state before returning it from crc_result(). */
extern void crc_init(crc_t *crc, int order, uint32_t polynom, uint32_t initial_value, uint32_t final_xor);
/* Update the crc state. data is the data of length data_width bits (only the the
* data_width lower-most bits are used).
*/
extern void crc_update(crc_t *crc, uint32_t data, int data_width);
/* Clean the crc state, e.g. reset it to initial_value */
extern void crc_clear(crc_t *crc);
/* Get the result of the crc calculation */
extern uint32_t crc_finish(crc_t *crc);
/* Static initialization of a crc structure */
#define CRC_INITIALIZER(_order, _polynom, _initial_value, _final_xor) { \
.state = ((_initial_value) & ((1L<<(_order))-1)), \
.order = (_order), \
.polynom = (_polynom), \
.initial_value = (_initial_value), \
.final_xor = (_final_xor), \
.mask = ((1L<<(_order))-1) }
#endif /* __CRC_H */