From 5644791bdb264300ebfac1c2e51cfc7d231c4070 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Tue, 6 Jan 2015 09:20:36 -0500 Subject: [PATCH 01/11] added data psk* cmds for pskdemod fixed a couple small bugs in other lf functions as well including detectaskclock, stopped changes from being made to graphbuffer. --- armsrc/lfops.c | 2 +- client/cmddata.c | 302 +- client/cmddata.h | 9 +- client/cmdlf.c | 30 +- client/cmdlfem4x.c | 2 +- client/graph.c | 52 +- client/graph.h | 1 + common/lfdemod.c | 482 +- common/lfdemod.h | 8 +- traces/ATA5577-HIDemu-FC1-C9.pm3 | 16000 +++++++++++++++++++++++++++++ traces/README.txt | 7 + 11 files changed, 16810 insertions(+), 85 deletions(-) create mode 100644 traces/ATA5577-HIDemu-FC1-C9.pm3 diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 894adef78..79d59bf9c 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -729,7 +729,7 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol) uint8_t *dest = (uint8_t *)BigBuf; size_t size=0; //, found=0; - uint32_t bitLen=0; + int bitLen=0; int clk=0, invert=0, errCnt=0; uint64_t lo=0; // Configure to go in 125Khz listen mode diff --git a/client/cmddata.c b/client/cmddata.c index d8a0fcf6b..4b5cb0401 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -21,9 +21,55 @@ #include "cmdmain.h" #include "cmddata.h" #include "lfdemod.h" - +uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN]; +int DemodBufferLen; static int CmdHelp(const char *Cmd); +//set the demod buffer with given array of binary (one bit per byte) +//by marshmellow +void setDemodBuf(uint8_t *buff,int size) +{ + int i=0; + for (; i < size; ++i){ + DemodBuffer[i]=buff[i]; + } + DemodBufferLen=size; + return; +} + +//by marshmellow +void printDemodBuff() +{ + uint32_t i = 0; + int bitLen = DemodBufferLen; + if (bitLen<16) { + PrintAndLog("no bits found in demod buffer"); + return; + } + if (bitLen>512) bitLen=512; //max output to 512 bits if we have more - should be plenty + for (i = 0; i <= (bitLen-16); i+=16) { + PrintAndLog("%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i", + DemodBuffer[i], + DemodBuffer[i+1], + DemodBuffer[i+2], + DemodBuffer[i+3], + DemodBuffer[i+4], + DemodBuffer[i+5], + DemodBuffer[i+6], + DemodBuffer[i+7], + DemodBuffer[i+8], + DemodBuffer[i+9], + DemodBuffer[i+10], + DemodBuffer[i+11], + DemodBuffer[i+12], + DemodBuffer[i+13], + DemodBuffer[i+14], + DemodBuffer[i+15]); + } + return; +} + + int CmdAmp(const char *Cmd) { int i, rising, falling; @@ -185,10 +231,10 @@ void printEM410x(uint64_t id) int CmdEm410xDecode(const char *Cmd) { uint64_t id=0; - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - uint32_t i=0; - i=getFromGraphBuf(BitStream); - id = Em410xDecode(BitStream,i); + // uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + // uint32_t i=0; + // i=getFromGraphBuf(BitStream); + id = Em410xDecode(DemodBuffer,DemodBufferLen); printEM410x(id); if (id>0) return 1; return 0; @@ -209,15 +255,15 @@ int Cmdaskmandemod(const char *Cmd) PrintAndLog("Invalid argument: %s", Cmd); return 0; } - uint32_t BitLen = getFromGraphBuf(BitStream); + + int BitLen = getFromGraphBuf(BitStream); // PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen); int errCnt=0; errCnt = askmandemod(BitStream, &BitLen,&clk,&invert); - if (errCnt<0){ //if fatal error (or -1) + if (errCnt<0||BitLen<16){ //if fatal error (or -1) // PrintAndLog("no data found %d, errors:%d, bitlen:%d, clock:%d",errCnt,invert,BitLen,clk); return 0; } - if (BitLen<16) return 0; PrintAndLog("\nUsing Clock: %d - Invert: %d - Bits Found: %d",clk,invert,BitLen); //output @@ -226,12 +272,12 @@ int Cmdaskmandemod(const char *Cmd) } PrintAndLog("ASK/Manchester decoded bitstream:"); // Now output the bitstream to the scrollback by line of 16 bits - printBitStream(BitStream,BitLen); + setDemodBuf(BitStream,BitLen); + printDemodBuff(); uint64_t lo =0; lo = Em410xDecode(BitStream,BitLen); if (lo>0){ //set GraphBuffer for clone or sim command - setGraphBuf(BitStream,BitLen); PrintAndLog("EM410x pattern found: "); printEM410x(lo); return 1; @@ -250,10 +296,10 @@ int Cmdmandecoderaw(const char *Cmd) int bitnum=0; uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; int high=0,low=0; - for (;ihigh) high=GraphBuffer[i]; - else if(GraphBuffer[i]high) high=DemodBuffer[i]; + else if(DemodBuffer[i]1 || low <0 ){ PrintAndLog("Error: please raw demod the wave first then mancheseter raw decode"); @@ -268,15 +314,9 @@ int Cmdmandecoderaw(const char *Cmd) PrintAndLog("Manchester Decoded - # errors:%d - data:",errCnt); printBitStream(BitStream,bitnum); if (errCnt==0){ - //put back in graphbuffer - ClearGraph(0); - for (i=0; i0) setDemodBuf(BitStream,bitnum); printEM410x(id); } return 1; @@ -301,10 +341,10 @@ int CmdBiphaseDecodeRaw(const char *Cmd) sscanf(Cmd, "%i", &offset); uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; //get graphbuffer & high and low - for (;ihigh)high=GraphBuffer[i]; - else if(GraphBuffer[i]high)high=DemodBuffer[i]; + else if(DemodBuffer[i]1 || low <0){ PrintAndLog("Error: please raw demod the wave first then decode"); @@ -329,7 +369,6 @@ int CmdBiphaseDecodeRaw(const char *Cmd) //prints binary found and saves in graphbuffer for further commands int Cmdaskrawdemod(const char *Cmd) { - uint32_t i; int invert=0; int clk=0; uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; @@ -341,21 +380,14 @@ int Cmdaskrawdemod(const char *Cmd) int BitLen = getFromGraphBuf(BitStream); int errCnt=0; errCnt = askrawdemod(BitStream, &BitLen,&clk,&invert); - if (errCnt==-1){ //throw away static - allow 1 and -1 (in case of threshold command first) + if (errCnt==-1||BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first) PrintAndLog("no data found"); return 0; } - if (BitLen<16) return 0; PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen); //PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum); - //move BitStream back to GraphBuffer - - ClearGraph(0); - for (i=0; i < BitLen; ++i){ - GraphBuffer[i]=BitStream[i]; - } - GraphTraceLen=BitLen; - RepaintGraphWindow(); + //move BitStream back to DemodBuffer + setDemodBuf(BitStream,BitLen); //output if (errCnt>0){ @@ -538,18 +570,12 @@ int CmdFSKrawdemod(const char *Cmd) } else if(rfLen==0) rfLen=50; } PrintAndLog("Args invert: %d - Clock:%d - fchigh:%d - fclow: %d",invert,rfLen,fchigh, fclow); - uint32_t i=0; uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; uint32_t BitLen = getFromGraphBuf(BitStream); int size = fskdemod(BitStream,BitLen,(uint8_t)rfLen,(uint8_t)invert,(uint8_t)fchigh,(uint8_t)fclow); if (size>0){ PrintAndLog("FSK decoded bitstream:"); - ClearGraph(0); - for (i=0;i (8*32)+2) size = (8*32)+2; //only output a max of 8 blocks of 32 bits most tags will have full bit stream inside that sample size @@ -578,9 +604,9 @@ int CmdFSKdemodHID(const char *Cmd) } if (hi2==0 && hi==0 && lo==0) return 0; if (hi2 != 0){ //extra large HID tags - PrintAndLog("TAG ID: %x%08x%08x (%d)", + PrintAndLog("HID Prox TAG ID: %x%08x%08x (%d)", (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); - setGraphBuf(BitStream,BitLen); + setDemodBuf(BitStream,BitLen); return 1; } else { //standard HID tags <38 bits @@ -625,10 +651,10 @@ int CmdFSKdemodHID(const char *Cmd) fc = ((hi&0xF)<<12)|(lo>>20); } } - PrintAndLog("TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d", + PrintAndLog("HID Prox TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d", (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF, (unsigned int) fmtLen, (unsigned int) fc, (unsigned int) cardnum); - setGraphBuf(BitStream,BitLen); + setDemodBuf(BitStream,BitLen); return 1; } return 0; @@ -682,9 +708,12 @@ int CmdFSKdemodIO(const char *Cmd) uint8_t version = bytebits_to_byte(BitStream+idx+27,8); //14,4 uint8_t facilitycode = bytebits_to_byte(BitStream+idx+18,8) ; uint16_t number = (bytebits_to_byte(BitStream+idx+36,8)<<8)|(bytebits_to_byte(BitStream+idx+45,8)); //36,9 - - PrintAndLog("XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2); - setGraphBuf(BitStream,BitLen); + PrintAndLog("IO Prox XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2); + int i; + for (i=0;i<64;++i) + DemodBuffer[i]=BitStream[idx++]; + + DemodBufferLen=64; return 1; } int CmdFSKdemod(const char *Cmd) //old CmdFSKdemod needs updating @@ -806,6 +835,160 @@ int CmdFSKdemod(const char *Cmd) //old CmdFSKdemod needs updating return 0; } +int CmdDetectNRZpskClockRate(const char *Cmd) +{ + GetNRZpskClock("",0,0); + return 0; +} + +int PSKnrzDemod(const char *Cmd){ + int invert=0; + int clk=0; + sscanf(Cmd, "%i %i", &clk, &invert); + if (invert != 0 && invert != 1) { + PrintAndLog("Invalid argument: %s", Cmd); + return -1; + } + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + int BitLen = getFromGraphBuf(BitStream); + int errCnt=0; + errCnt = pskNRZrawDemod(BitStream, &BitLen,&clk,&invert); + if (errCnt<0|| BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first) + //PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); + return -1; + } + PrintAndLog("Tried PSK/NRZ Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen); + + //prime demod buffer for output + setDemodBuf(BitStream,BitLen); + return errCnt; +} +// Indala 26 bit decode +// by marshmellow +// optional arguments - same as CmdpskNRZrawDemod (clock & invert) +int CmdIndalaDecode(const char *Cmd) +{ + + int ans=PSKnrzDemod(Cmd); + if (ans < 0){ + PrintAndLog("Error1: %d",ans); + return 0; + } + uint8_t invert=0; + ans = indala26decode(DemodBuffer, &DemodBufferLen, &invert); + if (ans < 1) { + PrintAndLog("Error2: %d",ans); + return -1; + } + char showbits[251]; + if(invert==1) PrintAndLog("Had to invert bits"); + //convert UID to HEX + uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7; + int idx; + uid1=0; + uid2=0; + PrintAndLog("BitLen: %d",DemodBufferLen); + if (DemodBufferLen==64){ + for( idx=0; idx<64; idx++) { + uid1=(uid1<<1)|(uid2>>31); + if (DemodBuffer[idx] == 0) { + uid2=(uid2<<1)|0; + showbits[idx]='0'; + } else { + uid2=(uid2<<1)|1; + showbits[idx]='1'; + } + } + showbits[idx]='\0'; + PrintAndLog("Indala UID=%s (%x%08x)", showbits, uid1, uid2); + } + else { + uid3=0; + uid4=0; + uid5=0; + uid6=0; + uid7=0; + for( idx=0; idx>31); + uid2=(uid2<<1)|(uid3>>31); + uid3=(uid3<<1)|(uid4>>31); + uid4=(uid4<<1)|(uid5>>31); + uid5=(uid5<<1)|(uid6>>31); + uid6=(uid6<<1)|(uid7>>31); + if (DemodBuffer[idx] == 0) { + uid7=(uid7<<1)|0; + showbits[idx]='0'; + } + else { + uid7=(uid7<<1)|1; + showbits[idx]='1'; + } + } + showbits[idx]='\0'; + PrintAndLog("Indala UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7); + } + return 1; +} + +/* +//by marshmellow (attempt to get rid of high immediately after a low) +void pskCleanWave2(uint8_t *bitStream, int bitLen) +{ + int i; + int low=128; + int gap = 4; + // int loopMax = 2048; + int newLow=0; + + for (i=0; i0){ + PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); + } + PrintAndLog("PSK or NRZ demoded bitstream:"); + // Now output the bitstream to the scrollback by line of 16 bits + printDemodBuff(); + + return 1; +} + + + int CmdGrid(const char *Cmd) { sscanf(Cmd, "%i %i", &PlotGridX, &PlotGridY); @@ -1216,8 +1399,9 @@ int CmdNorm(const char *Cmd) if (max != min) { for (i = 0; i < GraphTraceLen; ++i) { - GraphBuffer[i] = (GraphBuffer[i] - ((max + min) / 2)) * 1000 / - (max - min); + GraphBuffer[i] = (GraphBuffer[i] - ((max + min) / 2)) * 256 / + (max - min); + //marshmelow: adjusted *1000 to *256 to make +/- 128 so demod commands still work } } RepaintGraphWindow(); @@ -1348,7 +1532,7 @@ static command_t CommandTable[] = {"bitstream", CmdBitstream, 1, "[clock rate] -- Convert waveform into a bitstream"}, {"buffclear", CmdBuffClear, 1, "Clear sample buffer and graph window"}, {"dec", CmdDec, 1, "Decimate samples"}, - {"detectaskclock",CmdDetectClockRate, 1, "Detect ASK clock rate"}, + {"detectclock", CmdDetectClockRate, 1, "Detect ASK, PSK, or NRZ clock rate"}, {"fskdemod", CmdFSKdemod, 1, "Demodulate graph window as a HID FSK"}, {"fskhiddemod", CmdFSKdemodHID, 1, "Demodulate graph window as a HID FSK using raw"}, {"fskiodemod", CmdFSKdemodIO, 1, "Demodulate graph window as an IO Prox FSK using raw"}, @@ -1363,15 +1547,19 @@ static command_t CommandTable[] = {"mandemod", CmdManchesterDemod, 1, "[i] [clock rate] -- Manchester demodulate binary stream (option 'i' to invert output)"}, {"manrawdecode", Cmdmandecoderaw, 1, "Manchester decode binary stream already in graph buffer"}, {"manmod", CmdManchesterMod, 1, "[clock rate] -- Manchester modulate a binary stream"}, - {"norm", CmdNorm, 1, "Normalize max/min to +/-500"}, + {"norm", CmdNorm, 1, "Normalize max/min to +/-128"}, {"plot", CmdPlot, 1, "Show graph window (hit 'h' in window for keystroke help)"}, + {"pskclean", CmdPskClean, 1, "Attempt to clean psk wave"}, + {"pskdetectclock",CmdDetectNRZpskClockRate, 1, "Detect ASK, PSK, or NRZ clock rate"}, + {"pskindalademod",CmdIndalaDecode, 1, "[clock] [invert<0 or 1>] -- Attempt to demodulate psk indala tags and output ID binary & hex (args optional[clock will try Auto-detect])"}, + {"psknrzrawdemod",CmdpskNRZrawDemod, 1, "[clock] [invert<0 or 1>] -- Attempt to demodulate psk or nrz tags and output binary (args optional[clock will try Auto-detect])"}, {"samples", CmdSamples, 0, "[512 - 40000] -- Get raw samples for graph window"}, - {"tune", CmdTuneSamples, 0, "Get hw tune samples for graph window"}, {"save", CmdSave, 1, " -- Save trace (from graph window)"}, {"scale", CmdScale, 1, " -- Set cursor display scale"}, {"threshold", CmdThreshold, 1, " -- Maximize/minimize every value in the graph window depending on threshold"}, - {"zerocrossings", CmdZerocrossings, 1, "Count time between zero-crossings"}, {"dirthreshold", CmdDirectionalThreshold, 1, " -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev."}, + {"tune", CmdTuneSamples, 0, "Get hw tune samples for graph window"}, + {"zerocrossings", CmdZerocrossings, 1, "Count time between zero-crossings"}, {NULL, NULL, 0, NULL} }; diff --git a/client/cmddata.h b/client/cmddata.h index 999e6438c..8723b847a 100644 --- a/client/cmddata.h +++ b/client/cmddata.h @@ -14,7 +14,7 @@ command_t * CmdDataCommands(); int CmdData(const char *Cmd); - +void printDemodBuff(); int CmdAmp(const char *Cmd); int Cmdaskdemod(const char *Cmd); int Cmdaskrawdemod(const char *Cmd); @@ -30,6 +30,8 @@ int CmdFSKdemod(const char *Cmd); int CmdFSKdemodHID(const char *Cmd); int CmdFSKdemodIO(const char *Cmd); int CmdFSKrawdemod(const char *Cmd); +int CmdDetectNRZpskClockRate(const char *Cmd); +int CmdpskNRZrawDemod(const char *Cmd); int CmdGrid(const char *Cmd); int CmdHexsamples(const char *Cmd); int CmdHide(const char *Cmd); @@ -49,5 +51,10 @@ 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); + +#define MAX_DEMOD_BUF_LEN (1024*128) +extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN]; +extern int DemodBufferLen; #endif diff --git a/client/cmdlf.c b/client/cmdlf.c index d9b26e2ae..42a29d0db 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -57,7 +57,7 @@ int CmdFlexdemod(const char *Cmd) } } -#define LONG_WAIT 100 + #define LONG_WAIT 100 int start; for (start = 0; start < GraphTraceLen - LONG_WAIT; start++) { int first = GraphBuffer[start]; @@ -558,18 +558,32 @@ int CmdLFfind(const char *Cmd) ans=CmdSamples("20000"); } if (GraphTraceLen<1000) return 0; + PrintAndLog("NOTE: some demods output possible binary\n if it finds something that looks like a tag"); PrintAndLog("Checking for known tags:"); + ans=Cmdaskmandemod(""); - if (ans>0) return 1; + if (ans>0) { + PrintAndLog("Valid EM410x ID Found!"); + return 1; + } ans=CmdFSKdemodHID(""); - if (ans>0) return 1; + if (ans>0) { + PrintAndLog("Valid HID Prox ID Found!"); + return 1; + } ans=CmdFSKdemodIO(""); - if (ans>0) return 1; + if (ans>0) { + PrintAndLog("Valid IO Prox ID Found!"); + return 1; + } //add psk and indala - ans=CmdIndalaDemod(""); - if (ans>0) return 1; - ans=CmdIndalaDemod("224"); - if (ans>0) return 1; + ans=CmdIndalaDecode(""); + if (ans>0) { + PrintAndLog("Valid Indala ID Found!"); + return 1; + } + // ans=CmdIndalaDemod("224"); + // if (ans>0) return 1; PrintAndLog("No Known Tags Found!\n"); return 0; } diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index 83f49db7a..f29da8e07 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -595,7 +595,7 @@ int CmdWriteWordPWD(const char *Cmd) static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, - {"em410xdemod", CmdEMdemodASK, 0, "[clock rate] -- Extract ID from EM410x tag"}, + {"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, " -- Simulate EM410x tag"}, {"em410xwatch", CmdEM410xWatch, 0, "['h'] -- Watches for EM410x 125/134 kHz tags (option 'h' for 134)"}, diff --git a/client/graph.c b/client/graph.c index a0e85ffd4..d63c42714 100644 --- a/client/graph.c +++ b/client/graph.c @@ -146,7 +146,7 @@ void setGraphBuf(uint8_t *buff,int size) int i=0; ClearGraph(0); for (; i < size; ++i){ - GraphBuffer[i]=buff[i]; + GraphBuffer[i]=buff[i]-128; } GraphTraceLen=size; RepaintGraphWindow(); @@ -187,3 +187,53 @@ int GetClock(const char *str, int peak, int verbose) return clock; } +int GetNRZpskClock(const char *str, int peak, int verbose) +{ + // return GetClock(str,peak,verbose); + int clock; + // int clock2; + sscanf(str, "%i", &clock); + if (!strcmp(str, "")) + clock = 0; + + /* Auto-detect clock */ + if (!clock) + { + uint8_t grph[MAX_GRAPH_TRACE_LEN]={0}; + int size = getFromGraphBuf(grph); + clock = DetectpskNRZClock(grph,size,0); + //clock2 = DetectClock2(peak); + /* Only print this message if we're not looping something */ + if (!verbose){ + PrintAndLog("Auto-detected clock rate: %d", clock); + //PrintAndLog("clock2: %d",clock2); + } + } + return clock; +} +// Get or auto-detect clock rate +/* +int GetNRZpskClock(const char *str, int peak, int verbose) +{ + int clock; +// int clock2; + sscanf(str, "%i", &clock); + if (!strcmp(str, "")) + clock = 0; + + // Auto-detect clock + if (!clock) + { + uint8_t grph[MAX_GRAPH_TRACE_LEN]={0}; + int size = getFromGraphBuf(grph); + clock = DetectASKClock(grph,size,0); + //clock2 = DetectClock2(peak); + // Only print this message if we're not looping something + if (!verbose){ + PrintAndLog("Auto-detected clock rate: %d", clock); + //PrintAndLog("clock2: %d",clock2); + } + } + return clock; +} +*/ \ No newline at end of file diff --git a/client/graph.h b/client/graph.h index 325582a67..c5c137986 100644 --- a/client/graph.h +++ b/client/graph.h @@ -17,6 +17,7 @@ int ClearGraph(int redraw); //int DetectClock(int peak); int getFromGraphBuf(uint8_t *buff); int GetClock(const char *str, int peak, int verbose); +int GetNRZpskClock(const char *str, int peak, int verbose); void setGraphBuf(uint8_t *buff,int size); #define MAX_GRAPH_TRACE_LEN (1024*128) diff --git a/common/lfdemod.c b/common/lfdemod.c index a03e7f024..ad4721f16 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -14,7 +14,7 @@ //by marshmellow //takes 1s and 0s and searches for EM410x format - output EM ID -uint64_t Em410xDecode(uint8_t *BitStream,uint32_t BitLen) +uint64_t Em410xDecode(uint8_t *BitStream, int BitLen) { //no arguments needed - built this way in case we want this to be a direct call from "data " cmds in the future // otherwise could be a void with no arguments @@ -82,7 +82,7 @@ uint64_t Em410xDecode(uint8_t *BitStream,uint32_t BitLen) //takes 2 arguments - clock and invert both as integers //attempts to demodulate ask while decoding manchester //prints binary found and saves in graphbuffer for further commands -int askmandemod(uint8_t * BinStream,uint32_t *BitLen,int *clk, int *invert) +int askmandemod(uint8_t * BinStream, int *BitLen,int *clk, int *invert) { int i; int high = 0, low = 128; @@ -655,13 +655,13 @@ int DetectASKClock(uint8_t dest[], size_t size, int clock) low = dest[i]; } } - peak=(int)((peak-128)*.75)+128; - low= (int)((low-128)*.75)+128; + peak=(int)(((peak-128)*.75)+128); + low= (int)(((low-128)*.75)+128); int ii; int clkCnt; int tol = 0; - int bestErr=1000; - int errCnt[]={0,0,0,0,0,0,0,0}; + int bestErr[]={1000,1000,1000,1000,1000,1000,1000,1000}; + int errCnt=0; //test each valid clock from smallest to greatest to see which lines up for(clkCnt=0; clkCnt<6;++clkCnt){ if (clk[clkCnt]==32){ @@ -669,33 +669,487 @@ int DetectASKClock(uint8_t dest[], size_t size, int clock) }else{ tol=0; } - bestErr=1000; + bestErr[clkCnt]=1000; //try lining up the peaks by moving starting point (try first 256) for (ii=0; ii=peak) || (dest[ii]<=low)){ - errCnt[clkCnt]=0; + errCnt=0; // now that we have the first one lined up test rest of wave array for (i=0; i<((int)(size/clk[clkCnt])-1); ++i){ if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){ }else if(dest[ii+(i*clk[clkCnt])-tol]>=peak || dest[ii+(i*clk[clkCnt])-tol]<=low){ }else if(dest[ii+(i*clk[clkCnt])+tol]>=peak || dest[ii+(i*clk[clkCnt])+tol]<=low){ }else{ //error no peak detected - errCnt[clkCnt]++; + errCnt++; } } //if we found no errors this is correct one - return this clock - if(errCnt[clkCnt]==0) return clk[clkCnt]; + if(errCnt==0) return clk[clkCnt]; //if we found errors see if it is lowest so far and save it as best run - if(errCnt[clkCnt]peak){ + peak = dest[i]; + } + if(dest[i]=peak) || (dest[ii]<=low)){ + errCnt=0; + peakcnt=0; + // now that we have the first one lined up test rest of wave array + for (i=0; i<((int)(size/clk[clkCnt])-1); ++i){ + if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){ + peakcnt++; + }else if(dest[ii+(i*clk[clkCnt])-tol]>=peak || dest[ii+(i*clk[clkCnt])-tol]<=low){ + peakcnt++; + }else if(dest[ii+(i*clk[clkCnt])+tol]>=peak || dest[ii+(i*clk[clkCnt])+tol]<=low){ + peakcnt++; + }else{ //error no peak detected + errCnt++; + } + } + if(peakcnt>peaksdet[clkCnt]) { + peaksdet[clkCnt]=peakcnt; + bestErr[clkCnt]=errCnt; + } + } + } + } + int iii=0; + int best=0; + //int ratio2; //debug + int ratio; + //int bits; + for (iii=0; iii<7;++iii){ + ratio=1000; + //ratio2=1000; //debug + //bits=size/clk[iii]; //debug + if (peaksdet[iii]>0){ + ratio=bestErr[iii]/peaksdet[iii]; + if (((bestErr[best]/peaksdet[best])>(ratio)+1)){ + best = iii; + } + //ratio2=bits/peaksdet[iii]; //debug + } + //PrintAndLog("DEBUG: Clk: %d, peaks: %d, errs: %d, bestClk: %d, ratio: %d, bits: %d, peakbitr: %d",clk[iii],peaksdet[iii],bestErr[iii],clk[best],ratio, bits,ratio2); + } + return clk[best]; +} + +/* +int DetectNRZpskClock(uint8_t dest[], size_t size, int clock) +{ + int i=0; + int peak=0; + int low=128; + int clk[]={16,32,40,50,64,100,128,256}; + int loopCnt = 1500; //don't need to loop through entire array... + if (sizepeak){ + peak = dest[i]; + } + if(dest[i]=peak) || (dest[ii]<=low)){ + lastClk = ii-*clk; + errCnt[clkCnt]=0; + // now that we have the first one lined up test rest of wave array + for (i=ii; i=peak || dest[i]<=low) && (i>=lastClk+*clk-tol && i<=lastClk+*clk+tol)){ + bitHigh=1; + lastClk=lastClk+*clk; + ignorewin=clk[clkCnt]/8; + }else if(dest[i]low) { + if (ignorewin==0){ + bitHigh=0; + }else ignorewin--; + if (i>=lastClk+*clk+tol){ //past possible bar + lowBitCnt[clkCnt]++; + } + }else if ((dest[i]>=peak || dest[i]<=low) && (i=lastClk+*clk+tol) && (bitHigh==0)){ + //error bar found no clock... + errCnt[clkCnt]++; + } + } + //if we found no errors this is correct one - return this clock + if(errCnt[clkCnt]==0 && lowBitCnt[clkCnt]==0) return clk[clkCnt]; + //if we found errors see if it is lowest so far and save it as best run + if(errCnt[clkCnt]high) high=bitStream[i]; + } + high = (int)(((high-128)*.80)+128); + low = (int)(((low-128)*.90)+128); + //low = (uint8_t)(((int)(low)-128)*.80)+128; + for (i=0; i=high) newHigh=1; + } + return; +} + +int indala26decode(uint8_t *bitStream, int *bitLen, uint8_t *invert) +{ + //26 bit 40134 format (don't know other formats) + // Finding the start of a UID + int i; + int long_wait; + //uidlen = 64; + long_wait = 29;//29 leading zeros in format + int start; + int first = 0; + int first2 = 0; + int bitCnt = 0; + int ii; + for (start = 0; start <= *bitLen - 250; start++) { + first = bitStream[start]; + for (i = start; i < start + long_wait; i++) { + if (bitStream[i] != first) { + break; + } + } + if (i == (start + long_wait)) { + break; + } + } + if (start == *bitLen - 250 + 1) { + // did not find start sequence + return -1; + } + //found start once now test length by finding next one + // Inverting signal if needed + if (first == 1) { + for (i = start; i < *bitLen; i++) { + bitStream[i] = !bitStream[i]; + } + *invert = 1; + }else *invert=0; + + int iii; + for (ii=start+29; ii <= *bitLen - 250; ii++) { + first2 = bitStream[ii]; + for (iii = ii; iii < ii + long_wait; iii++) { + if (bitStream[iii] != first2) { + break; + } + } + if (iii == (ii + long_wait)) { + break; + } + } + if (ii== *bitLen - 250 + 1){ + // did not find second start sequence + return -2; + } + bitCnt=ii-start; + + // Dumping UID + i = start; + for (ii = 0; ii < bitCnt; ii++) { + bitStream[ii] = bitStream[i++]; + //showbits[bit] = '0' + bits[bit]; + } + *bitLen=bitCnt; + return 1; +} + +int pskNRZrawDemod(uint8_t *dest, int *bitLen, int *clk, int *invert) +{ + pskCleanWave(dest,*bitLen); + int clk2 = DetectpskNRZClock(dest, *bitLen, *clk); + *clk=clk2; + uint32_t i; + uint8_t high=0, low=128; + uint32_t gLen = *bitLen; + if (gLen > 1280) gLen=1280; + // get high + for (i=0; ihigh) high = dest[i]; + if (dest[i]=high)||(dest[iii]<=low)){ + lastBit=iii-*clk; + //loop through to see if this start location works + for (i = iii; i < *bitLen; ++i) { + //if we found a high bar and we are at a clock bit + if ((dest[i]>=high ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ + bitHigh=1; + lastBit+=*clk; + //curBit=1-*invert; + //dest[bitnum]=curBit; + ignorewin=*clk/8; + bitnum++; + //else if low bar found and we are at a clock point + }else if ((dest[i]<=low ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ + bitHigh=1; + lastBit+=*clk; + ignorewin=*clk/8; + //curBit=*invert; + //dest[bitnum]=curBit; + bitnum++; + //else if no bars found + }else if(dest[i]low) { + if (ignorewin==0){ + bitHigh=0; + }else ignorewin--; + //if we are past a clock point + if (i>=lastBit+*clk+tol){ //clock val + //dest[bitnum]=curBit; + lastBit+=*clk; + bitnum++; + } + //else if bar found but we are not at a clock bit and we did not just have a clock bit + }else if ((dest[i]>=high || dest[i]<=low) && (ilastBit+*clk+tol) && (bitHigh==0)){ + //error bar found no clock... + errCnt++; + } + if (bitnum>=1000) break; + } + //we got more than 64 good bits and not all errors + if ((bitnum > (64+errCnt)) && (errCnt<(maxErr))) { + //possible good read + if (errCnt==0){ + bestStart = iii; + bestErrCnt=errCnt; + break; //great read - finish + } + if (bestStart == iii) break; //if current run == bestErrCnt run (after exhausted testing) then finish + if (errCnt=high ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ + bitHigh=1; + lastBit+=*clk; + curBit=1-*invert; + dest[bitnum]=curBit; + ignorewin=*clk/8; + bitnum++; + //else if low bar found and we are at a clock point + }else if ((dest[i]<=low ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ + bitHigh=1; + lastBit+=*clk; + curBit=*invert; + dest[bitnum]=curBit; + ignorewin=*clk/8; + bitnum++; + //else if no bars found + }else if(dest[i]low) { + if (ignorewin==0){ + bitHigh=0; + }else ignorewin--; + //if we are past a clock point + if (i>=lastBit+*clk+tol){ //clock val + lastBit+=*clk; + dest[bitnum]=curBit; + bitnum++; + } + //else if bar found but we are not at a clock bit and we did not just have a clock bit + }else if ((dest[i]>=high || dest[i]<=low) && ((ilastBit+*clk+tol)) && (bitHigh==0)){ + //error bar found no clock... + bitHigh=1; + dest[bitnum]=77; + bitnum++; + errCnt++; + } + if (bitnum >=1000) break; + } + *bitLen=bitnum; + } else{ + *bitLen=bitnum; + *clk=bestStart; + return -1; + } + + if (bitnum>16){ + *bitLen=bitnum; + } else return -1; + return errCnt; +} + + + /*not needed? + uint32_t i; + uint8_t high=0, low=128; + uint32_t loopMax = 1280; //20 raw bits + + // get high + if (sizehigh) high = dest[i]; + if (dest[i]=high) dest[i]=high; + else if(dest[i]<=low) dest[i]=low; + else dest[i]=0; + } + */ diff --git a/common/lfdemod.h b/common/lfdemod.h index ad95fda5e..2e0acf751 100644 --- a/common/lfdemod.h +++ b/common/lfdemod.h @@ -12,8 +12,8 @@ #include int DetectASKClock(uint8_t dest[], size_t size, int clock); -int askmandemod(uint8_t *BinStream,uint32_t *BitLen,int *clk, int *invert); -uint64_t Em410xDecode(uint8_t *BitStream,uint32_t BitLen); +int askmandemod(uint8_t *BinStream,int *BitLen,int *clk, int *invert); +uint64_t Em410xDecode(uint8_t *BitStream,int BitLen); int manrawdecode(uint8_t *BitStream, int *bitLen); int BiphaseRawDecode(uint8_t * BitStream, int *bitLen, int offset); int askrawdemod(uint8_t *BinStream, int *bitLen,int *clk, int *invert); @@ -21,5 +21,9 @@ int HIDdemodFSK(uint8_t *dest, size_t size, uint32_t *hi2, uint32_t *hi, uint32_ 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, int numbits); +int pskNRZrawDemod(uint8_t *dest, int *bitLen, int *clk, int *invert); +int DetectpskNRZClock(uint8_t dest[], size_t size, int clock); +int indala26decode(uint8_t *bitStream, int *bitLen, uint8_t *invert); +void pskCleanWave(uint8_t *bitStream, int bitLen); #endif diff --git a/traces/ATA5577-HIDemu-FC1-C9.pm3 b/traces/ATA5577-HIDemu-FC1-C9.pm3 new file mode 100644 index 000000000..7c0a878e8 --- /dev/null +++ b/traces/ATA5577-HIDemu-FC1-C9.pm3 @@ -0,0 +1,16000 @@ +69 +73 +35 +-4 +-36 +-64 +-86 +-106 +-46 +60 +74 +38 +3 +-31 +-58 +-82 +-101 +-102 +-41 +68 +86 +50 +14 +-22 +-50 +-75 +-96 +-113 +-34 +75 +92 +55 +19 +-17 +-46 +-72 +-92 +-111 +-31 +79 +96 +60 +23 +-14 +-43 +-70 +-91 +-109 +-28 +82 +99 +63 +26 +-12 +-42 +-68 +-89 +-108 +-25 +84 +101 +65 +28 +-10 +-40 +-67 +-88 +-107 +-25 +85 +102 +65 +28 +-10 +-40 +-67 +-88 +-107 +-24 +85 +103 +66 +29 +-9 +-40 +-66 +-88 +-107 +-24 +85 +102 +66 +29 +-9 +-40 +-66 +-88 +-106 +-25 +85 +102 +65 +28 +-10 +-40 +-67 +-88 +-16 +92 +98 +60 +16 +-18 +-48 +-73 +-19 +85 +88 +49 +8 +-26 +-55 +-78 +-26 +78 +82 +43 +3 +-30 +-59 +-81 +-30 +74 +77 +40 +-1 +-33 +-61 +-83 +-33 +71 +75 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-35 +69 +73 +35 +-2 +-34 +-62 +-85 +-104 +-104 +-45 +66 +81 +47 +10 +-23 +-53 +-77 +-98 +-98 +-36 +75 +90 +56 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +95 +61 +22 +-13 +-44 +-69 +-91 +-108 +-28 +83 +97 +63 +25 +-11 +-42 +-68 +-90 +-107 +-26 +85 +100 +65 +21 +-14 +-45 +-70 +-14 +90 +94 +55 +12 +-22 +-51 +-75 +-22 +82 +86 +47 +6 +-27 +-56 +-80 +-28 +77 +81 +42 +2 +-31 +-59 +-82 +-31 +74 +77 +40 +0 +-33 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-34 +70 +74 +37 +-3 +-35 +-63 +-85 +-34 +69 +74 +36 +-4 +-35 +-63 +-85 +-35 +68 +73 +35 +-4 +-36 +-64 +-86 +-35 +68 +73 +35 +-4 +-36 +-64 +-86 +-35 +68 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +69 +73 +35 +-5 +-36 +-64 +-86 +-36 +68 +72 +34 +-5 +-37 +-64 +-86 +-35 +69 +72 +34 +-5 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +72 +35 +-5 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +68 +72 +35 +-4 +-36 +-64 +-86 +-36 +68 +72 +34 +-5 +-36 +-64 +-86 +-35 +69 +73 +35 +-5 +-36 +-64 +-86 +-36 +68 +72 +34 +-4 +-36 +-64 +-86 +-36 +68 +72 +34 +-5 +-36 +-64 +-86 +-36 +68 +72 +35 +-3 +-35 +-63 +-85 +-105 +-104 +-46 +65 +80 +47 +10 +-24 +-53 +-77 +-98 +-98 +-37 +74 +89 +55 +17 +-17 +-48 +-72 +-94 +-111 +-32 +79 +94 +60 +21 +-14 +-45 +-70 +-92 +-109 +-29 +82 +96 +62 +24 +-12 +-43 +-68 +-90 +-108 +-28 +84 +98 +64 +25 +-11 +-42 +-68 +-90 +-107 +-27 +85 +99 +65 +26 +-10 +-42 +-67 +-89 +-107 +-26 +85 +100 +65 +26 +-10 +-41 +-67 +-89 +-107 +-26 +86 +99 +65 +26 +-10 +-41 +-67 +-89 +-106 +-26 +85 +100 +65 +26 +-10 +-42 +-67 +-89 +-106 +-26 +86 +100 +65 +27 +-9 +-41 +-67 +-89 +-106 +-26 +86 +100 +65 +26 +-10 +-41 +-67 +-89 +-106 +-26 +85 +99 +65 +26 +-10 +-41 +-67 +-89 +-106 +-26 +86 +100 +66 +26 +-10 +-41 +-67 +-89 +-106 +-26 +85 +100 +65 +26 +-9 +-41 +-67 +-89 +-106 +-26 +86 +100 +66 +22 +-13 +-44 +-69 +-13 +91 +94 +55 +12 +-22 +-52 +-76 +-22 +82 +85 +47 +6 +-27 +-56 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +68 +83 +49 +11 +-22 +-52 +-76 +-97 +-97 +-35 +76 +91 +57 +19 +-16 +-47 +-71 +-93 +-110 +-31 +81 +95 +61 +22 +-13 +-44 +-69 +-91 +-108 +-29 +82 +97 +63 +23 +-12 +-43 +-68 +-90 +-108 +-28 +83 +97 +63 +20 +-15 +-46 +-70 +-15 +89 +92 +54 +11 +-23 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +74 +78 +40 +0 +-32 +-61 +-83 +-32 +72 +77 +39 +-1 +-33 +-62 +-84 +-33 +72 +76 +37 +-2 +-34 +-62 +-85 +-104 +-43 +63 +78 +41 +6 +-28 +-56 +-80 +-100 +-101 +-38 +72 +89 +53 +17 +-19 +-48 +-74 +-94 +-112 +-32 +77 +94 +58 +21 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-90 +-18 +89 +97 +58 +15 +-19 +-49 +-73 +-20 +83 +86 +48 +7 +-27 +-56 +-79 +-26 +77 +81 +43 +2 +-30 +-59 +-82 +-30 +74 +78 +40 +0 +-33 +-61 +-83 +-33 +72 +76 +38 +-2 +-34 +-62 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-105 +-45 +62 +75 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +88 +51 +15 +-20 +-49 +-75 +-95 +-113 +-33 +76 +93 +57 +21 +-16 +-45 +-71 +-92 +-110 +-30 +80 +96 +61 +24 +-13 +-43 +-69 +-90 +-109 +-28 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-18 +90 +96 +58 +15 +-19 +-49 +-73 +-20 +84 +88 +48 +7 +-26 +-55 +-79 +-26 +78 +82 +43 +2 +-30 +-59 +-82 +-30 +75 +79 +40 +0 +-32 +-60 +-83 +-32 +72 +76 +37 +-2 +-34 +-62 +-85 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-35 +70 +75 +37 +-1 +-33 +-61 +-84 +-104 +-104 +-44 +67 +82 +48 +11 +-23 +-52 +-76 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-48 +-72 +-94 +-110 +-31 +80 +95 +61 +22 +-13 +-44 +-69 +-91 +-109 +-29 +83 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +84 +98 +64 +20 +-15 +-45 +-70 +-15 +89 +93 +54 +12 +-22 +-52 +-76 +-24 +81 +85 +46 +5 +-28 +-57 +-80 +-29 +75 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +36 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +68 +82 +49 +11 +-22 +-52 +-76 +-97 +-98 +-35 +75 +90 +57 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +94 +61 +22 +-13 +-44 +-69 +-91 +-109 +-29 +82 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +84 +98 +64 +21 +-15 +-45 +-70 +-14 +90 +94 +54 +12 +-22 +-52 +-76 +-22 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +2 +-31 +-59 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-2 +-35 +-63 +-85 +-105 +-44 +62 +77 +41 +6 +-29 +-56 +-81 +-100 +-101 +-38 +71 +89 +53 +17 +-19 +-48 +-74 +-94 +-112 +-32 +77 +95 +58 +21 +-16 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-18 +89 +96 +58 +15 +-19 +-49 +-74 +-20 +83 +87 +48 +7 +-27 +-56 +-79 +-27 +77 +81 +43 +2 +-31 +-59 +-82 +-30 +74 +77 +39 +-1 +-33 +-61 +-84 +-32 +72 +75 +37 +-3 +-34 +-62 +-85 +-33 +71 +74 +36 +-3 +-35 +-63 +-85 +-105 +-44 +61 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +71 +88 +51 +15 +-20 +-49 +-75 +-95 +-112 +-33 +76 +93 +58 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +60 +24 +-13 +-43 +-69 +-90 +-109 +-28 +81 +99 +62 +25 +-12 +-42 +-68 +-90 +-108 +-27 +82 +100 +63 +26 +-11 +-41 +-68 +-89 +-108 +-26 +83 +101 +63 +26 +-11 +-41 +-68 +-89 +-107 +-26 +83 +101 +64 +27 +-10 +-41 +-67 +-88 +-107 +-25 +84 +101 +64 +27 +-10 +-41 +-67 +-88 +-107 +-25 +83 +100 +64 +27 +-10 +-40 +-67 +-88 +-16 +92 +99 +59 +16 +-18 +-48 +-73 +-19 +85 +88 +49 +8 +-26 +-55 +-78 +-26 +78 +83 +44 +3 +-30 +-59 +-81 +-30 +75 +79 +41 +0 +-32 +-60 +-83 +-32 +72 +77 +38 +-2 +-34 +-62 +-84 +-34 +70 +75 +37 +-3 +-35 +-63 +-85 +-35 +69 +74 +36 +-3 +-35 +-63 +-85 +-35 +69 +74 +35 +-4 +-35 +-63 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +68 +73 +35 +-4 +-36 +-64 +-86 +-36 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +68 +72 +35 +-2 +-34 +-62 +-85 +-104 +-104 +-45 +66 +81 +48 +11 +-23 +-53 +-77 +-97 +-98 +-36 +75 +89 +56 +18 +-17 +-48 +-72 +-94 +-111 +-31 +80 +94 +60 +22 +-14 +-45 +-70 +-91 +-109 +-29 +82 +97 +63 +24 +-12 +-43 +-68 +-90 +-107 +-27 +84 +98 +64 +20 +-15 +-46 +-70 +-14 +89 +93 +54 +11 +-22 +-52 +-76 +-23 +81 +84 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +41 +1 +-32 +-60 +-83 +-31 +74 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +76 +38 +-2 +-34 +-62 +-85 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-44 +62 +77 +41 +6 +-28 +-56 +-80 +-100 +-101 +-38 +72 +89 +53 +17 +-19 +-48 +-74 +-94 +-112 +-32 +77 +95 +59 +22 +-15 +-44 +-70 +-91 +-109 +-29 +81 +98 +62 +25 +-13 +-42 +-69 +-90 +-108 +-27 +82 +99 +63 +26 +-12 +-42 +-68 +-89 +-17 +89 +97 +59 +16 +-19 +-49 +-73 +-19 +84 +87 +49 +7 +-26 +-55 +-79 +-26 +78 +82 +43 +3 +-30 +-59 +-81 +-30 +74 +79 +40 +0 +-32 +-60 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +70 +75 +37 +-3 +-35 +-63 +-85 +-105 +-45 +62 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +87 +51 +15 +-20 +-49 +-75 +-95 +-113 +-33 +76 +93 +57 +20 +-16 +-46 +-72 +-92 +-110 +-30 +79 +96 +60 +23 +-14 +-44 +-70 +-91 +-109 +-28 +81 +98 +61 +24 +-13 +-43 +-69 +-90 +-19 +89 +97 +58 +15 +-19 +-49 +-74 +-21 +83 +87 +48 +7 +-27 +-56 +-79 +-27 +77 +81 +43 +2 +-31 +-59 +-82 +-30 +74 +78 +40 +0 +-32 +-61 +-83 +-32 +72 +76 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +37 +-3 +-35 +-63 +-85 +-35 +69 +75 +37 +-1 +-33 +-61 +-84 +-104 +-104 +-44 +67 +82 +48 +11 +-23 +-53 +-77 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +94 +61 +22 +-13 +-44 +-69 +-91 +-108 +-29 +82 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +84 +98 +64 +20 +-15 +-45 +-70 +-15 +89 +93 +54 +11 +-23 +-52 +-76 +-23 +80 +84 +46 +5 +-28 +-57 +-80 +-29 +75 +80 +42 +1 +-31 +-60 +-82 +-31 +72 +77 +39 +-1 +-33 +-62 +-84 +-33 +71 +76 +38 +-2 +-34 +-62 +-85 +-34 +70 +74 +37 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +67 +82 +49 +12 +-22 +-52 +-76 +-97 +-97 +-35 +75 +90 +57 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +95 +61 +22 +-13 +-45 +-69 +-91 +-109 +-29 +82 +96 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +84 +98 +64 +20 +-15 +-45 +-70 +-14 +89 +93 +54 +12 +-22 +-52 +-76 +-22 +81 +86 +47 +6 +-27 +-56 +-80 +-27 +77 +81 +42 +2 +-31 +-59 +-82 +-30 +74 +77 +39 +-1 +-33 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-85 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-45 +62 +77 +40 +5 +-29 +-56 +-81 +-100 +-101 +-38 +70 +88 +52 +16 +-20 +-49 +-74 +-94 +-112 +-32 +77 +94 +58 +22 +-16 +-45 +-71 +-91 +-110 +-29 +80 +96 +60 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +63 +26 +-12 +-42 +-68 +-89 +-18 +89 +97 +59 +16 +-19 +-49 +-73 +-20 +84 +88 +48 +7 +-26 +-56 +-79 +-26 +78 +82 +43 +3 +-30 +-59 +-82 +-30 +75 +79 +41 +0 +-32 +-60 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +76 +37 +-2 +-34 +-62 +-85 +-104 +-44 +62 +77 +40 +6 +-29 +-56 +-81 +-100 +-101 +-38 +72 +89 +53 +17 +-19 +-48 +-74 +-94 +-112 +-32 +77 +94 +58 +22 +-15 +-45 +-71 +-91 +-110 +-29 +80 +98 +61 +25 +-13 +-43 +-69 +-90 +-108 +-27 +81 +99 +62 +25 +-12 +-42 +-68 +-89 +-18 +90 +97 +58 +15 +-19 +-49 +-74 +-20 +83 +86 +47 +6 +-27 +-56 +-79 +-27 +77 +81 +42 +2 +-31 +-59 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-34 +70 +74 +36 +-4 +-35 +-63 +-85 +-36 +68 +72 +34 +-5 +-36 +-64 +-86 +-37 +67 +72 +34 +-3 +-35 +-63 +-85 +-105 +-104 +-46 +65 +79 +47 +9 +-24 +-54 +-77 +-98 +-98 +-37 +74 +89 +55 +17 +-17 +-48 +-72 +-94 +-111 +-32 +80 +95 +61 +22 +-14 +-45 +-69 +-91 +-109 +-28 +83 +97 +64 +25 +-11 +-42 +-68 +-90 +-107 +-26 +86 +100 +66 +22 +-13 +-44 +-69 +-13 +91 +94 +55 +13 +-21 +-51 +-75 +-22 +83 +86 +47 +6 +-27 +-56 +-80 +-27 +77 +81 +43 +2 +-30 +-59 +-82 +-30 +74 +77 +40 +-1 +-33 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-85 +-34 +70 +74 +36 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +67 +82 +48 +11 +-23 +-53 +-76 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-48 +-72 +-94 +-111 +-32 +79 +94 +60 +21 +-14 +-45 +-70 +-92 +-109 +-30 +81 +96 +62 +23 +-12 +-43 +-69 +-91 +-108 +-28 +83 +97 +64 +20 +-15 +-46 +-70 +-15 +89 +93 +54 +11 +-22 +-52 +-76 +-23 +81 +85 +47 +5 +-28 +-57 +-80 +-27 +77 +80 +42 +1 +-31 +-60 +-82 +-30 +74 +78 +40 +0 +-33 +-61 +-83 +-32 +73 +77 +39 +-1 +-33 +-62 +-84 +-33 +71 +76 +37 +-2 +-34 +-62 +-85 +-104 +-44 +62 +77 +41 +6 +-28 +-56 +-80 +-99 +-101 +-38 +71 +88 +52 +16 +-19 +-49 +-74 +-94 +-112 +-32 +77 +95 +58 +21 +-16 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-90 +-108 +-26 +83 +100 +63 +26 +-11 +-41 +-68 +-89 +-108 +-26 +83 +101 +64 +27 +-11 +-41 +-68 +-89 +-107 +-25 +84 +101 +64 +27 +-11 +-41 +-67 +-89 +-107 +-25 +84 +101 +65 +27 +-11 +-41 +-67 +-88 +-107 +-25 +84 +101 +64 +27 +-11 +-41 +-67 +-89 +-17 +91 +98 +59 +16 +-18 +-48 +-73 +-19 +85 +88 +49 +8 +-26 +-55 +-78 +-26 +78 +82 +43 +3 +-30 +-58 +-81 +-30 +75 +78 +40 +0 +-32 +-60 +-83 +-32 +72 +75 +38 +-2 +-34 +-62 +-85 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-44 +62 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +88 +51 +16 +-20 +-49 +-74 +-95 +-112 +-33 +76 +93 +57 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +96 +60 +24 +-14 +-43 +-69 +-90 +-109 +-28 +81 +99 +62 +25 +-12 +-42 +-69 +-90 +-18 +89 +97 +59 +15 +-19 +-49 +-73 +-20 +83 +87 +48 +7 +-27 +-56 +-79 +-26 +78 +81 +43 +2 +-31 +-59 +-82 +-30 +74 +78 +40 +0 +-32 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-85 +-33 +71 +74 +36 +-3 +-35 +-63 +-85 +-34 +70 +75 +37 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-4 +-35 +-63 +-85 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +69 +73 +35 +-4 +-36 +-63 +-86 +-36 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +69 +72 +34 +-5 +-36 +-64 +-86 +-36 +69 +73 +35 +-2 +-34 +-62 +-85 +-105 +-104 +-45 +66 +81 +48 +10 +-23 +-53 +-77 +-98 +-98 +-36 +75 +90 +56 +18 +-17 +-48 +-72 +-94 +-111 +-31 +80 +94 +60 +21 +-14 +-45 +-70 +-92 +-109 +-29 +82 +97 +63 +24 +-12 +-43 +-68 +-90 +-107 +-27 +83 +98 +64 +20 +-15 +-46 +-70 +-14 +89 +93 +54 +11 +-23 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-83 +-33 +71 +75 +37 +-2 +-34 +-62 +-85 +-34 +70 +75 +37 +-3 +-35 +-63 +-85 +-105 +-45 +62 +77 +40 +5 +-29 +-56 +-81 +-100 +-101 +-38 +70 +88 +51 +16 +-20 +-49 +-74 +-95 +-112 +-33 +77 +94 +57 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +60 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-17 +90 +97 +59 +16 +-19 +-49 +-73 +-19 +84 +88 +49 +8 +-26 +-55 +-78 +-25 +79 +82 +44 +3 +-29 +-58 +-81 +-29 +76 +80 +42 +1 +-32 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-104 +-43 +63 +77 +40 +6 +-28 +-56 +-81 +-100 +-101 +-38 +71 +88 +52 +16 +-20 +-49 +-74 +-95 +-112 +-33 +77 +94 +57 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-18 +89 +96 +58 +15 +-19 +-49 +-73 +-20 +83 +87 +48 +7 +-26 +-56 +-79 +-27 +77 +81 +43 +2 +-31 +-59 +-82 +-30 +74 +78 +40 +0 +-32 +-61 +-83 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-35 +69 +74 +36 +-2 +-34 +-62 +-84 +-104 +-104 +-44 +66 +80 +47 +10 +-23 +-53 +-77 +-97 +-98 +-36 +75 +89 +56 +18 +-17 +-48 +-72 +-94 +-111 +-32 +80 +95 +60 +22 +-14 +-45 +-69 +-91 +-109 +-29 +82 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-28 +83 +98 +64 +20 +-15 +-45 +-70 +-15 +89 +92 +54 +11 +-22 +-52 +-76 +-23 +81 +85 +47 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +76 +37 +-2 +-34 +-62 +-85 +-34 +69 +74 +36 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +68 +82 +49 +11 +-22 +-52 +-76 +-97 +-97 +-36 +75 +90 +56 +18 +-17 +-47 +-72 +-94 +-110 +-31 +80 +94 +60 +22 +-14 +-45 +-69 +-91 +-109 +-29 +82 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +83 +98 +64 +20 +-15 +-45 +-70 +-15 +89 +93 +54 +12 +-22 +-52 +-76 +-23 +80 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-32 +72 +75 +37 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-105 +-45 +61 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +88 +52 +16 +-20 +-49 +-74 +-95 +-112 +-33 +77 +94 +58 +21 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +83 +100 +63 +26 +-11 +-41 +-68 +-89 +-17 +90 +97 +59 +16 +-19 +-49 +-73 +-19 +84 +88 +50 +8 +-26 +-55 +-78 +-26 +78 +83 +44 +3 +-30 +-58 +-81 +-29 +75 +79 +40 +0 +-32 +-60 +-83 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-3 +-35 +-62 +-85 +-105 +-44 +63 +77 +40 +6 +-28 +-56 +-81 +-100 +-101 +-39 +71 +88 +52 +16 +-19 +-49 +-74 +-94 +-112 +-33 +77 +94 +58 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-28 +82 +98 +62 +25 +-12 +-42 +-69 +-89 +-108 +-27 +82 +100 +63 +26 +-12 +-42 +-68 +-89 +-108 +-26 +82 +100 +64 +27 +-11 +-41 +-67 +-89 +-107 +-25 +83 +100 +63 +27 +-11 +-41 +-67 +-89 +-107 +-26 +83 +101 +65 +27 +-10 +-41 +-67 +-88 +-107 +-26 +84 +101 +64 +27 +-10 +-41 +-67 +-88 +-16 +91 +98 +59 +16 +-18 +-49 +-73 +-19 +85 +88 +48 +7 +-26 +-55 +-79 +-26 +78 +82 +43 +2 +-30 +-59 +-82 +-30 +74 +78 +40 +0 +-33 +-61 +-83 +-33 +72 +75 +37 +-3 +-34 +-62 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-35 +70 +74 +36 +-4 +-35 +-63 +-85 +-35 +69 +73 +35 +-4 +-36 +-63 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +69 +73 +35 +-4 +-36 +-63 +-86 +-35 +68 +73 +35 +-2 +-34 +-62 +-85 +-104 +-104 +-44 +66 +81 +47 +10 +-23 +-53 +-77 +-98 +-98 +-36 +75 +90 +56 +18 +-17 +-47 +-72 +-94 +-110 +-31 +80 +94 +60 +22 +-14 +-45 +-69 +-91 +-108 +-29 +82 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +84 +98 +64 +20 +-15 +-46 +-70 +-14 +89 +93 +54 +11 +-23 +-52 +-76 +-23 +81 +84 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +41 +1 +-31 +-60 +-82 +-31 +74 +77 +40 +-1 +-33 +-61 +-84 +-33 +72 +75 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +37 +-3 +-35 +-63 +-85 +-105 +-45 +62 +76 +40 +5 +-29 +-56 +-81 +-100 +-101 +-39 +70 +88 +52 +16 +-20 +-49 +-74 +-94 +-112 +-32 +77 +94 +58 +22 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +63 +25 +-12 +-42 +-68 +-89 +-17 +89 +97 +58 +15 +-19 +-49 +-73 +-19 +84 +87 +49 +7 +-26 +-55 +-79 +-26 +78 +82 +44 +3 +-30 +-58 +-81 +-30 +75 +78 +41 +0 +-32 +-60 +-83 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +76 +37 +-2 +-34 +-62 +-85 +-104 +-44 +63 +78 +41 +6 +-28 +-56 +-80 +-100 +-101 +-38 +72 +89 +53 +17 +-19 +-48 +-74 +-94 +-112 +-32 +77 +94 +58 +22 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +63 +26 +-12 +-42 +-68 +-89 +-17 +90 +97 +59 +16 +-19 +-49 +-73 +-19 +84 +87 +49 +7 +-26 +-55 +-79 +-26 +78 +82 +43 +3 +-30 +-58 +-81 +-30 +75 +79 +41 +0 +-32 +-60 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-35 +69 +73 +35 +-2 +-34 +-62 +-84 +-104 +-104 +-45 +66 +81 +47 +10 +-24 +-53 +-77 +-98 +-98 +-37 +74 +89 +55 +17 +-18 +-48 +-73 +-94 +-111 +-32 +79 +93 +59 +21 +-14 +-45 +-70 +-92 +-109 +-29 +82 +96 +62 +23 +-13 +-44 +-69 +-91 +-108 +-28 +83 +97 +63 +20 +-15 +-46 +-71 +-15 +89 +93 +53 +11 +-23 +-52 +-76 +-24 +81 +84 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +74 +77 +39 +-1 +-33 +-61 +-84 +-33 +72 +76 +38 +-2 +-34 +-62 +-85 +-34 +70 +74 +37 +-1 +-33 +-61 +-84 +-104 +-103 +-43 +68 +82 +49 +12 +-22 +-52 +-76 +-97 +-97 +-35 +76 +90 +57 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +94 +61 +22 +-13 +-44 +-69 +-91 +-109 +-29 +82 +96 +63 +24 +-12 +-43 +-68 +-90 +-108 +-28 +84 +98 +64 +20 +-15 +-45 +-70 +-15 +89 +93 +53 +11 +-23 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +72 +76 +37 +-2 +-34 +-62 +-85 +-34 +70 +75 +37 +-3 +-35 +-63 +-85 +-105 +-45 +61 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +88 +51 +15 +-20 +-49 +-75 +-95 +-113 +-32 +77 +94 +58 +22 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +63 +26 +-12 +-41 +-68 +-89 +-17 +91 +98 +60 +16 +-18 +-48 +-73 +-19 +85 +88 +49 +8 +-26 +-55 +-78 +-26 +78 +82 +43 +3 +-30 +-59 +-81 +-30 +75 +79 +41 +0 +-32 +-60 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-85 +-33 +71 +75 +37 +-2 +-34 +-62 +-85 +-105 +-44 +62 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +87 +52 +16 +-20 +-49 +-74 +-94 +-112 +-33 +77 +93 +57 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-17 +90 +98 +59 +16 +-19 +-49 +-73 +-19 +85 +88 +49 +7 +-26 +-55 +-79 +-26 +78 +83 +44 +3 +-30 +-59 +-81 +-29 +75 +79 +41 +1 +-32 +-60 +-83 +-32 +73 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-2 +-34 +-62 +-85 +-34 +71 +75 +37 +-1 +-33 +-61 +-84 +-104 +-103 +-43 +67 +82 +49 +12 +-22 +-52 +-76 +-97 +-97 +-35 +76 +90 +56 +18 +-17 +-48 +-72 +-94 +-110 +-31 +80 +94 +60 +22 +-14 +-45 +-70 +-91 +-109 +-29 +82 +96 +62 +23 +-12 +-43 +-69 +-91 +-108 +-28 +83 +97 +63 +20 +-15 +-46 +-71 +-16 +88 +91 +52 +10 +-24 +-53 +-77 +-25 +79 +83 +44 +4 +-29 +-58 +-81 +-30 +74 +77 +39 +-1 +-33 +-61 +-83 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-4 +-35 +-63 +-85 +-35 +69 +73 +35 +-2 +-34 +-62 +-85 +-104 +-104 +-44 +67 +81 +48 +11 +-23 +-52 +-76 +-97 +-98 +-35 +76 +91 +57 +19 +-16 +-47 +-71 +-93 +-110 +-30 +81 +96 +62 +24 +-12 +-43 +-69 +-91 +-108 +-27 +84 +99 +64 +26 +-10 +-42 +-67 +-89 +-107 +-27 +84 +99 +65 +22 +-14 +-44 +-69 +-14 +90 +94 +55 +12 +-22 +-51 +-75 +-23 +81 +85 +47 +6 +-27 +-56 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-105 +-46 +61 +75 +40 +5 +-29 +-57 +-81 +-100 +-102 +-40 +70 +87 +51 +15 +-21 +-49 +-75 +-95 +-113 +-33 +76 +93 +57 +21 +-16 +-46 +-72 +-92 +-110 +-29 +79 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +100 +63 +26 +-11 +-41 +-68 +-89 +-17 +91 +97 +59 +16 +-18 +-49 +-73 +-19 +85 +88 +49 +8 +-26 +-55 +-78 +-25 +79 +82 +44 +3 +-29 +-58 +-81 +-29 +75 +80 +41 +1 +-32 +-60 +-83 +-31 +73 +77 +39 +-1 +-33 +-62 +-84 +-33 +71 +75 +37 +-2 +-35 +-62 +-85 +-105 +-44 +62 +77 +40 +6 +-29 +-56 +-81 +-100 +-101 +-38 +71 +88 +52 +16 +-20 +-49 +-74 +-95 +-112 +-32 +77 +94 +58 +21 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +63 +25 +-12 +-42 +-68 +-89 +-17 +90 +97 +59 +16 +-19 +-49 +-73 +-20 +84 +88 +49 +7 +-26 +-55 +-79 +-27 +78 +82 +43 +3 +-30 +-59 +-82 +-30 +74 +78 +40 +-1 +-33 +-61 +-84 +-33 +72 +75 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +37 +-3 +-35 +-63 +-85 +-35 +70 +74 +37 +-1 +-33 +-62 +-84 +-104 +-103 +-44 +67 +82 +48 +11 +-23 +-53 +-77 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-48 +-72 +-94 +-111 +-31 +80 +94 +60 +21 +-14 +-45 +-70 +-92 +-109 +-29 +82 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +84 +98 +64 +25 +-11 +-42 +-67 +-90 +-107 +-27 +84 +98 +64 +25 +-11 +-42 +-67 +-90 +-107 +-27 +84 +98 +64 +25 +-11 +-42 +-67 +-89 +-107 +-27 +84 +99 +65 +26 +-10 +-42 +-67 +-89 +-107 +-27 +84 +98 +64 +26 +-10 +-42 +-67 +-89 +-107 +-26 +86 +100 +65 +21 +-14 +-45 +-70 +-13 +90 +93 +54 +12 +-22 +-52 +-76 +-23 +81 +85 +47 +5 +-28 +-57 +-80 +-28 +76 +81 +43 +2 +-31 +-59 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-35 +69 +74 +36 +-4 +-35 +-63 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-63 +-86 +-35 +68 +72 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-106 +-46 +61 +75 +39 +4 +-30 +-57 +-81 +-101 +-102 +-39 +70 +87 +51 +15 +-20 +-49 +-75 +-95 +-113 +-33 +77 +94 +57 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-18 +90 +97 +59 +16 +-19 +-49 +-73 +-20 +84 +87 +49 +7 +-26 +-55 +-79 +-26 +78 +82 +43 +3 +-30 +-59 +-81 +-30 +74 +79 +41 +0 +-32 +-60 +-83 +-32 +72 +76 +38 +-1 +-33 +-62 +-84 +-34 +70 +75 +37 +-3 +-35 +-63 +-85 +-105 +-44 +62 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +87 +51 +15 +-20 +-49 +-74 +-95 +-112 +-33 +76 +93 +57 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-108 +-27 +83 +99 +63 +26 +-11 +-41 +-68 +-89 +-108 +-25 +84 +101 +65 +27 +-10 +-41 +-67 +-88 +-107 +-25 +84 +101 +65 +28 +-10 +-40 +-67 +-88 +-107 +-25 +85 +101 +65 +28 +-10 +-40 +-66 +-88 +-107 +-24 +85 +102 +65 +27 +-10 +-40 +-67 +-88 +-107 +-25 +85 +101 +64 +27 +-10 +-41 +-67 +-88 +-16 +91 +98 +60 +16 +-18 +-48 +-73 +-19 +85 +88 +49 +7 +-26 +-55 +-78 +-26 +77 +81 +43 +3 +-30 +-59 +-81 +-30 +75 +79 +41 +0 +-32 +-60 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-35 +70 +74 +35 +-2 +-34 +-62 +-84 +-104 +-104 +-45 +67 +81 +48 +10 +-23 +-53 +-77 +-98 +-98 +-36 +75 +89 +56 +18 +-17 +-48 +-72 +-94 +-111 +-32 +80 +94 +60 +21 +-14 +-45 +-70 +-92 +-109 +-29 +82 +97 +62 +23 +-12 +-43 +-69 +-91 +-108 +-28 +83 +98 +64 +20 +-15 +-46 +-70 +-15 +89 +93 +53 +11 +-23 +-52 +-76 +-23 +80 +84 +46 +5 +-28 +-57 +-80 +-29 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +37 +-3 +-35 +-63 +-85 +-35 +70 +74 +36 +-4 +-35 +-63 +-85 +-35 +69 +74 +36 +-4 +-35 +-63 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +74 +35 +-4 +-36 +-63 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-5 +-36 +-64 +-86 +-36 +68 +72 +34 +-5 +-36 +-64 +-86 +-36 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +68 +72 +35 +-5 +-36 +-64 +-86 +-35 +69 +73 +35 +-5 +-36 +-64 +-86 +-35 +69 +72 +34 +-5 +-36 +-64 +-86 +-36 +68 +72 +35 +-4 +-36 +-64 +-86 +-35 +69 +74 +36 +-4 +-35 +-63 +-86 +-36 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +69 +72 +35 +-4 +-36 +-64 +-86 +-36 +69 +72 +35 +-2 +-34 +-63 +-85 +-105 +-104 +-45 +67 +81 +48 +10 +-23 +-53 +-77 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-47 +-72 +-93 +-110 +-31 +81 +95 +61 +22 +-13 +-44 +-69 +-91 +-109 +-28 +83 +97 +63 +24 +-11 +-43 +-68 +-90 +-107 +-27 +85 +99 +65 +26 +-10 +-42 +-67 +-89 +-107 +-26 +85 +100 +65 +26 +-10 +-41 +-67 +-89 +-106 +-26 +86 +100 +66 +27 +-9 +-41 +-66 +-89 +-106 +-26 +86 +100 +66 +27 +-9 +-41 +-66 +-89 +-106 +-26 +86 +100 +66 +26 +-10 +-41 +-67 +-89 +-106 +-26 +86 +100 +66 +27 +-9 +-41 +-66 +-89 +-106 +-26 +85 +99 +65 +26 +-10 +-41 +-67 +-89 +-106 +-26 +85 +99 +65 +26 +-10 +-42 +-67 +-89 +-106 +-26 +85 +99 +65 +26 +-10 +-42 +-67 +-89 +-107 +-26 +85 +99 +65 +26 +-10 +-42 +-67 +-89 +-107 +-26 +86 +100 +65 +21 +-14 +-45 +-70 +-14 +90 +94 +54 +12 +-22 +-52 +-76 +-22 +82 +85 +47 +6 +-27 +-56 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +72 +77 +39 +-1 +-33 +-61 +-84 +-33 +70 +74 +37 +-3 +-35 +-63 +-85 +-34 +69 +74 +36 +-1 +-33 +-62 +-84 +-104 +-104 +-44 +67 +81 +48 +11 +-23 +-53 +-76 +-97 +-98 +-36 +74 +89 +56 +18 +-17 +-48 +-72 +-94 +-111 +-31 +80 +94 +60 +22 +-14 +-45 +-69 +-91 +-109 +-29 +82 +96 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +84 +98 +64 +21 +-14 +-45 +-70 +-14 +89 +93 +54 +11 +-22 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +74 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +76 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-105 +-45 +62 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +87 +52 +16 +-20 +-49 +-74 +-94 +-112 +-32 +77 +94 +58 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +63 +26 +-12 +-42 +-68 +-89 +-17 +90 +97 +59 +16 +-19 +-49 +-73 +-20 +84 +88 +49 +7 +-26 +-55 +-79 +-26 +78 +81 +43 +2 +-31 +-59 +-82 +-30 +75 +78 +40 +0 +-33 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-45 +61 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +71 +88 +52 +16 +-20 +-49 +-74 +-94 +-112 +-33 +77 +94 +58 +21 +-16 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-108 +-27 +82 +99 +63 +26 +-12 +-42 +-68 +-89 +-17 +90 +97 +59 +16 +-19 +-49 +-73 +-20 +85 +88 +49 +8 +-26 +-55 +-78 +-26 +79 +82 +43 +3 +-30 +-59 +-81 +-29 +75 +80 +41 +1 +-32 +-60 +-83 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +72 +76 +38 +-2 +-34 +-62 +-85 +-34 +71 +75 +37 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +67 +82 +49 +11 +-22 +-52 +-76 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +95 +61 +22 +-13 +-44 +-69 +-91 +-108 +-29 +83 +97 +63 +24 +-12 +-43 +-68 +-90 +-107 +-27 +85 +98 +64 +20 +-15 +-46 +-70 +-15 +89 +93 +54 +12 +-22 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-29 +75 +79 +41 +1 +-32 +-60 +-83 +-31 +73 +77 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-35 +69 +73 +35 +-2 +-34 +-62 +-84 +-104 +-104 +-45 +66 +81 +47 +10 +-23 +-53 +-77 +-98 +-98 +-36 +75 +89 +56 +17 +-17 +-48 +-72 +-94 +-111 +-32 +79 +94 +60 +21 +-14 +-45 +-70 +-92 +-109 +-29 +82 +96 +62 +24 +-12 +-43 +-68 +-90 +-108 +-28 +83 +98 +64 +20 +-15 +-45 +-70 +-15 +89 +93 +54 +11 +-23 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-32 +72 +75 +37 +-3 +-35 +-62 +-85 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-45 +62 +76 +40 +5 +-30 +-57 +-81 +-100 +-102 +-39 +70 +88 +52 +16 +-20 +-49 +-74 +-95 +-112 +-33 +77 +94 +58 +21 +-16 +-45 +-71 +-91 +-110 +-29 +80 +97 +60 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-17 +90 +97 +58 +15 +-19 +-49 +-73 +-20 +84 +88 +49 +7 +-26 +-55 +-79 +-26 +78 +82 +43 +3 +-30 +-58 +-81 +-30 +75 +78 +40 +0 +-32 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +70 +75 +37 +-3 +-35 +-63 +-85 +-105 +-45 +62 +77 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +88 +52 +16 +-20 +-49 +-74 +-94 +-112 +-32 +77 +94 +58 +22 +-15 +-45 +-71 +-91 +-110 +-28 +81 +98 +61 +24 +-13 +-43 +-69 +-90 +-108 +-27 +82 +100 +63 +26 +-11 +-41 +-68 +-89 +-108 +-26 +84 +101 +64 +27 +-11 +-41 +-67 +-88 +-107 +-25 +83 +100 +64 +27 +-11 +-41 +-67 +-88 +-107 +-25 +84 +101 +64 +27 +-10 +-40 +-67 +-88 +-107 +-25 +84 +102 +65 +27 +-10 +-41 +-67 +-88 +-107 +-25 +84 +101 +64 +27 +-10 +-41 +-67 +-88 +-16 +91 +98 +60 +16 +-18 +-48 +-73 +-19 +85 +88 +49 +7 +-26 +-55 +-78 +-26 +78 +82 +43 +3 +-30 +-59 +-81 +-30 +75 +79 +40 +0 +-32 +-60 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-35 +70 +74 +36 +-3 +-35 +-63 +-85 +-35 +69 +74 +36 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-4 +-35 +-63 +-85 +-35 +69 +73 +35 +-4 +-36 +-63 +-86 +-35 +68 +73 +35 +-2 +-34 +-62 +-84 +-104 +-104 +-45 +67 +81 +47 +10 +-24 +-53 +-77 +-98 +-98 +-36 +74 +89 +56 +17 +-17 +-48 +-72 +-94 +-111 +-32 +79 +93 +60 +21 +-14 +-45 +-70 +-92 +-109 +-30 +81 +96 +62 +23 +-13 +-44 +-69 +-91 +-108 +-29 +82 +96 +62 +19 +-16 +-47 +-71 +-16 +87 +91 +52 +10 +-24 +-53 +-77 +-25 +79 +83 +44 +3 +-29 +-58 +-81 +-30 +75 +78 +40 +0 +-33 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-34 +70 +74 +37 +-3 +-35 +-63 +-85 +-34 +70 +74 +37 +-3 +-35 +-63 +-85 +-105 +-44 +63 +77 +41 +6 +-28 +-56 +-81 +-100 +-101 +-38 +71 +89 +53 +17 +-19 +-48 +-73 +-94 +-112 +-31 +78 +96 +60 +23 +-14 +-44 +-70 +-91 +-109 +-28 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-108 +-27 +83 +100 +63 +26 +-11 +-41 +-68 +-89 +-17 +91 +98 +59 +16 +-19 +-49 +-73 +-19 +84 +87 +49 +7 +-26 +-55 +-79 +-26 +78 +81 +43 +2 +-30 +-59 +-82 +-30 +74 +78 +40 +-1 +-33 +-61 +-83 +-33 +71 +75 +37 +-2 +-34 +-62 +-85 +-34 +69 +74 +36 +-4 +-35 +-63 +-85 +-105 +-46 +61 +76 +40 +5 +-29 +-57 +-81 +-100 +-102 +-39 +70 +87 +51 +15 +-21 +-49 +-75 +-95 +-113 +-33 +77 +94 +58 +22 +-15 +-45 +-71 +-91 +-110 +-29 +80 +98 +62 +25 +-12 +-42 +-69 +-90 +-108 +-26 +83 +100 +63 +27 +-11 +-41 +-68 +-89 +-17 +91 +98 +60 +16 +-18 +-48 +-73 +-19 +84 +88 +49 +8 +-25 +-55 +-78 +-26 +78 +82 +44 +3 +-29 +-58 +-81 +-29 +75 +80 +41 +1 +-32 +-60 +-83 +-32 +72 +77 +38 +-2 +-34 +-62 +-84 +-33 +71 +76 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +37 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +67 +82 +48 +11 +-23 +-53 +-76 +-97 +-98 +-36 +75 +89 +56 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +95 +61 +22 +-14 +-45 +-70 +-91 +-109 +-29 +82 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +84 +99 +64 +20 +-15 +-45 +-70 +-15 +88 +93 +54 +11 +-23 +-52 +-76 +-24 +80 +84 +46 +5 +-28 +-57 +-80 +-29 +75 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +67 +82 +48 +11 +-23 +-52 +-76 +-97 +-98 +-35 +75 +90 +56 +18 +-17 +-48 +-72 +-94 +-110 +-31 +80 +94 +60 +22 +-14 +-45 +-69 +-91 +-109 +-29 +82 +97 +62 +23 +-12 +-43 +-68 +-90 +-108 +-28 +83 +98 +63 +20 +-15 +-46 +-71 +-16 +89 +93 +53 +11 +-23 +-52 +-76 +-23 +80 +84 +46 +5 +-28 +-57 +-80 +-28 +75 +80 +41 +1 +-32 +-60 +-83 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-34 +70 +75 +37 +-3 +-35 +-63 +-85 +-105 +-45 +62 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +71 +88 +52 +16 +-20 +-49 +-74 +-94 +-112 +-33 +77 +94 +58 +22 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-108 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-17 +90 +97 +59 +16 +-19 +-49 +-73 +-20 +84 +88 +49 +7 +-26 +-55 +-79 +-27 +77 +82 +43 +3 +-30 +-59 +-81 +-30 +74 +78 +40 +0 +-32 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-85 +-34 +70 +74 +37 +-3 +-35 +-63 +-85 +-105 +-45 +62 +76 +40 +5 +-29 +-56 +-81 +-100 +-101 +-39 +71 +88 +52 +16 +-20 +-49 +-74 +-94 +-112 +-32 +77 +94 +57 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-108 +-27 +82 +99 +63 +26 +-12 +-42 +-68 +-89 +-17 +90 +97 +59 +15 +-19 +-49 +-73 +-20 +84 +88 +49 +8 +-26 +-55 +-79 +-26 +78 +82 +43 +3 +-30 +-59 +-81 +-30 +75 +79 +41 +0 +-32 +-60 +-83 +-32 +72 +76 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-35 +69 +74 +36 +-2 +-34 +-62 +-84 +-104 +-104 +-45 +67 +82 +48 +11 +-23 +-53 +-77 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-47 +-72 +-93 +-110 +-31 +81 +95 +61 +22 +-13 +-44 +-69 +-91 +-108 +-28 +83 +98 +64 +25 +-11 +-42 +-67 +-90 +-107 +-26 +86 +100 +65 +21 +-14 +-45 +-70 +-14 +90 +94 +55 +12 +-22 +-52 +-75 +-22 +82 +86 +47 +6 +-27 +-56 +-80 +-28 +76 +81 +42 +2 +-31 +-59 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-3 +-35 +-62 +-85 +-34 +69 +74 +36 +-1 +-33 +-62 +-84 +-104 +-104 +-45 +67 +82 +48 +11 +-23 +-52 +-76 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-47 +-72 +-93 +-111 +-32 +79 +94 +60 +22 +-14 +-45 +-69 +-91 +-109 +-29 +82 +96 +62 +24 +-12 +-43 +-68 +-90 +-108 +-28 +83 +98 +64 +20 +-15 +-46 +-70 +-15 +89 +92 +54 +11 +-23 +-52 +-76 +-24 +80 +84 +46 +4 +-28 +-57 +-80 +-28 +76 +80 +41 +1 +-32 +-60 +-83 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-3 +-35 +-62 +-85 +-35 +69 +74 +36 +-3 +-35 +-63 +-85 +-105 +-45 +61 +75 +40 +5 +-29 +-57 +-81 +-100 +-102 +-39 +71 +87 +51 +16 +-20 +-49 +-74 +-95 +-112 +-33 +77 +95 +58 +22 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +63 +25 +-12 +-42 +-68 +-89 +-108 +-26 +83 +100 +63 +27 +-11 +-41 +-68 +-89 +-107 +-26 +83 +101 +64 +27 +-11 +-41 +-67 +-88 +-107 +-25 +84 +101 +64 +27 +-10 +-41 +-67 +-88 +-107 +-25 +84 +101 +64 +27 +-10 +-41 +-67 +-88 +-107 +-26 +83 +101 +64 +27 +-10 +-41 +-67 +-88 +-17 +91 +98 +60 +16 +-18 +-48 +-73 +-19 +85 +88 +49 +8 +-26 +-55 +-78 +-26 +78 +82 +43 +2 +-30 +-59 +-82 +-30 +74 +79 +40 +0 +-32 +-60 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-34 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-44 +62 +77 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +71 +88 +52 +16 +-20 +-49 +-74 +-95 +-112 +-32 +77 +94 +58 +22 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +60 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +62 +26 +-12 +-42 +-68 +-89 +-17 +90 +97 +59 +16 +-19 +-49 +-73 +-19 +85 +88 +49 +8 +-26 +-55 +-78 +-26 +78 +83 +44 +3 +-30 +-58 +-81 +-30 +75 +79 +41 +0 +-32 +-60 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-2 +-34 +-62 +-85 +-34 +71 +75 +37 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-4 +-35 +-63 +-86 +-35 +69 +73 +35 +-4 +-36 +-63 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +68 +72 +35 +-3 +-35 +-63 +-85 +-105 +-104 +-45 +66 +81 +47 +10 +-24 +-53 +-77 +-98 +-98 +-36 +75 +89 +55 +17 +-17 +-48 +-72 +-94 +-111 +-31 +79 +94 +60 +21 +-14 +-45 +-70 +-91 +-109 +-29 +82 +97 +62 +23 +-12 +-44 +-69 +-91 +-108 +-28 +83 +97 +63 +20 +-15 +-46 +-70 +-14 +89 +93 +53 +11 +-23 +-52 +-76 +-23 +81 +84 +46 +5 +-28 +-57 +-80 +-28 +75 +80 +41 +1 +-32 +-60 +-83 +-31 +73 +77 +38 +-1 +-33 +-62 +-84 +-33 +71 +74 +37 +-3 +-35 +-63 +-85 +-35 +70 +74 +36 +-3 +-35 +-63 +-85 +-105 +-45 +61 +76 +39 +5 +-30 +-57 +-81 +-100 +-102 +-39 +70 +87 +51 +16 +-20 +-49 +-74 +-95 +-112 +-32 +77 +94 +58 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +96 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +100 +63 +26 +-12 +-42 +-68 +-89 +-17 +90 +97 +59 +16 +-19 +-49 +-73 +-19 +84 +88 +49 +7 +-26 +-55 +-79 +-26 +78 +81 +43 +3 +-30 +-59 +-82 +-30 +75 +78 +40 +0 +-32 +-61 +-83 +-32 +72 +75 +37 +-2 +-34 +-62 +-85 +-33 +70 +74 +36 +-3 +-35 +-63 +-85 +-105 +-45 +61 +77 +40 +5 +-29 +-56 +-81 +-100 +-101 +-39 +71 +88 +52 +16 +-20 +-49 +-74 +-94 +-112 +-33 +77 +94 +57 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-108 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-18 +89 +97 +59 +15 +-19 +-49 +-73 +-20 +84 +87 +49 +7 +-26 +-55 +-79 +-26 +78 +82 +43 +3 +-30 +-59 +-81 +-30 +75 +79 +40 +0 +-32 +-60 +-83 +-33 +72 +76 +38 +-2 +-34 +-62 +-84 +-34 +70 +75 +37 +-3 +-35 +-63 +-85 +-35 +70 +74 +36 +-1 +-33 +-61 +-84 +-104 +-104 +-44 +67 +81 +48 +11 +-23 +-53 +-76 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +95 +61 +22 +-14 +-45 +-70 +-91 +-109 +-29 +83 +97 +64 +24 +-11 +-43 +-68 +-90 +-107 +-27 +85 +99 +65 +21 +-14 +-45 +-70 +-14 +90 +93 +55 +12 +-22 +-52 +-75 +-22 +82 +85 +47 +5 +-27 +-56 +-80 +-27 +77 +81 +43 +2 +-31 +-59 +-82 +-30 +74 +78 +40 +0 +-33 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +70 +75 +37 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +68 +82 +49 +12 +-22 +-52 +-76 +-97 +-97 +-35 +76 +91 +57 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +95 +61 +22 +-13 +-44 +-69 +-91 +-109 +-29 +83 +97 +63 +24 +-12 +-43 +-68 +-90 +-107 +-28 +84 +98 +64 +20 +-15 +-45 +-70 +-15 +89 +93 +54 +11 +-23 +-52 +-76 +-24 +81 +84 +46 +5 +-28 +-57 +-80 +-29 +75 +79 +41 +0 +-32 +-60 +-83 +-32 +72 +76 +38 +-1 +-34 +-62 +-84 +-33 +70 +74 +36 +-3 +-35 +-63 +-85 +-34 +69 +73 +35 +-4 +-35 +-63 +-85 +-105 +-45 +61 +75 +39 +5 +-30 +-57 +-81 +-101 +-102 +-40 +70 +88 +52 +15 +-20 +-49 +-75 +-95 +-113 +-33 +77 +94 +57 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +60 +24 +-13 +-43 +-69 +-90 +-109 +-28 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-18 +90 +97 +59 +16 +-19 +-49 +-73 +-20 +84 +88 +49 +8 +-26 +-55 +-78 +-26 +78 +82 +43 +3 +-30 +-59 +-81 +-30 +75 +79 +40 +0 +-32 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +70 +74 +36 +-3 +-35 +-63 +-85 +-105 +-45 +61 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +71 +88 +52 +16 +-20 +-49 +-74 +-95 +-112 +-32 +77 +94 +58 +21 +-16 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +62 +26 +-12 +-42 +-68 +-89 +-108 +-26 +83 +100 +64 +27 +-11 +-41 +-68 +-89 +-107 +-25 +84 +101 +63 +27 +-11 +-41 +-68 +-89 +-107 +-25 +84 +101 +64 +27 +-11 +-41 +-67 +-88 +-107 +-25 +84 +101 +64 +27 +-11 +-41 +-67 +-88 +-107 +-25 +84 +101 +64 +27 +-11 +-41 +-67 +-88 +-16 +91 +98 +60 +17 +-18 +-48 +-73 +-19 +85 +89 +50 +8 +-25 +-55 +-78 +-25 +79 +82 +44 +3 +-29 +-58 +-81 +-29 +75 +80 +41 +1 +-32 +-60 +-83 +-31 +73 +77 +39 +-1 +-33 +-62 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-34 +71 +75 +37 +-3 +-35 +-63 +-85 +-35 +69 +74 +36 +-4 +-35 +-63 +-86 +-35 +69 +74 +36 +-4 +-35 +-63 +-85 +-36 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +68 +72 +35 +-4 +-36 +-64 +-86 +-36 +68 +72 +35 +-4 +-36 +-64 +-86 +-36 +68 +72 +35 +-2 +-34 +-62 +-85 +-105 +-104 +-45 +66 +81 +47 +10 +-23 +-53 +-77 +-98 +-98 +-36 +75 +89 +56 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +95 +61 +22 +-14 +-45 +-69 +-91 +-109 +-28 +82 +97 +63 +24 +-11 +-43 +-68 +-90 +-107 +-27 +84 +98 +65 +21 +-14 +-45 +-70 +-14 +90 +94 +54 +12 +-22 +-52 +-76 +-22 +82 +86 +47 +6 +-27 +-56 +-80 +-27 +77 +81 +43 +2 +-31 +-59 +-82 +-30 +74 +77 +40 +-1 +-33 +-61 +-83 +-32 +72 +76 +37 +-2 +-34 +-62 +-85 +-34 +70 +75 +36 +-3 +-35 +-63 +-85 +-105 +-45 +61 +76 +39 +4 +-30 +-57 +-81 +-101 +-102 +-39 +70 +87 +51 +15 +-21 +-49 +-75 +-95 +-113 +-34 +76 +93 +56 +20 +-17 +-46 +-72 +-92 +-110 +-31 +77 +94 +58 +22 +-15 +-45 +-71 +-91 +-110 +-30 +80 +97 +60 +23 +-14 +-43 +-70 +-91 +-20 +88 +95 +56 +14 +-20 +-50 +-74 +-21 +83 +86 +47 +6 +-27 +-56 +-79 +-27 +77 +81 +43 +2 +-31 +-59 +-82 +-30 +74 +79 +40 +0 +-32 +-60 +-83 +-32 +72 +77 +39 +-1 +-33 +-62 +-84 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-104 +-43 +63 +78 +42 +7 +-28 +-55 +-80 +-99 +-100 +-37 +72 +90 +53 +17 +-19 +-48 +-74 +-94 +-112 +-32 +77 +95 +59 +22 +-14 +-44 +-70 +-91 +-109 +-29 +80 +97 +61 +25 +-13 +-42 +-69 +-90 +-108 +-27 +82 +99 +63 +26 +-12 +-42 +-68 +-89 +-17 +90 +97 +58 +15 +-19 +-49 +-73 +-20 +83 +86 +47 +6 +-27 +-56 +-79 +-27 +77 +81 +42 +2 +-31 +-59 +-82 +-31 +74 +78 +40 +0 +-33 +-61 +-83 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-4 +-35 +-63 +-85 +-35 +70 +74 +36 +-1 +-33 +-62 +-84 +-104 +-104 +-44 +67 +82 +49 +11 +-22 +-52 +-76 +-97 +-98 +-35 +76 +90 +56 +18 +-17 +-47 +-72 +-93 +-110 +-30 +81 +95 +62 +23 +-13 +-44 +-69 +-91 +-108 +-28 +83 +98 +64 +25 +-11 +-42 +-67 +-90 +-107 +-26 +85 +100 +65 +22 +-14 +-45 +-69 +-14 +90 +94 +54 +12 +-22 +-51 +-75 +-23 +81 +85 +47 +6 +-27 +-56 +-80 +-28 +77 +80 +42 +1 +-31 +-60 +-82 +-31 +74 +77 +39 +-1 +-33 +-61 +-84 +-32 +72 +75 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +36 +-1 +-33 +-62 +-84 +-104 +-104 +-44 +68 +82 +49 +11 +-22 +-52 +-76 +-97 +-98 +-35 +75 +90 +56 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +95 +61 +22 +-13 +-44 +-69 +-91 +-108 +-29 +82 +96 +63 +24 +-12 +-43 +-68 +-90 +-108 +-28 +83 +98 +63 +20 +-15 +-46 +-70 +-15 +89 +92 +54 +11 +-23 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +74 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +76 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-105 +-45 +62 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +88 +52 +16 +-20 +-49 +-74 +-95 +-112 +-33 +76 +93 +57 +20 +-16 +-45 +-71 +-92 +-110 +-30 +80 +97 +60 +23 +-14 +-44 +-70 +-91 +-109 +-28 +82 +99 +62 +25 +-12 +-42 +-68 +-90 +-18 +89 +97 +58 +15 +-19 +-49 +-74 +-20 +84 +87 +48 +7 +-27 +-56 +-79 +-26 +77 +82 +43 +2 +-31 +-59 +-82 +-30 +74 +78 +40 +0 +-33 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-44 +62 +76 +40 +6 +-29 +-56 +-81 +-100 +-101 +-39 +71 +88 +52 +16 +-20 +-49 +-74 +-94 +-112 +-32 +77 +94 +58 +21 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +63 +26 +-12 +-42 +-68 +-89 +-18 +89 +97 +59 +15 +-19 +-49 +-73 +-20 +84 +87 +49 +7 +-26 +-55 +-79 +-26 +78 +82 +43 +2 +-30 +-59 +-82 +-30 +74 +78 +40 +0 +-32 +-60 +-83 +-33 +72 +76 +38 +-2 +-34 +-62 +-84 +-34 +70 +75 +37 +-3 +-35 +-63 +-85 +-35 +70 +74 +36 +-1 +-33 +-62 +-84 +-104 +-104 +-45 +67 +82 +48 +11 +-23 +-53 +-77 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +95 +61 +22 +-13 +-44 +-69 +-91 +-109 +-28 +83 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +84 +99 +65 +21 +-14 +-45 +-70 +-14 +89 +94 +54 +12 +-22 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +75 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +76 +38 +-1 +-34 +-62 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-35 +69 +74 +36 +-1 +-33 +-61 +-84 +-104 +-103 +-43 +68 +83 +49 +12 +-22 +-52 +-76 +-97 +-97 +-35 +76 +91 +57 +19 +-16 +-47 +-71 +-93 +-110 +-30 +82 +96 +62 +23 +-12 +-44 +-69 +-91 +-108 +-27 +83 +98 +64 +25 +-11 +-42 +-67 +-90 +-107 +-27 +85 +99 +65 +21 +-14 +-45 +-70 +-14 +90 +93 +54 +12 +-22 +-52 +-76 +-22 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-105 +-45 +62 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +88 +52 +15 +-20 +-49 +-75 +-95 +-97 +-32 +77 +94 +57 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +60 +24 +-13 +-43 +-69 +-90 +-109 +-28 +81 +98 +62 +25 +-12 +-42 +-68 +-90 +-18 +89 +97 +58 +15 +-19 +-49 +-73 +-21 +83 +87 +48 +7 +-27 +-56 +-79 +-27 +77 +81 +43 +2 +-31 +-59 +-82 +-30 +74 +77 +40 +0 +-33 +-61 +-83 +-33 +72 +76 +38 +-2 +-34 +-62 +-85 +-34 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-45 +62 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +71 +88 +52 +16 +-20 +-49 +-74 +-95 +-112 +-33 +77 +94 +58 +21 +-16 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-108 +-27 +82 +99 +62 +26 +-12 +-42 +-68 +-89 +-17 +90 +97 +59 +15 +-19 +-49 +-73 +-20 +84 +87 +49 +7 +-26 +-55 +-79 +-27 +78 +82 +43 +3 +-30 +-59 +-82 +-30 +75 +79 +40 +0 +-32 +-60 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-85 +-33 +70 +74 +37 +-3 +-35 +-63 +-85 +-35 +70 +74 +37 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +67 +81 +48 +11 +-23 +-53 +-76 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-48 +-72 +-94 +-111 +-31 +80 +94 +60 +22 +-14 +-45 +-69 +-92 +-109 +-29 +83 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +84 +99 +64 +25 +-11 +-42 +-67 +-90 +-107 +-27 +84 +99 +65 +26 +-10 +-42 +-67 +-89 +-107 +-27 +85 +99 +65 +26 +-10 +-42 +-67 +-89 +-107 +-26 +86 +100 +65 +26 +-10 +-41 +-67 +-89 +-106 +-26 +85 +100 +66 +27 +-9 +-41 +-67 +-89 +-106 +-26 +86 +100 +66 +22 +-14 +-45 +-69 +-13 +90 +94 +55 +12 +-22 +-51 +-75 +-22 +82 +86 +47 +6 +-27 +-56 +-79 +-27 +77 +81 +43 +2 +-30 +-59 +-82 +-30 +74 +77 +40 +0 +-32 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-3 +-34 +-63 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-35 +69 +74 +36 +-4 +-35 +-63 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-5 +-36 +-64 +-86 +-35 +69 +72 +35 +-4 +-36 +-64 +-86 +-36 +68 +72 +34 +-5 +-36 +-64 +-86 +-106 +-46 +60 +75 +39 +4 +-30 +-58 +-82 +-101 +-102 +-40 +70 +87 +51 +15 +-21 +-49 +-75 +-95 +-97 +-33 +77 +93 +57 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +60 +24 +-13 +-43 +-69 +-90 +-109 +-28 +81 +99 +62 +25 +-12 +-42 +-68 +-89 +-18 +89 +97 +58 +15 +-19 +-49 +-74 +-20 +83 +87 +48 +7 +-26 +-55 +-79 +-27 +77 +81 +43 +2 +-31 +-59 +-82 +-31 +74 +77 +40 +-1 +-33 +-61 +-84 +-33 +72 +75 +37 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-105 +-45 +61 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +88 +52 +16 +-20 +-49 +-74 +-95 +-112 +-33 +77 +94 +58 +21 +-16 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-108 +-27 +82 +99 +63 +26 +-12 +-42 +-68 +-89 +-108 +-26 +83 +100 +63 +27 +-11 +-41 +-68 +-89 +-107 +-26 +83 +100 +64 +27 +-11 +-41 +-68 +-88 +-107 +-26 +84 +101 +64 +27 +-10 +-41 +-67 +-88 +-107 +-25 +84 +100 +64 +27 +-10 +-41 +-67 +-88 +-107 +-26 +83 +101 +65 +27 +-10 +-40 +-67 +-88 +-16 +91 +98 +60 +17 +-18 +-48 +-73 +-19 +85 +88 +49 +7 +-26 +-55 +-78 +-26 +78 +82 +43 +3 +-30 +-59 +-81 +-30 +75 +79 +41 +0 +-32 +-60 +-83 +-32 +72 +77 +38 +-2 +-34 +-62 +-84 +-34 +70 +75 +37 +-3 +-35 +-63 +-85 +-35 +70 +74 +36 +-1 +-33 +-62 +-84 +-104 +-103 +-44 +67 +82 +48 +11 +-23 +-52 +-76 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-47 +-72 +-93 +-110 +-32 +80 +95 +61 +22 +-13 +-44 +-69 +-91 +-109 +-29 +82 +97 +62 +24 +-12 +-43 +-68 +-90 +-108 +-27 +85 +99 +65 +21 +-14 +-45 +-70 +-14 +89 +93 +53 +11 +-23 +-52 +-76 +-22 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +77 +81 +43 +2 +-31 +-59 +-82 +-30 +74 +77 +39 +-1 +-33 +-61 +-84 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +38 +-2 +-34 +-62 +-85 +-34 +70 +75 +37 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-34 +69 +74 +36 +-4 +-35 +-63 +-86 +-35 +69 +74 +35 +-4 +-36 +-63 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +68 +72 +35 +-4 +-36 +-64 +-86 +-36 +68 +72 +34 +-5 +-36 +-64 +-86 +-36 +68 +72 +34 +-5 +-37 +-64 +-86 +-36 +68 +71 +33 +-6 +-37 +-65 +-87 +-37 +67 +72 +33 +-6 +-37 +-65 +-87 +-37 +68 +72 +34 +-5 +-37 +-64 +-86 +-37 +68 +72 +33 +-5 +-37 +-65 +-87 +-37 +68 +72 +34 +-5 +-37 +-64 +-86 +-36 +68 +73 +35 +-3 +-35 +-62 +-85 +-105 +-104 +-45 +65 +80 +47 +10 +-24 +-53 +-77 +-98 +-98 +-37 +74 +89 +56 +17 +-17 +-48 +-72 +-94 +-111 +-31 +80 +94 +60 +22 +-14 +-45 +-69 +-92 +-109 +-29 +83 +97 +63 +24 +-12 +-43 +-68 +-90 +-107 +-27 +85 +99 +64 +25 +-10 +-42 +-67 +-89 +-107 +-27 +85 +100 +65 +26 +-10 +-41 +-67 +-89 +-106 +-26 +85 +99 +65 +26 +-10 +-42 +-67 +-89 +-107 +-26 +85 +99 +65 +26 +-10 +-42 +-67 +-89 +-107 +-27 +85 +99 +65 +26 +-10 +-42 +-67 +-89 +-106 +-26 +85 +100 +65 +26 +-10 +-41 +-67 +-89 +-106 +-26 +85 +100 +65 +26 +-10 +-41 +-67 +-89 +-106 +-26 +86 +100 +65 +26 +-10 +-41 +-67 +-89 +-106 +-26 +86 +100 +65 +26 +-10 +-41 +-67 +-89 +-106 +-26 +86 +100 +65 +26 +-10 +-41 +-67 +-89 +-106 +-26 +86 +100 +66 +22 +-13 +-44 +-69 +-14 +90 +94 +55 +12 +-22 +-52 +-75 +-22 +81 +84 +46 +5 +-28 +-57 +-80 +-28 +77 +81 +42 +2 +-31 +-59 +-82 +-30 +74 +77 +39 +-1 +-33 +-61 +-84 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +0 +-33 +-61 +-84 +-104 +-103 +-43 +68 +83 +49 +12 +-22 +-52 +-76 +-97 +-97 +-35 +76 +90 +57 +19 +-16 +-47 +-71 +-93 +-110 +-30 +81 +95 +61 +22 +-13 +-44 +-69 +-91 +-108 +-28 +83 +97 +63 +24 +-11 +-43 +-68 +-90 +-107 +-27 +84 +98 +64 +20 +-15 +-46 +-70 +-14 +90 +93 +54 +12 +-22 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +41 +1 +-32 +-60 +-83 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +72 +75 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-105 +-45 +62 +77 +40 +5 +-29 +-57 +-81 +-100 +-101 +-38 +71 +88 +52 +16 +-20 +-49 +-74 +-94 +-112 +-32 +77 +95 +58 +22 +-15 +-45 +-71 +-91 +-110 +-28 +81 +98 +62 +25 +-13 +-42 +-69 +-90 +-108 +-27 +82 +100 +63 +26 +-11 +-42 +-68 +-89 +-17 +91 +98 +59 +16 +-18 +-49 +-73 +-19 +85 +88 +50 +8 +-26 +-55 +-78 +-26 +78 +82 +43 +3 +-30 +-59 +-81 +-30 +74 +78 +39 +-1 +-33 +-61 +-84 +-32 +72 +76 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +36 +-4 +-35 +-63 +-85 +-105 +-45 +61 +75 +38 +4 +-30 +-57 +-81 +-101 +-102 +-40 +69 +86 +50 +14 +-22 +-50 +-76 +-96 +-113 +-35 +74 +91 +55 +19 +-17 +-47 +-72 +-93 +-111 +-31 +78 +95 +58 +22 +-15 +-45 +-71 +-91 +-109 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-19 +89 +96 +58 +15 +-19 +-49 +-74 +-20 +84 +87 +48 +7 +-27 +-55 +-79 +-26 +79 +83 +44 +3 +-30 +-58 +-81 +-29 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +74 +77 +39 +-1 +-33 +-61 +-84 +-33 +72 +76 +38 +-1 +-34 +-62 +-84 +-33 +71 +76 +37 +0 +-32 +-61 +-83 +-103 +-103 +-44 +67 +82 +49 +11 +-22 +-52 +-76 +-97 +-98 +-36 +75 +91 +57 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +94 +60 +22 +-14 +-45 +-70 +-91 +-109 +-29 +82 +96 +63 +24 +-12 +-43 +-68 +-90 +-108 +-28 +83 +98 +64 +20 +-15 +-46 +-70 +-15 +88 +92 +53 +11 +-23 +-53 +-76 +-24 +80 +83 +45 +4 +-29 +-57 +-81 +-29 +75 +80 +41 +1 +-32 +-60 +-83 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +72 +76 +38 +-2 +-34 +-62 +-85 +-34 +70 +75 +37 +0 +-33 +-61 +-83 +-104 +-103 +-43 +69 +83 +50 +12 +-22 +-52 +-76 +-97 +-97 +-35 +77 +91 +57 +19 +-16 +-47 +-71 +-93 +-110 +-30 +81 +95 +62 +23 +-13 +-44 +-69 +-91 +-108 +-28 +83 +97 +64 +25 +-11 +-42 +-67 +-90 +-107 +-27 +84 +99 +65 +21 +-14 +-45 +-70 +-14 +90 +94 +54 +12 +-22 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +76 +37 +-2 +-34 +-62 +-85 +-34 +69 +74 +36 +-3 +-35 +-63 +-85 +-105 +-45 +61 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +88 +52 +16 +-20 +-49 +-74 +-95 +-112 +-33 +77 +94 +57 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-28 +82 +99 +63 +26 +-12 +-42 +-68 +-89 +-18 +90 +97 +59 +16 +-19 +-49 +-73 +-20 +84 +87 +48 +7 +-26 +-55 +-79 +-26 +78 +82 +43 +2 +-30 +-59 +-82 +-30 +74 +77 +40 +0 +-33 +-61 +-83 +-32 +71 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-45 +62 +75 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +88 +51 +15 +-20 +-49 +-75 +-95 +-97 +-33 +76 +93 +57 +21 +-16 +-45 +-71 +-92 +-110 +-30 +80 +97 +60 +23 +-14 +-43 +-70 +-90 +-109 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-90 +-108 +-27 +83 +100 +63 +26 +-11 +-41 +-68 +-89 +-108 +-26 +83 +101 +63 +27 +-11 +-41 +-67 +-89 +-107 +-26 +83 +101 +64 +27 +-10 +-41 +-67 +-88 +-107 +-25 +84 +101 +65 +27 +-10 +-40 +-67 +-88 +-107 +-25 +84 +101 +65 +27 +-10 +-41 +-67 +-88 +-16 +91 +98 +59 +16 +-18 +-48 +-73 +-19 +84 +88 +50 +8 +-25 +-55 +-78 +-26 +79 +82 +44 +3 +-30 +-58 +-81 +-30 +75 +79 +41 +0 +-32 +-60 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +74 +37 +-3 +-35 +-63 +-85 +-35 +69 +74 +36 +-3 +-35 +-63 +-85 +-35 +69 +74 +35 +-4 +-36 +-64 +-86 +-36 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +68 +72 +35 +-4 +-36 +-64 +-86 +-36 +68 +73 +35 +-2 +-34 +-62 +-85 +-105 +-104 +-44 +67 +81 +48 +11 +-23 +-53 +-77 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-48 +-72 +-94 +-110 +-31 +80 +95 +61 +22 +-13 +-44 +-69 +-91 +-108 +-29 +83 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +84 +98 +64 +20 +-15 +-45 +-70 +-14 +89 +93 +54 +11 +-22 +-52 +-76 +-23 +81 +84 +46 +5 +-29 +-57 +-80 +-28 +75 +80 +41 +1 +-32 +-60 +-83 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +72 +76 +37 +-2 +-34 +-62 +-85 +-33 +71 +75 +37 +-3 +-34 +-62 +-85 +-104 +-44 +62 +77 +41 +6 +-28 +-56 +-80 +-100 +-101 +-37 +72 +89 +53 +17 +-19 +-48 +-74 +-94 +-112 +-31 +78 +95 +59 +22 +-15 +-44 +-70 +-91 +-109 +-28 +81 +97 +61 +25 +-13 +-43 +-69 +-90 +-108 +-27 +82 +99 +63 +26 +-12 +-42 +-68 +-89 +-18 +90 +97 +58 +15 +-19 +-49 +-74 +-20 +84 +87 +48 +7 +-26 +-56 +-79 +-26 +78 +82 +43 +2 +-30 +-59 +-82 +-30 +74 +78 +40 +0 +-33 +-61 +-83 +-32 +72 +75 +37 +-2 +-34 +-62 +-85 +-33 +70 +74 +36 +-4 +-35 +-63 +-85 +-105 +-45 +61 +75 +39 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +88 +51 +15 +-20 +-49 +-74 +-95 +-113 +-33 +76 +93 +57 +21 +-16 +-45 +-71 +-92 +-110 +-30 +80 +97 +60 +24 +-13 +-43 +-69 +-90 +-109 +-28 +81 +98 +62 +25 +-12 +-42 +-68 +-90 +-18 +89 +96 +58 +15 +-19 +-49 +-74 +-20 +83 +87 +49 +7 +-26 +-55 +-79 +-27 +77 +81 +43 +2 +-30 +-59 +-82 +-30 +75 +79 +40 +0 +-32 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +70 +74 +36 +-3 +-35 +-63 +-85 +-34 +70 +75 +37 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +67 +82 +48 +11 +-23 +-52 +-76 +-97 +-98 +-36 +75 +90 +57 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +95 +61 +22 +-13 +-44 +-69 +-91 +-109 +-29 +82 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +84 +98 +64 +20 +-15 +-45 +-70 +-15 +89 +93 +54 +11 +-22 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +38 +-1 +-34 +-62 +-84 +-33 +71 +76 +37 +-2 +-34 +-62 +-85 +-35 +70 +74 +37 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +67 +82 +49 +11 +-23 +-52 +-76 +-97 +-98 +-36 +75 +90 +57 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +95 +61 +22 +-13 +-44 +-69 +-91 +-108 +-28 +83 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-28 +84 +98 +64 +20 +-15 +-46 +-70 +-15 +89 +93 +54 +12 +-22 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +2 +-31 +-59 +-82 +-31 +73 +77 +40 +-1 +-33 +-61 +-84 +-33 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-44 +62 +77 +41 +6 +-28 +-56 +-81 +-100 +-101 +-38 +71 +89 +53 +17 +-19 +-48 +-74 +-94 +-112 +-32 +77 +95 +58 +22 +-15 +-45 +-71 +-91 +-110 +-28 +81 +97 +62 +24 +-13 +-43 +-69 +-90 +-108 +-27 +83 +99 +63 +26 +-12 +-42 +-68 +-89 +-17 +90 +97 +59 +16 +-19 +-49 +-73 +-20 +84 +87 +48 +7 +-26 +-56 +-79 +-27 +77 +81 +43 +2 +-31 +-59 +-82 +-31 +74 +77 +40 +0 +-33 +-61 +-83 +-33 +71 +75 +37 +-2 +-34 +-62 +-85 +-34 +70 +75 +36 +-3 +-35 +-63 +-85 +-105 +-45 +62 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +88 +52 +16 +-20 +-49 +-74 +-95 +-112 +-33 +77 +94 +57 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-28 +82 +99 +62 +25 +-12 +-42 +-68 +-90 +-18 +89 +96 +57 +15 +-20 +-50 +-74 +-20 +83 +86 +48 +7 +-27 +-56 +-79 +-27 +77 +81 +43 +2 +-31 +-59 +-82 +-30 +74 +79 +40 +0 +-33 +-61 +-83 +-32 +71 +75 +37 +-3 +-35 +-62 +-85 +-33 +71 +74 +36 +-3 +-35 +-63 +-85 +-35 +70 +74 +36 +-1 +-33 +-62 +-84 +-104 +-104 +-44 +67 +82 +48 +11 +-23 +-53 +-76 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-47 +-72 +-94 +-110 +-31 +80 +95 +61 +22 +-13 +-44 +-69 +-91 +-109 +-29 +83 +97 +63 +24 +-12 +-43 +-68 +-90 +-107 +-27 +84 +98 +64 +21 +-14 +-45 +-70 +-14 +89 +93 +54 +12 +-22 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +37 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +67 +82 +48 +11 +-23 +-53 +-76 +-97 +-98 +-35 +75 +90 +57 +18 +-16 +-47 +-72 +-93 +-110 +-31 +80 +95 +61 +22 +-13 +-44 +-69 +-91 +-109 +-29 +83 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-28 +83 +98 +64 +21 +-15 +-45 +-70 +-15 +89 +93 +54 +11 +-22 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +72 +75 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +37 +-3 +-35 +-63 +-85 +-105 +-44 +62 +76 +40 +6 +-29 +-56 +-81 +-100 +-101 +-39 +71 +89 +52 +16 +-19 +-49 +-74 +-94 +-112 +-32 +77 +95 +59 +22 +-15 +-44 +-71 +-91 +-109 +-28 +81 +99 +62 +25 +-13 +-42 +-69 +-90 +-108 +-27 +83 +100 +63 +27 +-11 +-41 +-68 +-89 +-107 +-25 +84 +101 +64 +27 +-11 +-41 +-67 +-88 +-107 +-25 +84 +101 +64 +27 +-10 +-41 +-67 +-88 +-107 +-25 +84 +101 +64 +27 +-11 +-41 +-67 +-88 +-107 +-25 +84 +101 +65 +28 +-10 +-40 +-67 +-88 +-107 +-25 +84 +101 +65 +27 +-10 +-41 +-67 +-88 +-16 +91 +98 +60 +17 +-18 +-48 +-73 +-19 +84 +88 +49 +8 +-26 +-55 +-78 +-26 +78 +82 +43 +3 +-30 +-59 +-82 +-30 +74 +77 +40 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-3 +-35 +-62 +-85 +-34 +70 +74 +36 +-4 +-35 +-63 +-85 +-105 +-45 +61 +75 +39 +4 +-30 +-57 +-81 +-101 +-102 +-40 +70 +87 +51 +15 +-21 +-49 +-75 +-95 +-113 +-33 +76 +93 +57 +21 +-16 +-45 +-71 +-92 +-110 +-30 +80 +97 +60 +24 +-13 +-43 +-69 +-90 +-109 +-28 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-18 +89 +97 +58 +15 +-19 +-49 +-74 +-20 +84 +88 +49 +7 +-26 +-55 +-79 +-26 +78 +82 +43 +2 +-30 +-59 +-82 +-30 +75 +79 +40 +0 +-32 +-60 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +74 +36 +-3 +-35 +-63 +-85 +-34 +71 +75 +37 +-3 +-35 +-63 +-85 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +68 +72 +35 +-4 +-36 +-64 +-86 +-36 +68 +73 +35 +-2 +-34 +-63 +-85 +-104 +-104 +-45 +66 +81 +47 +10 +-23 +-53 +-77 +-98 +-98 +-36 +75 +90 +56 +18 +-17 +-48 +-72 +-94 +-111 +-31 +80 +94 +61 +22 +-13 +-44 +-69 +-91 +-109 +-29 +82 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-28 +83 +98 +64 +20 +-15 +-46 +-70 +-15 +89 +93 +54 +11 +-22 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +2 +-31 +-59 +-82 +-30 +74 +77 +40 +-1 +-33 +-61 +-84 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-44 +62 +77 +40 +6 +-29 +-56 +-81 +-100 +-101 +-39 +71 +88 +52 +16 +-20 +-49 +-74 +-94 +-112 +-32 +77 +94 +58 +22 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +60 +24 +-13 +-43 +-69 +-90 +-109 +-27 +81 +98 +62 +25 +-12 +-42 +-68 +-89 +-18 +89 +97 +59 +16 +-19 +-49 +-73 +-20 +84 +87 +48 +7 +-26 +-55 +-79 +-26 +78 +81 +43 +2 +-30 +-59 +-82 +-30 +74 +78 +40 +0 +-32 +-61 +-83 +-32 +72 +76 +37 +-2 +-34 +-62 +-85 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-44 +62 +76 +40 +6 +-28 +-56 +-81 +-100 +-101 +-38 +71 +89 +52 +16 +-19 +-49 +-74 +-94 +-112 +-32 +77 +95 +59 +22 +-14 +-44 +-70 +-91 +-109 +-28 +81 +98 +62 +25 +-12 +-42 +-69 +-90 +-108 +-26 +83 +99 +63 +26 +-11 +-41 +-68 +-89 +-17 +90 +97 +59 +16 +-19 +-49 +-73 +-20 +84 +88 +49 +7 +-26 +-55 +-79 +-26 +78 +81 +42 +2 +-31 +-59 +-82 +-31 +74 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +68 +72 +34 +-3 +-35 +-63 +-85 +-105 +-104 +-46 +65 +79 +46 +9 +-25 +-54 +-78 +-98 +-99 +-38 +73 +88 +54 +16 +-18 +-49 +-73 +-94 +-111 +-33 +78 +93 +59 +21 +-14 +-45 +-70 +-92 +-109 +-30 +82 +97 +62 +23 +-12 +-44 +-69 +-91 +-108 +-27 +85 +99 +65 +21 +-14 +-45 +-70 +-14 +90 +94 +54 +12 +-22 +-52 +-76 +-22 +82 +86 +47 +6 +-27 +-56 +-79 +-27 +77 +81 +43 +2 +-31 +-59 +-82 +-29 +75 +78 +40 +0 +-32 +-60 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +68 +83 +49 +11 +-22 +-52 +-76 +-97 +-98 +-36 +76 +90 +57 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +94 +60 +22 +-14 +-45 +-69 +-91 +-109 +-30 +82 +96 +62 +23 +-12 +-43 +-69 +-91 +-108 +-28 +83 +97 +63 +19 +-16 +-46 +-71 +-15 +89 +92 +53 +11 +-23 +-53 +-76 +-23 +80 +84 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-30 +74 +78 +40 +0 +-32 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-44 +62 +77 +41 +6 +-28 +-56 +-80 +-100 +-101 +-38 +72 +89 +53 +17 +-19 +-48 +-74 +-94 +-112 +-32 +77 +95 +58 +22 +-15 +-45 +-70 +-91 +-110 +-28 +81 +98 +62 +24 +-13 +-42 +-69 +-90 +-108 +-27 +82 +99 +63 +26 +-12 +-42 +-68 +-89 +-17 +90 +97 +59 +16 +-18 +-49 +-73 +-20 +83 +88 +49 +7 +-26 +-55 +-79 +-26 +77 +82 +43 +3 +-30 +-59 +-82 +-30 +74 +78 +40 +0 +-33 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-44 +61 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +87 +51 +15 +-20 +-49 +-75 +-95 +-97 +-33 +76 +93 +57 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-108 +-26 +83 +100 +63 +26 +-11 +-41 +-68 +-89 +-108 +-26 +83 +100 +64 +27 +-11 +-41 +-67 +-89 +-107 +-26 +83 +101 +64 +27 +-11 +-41 +-67 +-88 +-107 +-25 +84 +101 +63 +27 +-11 +-41 +-67 +-89 +-107 +-26 +83 +100 +64 +27 +-11 +-41 +-67 +-88 +-17 +91 +97 +59 +16 +-19 +-49 +-73 +-19 +84 +87 +49 +7 +-26 +-55 +-79 +-26 +78 +82 +43 +2 +-30 +-59 +-82 +-30 +75 +78 +40 +0 +-33 +-61 +-83 +-32 +72 +76 +37 +-2 +-34 +-62 +-85 +-33 +70 +74 +36 +-3 +-35 +-63 +-85 +-35 +70 +74 +36 +-4 +-35 +-63 +-85 +-35 +69 +74 +36 +-4 +-35 +-63 +-86 +-35 +69 +73 +35 +-4 +-36 +-63 +-86 +-36 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +69 +73 +35 +-2 +-34 +-62 +-85 +-104 +-104 +-45 +67 +81 +48 +10 +-23 +-53 +-77 +-98 +-98 +-36 +75 +90 +56 +17 +-17 +-48 +-72 +-94 +-111 +-31 +80 +94 +60 +22 +-14 +-45 +-69 +-91 +-109 +-29 +82 +96 +62 +24 +-12 +-43 +-68 +-90 +-108 +-28 +84 +98 +64 +20 +-15 +-45 +-70 +-14 +89 +93 +54 +12 +-22 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +37 +-3 +-35 +-63 +-85 +-105 +-45 +62 +77 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +71 +88 +52 +17 +-19 +-48 +-74 +-94 +-112 +-32 +77 +94 +58 +21 +-16 +-45 +-71 +-91 +-110 +-29 +80 +97 +60 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +98 +62 +25 +-12 +-42 +-68 +-89 +-18 +89 +96 +58 +15 +-19 +-49 +-74 +-20 +84 +88 +49 +7 +-26 +-55 +-79 +-26 +78 +82 +44 +3 +-30 +-58 +-81 +-29 +75 +79 +41 +1 +-32 +-60 +-83 +-31 +72 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +76 +38 +-2 +-34 +-62 +-84 +-104 +-44 +63 +78 +42 +6 +-28 +-56 +-80 +-99 +-101 +-37 +71 +88 +52 +16 +-19 +-48 +-74 +-94 +-112 +-33 +77 +95 +58 +21 +-16 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-18 +90 +97 +59 +16 +-19 +-49 +-73 +-20 +84 +87 +48 +6 +-27 +-56 +-79 +-26 +78 +81 +43 +2 +-31 +-59 +-82 +-31 +74 +79 +40 +0 +-32 +-60 +-83 +-33 +71 +76 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-35 +69 +74 +36 +-2 +-34 +-62 +-84 +-104 +-104 +-44 +67 +80 +47 +10 +-23 +-53 +-77 +-98 +-98 +-36 +75 +89 +56 +18 +-17 +-48 +-72 +-94 +-111 +-32 +79 +94 +60 +21 +-14 +-45 +-70 +-92 +-109 +-29 +82 +97 +62 +24 +-12 +-43 +-68 +-90 +-108 +-28 +83 +98 +64 +20 +-15 +-46 +-70 +-15 +89 +93 +54 +11 +-22 +-52 +-76 +-23 +81 +84 +46 +5 +-28 +-57 +-80 +-28 +77 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +72 +76 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +37 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +67 +82 +49 +11 +-23 +-52 +-76 +-97 +-98 +-36 +76 +90 +56 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +94 +61 +22 +-13 +-44 +-69 +-91 +-109 +-29 +83 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-28 +83 +98 +64 +20 +-15 +-45 +-70 +-15 +89 +93 +53 +11 +-23 +-52 +-76 +-23 +80 +84 +46 +5 +-28 +-57 +-80 +-28 +75 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +72 +76 +37 +-2 +-34 +-62 +-85 +-33 +70 +74 +37 +-3 +-35 +-63 +-85 +-105 +-45 +62 +77 +40 +5 +-29 +-56 +-81 +-100 +-101 +-39 +70 +88 +52 +16 +-20 +-49 +-74 +-94 +-112 +-33 +77 +94 +58 +21 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-70 +-90 +-109 +-27 +82 +99 +63 +26 +-12 +-42 +-68 +-89 +-18 +90 +97 +59 +16 +-19 +-49 +-73 +-19 +85 +88 +49 +7 +-26 +-55 +-79 +-26 +78 +82 +43 +3 +-30 +-58 +-81 +-29 +75 +78 +40 +0 +-32 +-60 +-83 +-31 +73 +77 +39 +-1 +-33 +-62 +-84 +-33 +71 +75 +37 +-2 +-34 +-62 +-85 +-105 +-43 +63 +77 +41 +6 +-28 +-56 +-80 +-100 +-101 +-38 +71 +88 +53 +17 +-19 +-49 +-74 +-94 +-112 +-32 +77 +94 +58 +22 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-108 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-18 +89 +97 +58 +15 +-19 +-49 +-74 +-20 +83 +87 +48 +7 +-27 +-56 +-79 +-27 +77 +81 +43 +2 +-31 +-59 +-82 +-30 +74 +78 +40 +-1 +-33 +-61 +-84 +-32 +71 +75 +37 +-3 +-35 +-62 +-85 +-33 +70 +74 +37 +-3 +-35 +-63 +-85 +-35 +70 +74 +36 +-1 +-33 +-62 +-84 +-104 +-104 +-44 +67 +81 +47 +10 +-23 +-53 +-77 +-97 +-98 +-36 +75 +89 +55 +17 +-17 +-48 +-72 +-94 +-111 +-31 +79 +94 +60 +21 +-14 +-45 +-70 +-92 +-109 +-29 +82 +96 +62 +24 +-12 +-43 +-68 +-90 +-108 +-28 +84 +98 +63 +20 +-15 +-46 +-70 +-15 +89 +93 +53 +11 +-23 +-52 +-76 +-23 +81 +84 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +76 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +37 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +67 +82 +49 +11 +-22 +-52 +-76 +-97 +-97 +-36 +76 +91 +57 +18 +-17 +-47 +-71 +-93 +-110 +-31 +80 +95 +61 +22 +-13 +-45 +-69 +-91 +-109 +-29 +82 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +83 +98 +64 +20 +-15 +-45 +-70 +-14 +89 +93 +54 +11 +-22 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +75 +80 +42 +1 +-31 +-59 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-32 +71 +76 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +37 +-3 +-35 +-63 +-85 +-105 +-45 +61 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +88 +52 +16 +-20 +-49 +-74 +-95 +-112 +-32 +77 +94 +58 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +60 +24 +-13 +-43 +-69 +-90 +-109 +-28 +82 +99 +63 +26 +-12 +-42 +-68 +-89 +-18 +90 +97 +59 +16 +-19 +-49 +-73 +-20 +84 +87 +48 +7 +-26 +-56 +-79 +-26 +78 +82 +43 +2 +-30 +-59 +-82 +-30 +75 +79 +40 +0 +-32 +-60 +-83 +-32 +73 +77 +38 +-2 +-34 +-62 +-84 +-34 +70 +75 +37 +-2 +-34 +-62 +-85 +-104 +-44 +62 +77 +41 +6 +-28 +-56 +-81 +-100 +-101 +-38 +71 +88 +53 +17 +-19 +-48 +-74 +-94 +-112 +-32 +77 +95 +59 +22 +-15 +-44 +-70 +-91 +-110 +-28 +81 +98 +62 +25 +-12 +-42 +-69 +-90 +-108 +-27 +83 +99 +63 +26 +-11 +-42 +-68 +-89 +-17 +91 +97 +59 +16 +-19 +-49 +-73 +-20 +84 +87 +49 +7 +-26 +-55 +-78 +-26 +78 +82 +43 +2 +-30 +-59 +-81 +-30 +75 +79 +41 +0 +-32 +-60 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-85 +-34 +71 +75 +37 +-3 +-35 +-63 +-85 +-35 +70 +74 +36 +-1 +-33 +-62 +-84 +-104 +-104 +-45 +66 +81 +48 +10 +-24 +-53 +-77 +-97 +-98 +-37 +75 +89 +55 +17 +-17 +-48 +-72 +-94 +-111 +-32 +79 +94 +59 +21 +-14 +-45 +-70 +-92 +-109 +-30 +81 +96 +61 +23 +-13 +-44 +-69 +-91 +-108 +-28 +83 +98 +63 +24 +-11 +-43 +-68 +-90 +-107 +-27 +84 +98 +64 +25 +-11 +-42 +-67 +-90 +-107 +-27 +84 +99 +65 +26 +-10 +-42 +-67 +-89 +-107 +-26 +85 +100 +65 +26 +-10 +-41 +-67 +-89 +-107 +-26 +85 +99 +65 +26 +-10 +-42 +-67 +-89 +-107 +-26 +86 +100 +65 +22 +-14 +-44 +-69 +-14 +90 +94 +55 +12 +-21 +-51 +-75 +-22 +82 +86 +47 +6 +-27 +-56 +-80 +-28 +77 +80 +42 +1 +-31 +-59 +-82 +-31 +74 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-3 +-34 +-62 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-35 +69 +73 +36 +-4 +-35 +-63 +-85 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +68 +73 +35 +-4 +-36 +-64 +-86 +-35 +68 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-106 +-46 +61 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +88 +52 +16 +-20 +-49 +-74 +-95 +-112 +-33 +77 +93 +57 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +60 +23 +-14 +-43 +-70 +-90 +-109 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-17 +90 +97 +59 +16 +-19 +-49 +-73 +-19 +85 +88 +49 +8 +-26 +-55 +-78 +-26 +78 +82 +44 +3 +-30 +-58 +-81 +-29 +75 +79 +41 +1 +-32 +-60 +-83 +-32 +73 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-2 +-34 +-62 +-85 +-104 +-44 +63 +77 +40 +5 +-29 +-56 +-81 +-100 +-101 +-38 +71 +88 +52 +16 +-19 +-49 +-74 +-94 +-112 +-33 +77 +94 +57 +21 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-108 +-26 +83 +100 +63 +26 +-11 +-41 +-68 +-89 +-107 +-26 +84 +100 +63 +27 +-11 +-41 +-68 +-89 +-107 +-26 +83 +101 +64 +27 +-11 +-41 +-67 +-88 +-107 +-25 +85 +101 +65 +28 +-10 +-40 +-67 +-88 +-107 +-24 +85 +101 +65 +28 +-10 +-40 +-67 +-88 +-16 +91 +98 +60 +17 +-17 +-48 +-72 +-19 +86 +89 +50 +8 +-25 +-54 +-78 +-25 +79 +83 +45 +4 +-29 +-58 +-81 +-29 +76 +80 +41 +1 +-32 +-60 +-83 +-31 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-35 +70 +74 +36 +-1 +-33 +-62 +-84 +-104 +-104 +-45 +66 +81 +47 +10 +-24 +-53 +-77 +-98 +-98 +-37 +75 +89 +55 +17 +-18 +-48 +-73 +-94 +-111 +-33 +78 +92 +58 +20 +-15 +-46 +-71 +-92 +-109 +-31 +80 +94 +60 +21 +-14 +-45 +-70 +-91 +-109 +-30 +82 +96 +62 +19 +-16 +-47 +-71 +-16 +87 +92 +52 +10 +-23 +-53 +-77 +-24 +80 +84 +45 +4 +-29 +-58 +-81 +-29 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +40 +-1 +-33 +-61 +-83 +-32 +72 +76 +38 +-1 +-33 +-62 +-84 +-33 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-2 +-34 +-62 +-85 +-33 +70 +75 +37 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-35 +69 +74 +36 +-4 +-35 +-63 +-85 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-5 +-36 +-64 +-86 +-36 +69 +72 +34 +-5 +-36 +-64 +-86 +-36 +68 +72 +34 +-5 +-37 +-65 +-86 +-36 +68 +72 +34 +-5 +-37 +-65 +-86 +-36 +68 +72 +34 +-5 +-37 +-64 +-86 +-36 +68 +72 +34 +-5 +-37 +-64 +-86 +-36 +68 +72 +35 +-5 +-36 +-64 +-86 +-36 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +74 +35 +-4 +-36 +-63 +-86 +-35 +70 +74 +36 +-3 +-35 +-63 +-85 +-35 +69 +74 +36 +-4 +-35 +-63 +-86 +-35 +69 +74 +36 +-4 +-35 +-63 +-85 +-35 +70 +74 +36 +-1 +-33 +-62 +-84 +-104 +-104 +-44 +67 +82 +48 +11 +-23 +-53 +-77 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +95 +61 +22 +-13 +-44 +-69 +-91 +-109 +-29 +82 +96 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +84 +98 +64 +25 +-11 +-42 +-67 +-90 +-107 +-27 +85 +98 +64 +26 +-10 +-42 +-67 +-89 +-107 +-26 +85 +99 +65 +26 +-10 +-42 +-67 +-89 +-107 +-26 +86 +100 +65 +26 +-10 +-42 +-67 +-89 +-106 +-26 +85 +99 +65 +26 +-10 +-42 +-67 +-89 +-107 +-26 +86 +100 +65 +26 +-10 +-42 +-67 +-89 +-107 +-26 +85 +99 +65 +26 +-10 +-41 +-67 +-89 +-107 +-26 +86 +100 +65 +26 +-10 +-41 +-67 +-89 +-106 +-26 +86 +100 +65 +26 +-9 +-41 +-67 +-89 +-106 +-26 +85 +99 +65 +26 +-10 +-41 +-67 +-89 +-106 +-26 +86 +100 +65 +22 +-14 +-45 +-69 +-14 +90 +94 +54 +12 +-22 +-51 +-76 +-22 +82 +85 +46 +5 +-28 +-57 +-80 +-28 +77 +80 +41 +1 +-32 +-60 +-82 +-31 +73 +77 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-34 +69 +73 +36 +-2 +-34 +-62 +-84 +-104 +-104 +-44 +67 +81 +48 +11 +-23 +-53 +-76 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-47 +-72 +-94 +-110 +-31 +80 +95 +61 +22 +-14 +-45 +-69 +-92 +-109 +-29 +83 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +84 +99 +64 +21 +-14 +-45 +-70 +-14 +90 +93 +54 +12 +-22 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-59 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-2 +-35 +-62 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-105 +-45 +62 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +71 +88 +51 +16 +-20 +-49 +-74 +-94 +-112 +-33 +77 +94 +58 +21 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +60 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +63 +25 +-12 +-42 +-68 +-89 +-17 +90 +97 +59 +15 +-19 +-49 +-73 +-20 +84 +87 +49 +7 +-26 +-55 +-79 +-27 +78 +82 +43 +3 +-30 +-59 +-82 +-29 +74 +78 +40 +0 +-33 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-44 +62 +76 +40 +6 +-28 +-56 +-81 +-100 +-101 +-38 +71 +88 +52 +16 +-20 +-49 +-74 +-95 +-112 +-33 +76 +94 +57 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +63 +25 +-12 +-42 +-68 +-89 +-17 +90 +97 +59 +16 +-19 +-49 +-73 +-19 +84 +88 +49 +8 +-26 +-55 +-78 +-26 +78 +83 +44 +3 +-30 +-58 +-81 +-29 +75 +80 +42 +1 +-31 +-60 +-83 +-32 +73 +77 +39 +-1 +-33 +-61 +-84 +-32 +71 +75 +37 +-2 +-34 +-62 +-85 +-34 +71 +75 +37 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +68 +82 +48 +10 +-23 +-53 +-77 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-47 +-72 +-93 +-111 +-31 +80 +94 +60 +21 +-14 +-45 +-70 +-92 +-109 +-29 +82 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +84 +98 +64 +20 +-15 +-46 +-70 +-15 +89 +93 +54 +11 +-23 +-52 +-76 +-23 +80 +84 +45 +4 +-29 +-57 +-81 +-28 +76 +80 +41 +1 +-32 +-60 +-83 +-31 +73 +77 +39 +-1 +-33 +-62 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-34 +69 +74 +36 +-2 +-34 +-62 +-84 +-104 +-104 +-44 +67 +81 +47 +10 +-23 +-53 +-77 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-48 +-72 +-94 +-110 +-31 +79 +95 +61 +22 +-13 +-45 +-69 +-91 +-109 +-29 +83 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +83 +97 +63 +20 +-15 +-46 +-70 +-14 +90 +93 +54 +11 +-23 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +72 +76 +38 +-2 +-34 +-62 +-84 +-34 +70 +75 +37 +-3 +-35 +-63 +-85 +-105 +-45 +62 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +87 +51 +16 +-20 +-49 +-74 +-95 +-112 +-32 +77 +94 +58 +21 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-18 +89 +97 +59 +16 +-19 +-49 +-73 +-20 +83 +87 +48 +7 +-26 +-55 +-79 +-26 +78 +82 +43 +3 +-30 +-59 +-81 +-30 +74 +78 +40 +0 +-32 +-60 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-44 +62 +76 +40 +5 +-29 +-57 +-81 +-100 +-102 +-39 +71 +88 +52 +16 +-20 +-49 +-74 +-94 +-112 +-32 +77 +94 +58 +21 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-108 +-27 +83 +100 +63 +26 +-12 +-42 +-68 +-89 +-108 +-26 +84 +101 +63 +27 +-11 +-41 +-68 +-89 +-108 +-25 +84 +101 +65 +28 +-10 +-40 +-67 +-88 +-107 +-25 +84 +101 +65 +28 +-10 +-40 +-67 +-88 +-107 +-24 +85 +102 +65 +28 +-10 +-40 +-67 +-88 +-107 +-24 +85 +102 +65 +27 +-10 +-40 +-67 +-88 +-16 +92 +98 +60 +16 +-18 +-48 +-73 +-19 +85 +89 +50 +8 +-25 +-55 +-78 +-25 +79 +82 +43 +3 +-30 +-59 +-81 +-30 +74 +78 +40 +0 +-33 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-34 +70 +74 +36 +-4 +-35 +-63 +-85 +-35 +70 +74 +36 +-3 +-35 +-63 +-85 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +69 +73 +34 +-5 +-36 +-64 +-86 +-36 +68 +72 +35 +-3 +-34 +-62 +-85 +-105 +-104 +-45 +66 +81 +47 +10 +-24 +-53 +-77 +-98 +-98 +-37 +75 +89 +55 +17 +-17 +-48 +-72 +-94 +-111 +-32 +79 +94 +60 +21 +-14 +-45 +-70 +-92 +-109 +-29 +82 +96 +62 +23 +-12 +-44 +-69 +-91 +-108 +-28 +83 +98 +63 +20 +-15 +-46 +-70 +-15 +89 +93 +54 +11 +-22 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +72 +76 +37 +-2 +-34 +-62 +-85 +-34 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-45 +61 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +71 +88 +52 +16 +-20 +-49 +-74 +-94 +-112 +-32 +77 +94 +58 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-17 +90 +97 +58 +15 +-19 +-49 +-74 +-20 +84 +88 +49 +7 +-26 +-55 +-79 +-26 +78 +82 +43 +3 +-30 +-59 +-81 +-30 +74 +78 +40 +0 +-33 +-61 +-83 +-32 +71 +76 +38 +-2 +-34 +-62 +-84 +-33 diff --git a/traces/README.txt b/traces/README.txt index 50b14aaee..424092dc5 100644 --- a/traces/README.txt +++ b/traces/README.txt @@ -15,3 +15,10 @@ Transit999-best.pm3: Transit 999 format (UID 99531670) The files 'modulation-'... are all encoded with identical data (hex 00 01 02 03 04 05 06 07 08 09 0A 0B) for the purpose of recognition and testing of demodulation schemes. They were created by writing Q5 tags appropriately configured. The raw data is in 'modulation-data.dat'. + +ata5577-HIDemu-FC1-C9.pm3: ata5577 in hid prox 26 bit emulation facility code:1 card#:9 +casi-12ed825c29.pm3: casi rusco 40 bit (EM410x ID: 12ed825c29) +EM4102-Fob.pm3: (ID: 0400193cbe) +ioprox-XSF-01-3B-44725.pm3: IO Prox FSK RF/64 ID in name +ioprox-XSF-01-BE-03011.pm3: IO Prox FSK RF/64 ID in name +indala-504278295.pm3: PSK 26 bit indala \ No newline at end of file From 1c4b102cd55d96d6a870f7f2153199b9e721e077 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Tue, 6 Jan 2015 10:58:35 -0500 Subject: [PATCH 02/11] sync with master lf files to resolve conflicts --- armsrc/lfops.c | 2834 +++++++++++++++++++++++----------------------- common/lfdemod.c | 1616 ++++++++++---------------- common/lfdemod.h | 8 +- 3 files changed, 1998 insertions(+), 2460 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 79d59bf9c..ab196325f 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -25,40 +25,40 @@ */ void DoAcquisition125k_internal(int trigger_threshold,bool silent) { - uint8_t *dest = (uint8_t *)BigBuf; - int n = sizeof(BigBuf); - int i; + uint8_t *dest = (uint8_t *)BigBuf; + int n = sizeof(BigBuf); + int i; - memset(dest, 0, n); - i = 0; - for(;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - LED_D_ON(); - } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - LED_D_OFF(); - if (trigger_threshold != -1 && dest[i] < trigger_threshold) - continue; - else - trigger_threshold = -1; - if (++i >= n) break; - } - } - if(!silent) - { - Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...", - dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); - - } + memset(dest, 0, n); + i = 0; + for(;;) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0x43; + LED_D_ON(); + } + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + LED_D_OFF(); + if (trigger_threshold != -1 && dest[i] < trigger_threshold) + continue; + else + trigger_threshold = -1; + if (++i >= n) break; + } + } + if(!silent) + { + Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...", + dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); + + } } /** * Perform sample aquisition. */ void DoAcquisition125k(int trigger_threshold) { - DoAcquisition125k_internal(trigger_threshold, false); + DoAcquisition125k_internal(trigger_threshold, false); } /** @@ -70,31 +70,31 @@ void DoAcquisition125k(int trigger_threshold) **/ void LFSetupFPGAForADC(int divisor, bool lf_field) { - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - if ( (divisor == 1) || (divisor < 0) || (divisor > 255) ) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz - else if (divisor == 0) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - else - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + if ( (divisor == 1) || (divisor < 0) || (divisor > 255) ) + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz + else if (divisor == 0) + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + else + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | (lf_field ? FPGA_LF_ADC_READER_FIELD : 0)); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | (lf_field ? FPGA_LF_ADC_READER_FIELD : 0)); - // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - // Give it a bit of time for the resonant antenna to settle. - SpinDelay(50); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); + // Connect the A/D to the peak-detected low-frequency path. + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + // Give it a bit of time for the resonant antenna to settle. + SpinDelay(50); + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); } /** * Initializes the FPGA, and acquires the samples. **/ void AcquireRawAdcSamples125k(int divisor) { - LFSetupFPGAForADC(divisor, true); - // Now call the acquisition routine - DoAcquisition125k_internal(-1,false); + LFSetupFPGAForADC(divisor, true); + // Now call the acquisition routine + DoAcquisition125k_internal(-1,false); } /** * Initializes the FPGA for snoop-mode, and acquires the samples. @@ -102,60 +102,60 @@ void AcquireRawAdcSamples125k(int divisor) void SnoopLFRawAdcSamples(int divisor, int trigger_threshold) { - LFSetupFPGAForADC(divisor, false); - DoAcquisition125k(trigger_threshold); + LFSetupFPGAForADC(divisor, false); + DoAcquisition125k(trigger_threshold); } void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, uint8_t *command) { - /* Make sure the tag is reset */ - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelay(2500); + /* Make sure the tag is reset */ + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelay(2500); - int divisor_used = 95; // 125 KHz - // see if 'h' was specified + int divisor_used = 95; // 125 KHz + // see if 'h' was specified - if (command[strlen((char *) command) - 1] == 'h') - divisor_used = 88; // 134.8 KHz + if (command[strlen((char *) command) - 1] == 'h') + divisor_used = 88; // 134.8 KHz - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // Give it a bit of time for the resonant antenna to settle. - SpinDelay(50); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + // Give it a bit of time for the resonant antenna to settle. + SpinDelay(50); - // And a little more time for the tag to fully power up - SpinDelay(2000); + // And a little more time for the tag to fully power up + SpinDelay(2000); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); - // now modulate the reader field - while(*command != '\0' && *command != ' ') { - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LED_D_OFF(); - SpinDelayUs(delay_off); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); + // now modulate the reader field + while(*command != '\0' && *command != ' ') { + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LED_D_OFF(); + SpinDelayUs(delay_off); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - LED_D_ON(); - if(*(command++) == '0') - SpinDelayUs(period_0); - else - SpinDelayUs(period_1); - } - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LED_D_OFF(); - SpinDelayUs(delay_off); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + LED_D_ON(); + if(*(command++) == '0') + SpinDelayUs(period_0); + else + SpinDelayUs(period_1); + } + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LED_D_OFF(); + SpinDelayUs(delay_off); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // now do the read - DoAcquisition125k(-1); + // now do the read + DoAcquisition125k(-1); } /* blank r/w tag data stream @@ -169,230 +169,230 @@ void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, */ void ReadTItag(void) { - // some hardcoded initial params - // when we read a TI tag we sample the zerocross line at 2Mhz - // TI tags modulate a 1 as 16 cycles of 123.2Khz - // TI tags modulate a 0 as 16 cycles of 134.2Khz - #define FSAMPLE 2000000 - #define FREQLO 123200 - #define FREQHI 134200 + // some hardcoded initial params + // when we read a TI tag we sample the zerocross line at 2Mhz + // TI tags modulate a 1 as 16 cycles of 123.2Khz + // TI tags modulate a 0 as 16 cycles of 134.2Khz +#define FSAMPLE 2000000 +#define FREQLO 123200 +#define FREQHI 134200 - signed char *dest = (signed char *)BigBuf; - int n = sizeof(BigBuf); -// int *dest = GraphBuffer; -// int n = GraphTraceLen; + signed char *dest = (signed char *)BigBuf; + int n = sizeof(BigBuf); + // int *dest = GraphBuffer; + // int n = GraphTraceLen; - // 128 bit shift register [shift3:shift2:shift1:shift0] - uint32_t shift3 = 0, shift2 = 0, shift1 = 0, shift0 = 0; + // 128 bit shift register [shift3:shift2:shift1:shift0] + uint32_t shift3 = 0, shift2 = 0, shift1 = 0, shift0 = 0; - int i, cycles=0, samples=0; - // how many sample points fit in 16 cycles of each frequency - uint32_t sampleslo = (FSAMPLE<<4)/FREQLO, sampleshi = (FSAMPLE<<4)/FREQHI; - // when to tell if we're close enough to one freq or another - uint32_t threshold = (sampleslo - sampleshi + 1)>>1; + int i, cycles=0, samples=0; + // how many sample points fit in 16 cycles of each frequency + uint32_t sampleslo = (FSAMPLE<<4)/FREQLO, sampleshi = (FSAMPLE<<4)/FREQHI; + // when to tell if we're close enough to one freq or another + uint32_t threshold = (sampleslo - sampleshi + 1)>>1; - // TI tags charge at 134.2Khz - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz + // TI tags charge at 134.2Khz + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz - // Place FPGA in passthrough mode, in this mode the CROSS_LO line - // connects to SSP_DIN and the SSP_DOUT logic level controls - // whether we're modulating the antenna (high) - // or listening to the antenna (low) - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); + // Place FPGA in passthrough mode, in this mode the CROSS_LO line + // connects to SSP_DIN and the SSP_DOUT logic level controls + // whether we're modulating the antenna (high) + // or listening to the antenna (low) + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); - // get TI tag data into the buffer - AcquireTiType(); + // get TI tag data into the buffer + AcquireTiType(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - for (i=0; i0) ) { - cycles++; - // after 16 cycles, measure the frequency - if (cycles>15) { - cycles=0; - samples=i-samples; // number of samples in these 16 cycles + for (i=0; i0) ) { + cycles++; + // after 16 cycles, measure the frequency + if (cycles>15) { + cycles=0; + samples=i-samples; // number of samples in these 16 cycles - // TI bits are coming to us lsb first so shift them - // right through our 128 bit right shift register - shift0 = (shift0>>1) | (shift1 << 31); - shift1 = (shift1>>1) | (shift2 << 31); - shift2 = (shift2>>1) | (shift3 << 31); - shift3 >>= 1; + // TI bits are coming to us lsb first so shift them + // right through our 128 bit right shift register + shift0 = (shift0>>1) | (shift1 << 31); + shift1 = (shift1>>1) | (shift2 << 31); + shift2 = (shift2>>1) | (shift3 << 31); + shift3 >>= 1; - // check if the cycles fall close to the number - // expected for either the low or high frequency - if ( (samples>(sampleslo-threshold)) && (samples<(sampleslo+threshold)) ) { - // low frequency represents a 1 - shift3 |= (1<<31); - } else if ( (samples>(sampleshi-threshold)) && (samples<(sampleshi+threshold)) ) { - // high frequency represents a 0 - } else { - // probably detected a gay waveform or noise - // use this as gaydar or discard shift register and start again - shift3 = shift2 = shift1 = shift0 = 0; - } - samples = i; + // check if the cycles fall close to the number + // expected for either the low or high frequency + if ( (samples>(sampleslo-threshold)) && (samples<(sampleslo+threshold)) ) { + // low frequency represents a 1 + shift3 |= (1<<31); + } else if ( (samples>(sampleshi-threshold)) && (samples<(sampleshi+threshold)) ) { + // high frequency represents a 0 + } else { + // probably detected a gay waveform or noise + // use this as gaydar or discard shift register and start again + shift3 = shift2 = shift1 = shift0 = 0; + } + samples = i; - // for each bit we receive, test if we've detected a valid tag + // for each bit we receive, test if we've detected a valid tag - // if we see 17 zeroes followed by 6 ones, we might have a tag - // remember the bits are backwards - if ( ((shift0 & 0x7fffff) == 0x7e0000) ) { - // if start and end bytes match, we have a tag so break out of the loop - if ( ((shift0>>16)&0xff) == ((shift3>>8)&0xff) ) { - cycles = 0xF0B; //use this as a flag (ugly but whatever) - break; - } - } - } - } - } + // if we see 17 zeroes followed by 6 ones, we might have a tag + // remember the bits are backwards + if ( ((shift0 & 0x7fffff) == 0x7e0000) ) { + // if start and end bytes match, we have a tag so break out of the loop + if ( ((shift0>>16)&0xff) == ((shift3>>8)&0xff) ) { + cycles = 0xF0B; //use this as a flag (ugly but whatever) + break; + } + } + } + } + } - // if flag is set we have a tag - if (cycles!=0xF0B) { - DbpString("Info: No valid tag detected."); - } else { - // put 64 bit data into shift1 and shift0 - shift0 = (shift0>>24) | (shift1 << 8); - shift1 = (shift1>>24) | (shift2 << 8); + // if flag is set we have a tag + if (cycles!=0xF0B) { + DbpString("Info: No valid tag detected."); + } else { + // put 64 bit data into shift1 and shift0 + shift0 = (shift0>>24) | (shift1 << 8); + shift1 = (shift1>>24) | (shift2 << 8); - // align 16 bit crc into lower half of shift2 - shift2 = ((shift2>>24) | (shift3 << 8)) & 0x0ffff; + // align 16 bit crc into lower half of shift2 + shift2 = ((shift2>>24) | (shift3 << 8)) & 0x0ffff; - // if r/w tag, check ident match - if ( shift3&(1<<15) ) { - DbpString("Info: TI tag is rewriteable"); - // only 15 bits compare, last bit of ident is not valid - if ( ((shift3>>16)^shift0)&0x7fff ) { - DbpString("Error: Ident mismatch!"); - } else { - DbpString("Info: TI tag ident is valid"); - } - } else { - DbpString("Info: TI tag is readonly"); - } + // if r/w tag, check ident match + if ( shift3&(1<<15) ) { + DbpString("Info: TI tag is rewriteable"); + // only 15 bits compare, last bit of ident is not valid + if ( ((shift3>>16)^shift0)&0x7fff ) { + DbpString("Error: Ident mismatch!"); + } else { + DbpString("Info: TI tag ident is valid"); + } + } else { + DbpString("Info: TI tag is readonly"); + } - // WARNING the order of the bytes in which we calc crc below needs checking - // i'm 99% sure the crc algorithm is correct, but it may need to eat the - // bytes in reverse or something - // calculate CRC - uint32_t crc=0; + // WARNING the order of the bytes in which we calc crc below needs checking + // i'm 99% sure the crc algorithm is correct, but it may need to eat the + // bytes in reverse or something + // calculate CRC + uint32_t crc=0; - crc = update_crc16(crc, (shift0)&0xff); - crc = update_crc16(crc, (shift0>>8)&0xff); - crc = update_crc16(crc, (shift0>>16)&0xff); - crc = update_crc16(crc, (shift0>>24)&0xff); - crc = update_crc16(crc, (shift1)&0xff); - crc = update_crc16(crc, (shift1>>8)&0xff); - crc = update_crc16(crc, (shift1>>16)&0xff); - crc = update_crc16(crc, (shift1>>24)&0xff); + crc = update_crc16(crc, (shift0)&0xff); + crc = update_crc16(crc, (shift0>>8)&0xff); + crc = update_crc16(crc, (shift0>>16)&0xff); + crc = update_crc16(crc, (shift0>>24)&0xff); + crc = update_crc16(crc, (shift1)&0xff); + crc = update_crc16(crc, (shift1>>8)&0xff); + crc = update_crc16(crc, (shift1>>16)&0xff); + crc = update_crc16(crc, (shift1>>24)&0xff); - Dbprintf("Info: Tag data: %x%08x, crc=%x", - (unsigned int)shift1, (unsigned int)shift0, (unsigned int)shift2 & 0xFFFF); - if (crc != (shift2&0xffff)) { - Dbprintf("Error: CRC mismatch, expected %x", (unsigned int)crc); - } else { - DbpString("Info: CRC is good"); - } - } + Dbprintf("Info: Tag data: %x%08x, crc=%x", + (unsigned int)shift1, (unsigned int)shift0, (unsigned int)shift2 & 0xFFFF); + if (crc != (shift2&0xffff)) { + Dbprintf("Error: CRC mismatch, expected %x", (unsigned int)crc); + } else { + DbpString("Info: CRC is good"); + } + } } void WriteTIbyte(uint8_t b) { - int i = 0; + int i = 0; - // modulate 8 bits out to the antenna - for (i=0; i<8; i++) - { - if (b&(1<PIO_PDR = GPIO_SSC_DIN; - AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN; + // Set up the synchronous serial port + AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DIN; + AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN; - // steal this pin from the SSP and use it to control the modulation - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + // steal this pin from the SSP and use it to control the modulation + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST; - AT91C_BASE_SSC->SSC_CR = AT91C_SSC_RXEN | AT91C_SSC_TXEN; + AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST; + AT91C_BASE_SSC->SSC_CR = AT91C_SSC_RXEN | AT91C_SSC_TXEN; - // Sample at 2 Mbit/s, so TI tags are 16.2 vs. 14.9 clocks long - // 48/2 = 24 MHz clock must be divided by 12 - AT91C_BASE_SSC->SSC_CMR = 12; + // Sample at 2 Mbit/s, so TI tags are 16.2 vs. 14.9 clocks long + // 48/2 = 24 MHz clock must be divided by 12 + AT91C_BASE_SSC->SSC_CMR = 12; - AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(0); - AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(32) | AT91C_SSC_MSBF; - AT91C_BASE_SSC->SSC_TCMR = 0; - AT91C_BASE_SSC->SSC_TFMR = 0; + AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(0); + AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(32) | AT91C_SSC_MSBF; + AT91C_BASE_SSC->SSC_TCMR = 0; + AT91C_BASE_SSC->SSC_TFMR = 0; - LED_D_ON(); + LED_D_ON(); - // modulate antenna - HIGH(GPIO_SSC_DOUT); + // modulate antenna + HIGH(GPIO_SSC_DOUT); - // Charge TI tag for 50ms. - SpinDelay(50); + // Charge TI tag for 50ms. + SpinDelay(50); - // stop modulating antenna and listen - LOW(GPIO_SSC_DOUT); + // stop modulating antenna and listen + LOW(GPIO_SSC_DOUT); - LED_D_OFF(); + LED_D_OFF(); - i = 0; - for(;;) { - if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - BigBuf[i] = AT91C_BASE_SSC->SSC_RHR; // store 32 bit values in buffer - i++; if(i >= TIBUFLEN) break; - } - WDT_HIT(); - } + i = 0; + for(;;) { + if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + BigBuf[i] = AT91C_BASE_SSC->SSC_RHR; // store 32 bit values in buffer + i++; if(i >= TIBUFLEN) break; + } + WDT_HIT(); + } - // return stolen pin to SSP - AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN | GPIO_SSC_DOUT; + // return stolen pin to SSP + AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN | GPIO_SSC_DOUT; - char *dest = (char *)BigBuf; - n = TIBUFLEN*32; - // unpack buffer - for (i=TIBUFLEN-1; i>=0; i--) { - for (j=0; j<32; j++) { - if(BigBuf[i] & (1 << j)) { - dest[--n] = 1; - } else { - dest[--n] = -1; - } - } - } + char *dest = (char *)BigBuf; + n = TIBUFLEN*32; + // unpack buffer + for (i=TIBUFLEN-1; i>=0; i--) { + for (j=0; j<32; j++) { + if(BigBuf[i] & (1 << j)) { + dest[--n] = 1; + } else { + dest[--n] = -1; + } + } + } } // arguments: 64bit data split into 32bit idhi:idlo and optional 16bit crc @@ -400,127 +400,127 @@ void AcquireTiType(void) // if not provided a valid crc will be computed from the data and written. void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc) { - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - if(crc == 0) { - crc = update_crc16(crc, (idlo)&0xff); - crc = update_crc16(crc, (idlo>>8)&0xff); - crc = update_crc16(crc, (idlo>>16)&0xff); - crc = update_crc16(crc, (idlo>>24)&0xff); - crc = update_crc16(crc, (idhi)&0xff); - crc = update_crc16(crc, (idhi>>8)&0xff); - crc = update_crc16(crc, (idhi>>16)&0xff); - crc = update_crc16(crc, (idhi>>24)&0xff); - } - Dbprintf("Writing to tag: %x%08x, crc=%x", - (unsigned int) idhi, (unsigned int) idlo, crc); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + if(crc == 0) { + crc = update_crc16(crc, (idlo)&0xff); + crc = update_crc16(crc, (idlo>>8)&0xff); + crc = update_crc16(crc, (idlo>>16)&0xff); + crc = update_crc16(crc, (idlo>>24)&0xff); + crc = update_crc16(crc, (idhi)&0xff); + crc = update_crc16(crc, (idhi>>8)&0xff); + crc = update_crc16(crc, (idhi>>16)&0xff); + crc = update_crc16(crc, (idhi>>24)&0xff); + } + Dbprintf("Writing to tag: %x%08x, crc=%x", + (unsigned int) idhi, (unsigned int) idlo, crc); - // TI tags charge at 134.2Khz - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz - // Place FPGA in passthrough mode, in this mode the CROSS_LO line - // connects to SSP_DIN and the SSP_DOUT logic level controls - // whether we're modulating the antenna (high) - // or listening to the antenna (low) - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); - LED_A_ON(); + // TI tags charge at 134.2Khz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz + // Place FPGA in passthrough mode, in this mode the CROSS_LO line + // connects to SSP_DIN and the SSP_DOUT logic level controls + // whether we're modulating the antenna (high) + // or listening to the antenna (low) + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); + LED_A_ON(); - // steal this pin from the SSP and use it to control the modulation - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + // steal this pin from the SSP and use it to control the modulation + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - // writing algorithm: - // a high bit consists of a field off for 1ms and field on for 1ms - // a low bit consists of a field off for 0.3ms and field on for 1.7ms - // initiate a charge time of 50ms (field on) then immediately start writing bits - // start by writing 0xBB (keyword) and 0xEB (password) - // then write 80 bits of data (or 64 bit data + 16 bit crc if you prefer) - // finally end with 0x0300 (write frame) - // all data is sent lsb firts - // finish with 15ms programming time + // writing algorithm: + // a high bit consists of a field off for 1ms and field on for 1ms + // a low bit consists of a field off for 0.3ms and field on for 1.7ms + // initiate a charge time of 50ms (field on) then immediately start writing bits + // start by writing 0xBB (keyword) and 0xEB (password) + // then write 80 bits of data (or 64 bit data + 16 bit crc if you prefer) + // finally end with 0x0300 (write frame) + // all data is sent lsb firts + // finish with 15ms programming time - // modulate antenna - HIGH(GPIO_SSC_DOUT); - SpinDelay(50); // charge time + // modulate antenna + HIGH(GPIO_SSC_DOUT); + SpinDelay(50); // charge time - WriteTIbyte(0xbb); // keyword - WriteTIbyte(0xeb); // password - WriteTIbyte( (idlo )&0xff ); - WriteTIbyte( (idlo>>8 )&0xff ); - WriteTIbyte( (idlo>>16)&0xff ); - WriteTIbyte( (idlo>>24)&0xff ); - WriteTIbyte( (idhi )&0xff ); - WriteTIbyte( (idhi>>8 )&0xff ); - WriteTIbyte( (idhi>>16)&0xff ); - WriteTIbyte( (idhi>>24)&0xff ); // data hi to lo - WriteTIbyte( (crc )&0xff ); // crc lo - WriteTIbyte( (crc>>8 )&0xff ); // crc hi - WriteTIbyte(0x00); // write frame lo - WriteTIbyte(0x03); // write frame hi - HIGH(GPIO_SSC_DOUT); - SpinDelay(50); // programming time + WriteTIbyte(0xbb); // keyword + WriteTIbyte(0xeb); // password + WriteTIbyte( (idlo )&0xff ); + WriteTIbyte( (idlo>>8 )&0xff ); + WriteTIbyte( (idlo>>16)&0xff ); + WriteTIbyte( (idlo>>24)&0xff ); + WriteTIbyte( (idhi )&0xff ); + WriteTIbyte( (idhi>>8 )&0xff ); + WriteTIbyte( (idhi>>16)&0xff ); + WriteTIbyte( (idhi>>24)&0xff ); // data hi to lo + WriteTIbyte( (crc )&0xff ); // crc lo + WriteTIbyte( (crc>>8 )&0xff ); // crc hi + WriteTIbyte(0x00); // write frame lo + WriteTIbyte(0x03); // write frame hi + HIGH(GPIO_SSC_DOUT); + SpinDelay(50); // programming time - LED_A_OFF(); + LED_A_OFF(); - // get TI tag data into the buffer - AcquireTiType(); + // get TI tag data into the buffer + AcquireTiType(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - DbpString("Now use tiread to check"); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + DbpString("Now use tiread to check"); } void SimulateTagLowFrequency(int period, int gap, int ledcontrol) { - int i; - uint8_t *tab = (uint8_t *)BigBuf; + int i; + uint8_t *tab = (uint8_t *)BigBuf; - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK; + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK; - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK; + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK; #define SHORT_COIL() LOW(GPIO_SSC_DOUT) #define OPEN_COIL() HIGH(GPIO_SSC_DOUT) - i = 0; - for(;;) { - while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) { - if(BUTTON_PRESS()) { - DbpString("Stopped"); - return; - } - WDT_HIT(); - } + i = 0; + for(;;) { + while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) { + if(BUTTON_PRESS()) { + DbpString("Stopped"); + return; + } + WDT_HIT(); + } - if (ledcontrol) - LED_D_ON(); + if (ledcontrol) + LED_D_ON(); - if(tab[i]) - OPEN_COIL(); - else - SHORT_COIL(); + if(tab[i]) + OPEN_COIL(); + else + SHORT_COIL(); - if (ledcontrol) - LED_D_OFF(); + if (ledcontrol) + LED_D_OFF(); - while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) { - if(BUTTON_PRESS()) { - DbpString("Stopped"); - return; - } - WDT_HIT(); - } + while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) { + if(BUTTON_PRESS()) { + DbpString("Stopped"); + return; + } + WDT_HIT(); + } - i++; - if(i == period) { - i = 0; - if (gap) { - SHORT_COIL(); - SpinDelayUs(gap); - } - } - } + i++; + if(i == period) { + i = 0; + if (gap) { + SHORT_COIL(); + SpinDelayUs(gap); + } + } + } } #define DEBUG_FRAME_CONTENTS 1 @@ -530,318 +530,314 @@ void SimulateTagLowFrequencyBidir(int divisor, int t0) // compose fc/8 fc/10 waveform static void fc(int c, int *n) { - uint8_t *dest = (uint8_t *)BigBuf; - int idx; + uint8_t *dest = (uint8_t *)BigBuf; + int idx; - // for when we want an fc8 pattern every 4 logical bits - if(c==0) { - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - } - // an fc/8 encoded bit is a bit pattern of 11000000 x6 = 48 samples - if(c==8) { - for (idx=0; idx<6; idx++) { - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - } - } + // for when we want an fc8 pattern every 4 logical bits + if(c==0) { + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + } + // an fc/8 encoded bit is a bit pattern of 11000000 x6 = 48 samples + if(c==8) { + for (idx=0; idx<6; idx++) { + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + } + } - // an fc/10 encoded bit is a bit pattern of 1110000000 x5 = 50 samples - if(c==10) { - for (idx=0; idx<5; idx++) { - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - } - } + // an fc/10 encoded bit is a bit pattern of 1110000000 x5 = 50 samples + if(c==10) { + for (idx=0; idx<5; idx++) { + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + } + } } // prepare a waveform pattern in the buffer based on the ID given then // simulate a HID tag until the button is pressed void CmdHIDsimTAG(int hi, int lo, int ledcontrol) { - int n=0, i=0; - /* - HID tag bitstream format - The tag contains a 44bit unique code. This is sent out MSB first in sets of 4 bits - A 1 bit is represented as 6 fc8 and 5 fc10 patterns - A 0 bit is represented as 5 fc10 and 6 fc8 patterns - A fc8 is inserted before every 4 bits - A special start of frame pattern is used consisting a0b0 where a and b are neither 0 - nor 1 bits, they are special patterns (a = set of 12 fc8 and b = set of 10 fc10) - */ + int n=0, i=0; + /* + HID tag bitstream format + The tag contains a 44bit unique code. This is sent out MSB first in sets of 4 bits + A 1 bit is represented as 6 fc8 and 5 fc10 patterns + A 0 bit is represented as 5 fc10 and 6 fc8 patterns + A fc8 is inserted before every 4 bits + A special start of frame pattern is used consisting a0b0 where a and b are neither 0 + nor 1 bits, they are special patterns (a = set of 12 fc8 and b = set of 10 fc10) + */ - if (hi>0xFFF) { - DbpString("Tags can only have 44 bits."); - return; - } - fc(0,&n); - // special start of frame marker containing invalid bit sequences - fc(8, &n); fc(8, &n); // invalid - fc(8, &n); fc(10, &n); // logical 0 - fc(10, &n); fc(10, &n); // invalid - fc(8, &n); fc(10, &n); // logical 0 + if (hi>0xFFF) { + DbpString("Tags can only have 44 bits."); + return; + } + fc(0,&n); + // special start of frame marker containing invalid bit sequences + fc(8, &n); fc(8, &n); // invalid + fc(8, &n); fc(10, &n); // logical 0 + fc(10, &n); fc(10, &n); // invalid + fc(8, &n); fc(10, &n); // logical 0 - WDT_HIT(); - // manchester encode bits 43 to 32 - for (i=11; i>=0; i--) { - if ((i%4)==3) fc(0,&n); - if ((hi>>i)&1) { - fc(10, &n); fc(8, &n); // low-high transition - } else { - fc(8, &n); fc(10, &n); // high-low transition - } - } + WDT_HIT(); + // manchester encode bits 43 to 32 + for (i=11; i>=0; i--) { + if ((i%4)==3) fc(0,&n); + if ((hi>>i)&1) { + fc(10, &n); fc(8, &n); // low-high transition + } else { + fc(8, &n); fc(10, &n); // high-low transition + } + } - WDT_HIT(); - // manchester encode bits 31 to 0 - for (i=31; i>=0; i--) { - if ((i%4)==3) fc(0,&n); - if ((lo>>i)&1) { - fc(10, &n); fc(8, &n); // low-high transition - } else { - fc(8, &n); fc(10, &n); // high-low transition - } - } + WDT_HIT(); + // manchester encode bits 31 to 0 + for (i=31; i>=0; i--) { + if ((i%4)==3) fc(0,&n); + if ((lo>>i)&1) { + fc(10, &n); fc(8, &n); // low-high transition + } else { + fc(8, &n); fc(10, &n); // high-low transition + } + } - if (ledcontrol) - LED_A_ON(); - SimulateTagLowFrequency(n, 0, ledcontrol); + if (ledcontrol) + LED_A_ON(); + SimulateTagLowFrequency(n, 0, ledcontrol); - if (ledcontrol) - LED_A_OFF(); + if (ledcontrol) + LED_A_OFF(); } // loop to get raw HID waveform then FSK demodulate the TAG ID from it void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) { - uint8_t *dest = (uint8_t *)BigBuf; + uint8_t *dest = (uint8_t *)BigBuf; - size_t size=0; //, found=0; - uint32_t hi2=0, hi=0, lo=0; + size_t size=0; //, found=0; + uint32_t hi2=0, hi=0, lo=0; - // Configure to go in 125Khz listen mode - LFSetupFPGAForADC(95, true); + // Configure to go in 125Khz listen mode + LFSetupFPGAForADC(95, true); - while(!BUTTON_PRESS()) { + while(!BUTTON_PRESS()) { - WDT_HIT(); - if (ledcontrol) LED_A_ON(); + WDT_HIT(); + if (ledcontrol) LED_A_ON(); - DoAcquisition125k_internal(-1,true); - size = sizeof(BigBuf); - if (size < 2000) continue; - // FSK demodulator + DoAcquisition125k_internal(-1,true); + size = sizeof(BigBuf); + if (size < 2000) continue; + // FSK demodulator - int bitLen = HIDdemodFSK(dest,size,&hi2,&hi,&lo); - - WDT_HIT(); + int bitLen = HIDdemodFSK(dest,size,&hi2,&hi,&lo); - if (bitLen>0 && lo>0){ - // final loop, go over previously decoded manchester data and decode into usable tag ID - // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0 - if (hi2 != 0){ //extra large HID tags - Dbprintf("TAG ID: %x%08x%08x (%d)", - (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); - }else { //standard HID tags <38 bits - //Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd - uint8_t bitlen = 0; - uint32_t fc = 0; - uint32_t cardnum = 0; - if (((hi>>5)&1)==1){//if bit 38 is set then < 37 bit format is used - uint32_t lo2=0; - lo2=(((hi & 31) << 12) | (lo>>20)); //get bits 21-37 to check for format len bit - uint8_t idx3 = 1; - while(lo2>1){ //find last bit set to 1 (format len bit) - lo2=lo2>>1; - idx3++; - } - bitlen =idx3+19; - fc =0; - cardnum=0; - if(bitlen==26){ - cardnum = (lo>>1)&0xFFFF; - fc = (lo>>17)&0xFF; - } - if(bitlen==37){ - cardnum = (lo>>1)&0x7FFFF; - fc = ((hi&0xF)<<12)|(lo>>20); - } - if(bitlen==34){ - cardnum = (lo>>1)&0xFFFF; - fc= ((hi&1)<<15)|(lo>>17); - } - if(bitlen==35){ - cardnum = (lo>>1)&0xFFFFF; - fc = ((hi&1)<<11)|(lo>>21); - } - } - else { //if bit 38 is not set then 37 bit format is used - bitlen= 37; - fc =0; - cardnum=0; - if(bitlen==37){ - cardnum = (lo>>1)&0x7FFFF; - fc = ((hi&0xF)<<12)|(lo>>20); - } - } - //Dbprintf("TAG ID: %x%08x (%d)", - // (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); - Dbprintf("TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d", - (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF, - (unsigned int) bitlen, (unsigned int) fc, (unsigned int) cardnum); - } - if (findone){ - if (ledcontrol) LED_A_OFF(); - return; - } - // reset - hi2 = hi = lo = 0; - } - WDT_HIT(); - //SpinDelay(50); - } - DbpString("Stopped"); - if (ledcontrol) LED_A_OFF(); + WDT_HIT(); + + if (bitLen>0 && lo>0){ + // final loop, go over previously decoded manchester data and decode into usable tag ID + // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0 + if (hi2 != 0){ //extra large HID tags + Dbprintf("TAG ID: %x%08x%08x (%d)", + (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); + }else { //standard HID tags <38 bits + //Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd + uint8_t bitlen = 0; + uint32_t fc = 0; + uint32_t cardnum = 0; + if (((hi>>5)&1)==1){//if bit 38 is set then < 37 bit format is used + uint32_t lo2=0; + lo2=(((hi & 31) << 12) | (lo>>20)); //get bits 21-37 to check for format len bit + uint8_t idx3 = 1; + while(lo2>1){ //find last bit set to 1 (format len bit) + lo2=lo2>>1; + idx3++; + } + bitlen =idx3+19; + fc =0; + cardnum=0; + if(bitlen==26){ + cardnum = (lo>>1)&0xFFFF; + fc = (lo>>17)&0xFF; + } + if(bitlen==37){ + cardnum = (lo>>1)&0x7FFFF; + fc = ((hi&0xF)<<12)|(lo>>20); + } + if(bitlen==34){ + cardnum = (lo>>1)&0xFFFF; + fc= ((hi&1)<<15)|(lo>>17); + } + if(bitlen==35){ + cardnum = (lo>>1)&0xFFFFF; + fc = ((hi&1)<<11)|(lo>>21); + } + } + else { //if bit 38 is not set then 37 bit format is used + bitlen= 37; + fc =0; + cardnum=0; + if(bitlen==37){ + cardnum = (lo>>1)&0x7FFFF; + fc = ((hi&0xF)<<12)|(lo>>20); + } + } + //Dbprintf("TAG ID: %x%08x (%d)", + // (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); + Dbprintf("TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d", + (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF, + (unsigned int) bitlen, (unsigned int) fc, (unsigned int) cardnum); + } + if (findone){ + if (ledcontrol) LED_A_OFF(); + return; + } + // reset + hi2 = hi = lo = 0; + } + WDT_HIT(); + //SpinDelay(50); + } + DbpString("Stopped"); + if (ledcontrol) LED_A_OFF(); } void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol) { - uint8_t *dest = (uint8_t *)BigBuf; + uint8_t *dest = (uint8_t *)BigBuf; - size_t size=0; //, found=0; - int bitLen=0; - int clk=0, invert=0, errCnt=0; - uint64_t lo=0; - // Configure to go in 125Khz listen mode - LFSetupFPGAForADC(95, true); + size_t size=0; //, found=0; + uint32_t bitLen=0; + int clk=0, invert=0, errCnt=0; + uint64_t lo=0; + // Configure to go in 125Khz listen mode + LFSetupFPGAForADC(95, true); - while(!BUTTON_PRESS()) { + while(!BUTTON_PRESS()) { - WDT_HIT(); - if (ledcontrol) LED_A_ON(); + WDT_HIT(); + if (ledcontrol) LED_A_ON(); - DoAcquisition125k_internal(-1,true); - size = sizeof(BigBuf); - if (size < 2000) continue; - // FSK demodulator - //int askmandemod(uint8_t *BinStream,uint32_t *BitLen,int *clk, int *invert); - bitLen=size; - //Dbprintf("DEBUG: Buffer got"); - errCnt = askmandemod(dest,&bitLen,&clk,&invert); //HIDdemodFSK(dest,size,&hi2,&hi,&lo); - //Dbprintf("DEBUG: ASK Got"); - WDT_HIT(); + DoAcquisition125k_internal(-1,true); + size = sizeof(BigBuf); + if (size < 2000) continue; + // FSK demodulator + //int askmandemod(uint8_t *BinStream,uint32_t *BitLen,int *clk, int *invert); + bitLen=size; + //Dbprintf("DEBUG: Buffer got"); + errCnt = askmandemod(dest,&bitLen,&clk,&invert); //HIDdemodFSK(dest,size,&hi2,&hi,&lo); + //Dbprintf("DEBUG: ASK Got"); + WDT_HIT(); - if (errCnt>=0){ - lo = Em410xDecode(dest,bitLen); - //Dbprintf("DEBUG: EM GOT"); - //printEM410x(lo); - if (lo>0){ - Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)",(uint32_t)(lo>>32),(uint32_t)lo,(uint32_t)(lo&0xFFFF),(uint32_t)((lo>>16LL) & 0xFF),(uint32_t)(lo & 0xFFFFFF)); - } - if (findone){ - if (ledcontrol) LED_A_OFF(); - return; - } - } else{ - //Dbprintf("DEBUG: No Tag"); - } - WDT_HIT(); - lo = 0; - clk=0; - invert=0; - errCnt=0; - size=0; - //SpinDelay(50); - } - DbpString("Stopped"); - if (ledcontrol) LED_A_OFF(); + if (errCnt>=0){ + lo = Em410xDecode(dest,bitLen); + //Dbprintf("DEBUG: EM GOT"); + //printEM410x(lo); + if (lo>0){ + Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)",(uint32_t)(lo>>32),(uint32_t)lo,(uint32_t)(lo&0xFFFF),(uint32_t)((lo>>16LL) & 0xFF),(uint32_t)(lo & 0xFFFFFF)); + } + if (findone){ + if (ledcontrol) LED_A_OFF(); + return; + } + } else{ + //Dbprintf("DEBUG: No Tag"); + } + WDT_HIT(); + lo = 0; + clk=0; + invert=0; + errCnt=0; + size=0; + //SpinDelay(50); + } + DbpString("Stopped"); + if (ledcontrol) LED_A_OFF(); } void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) { - uint8_t *dest = (uint8_t *)BigBuf; - size_t size=0; - int idx=0; - uint32_t code=0, code2=0; - uint8_t version=0; - uint8_t facilitycode=0; - uint16_t number=0; - // Configure to go in 125Khz listen mode - LFSetupFPGAForADC(95, true); - - while(!BUTTON_PRESS()) { - WDT_HIT(); - if (ledcontrol) LED_A_ON(); - DoAcquisition125k_internal(-1,true); - size = sizeof(BigBuf); - //make sure buffer has data - if (size < 2000) continue; - //fskdemod and get start index - WDT_HIT(); - idx = IOdemodFSK(dest,size); - if (idx>0){ - //valid tag found + uint8_t *dest = (uint8_t *)BigBuf; + int idx=0; + uint32_t code=0, code2=0; + uint8_t version=0; + uint8_t facilitycode=0; + uint16_t number=0; + // Configure to go in 125Khz listen mode + LFSetupFPGAForADC(95, true); - //Index map - //0 10 20 30 40 50 60 - //| | | | | | | - //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23 - //----------------------------------------------------------------------------- - //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11 - // - //XSF(version)facility:codeone+codetwo - //Handle the data - if(findone){ //only print binary if we are doing one - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx], dest[idx+1], dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7],dest[idx+8]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15],dest[idx+16],dest[idx+17]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23],dest[idx+24],dest[idx+25],dest[idx+26]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31],dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39],dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+45],dest[idx+46],dest[idx+47],dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53]); - Dbprintf("%d%d%d%d%d%d%d%d %d%d",dest[idx+54],dest[idx+55],dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]); - } - code = bytebits_to_byte(dest+idx,32); - code2 = bytebits_to_byte(dest+idx+32,32); - version = bytebits_to_byte(dest+idx+27,8); //14,4 - facilitycode = bytebits_to_byte(dest+idx+18,8) ; - number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9 - - Dbprintf("XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2); - // if we're only looking for one tag - if (findone){ - if (ledcontrol) LED_A_OFF(); - //LED_A_OFF(); - return; - } - code=code2=0; - version=facilitycode=0; - number=0; - idx=0; - } - WDT_HIT(); - } - DbpString("Stopped"); - if (ledcontrol) LED_A_OFF(); + while(!BUTTON_PRESS()) { + WDT_HIT(); + if (ledcontrol) LED_A_ON(); + DoAcquisition125k_internal(-1,true); + //fskdemod and get start index + WDT_HIT(); + idx = IOdemodFSK(dest,sizeof(BigBuf)); + if (idx>0){ + //valid tag found + + //Index map + //0 10 20 30 40 50 60 + //| | | | | | | + //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23 + //----------------------------------------------------------------------------- + //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11 + // + //XSF(version)facility:codeone+codetwo + //Handle the data + if(findone){ //only print binary if we are doing one + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx], dest[idx+1], dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7],dest[idx+8]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15],dest[idx+16],dest[idx+17]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23],dest[idx+24],dest[idx+25],dest[idx+26]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31],dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39],dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+45],dest[idx+46],dest[idx+47],dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53]); + Dbprintf("%d%d%d%d%d%d%d%d %d%d",dest[idx+54],dest[idx+55],dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]); + } + code = bytebits_to_byte(dest+idx,32); + code2 = bytebits_to_byte(dest+idx+32,32); + version = bytebits_to_byte(dest+idx+27,8); //14,4 + facilitycode = bytebits_to_byte(dest+idx+18,8) ; + number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9 + + Dbprintf("XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2); + // if we're only looking for one tag + if (findone){ + if (ledcontrol) LED_A_OFF(); + //LED_A_OFF(); + return; + } + code=code2=0; + version=facilitycode=0; + number=0; + idx=0; + } + WDT_HIT(); + } + DbpString("Stopped"); + if (ledcontrol) LED_A_OFF(); } /*------------------------------ @@ -911,307 +907,307 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) // Write one bit to card void T55xxWriteBit(int bit) { - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - if (bit == 0) - SpinDelayUs(WRITE_0); - else - SpinDelayUs(WRITE_1); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelayUs(WRITE_GAP); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + if (bit == 0) + SpinDelayUs(WRITE_0); + else + SpinDelayUs(WRITE_1); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelayUs(WRITE_GAP); } // Write one card block in page 0, no lock void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode) { - //unsigned int i; //enio adjustment 12/10/14 - uint32_t i; + //unsigned int i; //enio adjustment 12/10/14 + uint32_t i; - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // Give it a bit of time for the resonant antenna to settle. - // And for the tag to fully power up - SpinDelay(150); + // Give it a bit of time for the resonant antenna to settle. + // And for the tag to fully power up + SpinDelay(150); - // Now start writting - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelayUs(START_GAP); + // Now start writting + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelayUs(START_GAP); - // Opcode - T55xxWriteBit(1); - T55xxWriteBit(0); //Page 0 - if (PwdMode == 1){ - // Pwd + // Opcode + T55xxWriteBit(1); + T55xxWriteBit(0); //Page 0 + if (PwdMode == 1){ + // Pwd + for (i = 0x80000000; i != 0; i >>= 1) + T55xxWriteBit(Pwd & i); + } + // Lock bit + T55xxWriteBit(0); + + // Data for (i = 0x80000000; i != 0; i >>= 1) - T55xxWriteBit(Pwd & i); - } - // Lock bit - T55xxWriteBit(0); + T55xxWriteBit(Data & i); - // Data - for (i = 0x80000000; i != 0; i >>= 1) - T55xxWriteBit(Data & i); + // Block + for (i = 0x04; i != 0; i >>= 1) + T55xxWriteBit(Block & i); - // Block - for (i = 0x04; i != 0; i >>= 1) - T55xxWriteBit(Block & i); - - // Now perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550, - // so wait a little more) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - SpinDelay(20); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + // Now perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550, + // so wait a little more) + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + SpinDelay(20); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); } // Read one card block in page 0 void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode) { - uint8_t *dest = (uint8_t *)BigBuf; - //int m=0, i=0; //enio adjustment 12/10/14 - uint32_t m=0, i=0; - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - m = sizeof(BigBuf); - // Clear destination buffer before sending the command - memset(dest, 128, m); - // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); - - LED_D_ON(); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - - // Give it a bit of time for the resonant antenna to settle. - // And for the tag to fully power up - SpinDelay(150); - - // Now start writting - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelayUs(START_GAP); - - // Opcode - T55xxWriteBit(1); - T55xxWriteBit(0); //Page 0 - if (PwdMode == 1){ - // Pwd - for (i = 0x80000000; i != 0; i >>= 1) - T55xxWriteBit(Pwd & i); - } - // Lock bit - T55xxWriteBit(0); - // Block - for (i = 0x04; i != 0; i >>= 1) - T55xxWriteBit(Block & i); - - // Turn field on to read the response - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - - // Now do the acquisition - i = 0; - for(;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - // we don't care about actual value, only if it's more or less than a - // threshold essentially we capture zero crossings for later analysis - // if(dest[i] < 127) dest[i] = 0; else dest[i] = 1; - i++; - if (i >= m) break; - } - } - - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); - DbpString("DONE!"); + uint8_t *dest = (uint8_t *)BigBuf; + //int m=0, i=0; //enio adjustment 12/10/14 + uint32_t m=0, i=0; + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + m = sizeof(BigBuf); + // Clear destination buffer before sending the command + memset(dest, 128, m); + // Connect the A/D to the peak-detected low-frequency path. + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); + + LED_D_ON(); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + + // Give it a bit of time for the resonant antenna to settle. + // And for the tag to fully power up + SpinDelay(150); + + // Now start writting + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelayUs(START_GAP); + + // Opcode + T55xxWriteBit(1); + T55xxWriteBit(0); //Page 0 + if (PwdMode == 1){ + // Pwd + for (i = 0x80000000; i != 0; i >>= 1) + T55xxWriteBit(Pwd & i); + } + // Lock bit + T55xxWriteBit(0); + // Block + for (i = 0x04; i != 0; i >>= 1) + T55xxWriteBit(Block & i); + + // Turn field on to read the response + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + + // Now do the acquisition + i = 0; + for(;;) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0x43; + } + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + // we don't care about actual value, only if it's more or less than a + // threshold essentially we capture zero crossings for later analysis + // if(dest[i] < 127) dest[i] = 0; else dest[i] = 1; + i++; + if (i >= m) break; + } + } + + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + LED_D_OFF(); + DbpString("DONE!"); } // Read card traceability data (page 1) void T55xxReadTrace(void){ - uint8_t *dest = (uint8_t *)BigBuf; - int m=0, i=0; - - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - m = sizeof(BigBuf); - // Clear destination buffer before sending the command - memset(dest, 128, m); - // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); - - LED_D_ON(); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - - // Give it a bit of time for the resonant antenna to settle. - // And for the tag to fully power up - SpinDelay(150); - - // Now start writting - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelayUs(START_GAP); - - // Opcode - T55xxWriteBit(1); - T55xxWriteBit(1); //Page 1 - - // Turn field on to read the response - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - - // Now do the acquisition - i = 0; - for(;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - i++; - if (i >= m) break; - } - } - - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); - DbpString("DONE!"); + uint8_t *dest = (uint8_t *)BigBuf; + int m=0, i=0; + + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + m = sizeof(BigBuf); + // Clear destination buffer before sending the command + memset(dest, 128, m); + // Connect the A/D to the peak-detected low-frequency path. + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); + + LED_D_ON(); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + + // Give it a bit of time for the resonant antenna to settle. + // And for the tag to fully power up + SpinDelay(150); + + // Now start writting + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelayUs(START_GAP); + + // Opcode + T55xxWriteBit(1); + T55xxWriteBit(1); //Page 1 + + // Turn field on to read the response + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + + // Now do the acquisition + i = 0; + for(;;) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0x43; + } + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + i++; + if (i >= m) break; + } + } + + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + LED_D_OFF(); + DbpString("DONE!"); } /*-------------- Cloning routines -----------*/ // Copy HID id to card and setup block 0 config void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT) { - int data1=0, data2=0, data3=0, data4=0, data5=0, data6=0; //up to six blocks for long format - int last_block = 0; - - if (longFMT){ - // Ensure no more than 84 bits supplied - if (hi2>0xFFFFF) { - DbpString("Tags can only have 84 bits."); - return; - } - // Build the 6 data blocks for supplied 84bit ID - last_block = 6; - data1 = 0x1D96A900; // load preamble (1D) & long format identifier (9E manchester encoded) - for (int i=0;i<4;i++) { - if (hi2 & (1<<(19-i))) - data1 |= (1<<(((3-i)*2)+1)); // 1 -> 10 - else - data1 |= (1<<((3-i)*2)); // 0 -> 01 - } - - data2 = 0; - for (int i=0;i<16;i++) { - if (hi2 & (1<<(15-i))) - data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data2 |= (1<<((15-i)*2)); // 0 -> 01 + int data1=0, data2=0, data3=0, data4=0, data5=0, data6=0; //up to six blocks for long format + int last_block = 0; + + if (longFMT){ + // Ensure no more than 84 bits supplied + if (hi2>0xFFFFF) { + DbpString("Tags can only have 84 bits."); + return; + } + // Build the 6 data blocks for supplied 84bit ID + last_block = 6; + data1 = 0x1D96A900; // load preamble (1D) & long format identifier (9E manchester encoded) + for (int i=0;i<4;i++) { + if (hi2 & (1<<(19-i))) + data1 |= (1<<(((3-i)*2)+1)); // 1 -> 10 + else + data1 |= (1<<((3-i)*2)); // 0 -> 01 + } + + data2 = 0; + for (int i=0;i<16;i++) { + if (hi2 & (1<<(15-i))) + data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data2 |= (1<<((15-i)*2)); // 0 -> 01 + } + + data3 = 0; + for (int i=0;i<16;i++) { + if (hi & (1<<(31-i))) + data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data3 |= (1<<((15-i)*2)); // 0 -> 01 + } + + data4 = 0; + for (int i=0;i<16;i++) { + if (hi & (1<<(15-i))) + data4 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data4 |= (1<<((15-i)*2)); // 0 -> 01 + } + + data5 = 0; + for (int i=0;i<16;i++) { + if (lo & (1<<(31-i))) + data5 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data5 |= (1<<((15-i)*2)); // 0 -> 01 + } + + data6 = 0; + for (int i=0;i<16;i++) { + if (lo & (1<<(15-i))) + data6 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data6 |= (1<<((15-i)*2)); // 0 -> 01 + } } - - data3 = 0; - for (int i=0;i<16;i++) { - if (hi & (1<<(31-i))) - data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data3 |= (1<<((15-i)*2)); // 0 -> 01 - } - - data4 = 0; - for (int i=0;i<16;i++) { - if (hi & (1<<(15-i))) - data4 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data4 |= (1<<((15-i)*2)); // 0 -> 01 + else { + // Ensure no more than 44 bits supplied + if (hi>0xFFF) { + DbpString("Tags can only have 44 bits."); + return; + } + + // Build the 3 data blocks for supplied 44bit ID + last_block = 3; + + data1 = 0x1D000000; // load preamble + + for (int i=0;i<12;i++) { + if (hi & (1<<(11-i))) + data1 |= (1<<(((11-i)*2)+1)); // 1 -> 10 + else + data1 |= (1<<((11-i)*2)); // 0 -> 01 + } + + data2 = 0; + for (int i=0;i<16;i++) { + if (lo & (1<<(31-i))) + data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data2 |= (1<<((15-i)*2)); // 0 -> 01 + } + + data3 = 0; + for (int i=0;i<16;i++) { + if (lo & (1<<(15-i))) + data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data3 |= (1<<((15-i)*2)); // 0 -> 01 + } } - - data5 = 0; - for (int i=0;i<16;i++) { - if (lo & (1<<(31-i))) - data5 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data5 |= (1<<((15-i)*2)); // 0 -> 01 - } - - data6 = 0; - for (int i=0;i<16;i++) { - if (lo & (1<<(15-i))) - data6 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data6 |= (1<<((15-i)*2)); // 0 -> 01 + + LED_D_ON(); + // Program the data blocks for supplied ID + // and the block 0 for HID format + T55xxWriteBlock(data1,1,0,0); + T55xxWriteBlock(data2,2,0,0); + T55xxWriteBlock(data3,3,0,0); + + if (longFMT) { // if long format there are 6 blocks + T55xxWriteBlock(data4,4,0,0); + T55xxWriteBlock(data5,5,0,0); + T55xxWriteBlock(data6,6,0,0); } - } - else { - // Ensure no more than 44 bits supplied - if (hi>0xFFF) { - DbpString("Tags can only have 44 bits."); - return; - } - - // Build the 3 data blocks for supplied 44bit ID - last_block = 3; - - data1 = 0x1D000000; // load preamble - - for (int i=0;i<12;i++) { - if (hi & (1<<(11-i))) - data1 |= (1<<(((11-i)*2)+1)); // 1 -> 10 - else - data1 |= (1<<((11-i)*2)); // 0 -> 01 - } - - data2 = 0; - for (int i=0;i<16;i++) { - if (lo & (1<<(31-i))) - data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data2 |= (1<<((15-i)*2)); // 0 -> 01 - } - - data3 = 0; - for (int i=0;i<16;i++) { - if (lo & (1<<(15-i))) - data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data3 |= (1<<((15-i)*2)); // 0 -> 01 - } - } - - LED_D_ON(); - // Program the data blocks for supplied ID - // and the block 0 for HID format - T55xxWriteBlock(data1,1,0,0); - T55xxWriteBlock(data2,2,0,0); - T55xxWriteBlock(data3,3,0,0); - - if (longFMT) { // if long format there are 6 blocks - T55xxWriteBlock(data4,4,0,0); - T55xxWriteBlock(data5,5,0,0); - T55xxWriteBlock(data6,6,0,0); - } - - // Config for HID (RF/50, FSK2a, Maxblock=3 for short/6 for long) - T55xxWriteBlock(T55x7_BITRATE_RF_50 | - T55x7_MODULATION_FSK2a | - last_block << T55x7_MAXBLOCK_SHIFT, - 0,0,0); - - LED_D_OFF(); - - DbpString("DONE!"); + + // Config for HID (RF/50, FSK2a, Maxblock=3 for short/6 for long) + T55xxWriteBlock(T55x7_BITRATE_RF_50 | + T55x7_MODULATION_FSK2a | + last_block << T55x7_MAXBLOCK_SHIFT, + 0,0,0); + + LED_D_OFF(); + + DbpString("DONE!"); } void CopyIOtoT55x7(uint32_t hi, uint32_t lo, uint8_t longFMT) { - int data1=0, data2=0; //up to six blocks for long format - + int data1=0, data2=0; //up to six blocks for long format + data1 = hi; // load preamble data2 = lo; @@ -1220,11 +1216,11 @@ void CopyIOtoT55x7(uint32_t hi, uint32_t lo, uint8_t longFMT) // and the block 0 for HID format T55xxWriteBlock(data1,1,0,0); T55xxWriteBlock(data2,2,0,0); - + //Config Block T55xxWriteBlock(0x00147040,0,0,0); LED_D_OFF(); - + DbpString("DONE!"); } @@ -1234,151 +1230,151 @@ void CopyIOtoT55x7(uint32_t hi, uint32_t lo, uint8_t longFMT) void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo) { - int i, id_bit; - uint64_t id = EM410X_HEADER; - uint64_t rev_id = 0; // reversed ID - int c_parity[4]; // column parity - int r_parity = 0; // row parity - uint32_t clock = 0; + int i, id_bit; + uint64_t id = EM410X_HEADER; + uint64_t rev_id = 0; // reversed ID + int c_parity[4]; // column parity + int r_parity = 0; // row parity + uint32_t clock = 0; - // Reverse ID bits given as parameter (for simpler operations) - for (i = 0; i < EM410X_ID_LENGTH; ++i) { - if (i < 32) { - rev_id = (rev_id << 1) | (id_lo & 1); - id_lo >>= 1; - } else { - rev_id = (rev_id << 1) | (id_hi & 1); - id_hi >>= 1; - } - } + // Reverse ID bits given as parameter (for simpler operations) + for (i = 0; i < EM410X_ID_LENGTH; ++i) { + if (i < 32) { + rev_id = (rev_id << 1) | (id_lo & 1); + id_lo >>= 1; + } else { + rev_id = (rev_id << 1) | (id_hi & 1); + id_hi >>= 1; + } + } - for (i = 0; i < EM410X_ID_LENGTH; ++i) { - id_bit = rev_id & 1; + for (i = 0; i < EM410X_ID_LENGTH; ++i) { + id_bit = rev_id & 1; - if (i % 4 == 0) { - // Don't write row parity bit at start of parsing - if (i) - id = (id << 1) | r_parity; - // Start counting parity for new row - r_parity = id_bit; - } else { - // Count row parity - r_parity ^= id_bit; - } + if (i % 4 == 0) { + // Don't write row parity bit at start of parsing + if (i) + id = (id << 1) | r_parity; + // Start counting parity for new row + r_parity = id_bit; + } else { + // Count row parity + r_parity ^= id_bit; + } - // First elements in column? - if (i < 4) - // Fill out first elements - c_parity[i] = id_bit; - else - // Count column parity - c_parity[i % 4] ^= id_bit; + // First elements in column? + if (i < 4) + // Fill out first elements + c_parity[i] = id_bit; + else + // Count column parity + c_parity[i % 4] ^= id_bit; - // Insert ID bit - id = (id << 1) | id_bit; - rev_id >>= 1; - } + // Insert ID bit + id = (id << 1) | id_bit; + rev_id >>= 1; + } - // Insert parity bit of last row - id = (id << 1) | r_parity; + // Insert parity bit of last row + id = (id << 1) | r_parity; - // Fill out column parity at the end of tag - for (i = 0; i < 4; ++i) - id = (id << 1) | c_parity[i]; + // Fill out column parity at the end of tag + for (i = 0; i < 4; ++i) + id = (id << 1) | c_parity[i]; - // Add stop bit - id <<= 1; + // Add stop bit + id <<= 1; - Dbprintf("Started writing %s tag ...", card ? "T55x7":"T5555"); - LED_D_ON(); + Dbprintf("Started writing %s tag ...", card ? "T55x7":"T5555"); + LED_D_ON(); - // Write EM410x ID - T55xxWriteBlock((uint32_t)(id >> 32), 1, 0, 0); - T55xxWriteBlock((uint32_t)id, 2, 0, 0); + // Write EM410x ID + T55xxWriteBlock((uint32_t)(id >> 32), 1, 0, 0); + T55xxWriteBlock((uint32_t)id, 2, 0, 0); - // Config for EM410x (RF/64, Manchester, Maxblock=2) - if (card) { - // Clock rate is stored in bits 8-15 of the card value - clock = (card & 0xFF00) >> 8; - Dbprintf("Clock rate: %d", clock); - switch (clock) - { - case 32: - clock = T55x7_BITRATE_RF_32; - break; - case 16: - clock = T55x7_BITRATE_RF_16; - break; - case 0: - // A value of 0 is assumed to be 64 for backwards-compatibility - // Fall through... - case 64: - clock = T55x7_BITRATE_RF_64; - break; - default: - Dbprintf("Invalid clock rate: %d", clock); - return; - } + // Config for EM410x (RF/64, Manchester, Maxblock=2) + if (card) { + // Clock rate is stored in bits 8-15 of the card value + clock = (card & 0xFF00) >> 8; + Dbprintf("Clock rate: %d", clock); + switch (clock) + { + case 32: + clock = T55x7_BITRATE_RF_32; + break; + case 16: + clock = T55x7_BITRATE_RF_16; + break; + case 0: + // A value of 0 is assumed to be 64 for backwards-compatibility + // Fall through... + case 64: + clock = T55x7_BITRATE_RF_64; + break; + default: + Dbprintf("Invalid clock rate: %d", clock); + return; + } - // Writing configuration for T55x7 tag - T55xxWriteBlock(clock | - T55x7_MODULATION_MANCHESTER | - 2 << T55x7_MAXBLOCK_SHIFT, - 0, 0, 0); - } - else - // Writing configuration for T5555(Q5) tag - T55xxWriteBlock(0x1F << T5555_BITRATE_SHIFT | - T5555_MODULATION_MANCHESTER | - 2 << T5555_MAXBLOCK_SHIFT, - 0, 0, 0); + // Writing configuration for T55x7 tag + T55xxWriteBlock(clock | + T55x7_MODULATION_MANCHESTER | + 2 << T55x7_MAXBLOCK_SHIFT, + 0, 0, 0); + } + else + // Writing configuration for T5555(Q5) tag + T55xxWriteBlock(0x1F << T5555_BITRATE_SHIFT | + T5555_MODULATION_MANCHESTER | + 2 << T5555_MAXBLOCK_SHIFT, + 0, 0, 0); - LED_D_OFF(); - Dbprintf("Tag %s written with 0x%08x%08x\n", card ? "T55x7":"T5555", - (uint32_t)(id >> 32), (uint32_t)id); + LED_D_OFF(); + Dbprintf("Tag %s written with 0x%08x%08x\n", card ? "T55x7":"T5555", + (uint32_t)(id >> 32), (uint32_t)id); } // Clone Indala 64-bit tag by UID to T55x7 void CopyIndala64toT55x7(int hi, int lo) { - //Program the 2 data blocks for supplied 64bit UID - // and the block 0 for Indala64 format - T55xxWriteBlock(hi,1,0,0); - T55xxWriteBlock(lo,2,0,0); - //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=2) - T55xxWriteBlock(T55x7_BITRATE_RF_32 | - T55x7_MODULATION_PSK1 | - 2 << T55x7_MAXBLOCK_SHIFT, - 0, 0, 0); - //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data) -// T5567WriteBlock(0x603E1042,0); + //Program the 2 data blocks for supplied 64bit UID + // and the block 0 for Indala64 format + T55xxWriteBlock(hi,1,0,0); + T55xxWriteBlock(lo,2,0,0); + //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=2) + T55xxWriteBlock(T55x7_BITRATE_RF_32 | + T55x7_MODULATION_PSK1 | + 2 << T55x7_MAXBLOCK_SHIFT, + 0, 0, 0); + //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data) + // T5567WriteBlock(0x603E1042,0); - DbpString("DONE!"); + DbpString("DONE!"); } void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int uid6, int uid7) { - //Program the 7 data blocks for supplied 224bit UID - // and the block 0 for Indala224 format - T55xxWriteBlock(uid1,1,0,0); - T55xxWriteBlock(uid2,2,0,0); - T55xxWriteBlock(uid3,3,0,0); - T55xxWriteBlock(uid4,4,0,0); - T55xxWriteBlock(uid5,5,0,0); - T55xxWriteBlock(uid6,6,0,0); - T55xxWriteBlock(uid7,7,0,0); - //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=7) - T55xxWriteBlock(T55x7_BITRATE_RF_32 | - T55x7_MODULATION_PSK1 | - 7 << T55x7_MAXBLOCK_SHIFT, - 0,0,0); - //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data) -// T5567WriteBlock(0x603E10E2,0); + //Program the 7 data blocks for supplied 224bit UID + // and the block 0 for Indala224 format + T55xxWriteBlock(uid1,1,0,0); + T55xxWriteBlock(uid2,2,0,0); + T55xxWriteBlock(uid3,3,0,0); + T55xxWriteBlock(uid4,4,0,0); + T55xxWriteBlock(uid5,5,0,0); + T55xxWriteBlock(uid6,6,0,0); + T55xxWriteBlock(uid7,7,0,0); + //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=7) + T55xxWriteBlock(T55x7_BITRATE_RF_32 | + T55x7_MODULATION_PSK1 | + 7 << T55x7_MAXBLOCK_SHIFT, + 0,0,0); + //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data) + // T5567WriteBlock(0x603E10E2,0); - DbpString("DONE!"); + DbpString("DONE!"); } @@ -1387,261 +1383,261 @@ void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int #define max(x,y) ( x GraphBuffer[0]) { - while(i < GraphTraceLen) { - if( !(GraphBuffer[i] > GraphBuffer[i-1]) && GraphBuffer[i] > lmax) - break; - i++; + uint8_t BitStream[256]; + uint8_t Blocks[8][16]; + uint8_t *GraphBuffer = (uint8_t *)BigBuf; + int GraphTraceLen = sizeof(BigBuf); + int i, j, lastval, bitidx, half_switch; + int clock = 64; + int tolerance = clock / 8; + int pmc, block_done; + int lc, warnings = 0; + int num_blocks = 0; + int lmin=128, lmax=128; + uint8_t dir; + + AcquireRawAdcSamples125k(0); + + lmin = 64; + lmax = 192; + + i = 2; + + /* Find first local max/min */ + if(GraphBuffer[1] > GraphBuffer[0]) { + while(i < GraphTraceLen) { + if( !(GraphBuffer[i] > GraphBuffer[i-1]) && GraphBuffer[i] > lmax) + break; + i++; + } + dir = 0; } - dir = 0; - } - else { - while(i < GraphTraceLen) { - if( !(GraphBuffer[i] < GraphBuffer[i-1]) && GraphBuffer[i] < lmin) - break; - i++; + else { + while(i < GraphTraceLen) { + if( !(GraphBuffer[i] < GraphBuffer[i-1]) && GraphBuffer[i] < lmin) + break; + i++; + } + dir = 1; } - dir = 1; - } - - lastval = i++; - half_switch = 0; - pmc = 0; - block_done = 0; - - for (bitidx = 0; i < GraphTraceLen; i++) - { - if ( (GraphBuffer[i-1] > GraphBuffer[i] && dir == 1 && GraphBuffer[i] > lmax) || (GraphBuffer[i-1] < GraphBuffer[i] && dir == 0 && GraphBuffer[i] < lmin)) - { - lc = i - lastval; - lastval = i; - - // Switch depending on lc length: - // Tolerance is 1/8 of clock rate (arbitrary) - if (abs(lc-clock/4) < tolerance) { - // 16T0 - if((i - pmc) == lc) { /* 16T0 was previous one */ - /* It's a PMC ! */ - i += (128+127+16+32+33+16)-1; - lastval = i; - pmc = 0; - block_done = 1; - } - else { - pmc = i; - } - } else if (abs(lc-clock/2) < tolerance) { - // 32TO - if((i - pmc) == lc) { /* 16T0 was previous one */ - /* It's a PMC ! */ - i += (128+127+16+32+33)-1; - lastval = i; - pmc = 0; - block_done = 1; - } - else if(half_switch == 1) { - BitStream[bitidx++] = 0; - half_switch = 0; - } - else - half_switch++; - } else if (abs(lc-clock) < tolerance) { - // 64TO - BitStream[bitidx++] = 1; - } else { - // Error - warnings++; - if (warnings > 10) - { - Dbprintf("Error: too many detection errors, aborting."); - return 0; - } - } - - if(block_done == 1) { - if(bitidx == 128) { - for(j=0; j<16; j++) { - Blocks[num_blocks][j] = 128*BitStream[j*8+7]+ - 64*BitStream[j*8+6]+ - 32*BitStream[j*8+5]+ - 16*BitStream[j*8+4]+ - 8*BitStream[j*8+3]+ - 4*BitStream[j*8+2]+ - 2*BitStream[j*8+1]+ - BitStream[j*8]; - } - num_blocks++; - } - bitidx = 0; - block_done = 0; - half_switch = 0; - } - if(i < GraphTraceLen) - { - if (GraphBuffer[i-1] > GraphBuffer[i]) dir=0; - else dir = 1; - } - } - if(bitidx==255) - bitidx=0; - warnings = 0; - if(num_blocks == 4) break; - } - memcpy(outBlocks, Blocks, 16*num_blocks); - return num_blocks; + + lastval = i++; + half_switch = 0; + pmc = 0; + block_done = 0; + + for (bitidx = 0; i < GraphTraceLen; i++) + { + if ( (GraphBuffer[i-1] > GraphBuffer[i] && dir == 1 && GraphBuffer[i] > lmax) || (GraphBuffer[i-1] < GraphBuffer[i] && dir == 0 && GraphBuffer[i] < lmin)) + { + lc = i - lastval; + lastval = i; + + // Switch depending on lc length: + // Tolerance is 1/8 of clock rate (arbitrary) + if (abs(lc-clock/4) < tolerance) { + // 16T0 + if((i - pmc) == lc) { /* 16T0 was previous one */ + /* It's a PMC ! */ + i += (128+127+16+32+33+16)-1; + lastval = i; + pmc = 0; + block_done = 1; + } + else { + pmc = i; + } + } else if (abs(lc-clock/2) < tolerance) { + // 32TO + if((i - pmc) == lc) { /* 16T0 was previous one */ + /* It's a PMC ! */ + i += (128+127+16+32+33)-1; + lastval = i; + pmc = 0; + block_done = 1; + } + else if(half_switch == 1) { + BitStream[bitidx++] = 0; + half_switch = 0; + } + else + half_switch++; + } else if (abs(lc-clock) < tolerance) { + // 64TO + BitStream[bitidx++] = 1; + } else { + // Error + warnings++; + if (warnings > 10) + { + Dbprintf("Error: too many detection errors, aborting."); + return 0; + } + } + + if(block_done == 1) { + if(bitidx == 128) { + for(j=0; j<16; j++) { + Blocks[num_blocks][j] = 128*BitStream[j*8+7]+ + 64*BitStream[j*8+6]+ + 32*BitStream[j*8+5]+ + 16*BitStream[j*8+4]+ + 8*BitStream[j*8+3]+ + 4*BitStream[j*8+2]+ + 2*BitStream[j*8+1]+ + BitStream[j*8]; + } + num_blocks++; + } + bitidx = 0; + block_done = 0; + half_switch = 0; + } + if(i < GraphTraceLen) + { + if (GraphBuffer[i-1] > GraphBuffer[i]) dir=0; + else dir = 1; + } + } + if(bitidx==255) + bitidx=0; + warnings = 0; + if(num_blocks == 4) break; + } + memcpy(outBlocks, Blocks, 16*num_blocks); + return num_blocks; } int IsBlock0PCF7931(uint8_t *Block) { - // Assume RFU means 0 :) - if((memcmp(Block, "\x00\x00\x00\x00\x00\x00\x00\x01", 8) == 0) && memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) // PAC enabled - return 1; - if((memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) && Block[7] == 0) // PAC disabled, can it *really* happen ? - return 1; - return 0; + // Assume RFU means 0 :) + if((memcmp(Block, "\x00\x00\x00\x00\x00\x00\x00\x01", 8) == 0) && memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) // PAC enabled + return 1; + if((memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) && Block[7] == 0) // PAC disabled, can it *really* happen ? + return 1; + return 0; } int IsBlock1PCF7931(uint8_t *Block) { - // Assume RFU means 0 :) - if(Block[10] == 0 && Block[11] == 0 && Block[12] == 0 && Block[13] == 0) - if((Block[14] & 0x7f) <= 9 && Block[15] <= 9) - return 1; - - return 0; + // Assume RFU means 0 :) + if(Block[10] == 0 && Block[11] == 0 && Block[12] == 0 && Block[13] == 0) + if((Block[14] & 0x7f) <= 9 && Block[15] <= 9) + return 1; + + return 0; } #define ALLOC 16 void ReadPCF7931() { - uint8_t Blocks[8][17]; - uint8_t tmpBlocks[4][16]; - int i, j, ind, ind2, n; - int num_blocks = 0; - int max_blocks = 8; - int ident = 0; - int error = 0; - int tries = 0; - - memset(Blocks, 0, 8*17*sizeof(uint8_t)); - - do { - memset(tmpBlocks, 0, 4*16*sizeof(uint8_t)); - n = DemodPCF7931((uint8_t**)tmpBlocks); - if(!n) - error++; - if(error==10 && num_blocks == 0) { - Dbprintf("Error, no tag or bad tag"); - return; - } - else if (tries==20 || error==10) { - Dbprintf("Error reading the tag"); - Dbprintf("Here is the partial content"); - goto end; - } - - for(i=0; i= 0; ind--,ind2--) { - if(ind2 < 0) - ind2 = max_blocks; - if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found - // Dbprintf("Tmp %d -> Block %d", ind, ind2); - memcpy(Blocks[ind2], tmpBlocks[ind], 16); - Blocks[ind2][ALLOC] = 1; - num_blocks++; - if(num_blocks == max_blocks) goto end; - } - } - for(ind=i+1,ind2=j+1; ind < n; ind++,ind2++) { - if(ind2 > max_blocks) - ind2 = 0; - if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found - // Dbprintf("Tmp %d -> Block %d", ind, ind2); - memcpy(Blocks[ind2], tmpBlocks[ind], 16); - Blocks[ind2][ALLOC] = 1; - num_blocks++; - if(num_blocks == max_blocks) goto end; - } - } - } - } + else if (tries==20 || error==10) { + Dbprintf("Error reading the tag"); + Dbprintf("Here is the partial content"); + goto end; } - } - } - tries++; - if (BUTTON_PRESS()) return; - } while (num_blocks != max_blocks); + + for(i=0; i= 0; ind--,ind2--) { + if(ind2 < 0) + ind2 = max_blocks; + if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found + // Dbprintf("Tmp %d -> Block %d", ind, ind2); + memcpy(Blocks[ind2], tmpBlocks[ind], 16); + Blocks[ind2][ALLOC] = 1; + num_blocks++; + if(num_blocks == max_blocks) goto end; + } + } + for(ind=i+1,ind2=j+1; ind < n; ind++,ind2++) { + if(ind2 > max_blocks) + ind2 = 0; + if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found + // Dbprintf("Tmp %d -> Block %d", ind, ind2); + memcpy(Blocks[ind2], tmpBlocks[ind], 16); + Blocks[ind2][ALLOC] = 1; + num_blocks++; + if(num_blocks == max_blocks) goto end; + } + } + } + } + } + } + } + tries++; + if (BUTTON_PRESS()) return; + } while (num_blocks != max_blocks); end: - Dbprintf("-----------------------------------------"); - Dbprintf("Memory content:"); - Dbprintf("-----------------------------------------"); - for(i=0; i", i); - } - Dbprintf("-----------------------------------------"); - - return ; + Dbprintf("-----------------------------------------"); + Dbprintf("Memory content:"); + Dbprintf("-----------------------------------------"); + for(i=0; i", i); + } + Dbprintf("-----------------------------------------"); + + return ; } @@ -1665,20 +1661,20 @@ uint8_t * fwd_write_ptr; //forwardlink bit pointer //==================================================================== //-------------------------------------------------------------------- uint8_t Prepare_Cmd( uint8_t cmd ) { - //-------------------------------------------------------------------- - - *forward_ptr++ = 0; //start bit - *forward_ptr++ = 0; //second pause for 4050 code - - *forward_ptr++ = cmd; - cmd >>= 1; - *forward_ptr++ = cmd; - cmd >>= 1; - *forward_ptr++ = cmd; - cmd >>= 1; - *forward_ptr++ = cmd; - - return 6; //return number of emited bits + //-------------------------------------------------------------------- + + *forward_ptr++ = 0; //start bit + *forward_ptr++ = 0; //second pause for 4050 code + + *forward_ptr++ = cmd; + cmd >>= 1; + *forward_ptr++ = cmd; + cmd >>= 1; + *forward_ptr++ = cmd; + cmd >>= 1; + *forward_ptr++ = cmd; + + return 6; //return number of emited bits } //==================================================================== @@ -1688,21 +1684,21 @@ uint8_t Prepare_Cmd( uint8_t cmd ) { //-------------------------------------------------------------------- uint8_t Prepare_Addr( uint8_t addr ) { - //-------------------------------------------------------------------- - - register uint8_t line_parity; - - uint8_t i; - line_parity = 0; - for(i=0;i<6;i++) { - *forward_ptr++ = addr; - line_parity ^= addr; - addr >>= 1; - } - - *forward_ptr++ = (line_parity & 1); - - return 7; //return number of emited bits + //-------------------------------------------------------------------- + + register uint8_t line_parity; + + uint8_t i; + line_parity = 0; + for(i=0;i<6;i++) { + *forward_ptr++ = addr; + line_parity ^= addr; + addr >>= 1; + } + + *forward_ptr++ = (line_parity & 1); + + return 7; //return number of emited bits } //==================================================================== @@ -1712,36 +1708,36 @@ uint8_t Prepare_Addr( uint8_t addr ) { //-------------------------------------------------------------------- uint8_t Prepare_Data( uint16_t data_low, uint16_t data_hi) { - //-------------------------------------------------------------------- - - register uint8_t line_parity; - register uint8_t column_parity; - register uint8_t i, j; - register uint16_t data; - - data = data_low; - column_parity = 0; - - for(i=0; i<4; i++) { - line_parity = 0; - for(j=0; j<8; j++) { - line_parity ^= data; - column_parity ^= (data & 1) << j; - *forward_ptr++ = data; - data >>= 1; + //-------------------------------------------------------------------- + + register uint8_t line_parity; + register uint8_t column_parity; + register uint8_t i, j; + register uint16_t data; + + data = data_low; + column_parity = 0; + + for(i=0; i<4; i++) { + line_parity = 0; + for(j=0; j<8; j++) { + line_parity ^= data; + column_parity ^= (data & 1) << j; + *forward_ptr++ = data; + data >>= 1; + } + *forward_ptr++ = line_parity; + if(i == 1) + data = data_hi; } - *forward_ptr++ = line_parity; - if(i == 1) - data = data_hi; - } - - for(j=0; j<8; j++) { - *forward_ptr++ = column_parity; - column_parity >>= 1; - } - *forward_ptr = 0; - - return 45; //return number of emited bits + + for(j=0; j<8; j++) { + *forward_ptr++ = column_parity; + column_parity >>= 1; + } + *forward_ptr = 0; + + return 45; //return number of emited bits } //==================================================================== @@ -1750,115 +1746,115 @@ uint8_t Prepare_Data( uint16_t data_low, uint16_t data_hi) { // fwd_bit_count set with number of bits to be sent //==================================================================== void SendForward(uint8_t fwd_bit_count) { - - fwd_write_ptr = forwardLink_data; - fwd_bit_sz = fwd_bit_count; - - LED_D_ON(); - - //Field on - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - - // Give it a bit of time for the resonant antenna to settle. - // And for the tag to fully power up - SpinDelay(150); - - // force 1st mod pulse (start gap must be longer for 4305) - fwd_bit_sz--; //prepare next bit modulation - fwd_write_ptr++; - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - SpinDelayUs(55*8); //55 cycles off (8us each)for 4305 - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on - SpinDelayUs(16*8); //16 cycles on (8us each) - - // now start writting - while(fwd_bit_sz-- > 0) { //prepare next bit modulation - if(((*fwd_write_ptr++) & 1) == 1) - SpinDelayUs(32*8); //32 cycles at 125Khz (8us each) - else { - //These timings work for 4469/4269/4305 (with the 55*8 above) - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - SpinDelayUs(23*8); //16-4 cycles off (8us each) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on - SpinDelayUs(9*8); //16 cycles on (8us each) + + fwd_write_ptr = forwardLink_data; + fwd_bit_sz = fwd_bit_count; + + LED_D_ON(); + + //Field on + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + + // Give it a bit of time for the resonant antenna to settle. + // And for the tag to fully power up + SpinDelay(150); + + // force 1st mod pulse (start gap must be longer for 4305) + fwd_bit_sz--; //prepare next bit modulation + fwd_write_ptr++; + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + SpinDelayUs(55*8); //55 cycles off (8us each)for 4305 + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on + SpinDelayUs(16*8); //16 cycles on (8us each) + + // now start writting + while(fwd_bit_sz-- > 0) { //prepare next bit modulation + if(((*fwd_write_ptr++) & 1) == 1) + SpinDelayUs(32*8); //32 cycles at 125Khz (8us each) + else { + //These timings work for 4469/4269/4305 (with the 55*8 above) + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + SpinDelayUs(23*8); //16-4 cycles off (8us each) + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on + SpinDelayUs(9*8); //16 cycles on (8us each) + } } - } } void EM4xLogin(uint32_t Password) { - - uint8_t fwd_bit_count; - - forward_ptr = forwardLink_data; - fwd_bit_count = Prepare_Cmd( FWD_CMD_LOGIN ); - fwd_bit_count += Prepare_Data( Password&0xFFFF, Password>>16 ); - - SendForward(fwd_bit_count); - - //Wait for command to complete - SpinDelay(20); - + + uint8_t fwd_bit_count; + + forward_ptr = forwardLink_data; + fwd_bit_count = Prepare_Cmd( FWD_CMD_LOGIN ); + fwd_bit_count += Prepare_Data( Password&0xFFFF, Password>>16 ); + + SendForward(fwd_bit_count); + + //Wait for command to complete + SpinDelay(20); + } void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) { - - uint8_t fwd_bit_count; - uint8_t *dest = (uint8_t *)BigBuf; - int m=0, i=0; - - //If password mode do login - if (PwdMode == 1) EM4xLogin(Pwd); - - forward_ptr = forwardLink_data; - fwd_bit_count = Prepare_Cmd( FWD_CMD_READ ); - fwd_bit_count += Prepare_Addr( Address ); - - m = sizeof(BigBuf); - // Clear destination buffer before sending the command - memset(dest, 128, m); - // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); - - SendForward(fwd_bit_count); - - // Now do the acquisition - i = 0; - for(;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; + + uint8_t fwd_bit_count; + uint8_t *dest = (uint8_t *)BigBuf; + int m=0, i=0; + + //If password mode do login + if (PwdMode == 1) EM4xLogin(Pwd); + + forward_ptr = forwardLink_data; + fwd_bit_count = Prepare_Cmd( FWD_CMD_READ ); + fwd_bit_count += Prepare_Addr( Address ); + + m = sizeof(BigBuf); + // Clear destination buffer before sending the command + memset(dest, 128, m); + // Connect the A/D to the peak-detected low-frequency path. + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); + + SendForward(fwd_bit_count); + + // Now do the acquisition + i = 0; + for(;;) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0x43; + } + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + i++; + if (i >= m) break; + } } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - i++; - if (i >= m) break; - } - } - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + LED_D_OFF(); } void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode) { - - uint8_t fwd_bit_count; - - //If password mode do login - if (PwdMode == 1) EM4xLogin(Pwd); - - forward_ptr = forwardLink_data; - fwd_bit_count = Prepare_Cmd( FWD_CMD_WRITE ); - fwd_bit_count += Prepare_Addr( Address ); - fwd_bit_count += Prepare_Data( Data&0xFFFF, Data>>16 ); - - SendForward(fwd_bit_count); - - //Wait for write to complete - SpinDelay(20); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); + + uint8_t fwd_bit_count; + + //If password mode do login + if (PwdMode == 1) EM4xLogin(Pwd); + + forward_ptr = forwardLink_data; + fwd_bit_count = Prepare_Cmd( FWD_CMD_WRITE ); + fwd_bit_count += Prepare_Addr( Address ); + fwd_bit_count += Prepare_Data( Data&0xFFFF, Data>>16 ); + + SendForward(fwd_bit_count); + + //Wait for write to complete + SpinDelay(20); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + LED_D_OFF(); } diff --git a/common/lfdemod.c b/common/lfdemod.c index ad4721f16..79c99f733 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -14,195 +14,195 @@ //by marshmellow //takes 1s and 0s and searches for EM410x format - output EM ID -uint64_t Em410xDecode(uint8_t *BitStream, int BitLen) +uint64_t Em410xDecode(uint8_t *BitStream,uint32_t BitLen) { - //no arguments needed - built this way in case we want this to be a direct call from "data " cmds in the future - // otherwise could be a void with no arguments - //set defaults - int high=0, low=128; - uint64_t lo=0; //hi=0, + //no arguments needed - built this way in case we want this to be a direct call from "data " cmds in the future + // otherwise could be a void with no arguments + //set defaults + int high=0, low=128; + uint64_t lo=0; //hi=0, - uint32_t i = 0; - uint32_t initLoopMax = 65; - if (initLoopMax>BitLen) initLoopMax=BitLen; + uint32_t i = 0; + uint32_t initLoopMax = 65; + if (initLoopMax>BitLen) initLoopMax=BitLen; - for (;i < initLoopMax; ++i) //65 samples should be plenty to find high and low values - { - if (BitStream[i] > high) - high = BitStream[i]; - else if (BitStream[i] < low) - low = BitStream[i]; - } - if (((high !=1)||(low !=0))){ //allow only 1s and 0s - // PrintAndLog("no data found"); - return 0; - } - uint8_t parityTest=0; - // 111111111 bit pattern represent start of frame - uint8_t frame_marker_mask[] = {1,1,1,1,1,1,1,1,1}; - uint32_t idx = 0; - uint32_t ii=0; - uint8_t resetCnt = 0; - while( (idx + 64) < BitLen) { - restart: - // search for a start of frame marker - if ( memcmp(BitStream+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) - { // frame marker found - idx+=9;//sizeof(frame_marker_mask); - for (i=0; i<10;i++){ - for(ii=0; ii<5; ++ii){ - parityTest += BitStream[(i*5)+ii+idx]; - } - if (parityTest== ((parityTest>>1)<<1)){ - parityTest=0; - for (ii=0; ii<4;++ii){ - //hi = (hi<<1)|(lo>>31); - lo=(lo<<1LL)|(BitStream[(i*5)+ii+idx]); - } - //PrintAndLog("DEBUG: EM parity passed parity val: %d, i:%d, ii:%d,idx:%d, Buffer: %d%d%d%d%d,lo: %d",parityTest,i,ii,idx,BitStream[idx+ii+(i*5)-5],BitStream[idx+ii+(i*5)-4],BitStream[idx+ii+(i*5)-3],BitStream[idx+ii+(i*5)-2],BitStream[idx+ii+(i*5)-1],lo); - }else {//parity failed - //PrintAndLog("DEBUG: EM parity failed parity val: %d, i:%d, ii:%d,idx:%d, Buffer: %d%d%d%d%d",parityTest,i,ii,idx,BitStream[idx+ii+(i*5)-5],BitStream[idx+ii+(i*5)-4],BitStream[idx+ii+(i*5)-3],BitStream[idx+ii+(i*5)-2],BitStream[idx+ii+(i*5)-1]); - parityTest=0; - idx-=8; - if (resetCnt>5)return 0; - resetCnt++; - goto restart;//continue; - } - } - //skip last 5 bit parity test for simplicity. - return lo; - }else{ - idx++; + for (;i < initLoopMax; ++i) //65 samples should be plenty to find high and low values + { + if (BitStream[i] > high) + high = BitStream[i]; + else if (BitStream[i] < low) + low = BitStream[i]; } - } - return 0; + if (((high !=1)||(low !=0))){ //allow only 1s and 0s + // PrintAndLog("no data found"); + return 0; + } + uint8_t parityTest=0; + // 111111111 bit pattern represent start of frame + uint8_t frame_marker_mask[] = {1,1,1,1,1,1,1,1,1}; + uint32_t idx = 0; + uint32_t ii=0; + uint8_t resetCnt = 0; + while( (idx + 64) < BitLen) { +restart: + // search for a start of frame marker + if ( memcmp(BitStream+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) + { // frame marker found + idx+=9;//sizeof(frame_marker_mask); + for (i=0; i<10;i++){ + for(ii=0; ii<5; ++ii){ + parityTest += BitStream[(i*5)+ii+idx]; + } + if (parityTest== ((parityTest>>1)<<1)){ + parityTest=0; + for (ii=0; ii<4;++ii){ + //hi = (hi<<1)|(lo>>31); + lo=(lo<<1LL)|(BitStream[(i*5)+ii+idx]); + } + //PrintAndLog("DEBUG: EM parity passed parity val: %d, i:%d, ii:%d,idx:%d, Buffer: %d%d%d%d%d,lo: %d",parityTest,i,ii,idx,BitStream[idx+ii+(i*5)-5],BitStream[idx+ii+(i*5)-4],BitStream[idx+ii+(i*5)-3],BitStream[idx+ii+(i*5)-2],BitStream[idx+ii+(i*5)-1],lo); + }else {//parity failed + //PrintAndLog("DEBUG: EM parity failed parity val: %d, i:%d, ii:%d,idx:%d, Buffer: %d%d%d%d%d",parityTest,i,ii,idx,BitStream[idx+ii+(i*5)-5],BitStream[idx+ii+(i*5)-4],BitStream[idx+ii+(i*5)-3],BitStream[idx+ii+(i*5)-2],BitStream[idx+ii+(i*5)-1]); + parityTest=0; + idx-=8; + if (resetCnt>5)return 0; + resetCnt++; + goto restart;//continue; + } + } + //skip last 5 bit parity test for simplicity. + return lo; + }else{ + idx++; + } + } + return 0; } //by marshmellow //takes 2 arguments - clock and invert both as integers //attempts to demodulate ask while decoding manchester //prints binary found and saves in graphbuffer for further commands -int askmandemod(uint8_t * BinStream, int *BitLen,int *clk, int *invert) +int askmandemod(uint8_t * BinStream,uint32_t *BitLen,int *clk, int *invert) { - int i; - int high = 0, low = 128; - *clk=DetectASKClock(BinStream,(size_t)*BitLen,*clk); //clock default + int i; + int high = 0, low = 128; + *clk=DetectASKClock(BinStream,(size_t)*BitLen,*clk); //clock default - if (*clk<8) *clk =64; - if (*clk<32) *clk=32; - if (*invert != 0 && *invert != 1) *invert=0; - uint32_t initLoopMax = 200; - if (initLoopMax>*BitLen) initLoopMax=*BitLen; - // Detect high and lows - for (i = 0; i < initLoopMax; ++i) //200 samples should be enough to find high and low values - { - if (BinStream[i] > high) - high = BinStream[i]; - else if (BinStream[i] < low) - low = BinStream[i]; - } - if ((high < 158) ){ //throw away static - //PrintAndLog("no data found"); - return -2; - } - //25% fuzz in case highs and lows aren't clipped [marshmellow] - high=(int)((high-128)*.75)+128; - low= (int)((low-128)*.75)+128; - - //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); - int lastBit = 0; //set first clock check - uint32_t bitnum = 0; //output counter - int 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 - int iii = 0; - uint32_t gLen = *BitLen; - if (gLen > 3000) gLen=3000; - uint8_t errCnt =0; - uint32_t bestStart = *BitLen; - uint32_t bestErrCnt = (*BitLen/1000); - uint32_t maxErr = (*BitLen/1000); - //PrintAndLog("DEBUG - lastbit - %d",lastBit); - //loop to find first wave that works - for (iii=0; iii < gLen; ++iii){ - if ((BinStream[iii]>=high)||(BinStream[iii]<=low)){ - lastBit=iii-*clk; - errCnt=0; - //loop through to see if this start location works - for (i = iii; i < *BitLen; ++i) { - if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){ - lastBit+=*clk; - } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ - //low found and we are expecting a bar - lastBit+=*clk; - } else { - //mid value found or no bar supposed to be here - if ((i-lastBit)>(*clk+tol)){ - //should have hit a high or low based on clock!! - - //debug - //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; //allow 1 error for every 1000 samples else start over - } - } - if ((i-iii) >(400 * *clk)) break; //got plenty of bits - } - //we got more than 64 good bits and not all errors - if ((((i-iii)/ *clk) > (64+errCnt)) && (errCnt*BitLen) initLoopMax=*BitLen; + // Detect high and lows + for (i = 0; i < initLoopMax; ++i) //200 samples should be enough to find high and low values + { + if (BinStream[i] > high) + high = BinStream[i]; + else if (BinStream[i] < low) + low = BinStream[i]; } - } - if (bestErrCnt= high) && ((i-lastBit)>(*clk-tol))){ - lastBit+=*clk; - BinStream[bitnum] = *invert; - bitnum++; - } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ - //low found and we are expecting a bar - lastBit+=*clk; - BinStream[bitnum] = 1-*invert; - bitnum++; - } else { - //mid value found or no bar supposed to be here - if ((i-lastBit)>(*clk+tol)){ - //should have hit a high or low based on clock!! - - //debug - //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; - bitnum++; - } - - lastBit+=*clk;//skip over error - } - } - if (bitnum >=400) break; + if ((high < 158) ){ //throw away static + //PrintAndLog("no data found"); + return -2; } - *BitLen=bitnum; - } else{ - *invert=bestStart; - *clk=iii; - return -1; - } - return bestErrCnt; + //25% fuzz in case highs and lows aren't clipped [marshmellow] + high=(int)((high-128)*.75)+128; + low= (int)((low-128)*.75)+128; + + //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); + int lastBit = 0; //set first clock check + uint32_t bitnum = 0; //output counter + int 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 + int iii = 0; + uint32_t gLen = *BitLen; + if (gLen > 3000) gLen=3000; + uint8_t errCnt =0; + uint32_t bestStart = *BitLen; + uint32_t bestErrCnt = (*BitLen/1000); + uint32_t maxErr = (*BitLen/1000); + //PrintAndLog("DEBUG - lastbit - %d",lastBit); + //loop to find first wave that works + for (iii=0; iii < gLen; ++iii){ + if ((BinStream[iii]>=high)||(BinStream[iii]<=low)){ + lastBit=iii-*clk; + errCnt=0; + //loop through to see if this start location works + for (i = iii; i < *BitLen; ++i) { + if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){ + lastBit+=*clk; + } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ + //low found and we are expecting a bar + lastBit+=*clk; + } else { + //mid value found or no bar supposed to be here + if ((i-lastBit)>(*clk+tol)){ + //should have hit a high or low based on clock!! + + //debug + //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; //allow 1 error for every 1000 samples else start over + } + } + if ((i-iii) >(400 * *clk)) break; //got plenty of bits + } + //we got more than 64 good bits and not all errors + if ((((i-iii)/ *clk) > (64+errCnt)) && (errCnt= high) && ((i-lastBit)>(*clk-tol))){ + lastBit+=*clk; + BinStream[bitnum] = *invert; + bitnum++; + } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ + //low found and we are expecting a bar + lastBit+=*clk; + BinStream[bitnum] = 1-*invert; + bitnum++; + } else { + //mid value found or no bar supposed to be here + if ((i-lastBit)>(*clk+tol)){ + //should have hit a high or low based on clock!! + + //debug + //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; + bitnum++; + } + + lastBit+=*clk;//skip over error + } + } + if (bitnum >=400) break; + } + *BitLen=bitnum; + } else{ + *invert=bestStart; + *clk=iii; + return -1; + } + return bestErrCnt; } //by marshmellow @@ -210,46 +210,46 @@ int askmandemod(uint8_t * BinStream, int *BitLen,int *clk, int *invert) //run through 2 times and take least errCnt int manrawdecode(uint8_t * BitStream, int *bitLen) { - int bitnum=0; - int errCnt =0; - int i=1; - int bestErr = 1000; - int bestRun = 0; - int ii=1; - for (ii=1;ii<3;++ii){ - i=1; - for (i=i+ii;i<*bitLen-2;i+=2){ - if(BitStream[i]==1 && (BitStream[i+1]==0)){ - } else if((BitStream[i]==0)&& BitStream[i+1]==1){ - } else { - errCnt++; - } - if(bitnum>300) break; - } - if (bestErr>errCnt){ - bestErr=errCnt; - bestRun=ii; - } - errCnt=0; - } - errCnt=bestErr; - if (errCnt<20){ - ii=bestRun; - i=1; - for (i=i+ii;i<*bitLen-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; - //errCnt++; - } - if(bitnum>300) break; - } - *bitLen=bitnum; - } - return errCnt; + int bitnum=0; + int errCnt =0; + int i=1; + int bestErr = 1000; + int bestRun = 0; + int ii=1; + for (ii=1;ii<3;++ii){ + i=1; + for (i=i+ii;i<*bitLen-2;i+=2){ + if(BitStream[i]==1 && (BitStream[i+1]==0)){ + } else if((BitStream[i]==0)&& BitStream[i+1]==1){ + } else { + errCnt++; + } + if(bitnum>300) break; + } + if (bestErr>errCnt){ + bestErr=errCnt; + bestRun=ii; + } + errCnt=0; + } + errCnt=bestErr; + if (errCnt<20){ + ii=bestRun; + i=1; + for (i=i+ii;i<*bitLen-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; + //errCnt++; + } + if(bitnum>300) break; + } + *bitLen=bitnum; + } + return errCnt; } @@ -257,23 +257,23 @@ int manrawdecode(uint8_t * BitStream, int *bitLen) //take 01 or 10 = 0 and 11 or 00 = 1 int BiphaseRawDecode(uint8_t * BitStream, int *bitLen, int offset) { - uint8_t bitnum=0; - uint32_t errCnt =0; - uint32_t i=1; - i=offset; - for (;i<*bitLen-2;i+=2){ - if((BitStream[i]==1 && BitStream[i+1]==0)||(BitStream[i]==0 && BitStream[i+1]==1)){ - BitStream[bitnum++]=1; - } else if((BitStream[i]==0 && BitStream[i+1]==0)||(BitStream[i]==1 && BitStream[i+1]==1)){ - BitStream[bitnum++]=0; - } else { - BitStream[bitnum++]=77; - errCnt++; + uint8_t bitnum=0; + uint32_t errCnt =0; + uint32_t i=1; + i=offset; + for (;i<*bitLen-2;i+=2){ + if((BitStream[i]==1 && BitStream[i+1]==0)||(BitStream[i]==0 && BitStream[i+1]==1)){ + BitStream[bitnum++]=1; + } else if((BitStream[i]==0 && BitStream[i+1]==0)||(BitStream[i]==1 && BitStream[i+1]==1)){ + BitStream[bitnum++]=0; + } else { + BitStream[bitnum++]=77; + errCnt++; + } + if(bitnum>250) break; } - if(bitnum>250) break; - } - *bitLen=bitnum; - return errCnt; + *bitLen=bitnum; + return errCnt; } //by marshmellow @@ -282,352 +282,352 @@ int BiphaseRawDecode(uint8_t * BitStream, int *bitLen, int offset) //prints binary found and saves in graphbuffer for further commands int askrawdemod(uint8_t *BinStream, int *bitLen,int *clk, int *invert) { - uint32_t i; - // int invert=0; //invert default - int high = 0, low = 128; - *clk=DetectASKClock(BinStream,*bitLen,*clk); //clock default - uint8_t BitStream[502] = {0}; + uint32_t i; + // int invert=0; //invert default + int high = 0, low = 128; + *clk=DetectASKClock(BinStream,*bitLen,*clk); //clock default + uint8_t BitStream[502] = {0}; - if (*clk<8) *clk =64; - if (*clk<32) *clk=32; - if (*invert != 0 && *invert != 1) *invert =0; - uint32_t initLoopMax = 200; - if (initLoopMax>*bitLen) initLoopMax=*bitLen; - // Detect high and lows - for (i = 0; i < initLoopMax; ++i) //200 samples should be plenty to find high and low values - { - if (BinStream[i] > high) - high = BinStream[i]; - else if (BinStream[i] < low) - low = BinStream[i]; - } - if ((high < 158)){ //throw away static - // PrintAndLog("no data found"); - return -2; - } - //25% fuzz in case highs and lows aren't clipped [marshmellow] - high=(int)((high-128)*.75)+128; - low= (int)((low-128)*.75)+128; + if (*clk<8) *clk =64; + if (*clk<32) *clk=32; + if (*invert != 0 && *invert != 1) *invert =0; + uint32_t initLoopMax = 200; + if (initLoopMax>*bitLen) initLoopMax=*bitLen; + // Detect high and lows + for (i = 0; i < initLoopMax; ++i) //200 samples should be plenty to find high and low values + { + if (BinStream[i] > high) + high = BinStream[i]; + else if (BinStream[i] < low) + low = BinStream[i]; + } + if ((high < 158)){ //throw away static + // PrintAndLog("no data found"); + return -2; + } + //25% fuzz in case highs and lows aren't clipped [marshmellow] + high=(int)((high-128)*.75)+128; + low= (int)((low-128)*.75)+128; - //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); - int lastBit = 0; //set first clock check - uint32_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 - uint32_t iii = 0; - uint32_t gLen = *bitLen; - if (gLen > 500) gLen=500; - uint8_t errCnt =0; - uint32_t bestStart = *bitLen; - uint32_t bestErrCnt = (*bitLen/1000); - uint8_t midBit=0; - //PrintAndLog("DEBUG - lastbit - %d",lastBit); - //loop to find first wave that works - for (iii=0; iii < gLen; ++iii){ - if ((BinStream[iii]>=high)||(BinStream[iii]<=low)){ - lastBit=iii-*clk; - //loop through to see if this start location works - for (i = iii; i < *bitLen; ++i) { - if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){ - lastBit+=*clk; - BitStream[bitnum] = *invert; - bitnum++; - midBit=0; - } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ - //low found and we are expecting a bar - lastBit+=*clk; - BitStream[bitnum] = 1-*invert; - bitnum++; - midBit=0; - } else if ((BinStream[i]<=low) && (midBit==0) && ((i-lastBit)>((*clk/2)-tol))){ - //mid bar? - midBit=1; - BitStream[bitnum]= 1-*invert; - bitnum++; - } else if ((BinStream[i]>=high)&&(midBit==0) && ((i-lastBit)>((*clk/2)-tol))){ - //mid bar? - midBit=1; - BitStream[bitnum]= *invert; - bitnum++; - } else if ((i-lastBit)>((*clk/2)+tol)&&(midBit==0)){ - //no mid bar found - midBit=1; - BitStream[bitnum]= BitStream[bitnum-1]; - bitnum++; - } else { - //mid value found or no bar supposed to be here + //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); + int lastBit = 0; //set first clock check + uint32_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 + uint32_t iii = 0; + uint32_t gLen = *bitLen; + if (gLen > 500) gLen=500; + uint8_t errCnt =0; + uint32_t bestStart = *bitLen; + uint32_t bestErrCnt = (*bitLen/1000); + uint8_t midBit=0; + //PrintAndLog("DEBUG - lastbit - %d",lastBit); + //loop to find first wave that works + for (iii=0; iii < gLen; ++iii){ + if ((BinStream[iii]>=high)||(BinStream[iii]<=low)){ + lastBit=iii-*clk; + //loop through to see if this start location works + for (i = iii; i < *bitLen; ++i) { + if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){ + lastBit+=*clk; + BitStream[bitnum] = *invert; + bitnum++; + midBit=0; + } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ + //low found and we are expecting a bar + lastBit+=*clk; + BitStream[bitnum] = 1-*invert; + bitnum++; + midBit=0; + } else if ((BinStream[i]<=low) && (midBit==0) && ((i-lastBit)>((*clk/2)-tol))){ + //mid bar? + midBit=1; + BitStream[bitnum]= 1-*invert; + bitnum++; + } else if ((BinStream[i]>=high)&&(midBit==0) && ((i-lastBit)>((*clk/2)-tol))){ + //mid bar? + midBit=1; + BitStream[bitnum]= *invert; + bitnum++; + } else if ((i-lastBit)>((*clk/2)+tol)&&(midBit==0)){ + //no mid bar found + midBit=1; + BitStream[bitnum]= BitStream[bitnum-1]; + bitnum++; + } else { + //mid value found or no bar supposed to be here - if ((i-lastBit)>(*clk+tol)){ - //should have hit a high or low based on clock!! - //debug - //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){ - BitStream[bitnum]=77; - bitnum++; + if ((i-lastBit)>(*clk+tol)){ + //should have hit a high or low based on clock!! + //debug + //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){ + BitStream[bitnum]=77; + bitnum++; + } + + + errCnt++; + lastBit+=*clk;//skip over until hit too many errors + if (errCnt>((*bitLen/1000))){ //allow 1 error for every 1000 samples else start over + errCnt=0; + bitnum=0;//start over + break; + } + } + } + if (bitnum>500) break; } - - - errCnt++; - lastBit+=*clk;//skip over until hit too many errors - if (errCnt>((*bitLen/1000))){ //allow 1 error for every 1000 samples else start over - errCnt=0; - bitnum=0;//start over - break; + //we got more than 64 good bits and not all errors + if ((bitnum > (64+errCnt)) && (errCnt<(*bitLen/1000))) { + //possible good read + if (errCnt==0) break; //great read - finish + if (bestStart == iii) break; //if current run == bestErrCnt run (after exhausted testing) then finish + if (errCnt500) break; - } - //we got more than 64 good bits and not all errors - if ((bitnum > (64+errCnt)) && (errCnt<(*bitLen/1000))) { - //possible good read - if (errCnt==0) break; //great read - finish - if (bestStart == iii) break; //if current run == bestErrCnt run (after exhausted testing) then finish - if (errCnt=gLen){ //exhausted test + //if there was a ok test go back to that one and re-run the best run (then dump after that run) + if (bestErrCnt < (*bitLen/1000)) iii=bestStart; } - } } - if (iii>=gLen){ //exhausted test - //if there was a ok test go back to that one and re-run the best run (then dump after that run) - if (bestErrCnt < (*bitLen/1000)) iii=bestStart; - } - } - if (bitnum>16){ - - // PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum); - //move BitStream back to BinStream - // ClearGraph(0); - for (i=0; i < bitnum; ++i){ - BinStream[i]=BitStream[i]; - } - *bitLen=bitnum; - // RepaintGraphWindow(); - //output - // if (errCnt>0){ - // PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); - // } - // PrintAndLog("ASK decoded bitstream:"); - // Now output the bitstream to the scrollback by line of 16 bits - // printBitStream2(BitStream,bitnum); - //int errCnt=0; - //errCnt=manrawdemod(BitStream,bitnum); + if (bitnum>16){ - // Em410xDecode(Cmd); - } else return -1; - return errCnt; + // PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum); + //move BitStream back to BinStream + // ClearGraph(0); + for (i=0; i < bitnum; ++i){ + BinStream[i]=BitStream[i]; + } + *bitLen=bitnum; + // RepaintGraphWindow(); + //output + // if (errCnt>0){ + // PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); + // } + // PrintAndLog("ASK decoded bitstream:"); + // Now output the bitstream to the scrollback by line of 16 bits + // printBitStream2(BitStream,bitnum); + //int errCnt=0; + //errCnt=manrawdemod(BitStream,bitnum); + + // Em410xDecode(Cmd); + } else return -1; + return errCnt; } //translate wave to 11111100000 (1 for each short wave 0 for each long wave) size_t fsk_wave_demod(uint8_t * dest, size_t size, uint8_t fchigh, uint8_t fclow) { - uint32_t last_transition = 0; - uint32_t idx = 1; - uint32_t maxVal=0; - if (fchigh==0) fchigh=10; - if (fclow==0) fclow=8; - // we do care about the actual theshold value as sometimes near the center of the - // wave we may get static that changes direction of wave for one value - // if our value is too low it might affect the read. and if our tag or - // antenna is weak a setting too high might not see anything. [marshmellow] - if (size<100) return 0; - for(idx=1; idx<100; idx++){ - if(maxVal1 transition - if (dest[idx-1] < dest[idx]) { // 0 -> 1 transition - if ((idx-last_transition)<(fclow-2)){ //0-5 = garbage noise - //do nothing with extra garbage - } else if ((idx-last_transition) < (fchigh-1)) { //6-8 = 8 waves - dest[numBits]=1; - } else { //9+ = 10 waves - dest[numBits]=0; - } - last_transition = idx; - numBits++; - } - } - return numBits; //Actually, it returns the number of bytes, but each byte represents a bit: 1 or 0 + size_t numBits = 0; + // count cycles between consecutive lo-hi transitions, there should be either 8 (fc/8) + // or 10 (fc/10) cycles but in practice due to noise etc we may end up with with anywhere + // between 7 to 11 cycles so fuzz it by treat anything <9 as 8 and anything else as 10 + for(idx = 1; idx < size; idx++) { + // threshold current value + + if (dest[idx] < threshold_value) dest[idx] = 0; + else dest[idx] = 1; + + // Check for 0->1 transition + if (dest[idx-1] < dest[idx]) { // 0 -> 1 transition + if ((idx-last_transition)<(fclow-2)){ //0-5 = garbage noise + //do nothing with extra garbage + } else if ((idx-last_transition) < (fchigh-1)) { //6-8 = 8 waves + dest[numBits]=1; + } else { //9+ = 10 waves + dest[numBits]=0; + } + last_transition = idx; + numBits++; + } + } + return numBits; //Actually, it returns the number of bytes, but each byte represents a bit: 1 or 0 } uint32_t myround2(float f) { - if (f >= 2000) return 2000;//something bad happened - return (uint32_t) (f + (float)0.5); + if (f >= 2000) return 2000;//something bad happened + return (uint32_t) (f + (float)0.5); } //translate 11111100000 to 10 size_t aggregate_bits(uint8_t *dest,size_t size, uint8_t rfLen, uint8_t maxConsequtiveBits, uint8_t invert,uint8_t fchigh,uint8_t fclow )// uint8_t h2l_crossing_value,uint8_t l2h_crossing_value, { - uint8_t lastval=dest[0]; - uint32_t idx=0; - size_t numBits=0; - uint32_t n=1; + uint8_t lastval=dest[0]; + uint32_t idx=0; + size_t numBits=0; + uint32_t n=1; - for( idx=1; idx < size; idx++) { + for( idx=1; idx < size; idx++) { - if (dest[idx]==lastval) { - n++; - continue; - } - //if lastval was 1, we have a 1->0 crossing - if ( dest[idx-1]==1 ) { - n=myround2((float)(n+1)/((float)(rfLen)/(float)fclow)); - //n=(n+1) / h2l_crossing_value; - } else {// 0->1 crossing - n=myround2((float)(n+1)/((float)(rfLen-2)/(float)fchigh)); //-2 for fudge factor - //n=(n+1) / l2h_crossing_value; - } - if (n == 0) n = 1; + if (dest[idx]==lastval) { + n++; + continue; + } + //if lastval was 1, we have a 1->0 crossing + if ( dest[idx-1]==1 ) { + n=myround2((float)(n+1)/((float)(rfLen)/(float)fclow)); + //n=(n+1) / h2l_crossing_value; + } else {// 0->1 crossing + n=myround2((float)(n+1)/((float)(rfLen-2)/(float)fchigh)); //-2 for fudge factor + //n=(n+1) / l2h_crossing_value; + } + if (n == 0) n = 1; - if(n < maxConsequtiveBits) //Consecutive - { - if(invert==0){ //invert bits - memset(dest+numBits, dest[idx-1] , n); - }else{ - memset(dest+numBits, dest[idx-1]^1 , n); - } - numBits += n; - } - n=0; - lastval=dest[idx]; - }//end for - return numBits; + if(n < maxConsequtiveBits) //Consecutive + { + if(invert==0){ //invert bits + memset(dest+numBits, dest[idx-1] , n); + }else{ + memset(dest+numBits, dest[idx-1]^1 , n); + } + numBits += n; + } + n=0; + lastval=dest[idx]; + }//end for + return numBits; } //by marshmellow (from holiman's base) // full fsk demod from GraphBuffer wave to decoded 1s and 0s (no mandemod) int fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uint8_t fchigh, uint8_t fclow) { - // FSK demodulator - size = fsk_wave_demod(dest, size, fchigh, fclow); - size = aggregate_bits(dest, size,rfLen,192,invert,fchigh,fclow); - return size; + // FSK demodulator + size = fsk_wave_demod(dest, size, fchigh, fclow); + size = aggregate_bits(dest, size,rfLen,192,invert,fchigh,fclow); + return size; } // loop to get raw HID waveform then FSK demodulate the TAG ID from it int HIDdemodFSK(uint8_t *dest, size_t size, uint32_t *hi2, uint32_t *hi, uint32_t *lo) { - - size_t idx=0; //, found=0; //size=0, - // FSK demodulator - size = fskdemod(dest, size,50,0,10,8); - // final loop, go over previously decoded manchester data and decode into usable tag ID - // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0 - uint8_t frame_marker_mask[] = {1,1,1,0,0,0}; - int numshifts = 0; - idx = 0; - //one scan - while( idx + sizeof(frame_marker_mask) < size) { - // search for a start of frame marker - if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) - { // frame marker found - idx+=sizeof(frame_marker_mask); - while(dest[idx] != dest[idx+1] && idx < size-2) - { - // Keep going until next frame marker (or error) - // Shift in a bit. Start by shifting high registers - *hi2 = (*hi2<<1)|(*hi>>31); - *hi = (*hi<<1)|(*lo>>31); - //Then, shift in a 0 or one into low - if (dest[idx] && !dest[idx+1]) // 1 0 - *lo=(*lo<<1)|0; - else // 0 1 - *lo=(*lo<<1)|1; - numshifts++; - idx += 2; - } - // Hopefully, we read a tag and hit upon the next frame marker - if(idx + sizeof(frame_marker_mask) < size) - { - if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) - { - //good return - return idx; - } - } - // reset - *hi2 = *hi = *lo = 0; - numshifts = 0; - }else { - idx++; - } - } - return -1; + size_t idx=0; //, found=0; //size=0, + // FSK demodulator + size = fskdemod(dest, size,50,0,10,8); + + // final loop, go over previously decoded manchester data and decode into usable tag ID + // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0 + uint8_t frame_marker_mask[] = {1,1,1,0,0,0}; + int numshifts = 0; + idx = 0; + //one scan + while( idx + sizeof(frame_marker_mask) < size) { + // search for a start of frame marker + if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) + { // frame marker found + idx+=sizeof(frame_marker_mask); + while(dest[idx] != dest[idx+1] && idx < size-2) + { + // Keep going until next frame marker (or error) + // Shift in a bit. Start by shifting high registers + *hi2 = (*hi2<<1)|(*hi>>31); + *hi = (*hi<<1)|(*lo>>31); + //Then, shift in a 0 or one into low + if (dest[idx] && !dest[idx+1]) // 1 0 + *lo=(*lo<<1)|0; + else // 0 1 + *lo=(*lo<<1)|1; + numshifts++; + idx += 2; + } + // Hopefully, we read a tag and hit upon the next frame marker + if(idx + sizeof(frame_marker_mask) < size) + { + if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) + { + //good return + return idx; + } + } + // reset + *hi2 = *hi = *lo = 0; + numshifts = 0; + }else { + idx++; + } + } + return -1; } uint32_t bytebits_to_byte(uint8_t* src, int numbits) { - uint32_t num = 0; - for(int i = 0 ; i < numbits ; i++) - { - num = (num << 1) | (*src); - src++; - } - return num; + uint32_t num = 0; + for(int i = 0 ; i < numbits ; i++) + { + num = (num << 1) | (*src); + src++; + } + return num; } int IOdemodFSK(uint8_t *dest, size_t size) { - uint32_t idx=0; - //make sure buffer has data - if (size < 66) return -1; - //test samples are not just noise - uint8_t testMax=0; - for(idx=0;idx<65;idx++){ - if (testMax170){ - // FSK demodulator - size = fskdemod(dest, size,64,1,10,8); // RF/64 and invert - if (size < 65) return -1; //did we get a good demod? - //Index map - //0 10 20 30 40 50 60 - //| | | | | | | - //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23 - //----------------------------------------------------------------------------- - //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11 - // - //XSF(version)facility:codeone+codetwo - //Handle the data - uint8_t mask[] = {0,0,0,0,0,0,0,0,0,1}; - for( idx=0; idx < (size - 65); idx++) { - if ( memcmp(dest + idx, mask, sizeof(mask))==0) { - //frame marker found - if (!dest[idx+8] && dest[idx+17]==1 && dest[idx+26]==1 && dest[idx+35]==1 && dest[idx+44]==1 && dest[idx+53]==1){ - //confirmed proper separator bits found - //return start position - return (int) idx; - } - } - } - } - return 0; + uint32_t idx=0; + //make sure buffer has data + if (size < 66) return -1; + //test samples are not just noise + uint8_t testMax=0; + for(idx=0;idx<65;idx++){ + if (testMax20){ + // FSK demodulator + size = fskdemod(dest, size,64,1,10,8); // RF/64 and invert + if (size < 65) return -1; //did we get a good demod? + //Index map + //0 10 20 30 40 50 60 + //| | | | | | | + //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23 + //----------------------------------------------------------------------------- + //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11 + // + //XSF(version)facility:codeone+codetwo + //Handle the data + uint8_t mask[] = {0,0,0,0,0,0,0,0,0,1}; + for( idx=0; idx < (size - 65); idx++) { + if ( memcmp(dest + idx, mask, sizeof(mask))==0) { + //frame marker found + if (!dest[idx+8] && dest[idx+17]==1 && dest[idx+26]==1 && dest[idx+35]==1 && dest[idx+44]==1 && dest[idx+53]==1){ + //confirmed proper separator bits found + //return start position + return (int) idx; + } + } + } + } + return 0; } // by marshmellow @@ -635,521 +635,67 @@ int IOdemodFSK(uint8_t *dest, size_t size) // maybe somehow adjust peak trimming value based on samples to fix? int DetectASKClock(uint8_t dest[], size_t size, int clock) { - int i=0; - int peak=0; - int low=128; - int clk[]={16,32,40,50,64,100,128,256}; - int loopCnt = 256; //don't need to loop through entire array... - if (sizepeak){ - peak = dest[i]; - } - if(dest[i]=peak) || (dest[ii]<=low)){ - errCnt=0; - // now that we have the first one lined up test rest of wave array - for (i=0; i<((int)(size/clk[clkCnt])-1); ++i){ - if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){ - }else if(dest[ii+(i*clk[clkCnt])-tol]>=peak || dest[ii+(i*clk[clkCnt])-tol]<=low){ - }else if(dest[ii+(i*clk[clkCnt])+tol]>=peak || dest[ii+(i*clk[clkCnt])+tol]<=low){ - }else{ //error no peak detected - errCnt++; - } + //get high and low peak + for (i=0;ipeak){ + peak = dest[i]; } - //if we found no errors this is correct one - return this clock - if(errCnt==0) return clk[clkCnt]; - //if we found errors see if it is lowest so far and save it as best run - if(errCntpeak){ - peak = dest[i]; - } - if(dest[i]=peak) || (dest[ii]<=low)){ - errCnt=0; - peakcnt=0; - // now that we have the first one lined up test rest of wave array - for (i=0; i<((int)(size/clk[clkCnt])-1); ++i){ - if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){ - peakcnt++; - }else if(dest[ii+(i*clk[clkCnt])-tol]>=peak || dest[ii+(i*clk[clkCnt])-tol]<=low){ - peakcnt++; - }else if(dest[ii+(i*clk[clkCnt])+tol]>=peak || dest[ii+(i*clk[clkCnt])+tol]<=low){ - peakcnt++; - }else{ //error no peak detected - errCnt++; - } + if(dest[i]peaksdet[clkCnt]) { - peaksdet[clkCnt]=peakcnt; - bestErr[clkCnt]=errCnt; - } - } - } - } - int iii=0; - int best=0; - //int ratio2; //debug - int ratio; - //int bits; - for (iii=0; iii<7;++iii){ - ratio=1000; - //ratio2=1000; //debug - //bits=size/clk[iii]; //debug - if (peaksdet[iii]>0){ - ratio=bestErr[iii]/peaksdet[iii]; - if (((bestErr[best]/peaksdet[best])>(ratio)+1)){ - best = iii; - } - //ratio2=bits/peaksdet[iii]; //debug - } - //PrintAndLog("DEBUG: Clk: %d, peaks: %d, errs: %d, bestClk: %d, ratio: %d, bits: %d, peakbitr: %d",clk[iii],peaksdet[iii],bestErr[iii],clk[best],ratio, bits,ratio2); - } - return clk[best]; -} - -/* -int DetectNRZpskClock(uint8_t dest[], size_t size, int clock) -{ - int i=0; - int peak=0; - int low=128; - int clk[]={16,32,40,50,64,100,128,256}; - int loopCnt = 1500; //don't need to loop through entire array... - if (sizepeak){ - peak = dest[i]; } - if(dest[i]=peak) || (dest[ii]<=low)){ - lastClk = ii-*clk; - errCnt[clkCnt]=0; - // now that we have the first one lined up test rest of wave array - for (i=ii; i=peak || dest[i]<=low) && (i>=lastClk+*clk-tol && i<=lastClk+*clk+tol)){ - bitHigh=1; - lastClk=lastClk+*clk; - ignorewin=clk[clkCnt]/8; - }else if(dest[i]low) { - if (ignorewin==0){ - bitHigh=0; - }else ignorewin--; - if (i>=lastClk+*clk+tol){ //past possible bar - lowBitCnt[clkCnt]++; + peak=(int)((peak-128)*.75)+128; + low= (int)((low-128)*.75)+128; + int ii; + int clkCnt; + int tol = 0; + int bestErr=1000; + int errCnt[]={0,0,0,0,0,0,0,0}; + //test each valid clock from smallest to greatest to see which lines up + for(clkCnt=0; clkCnt<6;++clkCnt){ + if (clk[clkCnt]==32){ + tol=1; + }else{ + tol=0; + } + bestErr=1000; + //try lining up the peaks by moving starting point (try first 256) + for (ii=0; ii=peak) || (dest[ii]<=low)){ + errCnt[clkCnt]=0; + // now that we have the first one lined up test rest of wave array + for (i=0; i<((int)(size/clk[clkCnt])-1); ++i){ + if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){ + }else if(dest[ii+(i*clk[clkCnt])-tol]>=peak || dest[ii+(i*clk[clkCnt])-tol]<=low){ + }else if(dest[ii+(i*clk[clkCnt])+tol]>=peak || dest[ii+(i*clk[clkCnt])+tol]<=low){ + }else{ //error no peak detected + errCnt[clkCnt]++; + } + } + //if we found no errors this is correct one - return this clock + if(errCnt[clkCnt]==0) return clk[clkCnt]; + //if we found errors see if it is lowest so far and save it as best run + if(errCnt[clkCnt]=peak || dest[i]<=low) && (i=lastClk+*clk+tol) && (bitHigh==0)){ - //error bar found no clock... - errCnt[clkCnt]++; - } } - //if we found no errors this is correct one - return this clock - if(errCnt[clkCnt]==0 && lowBitCnt[clkCnt]==0) return clk[clkCnt]; - //if we found errors see if it is lowest so far and save it as best run - if(errCnt[clkCnt]high) high=bitStream[i]; - } - high = (int)(((high-128)*.80)+128); - low = (int)(((low-128)*.90)+128); - //low = (uint8_t)(((int)(low)-128)*.80)+128; - for (i=0; i=high) newHigh=1; - } - return; -} - -int indala26decode(uint8_t *bitStream, int *bitLen, uint8_t *invert) -{ - //26 bit 40134 format (don't know other formats) - // Finding the start of a UID - int i; - int long_wait; - //uidlen = 64; - long_wait = 29;//29 leading zeros in format - int start; - int first = 0; - int first2 = 0; - int bitCnt = 0; - int ii; - for (start = 0; start <= *bitLen - 250; start++) { - first = bitStream[start]; - for (i = start; i < start + long_wait; i++) { - if (bitStream[i] != first) { - break; - } - } - if (i == (start + long_wait)) { - break; - } - } - if (start == *bitLen - 250 + 1) { - // did not find start sequence - return -1; - } - //found start once now test length by finding next one - // Inverting signal if needed - if (first == 1) { - for (i = start; i < *bitLen; i++) { - bitStream[i] = !bitStream[i]; - } - *invert = 1; - }else *invert=0; - - int iii; - for (ii=start+29; ii <= *bitLen - 250; ii++) { - first2 = bitStream[ii]; - for (iii = ii; iii < ii + long_wait; iii++) { - if (bitStream[iii] != first2) { - break; - } - } - if (iii == (ii + long_wait)) { - break; - } - } - if (ii== *bitLen - 250 + 1){ - // did not find second start sequence - return -2; - } - bitCnt=ii-start; - - // Dumping UID - i = start; - for (ii = 0; ii < bitCnt; ii++) { - bitStream[ii] = bitStream[i++]; - //showbits[bit] = '0' + bits[bit]; - } - *bitLen=bitCnt; - return 1; -} - -int pskNRZrawDemod(uint8_t *dest, int *bitLen, int *clk, int *invert) -{ - pskCleanWave(dest,*bitLen); - int clk2 = DetectpskNRZClock(dest, *bitLen, *clk); - *clk=clk2; - uint32_t i; - uint8_t high=0, low=128; - uint32_t gLen = *bitLen; - if (gLen > 1280) gLen=1280; - // get high - for (i=0; ihigh) high = dest[i]; - if (dest[i]=high)||(dest[iii]<=low)){ - lastBit=iii-*clk; - //loop through to see if this start location works - for (i = iii; i < *bitLen; ++i) { - //if we found a high bar and we are at a clock bit - if ((dest[i]>=high ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ - bitHigh=1; - lastBit+=*clk; - //curBit=1-*invert; - //dest[bitnum]=curBit; - ignorewin=*clk/8; - bitnum++; - //else if low bar found and we are at a clock point - }else if ((dest[i]<=low ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ - bitHigh=1; - lastBit+=*clk; - ignorewin=*clk/8; - //curBit=*invert; - //dest[bitnum]=curBit; - bitnum++; - //else if no bars found - }else if(dest[i]low) { - if (ignorewin==0){ - bitHigh=0; - }else ignorewin--; - //if we are past a clock point - if (i>=lastBit+*clk+tol){ //clock val - //dest[bitnum]=curBit; - lastBit+=*clk; - bitnum++; - } - //else if bar found but we are not at a clock bit and we did not just have a clock bit - }else if ((dest[i]>=high || dest[i]<=low) && (ilastBit+*clk+tol) && (bitHigh==0)){ - //error bar found no clock... - errCnt++; - } - if (bitnum>=1000) break; - } - //we got more than 64 good bits and not all errors - if ((bitnum > (64+errCnt)) && (errCnt<(maxErr))) { - //possible good read - if (errCnt==0){ - bestStart = iii; - bestErrCnt=errCnt; - break; //great read - finish + int iii=0; + int best=0; + for (iii=0; iii<6;++iii){ + if (errCnt[iii]=high ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ - bitHigh=1; - lastBit+=*clk; - curBit=1-*invert; - dest[bitnum]=curBit; - ignorewin=*clk/8; - bitnum++; - //else if low bar found and we are at a clock point - }else if ((dest[i]<=low ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ - bitHigh=1; - lastBit+=*clk; - curBit=*invert; - dest[bitnum]=curBit; - ignorewin=*clk/8; - bitnum++; - //else if no bars found - }else if(dest[i]low) { - if (ignorewin==0){ - bitHigh=0; - }else ignorewin--; - //if we are past a clock point - if (i>=lastBit+*clk+tol){ //clock val - lastBit+=*clk; - dest[bitnum]=curBit; - bitnum++; - } - //else if bar found but we are not at a clock bit and we did not just have a clock bit - }else if ((dest[i]>=high || dest[i]<=low) && ((ilastBit+*clk+tol)) && (bitHigh==0)){ - //error bar found no clock... - bitHigh=1; - dest[bitnum]=77; - bitnum++; - errCnt++; - } - if (bitnum >=1000) break; - } - *bitLen=bitnum; - } else{ - *bitLen=bitnum; - *clk=bestStart; - return -1; - } - - if (bitnum>16){ - *bitLen=bitnum; - } else return -1; - return errCnt; + return clk[best]; } - - - /*not needed? - uint32_t i; - uint8_t high=0, low=128; - uint32_t loopMax = 1280; //20 raw bits - - // get high - if (sizehigh) high = dest[i]; - if (dest[i]=high) dest[i]=high; - else if(dest[i]<=low) dest[i]=low; - else dest[i]=0; - } - */ diff --git a/common/lfdemod.h b/common/lfdemod.h index 2e0acf751..ad95fda5e 100644 --- a/common/lfdemod.h +++ b/common/lfdemod.h @@ -12,8 +12,8 @@ #include int DetectASKClock(uint8_t dest[], size_t size, int clock); -int askmandemod(uint8_t *BinStream,int *BitLen,int *clk, int *invert); -uint64_t Em410xDecode(uint8_t *BitStream,int BitLen); +int askmandemod(uint8_t *BinStream,uint32_t *BitLen,int *clk, int *invert); +uint64_t Em410xDecode(uint8_t *BitStream,uint32_t BitLen); int manrawdecode(uint8_t *BitStream, int *bitLen); int BiphaseRawDecode(uint8_t * BitStream, int *bitLen, int offset); int askrawdemod(uint8_t *BinStream, int *bitLen,int *clk, int *invert); @@ -21,9 +21,5 @@ int HIDdemodFSK(uint8_t *dest, size_t size, uint32_t *hi2, uint32_t *hi, uint32_ 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, int numbits); -int pskNRZrawDemod(uint8_t *dest, int *bitLen, int *clk, int *invert); -int DetectpskNRZClock(uint8_t dest[], size_t size, int clock); -int indala26decode(uint8_t *bitStream, int *bitLen, uint8_t *invert); -void pskCleanWave(uint8_t *bitStream, int bitLen); #endif From a6293168da03b547d7cb283f94d8e7aa7109069a Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Tue, 6 Jan 2015 23:29:45 -0500 Subject: [PATCH 03/11] code cleanup. re-added psk commands. also fixed a bug in detect clock functions. sync with master prep for pull request --- armsrc/lfops.c | 2738 +++++++++++++++++++++++----------------------- client/cmddata.c | 2402 ++++++++++++++++++++-------------------- client/cmdlf.c | 988 ++++++++--------- client/graph.c | 324 +++--- client/graph.h | 4 +- common/lfdemod.c | 1473 +++++++++++++++---------- common/lfdemod.h | 18 +- 7 files changed, 4141 insertions(+), 3806 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index ab196325f..b9dbb8e27 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -18,144 +18,144 @@ /** -* Does the sample acquisition. If threshold is specified, the actual sampling -* is not commenced until the threshold has been reached. +* Does the sample acquisition. If threshold is specified, the actual sampling +* is not commenced until the threshold has been reached. * @param trigger_threshold - the threshold * @param silent - is true, now outputs are made. If false, dbprints the status */ void DoAcquisition125k_internal(int trigger_threshold,bool silent) { - uint8_t *dest = (uint8_t *)BigBuf; - int n = sizeof(BigBuf); - int i; + uint8_t *dest = (uint8_t *)BigBuf; + int n = sizeof(BigBuf); + int i; - memset(dest, 0, n); - i = 0; - for(;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - LED_D_ON(); - } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - LED_D_OFF(); - if (trigger_threshold != -1 && dest[i] < trigger_threshold) - continue; - else - trigger_threshold = -1; - if (++i >= n) break; - } - } - if(!silent) - { - Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...", - dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); + memset(dest, 0, n); + i = 0; + for(;;) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0x43; + LED_D_ON(); + } + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + LED_D_OFF(); + if (trigger_threshold != -1 && dest[i] < trigger_threshold) + continue; + else + trigger_threshold = -1; + if (++i >= n) break; + } + } + if(!silent) + { + Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...", + dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); - } + } } /** -* Perform sample aquisition. +* Perform sample aquisition. */ void DoAcquisition125k(int trigger_threshold) { - DoAcquisition125k_internal(trigger_threshold, false); + DoAcquisition125k_internal(trigger_threshold, false); } /** -* Setup the FPGA to listen for samples. This method downloads the FPGA bitstream -* if not already loaded, sets divisor and starts up the antenna. +* Setup the FPGA to listen for samples. This method downloads the FPGA bitstream +* if not already loaded, sets divisor and starts up the antenna. * @param divisor : 1, 88> 255 or negative ==> 134.8 KHz * 0 or 95 ==> 125 KHz -* +* **/ void LFSetupFPGAForADC(int divisor, bool lf_field) { - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - if ( (divisor == 1) || (divisor < 0) || (divisor > 255) ) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz - else if (divisor == 0) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - else - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + if ( (divisor == 1) || (divisor < 0) || (divisor > 255) ) + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz + else if (divisor == 0) + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + else + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | (lf_field ? FPGA_LF_ADC_READER_FIELD : 0)); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | (lf_field ? FPGA_LF_ADC_READER_FIELD : 0)); - // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - // Give it a bit of time for the resonant antenna to settle. - SpinDelay(50); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); + // Connect the A/D to the peak-detected low-frequency path. + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + // Give it a bit of time for the resonant antenna to settle. + SpinDelay(50); + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); } /** -* Initializes the FPGA, and acquires the samples. +* Initializes the FPGA, and acquires the samples. **/ void AcquireRawAdcSamples125k(int divisor) { - LFSetupFPGAForADC(divisor, true); - // Now call the acquisition routine - DoAcquisition125k_internal(-1,false); + LFSetupFPGAForADC(divisor, true); + // Now call the acquisition routine + DoAcquisition125k_internal(-1,false); } /** -* Initializes the FPGA for snoop-mode, and acquires the samples. +* Initializes the FPGA for snoop-mode, and acquires the samples. **/ void SnoopLFRawAdcSamples(int divisor, int trigger_threshold) { - LFSetupFPGAForADC(divisor, false); - DoAcquisition125k(trigger_threshold); + LFSetupFPGAForADC(divisor, false); + DoAcquisition125k(trigger_threshold); } void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, uint8_t *command) { - /* Make sure the tag is reset */ - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelay(2500); + /* Make sure the tag is reset */ + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelay(2500); - int divisor_used = 95; // 125 KHz - // see if 'h' was specified + int divisor_used = 95; // 125 KHz + // see if 'h' was specified - if (command[strlen((char *) command) - 1] == 'h') - divisor_used = 88; // 134.8 KHz + if (command[strlen((char *) command) - 1] == 'h') + divisor_used = 88; // 134.8 KHz - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // Give it a bit of time for the resonant antenna to settle. - SpinDelay(50); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + // Give it a bit of time for the resonant antenna to settle. + SpinDelay(50); - // And a little more time for the tag to fully power up - SpinDelay(2000); + // And a little more time for the tag to fully power up + SpinDelay(2000); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); - // now modulate the reader field - while(*command != '\0' && *command != ' ') { - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LED_D_OFF(); - SpinDelayUs(delay_off); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); + // now modulate the reader field + while(*command != '\0' && *command != ' ') { + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LED_D_OFF(); + SpinDelayUs(delay_off); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - LED_D_ON(); - if(*(command++) == '0') - SpinDelayUs(period_0); - else - SpinDelayUs(period_1); - } - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LED_D_OFF(); - SpinDelayUs(delay_off); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + LED_D_ON(); + if(*(command++) == '0') + SpinDelayUs(period_0); + else + SpinDelayUs(period_1); + } + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LED_D_OFF(); + SpinDelayUs(delay_off); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // now do the read - DoAcquisition125k(-1); + // now do the read + DoAcquisition125k(-1); } /* blank r/w tag data stream @@ -169,230 +169,227 @@ void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, */ void ReadTItag(void) { - // some hardcoded initial params - // when we read a TI tag we sample the zerocross line at 2Mhz - // TI tags modulate a 1 as 16 cycles of 123.2Khz - // TI tags modulate a 0 as 16 cycles of 134.2Khz -#define FSAMPLE 2000000 -#define FREQLO 123200 -#define FREQHI 134200 + // some hardcoded initial params + // when we read a TI tag we sample the zerocross line at 2Mhz + // TI tags modulate a 1 as 16 cycles of 123.2Khz + // TI tags modulate a 0 as 16 cycles of 134.2Khz + #define FSAMPLE 2000000 + #define FREQLO 123200 + #define FREQHI 134200 - signed char *dest = (signed char *)BigBuf; - int n = sizeof(BigBuf); - // int *dest = GraphBuffer; - // int n = GraphTraceLen; + signed char *dest = (signed char *)BigBuf; + int n = sizeof(BigBuf); + // 128 bit shift register [shift3:shift2:shift1:shift0] + uint32_t shift3 = 0, shift2 = 0, shift1 = 0, shift0 = 0; - // 128 bit shift register [shift3:shift2:shift1:shift0] - uint32_t shift3 = 0, shift2 = 0, shift1 = 0, shift0 = 0; + int i, cycles=0, samples=0; + // how many sample points fit in 16 cycles of each frequency + uint32_t sampleslo = (FSAMPLE<<4)/FREQLO, sampleshi = (FSAMPLE<<4)/FREQHI; + // when to tell if we're close enough to one freq or another + uint32_t threshold = (sampleslo - sampleshi + 1)>>1; - int i, cycles=0, samples=0; - // how many sample points fit in 16 cycles of each frequency - uint32_t sampleslo = (FSAMPLE<<4)/FREQLO, sampleshi = (FSAMPLE<<4)/FREQHI; - // when to tell if we're close enough to one freq or another - uint32_t threshold = (sampleslo - sampleshi + 1)>>1; + // TI tags charge at 134.2Khz + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz - // TI tags charge at 134.2Khz - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz + // Place FPGA in passthrough mode, in this mode the CROSS_LO line + // connects to SSP_DIN and the SSP_DOUT logic level controls + // whether we're modulating the antenna (high) + // or listening to the antenna (low) + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); - // Place FPGA in passthrough mode, in this mode the CROSS_LO line - // connects to SSP_DIN and the SSP_DOUT logic level controls - // whether we're modulating the antenna (high) - // or listening to the antenna (low) - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); + // get TI tag data into the buffer + AcquireTiType(); - // get TI tag data into the buffer - AcquireTiType(); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + for (i=0; i0) ) { + cycles++; + // after 16 cycles, measure the frequency + if (cycles>15) { + cycles=0; + samples=i-samples; // number of samples in these 16 cycles - for (i=0; i0) ) { - cycles++; - // after 16 cycles, measure the frequency - if (cycles>15) { - cycles=0; - samples=i-samples; // number of samples in these 16 cycles + // TI bits are coming to us lsb first so shift them + // right through our 128 bit right shift register + shift0 = (shift0>>1) | (shift1 << 31); + shift1 = (shift1>>1) | (shift2 << 31); + shift2 = (shift2>>1) | (shift3 << 31); + shift3 >>= 1; - // TI bits are coming to us lsb first so shift them - // right through our 128 bit right shift register - shift0 = (shift0>>1) | (shift1 << 31); - shift1 = (shift1>>1) | (shift2 << 31); - shift2 = (shift2>>1) | (shift3 << 31); - shift3 >>= 1; + // check if the cycles fall close to the number + // expected for either the low or high frequency + if ( (samples>(sampleslo-threshold)) && (samples<(sampleslo+threshold)) ) { + // low frequency represents a 1 + shift3 |= (1<<31); + } else if ( (samples>(sampleshi-threshold)) && (samples<(sampleshi+threshold)) ) { + // high frequency represents a 0 + } else { + // probably detected a gay waveform or noise + // use this as gaydar or discard shift register and start again + shift3 = shift2 = shift1 = shift0 = 0; + } + samples = i; - // check if the cycles fall close to the number - // expected for either the low or high frequency - if ( (samples>(sampleslo-threshold)) && (samples<(sampleslo+threshold)) ) { - // low frequency represents a 1 - shift3 |= (1<<31); - } else if ( (samples>(sampleshi-threshold)) && (samples<(sampleshi+threshold)) ) { - // high frequency represents a 0 - } else { - // probably detected a gay waveform or noise - // use this as gaydar or discard shift register and start again - shift3 = shift2 = shift1 = shift0 = 0; - } - samples = i; + // for each bit we receive, test if we've detected a valid tag - // for each bit we receive, test if we've detected a valid tag + // if we see 17 zeroes followed by 6 ones, we might have a tag + // remember the bits are backwards + if ( ((shift0 & 0x7fffff) == 0x7e0000) ) { + // if start and end bytes match, we have a tag so break out of the loop + if ( ((shift0>>16)&0xff) == ((shift3>>8)&0xff) ) { + cycles = 0xF0B; //use this as a flag (ugly but whatever) + break; + } + } + } + } + } - // if we see 17 zeroes followed by 6 ones, we might have a tag - // remember the bits are backwards - if ( ((shift0 & 0x7fffff) == 0x7e0000) ) { - // if start and end bytes match, we have a tag so break out of the loop - if ( ((shift0>>16)&0xff) == ((shift3>>8)&0xff) ) { - cycles = 0xF0B; //use this as a flag (ugly but whatever) - break; - } - } - } - } - } + // if flag is set we have a tag + if (cycles!=0xF0B) { + DbpString("Info: No valid tag detected."); + } else { + // put 64 bit data into shift1 and shift0 + shift0 = (shift0>>24) | (shift1 << 8); + shift1 = (shift1>>24) | (shift2 << 8); - // if flag is set we have a tag - if (cycles!=0xF0B) { - DbpString("Info: No valid tag detected."); - } else { - // put 64 bit data into shift1 and shift0 - shift0 = (shift0>>24) | (shift1 << 8); - shift1 = (shift1>>24) | (shift2 << 8); + // align 16 bit crc into lower half of shift2 + shift2 = ((shift2>>24) | (shift3 << 8)) & 0x0ffff; - // align 16 bit crc into lower half of shift2 - shift2 = ((shift2>>24) | (shift3 << 8)) & 0x0ffff; + // if r/w tag, check ident match + if (shift3 & (1<<15) ) { + DbpString("Info: TI tag is rewriteable"); + // only 15 bits compare, last bit of ident is not valid + if (((shift3 >> 16) ^ shift0) & 0x7fff ) { + DbpString("Error: Ident mismatch!"); + } else { + DbpString("Info: TI tag ident is valid"); + } + } else { + DbpString("Info: TI tag is readonly"); + } - // if r/w tag, check ident match - if ( shift3&(1<<15) ) { - DbpString("Info: TI tag is rewriteable"); - // only 15 bits compare, last bit of ident is not valid - if ( ((shift3>>16)^shift0)&0x7fff ) { - DbpString("Error: Ident mismatch!"); - } else { - DbpString("Info: TI tag ident is valid"); - } - } else { - DbpString("Info: TI tag is readonly"); - } + // WARNING the order of the bytes in which we calc crc below needs checking + // i'm 99% sure the crc algorithm is correct, but it may need to eat the + // bytes in reverse or something + // calculate CRC + uint32_t crc=0; - // WARNING the order of the bytes in which we calc crc below needs checking - // i'm 99% sure the crc algorithm is correct, but it may need to eat the - // bytes in reverse or something - // calculate CRC - uint32_t crc=0; + crc = update_crc16(crc, (shift0)&0xff); + crc = update_crc16(crc, (shift0>>8)&0xff); + crc = update_crc16(crc, (shift0>>16)&0xff); + crc = update_crc16(crc, (shift0>>24)&0xff); + crc = update_crc16(crc, (shift1)&0xff); + crc = update_crc16(crc, (shift1>>8)&0xff); + crc = update_crc16(crc, (shift1>>16)&0xff); + crc = update_crc16(crc, (shift1>>24)&0xff); - crc = update_crc16(crc, (shift0)&0xff); - crc = update_crc16(crc, (shift0>>8)&0xff); - crc = update_crc16(crc, (shift0>>16)&0xff); - crc = update_crc16(crc, (shift0>>24)&0xff); - crc = update_crc16(crc, (shift1)&0xff); - crc = update_crc16(crc, (shift1>>8)&0xff); - crc = update_crc16(crc, (shift1>>16)&0xff); - crc = update_crc16(crc, (shift1>>24)&0xff); - - Dbprintf("Info: Tag data: %x%08x, crc=%x", - (unsigned int)shift1, (unsigned int)shift0, (unsigned int)shift2 & 0xFFFF); - if (crc != (shift2&0xffff)) { - Dbprintf("Error: CRC mismatch, expected %x", (unsigned int)crc); - } else { - DbpString("Info: CRC is good"); - } - } + Dbprintf("Info: Tag data: %x%08x, crc=%x", + (unsigned int)shift1, (unsigned int)shift0, (unsigned int)shift2 & 0xFFFF); + if (crc != (shift2&0xffff)) { + Dbprintf("Error: CRC mismatch, expected %x", (unsigned int)crc); + } else { + DbpString("Info: CRC is good"); + } + } } void WriteTIbyte(uint8_t b) { - int i = 0; + int i = 0; - // modulate 8 bits out to the antenna - for (i=0; i<8; i++) - { - if (b&(1<PIO_PDR = GPIO_SSC_DIN; - AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN; + // Set up the synchronous serial port + AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DIN; + AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN; - // steal this pin from the SSP and use it to control the modulation - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + // steal this pin from the SSP and use it to control the modulation + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST; - AT91C_BASE_SSC->SSC_CR = AT91C_SSC_RXEN | AT91C_SSC_TXEN; + AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST; + AT91C_BASE_SSC->SSC_CR = AT91C_SSC_RXEN | AT91C_SSC_TXEN; - // Sample at 2 Mbit/s, so TI tags are 16.2 vs. 14.9 clocks long - // 48/2 = 24 MHz clock must be divided by 12 - AT91C_BASE_SSC->SSC_CMR = 12; + // Sample at 2 Mbit/s, so TI tags are 16.2 vs. 14.9 clocks long + // 48/2 = 24 MHz clock must be divided by 12 + AT91C_BASE_SSC->SSC_CMR = 12; - AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(0); - AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(32) | AT91C_SSC_MSBF; - AT91C_BASE_SSC->SSC_TCMR = 0; - AT91C_BASE_SSC->SSC_TFMR = 0; + AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(0); + AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(32) | AT91C_SSC_MSBF; + AT91C_BASE_SSC->SSC_TCMR = 0; + AT91C_BASE_SSC->SSC_TFMR = 0; - LED_D_ON(); + LED_D_ON(); - // modulate antenna - HIGH(GPIO_SSC_DOUT); + // modulate antenna + HIGH(GPIO_SSC_DOUT); - // Charge TI tag for 50ms. - SpinDelay(50); + // Charge TI tag for 50ms. + SpinDelay(50); - // stop modulating antenna and listen - LOW(GPIO_SSC_DOUT); + // stop modulating antenna and listen + LOW(GPIO_SSC_DOUT); - LED_D_OFF(); + LED_D_OFF(); - i = 0; - for(;;) { - if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - BigBuf[i] = AT91C_BASE_SSC->SSC_RHR; // store 32 bit values in buffer - i++; if(i >= TIBUFLEN) break; - } - WDT_HIT(); - } + i = 0; + for(;;) { + if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + BigBuf[i] = AT91C_BASE_SSC->SSC_RHR; // store 32 bit values in buffer + i++; if(i >= TIBUFLEN) break; + } + WDT_HIT(); + } - // return stolen pin to SSP - AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN | GPIO_SSC_DOUT; + // return stolen pin to SSP + AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN | GPIO_SSC_DOUT; - char *dest = (char *)BigBuf; - n = TIBUFLEN*32; - // unpack buffer - for (i=TIBUFLEN-1; i>=0; i--) { - for (j=0; j<32; j++) { - if(BigBuf[i] & (1 << j)) { - dest[--n] = 1; - } else { - dest[--n] = -1; - } - } - } + char *dest = (char *)BigBuf; + n = TIBUFLEN*32; + // unpack buffer + for (i=TIBUFLEN-1; i>=0; i--) { + for (j=0; j<32; j++) { + if(BigBuf[i] & (1 << j)) { + dest[--n] = 1; + } else { + dest[--n] = -1; + } + } + } } // arguments: 64bit data split into 32bit idhi:idlo and optional 16bit crc @@ -400,127 +397,127 @@ void AcquireTiType(void) // if not provided a valid crc will be computed from the data and written. void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc) { - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - if(crc == 0) { - crc = update_crc16(crc, (idlo)&0xff); - crc = update_crc16(crc, (idlo>>8)&0xff); - crc = update_crc16(crc, (idlo>>16)&0xff); - crc = update_crc16(crc, (idlo>>24)&0xff); - crc = update_crc16(crc, (idhi)&0xff); - crc = update_crc16(crc, (idhi>>8)&0xff); - crc = update_crc16(crc, (idhi>>16)&0xff); - crc = update_crc16(crc, (idhi>>24)&0xff); - } - Dbprintf("Writing to tag: %x%08x, crc=%x", - (unsigned int) idhi, (unsigned int) idlo, crc); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + if(crc == 0) { + crc = update_crc16(crc, (idlo)&0xff); + crc = update_crc16(crc, (idlo>>8)&0xff); + crc = update_crc16(crc, (idlo>>16)&0xff); + crc = update_crc16(crc, (idlo>>24)&0xff); + crc = update_crc16(crc, (idhi)&0xff); + crc = update_crc16(crc, (idhi>>8)&0xff); + crc = update_crc16(crc, (idhi>>16)&0xff); + crc = update_crc16(crc, (idhi>>24)&0xff); + } + Dbprintf("Writing to tag: %x%08x, crc=%x", + (unsigned int) idhi, (unsigned int) idlo, crc); - // TI tags charge at 134.2Khz - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz - // Place FPGA in passthrough mode, in this mode the CROSS_LO line - // connects to SSP_DIN and the SSP_DOUT logic level controls - // whether we're modulating the antenna (high) - // or listening to the antenna (low) - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); - LED_A_ON(); + // TI tags charge at 134.2Khz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz + // Place FPGA in passthrough mode, in this mode the CROSS_LO line + // connects to SSP_DIN and the SSP_DOUT logic level controls + // whether we're modulating the antenna (high) + // or listening to the antenna (low) + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); + LED_A_ON(); - // steal this pin from the SSP and use it to control the modulation - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + // steal this pin from the SSP and use it to control the modulation + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - // writing algorithm: - // a high bit consists of a field off for 1ms and field on for 1ms - // a low bit consists of a field off for 0.3ms and field on for 1.7ms - // initiate a charge time of 50ms (field on) then immediately start writing bits - // start by writing 0xBB (keyword) and 0xEB (password) - // then write 80 bits of data (or 64 bit data + 16 bit crc if you prefer) - // finally end with 0x0300 (write frame) - // all data is sent lsb firts - // finish with 15ms programming time + // writing algorithm: + // a high bit consists of a field off for 1ms and field on for 1ms + // a low bit consists of a field off for 0.3ms and field on for 1.7ms + // initiate a charge time of 50ms (field on) then immediately start writing bits + // start by writing 0xBB (keyword) and 0xEB (password) + // then write 80 bits of data (or 64 bit data + 16 bit crc if you prefer) + // finally end with 0x0300 (write frame) + // all data is sent lsb firts + // finish with 15ms programming time - // modulate antenna - HIGH(GPIO_SSC_DOUT); - SpinDelay(50); // charge time + // modulate antenna + HIGH(GPIO_SSC_DOUT); + SpinDelay(50); // charge time - WriteTIbyte(0xbb); // keyword - WriteTIbyte(0xeb); // password - WriteTIbyte( (idlo )&0xff ); - WriteTIbyte( (idlo>>8 )&0xff ); - WriteTIbyte( (idlo>>16)&0xff ); - WriteTIbyte( (idlo>>24)&0xff ); - WriteTIbyte( (idhi )&0xff ); - WriteTIbyte( (idhi>>8 )&0xff ); - WriteTIbyte( (idhi>>16)&0xff ); - WriteTIbyte( (idhi>>24)&0xff ); // data hi to lo - WriteTIbyte( (crc )&0xff ); // crc lo - WriteTIbyte( (crc>>8 )&0xff ); // crc hi - WriteTIbyte(0x00); // write frame lo - WriteTIbyte(0x03); // write frame hi - HIGH(GPIO_SSC_DOUT); - SpinDelay(50); // programming time + WriteTIbyte(0xbb); // keyword + WriteTIbyte(0xeb); // password + WriteTIbyte( (idlo )&0xff ); + WriteTIbyte( (idlo>>8 )&0xff ); + WriteTIbyte( (idlo>>16)&0xff ); + WriteTIbyte( (idlo>>24)&0xff ); + WriteTIbyte( (idhi )&0xff ); + WriteTIbyte( (idhi>>8 )&0xff ); + WriteTIbyte( (idhi>>16)&0xff ); + WriteTIbyte( (idhi>>24)&0xff ); // data hi to lo + WriteTIbyte( (crc )&0xff ); // crc lo + WriteTIbyte( (crc>>8 )&0xff ); // crc hi + WriteTIbyte(0x00); // write frame lo + WriteTIbyte(0x03); // write frame hi + HIGH(GPIO_SSC_DOUT); + SpinDelay(50); // programming time - LED_A_OFF(); + LED_A_OFF(); - // get TI tag data into the buffer - AcquireTiType(); + // get TI tag data into the buffer + AcquireTiType(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - DbpString("Now use tiread to check"); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + DbpString("Now use tiread to check"); } void SimulateTagLowFrequency(int period, int gap, int ledcontrol) { - int i; - uint8_t *tab = (uint8_t *)BigBuf; - - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); - - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK; - - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK; - + int i; + uint8_t *tab = (uint8_t *)BigBuf; + + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); + + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK; + + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK; + #define SHORT_COIL() LOW(GPIO_SSC_DOUT) #define OPEN_COIL() HIGH(GPIO_SSC_DOUT) - - i = 0; - for(;;) { - while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) { - if(BUTTON_PRESS()) { - DbpString("Stopped"); - return; - } - WDT_HIT(); - } - - if (ledcontrol) - LED_D_ON(); - - if(tab[i]) - OPEN_COIL(); - else - SHORT_COIL(); - - if (ledcontrol) - LED_D_OFF(); - - while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) { - if(BUTTON_PRESS()) { - DbpString("Stopped"); - return; - } - WDT_HIT(); - } - - i++; - if(i == period) { - i = 0; - if (gap) { - SHORT_COIL(); - SpinDelayUs(gap); - } - } - } + + i = 0; + for(;;) { + while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) { + if(BUTTON_PRESS()) { + DbpString("Stopped"); + return; + } + WDT_HIT(); + } + + if (ledcontrol) + LED_D_ON(); + + if(tab[i]) + OPEN_COIL(); + else + SHORT_COIL(); + + if (ledcontrol) + LED_D_OFF(); + + while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) { + if(BUTTON_PRESS()) { + DbpString("Stopped"); + return; + } + WDT_HIT(); + } + + i++; + if(i == period) { + i = 0; + if (gap) { + SHORT_COIL(); + SpinDelayUs(gap); + } + } + } } #define DEBUG_FRAME_CONTENTS 1 @@ -530,314 +527,309 @@ void SimulateTagLowFrequencyBidir(int divisor, int t0) // compose fc/8 fc/10 waveform static void fc(int c, int *n) { - uint8_t *dest = (uint8_t *)BigBuf; - int idx; + uint8_t *dest = (uint8_t *)BigBuf; + int idx; - // for when we want an fc8 pattern every 4 logical bits - if(c==0) { - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - } - // an fc/8 encoded bit is a bit pattern of 11000000 x6 = 48 samples - if(c==8) { - for (idx=0; idx<6; idx++) { - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - } - } + // for when we want an fc8 pattern every 4 logical bits + if(c==0) { + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + } + // an fc/8 encoded bit is a bit pattern of 11000000 x6 = 48 samples + if(c==8) { + for (idx=0; idx<6; idx++) { + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + } + } - // an fc/10 encoded bit is a bit pattern of 1110000000 x5 = 50 samples - if(c==10) { - for (idx=0; idx<5; idx++) { - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - } - } + // an fc/10 encoded bit is a bit pattern of 1110000000 x5 = 50 samples + if(c==10) { + for (idx=0; idx<5; idx++) { + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + } + } } // prepare a waveform pattern in the buffer based on the ID given then // simulate a HID tag until the button is pressed void CmdHIDsimTAG(int hi, int lo, int ledcontrol) { - int n=0, i=0; - /* - HID tag bitstream format - The tag contains a 44bit unique code. This is sent out MSB first in sets of 4 bits - A 1 bit is represented as 6 fc8 and 5 fc10 patterns - A 0 bit is represented as 5 fc10 and 6 fc8 patterns - A fc8 is inserted before every 4 bits - A special start of frame pattern is used consisting a0b0 where a and b are neither 0 - nor 1 bits, they are special patterns (a = set of 12 fc8 and b = set of 10 fc10) - */ + int n=0, i=0; + /* + HID tag bitstream format + The tag contains a 44bit unique code. This is sent out MSB first in sets of 4 bits + A 1 bit is represented as 6 fc8 and 5 fc10 patterns + A 0 bit is represented as 5 fc10 and 6 fc8 patterns + A fc8 is inserted before every 4 bits + A special start of frame pattern is used consisting a0b0 where a and b are neither 0 + nor 1 bits, they are special patterns (a = set of 12 fc8 and b = set of 10 fc10) + */ - if (hi>0xFFF) { - DbpString("Tags can only have 44 bits."); - return; - } - fc(0,&n); - // special start of frame marker containing invalid bit sequences - fc(8, &n); fc(8, &n); // invalid - fc(8, &n); fc(10, &n); // logical 0 - fc(10, &n); fc(10, &n); // invalid - fc(8, &n); fc(10, &n); // logical 0 + if (hi>0xFFF) { + DbpString("Tags can only have 44 bits."); + return; + } + fc(0,&n); + // special start of frame marker containing invalid bit sequences + fc(8, &n); fc(8, &n); // invalid + fc(8, &n); fc(10, &n); // logical 0 + fc(10, &n); fc(10, &n); // invalid + fc(8, &n); fc(10, &n); // logical 0 - WDT_HIT(); - // manchester encode bits 43 to 32 - for (i=11; i>=0; i--) { - if ((i%4)==3) fc(0,&n); - if ((hi>>i)&1) { - fc(10, &n); fc(8, &n); // low-high transition - } else { - fc(8, &n); fc(10, &n); // high-low transition - } - } + WDT_HIT(); + // manchester encode bits 43 to 32 + for (i=11; i>=0; i--) { + if ((i%4)==3) fc(0,&n); + if ((hi>>i)&1) { + fc(10, &n); fc(8, &n); // low-high transition + } else { + fc(8, &n); fc(10, &n); // high-low transition + } + } - WDT_HIT(); - // manchester encode bits 31 to 0 - for (i=31; i>=0; i--) { - if ((i%4)==3) fc(0,&n); - if ((lo>>i)&1) { - fc(10, &n); fc(8, &n); // low-high transition - } else { - fc(8, &n); fc(10, &n); // high-low transition - } - } + WDT_HIT(); + // manchester encode bits 31 to 0 + for (i=31; i>=0; i--) { + if ((i%4)==3) fc(0,&n); + if ((lo>>i)&1) { + fc(10, &n); fc(8, &n); // low-high transition + } else { + fc(8, &n); fc(10, &n); // high-low transition + } + } - if (ledcontrol) - LED_A_ON(); - SimulateTagLowFrequency(n, 0, ledcontrol); + if (ledcontrol) + LED_A_ON(); + SimulateTagLowFrequency(n, 0, ledcontrol); - if (ledcontrol) - LED_A_OFF(); + if (ledcontrol) + LED_A_OFF(); } // loop to get raw HID waveform then FSK demodulate the TAG ID from it void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) { - uint8_t *dest = (uint8_t *)BigBuf; + uint8_t *dest = (uint8_t *)BigBuf; - size_t size=0; //, found=0; - uint32_t hi2=0, hi=0, lo=0; + size_t size=0; //, found=0; + uint32_t hi2=0, hi=0, lo=0; - // Configure to go in 125Khz listen mode - LFSetupFPGAForADC(95, true); + // Configure to go in 125Khz listen mode + LFSetupFPGAForADC(95, true); - while(!BUTTON_PRESS()) { + while(!BUTTON_PRESS()) { - WDT_HIT(); - if (ledcontrol) LED_A_ON(); + WDT_HIT(); + if (ledcontrol) LED_A_ON(); - DoAcquisition125k_internal(-1,true); - size = sizeof(BigBuf); - if (size < 2000) continue; - // FSK demodulator + DoAcquisition125k_internal(-1,true); + // FSK demodulator + size = HIDdemodFSK(dest, sizeof(BigBuf), &hi2, &hi, &lo); - int bitLen = HIDdemodFSK(dest,size,&hi2,&hi,&lo); + WDT_HIT(); - WDT_HIT(); - - if (bitLen>0 && lo>0){ - // final loop, go over previously decoded manchester data and decode into usable tag ID - // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0 - if (hi2 != 0){ //extra large HID tags - Dbprintf("TAG ID: %x%08x%08x (%d)", - (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); - }else { //standard HID tags <38 bits - //Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd - uint8_t bitlen = 0; - uint32_t fc = 0; - uint32_t cardnum = 0; - if (((hi>>5)&1)==1){//if bit 38 is set then < 37 bit format is used - uint32_t lo2=0; - lo2=(((hi & 31) << 12) | (lo>>20)); //get bits 21-37 to check for format len bit - uint8_t idx3 = 1; - while(lo2>1){ //find last bit set to 1 (format len bit) - lo2=lo2>>1; - idx3++; - } - bitlen =idx3+19; - fc =0; - cardnum=0; - if(bitlen==26){ - cardnum = (lo>>1)&0xFFFF; - fc = (lo>>17)&0xFF; - } - if(bitlen==37){ - cardnum = (lo>>1)&0x7FFFF; - fc = ((hi&0xF)<<12)|(lo>>20); - } - if(bitlen==34){ - cardnum = (lo>>1)&0xFFFF; - fc= ((hi&1)<<15)|(lo>>17); - } - if(bitlen==35){ - cardnum = (lo>>1)&0xFFFFF; - fc = ((hi&1)<<11)|(lo>>21); - } - } - else { //if bit 38 is not set then 37 bit format is used - bitlen= 37; - fc =0; - cardnum=0; - if(bitlen==37){ - cardnum = (lo>>1)&0x7FFFF; - fc = ((hi&0xF)<<12)|(lo>>20); - } - } - //Dbprintf("TAG ID: %x%08x (%d)", - // (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); - Dbprintf("TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d", - (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF, - (unsigned int) bitlen, (unsigned int) fc, (unsigned int) cardnum); - } - if (findone){ - if (ledcontrol) LED_A_OFF(); - return; - } - // reset - hi2 = hi = lo = 0; - } - WDT_HIT(); - //SpinDelay(50); - } - DbpString("Stopped"); - if (ledcontrol) LED_A_OFF(); + if (size>0 && lo>0){ + // final loop, go over previously decoded manchester data and decode into usable tag ID + // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0 + if (hi2 != 0){ //extra large HID tags + Dbprintf("TAG ID: %x%08x%08x (%d)", + (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); + }else { //standard HID tags <38 bits + //Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd + uint8_t bitlen = 0; + uint32_t fc = 0; + uint32_t cardnum = 0; + if (((hi>>5)&1) == 1){//if bit 38 is set then < 37 bit format is used + uint32_t lo2=0; + lo2=(((hi & 31) << 12) | (lo>>20)); //get bits 21-37 to check for format len bit + uint8_t idx3 = 1; + while(lo2 > 1){ //find last bit set to 1 (format len bit) + lo2=lo2 >> 1; + idx3++; + } + bitlen = idx3+19; + fc =0; + cardnum=0; + if(bitlen == 26){ + cardnum = (lo>>1)&0xFFFF; + fc = (lo>>17)&0xFF; + } + if(bitlen == 37){ + cardnum = (lo>>1)&0x7FFFF; + fc = ((hi&0xF)<<12)|(lo>>20); + } + if(bitlen == 34){ + cardnum = (lo>>1)&0xFFFF; + fc= ((hi&1)<<15)|(lo>>17); + } + if(bitlen == 35){ + cardnum = (lo>>1)&0xFFFFF; + fc = ((hi&1)<<11)|(lo>>21); + } + } + else { //if bit 38 is not set then 37 bit format is used + bitlen= 37; + fc =0; + cardnum=0; + if(bitlen==37){ + cardnum = (lo>>1)&0x7FFFF; + fc = ((hi&0xF)<<12)|(lo>>20); + } + } + //Dbprintf("TAG ID: %x%08x (%d)", + // (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); + Dbprintf("TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d", + (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF, + (unsigned int) bitlen, (unsigned int) fc, (unsigned int) cardnum); + } + if (findone){ + if (ledcontrol) LED_A_OFF(); + return; + } + // reset + hi2 = hi = lo = 0; + } + WDT_HIT(); + } + DbpString("Stopped"); + if (ledcontrol) LED_A_OFF(); } void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol) { - uint8_t *dest = (uint8_t *)BigBuf; + uint8_t *dest = (uint8_t *)BigBuf; - size_t size=0; //, found=0; - uint32_t bitLen=0; - int clk=0, invert=0, errCnt=0; - uint64_t lo=0; - // Configure to go in 125Khz listen mode - LFSetupFPGAForADC(95, true); + size_t size=0; + int clk=0, invert=0, errCnt=0; + uint64_t lo=0; + // Configure to go in 125Khz listen mode + LFSetupFPGAForADC(95, true); - while(!BUTTON_PRESS()) { + while(!BUTTON_PRESS()) { - WDT_HIT(); - if (ledcontrol) LED_A_ON(); + WDT_HIT(); + if (ledcontrol) LED_A_ON(); - DoAcquisition125k_internal(-1,true); - size = sizeof(BigBuf); - if (size < 2000) continue; - // FSK demodulator - //int askmandemod(uint8_t *BinStream,uint32_t *BitLen,int *clk, int *invert); - bitLen=size; - //Dbprintf("DEBUG: Buffer got"); - errCnt = askmandemod(dest,&bitLen,&clk,&invert); //HIDdemodFSK(dest,size,&hi2,&hi,&lo); - //Dbprintf("DEBUG: ASK Got"); - WDT_HIT(); + DoAcquisition125k_internal(-1,true); + size = sizeof(BigBuf); + //Dbprintf("DEBUG: Buffer got"); + //askdemod and manchester decode + errCnt = askmandemod(dest, &size, &clk, &invert); + //Dbprintf("DEBUG: ASK Got"); + WDT_HIT(); - if (errCnt>=0){ - lo = Em410xDecode(dest,bitLen); - //Dbprintf("DEBUG: EM GOT"); - //printEM410x(lo); - if (lo>0){ - Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)",(uint32_t)(lo>>32),(uint32_t)lo,(uint32_t)(lo&0xFFFF),(uint32_t)((lo>>16LL) & 0xFF),(uint32_t)(lo & 0xFFFFFF)); - } - if (findone){ - if (ledcontrol) LED_A_OFF(); - return; - } - } else{ - //Dbprintf("DEBUG: No Tag"); - } - WDT_HIT(); - lo = 0; - clk=0; - invert=0; - errCnt=0; - size=0; - //SpinDelay(50); - } - DbpString("Stopped"); - if (ledcontrol) LED_A_OFF(); + if (errCnt>=0){ + lo = Em410xDecode(dest,size); + //Dbprintf("DEBUG: EM GOT"); + if (lo>0){ + Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)", + (uint32_t)(lo>>32), + (uint32_t)lo, + (uint32_t)(lo&0xFFFF), + (uint32_t)((lo>>16LL) & 0xFF), + (uint32_t)(lo & 0xFFFFFF)); + } + if (findone){ + if (ledcontrol) LED_A_OFF(); + return; + } + } else{ + //Dbprintf("DEBUG: No Tag"); + } + WDT_HIT(); + lo = 0; + clk=0; + invert=0; + errCnt=0; + size=0; + } + DbpString("Stopped"); + if (ledcontrol) LED_A_OFF(); } void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) { - uint8_t *dest = (uint8_t *)BigBuf; - int idx=0; - uint32_t code=0, code2=0; - uint8_t version=0; - uint8_t facilitycode=0; - uint16_t number=0; - // Configure to go in 125Khz listen mode - LFSetupFPGAForADC(95, true); + uint8_t *dest = (uint8_t *)BigBuf; + int idx=0; + uint32_t code=0, code2=0; + uint8_t version=0; + uint8_t facilitycode=0; + uint16_t number=0; + // Configure to go in 125Khz listen mode + LFSetupFPGAForADC(95, true); - while(!BUTTON_PRESS()) { - WDT_HIT(); - if (ledcontrol) LED_A_ON(); - DoAcquisition125k_internal(-1,true); - //fskdemod and get start index - WDT_HIT(); - idx = IOdemodFSK(dest,sizeof(BigBuf)); - if (idx>0){ - //valid tag found + while(!BUTTON_PRESS()) { + WDT_HIT(); + if (ledcontrol) LED_A_ON(); + DoAcquisition125k_internal(-1,true); + //fskdemod and get start index + WDT_HIT(); + idx = IOdemodFSK(dest,sizeof(BigBuf)); + if (idx>0){ + //valid tag found - //Index map - //0 10 20 30 40 50 60 - //| | | | | | | - //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23 - //----------------------------------------------------------------------------- - //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11 - // - //XSF(version)facility:codeone+codetwo - //Handle the data - if(findone){ //only print binary if we are doing one - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx], dest[idx+1], dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7],dest[idx+8]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15],dest[idx+16],dest[idx+17]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23],dest[idx+24],dest[idx+25],dest[idx+26]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31],dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39],dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+45],dest[idx+46],dest[idx+47],dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53]); - Dbprintf("%d%d%d%d%d%d%d%d %d%d",dest[idx+54],dest[idx+55],dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]); - } - code = bytebits_to_byte(dest+idx,32); - code2 = bytebits_to_byte(dest+idx+32,32); - version = bytebits_to_byte(dest+idx+27,8); //14,4 - facilitycode = bytebits_to_byte(dest+idx+18,8) ; - number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9 + //Index map + //0 10 20 30 40 50 60 + //| | | | | | | + //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23 + //----------------------------------------------------------------------------- + //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11 + // + //XSF(version)facility:codeone+codetwo + //Handle the data + if(findone){ //only print binary if we are doing one + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx], dest[idx+1], dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7],dest[idx+8]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15],dest[idx+16],dest[idx+17]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23],dest[idx+24],dest[idx+25],dest[idx+26]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31],dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39],dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+45],dest[idx+46],dest[idx+47],dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53]); + Dbprintf("%d%d%d%d%d%d%d%d %d%d",dest[idx+54],dest[idx+55],dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]); + } + code = bytebits_to_byte(dest+idx,32); + code2 = bytebits_to_byte(dest+idx+32,32); + version = bytebits_to_byte(dest+idx+27,8); //14,4 + facilitycode = bytebits_to_byte(dest+idx+18,8) ; + number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9 - Dbprintf("XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2); - // if we're only looking for one tag - if (findone){ - if (ledcontrol) LED_A_OFF(); - //LED_A_OFF(); - return; - } - code=code2=0; - version=facilitycode=0; - number=0; - idx=0; - } - WDT_HIT(); - } - DbpString("Stopped"); - if (ledcontrol) LED_A_OFF(); + Dbprintf("XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2); + // if we're only looking for one tag + if (findone){ + if (ledcontrol) LED_A_OFF(); + //LED_A_OFF(); + return; + } + code=code2=0; + version=facilitycode=0; + number=0; + idx=0; + } + WDT_HIT(); + } + DbpString("Stopped"); + if (ledcontrol) LED_A_OFF(); } /*------------------------------ @@ -907,321 +899,321 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) // Write one bit to card void T55xxWriteBit(int bit) { - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - if (bit == 0) - SpinDelayUs(WRITE_0); - else - SpinDelayUs(WRITE_1); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelayUs(WRITE_GAP); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + if (bit == 0) + SpinDelayUs(WRITE_0); + else + SpinDelayUs(WRITE_1); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelayUs(WRITE_GAP); } // Write one card block in page 0, no lock void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode) { - //unsigned int i; //enio adjustment 12/10/14 - uint32_t i; + //unsigned int i; //enio adjustment 12/10/14 + uint32_t i; - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // Give it a bit of time for the resonant antenna to settle. - // And for the tag to fully power up - SpinDelay(150); + // Give it a bit of time for the resonant antenna to settle. + // And for the tag to fully power up + SpinDelay(150); - // Now start writting - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelayUs(START_GAP); + // Now start writting + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelayUs(START_GAP); - // Opcode - T55xxWriteBit(1); - T55xxWriteBit(0); //Page 0 - if (PwdMode == 1){ - // Pwd - for (i = 0x80000000; i != 0; i >>= 1) - T55xxWriteBit(Pwd & i); - } - // Lock bit - T55xxWriteBit(0); + // Opcode + T55xxWriteBit(1); + T55xxWriteBit(0); //Page 0 + if (PwdMode == 1){ + // Pwd + for (i = 0x80000000; i != 0; i >>= 1) + T55xxWriteBit(Pwd & i); + } + // Lock bit + T55xxWriteBit(0); - // Data - for (i = 0x80000000; i != 0; i >>= 1) - T55xxWriteBit(Data & i); + // Data + for (i = 0x80000000; i != 0; i >>= 1) + T55xxWriteBit(Data & i); - // Block - for (i = 0x04; i != 0; i >>= 1) - T55xxWriteBit(Block & i); + // Block + for (i = 0x04; i != 0; i >>= 1) + T55xxWriteBit(Block & i); - // Now perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550, - // so wait a little more) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - SpinDelay(20); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + // Now perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550, + // so wait a little more) + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + SpinDelay(20); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); } // Read one card block in page 0 void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode) { - uint8_t *dest = (uint8_t *)BigBuf; - //int m=0, i=0; //enio adjustment 12/10/14 - uint32_t m=0, i=0; - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - m = sizeof(BigBuf); - // Clear destination buffer before sending the command - memset(dest, 128, m); - // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); + uint8_t *dest = (uint8_t *)BigBuf; + //int m=0, i=0; //enio adjustment 12/10/14 + uint32_t m=0, i=0; + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + m = sizeof(BigBuf); + // Clear destination buffer before sending the command + memset(dest, 128, m); + // Connect the A/D to the peak-detected low-frequency path. + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); - LED_D_ON(); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + LED_D_ON(); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // Give it a bit of time for the resonant antenna to settle. - // And for the tag to fully power up - SpinDelay(150); + // Give it a bit of time for the resonant antenna to settle. + // And for the tag to fully power up + SpinDelay(150); - // Now start writting - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelayUs(START_GAP); + // Now start writting + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelayUs(START_GAP); - // Opcode - T55xxWriteBit(1); - T55xxWriteBit(0); //Page 0 - if (PwdMode == 1){ - // Pwd - for (i = 0x80000000; i != 0; i >>= 1) - T55xxWriteBit(Pwd & i); - } - // Lock bit - T55xxWriteBit(0); - // Block - for (i = 0x04; i != 0; i >>= 1) - T55xxWriteBit(Block & i); + // Opcode + T55xxWriteBit(1); + T55xxWriteBit(0); //Page 0 + if (PwdMode == 1){ + // Pwd + for (i = 0x80000000; i != 0; i >>= 1) + T55xxWriteBit(Pwd & i); + } + // Lock bit + T55xxWriteBit(0); + // Block + for (i = 0x04; i != 0; i >>= 1) + T55xxWriteBit(Block & i); - // Turn field on to read the response - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + // Turn field on to read the response + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // Now do the acquisition - i = 0; - for(;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - // we don't care about actual value, only if it's more or less than a - // threshold essentially we capture zero crossings for later analysis - // if(dest[i] < 127) dest[i] = 0; else dest[i] = 1; - i++; - if (i >= m) break; - } - } + // Now do the acquisition + i = 0; + for(;;) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0x43; + } + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + // we don't care about actual value, only if it's more or less than a + // threshold essentially we capture zero crossings for later analysis + // if(dest[i] < 127) dest[i] = 0; else dest[i] = 1; + i++; + if (i >= m) break; + } + } - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); - DbpString("DONE!"); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + LED_D_OFF(); + DbpString("DONE!"); } // Read card traceability data (page 1) void T55xxReadTrace(void){ - uint8_t *dest = (uint8_t *)BigBuf; - int m=0, i=0; + uint8_t *dest = (uint8_t *)BigBuf; + int m=0, i=0; - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - m = sizeof(BigBuf); - // Clear destination buffer before sending the command - memset(dest, 128, m); - // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + m = sizeof(BigBuf); + // Clear destination buffer before sending the command + memset(dest, 128, m); + // Connect the A/D to the peak-detected low-frequency path. + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); - LED_D_ON(); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + LED_D_ON(); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // Give it a bit of time for the resonant antenna to settle. - // And for the tag to fully power up - SpinDelay(150); + // Give it a bit of time for the resonant antenna to settle. + // And for the tag to fully power up + SpinDelay(150); - // Now start writting - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelayUs(START_GAP); + // Now start writting + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelayUs(START_GAP); - // Opcode - T55xxWriteBit(1); - T55xxWriteBit(1); //Page 1 + // Opcode + T55xxWriteBit(1); + T55xxWriteBit(1); //Page 1 - // Turn field on to read the response - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + // Turn field on to read the response + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // Now do the acquisition - i = 0; - for(;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - i++; - if (i >= m) break; - } - } + // Now do the acquisition + i = 0; + for(;;) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0x43; + } + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + i++; + if (i >= m) break; + } + } - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); - DbpString("DONE!"); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + LED_D_OFF(); + DbpString("DONE!"); } /*-------------- Cloning routines -----------*/ // Copy HID id to card and setup block 0 config void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT) { - int data1=0, data2=0, data3=0, data4=0, data5=0, data6=0; //up to six blocks for long format - int last_block = 0; + int data1=0, data2=0, data3=0, data4=0, data5=0, data6=0; //up to six blocks for long format + int last_block = 0; - if (longFMT){ - // Ensure no more than 84 bits supplied - if (hi2>0xFFFFF) { - DbpString("Tags can only have 84 bits."); - return; - } - // Build the 6 data blocks for supplied 84bit ID - last_block = 6; - data1 = 0x1D96A900; // load preamble (1D) & long format identifier (9E manchester encoded) - for (int i=0;i<4;i++) { - if (hi2 & (1<<(19-i))) - data1 |= (1<<(((3-i)*2)+1)); // 1 -> 10 - else - data1 |= (1<<((3-i)*2)); // 0 -> 01 - } + if (longFMT){ + // Ensure no more than 84 bits supplied + if (hi2>0xFFFFF) { + DbpString("Tags can only have 84 bits."); + return; + } + // Build the 6 data blocks for supplied 84bit ID + last_block = 6; + data1 = 0x1D96A900; // load preamble (1D) & long format identifier (9E manchester encoded) + for (int i=0;i<4;i++) { + if (hi2 & (1<<(19-i))) + data1 |= (1<<(((3-i)*2)+1)); // 1 -> 10 + else + data1 |= (1<<((3-i)*2)); // 0 -> 01 + } - data2 = 0; - for (int i=0;i<16;i++) { - if (hi2 & (1<<(15-i))) - data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data2 |= (1<<((15-i)*2)); // 0 -> 01 - } + data2 = 0; + for (int i=0;i<16;i++) { + if (hi2 & (1<<(15-i))) + data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data2 |= (1<<((15-i)*2)); // 0 -> 01 + } - data3 = 0; - for (int i=0;i<16;i++) { - if (hi & (1<<(31-i))) - data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data3 |= (1<<((15-i)*2)); // 0 -> 01 - } + data3 = 0; + for (int i=0;i<16;i++) { + if (hi & (1<<(31-i))) + data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data3 |= (1<<((15-i)*2)); // 0 -> 01 + } - data4 = 0; - for (int i=0;i<16;i++) { - if (hi & (1<<(15-i))) - data4 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data4 |= (1<<((15-i)*2)); // 0 -> 01 - } + data4 = 0; + for (int i=0;i<16;i++) { + if (hi & (1<<(15-i))) + data4 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data4 |= (1<<((15-i)*2)); // 0 -> 01 + } - data5 = 0; - for (int i=0;i<16;i++) { - if (lo & (1<<(31-i))) - data5 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data5 |= (1<<((15-i)*2)); // 0 -> 01 - } + data5 = 0; + for (int i=0;i<16;i++) { + if (lo & (1<<(31-i))) + data5 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data5 |= (1<<((15-i)*2)); // 0 -> 01 + } - data6 = 0; - for (int i=0;i<16;i++) { - if (lo & (1<<(15-i))) - data6 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data6 |= (1<<((15-i)*2)); // 0 -> 01 - } - } - else { - // Ensure no more than 44 bits supplied - if (hi>0xFFF) { - DbpString("Tags can only have 44 bits."); - return; - } + data6 = 0; + for (int i=0;i<16;i++) { + if (lo & (1<<(15-i))) + data6 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data6 |= (1<<((15-i)*2)); // 0 -> 01 + } + } + else { + // Ensure no more than 44 bits supplied + if (hi>0xFFF) { + DbpString("Tags can only have 44 bits."); + return; + } - // Build the 3 data blocks for supplied 44bit ID - last_block = 3; + // Build the 3 data blocks for supplied 44bit ID + last_block = 3; - data1 = 0x1D000000; // load preamble + data1 = 0x1D000000; // load preamble - for (int i=0;i<12;i++) { - if (hi & (1<<(11-i))) - data1 |= (1<<(((11-i)*2)+1)); // 1 -> 10 - else - data1 |= (1<<((11-i)*2)); // 0 -> 01 - } + for (int i=0;i<12;i++) { + if (hi & (1<<(11-i))) + data1 |= (1<<(((11-i)*2)+1)); // 1 -> 10 + else + data1 |= (1<<((11-i)*2)); // 0 -> 01 + } - data2 = 0; - for (int i=0;i<16;i++) { - if (lo & (1<<(31-i))) - data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data2 |= (1<<((15-i)*2)); // 0 -> 01 - } + data2 = 0; + for (int i=0;i<16;i++) { + if (lo & (1<<(31-i))) + data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data2 |= (1<<((15-i)*2)); // 0 -> 01 + } - data3 = 0; - for (int i=0;i<16;i++) { - if (lo & (1<<(15-i))) - data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data3 |= (1<<((15-i)*2)); // 0 -> 01 - } - } + data3 = 0; + for (int i=0;i<16;i++) { + if (lo & (1<<(15-i))) + data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data3 |= (1<<((15-i)*2)); // 0 -> 01 + } + } - LED_D_ON(); - // Program the data blocks for supplied ID - // and the block 0 for HID format - T55xxWriteBlock(data1,1,0,0); - T55xxWriteBlock(data2,2,0,0); - T55xxWriteBlock(data3,3,0,0); + LED_D_ON(); + // Program the data blocks for supplied ID + // and the block 0 for HID format + T55xxWriteBlock(data1,1,0,0); + T55xxWriteBlock(data2,2,0,0); + T55xxWriteBlock(data3,3,0,0); - if (longFMT) { // if long format there are 6 blocks - T55xxWriteBlock(data4,4,0,0); - T55xxWriteBlock(data5,5,0,0); - T55xxWriteBlock(data6,6,0,0); - } + if (longFMT) { // if long format there are 6 blocks + T55xxWriteBlock(data4,4,0,0); + T55xxWriteBlock(data5,5,0,0); + T55xxWriteBlock(data6,6,0,0); + } - // Config for HID (RF/50, FSK2a, Maxblock=3 for short/6 for long) - T55xxWriteBlock(T55x7_BITRATE_RF_50 | - T55x7_MODULATION_FSK2a | - last_block << T55x7_MAXBLOCK_SHIFT, - 0,0,0); + // Config for HID (RF/50, FSK2a, Maxblock=3 for short/6 for long) + T55xxWriteBlock(T55x7_BITRATE_RF_50 | + T55x7_MODULATION_FSK2a | + last_block << T55x7_MAXBLOCK_SHIFT, + 0,0,0); - LED_D_OFF(); + LED_D_OFF(); - DbpString("DONE!"); + DbpString("DONE!"); } void CopyIOtoT55x7(uint32_t hi, uint32_t lo, uint8_t longFMT) { - int data1=0, data2=0; //up to six blocks for long format + int data1=0, data2=0; //up to six blocks for long format - data1 = hi; // load preamble - data2 = lo; - - LED_D_ON(); - // Program the data blocks for supplied ID - // and the block 0 for HID format - T55xxWriteBlock(data1,1,0,0); - T55xxWriteBlock(data2,2,0,0); + data1 = hi; // load preamble + data2 = lo; - //Config Block - T55xxWriteBlock(0x00147040,0,0,0); - LED_D_OFF(); + LED_D_ON(); + // Program the data blocks for supplied ID + // and the block 0 for HID format + T55xxWriteBlock(data1,1,0,0); + T55xxWriteBlock(data2,2,0,0); - DbpString("DONE!"); + //Config Block + T55xxWriteBlock(0x00147040,0,0,0); + LED_D_OFF(); + + DbpString("DONE!"); } // Define 9bit header for EM410x tags @@ -1230,151 +1222,151 @@ void CopyIOtoT55x7(uint32_t hi, uint32_t lo, uint8_t longFMT) void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo) { - int i, id_bit; - uint64_t id = EM410X_HEADER; - uint64_t rev_id = 0; // reversed ID - int c_parity[4]; // column parity - int r_parity = 0; // row parity - uint32_t clock = 0; + int i, id_bit; + uint64_t id = EM410X_HEADER; + uint64_t rev_id = 0; // reversed ID + int c_parity[4]; // column parity + int r_parity = 0; // row parity + uint32_t clock = 0; - // Reverse ID bits given as parameter (for simpler operations) - for (i = 0; i < EM410X_ID_LENGTH; ++i) { - if (i < 32) { - rev_id = (rev_id << 1) | (id_lo & 1); - id_lo >>= 1; - } else { - rev_id = (rev_id << 1) | (id_hi & 1); - id_hi >>= 1; - } - } + // Reverse ID bits given as parameter (for simpler operations) + for (i = 0; i < EM410X_ID_LENGTH; ++i) { + if (i < 32) { + rev_id = (rev_id << 1) | (id_lo & 1); + id_lo >>= 1; + } else { + rev_id = (rev_id << 1) | (id_hi & 1); + id_hi >>= 1; + } + } - for (i = 0; i < EM410X_ID_LENGTH; ++i) { - id_bit = rev_id & 1; + for (i = 0; i < EM410X_ID_LENGTH; ++i) { + id_bit = rev_id & 1; - if (i % 4 == 0) { - // Don't write row parity bit at start of parsing - if (i) - id = (id << 1) | r_parity; - // Start counting parity for new row - r_parity = id_bit; - } else { - // Count row parity - r_parity ^= id_bit; - } + if (i % 4 == 0) { + // Don't write row parity bit at start of parsing + if (i) + id = (id << 1) | r_parity; + // Start counting parity for new row + r_parity = id_bit; + } else { + // Count row parity + r_parity ^= id_bit; + } - // First elements in column? - if (i < 4) - // Fill out first elements - c_parity[i] = id_bit; - else - // Count column parity - c_parity[i % 4] ^= id_bit; + // First elements in column? + if (i < 4) + // Fill out first elements + c_parity[i] = id_bit; + else + // Count column parity + c_parity[i % 4] ^= id_bit; - // Insert ID bit - id = (id << 1) | id_bit; - rev_id >>= 1; - } + // Insert ID bit + id = (id << 1) | id_bit; + rev_id >>= 1; + } - // Insert parity bit of last row - id = (id << 1) | r_parity; + // Insert parity bit of last row + id = (id << 1) | r_parity; - // Fill out column parity at the end of tag - for (i = 0; i < 4; ++i) - id = (id << 1) | c_parity[i]; + // Fill out column parity at the end of tag + for (i = 0; i < 4; ++i) + id = (id << 1) | c_parity[i]; - // Add stop bit - id <<= 1; + // Add stop bit + id <<= 1; - Dbprintf("Started writing %s tag ...", card ? "T55x7":"T5555"); - LED_D_ON(); + Dbprintf("Started writing %s tag ...", card ? "T55x7":"T5555"); + LED_D_ON(); - // Write EM410x ID - T55xxWriteBlock((uint32_t)(id >> 32), 1, 0, 0); - T55xxWriteBlock((uint32_t)id, 2, 0, 0); + // Write EM410x ID + T55xxWriteBlock((uint32_t)(id >> 32), 1, 0, 0); + T55xxWriteBlock((uint32_t)id, 2, 0, 0); - // Config for EM410x (RF/64, Manchester, Maxblock=2) - if (card) { - // Clock rate is stored in bits 8-15 of the card value - clock = (card & 0xFF00) >> 8; - Dbprintf("Clock rate: %d", clock); - switch (clock) - { - case 32: - clock = T55x7_BITRATE_RF_32; - break; - case 16: - clock = T55x7_BITRATE_RF_16; - break; - case 0: - // A value of 0 is assumed to be 64 for backwards-compatibility - // Fall through... - case 64: - clock = T55x7_BITRATE_RF_64; - break; - default: - Dbprintf("Invalid clock rate: %d", clock); - return; - } + // Config for EM410x (RF/64, Manchester, Maxblock=2) + if (card) { + // Clock rate is stored in bits 8-15 of the card value + clock = (card & 0xFF00) >> 8; + Dbprintf("Clock rate: %d", clock); + switch (clock) + { + case 32: + clock = T55x7_BITRATE_RF_32; + break; + case 16: + clock = T55x7_BITRATE_RF_16; + break; + case 0: + // A value of 0 is assumed to be 64 for backwards-compatibility + // Fall through... + case 64: + clock = T55x7_BITRATE_RF_64; + break; + default: + Dbprintf("Invalid clock rate: %d", clock); + return; + } - // Writing configuration for T55x7 tag - T55xxWriteBlock(clock | - T55x7_MODULATION_MANCHESTER | - 2 << T55x7_MAXBLOCK_SHIFT, - 0, 0, 0); - } - else - // Writing configuration for T5555(Q5) tag - T55xxWriteBlock(0x1F << T5555_BITRATE_SHIFT | - T5555_MODULATION_MANCHESTER | - 2 << T5555_MAXBLOCK_SHIFT, - 0, 0, 0); + // Writing configuration for T55x7 tag + T55xxWriteBlock(clock | + T55x7_MODULATION_MANCHESTER | + 2 << T55x7_MAXBLOCK_SHIFT, + 0, 0, 0); + } + else + // Writing configuration for T5555(Q5) tag + T55xxWriteBlock(0x1F << T5555_BITRATE_SHIFT | + T5555_MODULATION_MANCHESTER | + 2 << T5555_MAXBLOCK_SHIFT, + 0, 0, 0); - LED_D_OFF(); - Dbprintf("Tag %s written with 0x%08x%08x\n", card ? "T55x7":"T5555", - (uint32_t)(id >> 32), (uint32_t)id); + LED_D_OFF(); + Dbprintf("Tag %s written with 0x%08x%08x\n", card ? "T55x7":"T5555", + (uint32_t)(id >> 32), (uint32_t)id); } // Clone Indala 64-bit tag by UID to T55x7 void CopyIndala64toT55x7(int hi, int lo) { - //Program the 2 data blocks for supplied 64bit UID - // and the block 0 for Indala64 format - T55xxWriteBlock(hi,1,0,0); - T55xxWriteBlock(lo,2,0,0); - //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=2) - T55xxWriteBlock(T55x7_BITRATE_RF_32 | - T55x7_MODULATION_PSK1 | - 2 << T55x7_MAXBLOCK_SHIFT, - 0, 0, 0); - //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data) - // T5567WriteBlock(0x603E1042,0); + //Program the 2 data blocks for supplied 64bit UID + // and the block 0 for Indala64 format + T55xxWriteBlock(hi,1,0,0); + T55xxWriteBlock(lo,2,0,0); + //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=2) + T55xxWriteBlock(T55x7_BITRATE_RF_32 | + T55x7_MODULATION_PSK1 | + 2 << T55x7_MAXBLOCK_SHIFT, + 0, 0, 0); + //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data) + // T5567WriteBlock(0x603E1042,0); - DbpString("DONE!"); + DbpString("DONE!"); -} +} void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int uid6, int uid7) { - //Program the 7 data blocks for supplied 224bit UID - // and the block 0 for Indala224 format - T55xxWriteBlock(uid1,1,0,0); - T55xxWriteBlock(uid2,2,0,0); - T55xxWriteBlock(uid3,3,0,0); - T55xxWriteBlock(uid4,4,0,0); - T55xxWriteBlock(uid5,5,0,0); - T55xxWriteBlock(uid6,6,0,0); - T55xxWriteBlock(uid7,7,0,0); - //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=7) - T55xxWriteBlock(T55x7_BITRATE_RF_32 | - T55x7_MODULATION_PSK1 | - 7 << T55x7_MAXBLOCK_SHIFT, - 0,0,0); - //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data) - // T5567WriteBlock(0x603E10E2,0); + //Program the 7 data blocks for supplied 224bit UID + // and the block 0 for Indala224 format + T55xxWriteBlock(uid1,1,0,0); + T55xxWriteBlock(uid2,2,0,0); + T55xxWriteBlock(uid3,3,0,0); + T55xxWriteBlock(uid4,4,0,0); + T55xxWriteBlock(uid5,5,0,0); + T55xxWriteBlock(uid6,6,0,0); + T55xxWriteBlock(uid7,7,0,0); + //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=7) + T55xxWriteBlock(T55x7_BITRATE_RF_32 | + T55x7_MODULATION_PSK1 | + 7 << T55x7_MAXBLOCK_SHIFT, + 0,0,0); + //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data) + // T5567WriteBlock(0x603E10E2,0); - DbpString("DONE!"); + DbpString("DONE!"); } @@ -1383,261 +1375,261 @@ void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int #define max(x,y) ( x GraphBuffer[0]) { - while(i < GraphTraceLen) { - if( !(GraphBuffer[i] > GraphBuffer[i-1]) && GraphBuffer[i] > lmax) - break; - i++; - } - dir = 0; - } - else { - while(i < GraphTraceLen) { - if( !(GraphBuffer[i] < GraphBuffer[i-1]) && GraphBuffer[i] < lmin) - break; - i++; - } - dir = 1; - } + /* Find first local max/min */ + if(GraphBuffer[1] > GraphBuffer[0]) { + while(i < GraphTraceLen) { + if( !(GraphBuffer[i] > GraphBuffer[i-1]) && GraphBuffer[i] > lmax) + break; + i++; + } + dir = 0; + } + else { + while(i < GraphTraceLen) { + if( !(GraphBuffer[i] < GraphBuffer[i-1]) && GraphBuffer[i] < lmin) + break; + i++; + } + dir = 1; + } - lastval = i++; - half_switch = 0; - pmc = 0; - block_done = 0; + lastval = i++; + half_switch = 0; + pmc = 0; + block_done = 0; - for (bitidx = 0; i < GraphTraceLen; i++) - { - if ( (GraphBuffer[i-1] > GraphBuffer[i] && dir == 1 && GraphBuffer[i] > lmax) || (GraphBuffer[i-1] < GraphBuffer[i] && dir == 0 && GraphBuffer[i] < lmin)) - { - lc = i - lastval; - lastval = i; + for (bitidx = 0; i < GraphTraceLen; i++) + { + if ( (GraphBuffer[i-1] > GraphBuffer[i] && dir == 1 && GraphBuffer[i] > lmax) || (GraphBuffer[i-1] < GraphBuffer[i] && dir == 0 && GraphBuffer[i] < lmin)) + { + lc = i - lastval; + lastval = i; - // Switch depending on lc length: - // Tolerance is 1/8 of clock rate (arbitrary) - if (abs(lc-clock/4) < tolerance) { - // 16T0 - if((i - pmc) == lc) { /* 16T0 was previous one */ - /* It's a PMC ! */ - i += (128+127+16+32+33+16)-1; - lastval = i; - pmc = 0; - block_done = 1; - } - else { - pmc = i; - } - } else if (abs(lc-clock/2) < tolerance) { - // 32TO - if((i - pmc) == lc) { /* 16T0 was previous one */ - /* It's a PMC ! */ - i += (128+127+16+32+33)-1; - lastval = i; - pmc = 0; - block_done = 1; - } - else if(half_switch == 1) { - BitStream[bitidx++] = 0; - half_switch = 0; - } - else - half_switch++; - } else if (abs(lc-clock) < tolerance) { - // 64TO - BitStream[bitidx++] = 1; - } else { - // Error - warnings++; - if (warnings > 10) - { - Dbprintf("Error: too many detection errors, aborting."); - return 0; - } - } + // Switch depending on lc length: + // Tolerance is 1/8 of clock rate (arbitrary) + if (abs(lc-clock/4) < tolerance) { + // 16T0 + if((i - pmc) == lc) { /* 16T0 was previous one */ + /* It's a PMC ! */ + i += (128+127+16+32+33+16)-1; + lastval = i; + pmc = 0; + block_done = 1; + } + else { + pmc = i; + } + } else if (abs(lc-clock/2) < tolerance) { + // 32TO + if((i - pmc) == lc) { /* 16T0 was previous one */ + /* It's a PMC ! */ + i += (128+127+16+32+33)-1; + lastval = i; + pmc = 0; + block_done = 1; + } + else if(half_switch == 1) { + BitStream[bitidx++] = 0; + half_switch = 0; + } + else + half_switch++; + } else if (abs(lc-clock) < tolerance) { + // 64TO + BitStream[bitidx++] = 1; + } else { + // Error + warnings++; + if (warnings > 10) + { + Dbprintf("Error: too many detection errors, aborting."); + return 0; + } + } - if(block_done == 1) { - if(bitidx == 128) { - for(j=0; j<16; j++) { - Blocks[num_blocks][j] = 128*BitStream[j*8+7]+ - 64*BitStream[j*8+6]+ - 32*BitStream[j*8+5]+ - 16*BitStream[j*8+4]+ - 8*BitStream[j*8+3]+ - 4*BitStream[j*8+2]+ - 2*BitStream[j*8+1]+ - BitStream[j*8]; - } - num_blocks++; - } - bitidx = 0; - block_done = 0; - half_switch = 0; - } - if(i < GraphTraceLen) - { - if (GraphBuffer[i-1] > GraphBuffer[i]) dir=0; - else dir = 1; - } - } - if(bitidx==255) - bitidx=0; - warnings = 0; - if(num_blocks == 4) break; - } - memcpy(outBlocks, Blocks, 16*num_blocks); - return num_blocks; + if(block_done == 1) { + if(bitidx == 128) { + for(j=0; j<16; j++) { + Blocks[num_blocks][j] = 128*BitStream[j*8+7]+ + 64*BitStream[j*8+6]+ + 32*BitStream[j*8+5]+ + 16*BitStream[j*8+4]+ + 8*BitStream[j*8+3]+ + 4*BitStream[j*8+2]+ + 2*BitStream[j*8+1]+ + BitStream[j*8]; + } + num_blocks++; + } + bitidx = 0; + block_done = 0; + half_switch = 0; + } + if(i < GraphTraceLen) + { + if (GraphBuffer[i-1] > GraphBuffer[i]) dir=0; + else dir = 1; + } + } + if(bitidx==255) + bitidx=0; + warnings = 0; + if(num_blocks == 4) break; + } + memcpy(outBlocks, Blocks, 16*num_blocks); + return num_blocks; } int IsBlock0PCF7931(uint8_t *Block) { - // Assume RFU means 0 :) - if((memcmp(Block, "\x00\x00\x00\x00\x00\x00\x00\x01", 8) == 0) && memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) // PAC enabled - return 1; - if((memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) && Block[7] == 0) // PAC disabled, can it *really* happen ? - return 1; - return 0; + // Assume RFU means 0 :) + if((memcmp(Block, "\x00\x00\x00\x00\x00\x00\x00\x01", 8) == 0) && memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) // PAC enabled + return 1; + if((memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) && Block[7] == 0) // PAC disabled, can it *really* happen ? + return 1; + return 0; } int IsBlock1PCF7931(uint8_t *Block) { - // Assume RFU means 0 :) - if(Block[10] == 0 && Block[11] == 0 && Block[12] == 0 && Block[13] == 0) - if((Block[14] & 0x7f) <= 9 && Block[15] <= 9) - return 1; + // Assume RFU means 0 :) + if(Block[10] == 0 && Block[11] == 0 && Block[12] == 0 && Block[13] == 0) + if((Block[14] & 0x7f) <= 9 && Block[15] <= 9) + return 1; - return 0; + return 0; } #define ALLOC 16 void ReadPCF7931() { - uint8_t Blocks[8][17]; - uint8_t tmpBlocks[4][16]; - int i, j, ind, ind2, n; - int num_blocks = 0; - int max_blocks = 8; - int ident = 0; - int error = 0; - int tries = 0; + uint8_t Blocks[8][17]; + uint8_t tmpBlocks[4][16]; + int i, j, ind, ind2, n; + int num_blocks = 0; + int max_blocks = 8; + int ident = 0; + int error = 0; + int tries = 0; - memset(Blocks, 0, 8*17*sizeof(uint8_t)); + memset(Blocks, 0, 8*17*sizeof(uint8_t)); - do { - memset(tmpBlocks, 0, 4*16*sizeof(uint8_t)); - n = DemodPCF7931((uint8_t**)tmpBlocks); - if(!n) - error++; - if(error==10 && num_blocks == 0) { - Dbprintf("Error, no tag or bad tag"); - return; - } - else if (tries==20 || error==10) { - Dbprintf("Error reading the tag"); - Dbprintf("Here is the partial content"); - goto end; - } + do { + memset(tmpBlocks, 0, 4*16*sizeof(uint8_t)); + n = DemodPCF7931((uint8_t**)tmpBlocks); + if(!n) + error++; + if(error==10 && num_blocks == 0) { + Dbprintf("Error, no tag or bad tag"); + return; + } + else if (tries==20 || error==10) { + Dbprintf("Error reading the tag"); + Dbprintf("Here is the partial content"); + goto end; + } - for(i=0; i= 0; ind--,ind2--) { - if(ind2 < 0) - ind2 = max_blocks; - if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found - // Dbprintf("Tmp %d -> Block %d", ind, ind2); - memcpy(Blocks[ind2], tmpBlocks[ind], 16); - Blocks[ind2][ALLOC] = 1; - num_blocks++; - if(num_blocks == max_blocks) goto end; - } - } - for(ind=i+1,ind2=j+1; ind < n; ind++,ind2++) { - if(ind2 > max_blocks) - ind2 = 0; - if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found - // Dbprintf("Tmp %d -> Block %d", ind, ind2); - memcpy(Blocks[ind2], tmpBlocks[ind], 16); - Blocks[ind2][ALLOC] = 1; - num_blocks++; - if(num_blocks == max_blocks) goto end; - } - } - } - } - } - } - } - tries++; - if (BUTTON_PRESS()) return; - } while (num_blocks != max_blocks); + for(i=0; i= 0; ind--,ind2--) { + if(ind2 < 0) + ind2 = max_blocks; + if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found + // Dbprintf("Tmp %d -> Block %d", ind, ind2); + memcpy(Blocks[ind2], tmpBlocks[ind], 16); + Blocks[ind2][ALLOC] = 1; + num_blocks++; + if(num_blocks == max_blocks) goto end; + } + } + for(ind=i+1,ind2=j+1; ind < n; ind++,ind2++) { + if(ind2 > max_blocks) + ind2 = 0; + if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found + // Dbprintf("Tmp %d -> Block %d", ind, ind2); + memcpy(Blocks[ind2], tmpBlocks[ind], 16); + Blocks[ind2][ALLOC] = 1; + num_blocks++; + if(num_blocks == max_blocks) goto end; + } + } + } + } + } + } + } + tries++; + if (BUTTON_PRESS()) return; + } while (num_blocks != max_blocks); end: - Dbprintf("-----------------------------------------"); - Dbprintf("Memory content:"); - Dbprintf("-----------------------------------------"); - for(i=0; i", i); - } - Dbprintf("-----------------------------------------"); + Dbprintf("-----------------------------------------"); + Dbprintf("Memory content:"); + Dbprintf("-----------------------------------------"); + for(i=0; i", i); + } + Dbprintf("-----------------------------------------"); - return ; + return ; } @@ -1661,20 +1653,20 @@ uint8_t * fwd_write_ptr; //forwardlink bit pointer //==================================================================== //-------------------------------------------------------------------- uint8_t Prepare_Cmd( uint8_t cmd ) { - //-------------------------------------------------------------------- + //-------------------------------------------------------------------- - *forward_ptr++ = 0; //start bit - *forward_ptr++ = 0; //second pause for 4050 code + *forward_ptr++ = 0; //start bit + *forward_ptr++ = 0; //second pause for 4050 code - *forward_ptr++ = cmd; - cmd >>= 1; - *forward_ptr++ = cmd; - cmd >>= 1; - *forward_ptr++ = cmd; - cmd >>= 1; - *forward_ptr++ = cmd; + *forward_ptr++ = cmd; + cmd >>= 1; + *forward_ptr++ = cmd; + cmd >>= 1; + *forward_ptr++ = cmd; + cmd >>= 1; + *forward_ptr++ = cmd; - return 6; //return number of emited bits + return 6; //return number of emited bits } //==================================================================== @@ -1684,21 +1676,21 @@ uint8_t Prepare_Cmd( uint8_t cmd ) { //-------------------------------------------------------------------- uint8_t Prepare_Addr( uint8_t addr ) { - //-------------------------------------------------------------------- + //-------------------------------------------------------------------- - register uint8_t line_parity; + register uint8_t line_parity; - uint8_t i; - line_parity = 0; - for(i=0;i<6;i++) { - *forward_ptr++ = addr; - line_parity ^= addr; - addr >>= 1; - } + uint8_t i; + line_parity = 0; + for(i=0;i<6;i++) { + *forward_ptr++ = addr; + line_parity ^= addr; + addr >>= 1; + } - *forward_ptr++ = (line_parity & 1); + *forward_ptr++ = (line_parity & 1); - return 7; //return number of emited bits + return 7; //return number of emited bits } //==================================================================== @@ -1708,36 +1700,36 @@ uint8_t Prepare_Addr( uint8_t addr ) { //-------------------------------------------------------------------- uint8_t Prepare_Data( uint16_t data_low, uint16_t data_hi) { - //-------------------------------------------------------------------- + //-------------------------------------------------------------------- - register uint8_t line_parity; - register uint8_t column_parity; - register uint8_t i, j; - register uint16_t data; + register uint8_t line_parity; + register uint8_t column_parity; + register uint8_t i, j; + register uint16_t data; - data = data_low; - column_parity = 0; + data = data_low; + column_parity = 0; - for(i=0; i<4; i++) { - line_parity = 0; - for(j=0; j<8; j++) { - line_parity ^= data; - column_parity ^= (data & 1) << j; - *forward_ptr++ = data; - data >>= 1; - } - *forward_ptr++ = line_parity; - if(i == 1) - data = data_hi; - } + for(i=0; i<4; i++) { + line_parity = 0; + for(j=0; j<8; j++) { + line_parity ^= data; + column_parity ^= (data & 1) << j; + *forward_ptr++ = data; + data >>= 1; + } + *forward_ptr++ = line_parity; + if(i == 1) + data = data_hi; + } - for(j=0; j<8; j++) { - *forward_ptr++ = column_parity; - column_parity >>= 1; - } - *forward_ptr = 0; + for(j=0; j<8; j++) { + *forward_ptr++ = column_parity; + column_parity >>= 1; + } + *forward_ptr = 0; - return 45; //return number of emited bits + return 45; //return number of emited bits } //==================================================================== @@ -1747,114 +1739,114 @@ uint8_t Prepare_Data( uint16_t data_low, uint16_t data_hi) { //==================================================================== void SendForward(uint8_t fwd_bit_count) { - fwd_write_ptr = forwardLink_data; - fwd_bit_sz = fwd_bit_count; + fwd_write_ptr = forwardLink_data; + fwd_bit_sz = fwd_bit_count; - LED_D_ON(); + LED_D_ON(); - //Field on - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + //Field on + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // Give it a bit of time for the resonant antenna to settle. - // And for the tag to fully power up - SpinDelay(150); + // Give it a bit of time for the resonant antenna to settle. + // And for the tag to fully power up + SpinDelay(150); - // force 1st mod pulse (start gap must be longer for 4305) - fwd_bit_sz--; //prepare next bit modulation - fwd_write_ptr++; - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - SpinDelayUs(55*8); //55 cycles off (8us each)for 4305 - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on - SpinDelayUs(16*8); //16 cycles on (8us each) + // force 1st mod pulse (start gap must be longer for 4305) + fwd_bit_sz--; //prepare next bit modulation + fwd_write_ptr++; + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + SpinDelayUs(55*8); //55 cycles off (8us each)for 4305 + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on + SpinDelayUs(16*8); //16 cycles on (8us each) - // now start writting - while(fwd_bit_sz-- > 0) { //prepare next bit modulation - if(((*fwd_write_ptr++) & 1) == 1) - SpinDelayUs(32*8); //32 cycles at 125Khz (8us each) - else { - //These timings work for 4469/4269/4305 (with the 55*8 above) - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - SpinDelayUs(23*8); //16-4 cycles off (8us each) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on - SpinDelayUs(9*8); //16 cycles on (8us each) - } - } + // now start writting + while(fwd_bit_sz-- > 0) { //prepare next bit modulation + if(((*fwd_write_ptr++) & 1) == 1) + SpinDelayUs(32*8); //32 cycles at 125Khz (8us each) + else { + //These timings work for 4469/4269/4305 (with the 55*8 above) + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + SpinDelayUs(23*8); //16-4 cycles off (8us each) + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on + SpinDelayUs(9*8); //16 cycles on (8us each) + } + } } void EM4xLogin(uint32_t Password) { - uint8_t fwd_bit_count; + uint8_t fwd_bit_count; - forward_ptr = forwardLink_data; - fwd_bit_count = Prepare_Cmd( FWD_CMD_LOGIN ); - fwd_bit_count += Prepare_Data( Password&0xFFFF, Password>>16 ); + forward_ptr = forwardLink_data; + fwd_bit_count = Prepare_Cmd( FWD_CMD_LOGIN ); + fwd_bit_count += Prepare_Data( Password&0xFFFF, Password>>16 ); - SendForward(fwd_bit_count); + SendForward(fwd_bit_count); - //Wait for command to complete - SpinDelay(20); + //Wait for command to complete + SpinDelay(20); } void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) { - uint8_t fwd_bit_count; - uint8_t *dest = (uint8_t *)BigBuf; - int m=0, i=0; + uint8_t fwd_bit_count; + uint8_t *dest = (uint8_t *)BigBuf; + int m=0, i=0; - //If password mode do login - if (PwdMode == 1) EM4xLogin(Pwd); + //If password mode do login + if (PwdMode == 1) EM4xLogin(Pwd); - forward_ptr = forwardLink_data; - fwd_bit_count = Prepare_Cmd( FWD_CMD_READ ); - fwd_bit_count += Prepare_Addr( Address ); + forward_ptr = forwardLink_data; + fwd_bit_count = Prepare_Cmd( FWD_CMD_READ ); + fwd_bit_count += Prepare_Addr( Address ); - m = sizeof(BigBuf); - // Clear destination buffer before sending the command - memset(dest, 128, m); - // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); + m = sizeof(BigBuf); + // Clear destination buffer before sending the command + memset(dest, 128, m); + // Connect the A/D to the peak-detected low-frequency path. + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); - SendForward(fwd_bit_count); + SendForward(fwd_bit_count); - // Now do the acquisition - i = 0; - for(;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - i++; - if (i >= m) break; - } - } - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); + // Now do the acquisition + i = 0; + for(;;) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0x43; + } + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + i++; + if (i >= m) break; + } + } + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + LED_D_OFF(); } void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode) { - uint8_t fwd_bit_count; + uint8_t fwd_bit_count; - //If password mode do login - if (PwdMode == 1) EM4xLogin(Pwd); + //If password mode do login + if (PwdMode == 1) EM4xLogin(Pwd); - forward_ptr = forwardLink_data; - fwd_bit_count = Prepare_Cmd( FWD_CMD_WRITE ); - fwd_bit_count += Prepare_Addr( Address ); - fwd_bit_count += Prepare_Data( Data&0xFFFF, Data>>16 ); + forward_ptr = forwardLink_data; + fwd_bit_count = Prepare_Cmd( FWD_CMD_WRITE ); + fwd_bit_count += Prepare_Addr( Address ); + fwd_bit_count += Prepare_Data( Data&0xFFFF, Data>>16 ); - SendForward(fwd_bit_count); + SendForward(fwd_bit_count); - //Wait for write to complete - SpinDelay(20); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); + //Wait for write to complete + SpinDelay(20); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + LED_D_OFF(); } diff --git a/client/cmddata.c b/client/cmddata.c index 4b5cb0401..bce5d2ced 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -27,82 +27,82 @@ static int CmdHelp(const char *Cmd); //set the demod buffer with given array of binary (one bit per byte) //by marshmellow -void setDemodBuf(uint8_t *buff,int size) +void setDemodBuf(uint8_t *buff,int size) { - int i=0; - for (; i < size; ++i){ - DemodBuffer[i]=buff[i]; - } - DemodBufferLen=size; - return; + int i=0; + for (; i < size; ++i){ + DemodBuffer[i]=buff[i]; + } + DemodBufferLen=size; + return; } //by marshmellow void printDemodBuff() { - uint32_t i = 0; - int bitLen = DemodBufferLen; - if (bitLen<16) { - PrintAndLog("no bits found in demod buffer"); - return; - } - if (bitLen>512) bitLen=512; //max output to 512 bits if we have more - should be plenty - for (i = 0; i <= (bitLen-16); i+=16) { - PrintAndLog("%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i", - DemodBuffer[i], - DemodBuffer[i+1], - DemodBuffer[i+2], - DemodBuffer[i+3], - DemodBuffer[i+4], - DemodBuffer[i+5], - DemodBuffer[i+6], - DemodBuffer[i+7], - DemodBuffer[i+8], - DemodBuffer[i+9], - DemodBuffer[i+10], - DemodBuffer[i+11], - DemodBuffer[i+12], - DemodBuffer[i+13], - DemodBuffer[i+14], - DemodBuffer[i+15]); - } - return; + uint32_t i = 0; + int bitLen = DemodBufferLen; + if (bitLen<16) { + PrintAndLog("no bits found in demod buffer"); + return; + } + if (bitLen>512) bitLen=512; //max output to 512 bits if we have more - should be plenty + for (i = 0; i <= (bitLen-16); i+=16) { + PrintAndLog("%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i", + DemodBuffer[i], + DemodBuffer[i+1], + DemodBuffer[i+2], + DemodBuffer[i+3], + DemodBuffer[i+4], + DemodBuffer[i+5], + DemodBuffer[i+6], + DemodBuffer[i+7], + DemodBuffer[i+8], + DemodBuffer[i+9], + DemodBuffer[i+10], + DemodBuffer[i+11], + DemodBuffer[i+12], + DemodBuffer[i+13], + DemodBuffer[i+14], + DemodBuffer[i+15]); + } + return; } int CmdAmp(const char *Cmd) { - int i, rising, falling; - int max = INT_MIN, min = INT_MAX; + int i, rising, falling; + int max = INT_MIN, min = INT_MAX; - for (i = 10; i < GraphTraceLen; ++i) { - if (GraphBuffer[i] > max) - max = GraphBuffer[i]; - if (GraphBuffer[i] < min) - min = GraphBuffer[i]; - } + for (i = 10; i < GraphTraceLen; ++i) { + if (GraphBuffer[i] > max) + max = GraphBuffer[i]; + if (GraphBuffer[i] < min) + min = GraphBuffer[i]; + } - if (max != min) { - rising = falling= 0; - for (i = 0; i < GraphTraceLen; ++i) { - if (GraphBuffer[i + 1] < GraphBuffer[i]) { - if (rising) { - GraphBuffer[i] = max; - rising = 0; - } - falling = 1; - } - if (GraphBuffer[i + 1] > GraphBuffer[i]) { - if (falling) { - GraphBuffer[i] = min; - falling = 0; - } - rising= 1; - } - } - } - RepaintGraphWindow(); - return 0; + if (max != min) { + rising = falling= 0; + for (i = 0; i < GraphTraceLen; ++i) { + if (GraphBuffer[i + 1] < GraphBuffer[i]) { + if (rising) { + GraphBuffer[i] = max; + rising = 0; + } + falling = 1; + } + if (GraphBuffer[i + 1] > GraphBuffer[i]) { + if (falling) { + GraphBuffer[i] = min; + falling = 0; + } + rising= 1; + } + } + } + RepaintGraphWindow(); + return 0; } /* @@ -119,171 +119,173 @@ int CmdAmp(const char *Cmd) //this method is dependant on all highs and lows to be the same(or clipped) this creates issues[marshmellow] it also ignores the clock int Cmdaskdemod(const char *Cmd) { - int i; - int c, high = 0, low = 0; + int i; + int c, high = 0, low = 0; - // TODO: complain if we do not give 2 arguments here ! - // (AL - this doesn't make sense! we're only using one argument!!!) - sscanf(Cmd, "%i", &c); + // TODO: complain if we do not give 2 arguments here ! + // (AL - this doesn't make sense! we're only using one argument!!!) + sscanf(Cmd, "%i", &c); - /* Detect high and lows and clock */ - // (AL - clock???) - for (i = 0; i < GraphTraceLen; ++i) - { - if (GraphBuffer[i] > high) - high = GraphBuffer[i]; - else if (GraphBuffer[i] < low) - low = GraphBuffer[i]; - } - high=abs(high*.75); - low=abs(low*.75); - if (c != 0 && c != 1) { - PrintAndLog("Invalid argument: %s", Cmd); - return 0; - } - //prime loop - if (GraphBuffer[0] > 0) { - GraphBuffer[0] = 1-c; - } else { - GraphBuffer[0] = c; - } - for (i = 1; i < GraphTraceLen; ++i) { - /* Transitions are detected at each peak - * Transitions are either: - * - we're low: transition if we hit a high - * - we're high: transition if we hit a low - * (we need to do it this way because some tags keep high or - * low for long periods, others just reach the peak and go - * down) - */ - //[marhsmellow] change == to >= for high and <= for low for fuzz - if ((GraphBuffer[i] == high) && (GraphBuffer[i - 1] == c)) { - GraphBuffer[i] = 1 - c; - } else if ((GraphBuffer[i] == low) && (GraphBuffer[i - 1] == (1 - c))){ - GraphBuffer[i] = c; - } else { - /* No transition */ - GraphBuffer[i] = GraphBuffer[i - 1]; - } - } - RepaintGraphWindow(); - return 0; + /* Detect high and lows and clock */ + // (AL - clock???) + for (i = 0; i < GraphTraceLen; ++i) + { + if (GraphBuffer[i] > high) + high = GraphBuffer[i]; + else if (GraphBuffer[i] < low) + low = GraphBuffer[i]; + } + high=abs(high*.75); + low=abs(low*.75); + if (c != 0 && c != 1) { + PrintAndLog("Invalid argument: %s", Cmd); + return 0; + } + //prime loop + if (GraphBuffer[0] > 0) { + GraphBuffer[0] = 1-c; + } else { + GraphBuffer[0] = c; + } + for (i = 1; i < GraphTraceLen; ++i) { + /* Transitions are detected at each peak + * Transitions are either: + * - we're low: transition if we hit a high + * - we're high: transition if we hit a low + * (we need to do it this way because some tags keep high or + * low for long periods, others just reach the peak and go + * down) + */ + //[marhsmellow] change == to >= for high and <= for low for fuzz + if ((GraphBuffer[i] == high) && (GraphBuffer[i - 1] == c)) { + GraphBuffer[i] = 1 - c; + } else if ((GraphBuffer[i] == low) && (GraphBuffer[i - 1] == (1 - c))){ + GraphBuffer[i] = c; + } else { + /* No transition */ + GraphBuffer[i] = GraphBuffer[i - 1]; + } + } + RepaintGraphWindow(); + return 0; } //by marshmellow void printBitStream(uint8_t BitStream[], uint32_t bitLen) { - uint32_t i = 0; - if (bitLen<16) { - PrintAndLog("Too few bits found: %d",bitLen); - return; - } - if (bitLen>512) bitLen=512; - for (i = 0; i <= (bitLen-16); i+=16) { - PrintAndLog("%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i", - BitStream[i], - BitStream[i+1], - BitStream[i+2], - BitStream[i+3], - BitStream[i+4], - BitStream[i+5], - BitStream[i+6], - BitStream[i+7], - BitStream[i+8], - BitStream[i+9], - BitStream[i+10], - BitStream[i+11], - BitStream[i+12], - BitStream[i+13], - BitStream[i+14], - BitStream[i+15]); - } - return; + uint32_t i = 0; + if (bitLen<16) { + PrintAndLog("Too few bits found: %d",bitLen); + return; + } + if (bitLen>512) bitLen=512; + for (i = 0; i <= (bitLen-16); i+=16) { + PrintAndLog("%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i", + BitStream[i], + BitStream[i+1], + BitStream[i+2], + BitStream[i+3], + BitStream[i+4], + BitStream[i+5], + BitStream[i+6], + BitStream[i+7], + BitStream[i+8], + BitStream[i+9], + BitStream[i+10], + BitStream[i+11], + BitStream[i+12], + BitStream[i+13], + BitStream[i+14], + BitStream[i+15]); + } + return; } //by marshmellow +//print EM410x ID in multiple formats void printEM410x(uint64_t id) { - if (id !=0){ - uint64_t iii=1; - uint64_t id2lo=0; //id2hi=0, - uint32_t ii=0; - uint32_t i=0; - for (ii=5; ii>0;ii--){ - for (i=0;i<8;i++){ - id2lo=(id2lo<<1LL)|((id & (iii<<(i+((ii-1)*8))))>>(i+((ii-1)*8))); - } - } - //output em id - PrintAndLog("EM TAG ID : %010llx", id); - PrintAndLog("Unique TAG ID: %010llx", id2lo); //id2hi, - PrintAndLog("DEZ 8 : %08lld",id & 0xFFFFFF); - PrintAndLog("DEZ 10 : %010lld",id & 0xFFFFFF); - PrintAndLog("DEZ 5.5 : %05lld.%05lld",(id>>16LL) & 0xFFFF,(id & 0xFFFF)); - 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)); - } - return; + if (id !=0){ + uint64_t iii=1; + uint64_t id2lo=0; //id2hi=0, + uint32_t ii=0; + uint32_t i=0; + for (ii=5; ii>0;ii--){ + for (i=0;i<8;i++){ + id2lo=(id2lo<<1LL) | ((id & (iii << (i+((ii-1)*8)))) >> (i+((ii-1)*8))); + } + } + //output em id + PrintAndLog("EM TAG ID : %010llx", id); + PrintAndLog("Unique TAG ID: %010llx", id2lo); //id2hi, + PrintAndLog("DEZ 8 : %08lld",id & 0xFFFFFF); + PrintAndLog("DEZ 10 : %010lld",id & 0xFFFFFF); + PrintAndLog("DEZ 5.5 : %05lld.%05lld",(id>>16LL) & 0xFFFF,(id & 0xFFFF)); + 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)); + } + return; } //by marshmellow +//take binary from demod buffer and see if we can find an EM410x ID int CmdEm410xDecode(const char *Cmd) { - uint64_t id=0; + uint64_t id=0; // uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; // uint32_t i=0; // i=getFromGraphBuf(BitStream); - id = Em410xDecode(DemodBuffer,DemodBufferLen); - printEM410x(id); - if (id>0) return 1; - return 0; + id = Em410xDecode(DemodBuffer,DemodBufferLen); + printEM410x(id); + if (id>0) return 1; + return 0; } //by marshmellow //takes 2 arguments - clock and invert both as integers -//attempts to demodulate ask while decoding manchester +//attempts to demodulate ask while decoding manchester //prints binary found and saves in graphbuffer for further commands int Cmdaskmandemod(const char *Cmd) { - int invert=0; - int clk=0; - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - sscanf(Cmd, "%i %i", &clk, &invert); - if (invert != 0 && invert != 1) { - PrintAndLog("Invalid argument: %s", Cmd); - return 0; - } + int invert=0; + int clk=0; + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + sscanf(Cmd, "%i %i", &clk, &invert); + if (invert != 0 && invert != 1) { + PrintAndLog("Invalid argument: %s", Cmd); + return 0; + } - int BitLen = getFromGraphBuf(BitStream); - // PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen); - int errCnt=0; - errCnt = askmandemod(BitStream, &BitLen,&clk,&invert); - if (errCnt<0||BitLen<16){ //if fatal error (or -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); - printDemodBuff(); - uint64_t lo =0; - lo = Em410xDecode(BitStream,BitLen); - if (lo>0){ - //set GraphBuffer for clone or sim command - PrintAndLog("EM410x pattern found: "); - printEM410x(lo); - return 1; - } - //if (BitLen>16) return 1; - return 0; + size_t BitLen = getFromGraphBuf(BitStream); + // PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen); + int errCnt=0; + errCnt = askmandemod(BitStream, &BitLen,&clk,&invert); + if (errCnt<0||BitLen<16){ //if fatal error (or -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); + printDemodBuff(); + uint64_t lo =0; + lo = Em410xDecode(BitStream,BitLen); + if (lo>0){ + //set GraphBuffer for clone or sim command + PrintAndLog("EM410x pattern found: "); + printEM410x(lo); + return 1; + } + //if (BitLen>16) return 1; + return 0; } //by marshmellow @@ -291,75 +293,75 @@ int Cmdaskmandemod(const char *Cmd) //stricktly take 10 and 01 and convert to 0 and 1 int Cmdmandecoderaw(const char *Cmd) { - int i =0; - int errCnt=0; - int bitnum=0; - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - int high=0,low=0; - for (;ihigh) high=DemodBuffer[i]; - else if(DemodBuffer[i]1 || low <0 ){ - PrintAndLog("Error: please raw demod the wave first then mancheseter raw decode"); - return 0; - } - bitnum=i; - errCnt=manrawdecode(BitStream,&bitnum); - if (errCnt>=20){ - PrintAndLog("Too many errors: %d",errCnt); - return 0; - } - PrintAndLog("Manchester Decoded - # errors:%d - data:",errCnt); - printBitStream(BitStream,bitnum); - if (errCnt==0){ - uint64_t id = 0; - id = Em410xDecode(BitStream,bitnum); - if (id>0) setDemodBuf(BitStream,bitnum); - printEM410x(id); - } - return 1; + int i =0; + int errCnt=0; + size_t size=0; + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + int high=0,low=0; + for (;ihigh) high=DemodBuffer[i]; + else if(DemodBuffer[i]1 || low <0 ){ + PrintAndLog("Error: please raw demod the wave first then mancheseter raw decode"); + return 0; + } + size=i; + errCnt=manrawdecode(BitStream, &size); + if (errCnt>=20){ + PrintAndLog("Too many errors: %d",errCnt); + return 0; + } + PrintAndLog("Manchester Decoded - # errors:%d - data:",errCnt); + printBitStream(BitStream, size); + if (errCnt==0){ + uint64_t id = 0; + id = Em410xDecode(BitStream, size); + if (id>0) setDemodBuf(BitStream, size); + printEM410x(id); + } + return 1; } //by marshmellow //biphase decode //take 01 or 10 = 0 and 11 or 00 = 1 //takes 1 argument "offset" default = 0 if 1 it will shift the decode by one bit -// since it is not like manchester and doesn't have an incorrect bit pattern we +// since it is not like manchester and doesn't have an incorrect bit pattern we // cannot determine if our decode is correct or if it should be shifted by one bit // the argument offset allows us to manually shift if the output is incorrect // (better would be to demod and decode at the same time so we can distinguish large // width waves vs small width waves to help the decode positioning) or askbiphdemod int CmdBiphaseDecodeRaw(const char *Cmd) { - int i = 0; - int errCnt=0; - int bitnum=0; - int offset=0; - int high=0, low=0; - sscanf(Cmd, "%i", &offset); - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - //get graphbuffer & high and low - for (;ihigh)high=DemodBuffer[i]; - else if(DemodBuffer[i]1 || low <0){ - PrintAndLog("Error: please raw demod the wave first then decode"); - return 0; - } - bitnum=i; - errCnt=BiphaseRawDecode(BitStream,&bitnum, offset); - if (errCnt>=20){ - PrintAndLog("Too many errors attempting to decode: %d",errCnt); - return 0; - } - PrintAndLog("Biphase Decoded using offset: %d - # errors:%d - data:",offset,errCnt); - printBitStream(BitStream,bitnum); - PrintAndLog("\nif bitstream does not look right try offset=1"); - return 1; + int i = 0; + int errCnt=0; + size_t size=0; + int offset=0; + int high=0, low=0; + sscanf(Cmd, "%i", &offset); + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + //get graphbuffer & high and low + for (;ihigh)high=DemodBuffer[i]; + else if(DemodBuffer[i]1 || low <0){ + PrintAndLog("Error: please raw demod the wave first then decode"); + return 0; + } + size=i; + errCnt=BiphaseRawDecode(BitStream, &size, offset); + if (errCnt>=20){ + PrintAndLog("Too many errors attempting to decode: %d",errCnt); + return 0; + } + PrintAndLog("Biphase Decoded using offset: %d - # errors:%d - data:",offset,errCnt); + printBitStream(BitStream, size); + PrintAndLog("\nif bitstream does not look right try offset=1"); + return 1; } @@ -369,89 +371,89 @@ int CmdBiphaseDecodeRaw(const char *Cmd) //prints binary found and saves in graphbuffer for further commands int Cmdaskrawdemod(const char *Cmd) { - int invert=0; - int clk=0; - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - sscanf(Cmd, "%i %i", &clk, &invert); - if (invert != 0 && invert != 1) { - PrintAndLog("Invalid argument: %s", Cmd); - return 0; - } - int BitLen = getFromGraphBuf(BitStream); - int errCnt=0; - errCnt = askrawdemod(BitStream, &BitLen,&clk,&invert); - if (errCnt==-1||BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first) - PrintAndLog("no data found"); - return 0; - } - PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen); - //PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum); - //move BitStream back to DemodBuffer - setDemodBuf(BitStream,BitLen); - - //output - if (errCnt>0){ - PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); - } - PrintAndLog("ASK demoded bitstream:"); - // Now output the bitstream to the scrollback by line of 16 bits - printBitStream(BitStream,BitLen); - - return 1; + int invert=0; + int clk=0; + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + sscanf(Cmd, "%i %i", &clk, &invert); + if (invert != 0 && invert != 1) { + PrintAndLog("Invalid argument: %s", Cmd); + return 0; + } + size_t BitLen = getFromGraphBuf(BitStream); + int errCnt=0; + errCnt = askrawdemod(BitStream, &BitLen,&clk,&invert); + if (errCnt==-1||BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first) + PrintAndLog("no data found"); + return 0; + } + PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen); + //PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum); + //move BitStream back to DemodBuffer + setDemodBuf(BitStream,BitLen); + + //output + if (errCnt>0){ + PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); + } + PrintAndLog("ASK demoded bitstream:"); + // Now output the bitstream to the scrollback by line of 16 bits + printBitStream(BitStream,BitLen); + + return 1; } int CmdAutoCorr(const char *Cmd) { - static int CorrelBuffer[MAX_GRAPH_TRACE_LEN]; + static int CorrelBuffer[MAX_GRAPH_TRACE_LEN]; - int window = atoi(Cmd); + 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; - } + 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); + 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; - } - GraphTraceLen = GraphTraceLen - window; - memcpy(GraphBuffer, CorrelBuffer, GraphTraceLen * sizeof (int)); + 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; + } + GraphTraceLen = GraphTraceLen - window; + memcpy(GraphBuffer, CorrelBuffer, GraphTraceLen * sizeof (int)); - RepaintGraphWindow(); - return 0; + RepaintGraphWindow(); + return 0; } int CmdBitsamples(const char *Cmd) { - int cnt = 0; - uint8_t got[12288]; - - GetFromBigBuf(got,sizeof(got),0); - WaitForResponse(CMD_ACK,NULL); + int cnt = 0; + uint8_t got[12288]; - for (int j = 0; j < sizeof(got); j++) { - for (int k = 0; k < 8; k++) { - if(got[j] & (1 << (7 - k))) { - GraphBuffer[cnt++] = 1; - } else { - GraphBuffer[cnt++] = 0; - } - } - } - GraphTraceLen = cnt; - RepaintGraphWindow(); - return 0; + GetFromBigBuf(got,sizeof(got),0); + WaitForResponse(CMD_ACK,NULL); + + for (int j = 0; j < sizeof(got); j++) { + for (int k = 0; k < 8; k++) { + if(got[j] & (1 << (7 - k))) { + GraphBuffer[cnt++] = 1; + } else { + GraphBuffer[cnt++] = 0; + } + } + } + GraphTraceLen = cnt; + RepaintGraphWindow(); + return 0; } /* @@ -459,92 +461,92 @@ int CmdBitsamples(const char *Cmd) */ int CmdBitstream(const char *Cmd) { - int i, j; - int bit; - int gtl; - int clock; - int low = 0; - int high = 0; - int hithigh, hitlow, first; + int i, j; + int bit; + int gtl; + int clock; + int low = 0; + int high = 0; + int hithigh, hitlow, first; - /* Detect high and lows and clock */ - for (i = 0; i < GraphTraceLen; ++i) - { - if (GraphBuffer[i] > high) - high = GraphBuffer[i]; - else if (GraphBuffer[i] < low) - low = GraphBuffer[i]; - } + /* Detect high and lows and clock */ + for (i = 0; i < GraphTraceLen; ++i) + { + if (GraphBuffer[i] > high) + high = GraphBuffer[i]; + else if (GraphBuffer[i] < low) + low = GraphBuffer[i]; + } - /* Get our clock */ - clock = GetClock(Cmd, high, 1); - gtl = ClearGraph(0); + /* Get our clock */ + clock = GetClock(Cmd, high, 1); + gtl = ClearGraph(0); - bit = 0; - for (i = 0; i < (int)(gtl / clock); ++i) - { - hithigh = 0; - hitlow = 0; - first = 1; - /* Find out if we hit both high and low peaks */ - for (j = 0; j < clock; ++j) - { - if (GraphBuffer[(i * clock) + j] == high) - hithigh = 1; - else if (GraphBuffer[(i * clock) + j] == low) - hitlow = 1; - /* it doesn't count if it's the first part of our read - because it's really just trailing from the last sequence */ - if (first && (hithigh || hitlow)) - hithigh = hitlow = 0; - else - first = 0; + bit = 0; + for (i = 0; i < (int)(gtl / clock); ++i) + { + hithigh = 0; + hitlow = 0; + first = 1; + /* Find out if we hit both high and low peaks */ + for (j = 0; j < clock; ++j) + { + if (GraphBuffer[(i * clock) + j] == high) + hithigh = 1; + else if (GraphBuffer[(i * clock) + j] == low) + hitlow = 1; + /* it doesn't count if it's the first part of our read + because it's really just trailing from the last sequence */ + if (first && (hithigh || hitlow)) + hithigh = hitlow = 0; + else + first = 0; - if (hithigh && hitlow) - break; - } + if (hithigh && hitlow) + break; + } - /* If we didn't hit both high and low peaks, we had a bit transition */ - if (!hithigh || !hitlow) - bit ^= 1; + /* If we didn't hit both high and low peaks, we had a bit transition */ + if (!hithigh || !hitlow) + bit ^= 1; - AppendGraph(0, clock, bit); - // for (j = 0; j < (int)(clock/2); j++) - // GraphBuffer[(i * clock) + j] = bit ^ 1; - // for (j = (int)(clock/2); j < clock; j++) - // GraphBuffer[(i * clock) + j] = bit; - } + AppendGraph(0, clock, bit); + // for (j = 0; j < (int)(clock/2); j++) + // GraphBuffer[(i * clock) + j] = bit ^ 1; + // for (j = (int)(clock/2); j < clock; j++) + // GraphBuffer[(i * clock) + j] = bit; + } - RepaintGraphWindow(); - return 0; + RepaintGraphWindow(); + return 0; } int CmdBuffClear(const char *Cmd) { - UsbCommand c = {CMD_BUFF_CLEAR}; - SendCommand(&c); - ClearGraph(true); - return 0; + UsbCommand c = {CMD_BUFF_CLEAR}; + SendCommand(&c); + ClearGraph(true); + return 0; } int CmdDec(const char *Cmd) { - for (int i = 0; i < (GraphTraceLen / 2); ++i) - GraphBuffer[i] = GraphBuffer[i * 2]; - GraphTraceLen /= 2; - PrintAndLog("decimated by 2"); - RepaintGraphWindow(); - return 0; + for (int i = 0; i < (GraphTraceLen / 2); ++i) + GraphBuffer[i] = GraphBuffer[i * 2]; + GraphTraceLen /= 2; + PrintAndLog("decimated by 2"); + RepaintGraphWindow(); + return 0; } /* Print our clock rate */ -// uses data from graphbuffer +// uses data from graphbuffer int CmdDetectClockRate(const char *Cmd) { - GetClock("",0,0); - //int clock = DetectASKClock(0); - //PrintAndLog("Auto-detected clock rate: %d", clock); - return 0; + GetClock("",0,0); + //int clock = DetectASKClock(0); + //PrintAndLog("Auto-detected clock rate: %d", clock); + return 0; } //by marshmellow @@ -553,37 +555,37 @@ int CmdDetectClockRate(const char *Cmd) //defaults: clock = 50, invert=0, rchigh=10, rclow=8 (RF/10 RF/8 (fsk2a)) int CmdFSKrawdemod(const char *Cmd) { - //raw fsk demod no manchester decoding no start bit finding just get binary from wave - //set defaults - int rfLen = 50; - int invert=0; - int fchigh=10; - int fclow=8; - //set options from parameters entered with the command - sscanf(Cmd, "%i %i %i %i", &rfLen, &invert, &fchigh, &fclow); - - if (strlen(Cmd)>0 && strlen(Cmd)<=2) { - //rfLen=param_get8(Cmd, 0); //if rfLen option only is used - if (rfLen==1){ - invert=1; //if invert option only is used - rfLen = 50; - } else if(rfLen==0) rfLen=50; - } - PrintAndLog("Args invert: %d - Clock:%d - fchigh:%d - fclow: %d",invert,rfLen,fchigh, fclow); - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - uint32_t BitLen = getFromGraphBuf(BitStream); - int size = fskdemod(BitStream,BitLen,(uint8_t)rfLen,(uint8_t)invert,(uint8_t)fchigh,(uint8_t)fclow); - if (size>0){ - PrintAndLog("FSK decoded bitstream:"); - setDemodBuf(BitStream,size); - - // Now output the bitstream to the scrollback by line of 16 bits - if(size > (8*32)+2) size = (8*32)+2; //only output a max of 8 blocks of 32 bits most tags will have full bit stream inside that sample size - printBitStream(BitStream,size); - } else{ - PrintAndLog("no FSK data found"); - } - return 0; + //raw fsk demod no manchester decoding no start bit finding just get binary from wave + //set defaults + int rfLen = 50; + int invert=0; + int fchigh=10; + int fclow=8; + //set options from parameters entered with the command + sscanf(Cmd, "%i %i %i %i", &rfLen, &invert, &fchigh, &fclow); + + if (strlen(Cmd)>0 && strlen(Cmd)<=2) { + //rfLen=param_get8(Cmd, 0); //if rfLen option only is used + if (rfLen==1){ + invert=1; //if invert option only is used + rfLen = 50; + } else if(rfLen==0) rfLen=50; + } + PrintAndLog("Args invert: %d - Clock:%d - fchigh:%d - fclow: %d",invert,rfLen,fchigh, fclow); + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + size_t BitLen = getFromGraphBuf(BitStream); + int size = fskdemod(BitStream,BitLen,(uint8_t)rfLen,(uint8_t)invert,(uint8_t)fchigh,(uint8_t)fclow); + if (size>0){ + PrintAndLog("FSK decoded bitstream:"); + setDemodBuf(BitStream,size); + + // Now output the bitstream to the scrollback by line of 16 bits + if(size > (8*32)+2) size = (8*32)+2; //only output a max of 8 blocks of 32 bits most tags will have full bit stream inside that sample size + printBitStream(BitStream,size); + } else{ + PrintAndLog("no FSK data found"); + } + return 0; } //by marshmellow (based on existing demod + holiman's refactor) @@ -591,73 +593,73 @@ int CmdFSKrawdemod(const char *Cmd) //print full HID Prox ID and some bit format details if found int CmdFSKdemodHID(const char *Cmd) { - //raw fsk demod no manchester decoding no start bit finding just get binary from wave - uint32_t hi2=0, hi=0, lo=0; + //raw fsk demod no manchester decoding no start bit finding just get binary from wave + uint32_t hi2=0, hi=0, lo=0; - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - uint32_t BitLen = getFromGraphBuf(BitStream); - //get binary from fsk wave - size_t size = HIDdemodFSK(BitStream,BitLen,&hi2,&hi,&lo); - if (size<0){ - PrintAndLog("Error demoding fsk"); - return 0; - } - if (hi2==0 && hi==0 && lo==0) return 0; - if (hi2 != 0){ //extra large HID tags - PrintAndLog("HID Prox TAG ID: %x%08x%08x (%d)", - (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); - setDemodBuf(BitStream,BitLen); - return 1; - } - else { //standard HID tags <38 bits - //Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd - uint8_t fmtLen = 0; - uint32_t fc = 0; - uint32_t cardnum = 0; - if (((hi>>5)&1)==1){//if bit 38 is set then < 37 bit format is used - uint32_t lo2=0; - lo2=(((hi & 15) << 12) | (lo>>20)); //get bits 21-37 to check for format len bit - uint8_t idx3 = 1; - while(lo2>1){ //find last bit set to 1 (format len bit) - lo2=lo2>>1; - idx3++; - } - fmtLen =idx3+19; - fc =0; - cardnum=0; - if(fmtLen==26){ - cardnum = (lo>>1)&0xFFFF; - fc = (lo>>17)&0xFF; - } - if(fmtLen==37){ - cardnum = (lo>>1)&0x7FFFF; - fc = ((hi&0xF)<<12)|(lo>>20); - } - if(fmtLen==34){ - cardnum = (lo>>1)&0xFFFF; - fc= ((hi&1)<<15)|(lo>>17); - } - if(fmtLen==35){ - cardnum = (lo>>1)&0xFFFFF; - fc = ((hi&1)<<11)|(lo>>21); - } - } - else { //if bit 38 is not set then 37 bit format is used - fmtLen= 37; - fc =0; - cardnum=0; - if(fmtLen==37){ - cardnum = (lo>>1)&0x7FFFF; - fc = ((hi&0xF)<<12)|(lo>>20); - } - } - PrintAndLog("HID Prox TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d", - (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF, - (unsigned int) fmtLen, (unsigned int) fc, (unsigned int) cardnum); - setDemodBuf(BitStream,BitLen); - return 1; - } - return 0; + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + size_t BitLen = getFromGraphBuf(BitStream); + //get binary from fsk wave + size_t size = HIDdemodFSK(BitStream,BitLen,&hi2,&hi,&lo); + if (size<0){ + PrintAndLog("Error demoding fsk"); + return 0; + } + if (hi2==0 && hi==0 && lo==0) return 0; + if (hi2 != 0){ //extra large HID tags + PrintAndLog("HID Prox TAG ID: %x%08x%08x (%d)", + (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); + setDemodBuf(BitStream,BitLen); + return 1; + } + else { //standard HID tags <38 bits + //Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd + uint8_t fmtLen = 0; + uint32_t fc = 0; + uint32_t cardnum = 0; + if (((hi>>5)&1)==1){//if bit 38 is set then < 37 bit format is used + uint32_t lo2=0; + lo2=(((hi & 15) << 12) | (lo>>20)); //get bits 21-37 to check for format len bit + uint8_t idx3 = 1; + while(lo2>1){ //find last bit set to 1 (format len bit) + lo2=lo2>>1; + idx3++; + } + fmtLen =idx3+19; + fc =0; + cardnum=0; + if(fmtLen==26){ + cardnum = (lo>>1)&0xFFFF; + fc = (lo>>17)&0xFF; + } + if(fmtLen==37){ + cardnum = (lo>>1)&0x7FFFF; + fc = ((hi&0xF)<<12)|(lo>>20); + } + if(fmtLen==34){ + cardnum = (lo>>1)&0xFFFF; + fc= ((hi&1)<<15)|(lo>>17); + } + if(fmtLen==35){ + cardnum = (lo>>1)&0xFFFFF; + fc = ((hi&1)<<11)|(lo>>21); + } + } + else { //if bit 38 is not set then 37 bit format is used + fmtLen= 37; + fc =0; + cardnum=0; + if(fmtLen==37){ + cardnum = (lo>>1)&0x7FFFF; + fc = ((hi&0xF)<<12)|(lo>>20); + } + } + PrintAndLog("HID Prox TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d", + (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF, + (unsigned int) fmtLen, (unsigned int) fc, (unsigned int) cardnum); + setDemodBuf(BitStream,BitLen); + return 1; + } + return 0; } //by marshmellow @@ -665,203 +667,203 @@ int CmdFSKdemodHID(const char *Cmd) //print ioprox ID and some format details int CmdFSKdemodIO(const char *Cmd) { - //raw fsk demod no manchester decoding no start bit finding just get binary from wave - //set defaults - int idx=0; - //something in graphbuffer - if (GraphTraceLen < 65) return 0; - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - uint32_t BitLen = getFromGraphBuf(BitStream); - //get binary from fsk wave - // PrintAndLog("DEBUG: got buff"); - idx = IOdemodFSK(BitStream,BitLen); - if (idx<0){ - //PrintAndLog("Error demoding fsk"); - return 0; - } - // PrintAndLog("DEBUG: Got IOdemodFSK"); - if (idx==0){ - //PrintAndLog("IO Prox Data not found - FSK Data:"); - //if (BitLen > 92) printBitStream(BitStream,92); - return 0; - } - //Index map - //0 10 20 30 40 50 60 - //| | | | | | | - //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23 - //----------------------------------------------------------------------------- - //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11 - // - //XSF(version)facility:codeone+codetwo (raw) - //Handle the data - if (idx+64>BitLen) return 0; - PrintAndLog("%d%d%d%d%d%d%d%d %d",BitStream[idx], BitStream[idx+1], BitStream[idx+2], BitStream[idx+3], BitStream[idx+4], BitStream[idx+5], BitStream[idx+6], BitStream[idx+7], BitStream[idx+8]); - PrintAndLog("%d%d%d%d%d%d%d%d %d",BitStream[idx+9], BitStream[idx+10], BitStream[idx+11],BitStream[idx+12],BitStream[idx+13],BitStream[idx+14],BitStream[idx+15],BitStream[idx+16],BitStream[idx+17]); - PrintAndLog("%d%d%d%d%d%d%d%d %d facility",BitStream[idx+18], BitStream[idx+19], BitStream[idx+20],BitStream[idx+21],BitStream[idx+22],BitStream[idx+23],BitStream[idx+24],BitStream[idx+25],BitStream[idx+26]); - PrintAndLog("%d%d%d%d%d%d%d%d %d version",BitStream[idx+27], BitStream[idx+28], BitStream[idx+29],BitStream[idx+30],BitStream[idx+31],BitStream[idx+32],BitStream[idx+33],BitStream[idx+34],BitStream[idx+35]); - PrintAndLog("%d%d%d%d%d%d%d%d %d code1",BitStream[idx+36], BitStream[idx+37], BitStream[idx+38],BitStream[idx+39],BitStream[idx+40],BitStream[idx+41],BitStream[idx+42],BitStream[idx+43],BitStream[idx+44]); - PrintAndLog("%d%d%d%d%d%d%d%d %d code2",BitStream[idx+45], BitStream[idx+46], BitStream[idx+47],BitStream[idx+48],BitStream[idx+49],BitStream[idx+50],BitStream[idx+51],BitStream[idx+52],BitStream[idx+53]); - PrintAndLog("%d%d%d%d%d%d%d%d %d%d checksum",BitStream[idx+54],BitStream[idx+55],BitStream[idx+56],BitStream[idx+57],BitStream[idx+58],BitStream[idx+59],BitStream[idx+60],BitStream[idx+61],BitStream[idx+62],BitStream[idx+63]); + //raw fsk demod no manchester decoding no start bit finding just get binary from wave + //set defaults + int idx=0; + //something in graphbuffer + if (GraphTraceLen < 65) return 0; + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + size_t BitLen = getFromGraphBuf(BitStream); + //get binary from fsk wave + // PrintAndLog("DEBUG: got buff"); + idx = IOdemodFSK(BitStream,BitLen); + if (idx<0){ + //PrintAndLog("Error demoding fsk"); + return 0; + } + // PrintAndLog("DEBUG: Got IOdemodFSK"); + if (idx==0){ + //PrintAndLog("IO Prox Data not found - FSK Data:"); + //if (BitLen > 92) printBitStream(BitStream,92); + return 0; + } + //Index map + //0 10 20 30 40 50 60 + //| | | | | | | + //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23 + //----------------------------------------------------------------------------- + //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11 + // + //XSF(version)facility:codeone+codetwo (raw) + //Handle the data + if (idx+64>BitLen) return 0; + PrintAndLog("%d%d%d%d%d%d%d%d %d",BitStream[idx], BitStream[idx+1], BitStream[idx+2], BitStream[idx+3], BitStream[idx+4], BitStream[idx+5], BitStream[idx+6], BitStream[idx+7], BitStream[idx+8]); + PrintAndLog("%d%d%d%d%d%d%d%d %d",BitStream[idx+9], BitStream[idx+10], BitStream[idx+11],BitStream[idx+12],BitStream[idx+13],BitStream[idx+14],BitStream[idx+15],BitStream[idx+16],BitStream[idx+17]); + PrintAndLog("%d%d%d%d%d%d%d%d %d facility",BitStream[idx+18], BitStream[idx+19], BitStream[idx+20],BitStream[idx+21],BitStream[idx+22],BitStream[idx+23],BitStream[idx+24],BitStream[idx+25],BitStream[idx+26]); + PrintAndLog("%d%d%d%d%d%d%d%d %d version",BitStream[idx+27], BitStream[idx+28], BitStream[idx+29],BitStream[idx+30],BitStream[idx+31],BitStream[idx+32],BitStream[idx+33],BitStream[idx+34],BitStream[idx+35]); + PrintAndLog("%d%d%d%d%d%d%d%d %d code1",BitStream[idx+36], BitStream[idx+37], BitStream[idx+38],BitStream[idx+39],BitStream[idx+40],BitStream[idx+41],BitStream[idx+42],BitStream[idx+43],BitStream[idx+44]); + PrintAndLog("%d%d%d%d%d%d%d%d %d code2",BitStream[idx+45], BitStream[idx+46], BitStream[idx+47],BitStream[idx+48],BitStream[idx+49],BitStream[idx+50],BitStream[idx+51],BitStream[idx+52],BitStream[idx+53]); + PrintAndLog("%d%d%d%d%d%d%d%d %d%d checksum",BitStream[idx+54],BitStream[idx+55],BitStream[idx+56],BitStream[idx+57],BitStream[idx+58],BitStream[idx+59],BitStream[idx+60],BitStream[idx+61],BitStream[idx+62],BitStream[idx+63]); - uint32_t code = bytebits_to_byte(BitStream+idx,32); - uint32_t code2 = bytebits_to_byte(BitStream+idx+32,32); - uint8_t version = bytebits_to_byte(BitStream+idx+27,8); //14,4 - uint8_t facilitycode = bytebits_to_byte(BitStream+idx+18,8) ; - uint16_t number = (bytebits_to_byte(BitStream+idx+36,8)<<8)|(bytebits_to_byte(BitStream+idx+45,8)); //36,9 - PrintAndLog("IO Prox XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2); - int i; - for (i=0;i<64;++i) - DemodBuffer[i]=BitStream[idx++]; + uint32_t code = bytebits_to_byte(BitStream+idx,32); + uint32_t code2 = bytebits_to_byte(BitStream+idx+32,32); + uint8_t version = bytebits_to_byte(BitStream+idx+27,8); //14,4 + uint8_t facilitycode = bytebits_to_byte(BitStream+idx+18,8) ; + uint16_t number = (bytebits_to_byte(BitStream+idx+36,8)<<8)|(bytebits_to_byte(BitStream+idx+45,8)); //36,9 + PrintAndLog("IO Prox XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2); + int i; + for (i=0;i<64;++i) + DemodBuffer[i]=BitStream[idx++]; - DemodBufferLen=64; - return 1; + DemodBufferLen=64; + return 1; } int CmdFSKdemod(const char *Cmd) //old CmdFSKdemod needs updating { - static const int LowTone[] = { - 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, -1, -1, -1, -1, -1 - }; - static const int HighTone[] = { - 1, 1, 1, 1, 1, -1, -1, -1, -1, - 1, 1, 1, 1, -1, -1, -1, -1, - 1, 1, 1, 1, -1, -1, -1, -1, - 1, 1, 1, 1, -1, -1, -1, -1, - 1, 1, 1, 1, -1, -1, -1, -1, - 1, 1, 1, 1, -1, -1, -1, -1, -1, - }; + static const int LowTone[] = { + 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, -1, -1, -1, -1, -1 + }; + static const int HighTone[] = { + 1, 1, 1, 1, 1, -1, -1, -1, -1, + 1, 1, 1, 1, -1, -1, -1, -1, + 1, 1, 1, 1, -1, -1, -1, -1, + 1, 1, 1, 1, -1, -1, -1, -1, + 1, 1, 1, 1, -1, -1, -1, -1, + 1, 1, 1, 1, -1, -1, -1, -1, -1, + }; - int lowLen = sizeof (LowTone) / sizeof (int); - int highLen = sizeof (HighTone) / sizeof (int); - int convLen = (highLen > lowLen) ? highLen : lowLen; //if highlen > lowLen then highlen else lowlen - uint32_t hi = 0, lo = 0; + int lowLen = sizeof (LowTone) / sizeof (int); + int highLen = sizeof (HighTone) / sizeof (int); + int convLen = (highLen > lowLen) ? highLen : lowLen; //if highlen > lowLen then highlen else lowlen + uint32_t hi = 0, lo = 0; - int i, j; - int minMark = 0, maxMark = 0; - - for (i = 0; i < GraphTraceLen - convLen; ++i) { - int lowSum = 0, highSum = 0; + int i, j; + int minMark = 0, maxMark = 0; - for (j = 0; j < lowLen; ++j) { - lowSum += LowTone[j]*GraphBuffer[i+j]; - } - for (j = 0; j < highLen; ++j) { - highSum += HighTone[j] * GraphBuffer[i + j]; - } - lowSum = abs(100 * lowSum / lowLen); - highSum = abs(100 * highSum / highLen); - GraphBuffer[i] = (highSum << 16) | lowSum; - } + for (i = 0; i < GraphTraceLen - convLen; ++i) { + int lowSum = 0, highSum = 0; - for(i = 0; i < GraphTraceLen - convLen - 16; ++i) { - int lowTot = 0, highTot = 0; - // 10 and 8 are f_s divided by f_l and f_h, rounded - for (j = 0; j < 10; ++j) { - lowTot += (GraphBuffer[i+j] & 0xffff); - } - for (j = 0; j < 8; j++) { - highTot += (GraphBuffer[i + j] >> 16); - } - GraphBuffer[i] = lowTot - highTot; - if (GraphBuffer[i] > maxMark) maxMark = GraphBuffer[i]; - if (GraphBuffer[i] < minMark) minMark = GraphBuffer[i]; - } + for (j = 0; j < lowLen; ++j) { + lowSum += LowTone[j]*GraphBuffer[i+j]; + } + for (j = 0; j < highLen; ++j) { + highSum += HighTone[j] * GraphBuffer[i + j]; + } + lowSum = abs(100 * lowSum / lowLen); + highSum = abs(100 * highSum / highLen); + GraphBuffer[i] = (highSum << 16) | lowSum; + } - GraphTraceLen -= (convLen + 16); - RepaintGraphWindow(); + for(i = 0; i < GraphTraceLen - convLen - 16; ++i) { + int lowTot = 0, highTot = 0; + // 10 and 8 are f_s divided by f_l and f_h, rounded + for (j = 0; j < 10; ++j) { + lowTot += (GraphBuffer[i+j] & 0xffff); + } + for (j = 0; j < 8; j++) { + highTot += (GraphBuffer[i + j] >> 16); + } + GraphBuffer[i] = lowTot - highTot; + if (GraphBuffer[i] > maxMark) maxMark = GraphBuffer[i]; + if (GraphBuffer[i] < minMark) minMark = GraphBuffer[i]; + } - // Find bit-sync (3 lo followed by 3 high) (HID ONLY) - int max = 0, maxPos = 0; - for (i = 0; i < 6000; ++i) { - int dec = 0; - for (j = 0; j < 3 * lowLen; ++j) { - dec -= GraphBuffer[i + j]; - } - for (; j < 3 * (lowLen + highLen ); ++j) { - dec += GraphBuffer[i + j]; - } - if (dec > max) { - max = dec; - maxPos = i; - } - } + GraphTraceLen -= (convLen + 16); + RepaintGraphWindow(); - // place start of bit sync marker in graph - GraphBuffer[maxPos] = maxMark; - GraphBuffer[maxPos + 1] = minMark; + // Find bit-sync (3 lo followed by 3 high) (HID ONLY) + int max = 0, maxPos = 0; + for (i = 0; i < 6000; ++i) { + int dec = 0; + for (j = 0; j < 3 * lowLen; ++j) { + dec -= GraphBuffer[i + j]; + } + for (; j < 3 * (lowLen + highLen ); ++j) { + dec += GraphBuffer[i + j]; + } + if (dec > max) { + max = dec; + maxPos = i; + } + } - maxPos += j; + // place start of bit sync marker in graph + GraphBuffer[maxPos] = maxMark; + GraphBuffer[maxPos + 1] = minMark; - // place end of bit sync marker in graph - GraphBuffer[maxPos] = maxMark; - GraphBuffer[maxPos+1] = minMark; + maxPos += j; - PrintAndLog("actual data bits start at sample %d", maxPos); - PrintAndLog("length %d/%d", highLen, lowLen); + // place end of bit sync marker in graph + GraphBuffer[maxPos] = maxMark; + GraphBuffer[maxPos+1] = minMark; - uint8_t bits[46]; - bits[sizeof(bits)-1] = '\0'; + PrintAndLog("actual data bits start at sample %d", maxPos); + PrintAndLog("length %d/%d", highLen, lowLen); - // find bit pairs and manchester decode them - for (i = 0; i < arraylen(bits) - 1; ++i) { - int dec = 0; - for (j = 0; j < lowLen; ++j) { - dec -= GraphBuffer[maxPos + j]; - } - for (; j < lowLen + highLen; ++j) { - dec += GraphBuffer[maxPos + j]; - } - maxPos += j; - // place inter bit marker in graph - GraphBuffer[maxPos] = maxMark; - GraphBuffer[maxPos + 1] = minMark; + uint8_t bits[46]; + bits[sizeof(bits)-1] = '\0'; - // hi and lo form a 64 bit pair - hi = (hi << 1) | (lo >> 31); - lo = (lo << 1); - // store decoded bit as binary (in hi/lo) and text (in bits[]) - if(dec < 0) { - bits[i] = '1'; - lo |= 1; - } else { - bits[i] = '0'; - } - } - PrintAndLog("bits: '%s'", bits); - PrintAndLog("hex: %08x %08x", hi, lo); - return 0; + // find bit pairs and manchester decode them + for (i = 0; i < arraylen(bits) - 1; ++i) { + int dec = 0; + for (j = 0; j < lowLen; ++j) { + dec -= GraphBuffer[maxPos + j]; + } + for (; j < lowLen + highLen; ++j) { + dec += GraphBuffer[maxPos + j]; + } + maxPos += j; + // place inter bit marker in graph + GraphBuffer[maxPos] = maxMark; + GraphBuffer[maxPos + 1] = minMark; + + // hi and lo form a 64 bit pair + hi = (hi << 1) | (lo >> 31); + lo = (lo << 1); + // store decoded bit as binary (in hi/lo) and text (in bits[]) + if(dec < 0) { + bits[i] = '1'; + lo |= 1; + } else { + bits[i] = '0'; + } + } + PrintAndLog("bits: '%s'", bits); + PrintAndLog("hex: %08x %08x", hi, lo); + return 0; } int CmdDetectNRZpskClockRate(const char *Cmd) { - GetNRZpskClock("",0,0); - return 0; + GetNRZpskClock("",0,0); + return 0; } int PSKnrzDemod(const char *Cmd){ - int invert=0; - int clk=0; - sscanf(Cmd, "%i %i", &clk, &invert); - if (invert != 0 && invert != 1) { - PrintAndLog("Invalid argument: %s", Cmd); - return -1; - } - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - int BitLen = getFromGraphBuf(BitStream); - int errCnt=0; - errCnt = pskNRZrawDemod(BitStream, &BitLen,&clk,&invert); - if (errCnt<0|| BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first) - //PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); - return -1; - } - PrintAndLog("Tried PSK/NRZ Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen); - - //prime demod buffer for output - setDemodBuf(BitStream,BitLen); - return errCnt; + int invert=0; + int clk=0; + sscanf(Cmd, "%i %i", &clk, &invert); + if (invert != 0 && invert != 1) { + PrintAndLog("Invalid argument: %s", Cmd); + return -1; + } + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + size_t BitLen = getFromGraphBuf(BitStream); + int errCnt=0; + errCnt = pskNRZrawDemod(BitStream, &BitLen,&clk,&invert); + if (errCnt<0|| BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first) + //PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); + return -1; + } + PrintAndLog("Tried PSK/NRZ Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen); + + //prime demod buffer for output + setDemodBuf(BitStream,BitLen); + return errCnt; } // Indala 26 bit decode // by marshmellow @@ -869,103 +871,103 @@ int PSKnrzDemod(const char *Cmd){ int CmdIndalaDecode(const char *Cmd) { - int ans=PSKnrzDemod(Cmd); - if (ans < 0){ - PrintAndLog("Error1: %d",ans); - return 0; - } - uint8_t invert=0; - ans = indala26decode(DemodBuffer, &DemodBufferLen, &invert); - if (ans < 1) { - PrintAndLog("Error2: %d",ans); - return -1; - } - char showbits[251]; - if(invert==1) PrintAndLog("Had to invert bits"); - //convert UID to HEX - uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7; - int idx; - uid1=0; - uid2=0; - PrintAndLog("BitLen: %d",DemodBufferLen); - if (DemodBufferLen==64){ - for( idx=0; idx<64; idx++) { - uid1=(uid1<<1)|(uid2>>31); - if (DemodBuffer[idx] == 0) { - uid2=(uid2<<1)|0; - showbits[idx]='0'; - } else { - uid2=(uid2<<1)|1; - showbits[idx]='1'; - } - } - showbits[idx]='\0'; - PrintAndLog("Indala UID=%s (%x%08x)", showbits, uid1, uid2); - } - else { - uid3=0; - uid4=0; - uid5=0; - uid6=0; - uid7=0; - for( idx=0; idx>31); - uid2=(uid2<<1)|(uid3>>31); - uid3=(uid3<<1)|(uid4>>31); - uid4=(uid4<<1)|(uid5>>31); - uid5=(uid5<<1)|(uid6>>31); - uid6=(uid6<<1)|(uid7>>31); - if (DemodBuffer[idx] == 0) { - uid7=(uid7<<1)|0; - showbits[idx]='0'; - } - else { - uid7=(uid7<<1)|1; - showbits[idx]='1'; - } - } - showbits[idx]='\0'; - PrintAndLog("Indala UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7); - } - return 1; + int ans=PSKnrzDemod(Cmd); + if (ans < 0){ + PrintAndLog("Error1: %d",ans); + return 0; + } + uint8_t invert=0; + ans = indala26decode(DemodBuffer,(size_t *) &DemodBufferLen, &invert); + if (ans < 1) { + PrintAndLog("Error2: %d",ans); + return -1; + } + char showbits[251]; + if(invert==1) PrintAndLog("Had to invert bits"); + //convert UID to HEX + uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7; + int idx; + uid1=0; + uid2=0; + PrintAndLog("BitLen: %d",DemodBufferLen); + if (DemodBufferLen==64){ + for( idx=0; idx<64; idx++) { + uid1=(uid1<<1)|(uid2>>31); + if (DemodBuffer[idx] == 0) { + uid2=(uid2<<1)|0; + showbits[idx]='0'; + } else { + uid2=(uid2<<1)|1; + showbits[idx]='1'; + } + } + showbits[idx]='\0'; + PrintAndLog("Indala UID=%s (%x%08x)", showbits, uid1, uid2); + } + else { + uid3=0; + uid4=0; + uid5=0; + uid6=0; + uid7=0; + for( idx=0; idx>31); + uid2=(uid2<<1)|(uid3>>31); + uid3=(uid3<<1)|(uid4>>31); + uid4=(uid4<<1)|(uid5>>31); + uid5=(uid5<<1)|(uid6>>31); + uid6=(uid6<<1)|(uid7>>31); + if (DemodBuffer[idx] == 0) { + uid7=(uid7<<1)|0; + showbits[idx]='0'; + } + else { + uid7=(uid7<<1)|1; + showbits[idx]='1'; + } + } + showbits[idx]='\0'; + PrintAndLog("Indala UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7); + } + return 1; } /* //by marshmellow (attempt to get rid of high immediately after a low) void pskCleanWave2(uint8_t *bitStream, int bitLen) { - int i; - int low=128; - int gap = 4; + int i; + int low=128; + int gap = 4; // int loopMax = 2048; - int newLow=0; + int newLow=0; - for (i=0; i0){ - PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); - } - PrintAndLog("PSK or NRZ demoded bitstream:"); - // Now output the bitstream to the scrollback by line of 16 bits - printDemodBuff(); - - return 1; + int errCnt= PSKnrzDemod(Cmd); + //output + if (errCnt<0) return 0; + if (errCnt>0){ + PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); + } + PrintAndLog("PSK or NRZ demoded bitstream:"); + // Now output the bitstream to the scrollback by line of 16 bits + printDemodBuff(); + + return 1; } int CmdGrid(const char *Cmd) { - sscanf(Cmd, "%i %i", &PlotGridX, &PlotGridY); - PlotGridXdefault= PlotGridX; - PlotGridYdefault= PlotGridY; - RepaintGraphWindow(); - return 0; + sscanf(Cmd, "%i %i", &PlotGridX, &PlotGridY); + PlotGridXdefault= PlotGridX; + PlotGridYdefault= PlotGridY; + RepaintGraphWindow(); + return 0; } int CmdHexsamples(const char *Cmd) { - int i, j; - int requested = 0; - int offset = 0; - char string_buf[25]; - char* string_ptr = string_buf; - uint8_t got[40000]; - - sscanf(Cmd, "%i %i", &requested, &offset); + int i, j; + int requested = 0; + int offset = 0; + char string_buf[25]; + char* string_ptr = string_buf; + uint8_t got[40000]; - /* if no args send something */ - if (requested == 0) { - requested = 8; - } - if (offset + requested > sizeof(got)) { - PrintAndLog("Tried to read past end of buffer, + > 40000"); - return 0; - } + sscanf(Cmd, "%i %i", &requested, &offset); - GetFromBigBuf(got,requested,offset); - WaitForResponse(CMD_ACK,NULL); + /* if no args send something */ + if (requested == 0) { + requested = 8; + } + if (offset + requested > sizeof(got)) { + PrintAndLog("Tried to read past end of buffer, + > 40000"); + return 0; + } - i = 0; - for (j = 0; j < requested; j++) { - i++; - string_ptr += sprintf(string_ptr, "%02x ", got[j]); - if (i == 8) { - *(string_ptr - 1) = '\0'; // remove the trailing space - PrintAndLog("%s", string_buf); - string_buf[0] = '\0'; - string_ptr = string_buf; - i = 0; - } - if (j == requested - 1 && string_buf[0] != '\0') { // print any remaining bytes - *(string_ptr - 1) = '\0'; - PrintAndLog("%s", string_buf); - string_buf[0] = '\0'; - } - } - return 0; + GetFromBigBuf(got,requested,offset); + WaitForResponse(CMD_ACK,NULL); + + i = 0; + for (j = 0; j < requested; j++) { + i++; + string_ptr += sprintf(string_ptr, "%02x ", got[j]); + if (i == 8) { + *(string_ptr - 1) = '\0'; // remove the trailing space + PrintAndLog("%s", string_buf); + string_buf[0] = '\0'; + string_ptr = string_buf; + i = 0; + } + if (j == requested - 1 && string_buf[0] != '\0') { // print any remaining bytes + *(string_ptr - 1) = '\0'; + PrintAndLog("%s", string_buf); + string_buf[0] = '\0'; + } + } + return 0; } int CmdHide(const char *Cmd) { - HideGraphWindow(); - return 0; + HideGraphWindow(); + return 0; } int CmdHpf(const char *Cmd) { - int i; - int accum = 0; + int i; + int accum = 0; - for (i = 10; i < GraphTraceLen; ++i) - accum += GraphBuffer[i]; - accum /= (GraphTraceLen - 10); - for (i = 0; i < GraphTraceLen; ++i) - GraphBuffer[i] -= accum; + for (i = 10; i < GraphTraceLen; ++i) + accum += GraphBuffer[i]; + accum /= (GraphTraceLen - 10); + for (i = 0; i < GraphTraceLen; ++i) + GraphBuffer[i] -= accum; - RepaintGraphWindow(); - return 0; + RepaintGraphWindow(); + return 0; } int CmdSamples(const char *Cmd) { - int cnt = 0; - int n; - uint8_t got[40000]; + int cnt = 0; + int n; + uint8_t got[40000]; - n = strtol(Cmd, NULL, 0); - if (n == 0) n = 6000; - if (n > sizeof(got)) n = sizeof(got); - - PrintAndLog("Reading %d samples\n", n); - GetFromBigBuf(got,n,0); - WaitForResponse(CMD_ACK,NULL); - for (int j = 0; j < n; j++) { - GraphBuffer[cnt++] = ((int)got[j]) - 128; - } - - PrintAndLog("Done!\n"); - GraphTraceLen = n; - RepaintGraphWindow(); - return 0; + n = strtol(Cmd, NULL, 0); + if (n == 0) n = 6000; + if (n > sizeof(got)) n = sizeof(got); + + PrintAndLog("Reading %d samples\n", n); + GetFromBigBuf(got,n,0); + WaitForResponse(CMD_ACK,NULL); + for (int j = 0; j < n; j++) { + GraphBuffer[cnt++] = ((int)got[j]) - 128; + } + + PrintAndLog("Done!\n"); + GraphTraceLen = n; + RepaintGraphWindow(); + return 0; } int CmdTuneSamples(const char *Cmd) { - int cnt = 0; - int n = 255; - uint8_t got[255]; + int cnt = 0; + int n = 255; + uint8_t got[255]; - PrintAndLog("Reading %d samples\n", n); - GetFromBigBuf(got,n,7256); // armsrc/apps.h: #define FREE_BUFFER_OFFSET 7256 - WaitForResponse(CMD_ACK,NULL); - for (int j = 0; j < n; j++) { - GraphBuffer[cnt++] = ((int)got[j]) - 128; - } - - PrintAndLog("Done! Divisor 89 is 134khz, 95 is 125khz.\n"); - PrintAndLog("\n"); - GraphTraceLen = n; - RepaintGraphWindow(); - return 0; + PrintAndLog("Reading %d samples\n", n); + GetFromBigBuf(got,n,7256); // armsrc/apps.h: #define FREE_BUFFER_OFFSET 7256 + WaitForResponse(CMD_ACK,NULL); + for (int j = 0; j < n; j++) { + GraphBuffer[cnt++] = ((int)got[j]) - 128; + } + + PrintAndLog("Done! Divisor 89 is 134khz, 95 is 125khz.\n"); + PrintAndLog("\n"); + GraphTraceLen = n; + RepaintGraphWindow(); + return 0; } int CmdLoad(const char *Cmd) { - FILE *f = fopen(Cmd, "r"); - if (!f) { - PrintAndLog("couldn't open '%s'", Cmd); - return 0; - } + FILE *f = fopen(Cmd, "r"); + if (!f) { + PrintAndLog("couldn't open '%s'", Cmd); + return 0; + } - GraphTraceLen = 0; - char line[80]; - while (fgets(line, sizeof (line), f)) { - GraphBuffer[GraphTraceLen] = atoi(line); - GraphTraceLen++; - } - fclose(f); - PrintAndLog("loaded %d samples", GraphTraceLen); - RepaintGraphWindow(); - return 0; + GraphTraceLen = 0; + char line[80]; + while (fgets(line, sizeof (line), f)) { + GraphBuffer[GraphTraceLen] = atoi(line); + GraphTraceLen++; + } + fclose(f); + PrintAndLog("loaded %d samples", GraphTraceLen); + RepaintGraphWindow(); + return 0; } int CmdLtrim(const char *Cmd) { - int ds = atoi(Cmd); + int ds = atoi(Cmd); - for (int i = ds; i < GraphTraceLen; ++i) - GraphBuffer[i-ds] = GraphBuffer[i]; - GraphTraceLen -= ds; + for (int i = ds; i < GraphTraceLen; ++i) + GraphBuffer[i-ds] = GraphBuffer[i]; + GraphTraceLen -= ds; - RepaintGraphWindow(); - return 0; + RepaintGraphWindow(); + return 0; } int CmdRtrim(const char *Cmd) { - int ds = atoi(Cmd); + int ds = atoi(Cmd); - GraphTraceLen = ds; + GraphTraceLen = ds; - RepaintGraphWindow(); - return 0; + RepaintGraphWindow(); + return 0; } /* @@ -1161,416 +1163,416 @@ int CmdRtrim(const char *Cmd) */ int CmdManchesterDemod(const char *Cmd) { - int i, j, invert= 0; - int bit; - int clock; - int lastval = 0; - int low = 0; - int high = 0; - int hithigh, hitlow, first; - int lc = 0; - int bitidx = 0; - int bit2idx = 0; - int warnings = 0; + int i, j, invert= 0; + int bit; + int clock; + int lastval = 0; + int low = 0; + int high = 0; + int hithigh, hitlow, first; + int lc = 0; + int bitidx = 0; + int bit2idx = 0; + int warnings = 0; - /* check if we're inverting output */ - if (*Cmd == 'i') - { - PrintAndLog("Inverting output"); - invert = 1; - ++Cmd; - do - ++Cmd; - while(*Cmd == ' '); // in case a 2nd argument was given - } + /* check if we're inverting output */ + if (*Cmd == 'i') + { + PrintAndLog("Inverting output"); + invert = 1; + ++Cmd; + do + ++Cmd; + while(*Cmd == ' '); // in case a 2nd argument was given + } - /* Holds the decoded bitstream: each clock period contains 2 bits */ - /* later simplified to 1 bit after manchester decoding. */ - /* Add 10 bits to allow for noisy / uncertain traces without aborting */ - /* int BitStream[GraphTraceLen*2/clock+10]; */ + /* Holds the decoded bitstream: each clock period contains 2 bits */ + /* later simplified to 1 bit after manchester decoding. */ + /* Add 10 bits to allow for noisy / uncertain traces without aborting */ + /* int BitStream[GraphTraceLen*2/clock+10]; */ - /* But it does not work if compiling on WIndows: therefore we just allocate a */ - /* large array */ - uint8_t BitStream[MAX_GRAPH_TRACE_LEN] = {0}; + /* But it does not work if compiling on WIndows: therefore we just allocate a */ + /* large array */ + uint8_t BitStream[MAX_GRAPH_TRACE_LEN] = {0}; - /* Detect high and lows */ - for (i = 0; i < GraphTraceLen; i++) - { - if (GraphBuffer[i] > high) - high = GraphBuffer[i]; - else if (GraphBuffer[i] < low) - low = GraphBuffer[i]; - } + /* Detect high and lows */ + for (i = 0; i < GraphTraceLen; i++) + { + if (GraphBuffer[i] > high) + high = GraphBuffer[i]; + else if (GraphBuffer[i] < low) + low = GraphBuffer[i]; + } - /* Get our clock */ - clock = GetClock(Cmd, high, 1); + /* Get our clock */ + clock = GetClock(Cmd, high, 1); - int tolerance = clock/4; + int tolerance = clock/4; - /* Detect first transition */ - /* Lo-Hi (arbitrary) */ - /* skip to the first high */ - for (i= 0; i < GraphTraceLen; i++) - if (GraphBuffer[i] == high) - break; - /* now look for the first low */ - for (; i < GraphTraceLen; i++) - { - if (GraphBuffer[i] == low) - { - lastval = i; - break; - } - } + /* Detect first transition */ + /* Lo-Hi (arbitrary) */ + /* skip to the first high */ + for (i= 0; i < GraphTraceLen; i++) + if (GraphBuffer[i] == high) + break; + /* now look for the first low */ + for (; i < GraphTraceLen; i++) + { + if (GraphBuffer[i] == low) + { + lastval = i; + break; + } + } - /* If we're not working with 1/0s, demod based off clock */ - if (high != 1) - { - bit = 0; /* We assume the 1st bit is zero, it may not be - * the case: this routine (I think) has an init problem. - * Ed. - */ - for (; i < (int)(GraphTraceLen / clock); i++) - { - hithigh = 0; - hitlow = 0; - first = 1; + /* If we're not working with 1/0s, demod based off clock */ + if (high != 1) + { + bit = 0; /* We assume the 1st bit is zero, it may not be + * the case: this routine (I think) has an init problem. + * Ed. + */ + for (; i < (int)(GraphTraceLen / clock); i++) + { + hithigh = 0; + hitlow = 0; + first = 1; - /* Find out if we hit both high and low peaks */ - for (j = 0; j < clock; j++) - { - if (GraphBuffer[(i * clock) + j] == high) - hithigh = 1; - else if (GraphBuffer[(i * clock) + j] == low) - hitlow = 1; + /* Find out if we hit both high and low peaks */ + for (j = 0; j < clock; j++) + { + if (GraphBuffer[(i * clock) + j] == high) + hithigh = 1; + else if (GraphBuffer[(i * clock) + j] == low) + hitlow = 1; - /* it doesn't count if it's the first part of our read - because it's really just trailing from the last sequence */ - if (first && (hithigh || hitlow)) - hithigh = hitlow = 0; - else - first = 0; + /* it doesn't count if it's the first part of our read + because it's really just trailing from the last sequence */ + if (first && (hithigh || hitlow)) + hithigh = hitlow = 0; + else + first = 0; - if (hithigh && hitlow) - break; - } + if (hithigh && hitlow) + break; + } - /* If we didn't hit both high and low peaks, we had a bit transition */ - if (!hithigh || !hitlow) - bit ^= 1; + /* If we didn't hit both high and low peaks, we had a bit transition */ + if (!hithigh || !hitlow) + bit ^= 1; - BitStream[bit2idx++] = bit ^ invert; - } - } + BitStream[bit2idx++] = bit ^ invert; + } + } - /* standard 1/0 bitstream */ - else - { + /* standard 1/0 bitstream */ + else + { - /* Then detect duration between 2 successive transitions */ - for (bitidx = 1; i < GraphTraceLen; i++) - { - if (GraphBuffer[i-1] != GraphBuffer[i]) - { - lc = i-lastval; - lastval = i; + /* Then detect duration between 2 successive transitions */ + for (bitidx = 1; i < GraphTraceLen; i++) + { + if (GraphBuffer[i-1] != GraphBuffer[i]) + { + lc = i-lastval; + lastval = i; - // Error check: if bitidx becomes too large, we do not - // have a Manchester encoded bitstream or the clock is really - // wrong! - if (bitidx > (GraphTraceLen*2/clock+8) ) { - PrintAndLog("Error: the clock you gave is probably wrong, aborting."); - return 0; - } - // Then switch depending on lc length: - // Tolerance is 1/4 of clock rate (arbitrary) - if (abs(lc-clock/2) < tolerance) { - // Short pulse : either "1" or "0" - BitStream[bitidx++]=GraphBuffer[i-1]; - } else if (abs(lc-clock) < tolerance) { - // Long pulse: either "11" or "00" - BitStream[bitidx++]=GraphBuffer[i-1]; - BitStream[bitidx++]=GraphBuffer[i-1]; - } else { - // Error - warnings++; - PrintAndLog("Warning: Manchester decode error for pulse width detection."); - PrintAndLog("(too many of those messages mean either the stream is not Manchester encoded, or clock is wrong)"); + // Error check: if bitidx becomes too large, we do not + // have a Manchester encoded bitstream or the clock is really + // wrong! + if (bitidx > (GraphTraceLen*2/clock+8) ) { + PrintAndLog("Error: the clock you gave is probably wrong, aborting."); + return 0; + } + // Then switch depending on lc length: + // Tolerance is 1/4 of clock rate (arbitrary) + if (abs(lc-clock/2) < tolerance) { + // Short pulse : either "1" or "0" + BitStream[bitidx++]=GraphBuffer[i-1]; + } else if (abs(lc-clock) < tolerance) { + // Long pulse: either "11" or "00" + BitStream[bitidx++]=GraphBuffer[i-1]; + BitStream[bitidx++]=GraphBuffer[i-1]; + } else { + // Error + warnings++; + PrintAndLog("Warning: Manchester decode error for pulse width detection."); + PrintAndLog("(too many of those messages mean either the stream is not Manchester encoded, or clock is wrong)"); - if (warnings > 10) - { - PrintAndLog("Error: too many detection errors, aborting."); - return 0; - } - } - } - } + if (warnings > 10) + { + PrintAndLog("Error: too many detection errors, aborting."); + return 0; + } + } + } + } - // At this stage, we now have a bitstream of "01" ("1") or "10" ("0"), parse it into final decoded bitstream - // Actually, we overwrite BitStream with the new decoded bitstream, we just need to be careful - // to stop output at the final bitidx2 value, not bitidx - for (i = 0; i < bitidx; i += 2) { - if ((BitStream[i] == 0) && (BitStream[i+1] == 1)) { - BitStream[bit2idx++] = 1 ^ invert; - } else if ((BitStream[i] == 1) && (BitStream[i+1] == 0)) { - BitStream[bit2idx++] = 0 ^ invert; - } else { - // We cannot end up in this state, this means we are unsynchronized, - // move up 1 bit: - i++; - warnings++; - PrintAndLog("Unsynchronized, resync..."); - PrintAndLog("(too many of those messages mean the stream is not Manchester encoded)"); + // At this stage, we now have a bitstream of "01" ("1") or "10" ("0"), parse it into final decoded bitstream + // Actually, we overwrite BitStream with the new decoded bitstream, we just need to be careful + // to stop output at the final bitidx2 value, not bitidx + for (i = 0; i < bitidx; i += 2) { + if ((BitStream[i] == 0) && (BitStream[i+1] == 1)) { + BitStream[bit2idx++] = 1 ^ invert; + } else if ((BitStream[i] == 1) && (BitStream[i+1] == 0)) { + BitStream[bit2idx++] = 0 ^ invert; + } else { + // We cannot end up in this state, this means we are unsynchronized, + // move up 1 bit: + i++; + warnings++; + PrintAndLog("Unsynchronized, resync..."); + PrintAndLog("(too many of those messages mean the stream is not Manchester encoded)"); - if (warnings > 10) - { - PrintAndLog("Error: too many decode errors, aborting."); - return 0; - } - } - } - } + if (warnings > 10) + { + PrintAndLog("Error: too many decode errors, aborting."); + return 0; + } + } + } + } - PrintAndLog("Manchester decoded bitstream"); - // Now output the bitstream to the scrollback by line of 16 bits - for (i = 0; i < (bit2idx-16); i+=16) { - PrintAndLog("%i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i", - BitStream[i], - BitStream[i+1], - BitStream[i+2], - BitStream[i+3], - BitStream[i+4], - BitStream[i+5], - BitStream[i+6], - BitStream[i+7], - BitStream[i+8], - BitStream[i+9], - BitStream[i+10], - BitStream[i+11], - BitStream[i+12], - BitStream[i+13], - BitStream[i+14], - BitStream[i+15]); - } - return 0; + PrintAndLog("Manchester decoded bitstream"); + // Now output the bitstream to the scrollback by line of 16 bits + for (i = 0; i < (bit2idx-16); i+=16) { + PrintAndLog("%i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i", + BitStream[i], + BitStream[i+1], + BitStream[i+2], + BitStream[i+3], + BitStream[i+4], + BitStream[i+5], + BitStream[i+6], + BitStream[i+7], + BitStream[i+8], + BitStream[i+9], + BitStream[i+10], + BitStream[i+11], + BitStream[i+12], + BitStream[i+13], + BitStream[i+14], + BitStream[i+15]); + } + return 0; } /* Modulate our data into manchester */ int CmdManchesterMod(const char *Cmd) { - int i, j; - int clock; - int bit, lastbit, wave; + int i, j; + int clock; + int bit, lastbit, wave; - /* Get our clock */ - clock = GetClock(Cmd, 0, 1); + /* Get our clock */ + clock = GetClock(Cmd, 0, 1); - wave = 0; - lastbit = 1; - for (i = 0; i < (int)(GraphTraceLen / clock); i++) - { - bit = GraphBuffer[i * clock] ^ 1; + wave = 0; + lastbit = 1; + for (i = 0; i < (int)(GraphTraceLen / clock); i++) + { + bit = GraphBuffer[i * clock] ^ 1; - for (j = 0; j < (int)(clock/2); j++) - GraphBuffer[(i * clock) + j] = bit ^ lastbit ^ wave; - for (j = (int)(clock/2); j < clock; j++) - GraphBuffer[(i * clock) + j] = bit ^ lastbit ^ wave ^ 1; + for (j = 0; j < (int)(clock/2); j++) + GraphBuffer[(i * clock) + j] = bit ^ lastbit ^ wave; + for (j = (int)(clock/2); j < clock; j++) + GraphBuffer[(i * clock) + j] = bit ^ lastbit ^ wave ^ 1; - /* Keep track of how we start our wave and if we changed or not this time */ - wave ^= bit ^ lastbit; - lastbit = bit; - } + /* Keep track of how we start our wave and if we changed or not this time */ + wave ^= bit ^ lastbit; + lastbit = bit; + } - RepaintGraphWindow(); - return 0; + RepaintGraphWindow(); + return 0; } int CmdNorm(const char *Cmd) { - int i; - int max = INT_MIN, min = INT_MAX; + int i; + int max = INT_MIN, min = INT_MAX; - for (i = 10; i < GraphTraceLen; ++i) { - if (GraphBuffer[i] > max) - max = GraphBuffer[i]; - if (GraphBuffer[i] < min) - min = GraphBuffer[i]; - } + for (i = 10; i < GraphTraceLen; ++i) { + if (GraphBuffer[i] > max) + max = GraphBuffer[i]; + if (GraphBuffer[i] < min) + min = GraphBuffer[i]; + } - if (max != min) { - for (i = 0; i < GraphTraceLen; ++i) { - GraphBuffer[i] = (GraphBuffer[i] - ((max + min) / 2)) * 256 / - (max - min); - //marshmelow: adjusted *1000 to *256 to make +/- 128 so demod commands still work - } - } - RepaintGraphWindow(); - return 0; + if (max != min) { + for (i = 0; i < GraphTraceLen; ++i) { + GraphBuffer[i] = (GraphBuffer[i] - ((max + min) / 2)) * 256 / + (max - min); + //marshmelow: adjusted *1000 to *256 to make +/- 128 so demod commands still work + } + } + RepaintGraphWindow(); + return 0; } int CmdPlot(const char *Cmd) { - ShowGraphWindow(); - return 0; + ShowGraphWindow(); + return 0; } int CmdSave(const char *Cmd) { - FILE *f = fopen(Cmd, "w"); - if(!f) { - PrintAndLog("couldn't open '%s'", Cmd); - return 0; - } - int i; - for (i = 0; i < GraphTraceLen; i++) { - fprintf(f, "%d\n", GraphBuffer[i]); - } - fclose(f); - PrintAndLog("saved to '%s'", Cmd); - return 0; + FILE *f = fopen(Cmd, "w"); + if(!f) { + PrintAndLog("couldn't open '%s'", Cmd); + return 0; + } + int i; + for (i = 0; i < GraphTraceLen; i++) { + fprintf(f, "%d\n", GraphBuffer[i]); + } + fclose(f); + PrintAndLog("saved to '%s'", Cmd); + return 0; } int CmdScale(const char *Cmd) { - CursorScaleFactor = atoi(Cmd); - if (CursorScaleFactor == 0) { - PrintAndLog("bad, can't have zero scale"); - CursorScaleFactor = 1; - } - RepaintGraphWindow(); - return 0; + CursorScaleFactor = atoi(Cmd); + if (CursorScaleFactor == 0) { + PrintAndLog("bad, can't have zero scale"); + CursorScaleFactor = 1; + } + RepaintGraphWindow(); + return 0; } int CmdThreshold(const char *Cmd) { - int threshold = atoi(Cmd); + int threshold = atoi(Cmd); - for (int i = 0; i < GraphTraceLen; ++i) { - if (GraphBuffer[i] >= threshold) - GraphBuffer[i] = 1; - else - GraphBuffer[i] = -1; - } - RepaintGraphWindow(); - return 0; + for (int i = 0; i < GraphTraceLen; ++i) { + if (GraphBuffer[i] >= threshold) + GraphBuffer[i] = 1; + else + GraphBuffer[i] = -1; + } + RepaintGraphWindow(); + return 0; } int CmdDirectionalThreshold(const char *Cmd) { int8_t upThres = param_get8(Cmd, 0); int8_t downThres = param_get8(Cmd, 1); - - printf("Applying Up Threshold: %d, Down Threshold: %d\n", upThres, downThres); - - int lastValue = GraphBuffer[0]; - GraphBuffer[0] = 0; // Will be changed at the end, but init 0 as we adjust to last samples value if no threshold kicks in. - - for (int i = 1; i < GraphTraceLen; ++i) { - // Apply first threshold to samples heading up - if (GraphBuffer[i] >= upThres && GraphBuffer[i] > lastValue) - { - lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it. - GraphBuffer[i] = 1; - } - // Apply second threshold to samples heading down - else if (GraphBuffer[i] <= downThres && GraphBuffer[i] < lastValue) - { - lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it. - GraphBuffer[i] = -1; - } - else - { - lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it. - GraphBuffer[i] = GraphBuffer[i-1]; - } - } - GraphBuffer[0] = GraphBuffer[1]; // Aline with first edited sample. - RepaintGraphWindow(); - return 0; + printf("Applying Up Threshold: %d, Down Threshold: %d\n", upThres, downThres); + + int lastValue = GraphBuffer[0]; + GraphBuffer[0] = 0; // Will be changed at the end, but init 0 as we adjust to last samples value if no threshold kicks in. + + for (int i = 1; i < GraphTraceLen; ++i) { + // Apply first threshold to samples heading up + if (GraphBuffer[i] >= upThres && GraphBuffer[i] > lastValue) + { + lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it. + GraphBuffer[i] = 1; + } + // Apply second threshold to samples heading down + else if (GraphBuffer[i] <= downThres && GraphBuffer[i] < lastValue) + { + lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it. + GraphBuffer[i] = -1; + } + else + { + lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it. + GraphBuffer[i] = GraphBuffer[i-1]; + + } + } + GraphBuffer[0] = GraphBuffer[1]; // Aline with first edited sample. + RepaintGraphWindow(); + return 0; } int CmdZerocrossings(const char *Cmd) { - // Zero-crossings aren't meaningful unless the signal is zero-mean. - CmdHpf(""); + // Zero-crossings aren't meaningful unless the signal is zero-mean. + CmdHpf(""); - int sign = 1; - int zc = 0; - int lastZc = 0; + int sign = 1; + int zc = 0; + int lastZc = 0; - for (int i = 0; i < GraphTraceLen; ++i) { - if (GraphBuffer[i] * sign >= 0) { - // No change in sign, reproduce the previous sample count. - zc++; - GraphBuffer[i] = lastZc; - } else { - // Change in sign, reset the sample count. - sign = -sign; - GraphBuffer[i] = lastZc; - if (sign > 0) { - lastZc = zc; - zc = 0; - } - } - } + for (int i = 0; i < GraphTraceLen; ++i) { + if (GraphBuffer[i] * sign >= 0) { + // No change in sign, reproduce the previous sample count. + zc++; + GraphBuffer[i] = lastZc; + } else { + // Change in sign, reset the sample count. + sign = -sign; + GraphBuffer[i] = lastZc; + if (sign > 0) { + lastZc = zc; + zc = 0; + } + } + } - RepaintGraphWindow(); - return 0; + RepaintGraphWindow(); + return 0; } -static command_t CommandTable[] = +static command_t CommandTable[] = { - {"help", CmdHelp, 1, "This help"}, - {"amp", CmdAmp, 1, "Amplify peaks"}, - {"askdemod", Cmdaskdemod, 1, "<0 or 1> -- Attempt to demodulate simple ASK tags"}, - {"askmandemod", Cmdaskmandemod, 1, "[clock] [invert<0 or 1>] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional[clock will try Auto-detect])"}, - {"askrawdemod", Cmdaskrawdemod, 1, "[clock] [invert<0 or 1>] -- Attempt to demodulate ASK tags and output binary (args optional[clock will try Auto-detect])"}, - {"autocorr", CmdAutoCorr, 1, " -- Autocorrelation over window"}, - {"biphaserawdecode",CmdBiphaseDecodeRaw,1,"[offset] Biphase decode binary stream already in graph buffer (offset = bit to start decode from)"}, - {"bitsamples", CmdBitsamples, 0, "Get raw samples as bitstring"}, - {"bitstream", CmdBitstream, 1, "[clock rate] -- Convert waveform into a bitstream"}, - {"buffclear", CmdBuffClear, 1, "Clear sample buffer and graph window"}, - {"dec", CmdDec, 1, "Decimate samples"}, - {"detectclock", CmdDetectClockRate, 1, "Detect ASK, PSK, or NRZ clock rate"}, - {"fskdemod", CmdFSKdemod, 1, "Demodulate graph window as a HID FSK"}, - {"fskhiddemod", CmdFSKdemodHID, 1, "Demodulate graph window as a HID FSK using raw"}, - {"fskiodemod", CmdFSKdemodIO, 1, "Demodulate graph window as an IO Prox FSK using raw"}, - {"fskrawdemod", CmdFSKrawdemod, 1, "[clock rate] [invert] [rchigh] [rclow] Demodulate graph window from FSK to binary (clock = 50)(invert = 1 or 0)(rchigh = 10)(rclow=8)"}, - {"grid", CmdGrid, 1, " -- overlay grid on graph window, use zero value to turn off either"}, - {"hexsamples", CmdHexsamples, 0, " [] -- Dump big buffer as hex bytes"}, - {"hide", CmdHide, 1, "Hide graph window"}, - {"hpf", CmdHpf, 1, "Remove DC offset from trace"}, - {"load", CmdLoad, 1, " -- Load trace (to graph window"}, - {"ltrim", CmdLtrim, 1, " -- Trim samples from left of trace"}, - {"rtrim", CmdRtrim, 1, " -- Trim samples from right of trace"}, - {"mandemod", CmdManchesterDemod, 1, "[i] [clock rate] -- Manchester demodulate binary stream (option 'i' to invert output)"}, - {"manrawdecode", Cmdmandecoderaw, 1, "Manchester decode binary stream already in graph buffer"}, - {"manmod", CmdManchesterMod, 1, "[clock rate] -- Manchester modulate a binary stream"}, - {"norm", CmdNorm, 1, "Normalize max/min to +/-128"}, - {"plot", CmdPlot, 1, "Show graph window (hit 'h' in window for keystroke help)"}, - {"pskclean", CmdPskClean, 1, "Attempt to clean psk wave"}, - {"pskdetectclock",CmdDetectNRZpskClockRate, 1, "Detect ASK, PSK, or NRZ clock rate"}, - {"pskindalademod",CmdIndalaDecode, 1, "[clock] [invert<0 or 1>] -- Attempt to demodulate psk indala tags and output ID binary & hex (args optional[clock will try Auto-detect])"}, - {"psknrzrawdemod",CmdpskNRZrawDemod, 1, "[clock] [invert<0 or 1>] -- Attempt to demodulate psk or nrz tags and output binary (args optional[clock will try Auto-detect])"}, - {"samples", CmdSamples, 0, "[512 - 40000] -- Get raw samples for graph window"}, - {"save", CmdSave, 1, " -- Save trace (from graph window)"}, - {"scale", CmdScale, 1, " -- Set cursor display scale"}, - {"threshold", CmdThreshold, 1, " -- Maximize/minimize every value in the graph window depending on threshold"}, - {"dirthreshold", CmdDirectionalThreshold, 1, " -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev."}, - {"tune", CmdTuneSamples, 0, "Get hw tune samples for graph window"}, - {"zerocrossings", CmdZerocrossings, 1, "Count time between zero-crossings"}, - {NULL, NULL, 0, NULL} + {"help", CmdHelp, 1, "This help"}, + {"amp", CmdAmp, 1, "Amplify peaks"}, + {"askdemod", Cmdaskdemod, 1, "<0 or 1> -- Attempt to demodulate simple ASK tags"}, + {"askmandemod", Cmdaskmandemod, 1, "[clock] [invert<0 or 1>] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional[clock will try Auto-detect])"}, + {"askrawdemod", Cmdaskrawdemod, 1, "[clock] [invert<0 or 1>] -- Attempt to demodulate ASK tags and output binary (args optional[clock will try Auto-detect])"}, + {"autocorr", CmdAutoCorr, 1, " -- Autocorrelation over window"}, + {"biphaserawdecode",CmdBiphaseDecodeRaw,1,"[offset] Biphase decode binary stream already in graph buffer (offset = bit to start decode from)"}, + {"bitsamples", CmdBitsamples, 0, "Get raw samples as bitstring"}, + {"bitstream", CmdBitstream, 1, "[clock rate] -- Convert waveform into a bitstream"}, + {"buffclear", CmdBuffClear, 1, "Clear sample buffer and graph window"}, + {"dec", CmdDec, 1, "Decimate samples"}, + {"detectclock", CmdDetectClockRate, 1, "Detect ASK clock rate"}, + {"fskdemod", CmdFSKdemod, 1, "Demodulate graph window as a HID FSK"}, + {"fskhiddemod", CmdFSKdemodHID, 1, "Demodulate graph window as a HID FSK using raw"}, + {"fskiodemod", CmdFSKdemodIO, 1, "Demodulate graph window as an IO Prox FSK using raw"}, + {"fskrawdemod", CmdFSKrawdemod, 1, "[clock rate] [invert] [rchigh] [rclow] Demodulate graph window from FSK to binary (clock = 50)(invert = 1 or 0)(rchigh = 10)(rclow=8)"}, + {"grid", CmdGrid, 1, " -- overlay grid on graph window, use zero value to turn off either"}, + {"hexsamples", CmdHexsamples, 0, " [] -- Dump big buffer as hex bytes"}, + {"hide", CmdHide, 1, "Hide graph window"}, + {"hpf", CmdHpf, 1, "Remove DC offset from trace"}, + {"load", CmdLoad, 1, " -- Load trace (to graph window"}, + {"ltrim", CmdLtrim, 1, " -- Trim samples from left of trace"}, + {"rtrim", CmdRtrim, 1, " -- Trim samples from right of trace"}, + {"mandemod", CmdManchesterDemod, 1, "[i] [clock rate] -- Manchester demodulate binary stream (option 'i' to invert output)"}, + {"manrawdecode", Cmdmandecoderaw, 1, "Manchester decode binary stream already in graph buffer"}, + {"manmod", CmdManchesterMod, 1, "[clock rate] -- Manchester modulate a binary stream"}, + {"norm", CmdNorm, 1, "Normalize max/min to +/-128"}, + {"plot", CmdPlot, 1, "Show graph window (hit 'h' in window for keystroke help)"}, + {"pskclean", CmdPskClean, 1, "Attempt to clean psk wave"}, + {"pskdetectclock",CmdDetectNRZpskClockRate, 1, "Detect ASK, PSK, or NRZ clock rate"}, + {"pskindalademod",CmdIndalaDecode, 1, "[clock] [invert<0 or 1>] -- Attempt to demodulate psk indala tags and output ID binary & hex (args optional[clock will try Auto-detect])"}, + {"psknrzrawdemod",CmdpskNRZrawDemod, 1, "[clock] [invert<0 or 1>] -- Attempt to demodulate psk or nrz tags and output binary (args optional[clock will try Auto-detect])"}, + {"samples", CmdSamples, 0, "[512 - 40000] -- Get raw samples for graph window"}, + {"save", CmdSave, 1, " -- Save trace (from graph window)"}, + {"scale", CmdScale, 1, " -- Set cursor display scale"}, + {"threshold", CmdThreshold, 1, " -- Maximize/minimize every value in the graph window depending on threshold"}, + {"dirthreshold", CmdDirectionalThreshold, 1, " -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev."}, + {"tune", CmdTuneSamples, 0, "Get hw tune samples for graph window"}, + {"zerocrossings", CmdZerocrossings, 1, "Count time between zero-crossings"}, + {NULL, NULL, 0, NULL} }; int CmdData(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; } diff --git a/client/cmdlf.c b/client/cmdlf.c index 42a29d0db..af24aa809 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -34,592 +34,592 @@ static int CmdHelp(const char *Cmd); /* send a command before reading */ int CmdLFCommandRead(const char *Cmd) { - static char dummy[3]; + static char dummy[3]; - dummy[0]= ' '; + dummy[0]= ' '; - UsbCommand c = {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K}; - sscanf(Cmd, "%"lli" %"lli" %"lli" %s %s", &c.arg[0], &c.arg[1], &c.arg[2],(char*)(&c.d.asBytes),(char*)(&dummy+1)); - // in case they specified 'h' - strcpy((char *)&c.d.asBytes + strlen((char *)c.d.asBytes), dummy); - SendCommand(&c); - return 0; + UsbCommand c = {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K}; + sscanf(Cmd, "%"lli" %"lli" %"lli" %s %s", &c.arg[0], &c.arg[1], &c.arg[2],(char*)(&c.d.asBytes),(char*)(&dummy+1)); + // in case they specified 'h' + strcpy((char *)&c.d.asBytes + strlen((char *)c.d.asBytes), dummy); + SendCommand(&c); + return 0; } int CmdFlexdemod(const char *Cmd) { - int i; - for (i = 0; i < GraphTraceLen; ++i) { - if (GraphBuffer[i] < 0) { - GraphBuffer[i] = -1; - } else { - GraphBuffer[i] = 1; - } - } + int i; + for (i = 0; i < GraphTraceLen; ++i) { + if (GraphBuffer[i] < 0) { + GraphBuffer[i] = -1; + } else { + GraphBuffer[i] = 1; + } + } - #define LONG_WAIT 100 - int start; - for (start = 0; start < GraphTraceLen - LONG_WAIT; start++) { - int first = GraphBuffer[start]; - for (i = start; i < start + LONG_WAIT; i++) { - if (GraphBuffer[i] != first) { - break; - } - } - if (i == (start + LONG_WAIT)) { - break; - } - } - if (start == GraphTraceLen - LONG_WAIT) { - PrintAndLog("nothing to wait for"); - return 0; - } + #define LONG_WAIT 100 + int start; + for (start = 0; start < GraphTraceLen - LONG_WAIT; start++) { + int first = GraphBuffer[start]; + for (i = start; i < start + LONG_WAIT; i++) { + if (GraphBuffer[i] != first) { + break; + } + } + if (i == (start + LONG_WAIT)) { + break; + } + } + if (start == GraphTraceLen - LONG_WAIT) { + PrintAndLog("nothing to wait for"); + return 0; + } - GraphBuffer[start] = 2; - GraphBuffer[start+1] = -2; + GraphBuffer[start] = 2; + GraphBuffer[start+1] = -2; - uint8_t bits[64]; + uint8_t bits[64]; - int bit; - i = start; - for (bit = 0; bit < 64; bit++) { - int j; - int sum = 0; - for (j = 0; j < 16; j++) { - sum += GraphBuffer[i++]; - } - if (sum > 0) { - bits[bit] = 1; - } else { - bits[bit] = 0; - } - PrintAndLog("bit %d sum %d", bit, sum); - } + int bit; + i = start; + for (bit = 0; bit < 64; bit++) { + int j; + int sum = 0; + for (j = 0; j < 16; j++) { + sum += GraphBuffer[i++]; + } + if (sum > 0) { + bits[bit] = 1; + } else { + bits[bit] = 0; + } + PrintAndLog("bit %d sum %d", bit, sum); + } - for (bit = 0; bit < 64; bit++) { - int j; - int sum = 0; - for (j = 0; j < 16; j++) { - sum += GraphBuffer[i++]; - } - if (sum > 0 && bits[bit] != 1) { - PrintAndLog("oops1 at %d", bit); - } - if (sum < 0 && bits[bit] != 0) { - PrintAndLog("oops2 at %d", bit); - } - } + for (bit = 0; bit < 64; bit++) { + int j; + int sum = 0; + for (j = 0; j < 16; j++) { + sum += GraphBuffer[i++]; + } + if (sum > 0 && bits[bit] != 1) { + PrintAndLog("oops1 at %d", bit); + } + if (sum < 0 && bits[bit] != 0) { + PrintAndLog("oops2 at %d", bit); + } + } - GraphTraceLen = 32*64; - i = 0; - int phase = 0; - for (bit = 0; bit < 64; bit++) { - if (bits[bit] == 0) { - phase = 0; - } else { - phase = 1; - } - int j; - for (j = 0; j < 32; j++) { - GraphBuffer[i++] = phase; - phase = !phase; - } - } + GraphTraceLen = 32*64; + i = 0; + int phase = 0; + for (bit = 0; bit < 64; bit++) { + if (bits[bit] == 0) { + phase = 0; + } else { + phase = 1; + } + int j; + for (j = 0; j < 32; j++) { + GraphBuffer[i++] = phase; + phase = !phase; + } + } - RepaintGraphWindow(); - return 0; + RepaintGraphWindow(); + return 0; } - + int CmdIndalaDemod(const char *Cmd) { - // Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID + // Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID - int state = -1; - int count = 0; - int i, j; - // worst case with GraphTraceLen=64000 is < 4096 - // under normal conditions it's < 2048 - uint8_t rawbits[4096]; - int rawbit = 0; - int worst = 0, worstPos = 0; + int state = -1; + int count = 0; + int i, j; + // worst case with GraphTraceLen=64000 is < 4096 + // under normal conditions it's < 2048 + uint8_t rawbits[4096]; + int rawbit = 0; + int worst = 0, worstPos = 0; // PrintAndLog("Expecting a bit less than %d raw bits", GraphTraceLen / 32); - for (i = 0; i < GraphTraceLen-1; i += 2) { - count += 1; - if ((GraphBuffer[i] > GraphBuffer[i + 1]) && (state != 1)) { - if (state == 0) { - for (j = 0; j < count - 8; j += 16) { - rawbits[rawbit++] = 0; - } - if ((abs(count - j)) > worst) { - worst = abs(count - j); - worstPos = i; - } - } - state = 1; - count = 0; - } else if ((GraphBuffer[i] < GraphBuffer[i + 1]) && (state != 0)) { - if (state == 1) { - for (j = 0; j < count - 8; j += 16) { - rawbits[rawbit++] = 1; - } - if ((abs(count - j)) > worst) { - worst = abs(count - j); - worstPos = i; - } - } - state = 0; - count = 0; - } - } - if (rawbit>0){ - PrintAndLog("Recovered %d raw bits, expected: %d", rawbit, GraphTraceLen/32); - PrintAndLog("worst metric (0=best..7=worst): %d at pos %d", worst, worstPos); - } else return 0; - // Finding the start of a UID - int uidlen, long_wait; - if (strcmp(Cmd, "224") == 0) { - uidlen = 224; - long_wait = 30; - } else { - uidlen = 64; - long_wait = 29; - } - int start; - int first = 0; - for (start = 0; start <= rawbit - uidlen; start++) { - first = rawbits[start]; - for (i = start; i < start + long_wait; i++) { - if (rawbits[i] != first) { - break; - } - } - if (i == (start + long_wait)) { - break; - } - } - if (start == rawbit - uidlen + 1) { - PrintAndLog("nothing to wait for"); - return 0; - } + for (i = 0; i < GraphTraceLen-1; i += 2) { + count += 1; + if ((GraphBuffer[i] > GraphBuffer[i + 1]) && (state != 1)) { + if (state == 0) { + for (j = 0; j < count - 8; j += 16) { + rawbits[rawbit++] = 0; + } + if ((abs(count - j)) > worst) { + worst = abs(count - j); + worstPos = i; + } + } + state = 1; + count = 0; + } else if ((GraphBuffer[i] < GraphBuffer[i + 1]) && (state != 0)) { + if (state == 1) { + for (j = 0; j < count - 8; j += 16) { + rawbits[rawbit++] = 1; + } + if ((abs(count - j)) > worst) { + worst = abs(count - j); + worstPos = i; + } + } + state = 0; + count = 0; + } + } + if (rawbit>0){ + PrintAndLog("Recovered %d raw bits, expected: %d", rawbit, GraphTraceLen/32); + PrintAndLog("worst metric (0=best..7=worst): %d at pos %d", worst, worstPos); + } else return 0; + // Finding the start of a UID + int uidlen, long_wait; + if (strcmp(Cmd, "224") == 0) { + uidlen = 224; + long_wait = 30; + } else { + uidlen = 64; + long_wait = 29; + } + int start; + int first = 0; + for (start = 0; start <= rawbit - uidlen; start++) { + first = rawbits[start]; + for (i = start; i < start + long_wait; i++) { + if (rawbits[i] != first) { + break; + } + } + if (i == (start + long_wait)) { + break; + } + } + if (start == rawbit - uidlen + 1) { + PrintAndLog("nothing to wait for"); + return 0; + } - // Inverting signal if needed - if (first == 1) { - for (i = start; i < rawbit; i++) { - rawbits[i] = !rawbits[i]; - } - } + // Inverting signal if needed + if (first == 1) { + for (i = start; i < rawbit; i++) { + rawbits[i] = !rawbits[i]; + } + } - // Dumping UID - uint8_t bits[224]; - char showbits[225]; - showbits[uidlen]='\0'; - int bit; - i = start; - int times = 0; - if (uidlen > rawbit) { - PrintAndLog("Warning: not enough raw bits to get a full UID"); - for (bit = 0; bit < rawbit; bit++) { - bits[bit] = rawbits[i++]; - // As we cannot know the parity, let's use "." and "/" - showbits[bit] = '.' + bits[bit]; - } - showbits[bit+1]='\0'; - PrintAndLog("Partial UID=%s", showbits); - return 0; - } else { - for (bit = 0; bit < uidlen; bit++) { - bits[bit] = rawbits[i++]; - showbits[bit] = '0' + bits[bit]; - } - times = 1; - } - - //convert UID to HEX - uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7; - int idx; - uid1=0; - uid2=0; - if (uidlen==64){ - for( idx=0; idx<64; idx++) { - if (showbits[idx] == '0') { - uid1=(uid1<<1)|(uid2>>31); - uid2=(uid2<<1)|0; - } else { - uid1=(uid1<<1)|(uid2>>31); - uid2=(uid2<<1)|1; - } - } - PrintAndLog("UID=%s (%x%08x)", showbits, uid1, uid2); - } - else { - uid3=0; - uid4=0; - uid5=0; - uid6=0; - uid7=0; - for( idx=0; idx<224; idx++) { - uid1=(uid1<<1)|(uid2>>31); - uid2=(uid2<<1)|(uid3>>31); - uid3=(uid3<<1)|(uid4>>31); - uid4=(uid4<<1)|(uid5>>31); - uid5=(uid5<<1)|(uid6>>31); - uid6=(uid6<<1)|(uid7>>31); - if (showbits[idx] == '0') uid7=(uid7<<1)|0; - else uid7=(uid7<<1)|1; - } - PrintAndLog("UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7); - } + // Dumping UID + uint8_t bits[224]; + char showbits[225]; + showbits[uidlen]='\0'; + int bit; + i = start; + int times = 0; + if (uidlen > rawbit) { + PrintAndLog("Warning: not enough raw bits to get a full UID"); + for (bit = 0; bit < rawbit; bit++) { + bits[bit] = rawbits[i++]; + // As we cannot know the parity, let's use "." and "/" + showbits[bit] = '.' + bits[bit]; + } + showbits[bit+1]='\0'; + PrintAndLog("Partial UID=%s", showbits); + return 0; + } else { + for (bit = 0; bit < uidlen; bit++) { + bits[bit] = rawbits[i++]; + showbits[bit] = '0' + bits[bit]; + } + times = 1; + } + + //convert UID to HEX + uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7; + int idx; + uid1=0; + uid2=0; + if (uidlen==64){ + for( idx=0; idx<64; idx++) { + if (showbits[idx] == '0') { + uid1=(uid1<<1)|(uid2>>31); + uid2=(uid2<<1)|0; + } else { + uid1=(uid1<<1)|(uid2>>31); + uid2=(uid2<<1)|1; + } + } + PrintAndLog("UID=%s (%x%08x)", showbits, uid1, uid2); + } + else { + uid3=0; + uid4=0; + uid5=0; + uid6=0; + uid7=0; + for( idx=0; idx<224; idx++) { + uid1=(uid1<<1)|(uid2>>31); + uid2=(uid2<<1)|(uid3>>31); + uid3=(uid3<<1)|(uid4>>31); + uid4=(uid4<<1)|(uid5>>31); + uid5=(uid5<<1)|(uid6>>31); + uid6=(uid6<<1)|(uid7>>31); + if (showbits[idx] == '0') uid7=(uid7<<1)|0; + else uid7=(uid7<<1)|1; + } + PrintAndLog("UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7); + } - // Checking UID against next occurrences - for (; i + uidlen <= rawbit;) { - int failed = 0; - for (bit = 0; bit < uidlen; bit++) { - if (bits[bit] != rawbits[i++]) { - failed = 1; - break; - } - } - if (failed == 1) { - break; - } - times += 1; - } - PrintAndLog("Occurrences: %d (expected %d)", times, (rawbit - start) / uidlen); + // Checking UID against next occurrences + for (; i + uidlen <= rawbit;) { + int failed = 0; + for (bit = 0; bit < uidlen; bit++) { + if (bits[bit] != rawbits[i++]) { + failed = 1; + break; + } + } + if (failed == 1) { + break; + } + times += 1; + } + PrintAndLog("Occurrences: %d (expected %d)", times, (rawbit - start) / uidlen); - // Remodulating for tag cloning - GraphTraceLen = 32*uidlen; - i = 0; - int phase = 0; - for (bit = 0; bit < uidlen; bit++) { - if (bits[bit] == 0) { - phase = 0; - } else { - phase = 1; - } - int j; - for (j = 0; j < 32; j++) { - GraphBuffer[i++] = phase; - phase = !phase; - } - } + // Remodulating for tag cloning + GraphTraceLen = 32*uidlen; + i = 0; + int phase = 0; + for (bit = 0; bit < uidlen; bit++) { + if (bits[bit] == 0) { + phase = 0; + } else { + phase = 1; + } + int j; + for (j = 0; j < 32; j++) { + GraphBuffer[i++] = phase; + phase = !phase; + } + } - RepaintGraphWindow(); - return 1; + RepaintGraphWindow(); + return 1; } int CmdIndalaClone(const char *Cmd) { - unsigned int uid1, uid2, uid3, uid4, uid5, uid6, uid7; - UsbCommand c; - uid1=0; - uid2=0; - uid3=0; - uid4=0; - uid5=0; - uid6=0; - uid7=0; - int n = 0, i = 0; + unsigned int uid1, uid2, uid3, uid4, uid5, uid6, uid7; + UsbCommand c; + uid1=0; + uid2=0; + uid3=0; + uid4=0; + uid5=0; + uid6=0; + uid7=0; + int n = 0, i = 0; - if (strchr(Cmd,'l') != 0) { - while (sscanf(&Cmd[i++], "%1x", &n ) == 1) { - uid1 = (uid1 << 4) | (uid2 >> 28); - uid2 = (uid2 << 4) | (uid3 >> 28); - uid3 = (uid3 << 4) | (uid4 >> 28); - uid4 = (uid4 << 4) | (uid5 >> 28); - uid5 = (uid5 << 4) | (uid6 >> 28); - uid6 = (uid6 << 4) | (uid7 >> 28); - uid7 = (uid7 << 4) | (n & 0xf); - } - PrintAndLog("Cloning 224bit tag with UID %x%08x%08x%08x%08x%08x%08x", uid1, uid2, uid3, uid4, uid5, uid6, uid7); - c.cmd = CMD_INDALA_CLONE_TAG_L; - c.d.asDwords[0] = uid1; - c.d.asDwords[1] = uid2; - c.d.asDwords[2] = uid3; - c.d.asDwords[3] = uid4; - c.d.asDwords[4] = uid5; - c.d.asDwords[5] = uid6; - c.d.asDwords[6] = uid7; - } - else - { - while (sscanf(&Cmd[i++], "%1x", &n ) == 1) { - uid1 = (uid1 << 4) | (uid2 >> 28); - uid2 = (uid2 << 4) | (n & 0xf); - } - PrintAndLog("Cloning 64bit tag with UID %x%08x", uid1, uid2); - c.cmd = CMD_INDALA_CLONE_TAG; - c.arg[0] = uid1; - c.arg[1] = uid2; - } + if (strchr(Cmd,'l') != 0) { + while (sscanf(&Cmd[i++], "%1x", &n ) == 1) { + uid1 = (uid1 << 4) | (uid2 >> 28); + uid2 = (uid2 << 4) | (uid3 >> 28); + uid3 = (uid3 << 4) | (uid4 >> 28); + uid4 = (uid4 << 4) | (uid5 >> 28); + uid5 = (uid5 << 4) | (uid6 >> 28); + uid6 = (uid6 << 4) | (uid7 >> 28); + uid7 = (uid7 << 4) | (n & 0xf); + } + PrintAndLog("Cloning 224bit tag with UID %x%08x%08x%08x%08x%08x%08x", uid1, uid2, uid3, uid4, uid5, uid6, uid7); + c.cmd = CMD_INDALA_CLONE_TAG_L; + c.d.asDwords[0] = uid1; + c.d.asDwords[1] = uid2; + c.d.asDwords[2] = uid3; + c.d.asDwords[3] = uid4; + c.d.asDwords[4] = uid5; + c.d.asDwords[5] = uid6; + c.d.asDwords[6] = uid7; + } + else + { + while (sscanf(&Cmd[i++], "%1x", &n ) == 1) { + uid1 = (uid1 << 4) | (uid2 >> 28); + uid2 = (uid2 << 4) | (n & 0xf); + } + PrintAndLog("Cloning 64bit tag with UID %x%08x", uid1, uid2); + c.cmd = CMD_INDALA_CLONE_TAG; + c.arg[0] = uid1; + c.arg[1] = uid2; + } - SendCommand(&c); - return 0; + SendCommand(&c); + return 0; } int CmdLFRead(const char *Cmd) { - UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K}; - // 'h' means higher-low-frequency, 134 kHz - if(*Cmd == 'h') { - c.arg[0] = 1; - } else if (*Cmd == '\0') { - c.arg[0] = 0; - } else if (sscanf(Cmd, "%"lli, &c.arg[0]) != 1) { - PrintAndLog("use 'read' or 'read h', or 'read '"); - return 0; - } - SendCommand(&c); - WaitForResponse(CMD_ACK,NULL); - return 0; + UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K}; + // 'h' means higher-low-frequency, 134 kHz + if(*Cmd == 'h') { + c.arg[0] = 1; + } else if (*Cmd == '\0') { + c.arg[0] = 0; + } else if (sscanf(Cmd, "%"lli, &c.arg[0]) != 1) { + PrintAndLog("use 'read' or 'read h', or 'read '"); + return 0; + } + SendCommand(&c); + WaitForResponse(CMD_ACK,NULL); + return 0; } static void ChkBitstream(const char *str) { - int i; + int i; - /* convert to bitstream if necessary */ - for (i = 0; i < (int)(GraphTraceLen / 2); i++) - { - if (GraphBuffer[i] > 1 || GraphBuffer[i] < 0) - { - CmdBitstream(str); - break; - } - } + /* convert to bitstream if necessary */ + for (i = 0; i < (int)(GraphTraceLen / 2); i++) + { + if (GraphBuffer[i] > 1 || GraphBuffer[i] < 0) + { + CmdBitstream(str); + break; + } + } } int CmdLFSim(const char *Cmd) { - int i; - static int gap; + int i; + static int gap; - sscanf(Cmd, "%i", &gap); + sscanf(Cmd, "%i", &gap); - /* convert to bitstream if necessary */ - ChkBitstream(Cmd); + /* convert to bitstream if necessary */ + ChkBitstream(Cmd); - PrintAndLog("Sending data, please wait..."); - for (i = 0; i < GraphTraceLen; i += 48) { - UsbCommand c={CMD_DOWNLOADED_SIM_SAMPLES_125K, {i, 0, 0}}; - int j; - for (j = 0; j < 48; j++) { - c.d.asBytes[j] = GraphBuffer[i+j]; - } - SendCommand(&c); - WaitForResponse(CMD_ACK,NULL); - } + PrintAndLog("Sending data, please wait..."); + for (i = 0; i < GraphTraceLen; i += 48) { + UsbCommand c={CMD_DOWNLOADED_SIM_SAMPLES_125K, {i, 0, 0}}; + int j; + for (j = 0; j < 48; j++) { + c.d.asBytes[j] = GraphBuffer[i+j]; + } + SendCommand(&c); + WaitForResponse(CMD_ACK,NULL); + } - PrintAndLog("Starting simulator..."); - UsbCommand c = {CMD_SIMULATE_TAG_125K, {GraphTraceLen, gap, 0}}; - SendCommand(&c); - return 0; + PrintAndLog("Starting simulator..."); + UsbCommand c = {CMD_SIMULATE_TAG_125K, {GraphTraceLen, gap, 0}}; + SendCommand(&c); + return 0; } int CmdLFSimBidir(const char *Cmd) { - /* Set ADC to twice the carrier for a slight supersampling */ - UsbCommand c = {CMD_LF_SIMULATE_BIDIR, {47, 384, 0}}; - SendCommand(&c); - return 0; + /* Set ADC to twice the carrier for a slight supersampling */ + UsbCommand c = {CMD_LF_SIMULATE_BIDIR, {47, 384, 0}}; + SendCommand(&c); + 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]; + static int clock, gap; + static char data[1024], gapstring[8]; - /* get settings/bits */ - sscanf(Cmd, "%i %s %i", &clock, &data[0], &gap); + /* get settings/bits */ + sscanf(Cmd, "%i %s %i", &clock, &data[0], &gap); - /* clear our graph */ - ClearGraph(0); + /* clear our graph */ + ClearGraph(0); - /* fill it with our bitstream */ - for (int i = 0; i < strlen(data) ; ++i) - AppendGraph(0, clock, data[i]- '0'); + /* fill it with our bitstream */ + for (int i = 0; i < strlen(data) ; ++i) + AppendGraph(0, clock, data[i]- '0'); - /* modulate */ - CmdManchesterMod(""); + /* modulate */ + CmdManchesterMod(""); - /* show what we've done */ - RepaintGraphWindow(); + /* show what we've done */ + RepaintGraphWindow(); - /* simulate */ - sprintf(&gapstring[0], "%i", gap); - CmdLFSim(gapstring); - return 0; + /* simulate */ + sprintf(&gapstring[0], "%i", gap); + CmdLFSim(gapstring); + return 0; } int CmdLFSnoop(const char *Cmd) { - UsbCommand c = {CMD_LF_SNOOP_RAW_ADC_SAMPLES}; - // 'h' means higher-low-frequency, 134 kHz - c.arg[0] = 0; - c.arg[1] = -1; - if (*Cmd == 0) { - // empty - } else if (*Cmd == 'l') { - sscanf(Cmd, "l %"lli, &c.arg[1]); - } else if(*Cmd == 'h') { - c.arg[0] = 1; - sscanf(Cmd, "h %"lli, &c.arg[1]); - } else if (sscanf(Cmd, "%"lli" %"lli, &c.arg[0], &c.arg[1]) < 1) { - PrintAndLog("use 'snoop' or 'snoop {l,h} [trigger threshold]', or 'snoop [trigger threshold]'"); - return 0; - } - SendCommand(&c); - WaitForResponse(CMD_ACK,NULL); - return 0; + UsbCommand c = {CMD_LF_SNOOP_RAW_ADC_SAMPLES}; + // 'h' means higher-low-frequency, 134 kHz + c.arg[0] = 0; + c.arg[1] = -1; + if (*Cmd == 0) { + // empty + } else if (*Cmd == 'l') { + sscanf(Cmd, "l %"lli, &c.arg[1]); + } else if(*Cmd == 'h') { + c.arg[0] = 1; + sscanf(Cmd, "h %"lli, &c.arg[1]); + } else if (sscanf(Cmd, "%"lli" %"lli, &c.arg[0], &c.arg[1]) < 1) { + PrintAndLog("use 'snoop' or 'snoop {l,h} [trigger threshold]', or 'snoop [trigger threshold]'"); + return 0; + } + SendCommand(&c); + WaitForResponse(CMD_ACK,NULL); + return 0; } int CmdVchDemod(const char *Cmd) { - // Is this the entire sync pattern, or does this also include some - // data bits that happen to be the same everywhere? That would be - // lovely to know. - static const int SyncPattern[] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - }; + // Is this the entire sync pattern, or does this also include some + // data bits that happen to be the same everywhere? That would be + // lovely to know. + static const int SyncPattern[] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }; - // So first, we correlate for the sync pattern, and mark that. - int bestCorrel = 0, bestPos = 0; - int i; - // It does us no good to find the sync pattern, with fewer than - // 2048 samples after it... - for (i = 0; i < (GraphTraceLen-2048); i++) { - int sum = 0; - int j; - for (j = 0; j < arraylen(SyncPattern); j++) { - sum += GraphBuffer[i+j]*SyncPattern[j]; - } - if (sum > bestCorrel) { - bestCorrel = sum; - bestPos = i; - } - } - PrintAndLog("best sync at %d [metric %d]", bestPos, bestCorrel); + // So first, we correlate for the sync pattern, and mark that. + int bestCorrel = 0, bestPos = 0; + int i; + // It does us no good to find the sync pattern, with fewer than + // 2048 samples after it... + for (i = 0; i < (GraphTraceLen-2048); i++) { + int sum = 0; + int j; + for (j = 0; j < arraylen(SyncPattern); j++) { + sum += GraphBuffer[i+j]*SyncPattern[j]; + } + if (sum > bestCorrel) { + bestCorrel = sum; + bestPos = i; + } + } + PrintAndLog("best sync at %d [metric %d]", bestPos, bestCorrel); - char bits[257]; - bits[256] = '\0'; + char bits[257]; + bits[256] = '\0'; - int worst = INT_MAX; - int worstPos = 0; + int worst = INT_MAX; + int worstPos = 0; - for (i = 0; i < 2048; i += 8) { - int sum = 0; - int j; - for (j = 0; j < 8; j++) { - sum += GraphBuffer[bestPos+i+j]; - } - if (sum < 0) { - bits[i/8] = '.'; - } else { - bits[i/8] = '1'; - } - if(abs(sum) < worst) { - worst = abs(sum); - worstPos = i; - } - } - PrintAndLog("bits:"); - PrintAndLog("%s", bits); - PrintAndLog("worst metric: %d at pos %d", worst, worstPos); + for (i = 0; i < 2048; i += 8) { + int sum = 0; + int j; + for (j = 0; j < 8; j++) { + sum += GraphBuffer[bestPos+i+j]; + } + if (sum < 0) { + bits[i/8] = '.'; + } else { + bits[i/8] = '1'; + } + if(abs(sum) < worst) { + worst = abs(sum); + worstPos = i; + } + } + PrintAndLog("bits:"); + PrintAndLog("%s", bits); + PrintAndLog("worst metric: %d at pos %d", worst, worstPos); - if (strcmp(Cmd, "clone")==0) { - GraphTraceLen = 0; - char *s; - for(s = bits; *s; s++) { - int j; - for(j = 0; j < 16; j++) { - GraphBuffer[GraphTraceLen++] = (*s == '1') ? 1 : 0; - } - } - RepaintGraphWindow(); - } - return 0; + if (strcmp(Cmd, "clone")==0) { + GraphTraceLen = 0; + char *s; + for(s = bits; *s; s++) { + int j; + for(j = 0; j < 16; j++) { + GraphBuffer[GraphTraceLen++] = (*s == '1') ? 1 : 0; + } + } + RepaintGraphWindow(); + } + return 0; } //by marshmellow int CmdLFfind(const char *Cmd) { - int ans=0; - if (!offline){ - ans=CmdLFRead(""); - ans=CmdSamples("20000"); - } - if (GraphTraceLen<1000) return 0; - PrintAndLog("NOTE: some demods output possible binary\n if it finds something that looks like a tag"); - PrintAndLog("Checking for known tags:"); + int ans=0; + if (!offline){ + ans=CmdLFRead(""); + ans=CmdSamples("20000"); + } + if (GraphTraceLen<1000) return 0; + PrintAndLog("NOTE: some demods output possible binary\n if it finds something that looks like a tag"); + PrintAndLog("Checking for known tags:"); - ans=Cmdaskmandemod(""); - if (ans>0) { - PrintAndLog("Valid EM410x ID Found!"); - return 1; - } - ans=CmdFSKdemodHID(""); - if (ans>0) { - PrintAndLog("Valid HID Prox ID Found!"); - return 1; - } - ans=CmdFSKdemodIO(""); - if (ans>0) { - PrintAndLog("Valid IO Prox ID Found!"); - return 1; - } - //add psk and indala - ans=CmdIndalaDecode(""); - if (ans>0) { - PrintAndLog("Valid Indala ID Found!"); - return 1; - } + ans=Cmdaskmandemod(""); + if (ans>0) { + PrintAndLog("Valid EM410x ID Found!"); + return 1; + } + ans=CmdFSKdemodHID(""); + if (ans>0) { + PrintAndLog("Valid HID Prox ID Found!"); + return 1; + } + ans=CmdFSKdemodIO(""); + if (ans>0) { + PrintAndLog("Valid IO Prox ID Found!"); + return 1; + } + //add psk and indala + ans=CmdIndalaDecode(""); + if (ans>0) { + PrintAndLog("Valid Indala ID Found!"); + return 1; + } // ans=CmdIndalaDemod("224"); // if (ans>0) return 1; - PrintAndLog("No Known Tags Found!\n"); - return 0; + PrintAndLog("No Known Tags Found!\n"); + return 0; } static command_t CommandTable[] = { - {"help", CmdHelp, 1, "This help"}, - {"cmdread", CmdLFCommandRead, 0, " <'0' period> <'1' period> ['h'] -- Modulate LF reader field to send command before read (all periods in microseconds) (option 'h' for 134)"}, - {"em4x", CmdLFEM4X, 1, "{ EM4X RFIDs... }"}, - {"flexdemod", CmdFlexdemod, 1, "Demodulate samples for FlexPass"}, - {"hid", CmdLFHID, 1, "{ HID RFIDs... }"}, - {"io", CmdLFIO, 1, "{ ioProx tags... }"}, - {"indalademod", CmdIndalaDemod, 1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"}, - {"indalaclone", CmdIndalaClone, 0, " ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"}, - {"read", CmdLFRead, 0, "['h' or ] -- Read 125/134 kHz LF ID-only tag (option 'h' for 134, alternatively: f=12MHz/(divisor+1))"}, - {"search", CmdLFfind, 1, "Read and Search for valid known tag (in offline mode it you can load first then search)"}, - {"sim", CmdLFSim, 0, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"}, - {"simbidir", CmdLFSimBidir, 0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"}, - {"simman", CmdLFSimManchester, 0, " [GAP] Simulate arbitrary Manchester LF tag"}, - {"snoop", CmdLFSnoop, 0, "['l'|'h'|] [trigger threshold]-- Snoop LF (l:125khz, h:134khz)"}, - {"ti", CmdLFTI, 1, "{ TI RFIDs... }"}, - {"hitag", CmdLFHitag, 1, "{ Hitag tags and transponders... }"}, - {"vchdemod", CmdVchDemod, 1, "['clone'] -- Demodulate samples for VeriChip"}, - {"t55xx", CmdLFT55XX, 1, "{ T55xx RFIDs... }"}, - {"pcf7931", CmdLFPCF7931, 1, "{PCF7931 RFIDs...}"}, - {NULL, NULL, 0, NULL} + {"help", CmdHelp, 1, "This help"}, + {"cmdread", CmdLFCommandRead, 0, " <'0' period> <'1' period> ['h'] -- Modulate LF reader field to send command before read (all periods in microseconds) (option 'h' for 134)"}, + {"em4x", CmdLFEM4X, 1, "{ EM4X RFIDs... }"}, + {"flexdemod", CmdFlexdemod, 1, "Demodulate samples for FlexPass"}, + {"hid", CmdLFHID, 1, "{ HID RFIDs... }"}, + {"io", CmdLFIO, 1, "{ ioProx tags... }"}, + {"indalademod", CmdIndalaDemod, 1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"}, + {"indalaclone", CmdIndalaClone, 0, " ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"}, + {"read", CmdLFRead, 0, "['h' or ] -- Read 125/134 kHz LF ID-only tag (option 'h' for 134, alternatively: f=12MHz/(divisor+1))"}, + {"search", CmdLFfind, 1, "Read and Search for valid known tag (in offline mode it you can load first then search)"}, + {"sim", CmdLFSim, 0, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"}, + {"simbidir", CmdLFSimBidir, 0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"}, + {"simman", CmdLFSimManchester, 0, " [GAP] Simulate arbitrary Manchester LF tag"}, + {"snoop", CmdLFSnoop, 0, "['l'|'h'|] [trigger threshold]-- Snoop LF (l:125khz, h:134khz)"}, + {"ti", CmdLFTI, 1, "{ TI RFIDs... }"}, + {"hitag", CmdLFHitag, 1, "{ Hitag tags and transponders... }"}, + {"vchdemod", CmdVchDemod, 1, "['clone'] -- Demodulate samples for VeriChip"}, + {"t55xx", CmdLFT55XX, 1, "{ T55xx RFIDs... }"}, + {"pcf7931", CmdLFPCF7931, 1, "{PCF7931 RFIDs...}"}, + {NULL, NULL, 0, NULL} }; int CmdLF(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; } diff --git a/client/graph.c b/client/graph.c index d63c42714..f41568e4f 100644 --- a/client/graph.c +++ b/client/graph.c @@ -20,61 +20,61 @@ int GraphTraceLen; /* write a bit to the graph */ void AppendGraph(int redraw, int clock, int bit) { - int i; + int i; - for (i = 0; i < (int)(clock / 2); ++i) - GraphBuffer[GraphTraceLen++] = bit ^ 1; - - for (i = (int)(clock / 2); i < clock; ++i) - GraphBuffer[GraphTraceLen++] = bit; + for (i = 0; i < (int)(clock / 2); ++i) + GraphBuffer[GraphTraceLen++] = bit ^ 1; - if (redraw) - RepaintGraphWindow(); + for (i = (int)(clock / 2); i < clock; ++i) + GraphBuffer[GraphTraceLen++] = bit; + + if (redraw) + RepaintGraphWindow(); } /* clear out our graph window */ int ClearGraph(int redraw) { - int gtl = GraphTraceLen; - GraphTraceLen = 0; + int gtl = GraphTraceLen; + GraphTraceLen = 0; - if (redraw) - RepaintGraphWindow(); + if (redraw) + RepaintGraphWindow(); - return gtl; + return gtl; } /* * Detect clock rate */ - //decommissioned - has difficulty detecting rf/32 + //decommissioned - has difficulty detecting rf/32 /* int DetectClockOld(int peak) { - int i; - int clock = 0xFFFF; - int lastpeak = 0; + int i; + int clock = 0xFFFF; + int lastpeak = 0; - // Detect peak if we don't have one - if (!peak) - for (i = 0; i < GraphTraceLen; ++i) - if (GraphBuffer[i] > peak) - peak = GraphBuffer[i]; + // Detect peak if we don't have one + if (!peak) + for (i = 0; i < GraphTraceLen; ++i) + if (GraphBuffer[i] > peak) + peak = GraphBuffer[i]; // peak=(int)(peak*.75); - for (i = 1; i < GraphTraceLen; ++i) - { - // If this is the beginning of a peak - if (GraphBuffer[i - 1] != GraphBuffer[i] && GraphBuffer[i] >= peak) - { - // Find lowest difference between peaks - if (lastpeak && i - lastpeak < clock) - clock = i - lastpeak; - lastpeak = i; - } - } + for (i = 1; i < GraphTraceLen; ++i) + { + // If this is the beginning of a peak + if (GraphBuffer[i - 1] != GraphBuffer[i] && GraphBuffer[i] >= peak) + { + // Find lowest difference between peaks + if (lastpeak && i - lastpeak < clock) + clock = i - lastpeak; + lastpeak = i; + } + } - return clock; + return clock; } */ /* @@ -85,155 +85,155 @@ NOW IN LFDEMOD.C // maybe somehow adjust peak trimming value based on samples to fix? int DetectASKClock(int peak) { - int i=0; - int low=0; - int clk[]={16,32,40,50,64,100,128,256}; - int loopCnt = 256; - if (GraphTraceLenpeak){ - peak = GraphBuffer[i]; - } - if(GraphBuffer[i]=peak) || (GraphBuffer[ii]<=low)){ - errCnt[clkCnt]=0; - for (i=0; i<((int)(GraphTraceLen/clk[clkCnt])-1); ++i){ - if (GraphBuffer[ii+(i*clk[clkCnt])]>=peak || GraphBuffer[ii+(i*clk[clkCnt])]<=low){ - }else if(GraphBuffer[ii+(i*clk[clkCnt])-tol]>=peak || GraphBuffer[ii+(i*clk[clkCnt])-tol]<=low){ - }else if(GraphBuffer[ii+(i*clk[clkCnt])+tol]>=peak || GraphBuffer[ii+(i*clk[clkCnt])+tol]<=low){ - }else{ //error no peak detected - errCnt[clkCnt]++; - } - } - if(errCnt[clkCnt]==0) return clk[clkCnt]; - if(errCnt[clkCnt]peak){ + peak = GraphBuffer[i]; + } + if(GraphBuffer[i]=peak) || (GraphBuffer[ii]<=low)){ + errCnt[clkCnt]=0; + for (i=0; i<((int)(GraphTraceLen/clk[clkCnt])-1); ++i){ + if (GraphBuffer[ii+(i*clk[clkCnt])]>=peak || GraphBuffer[ii+(i*clk[clkCnt])]<=low){ + }else if(GraphBuffer[ii+(i*clk[clkCnt])-tol]>=peak || GraphBuffer[ii+(i*clk[clkCnt])-tol]<=low){ + }else if(GraphBuffer[ii+(i*clk[clkCnt])+tol]>=peak || GraphBuffer[ii+(i*clk[clkCnt])+tol]<=low){ + }else{ //error no peak detected + errCnt[clkCnt]++; + } + } + if(errCnt[clkCnt]==0) return clk[clkCnt]; + if(errCnt[clkCnt]127) GraphBuffer[i]=127; //trim - if (GraphBuffer[i]<-127) GraphBuffer[i]=-127; //trim - buff[i]=(uint8_t)(GraphBuffer[i]+128); - } - return i; + uint32_t i; + for (i=0;i127) GraphBuffer[i]=127; //trim + if (GraphBuffer[i]<-127) GraphBuffer[i]=-127; //trim + buff[i]=(uint8_t)(GraphBuffer[i]+128); + } + return i; } /* Get or auto-detect clock rate */ int GetClock(const char *str, int peak, int verbose) { - int clock; + int clock; // int clock2; - sscanf(str, "%i", &clock); - if (!strcmp(str, "")) - clock = 0; + sscanf(str, "%i", &clock); + if (!strcmp(str, "")) + clock = 0; - /* Auto-detect clock */ - if (!clock) - { - uint8_t grph[MAX_GRAPH_TRACE_LEN]={0}; - int size = getFromGraphBuf(grph); - clock = DetectASKClock(grph,size,0); - //clock2 = DetectClock2(peak); - /* Only print this message if we're not looping something */ - if (!verbose){ - PrintAndLog("Auto-detected clock rate: %d", clock); - //PrintAndLog("clock2: %d",clock2); - } - } + /* Auto-detect clock */ + if (!clock) + { + uint8_t grph[MAX_GRAPH_TRACE_LEN]={0}; + size_t size = getFromGraphBuf(grph); + clock = DetectASKClock(grph,size,0); + //clock2 = DetectClock2(peak); + /* Only print this message if we're not looping something */ + if (!verbose){ + PrintAndLog("Auto-detected clock rate: %d", clock); + //PrintAndLog("clock2: %d",clock2); + } + } - return clock; + return clock; } int GetNRZpskClock(const char *str, int peak, int verbose) { // return GetClock(str,peak,verbose); - int clock; - // int clock2; - sscanf(str, "%i", &clock); - if (!strcmp(str, "")) - clock = 0; + int clock; + // int clock2; + sscanf(str, "%i", &clock); + if (!strcmp(str, "")) + clock = 0; - /* Auto-detect clock */ - if (!clock) - { - uint8_t grph[MAX_GRAPH_TRACE_LEN]={0}; - int size = getFromGraphBuf(grph); - clock = DetectpskNRZClock(grph,size,0); - //clock2 = DetectClock2(peak); - /* Only print this message if we're not looping something */ - if (!verbose){ - PrintAndLog("Auto-detected clock rate: %d", clock); - //PrintAndLog("clock2: %d",clock2); - } - } - return clock; + /* Auto-detect clock */ + if (!clock) + { + uint8_t grph[MAX_GRAPH_TRACE_LEN]={0}; + size_t size = getFromGraphBuf(grph); + clock = DetectpskNRZClock(grph,size,0); + //clock2 = DetectClock2(peak); + /* Only print this message if we're not looping something */ + if (!verbose){ + PrintAndLog("Auto-detected clock rate: %d", clock); + //PrintAndLog("clock2: %d",clock2); + } + } + return clock; } -// Get or auto-detect clock rate +// Get or auto-detect clock rate /* int GetNRZpskClock(const char *str, int peak, int verbose) { - int clock; + int clock; // int clock2; - sscanf(str, "%i", &clock); - if (!strcmp(str, "")) - clock = 0; + sscanf(str, "%i", &clock); + if (!strcmp(str, "")) + clock = 0; - // Auto-detect clock - if (!clock) - { - uint8_t grph[MAX_GRAPH_TRACE_LEN]={0}; - int size = getFromGraphBuf(grph); - clock = DetectASKClock(grph,size,0); - //clock2 = DetectClock2(peak); - // Only print this message if we're not looping something - if (!verbose){ - PrintAndLog("Auto-detected clock rate: %d", clock); - //PrintAndLog("clock2: %d",clock2); - } - } - return clock; + // Auto-detect clock + if (!clock) + { + uint8_t grph[MAX_GRAPH_TRACE_LEN]={0}; + int size = getFromGraphBuf(grph); + clock = DetectASKClock(grph,size,0); + //clock2 = DetectClock2(peak); + // Only print this message if we're not looping something + if (!verbose){ + PrintAndLog("Auto-detected clock rate: %d", clock); + //PrintAndLog("clock2: %d",clock2); + } + } + return clock; } -*/ \ No newline at end of file +*/ diff --git a/client/graph.h b/client/graph.h index c5c137986..1abeeb25a 100644 --- a/client/graph.h +++ b/client/graph.h @@ -15,10 +15,10 @@ void AppendGraph(int redraw, int clock, int bit); int ClearGraph(int redraw); //int DetectClock(int peak); -int getFromGraphBuf(uint8_t *buff); +size_t getFromGraphBuf(uint8_t *buff); int GetClock(const char *str, int peak, int verbose); int GetNRZpskClock(const char *str, int peak, int verbose); -void setGraphBuf(uint8_t *buff,int size); +void setGraphBuf(uint8_t *buff, size_t size); #define MAX_GRAPH_TRACE_LEN (1024*128) extern int GraphBuffer[MAX_GRAPH_TRACE_LEN]; diff --git a/common/lfdemod.c b/common/lfdemod.c index 144783198..11ba131b0 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -1,5 +1,5 @@ //----------------------------------------------------------------------------- -// Copyright (C) 2014 +// Copyright (C) 2014 // // 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 @@ -14,589 +14,588 @@ //by marshmellow //takes 1s and 0s and searches for EM410x format - output EM ID -uint64_t Em410xDecode(uint8_t *BitStream,uint32_t BitLen) +uint64_t Em410xDecode(uint8_t *BitStream, size_t size) { - //no arguments needed - built this way in case we want this to be a direct call from "data " cmds in the future - // otherwise could be a void with no arguments - //set defaults - int high=0, low=128; - uint64_t lo=0; //hi=0, + //no arguments needed - built this way in case we want this to be a direct call from "data " cmds in the future + // otherwise could be a void with no arguments + //set defaults + int high=0, low=128; + uint64_t lo=0; //hi=0, - uint32_t i = 0; - uint32_t initLoopMax = 65; - if (initLoopMax>BitLen) initLoopMax=BitLen; + uint32_t i = 0; + uint32_t initLoopMax = 65; + if (initLoopMax>size) initLoopMax=size; - for (;i < initLoopMax; ++i) //65 samples should be plenty to find high and low values - { - if (BitStream[i] > high) - high = BitStream[i]; - else if (BitStream[i] < low) - low = BitStream[i]; - } - if (((high !=1)||(low !=0))){ //allow only 1s and 0s - // PrintAndLog("no data found"); - return 0; - } - uint8_t parityTest=0; - // 111111111 bit pattern represent start of frame - uint8_t frame_marker_mask[] = {1,1,1,1,1,1,1,1,1}; - uint32_t idx = 0; - uint32_t ii=0; - uint8_t resetCnt = 0; - while( (idx + 64) < BitLen) { -restart: - // search for a start of frame marker - if ( memcmp(BitStream+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) - { // frame marker found - idx+=9;//sizeof(frame_marker_mask); - for (i=0; i<10;i++){ - for(ii=0; ii<5; ++ii){ - parityTest += BitStream[(i*5)+ii+idx]; - } - if (parityTest== ((parityTest>>1)<<1)){ - parityTest=0; - for (ii=0; ii<4;++ii){ - //hi = (hi<<1)|(lo>>31); - lo=(lo<<1LL)|(BitStream[(i*5)+ii+idx]); - } - //PrintAndLog("DEBUG: EM parity passed parity val: %d, i:%d, ii:%d,idx:%d, Buffer: %d%d%d%d%d,lo: %d",parityTest,i,ii,idx,BitStream[idx+ii+(i*5)-5],BitStream[idx+ii+(i*5)-4],BitStream[idx+ii+(i*5)-3],BitStream[idx+ii+(i*5)-2],BitStream[idx+ii+(i*5)-1],lo); - }else {//parity failed - //PrintAndLog("DEBUG: EM parity failed parity val: %d, i:%d, ii:%d,idx:%d, Buffer: %d%d%d%d%d",parityTest,i,ii,idx,BitStream[idx+ii+(i*5)-5],BitStream[idx+ii+(i*5)-4],BitStream[idx+ii+(i*5)-3],BitStream[idx+ii+(i*5)-2],BitStream[idx+ii+(i*5)-1]); - parityTest=0; - idx-=8; - if (resetCnt>5)return 0; - resetCnt++; - goto restart;//continue; - } - } - //skip last 5 bit parity test for simplicity. - return lo; - }else{ - idx++; - } - } - return 0; + for (;i < initLoopMax; ++i) //65 samples should be plenty to find high and low values + { + if (BitStream[i] > high) + high = BitStream[i]; + else if (BitStream[i] < low) + low = BitStream[i]; + } + if (((high !=1)||(low !=0))){ //allow only 1s and 0s + // PrintAndLog("no data found"); + return 0; + } + uint8_t parityTest=0; + // 111111111 bit pattern represent start of frame + uint8_t frame_marker_mask[] = {1,1,1,1,1,1,1,1,1}; + uint32_t idx = 0; + uint32_t ii=0; + uint8_t resetCnt = 0; + while( (idx + 64) < size) { + restart: + // search for a start of frame marker + if ( memcmp(BitStream+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) + { // frame marker found + idx+=9;//sizeof(frame_marker_mask); + for (i=0; i<10;i++){ + for(ii=0; ii<5; ++ii){ + parityTest += BitStream[(i*5)+ii+idx]; + } + if (parityTest== ((parityTest>>1)<<1)){ + parityTest=0; + for (ii=0; ii<4;++ii){ + //hi = (hi<<1)|(lo>>31); + lo=(lo<<1LL)|(BitStream[(i*5)+ii+idx]); + } + //PrintAndLog("DEBUG: EM parity passed parity val: %d, i:%d, ii:%d,idx:%d, Buffer: %d%d%d%d%d,lo: %d",parityTest,i,ii,idx,BitStream[idx+ii+(i*5)-5],BitStream[idx+ii+(i*5)-4],BitStream[idx+ii+(i*5)-3],BitStream[idx+ii+(i*5)-2],BitStream[idx+ii+(i*5)-1],lo); + }else {//parity failed + //PrintAndLog("DEBUG: EM parity failed parity val: %d, i:%d, ii:%d,idx:%d, Buffer: %d%d%d%d%d",parityTest,i,ii,idx,BitStream[idx+ii+(i*5)-5],BitStream[idx+ii+(i*5)-4],BitStream[idx+ii+(i*5)-3],BitStream[idx+ii+(i*5)-2],BitStream[idx+ii+(i*5)-1]); + parityTest=0; + idx-=8; + if (resetCnt>5)return 0; + resetCnt++; + goto restart;//continue; + } + } + //skip last 5 bit parity test for simplicity. + return lo; + }else{ + idx++; + } + } + return 0; } //by marshmellow //takes 2 arguments - clock and invert both as integers -//attempts to demodulate ask while decoding manchester +//attempts to demodulate ask while decoding manchester //prints binary found and saves in graphbuffer for further commands -int askmandemod(uint8_t * BinStream,uint32_t *BitLen,int *clk, int *invert) +int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert) { - int i; - int high = 0, low = 128; - *clk=DetectASKClock(BinStream,(size_t)*BitLen,*clk); //clock default + int i; + int high = 0, low = 128; + *clk=DetectASKClock(BinStream, *size, *clk); //clock default - if (*clk<8) *clk =64; - if (*clk<32) *clk=32; - if (*invert != 0 && *invert != 1) *invert=0; - uint32_t initLoopMax = 200; - if (initLoopMax>*BitLen) initLoopMax=*BitLen; - // Detect high and lows - for (i = 0; i < initLoopMax; ++i) //200 samples should be enough to find high and low values - { - if (BinStream[i] > high) - high = BinStream[i]; - else if (BinStream[i] < low) - low = BinStream[i]; - } - if ((high < 158) ){ //throw away static - //PrintAndLog("no data found"); - return -2; - } - //25% fuzz in case highs and lows aren't clipped [marshmellow] - high=(int)((high-128)*.75)+128; - low= (int)((low-128)*.75)+128; + if (*clk<8) *clk =64; + if (*clk<32) *clk=32; + if (*invert != 0 && *invert != 1) *invert=0; + uint32_t initLoopMax = 200; + if (initLoopMax > *size) initLoopMax=*size; + // Detect high and lows + for (i = 0; i < initLoopMax; ++i) //200 samples should be enough to find high and low values + { + if (BinStream[i] > high) + high = BinStream[i]; + else if (BinStream[i] < low) + low = BinStream[i]; + } + if ((high < 158) ){ //throw away static + //PrintAndLog("no data found"); + return -2; + } + //25% fuzz in case highs and lows aren't clipped [marshmellow] + high=(int)((high-128)*.75)+128; + low= (int)((low-128)*.75)+128; - //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); - int lastBit = 0; //set first clock check - uint32_t bitnum = 0; //output counter - int 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 - int iii = 0; - uint32_t gLen = *BitLen; - if (gLen > 3000) gLen=3000; - uint8_t errCnt =0; - uint32_t bestStart = *BitLen; - uint32_t bestErrCnt = (*BitLen/1000); - uint32_t maxErr = (*BitLen/1000); - //PrintAndLog("DEBUG - lastbit - %d",lastBit); - //loop to find first wave that works - for (iii=0; iii < gLen; ++iii){ - if ((BinStream[iii]>=high)||(BinStream[iii]<=low)){ - lastBit=iii-*clk; - errCnt=0; - //loop through to see if this start location works - for (i = iii; i < *BitLen; ++i) { - if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){ - lastBit+=*clk; - } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ - //low found and we are expecting a bar - lastBit+=*clk; - } else { - //mid value found or no bar supposed to be here - if ((i-lastBit)>(*clk+tol)){ - //should have hit a high or low based on clock!! + //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); + int lastBit = 0; //set first clock check + uint32_t bitnum = 0; //output counter + int 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 + int iii = 0; + uint32_t gLen = *size; + if (gLen > 3000) gLen=3000; + uint8_t errCnt =0; + uint32_t bestStart = *size; + uint32_t bestErrCnt = (*size/1000); + uint32_t maxErr = (*size/1000); + //PrintAndLog("DEBUG - lastbit - %d",lastBit); + //loop to find first wave that works + for (iii=0; iii < gLen; ++iii){ + if ((BinStream[iii] >= high) || (BinStream[iii] <= low)){ + lastBit=iii-*clk; + errCnt=0; + //loop through to see if this start location works + for (i = iii; i < *size; ++i) { + if ((BinStream[i] >= high) && ((i-lastBit) > (*clk-tol))){ + lastBit+=*clk; + } else if ((BinStream[i] <= low) && ((i-lastBit) > (*clk-tol))){ + //low found and we are expecting a bar + lastBit+=*clk; + } else { + //mid value found or no bar supposed to be here + if ((i-lastBit)>(*clk+tol)){ + //should have hit a high or low based on clock!! - //debug - //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); + //debug + //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; //allow 1 error for every 1000 samples else start over - } - } - if ((i-iii) >(400 * *clk)) break; //got plenty of bits - } - //we got more than 64 good bits and not all errors - if ((((i-iii)/ *clk) > (64+errCnt)) && (errCnt= high) && ((i-lastBit)>(*clk-tol))){ - lastBit+=*clk; - BinStream[bitnum] = *invert; - bitnum++; - } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ - //low found and we are expecting a bar - lastBit+=*clk; - BinStream[bitnum] = 1-*invert; - bitnum++; - } else { - //mid value found or no bar supposed to be here - if ((i-lastBit)>(*clk+tol)){ - //should have hit a high or low based on clock!! + errCnt++; + lastBit+=*clk;//skip over until hit too many errors + if (errCnt>(maxErr)) break; //allow 1 error for every 1000 samples else start over + } + } + if ((i-iii) >(400 * *clk)) break; //got plenty of bits + } + //we got more than 64 good bits and not all errors + if ((((i-iii)/ *clk) > (64+errCnt)) && (errCnt= high) && ((i-lastBit) > (*clk-tol))){ + lastBit += *clk; + BinStream[bitnum] = *invert; + bitnum++; + } else if ((BinStream[i] <= low) && ((i-lastBit) > (*clk-tol))){ + //low found and we are expecting a bar + lastBit+=*clk; + BinStream[bitnum] = 1-*invert; + bitnum++; + } else { + //mid value found or no bar supposed to be here + if ((i-lastBit)>(*clk+tol)){ + //should have hit a high or low based on clock!! - //debug - //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; - bitnum++; - } + //debug + //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; + bitnum++; + } - lastBit+=*clk;//skip over error - } - } - if (bitnum >=400) break; - } - *BitLen=bitnum; - } else{ - *invert=bestStart; - *clk=iii; - return -1; - } - return bestErrCnt; + lastBit+=*clk;//skip over error + } + } + if (bitnum >=400) break; + } + *size=bitnum; + } else{ + *invert=bestStart; + *clk=iii; + return -1; + } + return bestErrCnt; } //by marshmellow //take 10 and 01 and manchester decode //run through 2 times and take least errCnt -int manrawdecode(uint8_t * BitStream, int *bitLen) +int manrawdecode(uint8_t * BitStream, size_t *size) { - int bitnum=0; - int errCnt =0; - int i=1; - int bestErr = 1000; - int bestRun = 0; - int ii=1; - for (ii=1;ii<3;++ii){ - i=1; - for (i=i+ii;i<*bitLen-2;i+=2){ - if(BitStream[i]==1 && (BitStream[i+1]==0)){ - } else if((BitStream[i]==0)&& BitStream[i+1]==1){ - } else { - errCnt++; - } - if(bitnum>300) break; - } - if (bestErr>errCnt){ - bestErr=errCnt; - bestRun=ii; - } - errCnt=0; - } - errCnt=bestErr; - if (errCnt<20){ - ii=bestRun; - i=1; - for (i=i+ii;i<*bitLen-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; - //errCnt++; - } - if(bitnum>300) break; - } - *bitLen=bitnum; - } - return errCnt; + int bitnum=0; + int errCnt =0; + int i=1; + int bestErr = 1000; + int bestRun = 0; + int ii=1; + for (ii=1;ii<3;++ii){ + i=1; + for (i=i+ii;i<*size-2;i+=2){ + if(BitStream[i]==1 && (BitStream[i+1]==0)){ + } else if((BitStream[i]==0)&& BitStream[i+1]==1){ + } else { + errCnt++; + } + if(bitnum>300) break; + } + if (bestErr>errCnt){ + bestErr=errCnt; + bestRun=ii; + } + errCnt=0; + } + errCnt=bestErr; + if (errCnt<20){ + ii=bestRun; + i=1; + for (i=i+ii;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; + //errCnt++; + } + if(bitnum>300) break; + } + *size=bitnum; + } + return errCnt; } //by marshmellow //take 01 or 10 = 0 and 11 or 00 = 1 -int BiphaseRawDecode(uint8_t * BitStream, int *bitLen, int offset) +int BiphaseRawDecode(uint8_t *BitStream, size_t *size, int offset) { - uint8_t bitnum=0; - uint32_t errCnt =0; - uint32_t i=1; - i=offset; - for (;i<*bitLen-2;i+=2){ - if((BitStream[i]==1 && BitStream[i+1]==0)||(BitStream[i]==0 && BitStream[i+1]==1)){ - BitStream[bitnum++]=1; - } else if((BitStream[i]==0 && BitStream[i+1]==0)||(BitStream[i]==1 && BitStream[i+1]==1)){ - BitStream[bitnum++]=0; - } else { - BitStream[bitnum++]=77; - errCnt++; - } - if(bitnum>250) break; - } - *bitLen=bitnum; - return errCnt; + uint8_t bitnum=0; + uint32_t errCnt =0; + uint32_t i=1; + i=offset; + for (;i<*size-2;i+=2){ + if((BitStream[i]==1 && BitStream[i+1]==0) || (BitStream[i]==0 && BitStream[i+1]==1)){ + BitStream[bitnum++]=1; + } else if((BitStream[i]==0 && BitStream[i+1]==0) || (BitStream[i]==1 && BitStream[i+1]==1)){ + BitStream[bitnum++]=0; + } else { + BitStream[bitnum++]=77; + errCnt++; + } + if(bitnum>250) break; + } + *size=bitnum; + return errCnt; } //by marshmellow //takes 2 arguments - clock and invert both as integers //attempts to demodulate ask only //prints binary found and saves in graphbuffer for further commands -int askrawdemod(uint8_t *BinStream, int *bitLen,int *clk, int *invert) +int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert) { - uint32_t i; - // int invert=0; //invert default - int high = 0, low = 128; - *clk=DetectASKClock(BinStream,*bitLen,*clk); //clock default - uint8_t BitStream[502] = {0}; + uint32_t i; + // int invert=0; //invert default + int high = 0, low = 128; + *clk=DetectASKClock(BinStream, *size, *clk); //clock default + uint8_t BitStream[502] = {0}; - if (*clk<8) *clk =64; - if (*clk<32) *clk=32; - if (*invert != 0 && *invert != 1) *invert =0; - uint32_t initLoopMax = 200; - if (initLoopMax>*bitLen) initLoopMax=*bitLen; - // Detect high and lows - for (i = 0; i < initLoopMax; ++i) //200 samples should be plenty to find high and low values - { - if (BinStream[i] > high) - high = BinStream[i]; - else if (BinStream[i] < low) - low = BinStream[i]; - } - if ((high < 158)){ //throw away static - // PrintAndLog("no data found"); - return -2; - } - //25% fuzz in case highs and lows aren't clipped [marshmellow] - high=(int)((high-128)*.75)+128; - low= (int)((low-128)*.75)+128; + if (*clk<8) *clk =64; + if (*clk<32) *clk=32; + if (*invert != 0 && *invert != 1) *invert =0; + uint32_t initLoopMax = 200; + if (initLoopMax>*size) initLoopMax=*size; + // Detect high and lows + for (i = 0; i < initLoopMax; ++i) //200 samples should be plenty to find high and low values + { + if (BinStream[i] > high) + high = BinStream[i]; + else if (BinStream[i] < low) + low = BinStream[i]; + } + if ((high < 158)){ //throw away static + // PrintAndLog("no data found"); + return -2; + } + //25% fuzz in case highs and lows aren't clipped [marshmellow] + high=(int)((high-128)*.75)+128; + low= (int)((low-128)*.75)+128; - //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); - int lastBit = 0; //set first clock check - uint32_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 - uint32_t iii = 0; - uint32_t gLen = *bitLen; - if (gLen > 500) gLen=500; - uint8_t errCnt =0; - uint32_t bestStart = *bitLen; - uint32_t bestErrCnt = (*bitLen/1000); - uint8_t midBit=0; - //PrintAndLog("DEBUG - lastbit - %d",lastBit); - //loop to find first wave that works - for (iii=0; iii < gLen; ++iii){ - if ((BinStream[iii]>=high)||(BinStream[iii]<=low)){ - lastBit=iii-*clk; - //loop through to see if this start location works - for (i = iii; i < *bitLen; ++i) { - if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){ - lastBit+=*clk; - BitStream[bitnum] = *invert; - bitnum++; - midBit=0; - } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ - //low found and we are expecting a bar - lastBit+=*clk; - BitStream[bitnum] = 1-*invert; - bitnum++; - midBit=0; - } else if ((BinStream[i]<=low) && (midBit==0) && ((i-lastBit)>((*clk/2)-tol))){ - //mid bar? - midBit=1; - BitStream[bitnum]= 1-*invert; - bitnum++; - } else if ((BinStream[i]>=high)&&(midBit==0) && ((i-lastBit)>((*clk/2)-tol))){ - //mid bar? - midBit=1; - BitStream[bitnum]= *invert; - bitnum++; - } else if ((i-lastBit)>((*clk/2)+tol)&&(midBit==0)){ - //no mid bar found - midBit=1; - BitStream[bitnum]= BitStream[bitnum-1]; - bitnum++; - } else { - //mid value found or no bar supposed to be here + //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); + int lastBit = 0; //set first clock check + uint32_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 + uint32_t iii = 0; + uint32_t gLen = *size; + if (gLen > 500) gLen=500; + uint8_t errCnt =0; + uint32_t bestStart = *size; + uint32_t bestErrCnt = (*size/1000); + uint8_t midBit=0; + //PrintAndLog("DEBUG - lastbit - %d",lastBit); + //loop to find first wave that works + for (iii=0; iii < gLen; ++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 ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){ + lastBit+=*clk; + BitStream[bitnum] = *invert; + bitnum++; + midBit=0; + } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ + //low found and we are expecting a bar + lastBit+=*clk; + BitStream[bitnum] = 1- *invert; + bitnum++; + midBit=0; + } else if ((BinStream[i]<=low) && (midBit==0) && ((i-lastBit)>((*clk/2)-tol))){ + //mid bar? + midBit=1; + BitStream[bitnum]= 1- *invert; + bitnum++; + } else if ((BinStream[i]>=high) && (midBit==0) && ((i-lastBit)>((*clk/2)-tol))){ + //mid bar? + midBit=1; + BitStream[bitnum]= *invert; + bitnum++; + } else if ((i-lastBit)>((*clk/2)+tol) && (midBit==0)){ + //no mid bar found + midBit=1; + BitStream[bitnum]= BitStream[bitnum-1]; + bitnum++; + } else { + //mid value found or no bar supposed to be here - if ((i-lastBit)>(*clk+tol)){ - //should have hit a high or low based on clock!! - //debug - //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){ - BitStream[bitnum]=77; - bitnum++; - } + if ((i-lastBit)>(*clk+tol)){ + //should have hit a high or low based on clock!! + //debug + //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){ + BitStream[bitnum]=77; + bitnum++; + } - errCnt++; - lastBit+=*clk;//skip over until hit too many errors - if (errCnt>((*bitLen/1000))){ //allow 1 error for every 1000 samples else start over - errCnt=0; - bitnum=0;//start over - break; - } - } - } - if (bitnum>500) break; - } - //we got more than 64 good bits and not all errors - if ((bitnum > (64+errCnt)) && (errCnt<(*bitLen/1000))) { - //possible good read - if (errCnt==0) break; //great read - finish - if (bestStart == iii) break; //if current run == bestErrCnt run (after exhausted testing) then finish - if (errCnt=gLen){ //exhausted test - //if there was a ok test go back to that one and re-run the best run (then dump after that run) - if (bestErrCnt < (*bitLen/1000)) iii=bestStart; - } - } - if (bitnum>16){ + errCnt++; + lastBit+=*clk;//skip over until hit too many errors + if (errCnt > ((*size/1000))){ //allow 1 error for every 1000 samples else start over + errCnt=0; + bitnum=0;//start over + break; + } + } + } + if (bitnum>500) break; + } + //we got more than 64 good bits and not all errors + if ((bitnum > (64+errCnt)) && (errCnt<(*size/1000))) { + //possible good read + if (errCnt==0) break; //great read - finish + if (bestStart == iii) break; //if current run == bestErrCnt run (after exhausted testing) then finish + if (errCnt=gLen){ //exhausted test + //if there was a ok test go back to that one and re-run the best run (then dump after that run) + if (bestErrCnt < (*size/1000)) iii=bestStart; + } + } + if (bitnum>16){ - // PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum); - //move BitStream back to BinStream - // ClearGraph(0); - for (i=0; i < bitnum; ++i){ - BinStream[i]=BitStream[i]; - } - *bitLen=bitnum; - // RepaintGraphWindow(); - //output - // if (errCnt>0){ - // PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); - // } - // PrintAndLog("ASK decoded bitstream:"); - // Now output the bitstream to the scrollback by line of 16 bits - // printBitStream2(BitStream,bitnum); - //int errCnt=0; - //errCnt=manrawdemod(BitStream,bitnum); + // PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum); + //move BitStream back to BinStream + // ClearGraph(0); + for (i=0; i < bitnum; ++i){ + BinStream[i]=BitStream[i]; + } + *size=bitnum; + // RepaintGraphWindow(); + //output + // if (errCnt>0){ + // PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); + // } + // PrintAndLog("ASK decoded bitstream:"); + // Now output the bitstream to the scrollback by line of 16 bits + // printBitStream2(BitStream,bitnum); + //int errCnt=0; + //errCnt=manrawdemod(BitStream,bitnum); - // Em410xDecode(Cmd); - } else return -1; - return errCnt; + // Em410xDecode(Cmd); + } else return -1; + return errCnt; } -//translate wave to 11111100000 (1 for each short wave 0 for each long wave) +//translate wave to 11111100000 (1 for each short wave 0 for each long wave) size_t fsk_wave_demod(uint8_t * dest, size_t size, uint8_t fchigh, uint8_t fclow) { - uint32_t last_transition = 0; - uint32_t idx = 1; - uint32_t maxVal=0; - if (fchigh==0) fchigh=10; - if (fclow==0) fclow=8; - // we do care about the actual theshold value as sometimes near the center of the - // wave we may get static that changes direction of wave for one value - // if our value is too low it might affect the read. and if our tag or - // antenna is weak a setting too high might not see anything. [marshmellow] - if (size<100) return 0; - for(idx=1; idx<100; idx++){ - if(maxVal1 transition - if (dest[idx-1] < dest[idx]) { // 0 -> 1 transition - if ((idx-last_transition)<(fclow-2)){ //0-5 = garbage noise - //do nothing with extra garbage - } else if ((idx-last_transition) < (fchigh-1)) { //6-8 = 8 waves - dest[numBits]=1; - } else { //9+ = 10 waves - dest[numBits]=0; - } - last_transition = idx; - numBits++; - } - } - return numBits; //Actually, it returns the number of bytes, but each byte represents a bit: 1 or 0 + // Check for 0->1 transition + if (dest[idx-1] < dest[idx]) { // 0 -> 1 transition + if ((idx-last_transition)<(fclow-2)){ //0-5 = garbage noise + //do nothing with extra garbage + } else if ((idx-last_transition) < (fchigh-1)) { //6-8 = 8 waves + dest[numBits]=1; + } else { //9+ = 10 waves + dest[numBits]=0; + } + last_transition = idx; + numBits++; + } + } + return numBits; //Actually, it returns the number of bytes, but each byte represents a bit: 1 or 0 } uint32_t myround2(float f) { - if (f >= 2000) return 2000;//something bad happened - return (uint32_t) (f + (float)0.5); + if (f >= 2000) return 2000;//something bad happened + return (uint32_t) (f + (float)0.5); } -//translate 11111100000 to 10 -size_t aggregate_bits(uint8_t *dest,size_t size, uint8_t rfLen, uint8_t maxConsequtiveBits, uint8_t invert,uint8_t fchigh,uint8_t fclow )// uint8_t h2l_crossing_value,uint8_t l2h_crossing_value, +//translate 11111100000 to 10 +size_t aggregate_bits(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t maxConsequtiveBits, + uint8_t invert, uint8_t fchigh, uint8_t fclow) { - uint8_t lastval=dest[0]; - uint32_t idx=0; - size_t numBits=0; - uint32_t n=1; + uint8_t lastval=dest[0]; + uint32_t idx=0; + size_t numBits=0; + uint32_t n=1; - for( idx=1; idx < size; idx++) { + for( idx=1; idx < size; idx++) { - if (dest[idx]==lastval) { - n++; - continue; - } - //if lastval was 1, we have a 1->0 crossing - if ( dest[idx-1]==1 ) { - n=myround2((float)(n+1)/((float)(rfLen)/(float)fclow)); - //n=(n+1) / h2l_crossing_value; - } else {// 0->1 crossing - n=myround2((float)(n+1)/((float)(rfLen-2)/(float)fchigh)); //-2 for fudge factor - //n=(n+1) / l2h_crossing_value; - } - if (n == 0) n = 1; + if (dest[idx]==lastval) { + n++; + continue; + } + //if lastval was 1, we have a 1->0 crossing + if ( dest[idx-1]==1 ) { + n=myround2((float)(n+1)/((float)(rfLen)/(float)fclow)); + //n=(n+1) / h2l_crossing_value; + } else {// 0->1 crossing + n=myround2((float)(n+1)/((float)(rfLen-2)/(float)fchigh)); //-2 for fudge factor + //n=(n+1) / l2h_crossing_value; + } + if (n == 0) n = 1; - if(n < maxConsequtiveBits) //Consecutive - { - if(invert==0){ //invert bits - memset(dest+numBits, dest[idx-1] , n); - }else{ - memset(dest+numBits, dest[idx-1]^1 , n); - } - numBits += n; - } - n=0; - lastval=dest[idx]; - }//end for - return numBits; + if(n < maxConsequtiveBits) //Consecutive + { + if(invert==0){ //invert bits + memset(dest+numBits, dest[idx-1] , n); + }else{ + memset(dest+numBits, dest[idx-1]^1 , n); + } + numBits += n; + } + n=0; + lastval=dest[idx]; + }//end for + return numBits; } //by marshmellow (from holiman's base) // full fsk demod from GraphBuffer wave to decoded 1s and 0s (no mandemod) int fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uint8_t fchigh, uint8_t fclow) { - // FSK demodulator - size = fsk_wave_demod(dest, size, fchigh, fclow); - size = aggregate_bits(dest, size,rfLen,192,invert,fchigh,fclow); - return size; + // FSK demodulator + size = fsk_wave_demod(dest, size, fchigh, fclow); + size = aggregate_bits(dest, size, rfLen, 192, invert, fchigh, fclow); + return size; } // loop to get raw HID waveform then FSK demodulate the TAG ID from it int HIDdemodFSK(uint8_t *dest, size_t size, uint32_t *hi2, uint32_t *hi, uint32_t *lo) { - size_t idx=0; //, found=0; //size=0, - // FSK demodulator - size = fskdemod(dest, size,50,0,10,8); + size_t idx=0; //, found=0; //size=0, + // FSK demodulator + size = fskdemod(dest, size,50,0,10,8); - // final loop, go over previously decoded manchester data and decode into usable tag ID - // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0 - uint8_t frame_marker_mask[] = {1,1,1,0,0,0}; - int numshifts = 0; - idx = 0; - //one scan - while( idx + sizeof(frame_marker_mask) < size) { - // search for a start of frame marker - if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) - { // frame marker found - idx+=sizeof(frame_marker_mask); - while(dest[idx] != dest[idx+1] && idx < size-2) - { - // Keep going until next frame marker (or error) - // Shift in a bit. Start by shifting high registers - *hi2 = (*hi2<<1)|(*hi>>31); - *hi = (*hi<<1)|(*lo>>31); - //Then, shift in a 0 or one into low - if (dest[idx] && !dest[idx+1]) // 1 0 - *lo=(*lo<<1)|0; - else // 0 1 - *lo=(*lo<<1)|1; - numshifts++; - idx += 2; - } - // Hopefully, we read a tag and hit upon the next frame marker - if(idx + sizeof(frame_marker_mask) < size) - { - if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) - { - //good return - return idx; - } - } - // reset - *hi2 = *hi = *lo = 0; - numshifts = 0; - }else { - idx++; - } - } - return -1; + // final loop, go over previously decoded manchester data and decode into usable tag ID + // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0 + uint8_t frame_marker_mask[] = {1,1,1,0,0,0}; + int numshifts = 0; + idx = 0; + //one scan + while( idx + sizeof(frame_marker_mask) < size) { + // search for a start of frame marker + if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) + { // frame marker found + idx+=sizeof(frame_marker_mask); + while(dest[idx] != dest[idx+1] && idx < size-2) + { + // Keep going until next frame marker (or error) + // Shift in a bit. Start by shifting high registers + *hi2 = (*hi2<<1)|(*hi>>31); + *hi = (*hi<<1)|(*lo>>31); + //Then, shift in a 0 or one into low + if (dest[idx] && !dest[idx+1]) // 1 0 + *lo=(*lo<<1)|0; + else // 0 1 + *lo=(*lo<<1)|1; + numshifts++; + idx += 2; + } + // Hopefully, we read a tag and hit upon the next frame marker + if(idx + sizeof(frame_marker_mask) < size) + { + if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) + { + //good return + return idx; + } + } + // reset + *hi2 = *hi = *lo = 0; + numshifts = 0; + }else { + idx++; + } + } + return -1; } -uint32_t bytebits_to_byte(uint8_t* src, int numbits) +uint32_t bytebits_to_byte(uint8_t* src, size_t numbits) { - uint32_t num = 0; - for(int i = 0 ; i < numbits ; i++) - { - num = (num << 1) | (*src); - src++; - } - return num; + uint32_t num = 0; + for(int i = 0 ; i < numbits ; i++) + { + num = (num << 1) | (*src); + src++; + } + return num; } int IOdemodFSK(uint8_t *dest, size_t size) { static const uint8_t THRESHOLD = 140; - uint32_t idx=0; - //make sure buffer has data - if (size < 66) return -1; - //test samples are not just noise + uint32_t idx=0; + //make sure buffer has data + if (size < 66) return -1; + //test samples are not just noise uint8_t justNoise = 1; for(idx=0;idx< size && justNoise ;idx++){ justNoise = dest[idx] < THRESHOLD; @@ -604,7 +603,7 @@ int IOdemodFSK(uint8_t *dest, size_t size) if(justNoise) return 0; // FSK demodulator - size = fskdemod(dest, size,64,1,10,8); // RF/64 and invert + size = fskdemod(dest, size, 64, 1, 10, 8); // RF/64 and invert if (size < 65) return -1; //did we get a good demod? //Index map //0 10 20 30 40 50 60 @@ -626,7 +625,7 @@ int IOdemodFSK(uint8_t *dest, size_t size) } } } - return 0; + return 0; } // by marshmellow @@ -634,67 +633,405 @@ int IOdemodFSK(uint8_t *dest, size_t size) // maybe somehow adjust peak trimming value based on samples to fix? int DetectASKClock(uint8_t dest[], size_t size, int clock) { - int i=0; - int peak=0; - int low=128; - int clk[]={16,32,40,50,64,100,128,256}; - int loopCnt = 256; //don't need to loop through entire array... - if (sizepeak){ - peak = dest[i]; - } - if(dest[i]=peak) || (dest[ii]<=low)){ - errCnt[clkCnt]=0; - // now that we have the first one lined up test rest of wave array - for (i=0; i<((int)(size/clk[clkCnt])-1); ++i){ - if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){ - }else if(dest[ii+(i*clk[clkCnt])-tol]>=peak || dest[ii+(i*clk[clkCnt])-tol]<=low){ - }else if(dest[ii+(i*clk[clkCnt])+tol]>=peak || dest[ii+(i*clk[clkCnt])+tol]<=low){ - }else{ //error no peak detected - errCnt[clkCnt]++; - } - } - //if we found no errors this is correct one - return this clock - if(errCnt[clkCnt]==0) return clk[clkCnt]; - //if we found errors see if it is lowest so far and save it as best run - if(errCnt[clkCnt]peak){ + peak = dest[i]; + } + if(dest[i]=peak) || (dest[ii]<=low)){ + errCnt=0; + // now that we have the first one lined up test rest of wave array + for (i=0; i<((int)(size/clk[clkCnt])-1); ++i){ + if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){ + }else if(dest[ii+(i*clk[clkCnt])-tol]>=peak || dest[ii+(i*clk[clkCnt])-tol]<=low){ + }else if(dest[ii+(i*clk[clkCnt])+tol]>=peak || dest[ii+(i*clk[clkCnt])+tol]<=low){ + }else{ //error no peak detected + errCnt++; + } + } + //if we found no errors this is correct one - return this clock + if(errCnt==0) return clk[clkCnt]; + //if we found errors see if it is lowest so far and save it as best run + if(errCntpeak){ + peak = dest[i]; + } + if(dest[i]=peak) || (dest[ii]<=low)){ + errCnt=0; + peakcnt=0; + // now that we have the first one lined up test rest of wave array + for (i=0; i<((int)(size/clk[clkCnt])-1); ++i){ + if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){ + peakcnt++; + }else if(dest[ii+(i*clk[clkCnt])-tol]>=peak || dest[ii+(i*clk[clkCnt])-tol]<=low){ + peakcnt++; + }else if(dest[ii+(i*clk[clkCnt])+tol]>=peak || dest[ii+(i*clk[clkCnt])+tol]<=low){ + peakcnt++; + }else{ //error no peak detected + errCnt++; + } + } + if(peakcnt>peaksdet[clkCnt]) { + peaksdet[clkCnt]=peakcnt; + bestErr[clkCnt]=errCnt; + } + } + } + } + int iii=0; + int best=0; + //int ratio2; //debug + int ratio; + //int bits; + for (iii=0; iii<7;++iii){ + ratio=1000; + //ratio2=1000; //debug + //bits=size/clk[iii]; //debug + if (peaksdet[iii]>0){ + ratio=bestErr[iii]/peaksdet[iii]; + if (((bestErr[best]/peaksdet[best])>(ratio)+1)){ + best = iii; + } + //ratio2=bits/peaksdet[iii]; //debug + } + //PrintAndLog("DEBUG: Clk: %d, peaks: %d, errs: %d, bestClk: %d, ratio: %d, bits: %d, peakbitr: %d",clk[iii],peaksdet[iii],bestErr[iii],clk[best],ratio, bits,ratio2); + } + return clk[best]; +} + +//by marshmellow (attempt to get rid of high immediately after a low) +void pskCleanWave(uint8_t *bitStream, size_t size) +{ + int i; + int low=128; + int high=0; + int gap = 4; + // int loopMax = 2048; + int newLow=0; + int newHigh=0; + for (i=0; ihigh) high=bitStream[i]; + } + high = (int)(((high-128)*.80)+128); + low = (int)(((low-128)*.90)+128); + //low = (uint8_t)(((int)(low)-128)*.80)+128; + for (i=0; i=high) newHigh=1; + } + return; +} + + +//redesigned by marshmellow adjusted from existing decode functions +//indala id decoding - only tested on 26 bit tags, but attempted to make it work for more +int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert) +{ + //26 bit 40134 format (don't know other formats) + int i; + int long_wait; + long_wait = 29;//29 leading zeros in format + int start; + int first = 0; + int first2 = 0; + int bitCnt = 0; + int ii; + // Finding the start of a UID + for (start = 0; start <= *size - 250; start++) { + first = bitStream[start]; + for (i = start; i < start + long_wait; i++) { + if (bitStream[i] != first) { + break; + } + } + if (i == (start + long_wait)) { + break; + } + } + if (start == *size - 250 + 1) { + // did not find start sequence + return -1; + } + //found start once now test length by finding next one + // Inverting signal if needed + if (first == 1) { + for (i = start; i < *size; i++) { + bitStream[i] = !bitStream[i]; + } + *invert = 1; + }else *invert=0; + + int iii; + for (ii=start+29; ii <= *size - 250; ii++) { + first2 = bitStream[ii]; + for (iii = ii; iii < ii + long_wait; iii++) { + if (bitStream[iii] != first2) { + break; + } + } + if (iii == (ii + long_wait)) { + break; + } + } + if (ii== *size - 250 + 1){ + // did not find second start sequence + return -2; + } + bitCnt=ii-start; + + // Dumping UID + i = start; + for (ii = 0; ii < bitCnt; ii++) { + bitStream[ii] = bitStream[i++]; + } + *size=bitCnt; + return 1; +} + + +//by marshmellow - demodulate PSK wave or NRZ wave (both similar enough) +//peaks switch bit (high=1 low=0) each clock cycle = 1 bit determined by last peak +int pskNRZrawDemod(uint8_t *dest, size_t *size, int *clk, int *invert) +{ + pskCleanWave(dest,*size); + int clk2 = DetectpskNRZClock(dest, *size, *clk); + *clk=clk2; + uint32_t i; + uint8_t high=0, low=128; + uint32_t gLen = *size; + if (gLen > 1280) gLen=1280; + // get high + for (i=0; ihigh) high = dest[i]; + if (dest[i]=high)||(dest[iii]<=low)){ + lastBit=iii-*clk; + //loop through to see if this start location works + for (i = iii; i < *size; ++i) { + //if we found a high bar and we are at a clock bit + if ((dest[i]>=high ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ + bitHigh=1; + lastBit+=*clk; + ignorewin=*clk/8; + bitnum++; + //else if low bar found and we are at a clock point + }else if ((dest[i]<=low ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ + bitHigh=1; + lastBit+=*clk; + ignorewin=*clk/8; + bitnum++; + //else if no bars found + }else if(dest[i]low) { + if (ignorewin==0){ + bitHigh=0; + }else ignorewin--; + //if we are past a clock point + if (i>=lastBit+*clk+tol){ //clock val + lastBit+=*clk; + bitnum++; + } + //else if bar found but we are not at a clock bit and we did not just have a clock bit + }else if ((dest[i]>=high || dest[i]<=low) && (ilastBit+*clk+tol) && (bitHigh==0)){ + //error bar found no clock... + errCnt++; + } + if (bitnum>=1000) break; + } + //we got more than 64 good bits and not all errors + if ((bitnum > (64+errCnt)) && (errCnt<(maxErr))) { + //possible good read + if (errCnt==0){ + bestStart = iii; + bestErrCnt=errCnt; + break; //great read - finish + } + if (bestStart == iii) break; //if current run == bestErrCnt run (after exhausted testing) then finish + if (errCnt=high ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ + bitHigh=1; + lastBit+=*clk; + curBit=1-*invert; + dest[bitnum]=curBit; + ignorewin=*clk/8; + bitnum++; + //else if low bar found and we are at a clock point + }else if ((dest[i]<=low ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ + bitHigh=1; + lastBit+=*clk; + curBit=*invert; + dest[bitnum]=curBit; + ignorewin=*clk/8; + bitnum++; + //else if no bars found + }else if(dest[i]low) { + if (ignorewin==0){ + bitHigh=0; + }else ignorewin--; + //if we are past a clock point + if (i>=lastBit+*clk+tol){ //clock val + lastBit+=*clk; + dest[bitnum]=curBit; + bitnum++; + } + //else if bar found but we are not at a clock bit and we did not just have a clock bit + }else if ((dest[i]>=high || dest[i]<=low) && ((ilastBit+*clk+tol)) && (bitHigh==0)){ + //error bar found no clock... + bitHigh=1; + dest[bitnum]=77; + bitnum++; + errCnt++; + } + if (bitnum >=1000) break; + } + *size=bitnum; + } else{ + *size=bitnum; + *clk=bestStart; + return -1; + } + + if (bitnum>16){ + *size=bitnum; + } else return -1; + return errCnt; +} + diff --git a/common/lfdemod.h b/common/lfdemod.h index ad95fda5e..b0feff043 100644 --- a/common/lfdemod.h +++ b/common/lfdemod.h @@ -1,4 +1,4 @@ -// Copyright (C) 2014 +// Copyright (C) 2014 // // 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 @@ -12,14 +12,18 @@ #include int DetectASKClock(uint8_t dest[], size_t size, int clock); -int askmandemod(uint8_t *BinStream,uint32_t *BitLen,int *clk, int *invert); -uint64_t Em410xDecode(uint8_t *BitStream,uint32_t BitLen); -int manrawdecode(uint8_t *BitStream, int *bitLen); -int BiphaseRawDecode(uint8_t * BitStream, int *bitLen, int offset); -int askrawdemod(uint8_t *BinStream, int *bitLen,int *clk, int *invert); +int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert); +uint64_t Em410xDecode(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 askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert); 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, int numbits); +uint32_t bytebits_to_byte(uint8_t* src, size_t numbits); +int pskNRZrawDemod(uint8_t *dest, size_t *size, int *clk, int *invert); +int DetectpskNRZClock(uint8_t dest[], size_t size, int clock); +int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert); +void pskCleanWave(uint8_t *bitStream, size_t size); #endif From 809fb6aeabdf2427cfd863bf56d7a05f0217ce46 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Wed, 7 Jan 2015 16:34:02 -0500 Subject: [PATCH 04/11] Fix Tune Samples (broken in commit 12/31 by me) --- client/cmddata.c | 54 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 11 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index bce5d2ced..657a118ba 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1089,24 +1089,56 @@ int CmdSamples(const char *Cmd) int CmdTuneSamples(const char *Cmd) { - int cnt = 0; - int n = 255; - uint8_t got[255]; + int timeout = 0; + printf("\nMeasuring antenna characteristics, please wait..."); - PrintAndLog("Reading %d samples\n", n); - GetFromBigBuf(got,n,7256); // armsrc/apps.h: #define FREE_BUFFER_OFFSET 7256 - WaitForResponse(CMD_ACK,NULL); - for (int j = 0; j < n; j++) { - GraphBuffer[cnt++] = ((int)got[j]) - 128; + UsbCommand c = {CMD_MEASURE_ANTENNA_TUNING}; + SendCommand(&c); + + UsbCommand resp; + while(!WaitForResponseTimeout(CMD_MEASURED_ANTENNA_TUNING,&resp,1000)) { + timeout++; + printf("."); + if (timeout > 7) { + PrintAndLog("\nNo response from Proxmark. Aborting..."); + return 1; + } + } + + int peakv, peakf; + int vLf125, vLf134, vHf; + vLf125 = resp.arg[0] & 0xffff; + vLf134 = resp.arg[0] >> 16; + vHf = resp.arg[1] & 0xffff;; + peakf = resp.arg[2] & 0xffff; + peakv = resp.arg[2] >> 16; + PrintAndLog(""); + PrintAndLog("# LF antenna: %5.2f V @ 125.00 kHz", vLf125/1000.0); + PrintAndLog("# LF antenna: %5.2f V @ 134.00 kHz", vLf134/1000.0); + PrintAndLog("# LF optimal: %5.2f V @%9.2f kHz", peakv/1000.0, 12000.0/(peakf+1)); + PrintAndLog("# HF antenna: %5.2f V @ 13.56 MHz", vHf/1000.0); + if (peakv<2000) + PrintAndLog("# Your LF antenna is unusable."); + else if (peakv<10000) + PrintAndLog("# Your LF antenna is marginal."); + if (vHf<2000) + PrintAndLog("# Your HF antenna is unusable."); + else if (vHf<5000) + PrintAndLog("# Your HF antenna is marginal."); + + for (int i = 0; i < 256; i++) { + GraphBuffer[i] = resp.d.asBytes[i] - 128; } PrintAndLog("Done! Divisor 89 is 134khz, 95 is 125khz.\n"); PrintAndLog("\n"); - GraphTraceLen = n; - RepaintGraphWindow(); - return 0; + GraphTraceLen = 256; + ShowGraphWindow(); + + return 0; } + int CmdLoad(const char *Cmd) { FILE *f = fopen(Cmd, "r"); From 4118b74dc8834bd2f45002ca6b781ce7cfae6d0c Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Tue, 6 Jan 2015 09:20:36 -0500 Subject: [PATCH 05/11] added data psk* cmds for pskdemod fixed a couple small bugs in other lf functions as well including detectaskclock, stopped changes from being made to graphbuffer. --- armsrc/lfops.c | 2840 ++--- client/cmddata.c | 337 +- client/cmddata.h | 9 +- client/cmdlf.c | 30 +- client/cmdlfem4x.c | 2 +- client/graph.c | 52 +- client/graph.h | 1 + common/lfdemod.c | 1619 +-- common/lfdemod.h | 8 +- traces/ATA5577-HIDemu-FC1-C9.pm3 | 16000 +++++++++++++++++++++++++++++ traces/README.txt | 7 + 11 files changed, 18827 insertions(+), 2078 deletions(-) create mode 100644 traces/ATA5577-HIDemu-FC1-C9.pm3 diff --git a/armsrc/lfops.c b/armsrc/lfops.c index edddb1c60..79d59bf9c 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -25,40 +25,40 @@ */ void DoAcquisition125k_internal(int trigger_threshold,bool silent) { - uint8_t *dest = (uint8_t *)BigBuf; - int n = sizeof(BigBuf); - int i; + uint8_t *dest = (uint8_t *)BigBuf; + int n = sizeof(BigBuf); + int i; - memset(dest, 0, n); - i = 0; - for(;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - LED_D_ON(); - } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - LED_D_OFF(); - if (trigger_threshold != -1 && dest[i] < trigger_threshold) - continue; - else - trigger_threshold = -1; - if (++i >= n) break; - } - } - if(!silent) - { - Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...", - dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); - - } + memset(dest, 0, n); + i = 0; + for(;;) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0x43; + LED_D_ON(); + } + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + LED_D_OFF(); + if (trigger_threshold != -1 && dest[i] < trigger_threshold) + continue; + else + trigger_threshold = -1; + if (++i >= n) break; + } + } + if(!silent) + { + Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...", + dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); + + } } /** * Perform sample aquisition. */ void DoAcquisition125k(int trigger_threshold) { - DoAcquisition125k_internal(trigger_threshold, false); + DoAcquisition125k_internal(trigger_threshold, false); } /** @@ -70,31 +70,31 @@ void DoAcquisition125k(int trigger_threshold) **/ void LFSetupFPGAForADC(int divisor, bool lf_field) { - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - if ( (divisor == 1) || (divisor < 0) || (divisor > 255) ) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz - else if (divisor == 0) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - else - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + if ( (divisor == 1) || (divisor < 0) || (divisor > 255) ) + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz + else if (divisor == 0) + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + else + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | (lf_field ? FPGA_LF_ADC_READER_FIELD : 0)); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | (lf_field ? FPGA_LF_ADC_READER_FIELD : 0)); - // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - // Give it a bit of time for the resonant antenna to settle. - SpinDelay(50); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); + // Connect the A/D to the peak-detected low-frequency path. + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + // Give it a bit of time for the resonant antenna to settle. + SpinDelay(50); + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); } /** * Initializes the FPGA, and acquires the samples. **/ void AcquireRawAdcSamples125k(int divisor) { - LFSetupFPGAForADC(divisor, true); - // Now call the acquisition routine - DoAcquisition125k_internal(-1,false); + LFSetupFPGAForADC(divisor, true); + // Now call the acquisition routine + DoAcquisition125k_internal(-1,false); } /** * Initializes the FPGA for snoop-mode, and acquires the samples. @@ -102,60 +102,60 @@ void AcquireRawAdcSamples125k(int divisor) void SnoopLFRawAdcSamples(int divisor, int trigger_threshold) { - LFSetupFPGAForADC(divisor, false); - DoAcquisition125k(trigger_threshold); + LFSetupFPGAForADC(divisor, false); + DoAcquisition125k(trigger_threshold); } void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, uint8_t *command) { - /* Make sure the tag is reset */ - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelay(2500); + /* Make sure the tag is reset */ + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelay(2500); - int divisor_used = 95; // 125 KHz - // see if 'h' was specified + int divisor_used = 95; // 125 KHz + // see if 'h' was specified - if (command[strlen((char *) command) - 1] == 'h') - divisor_used = 88; // 134.8 KHz + if (command[strlen((char *) command) - 1] == 'h') + divisor_used = 88; // 134.8 KHz - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // Give it a bit of time for the resonant antenna to settle. - SpinDelay(50); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + // Give it a bit of time for the resonant antenna to settle. + SpinDelay(50); - // And a little more time for the tag to fully power up - SpinDelay(2000); + // And a little more time for the tag to fully power up + SpinDelay(2000); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); - // now modulate the reader field - while(*command != '\0' && *command != ' ') { - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LED_D_OFF(); - SpinDelayUs(delay_off); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); + // now modulate the reader field + while(*command != '\0' && *command != ' ') { + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LED_D_OFF(); + SpinDelayUs(delay_off); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - LED_D_ON(); - if(*(command++) == '0') - SpinDelayUs(period_0); - else - SpinDelayUs(period_1); - } - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LED_D_OFF(); - SpinDelayUs(delay_off); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + LED_D_ON(); + if(*(command++) == '0') + SpinDelayUs(period_0); + else + SpinDelayUs(period_1); + } + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LED_D_OFF(); + SpinDelayUs(delay_off); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // now do the read - DoAcquisition125k(-1); + // now do the read + DoAcquisition125k(-1); } /* blank r/w tag data stream @@ -169,228 +169,230 @@ void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, */ void ReadTItag(void) { - // some hardcoded initial params - // when we read a TI tag we sample the zerocross line at 2Mhz - // TI tags modulate a 1 as 16 cycles of 123.2Khz - // TI tags modulate a 0 as 16 cycles of 134.2Khz -#define FSAMPLE 2000000 -#define FREQLO 123200 -#define FREQHI 134200 + // some hardcoded initial params + // when we read a TI tag we sample the zerocross line at 2Mhz + // TI tags modulate a 1 as 16 cycles of 123.2Khz + // TI tags modulate a 0 as 16 cycles of 134.2Khz + #define FSAMPLE 2000000 + #define FREQLO 123200 + #define FREQHI 134200 - signed char *dest = (signed char *)BigBuf; - int n = sizeof(BigBuf); + signed char *dest = (signed char *)BigBuf; + int n = sizeof(BigBuf); +// int *dest = GraphBuffer; +// int n = GraphTraceLen; - // 128 bit shift register [shift3:shift2:shift1:shift0] - uint32_t shift3 = 0, shift2 = 0, shift1 = 0, shift0 = 0; + // 128 bit shift register [shift3:shift2:shift1:shift0] + uint32_t shift3 = 0, shift2 = 0, shift1 = 0, shift0 = 0; - int i, cycles=0, samples=0; - // how many sample points fit in 16 cycles of each frequency - uint32_t sampleslo = (FSAMPLE<<4)/FREQLO, sampleshi = (FSAMPLE<<4)/FREQHI; - // when to tell if we're close enough to one freq or another - uint32_t threshold = (sampleslo - sampleshi + 1)>>1; + int i, cycles=0, samples=0; + // how many sample points fit in 16 cycles of each frequency + uint32_t sampleslo = (FSAMPLE<<4)/FREQLO, sampleshi = (FSAMPLE<<4)/FREQHI; + // when to tell if we're close enough to one freq or another + uint32_t threshold = (sampleslo - sampleshi + 1)>>1; - // TI tags charge at 134.2Khz - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz + // TI tags charge at 134.2Khz + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz - // Place FPGA in passthrough mode, in this mode the CROSS_LO line - // connects to SSP_DIN and the SSP_DOUT logic level controls - // whether we're modulating the antenna (high) - // or listening to the antenna (low) - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); + // Place FPGA in passthrough mode, in this mode the CROSS_LO line + // connects to SSP_DIN and the SSP_DOUT logic level controls + // whether we're modulating the antenna (high) + // or listening to the antenna (low) + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); - // get TI tag data into the buffer - AcquireTiType(); + // get TI tag data into the buffer + AcquireTiType(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - for (i=0; i0) ) { - cycles++; - // after 16 cycles, measure the frequency - if (cycles>15) { - cycles=0; - samples=i-samples; // number of samples in these 16 cycles + for (i=0; i0) ) { + cycles++; + // after 16 cycles, measure the frequency + if (cycles>15) { + cycles=0; + samples=i-samples; // number of samples in these 16 cycles - // TI bits are coming to us lsb first so shift them - // right through our 128 bit right shift register - shift0 = (shift0>>1) | (shift1 << 31); - shift1 = (shift1>>1) | (shift2 << 31); - shift2 = (shift2>>1) | (shift3 << 31); - shift3 >>= 1; + // TI bits are coming to us lsb first so shift them + // right through our 128 bit right shift register + shift0 = (shift0>>1) | (shift1 << 31); + shift1 = (shift1>>1) | (shift2 << 31); + shift2 = (shift2>>1) | (shift3 << 31); + shift3 >>= 1; - // check if the cycles fall close to the number - // expected for either the low or high frequency - if ( (samples>(sampleslo-threshold)) && (samples<(sampleslo+threshold)) ) { - // low frequency represents a 1 - shift3 |= (1<<31); - } else if ( (samples>(sampleshi-threshold)) && (samples<(sampleshi+threshold)) ) { - // high frequency represents a 0 - } else { - // probably detected a gay waveform or noise - // use this as gaydar or discard shift register and start again - shift3 = shift2 = shift1 = shift0 = 0; - } - samples = i; + // check if the cycles fall close to the number + // expected for either the low or high frequency + if ( (samples>(sampleslo-threshold)) && (samples<(sampleslo+threshold)) ) { + // low frequency represents a 1 + shift3 |= (1<<31); + } else if ( (samples>(sampleshi-threshold)) && (samples<(sampleshi+threshold)) ) { + // high frequency represents a 0 + } else { + // probably detected a gay waveform or noise + // use this as gaydar or discard shift register and start again + shift3 = shift2 = shift1 = shift0 = 0; + } + samples = i; - // for each bit we receive, test if we've detected a valid tag + // for each bit we receive, test if we've detected a valid tag - // if we see 17 zeroes followed by 6 ones, we might have a tag - // remember the bits are backwards - if ( ((shift0 & 0x7fffff) == 0x7e0000) ) { - // if start and end bytes match, we have a tag so break out of the loop - if ( ((shift0>>16)&0xff) == ((shift3>>8)&0xff) ) { - cycles = 0xF0B; //use this as a flag (ugly but whatever) - break; - } - } - } - } - } + // if we see 17 zeroes followed by 6 ones, we might have a tag + // remember the bits are backwards + if ( ((shift0 & 0x7fffff) == 0x7e0000) ) { + // if start and end bytes match, we have a tag so break out of the loop + if ( ((shift0>>16)&0xff) == ((shift3>>8)&0xff) ) { + cycles = 0xF0B; //use this as a flag (ugly but whatever) + break; + } + } + } + } + } - // if flag is set we have a tag - if (cycles!=0xF0B) { - DbpString("Info: No valid tag detected."); - } else { - // put 64 bit data into shift1 and shift0 - shift0 = (shift0>>24) | (shift1 << 8); - shift1 = (shift1>>24) | (shift2 << 8); + // if flag is set we have a tag + if (cycles!=0xF0B) { + DbpString("Info: No valid tag detected."); + } else { + // put 64 bit data into shift1 and shift0 + shift0 = (shift0>>24) | (shift1 << 8); + shift1 = (shift1>>24) | (shift2 << 8); - // align 16 bit crc into lower half of shift2 - shift2 = ((shift2>>24) | (shift3 << 8)) & 0x0ffff; + // align 16 bit crc into lower half of shift2 + shift2 = ((shift2>>24) | (shift3 << 8)) & 0x0ffff; - // if r/w tag, check ident match - if ( shift3&(1<<15) ) { - DbpString("Info: TI tag is rewriteable"); - // only 15 bits compare, last bit of ident is not valid - if ( ((shift3>>16)^shift0)&0x7fff ) { - DbpString("Error: Ident mismatch!"); - } else { - DbpString("Info: TI tag ident is valid"); - } - } else { - DbpString("Info: TI tag is readonly"); - } + // if r/w tag, check ident match + if ( shift3&(1<<15) ) { + DbpString("Info: TI tag is rewriteable"); + // only 15 bits compare, last bit of ident is not valid + if ( ((shift3>>16)^shift0)&0x7fff ) { + DbpString("Error: Ident mismatch!"); + } else { + DbpString("Info: TI tag ident is valid"); + } + } else { + DbpString("Info: TI tag is readonly"); + } - // WARNING the order of the bytes in which we calc crc below needs checking - // i'm 99% sure the crc algorithm is correct, but it may need to eat the - // bytes in reverse or something - // calculate CRC - uint32_t crc=0; + // WARNING the order of the bytes in which we calc crc below needs checking + // i'm 99% sure the crc algorithm is correct, but it may need to eat the + // bytes in reverse or something + // calculate CRC + uint32_t crc=0; - crc = update_crc16(crc, (shift0)&0xff); - crc = update_crc16(crc, (shift0>>8)&0xff); - crc = update_crc16(crc, (shift0>>16)&0xff); - crc = update_crc16(crc, (shift0>>24)&0xff); - crc = update_crc16(crc, (shift1)&0xff); - crc = update_crc16(crc, (shift1>>8)&0xff); - crc = update_crc16(crc, (shift1>>16)&0xff); - crc = update_crc16(crc, (shift1>>24)&0xff); + crc = update_crc16(crc, (shift0)&0xff); + crc = update_crc16(crc, (shift0>>8)&0xff); + crc = update_crc16(crc, (shift0>>16)&0xff); + crc = update_crc16(crc, (shift0>>24)&0xff); + crc = update_crc16(crc, (shift1)&0xff); + crc = update_crc16(crc, (shift1>>8)&0xff); + crc = update_crc16(crc, (shift1>>16)&0xff); + crc = update_crc16(crc, (shift1>>24)&0xff); - Dbprintf("Info: Tag data: %x%08x, crc=%x", - (unsigned int)shift1, (unsigned int)shift0, (unsigned int)shift2 & 0xFFFF); - if (crc != (shift2&0xffff)) { - Dbprintf("Error: CRC mismatch, expected %x", (unsigned int)crc); - } else { - DbpString("Info: CRC is good"); - } - } + Dbprintf("Info: Tag data: %x%08x, crc=%x", + (unsigned int)shift1, (unsigned int)shift0, (unsigned int)shift2 & 0xFFFF); + if (crc != (shift2&0xffff)) { + Dbprintf("Error: CRC mismatch, expected %x", (unsigned int)crc); + } else { + DbpString("Info: CRC is good"); + } + } } void WriteTIbyte(uint8_t b) { - int i = 0; + int i = 0; - // modulate 8 bits out to the antenna - for (i=0; i<8; i++) - { - if (b&(1<PIO_PDR = GPIO_SSC_DIN; - AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN; + // Set up the synchronous serial port + AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DIN; + AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN; - // steal this pin from the SSP and use it to control the modulation - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + // steal this pin from the SSP and use it to control the modulation + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST; - AT91C_BASE_SSC->SSC_CR = AT91C_SSC_RXEN | AT91C_SSC_TXEN; + AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST; + AT91C_BASE_SSC->SSC_CR = AT91C_SSC_RXEN | AT91C_SSC_TXEN; - // Sample at 2 Mbit/s, so TI tags are 16.2 vs. 14.9 clocks long - // 48/2 = 24 MHz clock must be divided by 12 - AT91C_BASE_SSC->SSC_CMR = 12; + // Sample at 2 Mbit/s, so TI tags are 16.2 vs. 14.9 clocks long + // 48/2 = 24 MHz clock must be divided by 12 + AT91C_BASE_SSC->SSC_CMR = 12; - AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(0); - AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(32) | AT91C_SSC_MSBF; - AT91C_BASE_SSC->SSC_TCMR = 0; - AT91C_BASE_SSC->SSC_TFMR = 0; + AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(0); + AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(32) | AT91C_SSC_MSBF; + AT91C_BASE_SSC->SSC_TCMR = 0; + AT91C_BASE_SSC->SSC_TFMR = 0; - LED_D_ON(); + LED_D_ON(); - // modulate antenna - HIGH(GPIO_SSC_DOUT); + // modulate antenna + HIGH(GPIO_SSC_DOUT); - // Charge TI tag for 50ms. - SpinDelay(50); + // Charge TI tag for 50ms. + SpinDelay(50); - // stop modulating antenna and listen - LOW(GPIO_SSC_DOUT); + // stop modulating antenna and listen + LOW(GPIO_SSC_DOUT); - LED_D_OFF(); + LED_D_OFF(); - i = 0; - for(;;) { - if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - BigBuf[i] = AT91C_BASE_SSC->SSC_RHR; // store 32 bit values in buffer - i++; if(i >= TIBUFLEN) break; - } - WDT_HIT(); - } + i = 0; + for(;;) { + if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + BigBuf[i] = AT91C_BASE_SSC->SSC_RHR; // store 32 bit values in buffer + i++; if(i >= TIBUFLEN) break; + } + WDT_HIT(); + } - // return stolen pin to SSP - AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN | GPIO_SSC_DOUT; + // return stolen pin to SSP + AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN | GPIO_SSC_DOUT; - char *dest = (char *)BigBuf; - n = TIBUFLEN*32; - // unpack buffer - for (i=TIBUFLEN-1; i>=0; i--) { - for (j=0; j<32; j++) { - if(BigBuf[i] & (1 << j)) { - dest[--n] = 1; - } else { - dest[--n] = -1; - } - } - } + char *dest = (char *)BigBuf; + n = TIBUFLEN*32; + // unpack buffer + for (i=TIBUFLEN-1; i>=0; i--) { + for (j=0; j<32; j++) { + if(BigBuf[i] & (1 << j)) { + dest[--n] = 1; + } else { + dest[--n] = -1; + } + } + } } // arguments: 64bit data split into 32bit idhi:idlo and optional 16bit crc @@ -398,127 +400,127 @@ void AcquireTiType(void) // if not provided a valid crc will be computed from the data and written. void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc) { - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - if(crc == 0) { - crc = update_crc16(crc, (idlo)&0xff); - crc = update_crc16(crc, (idlo>>8)&0xff); - crc = update_crc16(crc, (idlo>>16)&0xff); - crc = update_crc16(crc, (idlo>>24)&0xff); - crc = update_crc16(crc, (idhi)&0xff); - crc = update_crc16(crc, (idhi>>8)&0xff); - crc = update_crc16(crc, (idhi>>16)&0xff); - crc = update_crc16(crc, (idhi>>24)&0xff); - } - Dbprintf("Writing to tag: %x%08x, crc=%x", - (unsigned int) idhi, (unsigned int) idlo, crc); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + if(crc == 0) { + crc = update_crc16(crc, (idlo)&0xff); + crc = update_crc16(crc, (idlo>>8)&0xff); + crc = update_crc16(crc, (idlo>>16)&0xff); + crc = update_crc16(crc, (idlo>>24)&0xff); + crc = update_crc16(crc, (idhi)&0xff); + crc = update_crc16(crc, (idhi>>8)&0xff); + crc = update_crc16(crc, (idhi>>16)&0xff); + crc = update_crc16(crc, (idhi>>24)&0xff); + } + Dbprintf("Writing to tag: %x%08x, crc=%x", + (unsigned int) idhi, (unsigned int) idlo, crc); - // TI tags charge at 134.2Khz - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz - // Place FPGA in passthrough mode, in this mode the CROSS_LO line - // connects to SSP_DIN and the SSP_DOUT logic level controls - // whether we're modulating the antenna (high) - // or listening to the antenna (low) - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); - LED_A_ON(); + // TI tags charge at 134.2Khz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz + // Place FPGA in passthrough mode, in this mode the CROSS_LO line + // connects to SSP_DIN and the SSP_DOUT logic level controls + // whether we're modulating the antenna (high) + // or listening to the antenna (low) + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); + LED_A_ON(); - // steal this pin from the SSP and use it to control the modulation - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + // steal this pin from the SSP and use it to control the modulation + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - // writing algorithm: - // a high bit consists of a field off for 1ms and field on for 1ms - // a low bit consists of a field off for 0.3ms and field on for 1.7ms - // initiate a charge time of 50ms (field on) then immediately start writing bits - // start by writing 0xBB (keyword) and 0xEB (password) - // then write 80 bits of data (or 64 bit data + 16 bit crc if you prefer) - // finally end with 0x0300 (write frame) - // all data is sent lsb firts - // finish with 15ms programming time + // writing algorithm: + // a high bit consists of a field off for 1ms and field on for 1ms + // a low bit consists of a field off for 0.3ms and field on for 1.7ms + // initiate a charge time of 50ms (field on) then immediately start writing bits + // start by writing 0xBB (keyword) and 0xEB (password) + // then write 80 bits of data (or 64 bit data + 16 bit crc if you prefer) + // finally end with 0x0300 (write frame) + // all data is sent lsb firts + // finish with 15ms programming time - // modulate antenna - HIGH(GPIO_SSC_DOUT); - SpinDelay(50); // charge time + // modulate antenna + HIGH(GPIO_SSC_DOUT); + SpinDelay(50); // charge time - WriteTIbyte(0xbb); // keyword - WriteTIbyte(0xeb); // password - WriteTIbyte( (idlo )&0xff ); - WriteTIbyte( (idlo>>8 )&0xff ); - WriteTIbyte( (idlo>>16)&0xff ); - WriteTIbyte( (idlo>>24)&0xff ); - WriteTIbyte( (idhi )&0xff ); - WriteTIbyte( (idhi>>8 )&0xff ); - WriteTIbyte( (idhi>>16)&0xff ); - WriteTIbyte( (idhi>>24)&0xff ); // data hi to lo - WriteTIbyte( (crc )&0xff ); // crc lo - WriteTIbyte( (crc>>8 )&0xff ); // crc hi - WriteTIbyte(0x00); // write frame lo - WriteTIbyte(0x03); // write frame hi - HIGH(GPIO_SSC_DOUT); - SpinDelay(50); // programming time + WriteTIbyte(0xbb); // keyword + WriteTIbyte(0xeb); // password + WriteTIbyte( (idlo )&0xff ); + WriteTIbyte( (idlo>>8 )&0xff ); + WriteTIbyte( (idlo>>16)&0xff ); + WriteTIbyte( (idlo>>24)&0xff ); + WriteTIbyte( (idhi )&0xff ); + WriteTIbyte( (idhi>>8 )&0xff ); + WriteTIbyte( (idhi>>16)&0xff ); + WriteTIbyte( (idhi>>24)&0xff ); // data hi to lo + WriteTIbyte( (crc )&0xff ); // crc lo + WriteTIbyte( (crc>>8 )&0xff ); // crc hi + WriteTIbyte(0x00); // write frame lo + WriteTIbyte(0x03); // write frame hi + HIGH(GPIO_SSC_DOUT); + SpinDelay(50); // programming time - LED_A_OFF(); + LED_A_OFF(); - // get TI tag data into the buffer - AcquireTiType(); + // get TI tag data into the buffer + AcquireTiType(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - DbpString("Now use tiread to check"); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + DbpString("Now use tiread to check"); } void SimulateTagLowFrequency(int period, int gap, int ledcontrol) { - int i; - uint8_t *tab = (uint8_t *)BigBuf; + int i; + uint8_t *tab = (uint8_t *)BigBuf; - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK; + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK; - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK; + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK; #define SHORT_COIL() LOW(GPIO_SSC_DOUT) #define OPEN_COIL() HIGH(GPIO_SSC_DOUT) - i = 0; - for(;;) { - while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) { - if(BUTTON_PRESS()) { - DbpString("Stopped"); - return; - } - WDT_HIT(); - } + i = 0; + for(;;) { + while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) { + if(BUTTON_PRESS()) { + DbpString("Stopped"); + return; + } + WDT_HIT(); + } - if (ledcontrol) - LED_D_ON(); + if (ledcontrol) + LED_D_ON(); - if(tab[i]) - OPEN_COIL(); - else - SHORT_COIL(); + if(tab[i]) + OPEN_COIL(); + else + SHORT_COIL(); - if (ledcontrol) - LED_D_OFF(); + if (ledcontrol) + LED_D_OFF(); - while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) { - if(BUTTON_PRESS()) { - DbpString("Stopped"); - return; - } - WDT_HIT(); - } + while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) { + if(BUTTON_PRESS()) { + DbpString("Stopped"); + return; + } + WDT_HIT(); + } - i++; - if(i == period) { - i = 0; - if (gap) { - SHORT_COIL(); - SpinDelayUs(gap); - } - } - } + i++; + if(i == period) { + i = 0; + if (gap) { + SHORT_COIL(); + SpinDelayUs(gap); + } + } + } } #define DEBUG_FRAME_CONTENTS 1 @@ -528,314 +530,318 @@ void SimulateTagLowFrequencyBidir(int divisor, int t0) // compose fc/8 fc/10 waveform static void fc(int c, int *n) { - uint8_t *dest = (uint8_t *)BigBuf; - int idx; + uint8_t *dest = (uint8_t *)BigBuf; + int idx; - // for when we want an fc8 pattern every 4 logical bits - if(c==0) { - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - } - // an fc/8 encoded bit is a bit pattern of 11000000 x6 = 48 samples - if(c==8) { - for (idx=0; idx<6; idx++) { - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - } - } + // for when we want an fc8 pattern every 4 logical bits + if(c==0) { + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + } + // an fc/8 encoded bit is a bit pattern of 11000000 x6 = 48 samples + if(c==8) { + for (idx=0; idx<6; idx++) { + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + } + } - // an fc/10 encoded bit is a bit pattern of 1110000000 x5 = 50 samples - if(c==10) { - for (idx=0; idx<5; idx++) { - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - } - } + // an fc/10 encoded bit is a bit pattern of 1110000000 x5 = 50 samples + if(c==10) { + for (idx=0; idx<5; idx++) { + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + } + } } // prepare a waveform pattern in the buffer based on the ID given then // simulate a HID tag until the button is pressed void CmdHIDsimTAG(int hi, int lo, int ledcontrol) { - int n=0, i=0; - /* - HID tag bitstream format - The tag contains a 44bit unique code. This is sent out MSB first in sets of 4 bits - A 1 bit is represented as 6 fc8 and 5 fc10 patterns - A 0 bit is represented as 5 fc10 and 6 fc8 patterns - A fc8 is inserted before every 4 bits - A special start of frame pattern is used consisting a0b0 where a and b are neither 0 - nor 1 bits, they are special patterns (a = set of 12 fc8 and b = set of 10 fc10) - */ + int n=0, i=0; + /* + HID tag bitstream format + The tag contains a 44bit unique code. This is sent out MSB first in sets of 4 bits + A 1 bit is represented as 6 fc8 and 5 fc10 patterns + A 0 bit is represented as 5 fc10 and 6 fc8 patterns + A fc8 is inserted before every 4 bits + A special start of frame pattern is used consisting a0b0 where a and b are neither 0 + nor 1 bits, they are special patterns (a = set of 12 fc8 and b = set of 10 fc10) + */ - if (hi>0xFFF) { - DbpString("Tags can only have 44 bits."); - return; - } - fc(0,&n); - // special start of frame marker containing invalid bit sequences - fc(8, &n); fc(8, &n); // invalid - fc(8, &n); fc(10, &n); // logical 0 - fc(10, &n); fc(10, &n); // invalid - fc(8, &n); fc(10, &n); // logical 0 + if (hi>0xFFF) { + DbpString("Tags can only have 44 bits."); + return; + } + fc(0,&n); + // special start of frame marker containing invalid bit sequences + fc(8, &n); fc(8, &n); // invalid + fc(8, &n); fc(10, &n); // logical 0 + fc(10, &n); fc(10, &n); // invalid + fc(8, &n); fc(10, &n); // logical 0 - WDT_HIT(); - // manchester encode bits 43 to 32 - for (i=11; i>=0; i--) { - if ((i%4)==3) fc(0,&n); - if ((hi>>i)&1) { - fc(10, &n); fc(8, &n); // low-high transition - } else { - fc(8, &n); fc(10, &n); // high-low transition - } - } + WDT_HIT(); + // manchester encode bits 43 to 32 + for (i=11; i>=0; i--) { + if ((i%4)==3) fc(0,&n); + if ((hi>>i)&1) { + fc(10, &n); fc(8, &n); // low-high transition + } else { + fc(8, &n); fc(10, &n); // high-low transition + } + } - WDT_HIT(); - // manchester encode bits 31 to 0 - for (i=31; i>=0; i--) { - if ((i%4)==3) fc(0,&n); - if ((lo>>i)&1) { - fc(10, &n); fc(8, &n); // low-high transition - } else { - fc(8, &n); fc(10, &n); // high-low transition - } - } + WDT_HIT(); + // manchester encode bits 31 to 0 + for (i=31; i>=0; i--) { + if ((i%4)==3) fc(0,&n); + if ((lo>>i)&1) { + fc(10, &n); fc(8, &n); // low-high transition + } else { + fc(8, &n); fc(10, &n); // high-low transition + } + } - if (ledcontrol) - LED_A_ON(); - - SimulateTagLowFrequency(n, 0, ledcontrol); + if (ledcontrol) + LED_A_ON(); + SimulateTagLowFrequency(n, 0, ledcontrol); - if (ledcontrol) - LED_A_OFF(); + if (ledcontrol) + LED_A_OFF(); } // loop to get raw HID waveform then FSK demodulate the TAG ID from it void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) { - uint8_t *dest = (uint8_t *)BigBuf; + uint8_t *dest = (uint8_t *)BigBuf; - size_t size=0; //, found=0; - uint32_t hi2=0, hi=0, lo=0; + size_t size=0; //, found=0; + uint32_t hi2=0, hi=0, lo=0; - // Configure to go in 125Khz listen mode - LFSetupFPGAForADC(95, true); + // Configure to go in 125Khz listen mode + LFSetupFPGAForADC(95, true); - while(!BUTTON_PRESS()) { + while(!BUTTON_PRESS()) { - WDT_HIT(); - if (ledcontrol) LED_A_ON(); + WDT_HIT(); + if (ledcontrol) LED_A_ON(); - DoAcquisition125k_internal(-1,true); - size = sizeof(BigBuf); - if (size < 2000) continue; - // FSK demodulator + DoAcquisition125k_internal(-1,true); + size = sizeof(BigBuf); + if (size < 2000) continue; + // FSK demodulator - int bitLen = HIDdemodFSK(dest,size,&hi2,&hi,&lo); + int bitLen = HIDdemodFSK(dest,size,&hi2,&hi,&lo); + + WDT_HIT(); - WDT_HIT(); - - if (bitLen>0 && lo>0){ - // final loop, go over previously decoded manchester data and decode into usable tag ID - // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0 - if (hi2 != 0){ //extra large HID tags - Dbprintf("TAG ID: %x%08x%08x (%d)", - (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); - }else { //standard HID tags <38 bits - //Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd - uint8_t bitlen = 0; - uint32_t fc = 0; - uint32_t cardnum = 0; - if (((hi>>5)&1)==1){//if bit 38 is set then < 37 bit format is used - uint32_t lo2=0; - lo2=(((hi & 31) << 12) | (lo>>20)); //get bits 21-37 to check for format len bit - uint8_t idx3 = 1; - while(lo2>1){ //find last bit set to 1 (format len bit) - lo2=lo2>>1; - idx3++; - } - bitlen =idx3+19; - fc =0; - cardnum=0; - if(bitlen==26){ - cardnum = (lo>>1)&0xFFFF; - fc = (lo>>17)&0xFF; - } - if(bitlen==37){ - cardnum = (lo>>1)&0x7FFFF; - fc = ((hi&0xF)<<12)|(lo>>20); - } - if(bitlen==34){ - cardnum = (lo>>1)&0xFFFF; - fc= ((hi&1)<<15)|(lo>>17); - } - if(bitlen==35){ - cardnum = (lo>>1)&0xFFFFF; - fc = ((hi&1)<<11)|(lo>>21); - } - } - else { //if bit 38 is not set then 37 bit format is used - bitlen= 37; - fc =0; - cardnum=0; - if(bitlen==37){ - cardnum = (lo>>1)&0x7FFFF; - fc = ((hi&0xF)<<12)|(lo>>20); - } - } - //Dbprintf("TAG ID: %x%08x (%d)", - // (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); - Dbprintf("TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d", - (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF, - (unsigned int) bitlen, (unsigned int) fc, (unsigned int) cardnum); - } - if (findone){ - if (ledcontrol) LED_A_OFF(); - return; - } - // reset - hi2 = hi = lo = 0; - } - WDT_HIT(); - } - DbpString("Stopped"); - if (ledcontrol) LED_A_OFF(); + if (bitLen>0 && lo>0){ + // final loop, go over previously decoded manchester data and decode into usable tag ID + // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0 + if (hi2 != 0){ //extra large HID tags + Dbprintf("TAG ID: %x%08x%08x (%d)", + (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); + }else { //standard HID tags <38 bits + //Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd + uint8_t bitlen = 0; + uint32_t fc = 0; + uint32_t cardnum = 0; + if (((hi>>5)&1)==1){//if bit 38 is set then < 37 bit format is used + uint32_t lo2=0; + lo2=(((hi & 31) << 12) | (lo>>20)); //get bits 21-37 to check for format len bit + uint8_t idx3 = 1; + while(lo2>1){ //find last bit set to 1 (format len bit) + lo2=lo2>>1; + idx3++; + } + bitlen =idx3+19; + fc =0; + cardnum=0; + if(bitlen==26){ + cardnum = (lo>>1)&0xFFFF; + fc = (lo>>17)&0xFF; + } + if(bitlen==37){ + cardnum = (lo>>1)&0x7FFFF; + fc = ((hi&0xF)<<12)|(lo>>20); + } + if(bitlen==34){ + cardnum = (lo>>1)&0xFFFF; + fc= ((hi&1)<<15)|(lo>>17); + } + if(bitlen==35){ + cardnum = (lo>>1)&0xFFFFF; + fc = ((hi&1)<<11)|(lo>>21); + } + } + else { //if bit 38 is not set then 37 bit format is used + bitlen= 37; + fc =0; + cardnum=0; + if(bitlen==37){ + cardnum = (lo>>1)&0x7FFFF; + fc = ((hi&0xF)<<12)|(lo>>20); + } + } + //Dbprintf("TAG ID: %x%08x (%d)", + // (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); + Dbprintf("TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d", + (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF, + (unsigned int) bitlen, (unsigned int) fc, (unsigned int) cardnum); + } + if (findone){ + if (ledcontrol) LED_A_OFF(); + return; + } + // reset + hi2 = hi = lo = 0; + } + WDT_HIT(); + //SpinDelay(50); + } + DbpString("Stopped"); + if (ledcontrol) LED_A_OFF(); } void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol) { - uint8_t *dest = (uint8_t *)BigBuf; + uint8_t *dest = (uint8_t *)BigBuf; - size_t size=0; //, found=0; - uint32_t bitLen=0; - int clk=0, invert=0, errCnt=0; - uint64_t lo=0; - // Configure to go in 125Khz listen mode - LFSetupFPGAForADC(95, true); + size_t size=0; //, found=0; + int bitLen=0; + int clk=0, invert=0, errCnt=0; + uint64_t lo=0; + // Configure to go in 125Khz listen mode + LFSetupFPGAForADC(95, true); - while(!BUTTON_PRESS()) { + while(!BUTTON_PRESS()) { - WDT_HIT(); - if (ledcontrol) LED_A_ON(); + WDT_HIT(); + if (ledcontrol) LED_A_ON(); - DoAcquisition125k_internal(-1,true); - size = sizeof(BigBuf); - if (size < 2000) continue; - // FSK demodulator - //int askmandemod(uint8_t *BinStream,uint32_t *BitLen,int *clk, int *invert); - bitLen=size; - //Dbprintf("DEBUG: Buffer got"); - errCnt = askmandemod(dest,&bitLen,&clk,&invert); //HIDdemodFSK(dest,size,&hi2,&hi,&lo); - //Dbprintf("DEBUG: ASK Got"); - WDT_HIT(); + DoAcquisition125k_internal(-1,true); + size = sizeof(BigBuf); + if (size < 2000) continue; + // FSK demodulator + //int askmandemod(uint8_t *BinStream,uint32_t *BitLen,int *clk, int *invert); + bitLen=size; + //Dbprintf("DEBUG: Buffer got"); + errCnt = askmandemod(dest,&bitLen,&clk,&invert); //HIDdemodFSK(dest,size,&hi2,&hi,&lo); + //Dbprintf("DEBUG: ASK Got"); + WDT_HIT(); - if (errCnt>=0){ - lo = Em410xDecode(dest,bitLen); - //Dbprintf("DEBUG: EM GOT"); - //printEM410x(lo); - if (lo>0){ - Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)",(uint32_t)(lo>>32),(uint32_t)lo,(uint32_t)(lo&0xFFFF),(uint32_t)((lo>>16LL) & 0xFF),(uint32_t)(lo & 0xFFFFFF)); - } - if (findone){ - if (ledcontrol) LED_A_OFF(); - return; - } - } else{ - //Dbprintf("DEBUG: No Tag"); - } - WDT_HIT(); - lo = 0; - clk=0; - invert=0; - errCnt=0; - size=0; - //SpinDelay(50); - } - DbpString("Stopped"); - if (ledcontrol) LED_A_OFF(); + if (errCnt>=0){ + lo = Em410xDecode(dest,bitLen); + //Dbprintf("DEBUG: EM GOT"); + //printEM410x(lo); + if (lo>0){ + Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)",(uint32_t)(lo>>32),(uint32_t)lo,(uint32_t)(lo&0xFFFF),(uint32_t)((lo>>16LL) & 0xFF),(uint32_t)(lo & 0xFFFFFF)); + } + if (findone){ + if (ledcontrol) LED_A_OFF(); + return; + } + } else{ + //Dbprintf("DEBUG: No Tag"); + } + WDT_HIT(); + lo = 0; + clk=0; + invert=0; + errCnt=0; + size=0; + //SpinDelay(50); + } + DbpString("Stopped"); + if (ledcontrol) LED_A_OFF(); } void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) { - uint8_t *dest = (uint8_t *)BigBuf; - int idx=0; - uint32_t code=0, code2=0; - uint8_t version=0; - uint8_t facilitycode=0; - uint16_t number=0; - // Configure to go in 125Khz listen mode - LFSetupFPGAForADC(95, true); + uint8_t *dest = (uint8_t *)BigBuf; + size_t size=0; + int idx=0; + uint32_t code=0, code2=0; + uint8_t version=0; + uint8_t facilitycode=0; + uint16_t number=0; + // Configure to go in 125Khz listen mode + LFSetupFPGAForADC(95, true); + + while(!BUTTON_PRESS()) { + WDT_HIT(); + if (ledcontrol) LED_A_ON(); + DoAcquisition125k_internal(-1,true); + size = sizeof(BigBuf); + //make sure buffer has data + if (size < 2000) continue; + //fskdemod and get start index + WDT_HIT(); + idx = IOdemodFSK(dest,size); + if (idx>0){ + //valid tag found - while(!BUTTON_PRESS()) { - WDT_HIT(); - if (ledcontrol) LED_A_ON(); - DoAcquisition125k_internal(-1,true); - //fskdemod and get start index - WDT_HIT(); - idx = IOdemodFSK(dest,sizeof(BigBuf)); - if (idx>0){ - //valid tag found - - //Index map - //0 10 20 30 40 50 60 - //| | | | | | | - //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23 - //----------------------------------------------------------------------------- - //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11 - // - //XSF(version)facility:codeone+codetwo - //Handle the data - if(findone){ //only print binary if we are doing one - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx], dest[idx+1], dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7],dest[idx+8]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15],dest[idx+16],dest[idx+17]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23],dest[idx+24],dest[idx+25],dest[idx+26]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31],dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39],dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+45],dest[idx+46],dest[idx+47],dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53]); - Dbprintf("%d%d%d%d%d%d%d%d %d%d",dest[idx+54],dest[idx+55],dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]); - } - code = bytebits_to_byte(dest+idx,32); - code2 = bytebits_to_byte(dest+idx+32,32); - version = bytebits_to_byte(dest+idx+27,8); //14,4 - facilitycode = bytebits_to_byte(dest+idx+18,8) ; - number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9 - - Dbprintf("XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2); - // if we're only looking for one tag - if (findone){ - if (ledcontrol) LED_A_OFF(); - //LED_A_OFF(); - return; - } - code=code2=0; - version=facilitycode=0; - number=0; - idx=0; - } - WDT_HIT(); - } - DbpString("Stopped"); - if (ledcontrol) LED_A_OFF(); + //Index map + //0 10 20 30 40 50 60 + //| | | | | | | + //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23 + //----------------------------------------------------------------------------- + //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11 + // + //XSF(version)facility:codeone+codetwo + //Handle the data + if(findone){ //only print binary if we are doing one + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx], dest[idx+1], dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7],dest[idx+8]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15],dest[idx+16],dest[idx+17]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23],dest[idx+24],dest[idx+25],dest[idx+26]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31],dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39],dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+45],dest[idx+46],dest[idx+47],dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53]); + Dbprintf("%d%d%d%d%d%d%d%d %d%d",dest[idx+54],dest[idx+55],dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]); + } + code = bytebits_to_byte(dest+idx,32); + code2 = bytebits_to_byte(dest+idx+32,32); + version = bytebits_to_byte(dest+idx+27,8); //14,4 + facilitycode = bytebits_to_byte(dest+idx+18,8) ; + number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9 + + Dbprintf("XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2); + // if we're only looking for one tag + if (findone){ + if (ledcontrol) LED_A_OFF(); + //LED_A_OFF(); + return; + } + code=code2=0; + version=facilitycode=0; + number=0; + idx=0; + } + WDT_HIT(); + } + DbpString("Stopped"); + if (ledcontrol) LED_A_OFF(); } /*------------------------------ @@ -905,307 +911,307 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) // Write one bit to card void T55xxWriteBit(int bit) { - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - if (bit == 0) - SpinDelayUs(WRITE_0); - else - SpinDelayUs(WRITE_1); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelayUs(WRITE_GAP); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + if (bit == 0) + SpinDelayUs(WRITE_0); + else + SpinDelayUs(WRITE_1); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelayUs(WRITE_GAP); } // Write one card block in page 0, no lock void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode) { - //unsigned int i; //enio adjustment 12/10/14 - uint32_t i; + //unsigned int i; //enio adjustment 12/10/14 + uint32_t i; - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // Give it a bit of time for the resonant antenna to settle. - // And for the tag to fully power up - SpinDelay(150); + // Give it a bit of time for the resonant antenna to settle. + // And for the tag to fully power up + SpinDelay(150); - // Now start writting - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelayUs(START_GAP); + // Now start writting + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelayUs(START_GAP); - // Opcode - T55xxWriteBit(1); - T55xxWriteBit(0); //Page 0 - if (PwdMode == 1){ - // Pwd - for (i = 0x80000000; i != 0; i >>= 1) - T55xxWriteBit(Pwd & i); - } - // Lock bit - T55xxWriteBit(0); - - // Data + // Opcode + T55xxWriteBit(1); + T55xxWriteBit(0); //Page 0 + if (PwdMode == 1){ + // Pwd for (i = 0x80000000; i != 0; i >>= 1) - T55xxWriteBit(Data & i); + T55xxWriteBit(Pwd & i); + } + // Lock bit + T55xxWriteBit(0); - // Block - for (i = 0x04; i != 0; i >>= 1) - T55xxWriteBit(Block & i); + // Data + for (i = 0x80000000; i != 0; i >>= 1) + T55xxWriteBit(Data & i); - // Now perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550, - // so wait a little more) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - SpinDelay(20); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + // Block + for (i = 0x04; i != 0; i >>= 1) + T55xxWriteBit(Block & i); + + // Now perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550, + // so wait a little more) + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + SpinDelay(20); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); } // Read one card block in page 0 void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode) { - uint8_t *dest = (uint8_t *)BigBuf; - //int m=0, i=0; //enio adjustment 12/10/14 - uint32_t m=0, i=0; - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - m = sizeof(BigBuf); - // Clear destination buffer before sending the command - memset(dest, 128, m); - // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); - - LED_D_ON(); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - - // Give it a bit of time for the resonant antenna to settle. - // And for the tag to fully power up - SpinDelay(150); - - // Now start writting - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelayUs(START_GAP); - - // Opcode - T55xxWriteBit(1); - T55xxWriteBit(0); //Page 0 - if (PwdMode == 1){ - // Pwd - for (i = 0x80000000; i != 0; i >>= 1) - T55xxWriteBit(Pwd & i); - } - // Lock bit - T55xxWriteBit(0); - // Block - for (i = 0x04; i != 0; i >>= 1) - T55xxWriteBit(Block & i); - - // Turn field on to read the response - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - - // Now do the acquisition - i = 0; - for(;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - // we don't care about actual value, only if it's more or less than a - // threshold essentially we capture zero crossings for later analysis - // if(dest[i] < 127) dest[i] = 0; else dest[i] = 1; - i++; - if (i >= m) break; - } - } - - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); - DbpString("DONE!"); + uint8_t *dest = (uint8_t *)BigBuf; + //int m=0, i=0; //enio adjustment 12/10/14 + uint32_t m=0, i=0; + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + m = sizeof(BigBuf); + // Clear destination buffer before sending the command + memset(dest, 128, m); + // Connect the A/D to the peak-detected low-frequency path. + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); + + LED_D_ON(); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + + // Give it a bit of time for the resonant antenna to settle. + // And for the tag to fully power up + SpinDelay(150); + + // Now start writting + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelayUs(START_GAP); + + // Opcode + T55xxWriteBit(1); + T55xxWriteBit(0); //Page 0 + if (PwdMode == 1){ + // Pwd + for (i = 0x80000000; i != 0; i >>= 1) + T55xxWriteBit(Pwd & i); + } + // Lock bit + T55xxWriteBit(0); + // Block + for (i = 0x04; i != 0; i >>= 1) + T55xxWriteBit(Block & i); + + // Turn field on to read the response + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + + // Now do the acquisition + i = 0; + for(;;) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0x43; + } + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + // we don't care about actual value, only if it's more or less than a + // threshold essentially we capture zero crossings for later analysis + // if(dest[i] < 127) dest[i] = 0; else dest[i] = 1; + i++; + if (i >= m) break; + } + } + + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + LED_D_OFF(); + DbpString("DONE!"); } // Read card traceability data (page 1) void T55xxReadTrace(void){ - uint8_t *dest = (uint8_t *)BigBuf; - int m=0, i=0; - - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - m = sizeof(BigBuf); - // Clear destination buffer before sending the command - memset(dest, 128, m); - // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); - - LED_D_ON(); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - - // Give it a bit of time for the resonant antenna to settle. - // And for the tag to fully power up - SpinDelay(150); - - // Now start writting - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelayUs(START_GAP); - - // Opcode - T55xxWriteBit(1); - T55xxWriteBit(1); //Page 1 - - // Turn field on to read the response - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - - // Now do the acquisition - i = 0; - for(;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - i++; - if (i >= m) break; - } - } - - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); - DbpString("DONE!"); + uint8_t *dest = (uint8_t *)BigBuf; + int m=0, i=0; + + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + m = sizeof(BigBuf); + // Clear destination buffer before sending the command + memset(dest, 128, m); + // Connect the A/D to the peak-detected low-frequency path. + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); + + LED_D_ON(); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + + // Give it a bit of time for the resonant antenna to settle. + // And for the tag to fully power up + SpinDelay(150); + + // Now start writting + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelayUs(START_GAP); + + // Opcode + T55xxWriteBit(1); + T55xxWriteBit(1); //Page 1 + + // Turn field on to read the response + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + + // Now do the acquisition + i = 0; + for(;;) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0x43; + } + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + i++; + if (i >= m) break; + } + } + + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + LED_D_OFF(); + DbpString("DONE!"); } /*-------------- Cloning routines -----------*/ // Copy HID id to card and setup block 0 config void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT) { - int data1=0, data2=0, data3=0, data4=0, data5=0, data6=0; //up to six blocks for long format - int last_block = 0; - - if (longFMT){ - // Ensure no more than 84 bits supplied - if (hi2>0xFFFFF) { - DbpString("Tags can only have 84 bits."); - return; - } - // Build the 6 data blocks for supplied 84bit ID - last_block = 6; - data1 = 0x1D96A900; // load preamble (1D) & long format identifier (9E manchester encoded) - for (int i=0;i<4;i++) { - if (hi2 & (1<<(19-i))) - data1 |= (1<<(((3-i)*2)+1)); // 1 -> 10 - else - data1 |= (1<<((3-i)*2)); // 0 -> 01 - } - - data2 = 0; - for (int i=0;i<16;i++) { - if (hi2 & (1<<(15-i))) - data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data2 |= (1<<((15-i)*2)); // 0 -> 01 - } - - data3 = 0; - for (int i=0;i<16;i++) { - if (hi & (1<<(31-i))) - data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data3 |= (1<<((15-i)*2)); // 0 -> 01 - } - - data4 = 0; - for (int i=0;i<16;i++) { - if (hi & (1<<(15-i))) - data4 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data4 |= (1<<((15-i)*2)); // 0 -> 01 - } - - data5 = 0; - for (int i=0;i<16;i++) { - if (lo & (1<<(31-i))) - data5 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data5 |= (1<<((15-i)*2)); // 0 -> 01 - } - - data6 = 0; - for (int i=0;i<16;i++) { - if (lo & (1<<(15-i))) - data6 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data6 |= (1<<((15-i)*2)); // 0 -> 01 - } + int data1=0, data2=0, data3=0, data4=0, data5=0, data6=0; //up to six blocks for long format + int last_block = 0; + + if (longFMT){ + // Ensure no more than 84 bits supplied + if (hi2>0xFFFFF) { + DbpString("Tags can only have 84 bits."); + return; + } + // Build the 6 data blocks for supplied 84bit ID + last_block = 6; + data1 = 0x1D96A900; // load preamble (1D) & long format identifier (9E manchester encoded) + for (int i=0;i<4;i++) { + if (hi2 & (1<<(19-i))) + data1 |= (1<<(((3-i)*2)+1)); // 1 -> 10 + else + data1 |= (1<<((3-i)*2)); // 0 -> 01 + } + + data2 = 0; + for (int i=0;i<16;i++) { + if (hi2 & (1<<(15-i))) + data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data2 |= (1<<((15-i)*2)); // 0 -> 01 } - else { - // Ensure no more than 44 bits supplied - if (hi>0xFFF) { - DbpString("Tags can only have 44 bits."); - return; - } - - // Build the 3 data blocks for supplied 44bit ID - last_block = 3; - - data1 = 0x1D000000; // load preamble - - for (int i=0;i<12;i++) { - if (hi & (1<<(11-i))) - data1 |= (1<<(((11-i)*2)+1)); // 1 -> 10 - else - data1 |= (1<<((11-i)*2)); // 0 -> 01 - } - - data2 = 0; - for (int i=0;i<16;i++) { - if (lo & (1<<(31-i))) - data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data2 |= (1<<((15-i)*2)); // 0 -> 01 - } - - data3 = 0; - for (int i=0;i<16;i++) { - if (lo & (1<<(15-i))) - data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data3 |= (1<<((15-i)*2)); // 0 -> 01 - } + + data3 = 0; + for (int i=0;i<16;i++) { + if (hi & (1<<(31-i))) + data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data3 |= (1<<((15-i)*2)); // 0 -> 01 + } + + data4 = 0; + for (int i=0;i<16;i++) { + if (hi & (1<<(15-i))) + data4 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data4 |= (1<<((15-i)*2)); // 0 -> 01 } - - LED_D_ON(); - // Program the data blocks for supplied ID - // and the block 0 for HID format - T55xxWriteBlock(data1,1,0,0); - T55xxWriteBlock(data2,2,0,0); - T55xxWriteBlock(data3,3,0,0); - - if (longFMT) { // if long format there are 6 blocks - T55xxWriteBlock(data4,4,0,0); - T55xxWriteBlock(data5,5,0,0); - T55xxWriteBlock(data6,6,0,0); + + data5 = 0; + for (int i=0;i<16;i++) { + if (lo & (1<<(31-i))) + data5 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data5 |= (1<<((15-i)*2)); // 0 -> 01 + } + + data6 = 0; + for (int i=0;i<16;i++) { + if (lo & (1<<(15-i))) + data6 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data6 |= (1<<((15-i)*2)); // 0 -> 01 } - - // Config for HID (RF/50, FSK2a, Maxblock=3 for short/6 for long) - T55xxWriteBlock(T55x7_BITRATE_RF_50 | - T55x7_MODULATION_FSK2a | - last_block << T55x7_MAXBLOCK_SHIFT, - 0,0,0); - - LED_D_OFF(); - - DbpString("DONE!"); + } + else { + // Ensure no more than 44 bits supplied + if (hi>0xFFF) { + DbpString("Tags can only have 44 bits."); + return; + } + + // Build the 3 data blocks for supplied 44bit ID + last_block = 3; + + data1 = 0x1D000000; // load preamble + + for (int i=0;i<12;i++) { + if (hi & (1<<(11-i))) + data1 |= (1<<(((11-i)*2)+1)); // 1 -> 10 + else + data1 |= (1<<((11-i)*2)); // 0 -> 01 + } + + data2 = 0; + for (int i=0;i<16;i++) { + if (lo & (1<<(31-i))) + data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data2 |= (1<<((15-i)*2)); // 0 -> 01 + } + + data3 = 0; + for (int i=0;i<16;i++) { + if (lo & (1<<(15-i))) + data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data3 |= (1<<((15-i)*2)); // 0 -> 01 + } + } + + LED_D_ON(); + // Program the data blocks for supplied ID + // and the block 0 for HID format + T55xxWriteBlock(data1,1,0,0); + T55xxWriteBlock(data2,2,0,0); + T55xxWriteBlock(data3,3,0,0); + + if (longFMT) { // if long format there are 6 blocks + T55xxWriteBlock(data4,4,0,0); + T55xxWriteBlock(data5,5,0,0); + T55xxWriteBlock(data6,6,0,0); + } + + // Config for HID (RF/50, FSK2a, Maxblock=3 for short/6 for long) + T55xxWriteBlock(T55x7_BITRATE_RF_50 | + T55x7_MODULATION_FSK2a | + last_block << T55x7_MAXBLOCK_SHIFT, + 0,0,0); + + LED_D_OFF(); + + DbpString("DONE!"); } void CopyIOtoT55x7(uint32_t hi, uint32_t lo, uint8_t longFMT) { - int data1=0, data2=0; //up to six blocks for long format - + int data1=0, data2=0; //up to six blocks for long format + data1 = hi; // load preamble data2 = lo; @@ -1214,11 +1220,11 @@ void CopyIOtoT55x7(uint32_t hi, uint32_t lo, uint8_t longFMT) // and the block 0 for HID format T55xxWriteBlock(data1,1,0,0); T55xxWriteBlock(data2,2,0,0); - + //Config Block T55xxWriteBlock(0x00147040,0,0,0); LED_D_OFF(); - + DbpString("DONE!"); } @@ -1228,148 +1234,152 @@ void CopyIOtoT55x7(uint32_t hi, uint32_t lo, uint8_t longFMT) void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo) { - int i, id_bit; - uint64_t id = EM410X_HEADER; - uint64_t rev_id = 0; // reversed ID - int c_parity[4]; // column parity - int r_parity = 0; // row parity - uint32_t clock = 0; + int i, id_bit; + uint64_t id = EM410X_HEADER; + uint64_t rev_id = 0; // reversed ID + int c_parity[4]; // column parity + int r_parity = 0; // row parity + uint32_t clock = 0; - // Reverse ID bits given as parameter (for simpler operations) - for (i = 0; i < EM410X_ID_LENGTH; ++i) { - if (i < 32) { - rev_id = (rev_id << 1) | (id_lo & 1); - id_lo >>= 1; - } else { - rev_id = (rev_id << 1) | (id_hi & 1); - id_hi >>= 1; - } - } + // Reverse ID bits given as parameter (for simpler operations) + for (i = 0; i < EM410X_ID_LENGTH; ++i) { + if (i < 32) { + rev_id = (rev_id << 1) | (id_lo & 1); + id_lo >>= 1; + } else { + rev_id = (rev_id << 1) | (id_hi & 1); + id_hi >>= 1; + } + } - for (i = 0; i < EM410X_ID_LENGTH; ++i) { - id_bit = rev_id & 1; + for (i = 0; i < EM410X_ID_LENGTH; ++i) { + id_bit = rev_id & 1; - if (i % 4 == 0) { - // Don't write row parity bit at start of parsing - if (i) - id = (id << 1) | r_parity; - // Start counting parity for new row - r_parity = id_bit; - } else { - // Count row parity - r_parity ^= id_bit; - } + if (i % 4 == 0) { + // Don't write row parity bit at start of parsing + if (i) + id = (id << 1) | r_parity; + // Start counting parity for new row + r_parity = id_bit; + } else { + // Count row parity + r_parity ^= id_bit; + } - // First elements in column? - if (i < 4) - // Fill out first elements - c_parity[i] = id_bit; - else - // Count column parity - c_parity[i % 4] ^= id_bit; + // First elements in column? + if (i < 4) + // Fill out first elements + c_parity[i] = id_bit; + else + // Count column parity + c_parity[i % 4] ^= id_bit; - // Insert ID bit - id = (id << 1) | id_bit; - rev_id >>= 1; - } + // Insert ID bit + id = (id << 1) | id_bit; + rev_id >>= 1; + } - // Insert parity bit of last row - id = (id << 1) | r_parity; + // Insert parity bit of last row + id = (id << 1) | r_parity; - // Fill out column parity at the end of tag - for (i = 0; i < 4; ++i) - id = (id << 1) | c_parity[i]; + // Fill out column parity at the end of tag + for (i = 0; i < 4; ++i) + id = (id << 1) | c_parity[i]; - // Add stop bit - id <<= 1; + // Add stop bit + id <<= 1; - Dbprintf("Started writing %s tag ...", card ? "T55x7":"T5555"); - LED_D_ON(); + Dbprintf("Started writing %s tag ...", card ? "T55x7":"T5555"); + LED_D_ON(); - // Write EM410x ID - T55xxWriteBlock((uint32_t)(id >> 32), 1, 0, 0); - T55xxWriteBlock((uint32_t)id, 2, 0, 0); + // Write EM410x ID + T55xxWriteBlock((uint32_t)(id >> 32), 1, 0, 0); + T55xxWriteBlock((uint32_t)id, 2, 0, 0); - // Config for EM410x (RF/64, Manchester, Maxblock=2) - if (card) { - // Clock rate is stored in bits 8-15 of the card value - clock = (card & 0xFF00) >> 8; - Dbprintf("Clock rate: %d", clock); - switch (clock) - { - case 32: - clock = T55x7_BITRATE_RF_32; - break; - case 16: - clock = T55x7_BITRATE_RF_16; - break; - case 0: - // A value of 0 is assumed to be 64 for backwards-compatibility - // Fall through... - case 64: - clock = T55x7_BITRATE_RF_64; - break; - default: - Dbprintf("Invalid clock rate: %d", clock); - return; - } + // Config for EM410x (RF/64, Manchester, Maxblock=2) + if (card) { + // Clock rate is stored in bits 8-15 of the card value + clock = (card & 0xFF00) >> 8; + Dbprintf("Clock rate: %d", clock); + switch (clock) + { + case 32: + clock = T55x7_BITRATE_RF_32; + break; + case 16: + clock = T55x7_BITRATE_RF_16; + break; + case 0: + // A value of 0 is assumed to be 64 for backwards-compatibility + // Fall through... + case 64: + clock = T55x7_BITRATE_RF_64; + break; + default: + Dbprintf("Invalid clock rate: %d", clock); + return; + } - // Writing configuration for T55x7 tag - T55xxWriteBlock(clock | - T55x7_MODULATION_MANCHESTER | - 2 << T55x7_MAXBLOCK_SHIFT, - 0, 0, 0); - } - else - // Writing configuration for T5555(Q5) tag - T55xxWriteBlock(0x1F << T5555_BITRATE_SHIFT | - T5555_MODULATION_MANCHESTER | - 2 << T5555_MAXBLOCK_SHIFT, - 0, 0, 0); + // Writing configuration for T55x7 tag + T55xxWriteBlock(clock | + T55x7_MODULATION_MANCHESTER | + 2 << T55x7_MAXBLOCK_SHIFT, + 0, 0, 0); + } + else + // Writing configuration for T5555(Q5) tag + T55xxWriteBlock(0x1F << T5555_BITRATE_SHIFT | + T5555_MODULATION_MANCHESTER | + 2 << T5555_MAXBLOCK_SHIFT, + 0, 0, 0); - LED_D_OFF(); - Dbprintf("Tag %s written with 0x%08x%08x\n", card ? "T55x7":"T5555", - (uint32_t)(id >> 32), (uint32_t)id); + LED_D_OFF(); + Dbprintf("Tag %s written with 0x%08x%08x\n", card ? "T55x7":"T5555", + (uint32_t)(id >> 32), (uint32_t)id); } // Clone Indala 64-bit tag by UID to T55x7 void CopyIndala64toT55x7(int hi, int lo) { - //Program the 2 data blocks for supplied 64bit UID - // and the block 0 for Indala64 format - T55xxWriteBlock(hi,1,0,0); - T55xxWriteBlock(lo,2,0,0); - //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=2) - T55xxWriteBlock(T55x7_BITRATE_RF_32 | - T55x7_MODULATION_PSK1 | - 2 << T55x7_MAXBLOCK_SHIFT, - 0, 0, 0); - //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data) - // T5567WriteBlock(0x603E1042,0); - DbpString("DONE!"); + //Program the 2 data blocks for supplied 64bit UID + // and the block 0 for Indala64 format + T55xxWriteBlock(hi,1,0,0); + T55xxWriteBlock(lo,2,0,0); + //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=2) + T55xxWriteBlock(T55x7_BITRATE_RF_32 | + T55x7_MODULATION_PSK1 | + 2 << T55x7_MAXBLOCK_SHIFT, + 0, 0, 0); + //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data) +// T5567WriteBlock(0x603E1042,0); + + DbpString("DONE!"); + } void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int uid6, int uid7) { - //Program the 7 data blocks for supplied 224bit UID - // and the block 0 for Indala224 format - T55xxWriteBlock(uid1,1,0,0); - T55xxWriteBlock(uid2,2,0,0); - T55xxWriteBlock(uid3,3,0,0); - T55xxWriteBlock(uid4,4,0,0); - T55xxWriteBlock(uid5,5,0,0); - T55xxWriteBlock(uid6,6,0,0); - T55xxWriteBlock(uid7,7,0,0); - //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=7) - T55xxWriteBlock(T55x7_BITRATE_RF_32 | - T55x7_MODULATION_PSK1 | - 7 << T55x7_MAXBLOCK_SHIFT, - 0,0,0); - //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data) - // T5567WriteBlock(0x603E10E2,0); - DbpString("DONE!"); + //Program the 7 data blocks for supplied 224bit UID + // and the block 0 for Indala224 format + T55xxWriteBlock(uid1,1,0,0); + T55xxWriteBlock(uid2,2,0,0); + T55xxWriteBlock(uid3,3,0,0); + T55xxWriteBlock(uid4,4,0,0); + T55xxWriteBlock(uid5,5,0,0); + T55xxWriteBlock(uid6,6,0,0); + T55xxWriteBlock(uid7,7,0,0); + //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=7) + T55xxWriteBlock(T55x7_BITRATE_RF_32 | + T55x7_MODULATION_PSK1 | + 7 << T55x7_MAXBLOCK_SHIFT, + 0,0,0); + //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data) +// T5567WriteBlock(0x603E10E2,0); + + DbpString("DONE!"); + } @@ -1377,260 +1387,261 @@ void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int #define max(x,y) ( x GraphBuffer[0]) { - while(i < GraphTraceLen) { - if( !(GraphBuffer[i] > GraphBuffer[i-1]) && GraphBuffer[i] > lmax) - break; - i++; - } - dir = 0; + uint8_t BitStream[256]; + uint8_t Blocks[8][16]; + uint8_t *GraphBuffer = (uint8_t *)BigBuf; + int GraphTraceLen = sizeof(BigBuf); + int i, j, lastval, bitidx, half_switch; + int clock = 64; + int tolerance = clock / 8; + int pmc, block_done; + int lc, warnings = 0; + int num_blocks = 0; + int lmin=128, lmax=128; + uint8_t dir; + + AcquireRawAdcSamples125k(0); + + lmin = 64; + lmax = 192; + + i = 2; + + /* Find first local max/min */ + if(GraphBuffer[1] > GraphBuffer[0]) { + while(i < GraphTraceLen) { + if( !(GraphBuffer[i] > GraphBuffer[i-1]) && GraphBuffer[i] > lmax) + break; + i++; } - else { - while(i < GraphTraceLen) { - if( !(GraphBuffer[i] < GraphBuffer[i-1]) && GraphBuffer[i] < lmin) - break; - i++; - } - dir = 1; + dir = 0; + } + else { + while(i < GraphTraceLen) { + if( !(GraphBuffer[i] < GraphBuffer[i-1]) && GraphBuffer[i] < lmin) + break; + i++; } - - lastval = i++; - half_switch = 0; - pmc = 0; - block_done = 0; - - for (bitidx = 0; i < GraphTraceLen; i++) - { - if ( (GraphBuffer[i-1] > GraphBuffer[i] && dir == 1 && GraphBuffer[i] > lmax) || (GraphBuffer[i-1] < GraphBuffer[i] && dir == 0 && GraphBuffer[i] < lmin)) - { - lc = i - lastval; - lastval = i; - - // Switch depending on lc length: - // Tolerance is 1/8 of clock rate (arbitrary) - if (abs(lc-clock/4) < tolerance) { - // 16T0 - if((i - pmc) == lc) { /* 16T0 was previous one */ - /* It's a PMC ! */ - i += (128+127+16+32+33+16)-1; - lastval = i; - pmc = 0; - block_done = 1; - } - else { - pmc = i; - } - } else if (abs(lc-clock/2) < tolerance) { - // 32TO - if((i - pmc) == lc) { /* 16T0 was previous one */ - /* It's a PMC ! */ - i += (128+127+16+32+33)-1; - lastval = i; - pmc = 0; - block_done = 1; - } - else if(half_switch == 1) { - BitStream[bitidx++] = 0; - half_switch = 0; - } - else - half_switch++; - } else if (abs(lc-clock) < tolerance) { - // 64TO - BitStream[bitidx++] = 1; - } else { - // Error - warnings++; - if (warnings > 10) - { - Dbprintf("Error: too many detection errors, aborting."); - return 0; - } - } - - if(block_done == 1) { - if(bitidx == 128) { - for(j=0; j<16; j++) { - Blocks[num_blocks][j] = 128*BitStream[j*8+7]+ - 64*BitStream[j*8+6]+ - 32*BitStream[j*8+5]+ - 16*BitStream[j*8+4]+ - 8*BitStream[j*8+3]+ - 4*BitStream[j*8+2]+ - 2*BitStream[j*8+1]+ - BitStream[j*8]; - } - num_blocks++; - } - bitidx = 0; - block_done = 0; - half_switch = 0; - } - if(i < GraphTraceLen) - { - if (GraphBuffer[i-1] > GraphBuffer[i]) dir=0; - else dir = 1; - } - } - if(bitidx==255) - bitidx=0; - warnings = 0; - if(num_blocks == 4) break; - } - memcpy(outBlocks, Blocks, 16*num_blocks); - return num_blocks; + dir = 1; + } + + lastval = i++; + half_switch = 0; + pmc = 0; + block_done = 0; + + for (bitidx = 0; i < GraphTraceLen; i++) + { + if ( (GraphBuffer[i-1] > GraphBuffer[i] && dir == 1 && GraphBuffer[i] > lmax) || (GraphBuffer[i-1] < GraphBuffer[i] && dir == 0 && GraphBuffer[i] < lmin)) + { + lc = i - lastval; + lastval = i; + + // Switch depending on lc length: + // Tolerance is 1/8 of clock rate (arbitrary) + if (abs(lc-clock/4) < tolerance) { + // 16T0 + if((i - pmc) == lc) { /* 16T0 was previous one */ + /* It's a PMC ! */ + i += (128+127+16+32+33+16)-1; + lastval = i; + pmc = 0; + block_done = 1; + } + else { + pmc = i; + } + } else if (abs(lc-clock/2) < tolerance) { + // 32TO + if((i - pmc) == lc) { /* 16T0 was previous one */ + /* It's a PMC ! */ + i += (128+127+16+32+33)-1; + lastval = i; + pmc = 0; + block_done = 1; + } + else if(half_switch == 1) { + BitStream[bitidx++] = 0; + half_switch = 0; + } + else + half_switch++; + } else if (abs(lc-clock) < tolerance) { + // 64TO + BitStream[bitidx++] = 1; + } else { + // Error + warnings++; + if (warnings > 10) + { + Dbprintf("Error: too many detection errors, aborting."); + return 0; + } + } + + if(block_done == 1) { + if(bitidx == 128) { + for(j=0; j<16; j++) { + Blocks[num_blocks][j] = 128*BitStream[j*8+7]+ + 64*BitStream[j*8+6]+ + 32*BitStream[j*8+5]+ + 16*BitStream[j*8+4]+ + 8*BitStream[j*8+3]+ + 4*BitStream[j*8+2]+ + 2*BitStream[j*8+1]+ + BitStream[j*8]; + } + num_blocks++; + } + bitidx = 0; + block_done = 0; + half_switch = 0; + } + if(i < GraphTraceLen) + { + if (GraphBuffer[i-1] > GraphBuffer[i]) dir=0; + else dir = 1; + } + } + if(bitidx==255) + bitidx=0; + warnings = 0; + if(num_blocks == 4) break; + } + memcpy(outBlocks, Blocks, 16*num_blocks); + return num_blocks; } int IsBlock0PCF7931(uint8_t *Block) { - // Assume RFU means 0 :) - if((memcmp(Block, "\x00\x00\x00\x00\x00\x00\x00\x01", 8) == 0) && memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) // PAC enabled - return 1; - if((memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) && Block[7] == 0) // PAC disabled, can it *really* happen ? - return 1; - return 0; + // Assume RFU means 0 :) + if((memcmp(Block, "\x00\x00\x00\x00\x00\x00\x00\x01", 8) == 0) && memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) // PAC enabled + return 1; + if((memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) && Block[7] == 0) // PAC disabled, can it *really* happen ? + return 1; + return 0; } int IsBlock1PCF7931(uint8_t *Block) { - // Assume RFU means 0 :) - if(Block[10] == 0 && Block[11] == 0 && Block[12] == 0 && Block[13] == 0) - if((Block[14] & 0x7f) <= 9 && Block[15] <= 9) - return 1; - - return 0; + // Assume RFU means 0 :) + if(Block[10] == 0 && Block[11] == 0 && Block[12] == 0 && Block[13] == 0) + if((Block[14] & 0x7f) <= 9 && Block[15] <= 9) + return 1; + + return 0; } + #define ALLOC 16 void ReadPCF7931() { - uint8_t Blocks[8][17]; - uint8_t tmpBlocks[4][16]; - int i, j, ind, ind2, n; - int num_blocks = 0; - int max_blocks = 8; - int ident = 0; - int error = 0; - int tries = 0; - - memset(Blocks, 0, 8*17*sizeof(uint8_t)); - - do { - memset(tmpBlocks, 0, 4*16*sizeof(uint8_t)); - n = DemodPCF7931((uint8_t**)tmpBlocks); - if(!n) - error++; - if(error==10 && num_blocks == 0) { - Dbprintf("Error, no tag or bad tag"); - return; - } - else if (tries==20 || error==10) { - Dbprintf("Error reading the tag"); - Dbprintf("Here is the partial content"); - goto end; - } - - for(i=0; i= 0; ind--,ind2--) { - if(ind2 < 0) - ind2 = max_blocks; - if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found - // Dbprintf("Tmp %d -> Block %d", ind, ind2); - memcpy(Blocks[ind2], tmpBlocks[ind], 16); - Blocks[ind2][ALLOC] = 1; - num_blocks++; - if(num_blocks == max_blocks) goto end; - } - } - for(ind=i+1,ind2=j+1; ind < n; ind++,ind2++) { - if(ind2 > max_blocks) - ind2 = 0; - if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found - // Dbprintf("Tmp %d -> Block %d", ind, ind2); - memcpy(Blocks[ind2], tmpBlocks[ind], 16); - Blocks[ind2][ALLOC] = 1; - num_blocks++; - if(num_blocks == max_blocks) goto end; - } - } - } - } - } - } - } - tries++; - if (BUTTON_PRESS()) return; - } while (num_blocks != max_blocks); -end: - Dbprintf("-----------------------------------------"); - Dbprintf("Memory content:"); - Dbprintf("-----------------------------------------"); - for(i=0; i", i); + uint8_t Blocks[8][17]; + uint8_t tmpBlocks[4][16]; + int i, j, ind, ind2, n; + int num_blocks = 0; + int max_blocks = 8; + int ident = 0; + int error = 0; + int tries = 0; + + memset(Blocks, 0, 8*17*sizeof(uint8_t)); + + do { + memset(tmpBlocks, 0, 4*16*sizeof(uint8_t)); + n = DemodPCF7931((uint8_t**)tmpBlocks); + if(!n) + error++; + if(error==10 && num_blocks == 0) { + Dbprintf("Error, no tag or bad tag"); + return; } - Dbprintf("-----------------------------------------"); - - return ; + else if (tries==20 || error==10) { + Dbprintf("Error reading the tag"); + Dbprintf("Here is the partial content"); + goto end; + } + + for(i=0; i= 0; ind--,ind2--) { + if(ind2 < 0) + ind2 = max_blocks; + if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found + // Dbprintf("Tmp %d -> Block %d", ind, ind2); + memcpy(Blocks[ind2], tmpBlocks[ind], 16); + Blocks[ind2][ALLOC] = 1; + num_blocks++; + if(num_blocks == max_blocks) goto end; + } + } + for(ind=i+1,ind2=j+1; ind < n; ind++,ind2++) { + if(ind2 > max_blocks) + ind2 = 0; + if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found + // Dbprintf("Tmp %d -> Block %d", ind, ind2); + memcpy(Blocks[ind2], tmpBlocks[ind], 16); + Blocks[ind2][ALLOC] = 1; + num_blocks++; + if(num_blocks == max_blocks) goto end; + } + } + } + } + } + } + } + tries++; + if (BUTTON_PRESS()) return; + } while (num_blocks != max_blocks); +end: + Dbprintf("-----------------------------------------"); + Dbprintf("Memory content:"); + Dbprintf("-----------------------------------------"); + for(i=0; i", i); + } + Dbprintf("-----------------------------------------"); + + return ; } @@ -1654,20 +1665,20 @@ uint8_t * fwd_write_ptr; //forwardlink bit pointer //==================================================================== //-------------------------------------------------------------------- uint8_t Prepare_Cmd( uint8_t cmd ) { - //-------------------------------------------------------------------- - - *forward_ptr++ = 0; //start bit - *forward_ptr++ = 0; //second pause for 4050 code - - *forward_ptr++ = cmd; - cmd >>= 1; - *forward_ptr++ = cmd; - cmd >>= 1; - *forward_ptr++ = cmd; - cmd >>= 1; - *forward_ptr++ = cmd; - - return 6; //return number of emited bits + //-------------------------------------------------------------------- + + *forward_ptr++ = 0; //start bit + *forward_ptr++ = 0; //second pause for 4050 code + + *forward_ptr++ = cmd; + cmd >>= 1; + *forward_ptr++ = cmd; + cmd >>= 1; + *forward_ptr++ = cmd; + cmd >>= 1; + *forward_ptr++ = cmd; + + return 6; //return number of emited bits } //==================================================================== @@ -1677,21 +1688,21 @@ uint8_t Prepare_Cmd( uint8_t cmd ) { //-------------------------------------------------------------------- uint8_t Prepare_Addr( uint8_t addr ) { - //-------------------------------------------------------------------- - - register uint8_t line_parity; - - uint8_t i; - line_parity = 0; - for(i=0;i<6;i++) { - *forward_ptr++ = addr; - line_parity ^= addr; - addr >>= 1; - } - - *forward_ptr++ = (line_parity & 1); - - return 7; //return number of emited bits + //-------------------------------------------------------------------- + + register uint8_t line_parity; + + uint8_t i; + line_parity = 0; + for(i=0;i<6;i++) { + *forward_ptr++ = addr; + line_parity ^= addr; + addr >>= 1; + } + + *forward_ptr++ = (line_parity & 1); + + return 7; //return number of emited bits } //==================================================================== @@ -1701,36 +1712,36 @@ uint8_t Prepare_Addr( uint8_t addr ) { //-------------------------------------------------------------------- uint8_t Prepare_Data( uint16_t data_low, uint16_t data_hi) { - //-------------------------------------------------------------------- - - register uint8_t line_parity; - register uint8_t column_parity; - register uint8_t i, j; - register uint16_t data; - - data = data_low; - column_parity = 0; - - for(i=0; i<4; i++) { - line_parity = 0; - for(j=0; j<8; j++) { - line_parity ^= data; - column_parity ^= (data & 1) << j; - *forward_ptr++ = data; - data >>= 1; - } - *forward_ptr++ = line_parity; - if(i == 1) - data = data_hi; - } - + //-------------------------------------------------------------------- + + register uint8_t line_parity; + register uint8_t column_parity; + register uint8_t i, j; + register uint16_t data; + + data = data_low; + column_parity = 0; + + for(i=0; i<4; i++) { + line_parity = 0; for(j=0; j<8; j++) { - *forward_ptr++ = column_parity; - column_parity >>= 1; + line_parity ^= data; + column_parity ^= (data & 1) << j; + *forward_ptr++ = data; + data >>= 1; } - *forward_ptr = 0; - - return 45; //return number of emited bits + *forward_ptr++ = line_parity; + if(i == 1) + data = data_hi; + } + + for(j=0; j<8; j++) { + *forward_ptr++ = column_parity; + column_parity >>= 1; + } + *forward_ptr = 0; + + return 45; //return number of emited bits } //==================================================================== @@ -1739,116 +1750,115 @@ uint8_t Prepare_Data( uint16_t data_low, uint16_t data_hi) { // fwd_bit_count set with number of bits to be sent //==================================================================== void SendForward(uint8_t fwd_bit_count) { - - fwd_write_ptr = forwardLink_data; - fwd_bit_sz = fwd_bit_count; - - LED_D_ON(); - - //Field on - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - - // Give it a bit of time for the resonant antenna to settle. - // And for the tag to fully power up - SpinDelay(150); - - // force 1st mod pulse (start gap must be longer for 4305) - fwd_bit_sz--; //prepare next bit modulation - fwd_write_ptr++; - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - SpinDelayUs(55*8); //55 cycles off (8us each)for 4305 - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on - SpinDelayUs(16*8); //16 cycles on (8us each) - - // now start writting - while(fwd_bit_sz-- > 0) { //prepare next bit modulation - if(((*fwd_write_ptr++) & 1) == 1) - SpinDelayUs(32*8); //32 cycles at 125Khz (8us each) - else { - //These timings work for 4469/4269/4305 (with the 55*8 above) - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - SpinDelayUs(23*8); //16-4 cycles off (8us each) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on - SpinDelayUs(9*8); //16 cycles on (8us each) - } + + fwd_write_ptr = forwardLink_data; + fwd_bit_sz = fwd_bit_count; + + LED_D_ON(); + + //Field on + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + + // Give it a bit of time for the resonant antenna to settle. + // And for the tag to fully power up + SpinDelay(150); + + // force 1st mod pulse (start gap must be longer for 4305) + fwd_bit_sz--; //prepare next bit modulation + fwd_write_ptr++; + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + SpinDelayUs(55*8); //55 cycles off (8us each)for 4305 + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on + SpinDelayUs(16*8); //16 cycles on (8us each) + + // now start writting + while(fwd_bit_sz-- > 0) { //prepare next bit modulation + if(((*fwd_write_ptr++) & 1) == 1) + SpinDelayUs(32*8); //32 cycles at 125Khz (8us each) + else { + //These timings work for 4469/4269/4305 (with the 55*8 above) + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + SpinDelayUs(23*8); //16-4 cycles off (8us each) + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on + SpinDelayUs(9*8); //16 cycles on (8us each) } + } } - void EM4xLogin(uint32_t Password) { - - uint8_t fwd_bit_count; - - forward_ptr = forwardLink_data; - fwd_bit_count = Prepare_Cmd( FWD_CMD_LOGIN ); - fwd_bit_count += Prepare_Data( Password&0xFFFF, Password>>16 ); - - SendForward(fwd_bit_count); - - //Wait for command to complete - SpinDelay(20); - + + uint8_t fwd_bit_count; + + forward_ptr = forwardLink_data; + fwd_bit_count = Prepare_Cmd( FWD_CMD_LOGIN ); + fwd_bit_count += Prepare_Data( Password&0xFFFF, Password>>16 ); + + SendForward(fwd_bit_count); + + //Wait for command to complete + SpinDelay(20); + } void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) { - - uint8_t fwd_bit_count; - uint8_t *dest = (uint8_t *)BigBuf; - int m=0, i=0; - - //If password mode do login - if (PwdMode == 1) EM4xLogin(Pwd); - - forward_ptr = forwardLink_data; - fwd_bit_count = Prepare_Cmd( FWD_CMD_READ ); - fwd_bit_count += Prepare_Addr( Address ); - - m = sizeof(BigBuf); - // Clear destination buffer before sending the command - memset(dest, 128, m); - // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); - - SendForward(fwd_bit_count); - - // Now do the acquisition - i = 0; - for(;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - i++; - if (i >= m) break; - } + + uint8_t fwd_bit_count; + uint8_t *dest = (uint8_t *)BigBuf; + int m=0, i=0; + + //If password mode do login + if (PwdMode == 1) EM4xLogin(Pwd); + + forward_ptr = forwardLink_data; + fwd_bit_count = Prepare_Cmd( FWD_CMD_READ ); + fwd_bit_count += Prepare_Addr( Address ); + + m = sizeof(BigBuf); + // Clear destination buffer before sending the command + memset(dest, 128, m); + // Connect the A/D to the peak-detected low-frequency path. + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); + + SendForward(fwd_bit_count); + + // Now do the acquisition + i = 0; + for(;;) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0x43; } - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + i++; + if (i >= m) break; + } + } + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + LED_D_OFF(); } void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode) { - - uint8_t fwd_bit_count; - - //If password mode do login - if (PwdMode == 1) EM4xLogin(Pwd); - - forward_ptr = forwardLink_data; - fwd_bit_count = Prepare_Cmd( FWD_CMD_WRITE ); - fwd_bit_count += Prepare_Addr( Address ); - fwd_bit_count += Prepare_Data( Data&0xFFFF, Data>>16 ); - - SendForward(fwd_bit_count); - - //Wait for write to complete - SpinDelay(20); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); + + uint8_t fwd_bit_count; + + //If password mode do login + if (PwdMode == 1) EM4xLogin(Pwd); + + forward_ptr = forwardLink_data; + fwd_bit_count = Prepare_Cmd( FWD_CMD_WRITE ); + fwd_bit_count += Prepare_Addr( Address ); + fwd_bit_count += Prepare_Data( Data&0xFFFF, Data>>16 ); + + SendForward(fwd_bit_count); + + //Wait for write to complete + SpinDelay(20); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + LED_D_OFF(); } diff --git a/client/cmddata.c b/client/cmddata.c index 38917a33c..4b5cb0401 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -21,9 +21,55 @@ #include "cmdmain.h" #include "cmddata.h" #include "lfdemod.h" - +uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN]; +int DemodBufferLen; static int CmdHelp(const char *Cmd); +//set the demod buffer with given array of binary (one bit per byte) +//by marshmellow +void setDemodBuf(uint8_t *buff,int size) +{ + int i=0; + for (; i < size; ++i){ + DemodBuffer[i]=buff[i]; + } + DemodBufferLen=size; + return; +} + +//by marshmellow +void printDemodBuff() +{ + uint32_t i = 0; + int bitLen = DemodBufferLen; + if (bitLen<16) { + PrintAndLog("no bits found in demod buffer"); + return; + } + if (bitLen>512) bitLen=512; //max output to 512 bits if we have more - should be plenty + for (i = 0; i <= (bitLen-16); i+=16) { + PrintAndLog("%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i", + DemodBuffer[i], + DemodBuffer[i+1], + DemodBuffer[i+2], + DemodBuffer[i+3], + DemodBuffer[i+4], + DemodBuffer[i+5], + DemodBuffer[i+6], + DemodBuffer[i+7], + DemodBuffer[i+8], + DemodBuffer[i+9], + DemodBuffer[i+10], + DemodBuffer[i+11], + DemodBuffer[i+12], + DemodBuffer[i+13], + DemodBuffer[i+14], + DemodBuffer[i+15]); + } + return; +} + + int CmdAmp(const char *Cmd) { int i, rising, falling; @@ -185,10 +231,10 @@ void printEM410x(uint64_t id) int CmdEm410xDecode(const char *Cmd) { uint64_t id=0; - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - uint32_t i=0; - i=getFromGraphBuf(BitStream); - id = Em410xDecode(BitStream,i); + // uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + // uint32_t i=0; + // i=getFromGraphBuf(BitStream); + id = Em410xDecode(DemodBuffer,DemodBufferLen); printEM410x(id); if (id>0) return 1; return 0; @@ -209,15 +255,15 @@ int Cmdaskmandemod(const char *Cmd) PrintAndLog("Invalid argument: %s", Cmd); return 0; } - uint32_t BitLen = getFromGraphBuf(BitStream); + + int BitLen = getFromGraphBuf(BitStream); // PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen); int errCnt=0; errCnt = askmandemod(BitStream, &BitLen,&clk,&invert); - if (errCnt<0){ //if fatal error (or -1) + if (errCnt<0||BitLen<16){ //if fatal error (or -1) // PrintAndLog("no data found %d, errors:%d, bitlen:%d, clock:%d",errCnt,invert,BitLen,clk); return 0; } - if (BitLen<16) return 0; PrintAndLog("\nUsing Clock: %d - Invert: %d - Bits Found: %d",clk,invert,BitLen); //output @@ -226,12 +272,12 @@ int Cmdaskmandemod(const char *Cmd) } PrintAndLog("ASK/Manchester decoded bitstream:"); // Now output the bitstream to the scrollback by line of 16 bits - printBitStream(BitStream,BitLen); + setDemodBuf(BitStream,BitLen); + printDemodBuff(); uint64_t lo =0; lo = Em410xDecode(BitStream,BitLen); if (lo>0){ //set GraphBuffer for clone or sim command - setGraphBuf(BitStream,BitLen); PrintAndLog("EM410x pattern found: "); printEM410x(lo); return 1; @@ -250,10 +296,10 @@ int Cmdmandecoderaw(const char *Cmd) int bitnum=0; uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; int high=0,low=0; - for (;ihigh) high=GraphBuffer[i]; - else if(GraphBuffer[i]high) high=DemodBuffer[i]; + else if(DemodBuffer[i]1 || low <0 ){ PrintAndLog("Error: please raw demod the wave first then mancheseter raw decode"); @@ -268,15 +314,9 @@ int Cmdmandecoderaw(const char *Cmd) PrintAndLog("Manchester Decoded - # errors:%d - data:",errCnt); printBitStream(BitStream,bitnum); if (errCnt==0){ - //put back in graphbuffer - ClearGraph(0); - for (i=0; i0) setDemodBuf(BitStream,bitnum); printEM410x(id); } return 1; @@ -301,10 +341,10 @@ int CmdBiphaseDecodeRaw(const char *Cmd) sscanf(Cmd, "%i", &offset); uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; //get graphbuffer & high and low - for (;ihigh)high=GraphBuffer[i]; - else if(GraphBuffer[i]high)high=DemodBuffer[i]; + else if(DemodBuffer[i]1 || low <0){ PrintAndLog("Error: please raw demod the wave first then decode"); @@ -329,7 +369,6 @@ int CmdBiphaseDecodeRaw(const char *Cmd) //prints binary found and saves in graphbuffer for further commands int Cmdaskrawdemod(const char *Cmd) { - int invert=0; int clk=0; uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; @@ -340,23 +379,21 @@ int Cmdaskrawdemod(const char *Cmd) } int BitLen = getFromGraphBuf(BitStream); int errCnt=0; - errCnt = askrawdemod(BitStream, &BitLen, &clk, &invert); - if (errCnt==-1){ //throw away static - allow 1 and -1 (in case of threshold command first) + errCnt = askrawdemod(BitStream, &BitLen,&clk,&invert); + if (errCnt==-1||BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first) PrintAndLog("no data found"); return 0; } - if (BitLen<16) return 0; PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen); //PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum); - //move BitStream back to GraphBuffer - setGraphBuf(BitStream, BitLen); - + //move BitStream back to DemodBuffer + setDemodBuf(BitStream,BitLen); + + //output if (errCnt>0){ PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); } - PrintAndLog("ASK demoded bitstream:"); - // Now output the bitstream to the scrollback by line of 16 bits printBitStream(BitStream,BitLen); @@ -472,6 +509,10 @@ int CmdBitstream(const char *Cmd) bit ^= 1; AppendGraph(0, clock, bit); + // for (j = 0; j < (int)(clock/2); j++) + // GraphBuffer[(i * clock) + j] = bit ^ 1; + // for (j = (int)(clock/2); j < clock; j++) + // GraphBuffer[(i * clock) + j] = bit; } RepaintGraphWindow(); @@ -501,6 +542,8 @@ int CmdDec(const char *Cmd) int CmdDetectClockRate(const char *Cmd) { GetClock("",0,0); + //int clock = DetectASKClock(0); + //PrintAndLog("Auto-detected clock rate: %d", clock); return 0; } @@ -527,18 +570,12 @@ int CmdFSKrawdemod(const char *Cmd) } else if(rfLen==0) rfLen=50; } PrintAndLog("Args invert: %d - Clock:%d - fchigh:%d - fclow: %d",invert,rfLen,fchigh, fclow); - uint32_t i=0; uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; uint32_t BitLen = getFromGraphBuf(BitStream); int size = fskdemod(BitStream,BitLen,(uint8_t)rfLen,(uint8_t)invert,(uint8_t)fchigh,(uint8_t)fclow); if (size>0){ PrintAndLog("FSK decoded bitstream:"); - ClearGraph(0); - for (i=0;i (8*32)+2) size = (8*32)+2; //only output a max of 8 blocks of 32 bits most tags will have full bit stream inside that sample size @@ -567,9 +604,9 @@ int CmdFSKdemodHID(const char *Cmd) } if (hi2==0 && hi==0 && lo==0) return 0; if (hi2 != 0){ //extra large HID tags - PrintAndLog("TAG ID: %x%08x%08x (%d)", + PrintAndLog("HID Prox TAG ID: %x%08x%08x (%d)", (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); - setGraphBuf(BitStream,BitLen); + setDemodBuf(BitStream,BitLen); return 1; } else { //standard HID tags <38 bits @@ -614,10 +651,10 @@ int CmdFSKdemodHID(const char *Cmd) fc = ((hi&0xF)<<12)|(lo>>20); } } - PrintAndLog("TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d", + PrintAndLog("HID Prox TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d", (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF, (unsigned int) fmtLen, (unsigned int) fc, (unsigned int) cardnum); - setGraphBuf(BitStream,BitLen); + setDemodBuf(BitStream,BitLen); return 1; } return 0; @@ -671,9 +708,12 @@ int CmdFSKdemodIO(const char *Cmd) uint8_t version = bytebits_to_byte(BitStream+idx+27,8); //14,4 uint8_t facilitycode = bytebits_to_byte(BitStream+idx+18,8) ; uint16_t number = (bytebits_to_byte(BitStream+idx+36,8)<<8)|(bytebits_to_byte(BitStream+idx+45,8)); //36,9 - - PrintAndLog("XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2); - setGraphBuf(BitStream,BitLen); + PrintAndLog("IO Prox XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2); + int i; + for (i=0;i<64;++i) + DemodBuffer[i]=BitStream[idx++]; + + DemodBufferLen=64; return 1; } int CmdFSKdemod(const char *Cmd) //old CmdFSKdemod needs updating @@ -762,7 +802,8 @@ int CmdFSKdemod(const char *Cmd) //old CmdFSKdemod needs updating PrintAndLog("actual data bits start at sample %d", maxPos); PrintAndLog("length %d/%d", highLen, lowLen); - uint8_t bits[46] = {0x00}; + uint8_t bits[46]; + bits[sizeof(bits)-1] = '\0'; // find bit pairs and manchester decode them for (i = 0; i < arraylen(bits) - 1; ++i) { @@ -794,6 +835,160 @@ int CmdFSKdemod(const char *Cmd) //old CmdFSKdemod needs updating return 0; } +int CmdDetectNRZpskClockRate(const char *Cmd) +{ + GetNRZpskClock("",0,0); + return 0; +} + +int PSKnrzDemod(const char *Cmd){ + int invert=0; + int clk=0; + sscanf(Cmd, "%i %i", &clk, &invert); + if (invert != 0 && invert != 1) { + PrintAndLog("Invalid argument: %s", Cmd); + return -1; + } + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + int BitLen = getFromGraphBuf(BitStream); + int errCnt=0; + errCnt = pskNRZrawDemod(BitStream, &BitLen,&clk,&invert); + if (errCnt<0|| BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first) + //PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); + return -1; + } + PrintAndLog("Tried PSK/NRZ Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen); + + //prime demod buffer for output + setDemodBuf(BitStream,BitLen); + return errCnt; +} +// Indala 26 bit decode +// by marshmellow +// optional arguments - same as CmdpskNRZrawDemod (clock & invert) +int CmdIndalaDecode(const char *Cmd) +{ + + int ans=PSKnrzDemod(Cmd); + if (ans < 0){ + PrintAndLog("Error1: %d",ans); + return 0; + } + uint8_t invert=0; + ans = indala26decode(DemodBuffer, &DemodBufferLen, &invert); + if (ans < 1) { + PrintAndLog("Error2: %d",ans); + return -1; + } + char showbits[251]; + if(invert==1) PrintAndLog("Had to invert bits"); + //convert UID to HEX + uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7; + int idx; + uid1=0; + uid2=0; + PrintAndLog("BitLen: %d",DemodBufferLen); + if (DemodBufferLen==64){ + for( idx=0; idx<64; idx++) { + uid1=(uid1<<1)|(uid2>>31); + if (DemodBuffer[idx] == 0) { + uid2=(uid2<<1)|0; + showbits[idx]='0'; + } else { + uid2=(uid2<<1)|1; + showbits[idx]='1'; + } + } + showbits[idx]='\0'; + PrintAndLog("Indala UID=%s (%x%08x)", showbits, uid1, uid2); + } + else { + uid3=0; + uid4=0; + uid5=0; + uid6=0; + uid7=0; + for( idx=0; idx>31); + uid2=(uid2<<1)|(uid3>>31); + uid3=(uid3<<1)|(uid4>>31); + uid4=(uid4<<1)|(uid5>>31); + uid5=(uid5<<1)|(uid6>>31); + uid6=(uid6<<1)|(uid7>>31); + if (DemodBuffer[idx] == 0) { + uid7=(uid7<<1)|0; + showbits[idx]='0'; + } + else { + uid7=(uid7<<1)|1; + showbits[idx]='1'; + } + } + showbits[idx]='\0'; + PrintAndLog("Indala UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7); + } + return 1; +} + +/* +//by marshmellow (attempt to get rid of high immediately after a low) +void pskCleanWave2(uint8_t *bitStream, int bitLen) +{ + int i; + int low=128; + int gap = 4; + // int loopMax = 2048; + int newLow=0; + + for (i=0; i0){ + PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); + } + PrintAndLog("PSK or NRZ demoded bitstream:"); + // Now output the bitstream to the scrollback by line of 16 bits + printDemodBuff(); + + return 1; +} + + + int CmdGrid(const char *Cmd) { sscanf(Cmd, "%i %i", &PlotGridX, &PlotGridY); @@ -869,21 +1064,22 @@ int CmdHpf(const char *Cmd) int CmdSamples(const char *Cmd) { - uint8_t got[40000] = {0x00}; + int cnt = 0; + int n; + uint8_t got[40000]; - int n = strtol(Cmd, NULL, 0); - if (n == 0) - n = 20000; - - if (n > sizeof(got)) - n = sizeof(got); + n = strtol(Cmd, NULL, 0); + if (n == 0) n = 6000; + if (n > sizeof(got)) n = sizeof(got); - PrintAndLog("Reading %d samples from device memory\n", n); + PrintAndLog("Reading %d samples\n", n); GetFromBigBuf(got,n,0); WaitForResponse(CMD_ACK,NULL); - for (int j = 0; j < n; ++j) { - GraphBuffer[j] = ((int)got[j]) - 128; + for (int j = 0; j < n; j++) { + GraphBuffer[cnt++] = ((int)got[j]) - 128; } + + PrintAndLog("Done!\n"); GraphTraceLen = n; RepaintGraphWindow(); return 0; @@ -1203,8 +1399,9 @@ int CmdNorm(const char *Cmd) if (max != min) { for (i = 0; i < GraphTraceLen; ++i) { - GraphBuffer[i] = (GraphBuffer[i] - ((max + min) / 2)) * 1000 / - (max - min); + GraphBuffer[i] = (GraphBuffer[i] - ((max + min) / 2)) * 256 / + (max - min); + //marshmelow: adjusted *1000 to *256 to make +/- 128 so demod commands still work } } RepaintGraphWindow(); @@ -1327,15 +1524,15 @@ static command_t CommandTable[] = {"help", CmdHelp, 1, "This help"}, {"amp", CmdAmp, 1, "Amplify peaks"}, {"askdemod", Cmdaskdemod, 1, "<0 or 1> -- Attempt to demodulate simple ASK tags"}, - {"askmandemod", Cmdaskmandemod, 1, "[clock] [invert <0|1>] -- Attempt to demodulate ASK/Manchester tags and output binary"}, - {"askrawdemod", Cmdaskrawdemod, 1, "[clock] [invert <0|1>] -- Attempt to demodulate ASK tags and output binary"}, + {"askmandemod", Cmdaskmandemod, 1, "[clock] [invert<0 or 1>] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional[clock will try Auto-detect])"}, + {"askrawdemod", Cmdaskrawdemod, 1, "[clock] [invert<0 or 1>] -- Attempt to demodulate ASK tags and output binary (args optional[clock will try Auto-detect])"}, {"autocorr", CmdAutoCorr, 1, " -- Autocorrelation over window"}, {"biphaserawdecode",CmdBiphaseDecodeRaw,1,"[offset] Biphase decode binary stream already in graph buffer (offset = bit to start decode from)"}, {"bitsamples", CmdBitsamples, 0, "Get raw samples as bitstring"}, {"bitstream", CmdBitstream, 1, "[clock rate] -- Convert waveform into a bitstream"}, {"buffclear", CmdBuffClear, 1, "Clear sample buffer and graph window"}, {"dec", CmdDec, 1, "Decimate samples"}, - {"detectaskclock",CmdDetectClockRate, 1, "Detect ASK clock rate"}, + {"detectclock", CmdDetectClockRate, 1, "Detect ASK, PSK, or NRZ clock rate"}, {"fskdemod", CmdFSKdemod, 1, "Demodulate graph window as a HID FSK"}, {"fskhiddemod", CmdFSKdemodHID, 1, "Demodulate graph window as a HID FSK using raw"}, {"fskiodemod", CmdFSKdemodIO, 1, "Demodulate graph window as an IO Prox FSK using raw"}, @@ -1350,15 +1547,19 @@ static command_t CommandTable[] = {"mandemod", CmdManchesterDemod, 1, "[i] [clock rate] -- Manchester demodulate binary stream (option 'i' to invert output)"}, {"manrawdecode", Cmdmandecoderaw, 1, "Manchester decode binary stream already in graph buffer"}, {"manmod", CmdManchesterMod, 1, "[clock rate] -- Manchester modulate a binary stream"}, - {"norm", CmdNorm, 1, "Normalize max/min to +/-500"}, + {"norm", CmdNorm, 1, "Normalize max/min to +/-128"}, {"plot", CmdPlot, 1, "Show graph window (hit 'h' in window for keystroke help)"}, + {"pskclean", CmdPskClean, 1, "Attempt to clean psk wave"}, + {"pskdetectclock",CmdDetectNRZpskClockRate, 1, "Detect ASK, PSK, or NRZ clock rate"}, + {"pskindalademod",CmdIndalaDecode, 1, "[clock] [invert<0 or 1>] -- Attempt to demodulate psk indala tags and output ID binary & hex (args optional[clock will try Auto-detect])"}, + {"psknrzrawdemod",CmdpskNRZrawDemod, 1, "[clock] [invert<0 or 1>] -- Attempt to demodulate psk or nrz tags and output binary (args optional[clock will try Auto-detect])"}, {"samples", CmdSamples, 0, "[512 - 40000] -- Get raw samples for graph window"}, - {"tune", CmdTuneSamples, 0, "Get hw tune samples for graph window"}, {"save", CmdSave, 1, " -- Save trace (from graph window)"}, {"scale", CmdScale, 1, " -- Set cursor display scale"}, {"threshold", CmdThreshold, 1, " -- Maximize/minimize every value in the graph window depending on threshold"}, - {"zerocrossings", CmdZerocrossings, 1, "Count time between zero-crossings"}, {"dirthreshold", CmdDirectionalThreshold, 1, " -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev."}, + {"tune", CmdTuneSamples, 0, "Get hw tune samples for graph window"}, + {"zerocrossings", CmdZerocrossings, 1, "Count time between zero-crossings"}, {NULL, NULL, 0, NULL} }; diff --git a/client/cmddata.h b/client/cmddata.h index 999e6438c..8723b847a 100644 --- a/client/cmddata.h +++ b/client/cmddata.h @@ -14,7 +14,7 @@ command_t * CmdDataCommands(); int CmdData(const char *Cmd); - +void printDemodBuff(); int CmdAmp(const char *Cmd); int Cmdaskdemod(const char *Cmd); int Cmdaskrawdemod(const char *Cmd); @@ -30,6 +30,8 @@ int CmdFSKdemod(const char *Cmd); int CmdFSKdemodHID(const char *Cmd); int CmdFSKdemodIO(const char *Cmd); int CmdFSKrawdemod(const char *Cmd); +int CmdDetectNRZpskClockRate(const char *Cmd); +int CmdpskNRZrawDemod(const char *Cmd); int CmdGrid(const char *Cmd); int CmdHexsamples(const char *Cmd); int CmdHide(const char *Cmd); @@ -49,5 +51,10 @@ 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); + +#define MAX_DEMOD_BUF_LEN (1024*128) +extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN]; +extern int DemodBufferLen; #endif diff --git a/client/cmdlf.c b/client/cmdlf.c index 18bcf747e..b39868973 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -56,7 +56,7 @@ int CmdFlexdemod(const char *Cmd) } } -#define LONG_WAIT 100 + #define LONG_WAIT 100 int start; for (start = 0; start < GraphTraceLen - LONG_WAIT; start++) { int first = GraphBuffer[start]; @@ -559,18 +559,32 @@ int CmdLFfind(const char *Cmd) ans=CmdSamples("20000"); } if (GraphTraceLen<1000) return 0; + PrintAndLog("NOTE: some demods output possible binary\n if it finds something that looks like a tag"); PrintAndLog("Checking for known tags:"); + ans=Cmdaskmandemod(""); - if (ans>0) return 1; + if (ans>0) { + PrintAndLog("Valid EM410x ID Found!"); + return 1; + } ans=CmdFSKdemodHID(""); - if (ans>0) return 1; + if (ans>0) { + PrintAndLog("Valid HID Prox ID Found!"); + return 1; + } ans=CmdFSKdemodIO(""); - if (ans>0) return 1; + if (ans>0) { + PrintAndLog("Valid IO Prox ID Found!"); + return 1; + } //add psk and indala - ans=CmdIndalaDemod(""); - if (ans>0) return 1; - ans=CmdIndalaDemod("224"); - if (ans>0) return 1; + ans=CmdIndalaDecode(""); + if (ans>0) { + PrintAndLog("Valid Indala ID Found!"); + return 1; + } + // ans=CmdIndalaDemod("224"); + // if (ans>0) return 1; PrintAndLog("No Known Tags Found!\n"); return 0; } diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index 32a0ff7c6..f6f103bf2 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -606,7 +606,7 @@ int CmdWriteWordPWD(const char *Cmd) static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, - {"em410xdemod", CmdEMdemodASK, 0, "[clock rate] -- Extract ID from EM410x tag"}, + {"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, " -- Simulate EM410x tag"}, {"em410xwatch", CmdEM410xWatch, 0, "['h'] -- Watches for EM410x 125/134 kHz tags (option 'h' for 134)"}, diff --git a/client/graph.c b/client/graph.c index a0e85ffd4..d63c42714 100644 --- a/client/graph.c +++ b/client/graph.c @@ -146,7 +146,7 @@ void setGraphBuf(uint8_t *buff,int size) int i=0; ClearGraph(0); for (; i < size; ++i){ - GraphBuffer[i]=buff[i]; + GraphBuffer[i]=buff[i]-128; } GraphTraceLen=size; RepaintGraphWindow(); @@ -187,3 +187,53 @@ int GetClock(const char *str, int peak, int verbose) return clock; } +int GetNRZpskClock(const char *str, int peak, int verbose) +{ + // return GetClock(str,peak,verbose); + int clock; + // int clock2; + sscanf(str, "%i", &clock); + if (!strcmp(str, "")) + clock = 0; + + /* Auto-detect clock */ + if (!clock) + { + uint8_t grph[MAX_GRAPH_TRACE_LEN]={0}; + int size = getFromGraphBuf(grph); + clock = DetectpskNRZClock(grph,size,0); + //clock2 = DetectClock2(peak); + /* Only print this message if we're not looping something */ + if (!verbose){ + PrintAndLog("Auto-detected clock rate: %d", clock); + //PrintAndLog("clock2: %d",clock2); + } + } + return clock; +} +// Get or auto-detect clock rate +/* +int GetNRZpskClock(const char *str, int peak, int verbose) +{ + int clock; +// int clock2; + sscanf(str, "%i", &clock); + if (!strcmp(str, "")) + clock = 0; + + // Auto-detect clock + if (!clock) + { + uint8_t grph[MAX_GRAPH_TRACE_LEN]={0}; + int size = getFromGraphBuf(grph); + clock = DetectASKClock(grph,size,0); + //clock2 = DetectClock2(peak); + // Only print this message if we're not looping something + if (!verbose){ + PrintAndLog("Auto-detected clock rate: %d", clock); + //PrintAndLog("clock2: %d",clock2); + } + } + return clock; +} +*/ \ No newline at end of file diff --git a/client/graph.h b/client/graph.h index 325582a67..c5c137986 100644 --- a/client/graph.h +++ b/client/graph.h @@ -17,6 +17,7 @@ int ClearGraph(int redraw); //int DetectClock(int peak); int getFromGraphBuf(uint8_t *buff); int GetClock(const char *str, int peak, int verbose); +int GetNRZpskClock(const char *str, int peak, int verbose); void setGraphBuf(uint8_t *buff,int size); #define MAX_GRAPH_TRACE_LEN (1024*128) diff --git a/common/lfdemod.c b/common/lfdemod.c index 144783198..ad4721f16 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -14,195 +14,195 @@ //by marshmellow //takes 1s and 0s and searches for EM410x format - output EM ID -uint64_t Em410xDecode(uint8_t *BitStream,uint32_t BitLen) +uint64_t Em410xDecode(uint8_t *BitStream, int BitLen) { - //no arguments needed - built this way in case we want this to be a direct call from "data " cmds in the future - // otherwise could be a void with no arguments - //set defaults - int high=0, low=128; - uint64_t lo=0; //hi=0, + //no arguments needed - built this way in case we want this to be a direct call from "data " cmds in the future + // otherwise could be a void with no arguments + //set defaults + int high=0, low=128; + uint64_t lo=0; //hi=0, - uint32_t i = 0; - uint32_t initLoopMax = 65; - if (initLoopMax>BitLen) initLoopMax=BitLen; + uint32_t i = 0; + uint32_t initLoopMax = 65; + if (initLoopMax>BitLen) initLoopMax=BitLen; - for (;i < initLoopMax; ++i) //65 samples should be plenty to find high and low values - { - if (BitStream[i] > high) - high = BitStream[i]; - else if (BitStream[i] < low) - low = BitStream[i]; - } - if (((high !=1)||(low !=0))){ //allow only 1s and 0s - // PrintAndLog("no data found"); - return 0; - } - uint8_t parityTest=0; - // 111111111 bit pattern represent start of frame - uint8_t frame_marker_mask[] = {1,1,1,1,1,1,1,1,1}; - uint32_t idx = 0; - uint32_t ii=0; - uint8_t resetCnt = 0; - while( (idx + 64) < BitLen) { -restart: - // search for a start of frame marker - if ( memcmp(BitStream+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) - { // frame marker found - idx+=9;//sizeof(frame_marker_mask); - for (i=0; i<10;i++){ - for(ii=0; ii<5; ++ii){ - parityTest += BitStream[(i*5)+ii+idx]; - } - if (parityTest== ((parityTest>>1)<<1)){ - parityTest=0; - for (ii=0; ii<4;++ii){ - //hi = (hi<<1)|(lo>>31); - lo=(lo<<1LL)|(BitStream[(i*5)+ii+idx]); - } - //PrintAndLog("DEBUG: EM parity passed parity val: %d, i:%d, ii:%d,idx:%d, Buffer: %d%d%d%d%d,lo: %d",parityTest,i,ii,idx,BitStream[idx+ii+(i*5)-5],BitStream[idx+ii+(i*5)-4],BitStream[idx+ii+(i*5)-3],BitStream[idx+ii+(i*5)-2],BitStream[idx+ii+(i*5)-1],lo); - }else {//parity failed - //PrintAndLog("DEBUG: EM parity failed parity val: %d, i:%d, ii:%d,idx:%d, Buffer: %d%d%d%d%d",parityTest,i,ii,idx,BitStream[idx+ii+(i*5)-5],BitStream[idx+ii+(i*5)-4],BitStream[idx+ii+(i*5)-3],BitStream[idx+ii+(i*5)-2],BitStream[idx+ii+(i*5)-1]); - parityTest=0; - idx-=8; - if (resetCnt>5)return 0; - resetCnt++; - goto restart;//continue; - } - } - //skip last 5 bit parity test for simplicity. - return lo; - }else{ - idx++; - } - } + for (;i < initLoopMax; ++i) //65 samples should be plenty to find high and low values + { + if (BitStream[i] > high) + high = BitStream[i]; + else if (BitStream[i] < low) + low = BitStream[i]; + } + if (((high !=1)||(low !=0))){ //allow only 1s and 0s + // PrintAndLog("no data found"); return 0; + } + uint8_t parityTest=0; + // 111111111 bit pattern represent start of frame + uint8_t frame_marker_mask[] = {1,1,1,1,1,1,1,1,1}; + uint32_t idx = 0; + uint32_t ii=0; + uint8_t resetCnt = 0; + while( (idx + 64) < BitLen) { + restart: + // search for a start of frame marker + if ( memcmp(BitStream+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) + { // frame marker found + idx+=9;//sizeof(frame_marker_mask); + for (i=0; i<10;i++){ + for(ii=0; ii<5; ++ii){ + parityTest += BitStream[(i*5)+ii+idx]; + } + if (parityTest== ((parityTest>>1)<<1)){ + parityTest=0; + for (ii=0; ii<4;++ii){ + //hi = (hi<<1)|(lo>>31); + lo=(lo<<1LL)|(BitStream[(i*5)+ii+idx]); + } + //PrintAndLog("DEBUG: EM parity passed parity val: %d, i:%d, ii:%d,idx:%d, Buffer: %d%d%d%d%d,lo: %d",parityTest,i,ii,idx,BitStream[idx+ii+(i*5)-5],BitStream[idx+ii+(i*5)-4],BitStream[idx+ii+(i*5)-3],BitStream[idx+ii+(i*5)-2],BitStream[idx+ii+(i*5)-1],lo); + }else {//parity failed + //PrintAndLog("DEBUG: EM parity failed parity val: %d, i:%d, ii:%d,idx:%d, Buffer: %d%d%d%d%d",parityTest,i,ii,idx,BitStream[idx+ii+(i*5)-5],BitStream[idx+ii+(i*5)-4],BitStream[idx+ii+(i*5)-3],BitStream[idx+ii+(i*5)-2],BitStream[idx+ii+(i*5)-1]); + parityTest=0; + idx-=8; + if (resetCnt>5)return 0; + resetCnt++; + goto restart;//continue; + } + } + //skip last 5 bit parity test for simplicity. + return lo; + }else{ + idx++; + } + } + return 0; } //by marshmellow //takes 2 arguments - clock and invert both as integers //attempts to demodulate ask while decoding manchester //prints binary found and saves in graphbuffer for further commands -int askmandemod(uint8_t * BinStream,uint32_t *BitLen,int *clk, int *invert) +int askmandemod(uint8_t * BinStream, int *BitLen,int *clk, int *invert) { - int i; - int high = 0, low = 128; - *clk=DetectASKClock(BinStream,(size_t)*BitLen,*clk); //clock default + int i; + int high = 0, low = 128; + *clk=DetectASKClock(BinStream,(size_t)*BitLen,*clk); //clock default - if (*clk<8) *clk =64; - if (*clk<32) *clk=32; - if (*invert != 0 && *invert != 1) *invert=0; - uint32_t initLoopMax = 200; - if (initLoopMax>*BitLen) initLoopMax=*BitLen; - // Detect high and lows - for (i = 0; i < initLoopMax; ++i) //200 samples should be enough to find high and low values - { - if (BinStream[i] > high) - high = BinStream[i]; - else if (BinStream[i] < low) - low = BinStream[i]; - } - if ((high < 158) ){ //throw away static - //PrintAndLog("no data found"); - return -2; - } - //25% fuzz in case highs and lows aren't clipped [marshmellow] - high=(int)((high-128)*.75)+128; - low= (int)((low-128)*.75)+128; - - //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); - int lastBit = 0; //set first clock check - uint32_t bitnum = 0; //output counter - int 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 - int iii = 0; - uint32_t gLen = *BitLen; - if (gLen > 3000) gLen=3000; - uint8_t errCnt =0; - uint32_t bestStart = *BitLen; - uint32_t bestErrCnt = (*BitLen/1000); - uint32_t maxErr = (*BitLen/1000); - //PrintAndLog("DEBUG - lastbit - %d",lastBit); - //loop to find first wave that works - for (iii=0; iii < gLen; ++iii){ - if ((BinStream[iii]>=high)||(BinStream[iii]<=low)){ - lastBit=iii-*clk; - errCnt=0; - //loop through to see if this start location works - for (i = iii; i < *BitLen; ++i) { - if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){ - lastBit+=*clk; - } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ - //low found and we are expecting a bar - lastBit+=*clk; - } else { - //mid value found or no bar supposed to be here - if ((i-lastBit)>(*clk+tol)){ - //should have hit a high or low based on clock!! - - //debug - //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; //allow 1 error for every 1000 samples else start over - } - } - if ((i-iii) >(400 * *clk)) break; //got plenty of bits - } - //we got more than 64 good bits and not all errors - if ((((i-iii)/ *clk) > (64+errCnt)) && (errCnt*BitLen) initLoopMax=*BitLen; + // Detect high and lows + for (i = 0; i < initLoopMax; ++i) //200 samples should be enough to find high and low values + { + if (BinStream[i] > high) + high = BinStream[i]; + else if (BinStream[i] < low) + low = BinStream[i]; + } + if ((high < 158) ){ //throw away static + //PrintAndLog("no data found"); + return -2; + } + //25% fuzz in case highs and lows aren't clipped [marshmellow] + high=(int)((high-128)*.75)+128; + low= (int)((low-128)*.75)+128; + + //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); + int lastBit = 0; //set first clock check + uint32_t bitnum = 0; //output counter + int 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 + int iii = 0; + uint32_t gLen = *BitLen; + if (gLen > 3000) gLen=3000; + uint8_t errCnt =0; + uint32_t bestStart = *BitLen; + uint32_t bestErrCnt = (*BitLen/1000); + uint32_t maxErr = (*BitLen/1000); + //PrintAndLog("DEBUG - lastbit - %d",lastBit); + //loop to find first wave that works + for (iii=0; iii < gLen; ++iii){ + if ((BinStream[iii]>=high)||(BinStream[iii]<=low)){ + lastBit=iii-*clk; + errCnt=0; + //loop through to see if this start location works + for (i = iii; i < *BitLen; ++i) { + if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){ + lastBit+=*clk; + } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ + //low found and we are expecting a bar + lastBit+=*clk; + } else { + //mid value found or no bar supposed to be here + if ((i-lastBit)>(*clk+tol)){ + //should have hit a high or low based on clock!! + + //debug + //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; //allow 1 error for every 1000 samples else start over + } } - } - if (bestErrCnt= high) && ((i-lastBit)>(*clk-tol))){ - lastBit+=*clk; - BinStream[bitnum] = *invert; - bitnum++; - } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ - //low found and we are expecting a bar - lastBit+=*clk; - BinStream[bitnum] = 1-*invert; - bitnum++; - } else { - //mid value found or no bar supposed to be here - if ((i-lastBit)>(*clk+tol)){ - //should have hit a high or low based on clock!! - - //debug - //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; - bitnum++; - } - - lastBit+=*clk;//skip over error - } - } - if (bitnum >=400) break; + if ((i-iii) >(400 * *clk)) break; //got plenty of bits + } + //we got more than 64 good bits and not all errors + if ((((i-iii)/ *clk) > (64+errCnt)) && (errCnt= high) && ((i-lastBit)>(*clk-tol))){ + lastBit+=*clk; + BinStream[bitnum] = *invert; + bitnum++; + } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ + //low found and we are expecting a bar + lastBit+=*clk; + BinStream[bitnum] = 1-*invert; + bitnum++; + } else { + //mid value found or no bar supposed to be here + if ((i-lastBit)>(*clk+tol)){ + //should have hit a high or low based on clock!! + + //debug + //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; + bitnum++; + } + + lastBit+=*clk;//skip over error + } + } + if (bitnum >=400) break; + } + *BitLen=bitnum; + } else{ + *invert=bestStart; + *clk=iii; + return -1; + } + return bestErrCnt; } //by marshmellow @@ -210,46 +210,46 @@ int askmandemod(uint8_t * BinStream,uint32_t *BitLen,int *clk, int *invert) //run through 2 times and take least errCnt int manrawdecode(uint8_t * BitStream, int *bitLen) { - int bitnum=0; - int errCnt =0; - int i=1; - int bestErr = 1000; - int bestRun = 0; - int ii=1; - for (ii=1;ii<3;++ii){ - i=1; - for (i=i+ii;i<*bitLen-2;i+=2){ - if(BitStream[i]==1 && (BitStream[i+1]==0)){ - } else if((BitStream[i]==0)&& BitStream[i+1]==1){ - } else { - errCnt++; - } - if(bitnum>300) break; - } - if (bestErr>errCnt){ - bestErr=errCnt; - bestRun=ii; - } - errCnt=0; - } - errCnt=bestErr; - if (errCnt<20){ - ii=bestRun; - i=1; - for (i=i+ii;i<*bitLen-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; - //errCnt++; - } - if(bitnum>300) break; - } - *bitLen=bitnum; - } - return errCnt; + int bitnum=0; + int errCnt =0; + int i=1; + int bestErr = 1000; + int bestRun = 0; + int ii=1; + for (ii=1;ii<3;++ii){ + i=1; + for (i=i+ii;i<*bitLen-2;i+=2){ + if(BitStream[i]==1 && (BitStream[i+1]==0)){ + } else if((BitStream[i]==0)&& BitStream[i+1]==1){ + } else { + errCnt++; + } + if(bitnum>300) break; + } + if (bestErr>errCnt){ + bestErr=errCnt; + bestRun=ii; + } + errCnt=0; + } + errCnt=bestErr; + if (errCnt<20){ + ii=bestRun; + i=1; + for (i=i+ii;i<*bitLen-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; + //errCnt++; + } + if(bitnum>300) break; + } + *bitLen=bitnum; + } + return errCnt; } @@ -257,23 +257,23 @@ int manrawdecode(uint8_t * BitStream, int *bitLen) //take 01 or 10 = 0 and 11 or 00 = 1 int BiphaseRawDecode(uint8_t * BitStream, int *bitLen, int offset) { - uint8_t bitnum=0; - uint32_t errCnt =0; - uint32_t i=1; - i=offset; - for (;i<*bitLen-2;i+=2){ - if((BitStream[i]==1 && BitStream[i+1]==0)||(BitStream[i]==0 && BitStream[i+1]==1)){ - BitStream[bitnum++]=1; - } else if((BitStream[i]==0 && BitStream[i+1]==0)||(BitStream[i]==1 && BitStream[i+1]==1)){ - BitStream[bitnum++]=0; - } else { - BitStream[bitnum++]=77; - errCnt++; - } - if(bitnum>250) break; + uint8_t bitnum=0; + uint32_t errCnt =0; + uint32_t i=1; + i=offset; + for (;i<*bitLen-2;i+=2){ + if((BitStream[i]==1 && BitStream[i+1]==0)||(BitStream[i]==0 && BitStream[i+1]==1)){ + BitStream[bitnum++]=1; + } else if((BitStream[i]==0 && BitStream[i+1]==0)||(BitStream[i]==1 && BitStream[i+1]==1)){ + BitStream[bitnum++]=0; + } else { + BitStream[bitnum++]=77; + errCnt++; } - *bitLen=bitnum; - return errCnt; + if(bitnum>250) break; + } + *bitLen=bitnum; + return errCnt; } //by marshmellow @@ -282,351 +282,352 @@ int BiphaseRawDecode(uint8_t * BitStream, int *bitLen, int offset) //prints binary found and saves in graphbuffer for further commands int askrawdemod(uint8_t *BinStream, int *bitLen,int *clk, int *invert) { - uint32_t i; - // int invert=0; //invert default - int high = 0, low = 128; - *clk=DetectASKClock(BinStream,*bitLen,*clk); //clock default - uint8_t BitStream[502] = {0}; + uint32_t i; + // int invert=0; //invert default + int high = 0, low = 128; + *clk=DetectASKClock(BinStream,*bitLen,*clk); //clock default + uint8_t BitStream[502] = {0}; - if (*clk<8) *clk =64; - if (*clk<32) *clk=32; - if (*invert != 0 && *invert != 1) *invert =0; - uint32_t initLoopMax = 200; - if (initLoopMax>*bitLen) initLoopMax=*bitLen; - // Detect high and lows - for (i = 0; i < initLoopMax; ++i) //200 samples should be plenty to find high and low values - { - if (BinStream[i] > high) - high = BinStream[i]; - else if (BinStream[i] < low) - low = BinStream[i]; - } - if ((high < 158)){ //throw away static - // PrintAndLog("no data found"); - return -2; - } - //25% fuzz in case highs and lows aren't clipped [marshmellow] - high=(int)((high-128)*.75)+128; - low= (int)((low-128)*.75)+128; + if (*clk<8) *clk =64; + if (*clk<32) *clk=32; + if (*invert != 0 && *invert != 1) *invert =0; + uint32_t initLoopMax = 200; + if (initLoopMax>*bitLen) initLoopMax=*bitLen; + // Detect high and lows + for (i = 0; i < initLoopMax; ++i) //200 samples should be plenty to find high and low values + { + if (BinStream[i] > high) + high = BinStream[i]; + else if (BinStream[i] < low) + low = BinStream[i]; + } + if ((high < 158)){ //throw away static + // PrintAndLog("no data found"); + return -2; + } + //25% fuzz in case highs and lows aren't clipped [marshmellow] + high=(int)((high-128)*.75)+128; + low= (int)((low-128)*.75)+128; - //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); - int lastBit = 0; //set first clock check - uint32_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 - uint32_t iii = 0; - uint32_t gLen = *bitLen; - if (gLen > 500) gLen=500; - uint8_t errCnt =0; - uint32_t bestStart = *bitLen; - uint32_t bestErrCnt = (*bitLen/1000); - uint8_t midBit=0; - //PrintAndLog("DEBUG - lastbit - %d",lastBit); - //loop to find first wave that works - for (iii=0; iii < gLen; ++iii){ - if ((BinStream[iii]>=high)||(BinStream[iii]<=low)){ - lastBit=iii-*clk; - //loop through to see if this start location works - for (i = iii; i < *bitLen; ++i) { - if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){ - lastBit+=*clk; - BitStream[bitnum] = *invert; - bitnum++; - midBit=0; - } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ - //low found and we are expecting a bar - lastBit+=*clk; - BitStream[bitnum] = 1-*invert; - bitnum++; - midBit=0; - } else if ((BinStream[i]<=low) && (midBit==0) && ((i-lastBit)>((*clk/2)-tol))){ - //mid bar? - midBit=1; - BitStream[bitnum]= 1-*invert; - bitnum++; - } else if ((BinStream[i]>=high)&&(midBit==0) && ((i-lastBit)>((*clk/2)-tol))){ - //mid bar? - midBit=1; - BitStream[bitnum]= *invert; - bitnum++; - } else if ((i-lastBit)>((*clk/2)+tol)&&(midBit==0)){ - //no mid bar found - midBit=1; - BitStream[bitnum]= BitStream[bitnum-1]; - bitnum++; - } else { - //mid value found or no bar supposed to be here + //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); + int lastBit = 0; //set first clock check + uint32_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 + uint32_t iii = 0; + uint32_t gLen = *bitLen; + if (gLen > 500) gLen=500; + uint8_t errCnt =0; + uint32_t bestStart = *bitLen; + uint32_t bestErrCnt = (*bitLen/1000); + uint8_t midBit=0; + //PrintAndLog("DEBUG - lastbit - %d",lastBit); + //loop to find first wave that works + for (iii=0; iii < gLen; ++iii){ + if ((BinStream[iii]>=high)||(BinStream[iii]<=low)){ + lastBit=iii-*clk; + //loop through to see if this start location works + for (i = iii; i < *bitLen; ++i) { + if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){ + lastBit+=*clk; + BitStream[bitnum] = *invert; + bitnum++; + midBit=0; + } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ + //low found and we are expecting a bar + lastBit+=*clk; + BitStream[bitnum] = 1-*invert; + bitnum++; + midBit=0; + } else if ((BinStream[i]<=low) && (midBit==0) && ((i-lastBit)>((*clk/2)-tol))){ + //mid bar? + midBit=1; + BitStream[bitnum]= 1-*invert; + bitnum++; + } else if ((BinStream[i]>=high)&&(midBit==0) && ((i-lastBit)>((*clk/2)-tol))){ + //mid bar? + midBit=1; + BitStream[bitnum]= *invert; + bitnum++; + } else if ((i-lastBit)>((*clk/2)+tol)&&(midBit==0)){ + //no mid bar found + midBit=1; + BitStream[bitnum]= BitStream[bitnum-1]; + bitnum++; + } else { + //mid value found or no bar supposed to be here - if ((i-lastBit)>(*clk+tol)){ - //should have hit a high or low based on clock!! - //debug - //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){ - BitStream[bitnum]=77; - bitnum++; - } - - - errCnt++; - lastBit+=*clk;//skip over until hit too many errors - if (errCnt>((*bitLen/1000))){ //allow 1 error for every 1000 samples else start over - errCnt=0; - bitnum=0;//start over - break; - } - } - } - if (bitnum>500) break; + if ((i-lastBit)>(*clk+tol)){ + //should have hit a high or low based on clock!! + //debug + //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){ + BitStream[bitnum]=77; + bitnum++; } - //we got more than 64 good bits and not all errors - if ((bitnum > (64+errCnt)) && (errCnt<(*bitLen/1000))) { - //possible good read - if (errCnt==0) break; //great read - finish - if (bestStart == iii) break; //if current run == bestErrCnt run (after exhausted testing) then finish - if (errCnt((*bitLen/1000))){ //allow 1 error for every 1000 samples else start over + errCnt=0; + bitnum=0;//start over + break; } + } } - if (iii>=gLen){ //exhausted test - //if there was a ok test go back to that one and re-run the best run (then dump after that run) - if (bestErrCnt < (*bitLen/1000)) iii=bestStart; + if (bitnum>500) break; + } + //we got more than 64 good bits and not all errors + if ((bitnum > (64+errCnt)) && (errCnt<(*bitLen/1000))) { + //possible good read + if (errCnt==0) break; //great read - finish + if (bestStart == iii) break; //if current run == bestErrCnt run (after exhausted testing) then finish + if (errCnt16){ + if (iii>=gLen){ //exhausted test + //if there was a ok test go back to that one and re-run the best run (then dump after that run) + if (bestErrCnt < (*bitLen/1000)) iii=bestStart; + } + } + if (bitnum>16){ + + // PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum); + //move BitStream back to BinStream + // ClearGraph(0); + for (i=0; i < bitnum; ++i){ + BinStream[i]=BitStream[i]; + } + *bitLen=bitnum; + // RepaintGraphWindow(); + //output + // if (errCnt>0){ + // PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); + // } + // PrintAndLog("ASK decoded bitstream:"); + // Now output the bitstream to the scrollback by line of 16 bits + // printBitStream2(BitStream,bitnum); + //int errCnt=0; + //errCnt=manrawdemod(BitStream,bitnum); - // PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum); - //move BitStream back to BinStream - // ClearGraph(0); - for (i=0; i < bitnum; ++i){ - BinStream[i]=BitStream[i]; - } - *bitLen=bitnum; - // RepaintGraphWindow(); - //output - // if (errCnt>0){ - // PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); - // } - // PrintAndLog("ASK decoded bitstream:"); - // Now output the bitstream to the scrollback by line of 16 bits - // printBitStream2(BitStream,bitnum); - //int errCnt=0; - //errCnt=manrawdemod(BitStream,bitnum); - - // Em410xDecode(Cmd); - } else return -1; - return errCnt; + // Em410xDecode(Cmd); + } else return -1; + return errCnt; } //translate wave to 11111100000 (1 for each short wave 0 for each long wave) size_t fsk_wave_demod(uint8_t * dest, size_t size, uint8_t fchigh, uint8_t fclow) { - uint32_t last_transition = 0; - uint32_t idx = 1; - uint32_t maxVal=0; - if (fchigh==0) fchigh=10; - if (fclow==0) fclow=8; - // we do care about the actual theshold value as sometimes near the center of the - // wave we may get static that changes direction of wave for one value - // if our value is too low it might affect the read. and if our tag or - // antenna is weak a setting too high might not see anything. [marshmellow] - if (size<100) return 0; - for(idx=1; idx<100; idx++){ - if(maxVal1 transition - if (dest[idx-1] < dest[idx]) { // 0 -> 1 transition - if ((idx-last_transition)<(fclow-2)){ //0-5 = garbage noise - //do nothing with extra garbage - } else if ((idx-last_transition) < (fchigh-1)) { //6-8 = 8 waves - dest[numBits]=1; - } else { //9+ = 10 waves - dest[numBits]=0; - } - last_transition = idx; - numBits++; - } - } - return numBits; //Actually, it returns the number of bytes, but each byte represents a bit: 1 or 0 + // Check for 0->1 transition + if (dest[idx-1] < dest[idx]) { // 0 -> 1 transition + if ((idx-last_transition)<(fclow-2)){ //0-5 = garbage noise + //do nothing with extra garbage + } else if ((idx-last_transition) < (fchigh-1)) { //6-8 = 8 waves + dest[numBits]=1; + } else { //9+ = 10 waves + dest[numBits]=0; + } + last_transition = idx; + numBits++; + } + } + return numBits; //Actually, it returns the number of bytes, but each byte represents a bit: 1 or 0 } uint32_t myround2(float f) { - if (f >= 2000) return 2000;//something bad happened - return (uint32_t) (f + (float)0.5); + if (f >= 2000) return 2000;//something bad happened + return (uint32_t) (f + (float)0.5); } //translate 11111100000 to 10 size_t aggregate_bits(uint8_t *dest,size_t size, uint8_t rfLen, uint8_t maxConsequtiveBits, uint8_t invert,uint8_t fchigh,uint8_t fclow )// uint8_t h2l_crossing_value,uint8_t l2h_crossing_value, { - uint8_t lastval=dest[0]; - uint32_t idx=0; - size_t numBits=0; - uint32_t n=1; + uint8_t lastval=dest[0]; + uint32_t idx=0; + size_t numBits=0; + uint32_t n=1; - for( idx=1; idx < size; idx++) { + for( idx=1; idx < size; idx++) { - if (dest[idx]==lastval) { - n++; - continue; - } - //if lastval was 1, we have a 1->0 crossing - if ( dest[idx-1]==1 ) { - n=myround2((float)(n+1)/((float)(rfLen)/(float)fclow)); - //n=(n+1) / h2l_crossing_value; - } else {// 0->1 crossing - n=myround2((float)(n+1)/((float)(rfLen-2)/(float)fchigh)); //-2 for fudge factor - //n=(n+1) / l2h_crossing_value; - } - if (n == 0) n = 1; + if (dest[idx]==lastval) { + n++; + continue; + } + //if lastval was 1, we have a 1->0 crossing + if ( dest[idx-1]==1 ) { + n=myround2((float)(n+1)/((float)(rfLen)/(float)fclow)); + //n=(n+1) / h2l_crossing_value; + } else {// 0->1 crossing + n=myround2((float)(n+1)/((float)(rfLen-2)/(float)fchigh)); //-2 for fudge factor + //n=(n+1) / l2h_crossing_value; + } + if (n == 0) n = 1; - if(n < maxConsequtiveBits) //Consecutive - { - if(invert==0){ //invert bits - memset(dest+numBits, dest[idx-1] , n); - }else{ - memset(dest+numBits, dest[idx-1]^1 , n); - } - numBits += n; - } - n=0; - lastval=dest[idx]; - }//end for - return numBits; + if(n < maxConsequtiveBits) //Consecutive + { + if(invert==0){ //invert bits + memset(dest+numBits, dest[idx-1] , n); + }else{ + memset(dest+numBits, dest[idx-1]^1 , n); + } + numBits += n; + } + n=0; + lastval=dest[idx]; + }//end for + return numBits; } //by marshmellow (from holiman's base) // full fsk demod from GraphBuffer wave to decoded 1s and 0s (no mandemod) int fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uint8_t fchigh, uint8_t fclow) { - // FSK demodulator - size = fsk_wave_demod(dest, size, fchigh, fclow); - size = aggregate_bits(dest, size,rfLen,192,invert,fchigh,fclow); - return size; + // FSK demodulator + size = fsk_wave_demod(dest, size, fchigh, fclow); + size = aggregate_bits(dest, size,rfLen,192,invert,fchigh,fclow); + return size; } // loop to get raw HID waveform then FSK demodulate the TAG ID from it int HIDdemodFSK(uint8_t *dest, size_t size, uint32_t *hi2, uint32_t *hi, uint32_t *lo) { + + size_t idx=0; //, found=0; //size=0, + // FSK demodulator + size = fskdemod(dest, size,50,0,10,8); - size_t idx=0; //, found=0; //size=0, - // FSK demodulator - size = fskdemod(dest, size,50,0,10,8); - - // final loop, go over previously decoded manchester data and decode into usable tag ID - // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0 - uint8_t frame_marker_mask[] = {1,1,1,0,0,0}; - int numshifts = 0; - idx = 0; - //one scan - while( idx + sizeof(frame_marker_mask) < size) { - // search for a start of frame marker - if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) - { // frame marker found - idx+=sizeof(frame_marker_mask); - while(dest[idx] != dest[idx+1] && idx < size-2) - { - // Keep going until next frame marker (or error) - // Shift in a bit. Start by shifting high registers - *hi2 = (*hi2<<1)|(*hi>>31); - *hi = (*hi<<1)|(*lo>>31); - //Then, shift in a 0 or one into low - if (dest[idx] && !dest[idx+1]) // 1 0 - *lo=(*lo<<1)|0; - else // 0 1 - *lo=(*lo<<1)|1; - numshifts++; - idx += 2; - } - // Hopefully, we read a tag and hit upon the next frame marker - if(idx + sizeof(frame_marker_mask) < size) - { - if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) - { - //good return - return idx; - } - } - // reset - *hi2 = *hi = *lo = 0; - numshifts = 0; - }else { - idx++; - } - } - return -1; + // final loop, go over previously decoded manchester data and decode into usable tag ID + // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0 + uint8_t frame_marker_mask[] = {1,1,1,0,0,0}; + int numshifts = 0; + idx = 0; + //one scan + while( idx + sizeof(frame_marker_mask) < size) { + // search for a start of frame marker + if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) + { // frame marker found + idx+=sizeof(frame_marker_mask); + while(dest[idx] != dest[idx+1] && idx < size-2) + { + // Keep going until next frame marker (or error) + // Shift in a bit. Start by shifting high registers + *hi2 = (*hi2<<1)|(*hi>>31); + *hi = (*hi<<1)|(*lo>>31); + //Then, shift in a 0 or one into low + if (dest[idx] && !dest[idx+1]) // 1 0 + *lo=(*lo<<1)|0; + else // 0 1 + *lo=(*lo<<1)|1; + numshifts++; + idx += 2; + } + // Hopefully, we read a tag and hit upon the next frame marker + if(idx + sizeof(frame_marker_mask) < size) + { + if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) + { + //good return + return idx; + } + } + // reset + *hi2 = *hi = *lo = 0; + numshifts = 0; + }else { + idx++; + } + } + return -1; } uint32_t bytebits_to_byte(uint8_t* src, int numbits) { - uint32_t num = 0; - for(int i = 0 ; i < numbits ; i++) - { - num = (num << 1) | (*src); - src++; - } - return num; + uint32_t num = 0; + for(int i = 0 ; i < numbits ; i++) + { + num = (num << 1) | (*src); + src++; + } + return num; } int IOdemodFSK(uint8_t *dest, size_t size) { - static const uint8_t THRESHOLD = 140; - uint32_t idx=0; - //make sure buffer has data - if (size < 66) return -1; - //test samples are not just noise - uint8_t justNoise = 1; - for(idx=0;idx< size && justNoise ;idx++){ - justNoise = dest[idx] < THRESHOLD; + uint32_t idx=0; + //make sure buffer has data + if (size < 66) return -1; + //test samples are not just noise + uint8_t testMax=0; + for(idx=0;idx<65;idx++){ + if (testMax170){ + // FSK demodulator + size = fskdemod(dest, size,64,1,10,8); // RF/64 and invert + if (size < 65) return -1; //did we get a good demod? + //Index map + //0 10 20 30 40 50 60 + //| | | | | | | + //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23 + //----------------------------------------------------------------------------- + //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11 + // + //XSF(version)facility:codeone+codetwo + //Handle the data + uint8_t mask[] = {0,0,0,0,0,0,0,0,0,1}; + for( idx=0; idx < (size - 65); idx++) { + if ( memcmp(dest + idx, mask, sizeof(mask))==0) { + //frame marker found + if (!dest[idx+8] && dest[idx+17]==1 && dest[idx+26]==1 && dest[idx+35]==1 && dest[idx+44]==1 && dest[idx+53]==1){ + //confirmed proper separator bits found + //return start position + return (int) idx; + } + } } - } - return 0; + } + return 0; } // by marshmellow @@ -634,67 +635,521 @@ int IOdemodFSK(uint8_t *dest, size_t size) // maybe somehow adjust peak trimming value based on samples to fix? int DetectASKClock(uint8_t dest[], size_t size, int clock) { - int i=0; - int peak=0; - int low=128; - int clk[]={16,32,40,50,64,100,128,256}; - int loopCnt = 256; //don't need to loop through entire array... - if (sizepeak){ - peak = dest[i]; - } - if(dest[i]peak){ + peak = dest[i]; } - peak=(int)((peak-128)*.75)+128; - low= (int)((low-128)*.75)+128; - int ii; - int clkCnt; - int tol = 0; - int bestErr=1000; - int errCnt[]={0,0,0,0,0,0,0,0}; - //test each valid clock from smallest to greatest to see which lines up - for(clkCnt=0; clkCnt<6;++clkCnt){ - if (clk[clkCnt]==32){ - tol=1; - }else{ - tol=0; - } - bestErr=1000; - //try lining up the peaks by moving starting point (try first 256) - for (ii=0; ii=peak) || (dest[ii]<=low)){ - errCnt[clkCnt]=0; - // now that we have the first one lined up test rest of wave array - for (i=0; i<((int)(size/clk[clkCnt])-1); ++i){ - if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){ - }else if(dest[ii+(i*clk[clkCnt])-tol]>=peak || dest[ii+(i*clk[clkCnt])-tol]<=low){ - }else if(dest[ii+(i*clk[clkCnt])+tol]>=peak || dest[ii+(i*clk[clkCnt])+tol]<=low){ - }else{ //error no peak detected - errCnt[clkCnt]++; - } - } - //if we found no errors this is correct one - return this clock - if(errCnt[clkCnt]==0) return clk[clkCnt]; - //if we found errors see if it is lowest so far and save it as best run - if(errCnt[clkCnt]=peak) || (dest[ii]<=low)){ + errCnt=0; + // now that we have the first one lined up test rest of wave array + for (i=0; i<((int)(size/clk[clkCnt])-1); ++i){ + if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){ + }else if(dest[ii+(i*clk[clkCnt])-tol]>=peak || dest[ii+(i*clk[clkCnt])-tol]<=low){ + }else if(dest[ii+(i*clk[clkCnt])+tol]>=peak || dest[ii+(i*clk[clkCnt])+tol]<=low){ + }else{ //error no peak detected + errCnt++; + } + } + //if we found no errors this is correct one - return this clock + if(errCnt==0) return clk[clkCnt]; + //if we found errors see if it is lowest so far and save it as best run + if(errCntpeak){ + peak = dest[i]; + } + if(dest[i]=peak) || (dest[ii]<=low)){ + errCnt=0; + peakcnt=0; + // now that we have the first one lined up test rest of wave array + for (i=0; i<((int)(size/clk[clkCnt])-1); ++i){ + if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){ + peakcnt++; + }else if(dest[ii+(i*clk[clkCnt])-tol]>=peak || dest[ii+(i*clk[clkCnt])-tol]<=low){ + peakcnt++; + }else if(dest[ii+(i*clk[clkCnt])+tol]>=peak || dest[ii+(i*clk[clkCnt])+tol]<=low){ + peakcnt++; + }else{ //error no peak detected + errCnt++; + } + } + if(peakcnt>peaksdet[clkCnt]) { + peaksdet[clkCnt]=peakcnt; + bestErr[clkCnt]=errCnt; + } + } + } + } + int iii=0; + int best=0; + //int ratio2; //debug + int ratio; + //int bits; + for (iii=0; iii<7;++iii){ + ratio=1000; + //ratio2=1000; //debug + //bits=size/clk[iii]; //debug + if (peaksdet[iii]>0){ + ratio=bestErr[iii]/peaksdet[iii]; + if (((bestErr[best]/peaksdet[best])>(ratio)+1)){ + best = iii; + } + //ratio2=bits/peaksdet[iii]; //debug + } + //PrintAndLog("DEBUG: Clk: %d, peaks: %d, errs: %d, bestClk: %d, ratio: %d, bits: %d, peakbitr: %d",clk[iii],peaksdet[iii],bestErr[iii],clk[best],ratio, bits,ratio2); + } + return clk[best]; +} + +/* +int DetectNRZpskClock(uint8_t dest[], size_t size, int clock) +{ + int i=0; + int peak=0; + int low=128; + int clk[]={16,32,40,50,64,100,128,256}; + int loopCnt = 1500; //don't need to loop through entire array... + if (sizepeak){ + peak = dest[i]; + } + if(dest[i]=peak) || (dest[ii]<=low)){ + lastClk = ii-*clk; + errCnt[clkCnt]=0; + // now that we have the first one lined up test rest of wave array + for (i=ii; i=peak || dest[i]<=low) && (i>=lastClk+*clk-tol && i<=lastClk+*clk+tol)){ + bitHigh=1; + lastClk=lastClk+*clk; + ignorewin=clk[clkCnt]/8; + }else if(dest[i]low) { + if (ignorewin==0){ + bitHigh=0; + }else ignorewin--; + if (i>=lastClk+*clk+tol){ //past possible bar + lowBitCnt[clkCnt]++; + } + }else if ((dest[i]>=peak || dest[i]<=low) && (i=lastClk+*clk+tol) && (bitHigh==0)){ + //error bar found no clock... + errCnt[clkCnt]++; + } + } + //if we found no errors this is correct one - return this clock + if(errCnt[clkCnt]==0 && lowBitCnt[clkCnt]==0) return clk[clkCnt]; + //if we found errors see if it is lowest so far and save it as best run + if(errCnt[clkCnt]high) high=bitStream[i]; + } + high = (int)(((high-128)*.80)+128); + low = (int)(((low-128)*.90)+128); + //low = (uint8_t)(((int)(low)-128)*.80)+128; + for (i=0; i=high) newHigh=1; + } + return; +} + +int indala26decode(uint8_t *bitStream, int *bitLen, uint8_t *invert) +{ + //26 bit 40134 format (don't know other formats) + // Finding the start of a UID + int i; + int long_wait; + //uidlen = 64; + long_wait = 29;//29 leading zeros in format + int start; + int first = 0; + int first2 = 0; + int bitCnt = 0; + int ii; + for (start = 0; start <= *bitLen - 250; start++) { + first = bitStream[start]; + for (i = start; i < start + long_wait; i++) { + if (bitStream[i] != first) { + break; + } + } + if (i == (start + long_wait)) { + break; + } + } + if (start == *bitLen - 250 + 1) { + // did not find start sequence + return -1; + } + //found start once now test length by finding next one + // Inverting signal if needed + if (first == 1) { + for (i = start; i < *bitLen; i++) { + bitStream[i] = !bitStream[i]; + } + *invert = 1; + }else *invert=0; + + int iii; + for (ii=start+29; ii <= *bitLen - 250; ii++) { + first2 = bitStream[ii]; + for (iii = ii; iii < ii + long_wait; iii++) { + if (bitStream[iii] != first2) { + break; + } + } + if (iii == (ii + long_wait)) { + break; + } + } + if (ii== *bitLen - 250 + 1){ + // did not find second start sequence + return -2; + } + bitCnt=ii-start; + + // Dumping UID + i = start; + for (ii = 0; ii < bitCnt; ii++) { + bitStream[ii] = bitStream[i++]; + //showbits[bit] = '0' + bits[bit]; + } + *bitLen=bitCnt; + return 1; +} + +int pskNRZrawDemod(uint8_t *dest, int *bitLen, int *clk, int *invert) +{ + pskCleanWave(dest,*bitLen); + int clk2 = DetectpskNRZClock(dest, *bitLen, *clk); + *clk=clk2; + uint32_t i; + uint8_t high=0, low=128; + uint32_t gLen = *bitLen; + if (gLen > 1280) gLen=1280; + // get high + for (i=0; ihigh) high = dest[i]; + if (dest[i]=high)||(dest[iii]<=low)){ + lastBit=iii-*clk; + //loop through to see if this start location works + for (i = iii; i < *bitLen; ++i) { + //if we found a high bar and we are at a clock bit + if ((dest[i]>=high ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ + bitHigh=1; + lastBit+=*clk; + //curBit=1-*invert; + //dest[bitnum]=curBit; + ignorewin=*clk/8; + bitnum++; + //else if low bar found and we are at a clock point + }else if ((dest[i]<=low ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ + bitHigh=1; + lastBit+=*clk; + ignorewin=*clk/8; + //curBit=*invert; + //dest[bitnum]=curBit; + bitnum++; + //else if no bars found + }else if(dest[i]low) { + if (ignorewin==0){ + bitHigh=0; + }else ignorewin--; + //if we are past a clock point + if (i>=lastBit+*clk+tol){ //clock val + //dest[bitnum]=curBit; + lastBit+=*clk; + bitnum++; + } + //else if bar found but we are not at a clock bit and we did not just have a clock bit + }else if ((dest[i]>=high || dest[i]<=low) && (ilastBit+*clk+tol) && (bitHigh==0)){ + //error bar found no clock... + errCnt++; + } + if (bitnum>=1000) break; + } + //we got more than 64 good bits and not all errors + if ((bitnum > (64+errCnt)) && (errCnt<(maxErr))) { + //possible good read + if (errCnt==0){ + bestStart = iii; + bestErrCnt=errCnt; + break; //great read - finish + } + if (bestStart == iii) break; //if current run == bestErrCnt run (after exhausted testing) then finish + if (errCnt=high ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ + bitHigh=1; + lastBit+=*clk; + curBit=1-*invert; + dest[bitnum]=curBit; + ignorewin=*clk/8; + bitnum++; + //else if low bar found and we are at a clock point + }else if ((dest[i]<=low ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ + bitHigh=1; + lastBit+=*clk; + curBit=*invert; + dest[bitnum]=curBit; + ignorewin=*clk/8; + bitnum++; + //else if no bars found + }else if(dest[i]low) { + if (ignorewin==0){ + bitHigh=0; + }else ignorewin--; + //if we are past a clock point + if (i>=lastBit+*clk+tol){ //clock val + lastBit+=*clk; + dest[bitnum]=curBit; + bitnum++; + } + //else if bar found but we are not at a clock bit and we did not just have a clock bit + }else if ((dest[i]>=high || dest[i]<=low) && ((ilastBit+*clk+tol)) && (bitHigh==0)){ + //error bar found no clock... + bitHigh=1; + dest[bitnum]=77; + bitnum++; + errCnt++; + } + if (bitnum >=1000) break; + } + *bitLen=bitnum; + } else{ + *bitLen=bitnum; + *clk=bestStart; + return -1; + } + + if (bitnum>16){ + *bitLen=bitnum; + } else return -1; + return errCnt; +} + + + /*not needed? + uint32_t i; + uint8_t high=0, low=128; + uint32_t loopMax = 1280; //20 raw bits + + // get high + if (sizehigh) high = dest[i]; + if (dest[i]=high) dest[i]=high; + else if(dest[i]<=low) dest[i]=low; + else dest[i]=0; + } + */ diff --git a/common/lfdemod.h b/common/lfdemod.h index ad95fda5e..2e0acf751 100644 --- a/common/lfdemod.h +++ b/common/lfdemod.h @@ -12,8 +12,8 @@ #include int DetectASKClock(uint8_t dest[], size_t size, int clock); -int askmandemod(uint8_t *BinStream,uint32_t *BitLen,int *clk, int *invert); -uint64_t Em410xDecode(uint8_t *BitStream,uint32_t BitLen); +int askmandemod(uint8_t *BinStream,int *BitLen,int *clk, int *invert); +uint64_t Em410xDecode(uint8_t *BitStream,int BitLen); int manrawdecode(uint8_t *BitStream, int *bitLen); int BiphaseRawDecode(uint8_t * BitStream, int *bitLen, int offset); int askrawdemod(uint8_t *BinStream, int *bitLen,int *clk, int *invert); @@ -21,5 +21,9 @@ int HIDdemodFSK(uint8_t *dest, size_t size, uint32_t *hi2, uint32_t *hi, uint32_ 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, int numbits); +int pskNRZrawDemod(uint8_t *dest, int *bitLen, int *clk, int *invert); +int DetectpskNRZClock(uint8_t dest[], size_t size, int clock); +int indala26decode(uint8_t *bitStream, int *bitLen, uint8_t *invert); +void pskCleanWave(uint8_t *bitStream, int bitLen); #endif diff --git a/traces/ATA5577-HIDemu-FC1-C9.pm3 b/traces/ATA5577-HIDemu-FC1-C9.pm3 new file mode 100644 index 000000000..7c0a878e8 --- /dev/null +++ b/traces/ATA5577-HIDemu-FC1-C9.pm3 @@ -0,0 +1,16000 @@ +69 +73 +35 +-4 +-36 +-64 +-86 +-106 +-46 +60 +74 +38 +3 +-31 +-58 +-82 +-101 +-102 +-41 +68 +86 +50 +14 +-22 +-50 +-75 +-96 +-113 +-34 +75 +92 +55 +19 +-17 +-46 +-72 +-92 +-111 +-31 +79 +96 +60 +23 +-14 +-43 +-70 +-91 +-109 +-28 +82 +99 +63 +26 +-12 +-42 +-68 +-89 +-108 +-25 +84 +101 +65 +28 +-10 +-40 +-67 +-88 +-107 +-25 +85 +102 +65 +28 +-10 +-40 +-67 +-88 +-107 +-24 +85 +103 +66 +29 +-9 +-40 +-66 +-88 +-107 +-24 +85 +102 +66 +29 +-9 +-40 +-66 +-88 +-106 +-25 +85 +102 +65 +28 +-10 +-40 +-67 +-88 +-16 +92 +98 +60 +16 +-18 +-48 +-73 +-19 +85 +88 +49 +8 +-26 +-55 +-78 +-26 +78 +82 +43 +3 +-30 +-59 +-81 +-30 +74 +77 +40 +-1 +-33 +-61 +-83 +-33 +71 +75 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-35 +69 +73 +35 +-2 +-34 +-62 +-85 +-104 +-104 +-45 +66 +81 +47 +10 +-23 +-53 +-77 +-98 +-98 +-36 +75 +90 +56 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +95 +61 +22 +-13 +-44 +-69 +-91 +-108 +-28 +83 +97 +63 +25 +-11 +-42 +-68 +-90 +-107 +-26 +85 +100 +65 +21 +-14 +-45 +-70 +-14 +90 +94 +55 +12 +-22 +-51 +-75 +-22 +82 +86 +47 +6 +-27 +-56 +-80 +-28 +77 +81 +42 +2 +-31 +-59 +-82 +-31 +74 +77 +40 +0 +-33 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-34 +70 +74 +37 +-3 +-35 +-63 +-85 +-34 +69 +74 +36 +-4 +-35 +-63 +-85 +-35 +68 +73 +35 +-4 +-36 +-64 +-86 +-35 +68 +73 +35 +-4 +-36 +-64 +-86 +-35 +68 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +69 +73 +35 +-5 +-36 +-64 +-86 +-36 +68 +72 +34 +-5 +-37 +-64 +-86 +-35 +69 +72 +34 +-5 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +72 +35 +-5 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +68 +72 +35 +-4 +-36 +-64 +-86 +-36 +68 +72 +34 +-5 +-36 +-64 +-86 +-35 +69 +73 +35 +-5 +-36 +-64 +-86 +-36 +68 +72 +34 +-4 +-36 +-64 +-86 +-36 +68 +72 +34 +-5 +-36 +-64 +-86 +-36 +68 +72 +35 +-3 +-35 +-63 +-85 +-105 +-104 +-46 +65 +80 +47 +10 +-24 +-53 +-77 +-98 +-98 +-37 +74 +89 +55 +17 +-17 +-48 +-72 +-94 +-111 +-32 +79 +94 +60 +21 +-14 +-45 +-70 +-92 +-109 +-29 +82 +96 +62 +24 +-12 +-43 +-68 +-90 +-108 +-28 +84 +98 +64 +25 +-11 +-42 +-68 +-90 +-107 +-27 +85 +99 +65 +26 +-10 +-42 +-67 +-89 +-107 +-26 +85 +100 +65 +26 +-10 +-41 +-67 +-89 +-107 +-26 +86 +99 +65 +26 +-10 +-41 +-67 +-89 +-106 +-26 +85 +100 +65 +26 +-10 +-42 +-67 +-89 +-106 +-26 +86 +100 +65 +27 +-9 +-41 +-67 +-89 +-106 +-26 +86 +100 +65 +26 +-10 +-41 +-67 +-89 +-106 +-26 +85 +99 +65 +26 +-10 +-41 +-67 +-89 +-106 +-26 +86 +100 +66 +26 +-10 +-41 +-67 +-89 +-106 +-26 +85 +100 +65 +26 +-9 +-41 +-67 +-89 +-106 +-26 +86 +100 +66 +22 +-13 +-44 +-69 +-13 +91 +94 +55 +12 +-22 +-52 +-76 +-22 +82 +85 +47 +6 +-27 +-56 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +68 +83 +49 +11 +-22 +-52 +-76 +-97 +-97 +-35 +76 +91 +57 +19 +-16 +-47 +-71 +-93 +-110 +-31 +81 +95 +61 +22 +-13 +-44 +-69 +-91 +-108 +-29 +82 +97 +63 +23 +-12 +-43 +-68 +-90 +-108 +-28 +83 +97 +63 +20 +-15 +-46 +-70 +-15 +89 +92 +54 +11 +-23 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +74 +78 +40 +0 +-32 +-61 +-83 +-32 +72 +77 +39 +-1 +-33 +-62 +-84 +-33 +72 +76 +37 +-2 +-34 +-62 +-85 +-104 +-43 +63 +78 +41 +6 +-28 +-56 +-80 +-100 +-101 +-38 +72 +89 +53 +17 +-19 +-48 +-74 +-94 +-112 +-32 +77 +94 +58 +21 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-90 +-18 +89 +97 +58 +15 +-19 +-49 +-73 +-20 +83 +86 +48 +7 +-27 +-56 +-79 +-26 +77 +81 +43 +2 +-30 +-59 +-82 +-30 +74 +78 +40 +0 +-33 +-61 +-83 +-33 +72 +76 +38 +-2 +-34 +-62 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-105 +-45 +62 +75 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +88 +51 +15 +-20 +-49 +-75 +-95 +-113 +-33 +76 +93 +57 +21 +-16 +-45 +-71 +-92 +-110 +-30 +80 +96 +61 +24 +-13 +-43 +-69 +-90 +-109 +-28 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-18 +90 +96 +58 +15 +-19 +-49 +-73 +-20 +84 +88 +48 +7 +-26 +-55 +-79 +-26 +78 +82 +43 +2 +-30 +-59 +-82 +-30 +75 +79 +40 +0 +-32 +-60 +-83 +-32 +72 +76 +37 +-2 +-34 +-62 +-85 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-35 +70 +75 +37 +-1 +-33 +-61 +-84 +-104 +-104 +-44 +67 +82 +48 +11 +-23 +-52 +-76 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-48 +-72 +-94 +-110 +-31 +80 +95 +61 +22 +-13 +-44 +-69 +-91 +-109 +-29 +83 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +84 +98 +64 +20 +-15 +-45 +-70 +-15 +89 +93 +54 +12 +-22 +-52 +-76 +-24 +81 +85 +46 +5 +-28 +-57 +-80 +-29 +75 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +36 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +68 +82 +49 +11 +-22 +-52 +-76 +-97 +-98 +-35 +75 +90 +57 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +94 +61 +22 +-13 +-44 +-69 +-91 +-109 +-29 +82 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +84 +98 +64 +21 +-15 +-45 +-70 +-14 +90 +94 +54 +12 +-22 +-52 +-76 +-22 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +2 +-31 +-59 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-2 +-35 +-63 +-85 +-105 +-44 +62 +77 +41 +6 +-29 +-56 +-81 +-100 +-101 +-38 +71 +89 +53 +17 +-19 +-48 +-74 +-94 +-112 +-32 +77 +95 +58 +21 +-16 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-18 +89 +96 +58 +15 +-19 +-49 +-74 +-20 +83 +87 +48 +7 +-27 +-56 +-79 +-27 +77 +81 +43 +2 +-31 +-59 +-82 +-30 +74 +77 +39 +-1 +-33 +-61 +-84 +-32 +72 +75 +37 +-3 +-34 +-62 +-85 +-33 +71 +74 +36 +-3 +-35 +-63 +-85 +-105 +-44 +61 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +71 +88 +51 +15 +-20 +-49 +-75 +-95 +-112 +-33 +76 +93 +58 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +60 +24 +-13 +-43 +-69 +-90 +-109 +-28 +81 +99 +62 +25 +-12 +-42 +-68 +-90 +-108 +-27 +82 +100 +63 +26 +-11 +-41 +-68 +-89 +-108 +-26 +83 +101 +63 +26 +-11 +-41 +-68 +-89 +-107 +-26 +83 +101 +64 +27 +-10 +-41 +-67 +-88 +-107 +-25 +84 +101 +64 +27 +-10 +-41 +-67 +-88 +-107 +-25 +83 +100 +64 +27 +-10 +-40 +-67 +-88 +-16 +92 +99 +59 +16 +-18 +-48 +-73 +-19 +85 +88 +49 +8 +-26 +-55 +-78 +-26 +78 +83 +44 +3 +-30 +-59 +-81 +-30 +75 +79 +41 +0 +-32 +-60 +-83 +-32 +72 +77 +38 +-2 +-34 +-62 +-84 +-34 +70 +75 +37 +-3 +-35 +-63 +-85 +-35 +69 +74 +36 +-3 +-35 +-63 +-85 +-35 +69 +74 +35 +-4 +-35 +-63 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +68 +73 +35 +-4 +-36 +-64 +-86 +-36 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +68 +72 +35 +-2 +-34 +-62 +-85 +-104 +-104 +-45 +66 +81 +48 +11 +-23 +-53 +-77 +-97 +-98 +-36 +75 +89 +56 +18 +-17 +-48 +-72 +-94 +-111 +-31 +80 +94 +60 +22 +-14 +-45 +-70 +-91 +-109 +-29 +82 +97 +63 +24 +-12 +-43 +-68 +-90 +-107 +-27 +84 +98 +64 +20 +-15 +-46 +-70 +-14 +89 +93 +54 +11 +-22 +-52 +-76 +-23 +81 +84 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +41 +1 +-32 +-60 +-83 +-31 +74 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +76 +38 +-2 +-34 +-62 +-85 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-44 +62 +77 +41 +6 +-28 +-56 +-80 +-100 +-101 +-38 +72 +89 +53 +17 +-19 +-48 +-74 +-94 +-112 +-32 +77 +95 +59 +22 +-15 +-44 +-70 +-91 +-109 +-29 +81 +98 +62 +25 +-13 +-42 +-69 +-90 +-108 +-27 +82 +99 +63 +26 +-12 +-42 +-68 +-89 +-17 +89 +97 +59 +16 +-19 +-49 +-73 +-19 +84 +87 +49 +7 +-26 +-55 +-79 +-26 +78 +82 +43 +3 +-30 +-59 +-81 +-30 +74 +79 +40 +0 +-32 +-60 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +70 +75 +37 +-3 +-35 +-63 +-85 +-105 +-45 +62 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +87 +51 +15 +-20 +-49 +-75 +-95 +-113 +-33 +76 +93 +57 +20 +-16 +-46 +-72 +-92 +-110 +-30 +79 +96 +60 +23 +-14 +-44 +-70 +-91 +-109 +-28 +81 +98 +61 +24 +-13 +-43 +-69 +-90 +-19 +89 +97 +58 +15 +-19 +-49 +-74 +-21 +83 +87 +48 +7 +-27 +-56 +-79 +-27 +77 +81 +43 +2 +-31 +-59 +-82 +-30 +74 +78 +40 +0 +-32 +-61 +-83 +-32 +72 +76 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +37 +-3 +-35 +-63 +-85 +-35 +69 +75 +37 +-1 +-33 +-61 +-84 +-104 +-104 +-44 +67 +82 +48 +11 +-23 +-53 +-77 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +94 +61 +22 +-13 +-44 +-69 +-91 +-108 +-29 +82 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +84 +98 +64 +20 +-15 +-45 +-70 +-15 +89 +93 +54 +11 +-23 +-52 +-76 +-23 +80 +84 +46 +5 +-28 +-57 +-80 +-29 +75 +80 +42 +1 +-31 +-60 +-82 +-31 +72 +77 +39 +-1 +-33 +-62 +-84 +-33 +71 +76 +38 +-2 +-34 +-62 +-85 +-34 +70 +74 +37 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +67 +82 +49 +12 +-22 +-52 +-76 +-97 +-97 +-35 +75 +90 +57 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +95 +61 +22 +-13 +-45 +-69 +-91 +-109 +-29 +82 +96 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +84 +98 +64 +20 +-15 +-45 +-70 +-14 +89 +93 +54 +12 +-22 +-52 +-76 +-22 +81 +86 +47 +6 +-27 +-56 +-80 +-27 +77 +81 +42 +2 +-31 +-59 +-82 +-30 +74 +77 +39 +-1 +-33 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-85 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-45 +62 +77 +40 +5 +-29 +-56 +-81 +-100 +-101 +-38 +70 +88 +52 +16 +-20 +-49 +-74 +-94 +-112 +-32 +77 +94 +58 +22 +-16 +-45 +-71 +-91 +-110 +-29 +80 +96 +60 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +63 +26 +-12 +-42 +-68 +-89 +-18 +89 +97 +59 +16 +-19 +-49 +-73 +-20 +84 +88 +48 +7 +-26 +-56 +-79 +-26 +78 +82 +43 +3 +-30 +-59 +-82 +-30 +75 +79 +41 +0 +-32 +-60 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +76 +37 +-2 +-34 +-62 +-85 +-104 +-44 +62 +77 +40 +6 +-29 +-56 +-81 +-100 +-101 +-38 +72 +89 +53 +17 +-19 +-48 +-74 +-94 +-112 +-32 +77 +94 +58 +22 +-15 +-45 +-71 +-91 +-110 +-29 +80 +98 +61 +25 +-13 +-43 +-69 +-90 +-108 +-27 +81 +99 +62 +25 +-12 +-42 +-68 +-89 +-18 +90 +97 +58 +15 +-19 +-49 +-74 +-20 +83 +86 +47 +6 +-27 +-56 +-79 +-27 +77 +81 +42 +2 +-31 +-59 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-34 +70 +74 +36 +-4 +-35 +-63 +-85 +-36 +68 +72 +34 +-5 +-36 +-64 +-86 +-37 +67 +72 +34 +-3 +-35 +-63 +-85 +-105 +-104 +-46 +65 +79 +47 +9 +-24 +-54 +-77 +-98 +-98 +-37 +74 +89 +55 +17 +-17 +-48 +-72 +-94 +-111 +-32 +80 +95 +61 +22 +-14 +-45 +-69 +-91 +-109 +-28 +83 +97 +64 +25 +-11 +-42 +-68 +-90 +-107 +-26 +86 +100 +66 +22 +-13 +-44 +-69 +-13 +91 +94 +55 +13 +-21 +-51 +-75 +-22 +83 +86 +47 +6 +-27 +-56 +-80 +-27 +77 +81 +43 +2 +-30 +-59 +-82 +-30 +74 +77 +40 +-1 +-33 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-85 +-34 +70 +74 +36 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +67 +82 +48 +11 +-23 +-53 +-76 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-48 +-72 +-94 +-111 +-32 +79 +94 +60 +21 +-14 +-45 +-70 +-92 +-109 +-30 +81 +96 +62 +23 +-12 +-43 +-69 +-91 +-108 +-28 +83 +97 +64 +20 +-15 +-46 +-70 +-15 +89 +93 +54 +11 +-22 +-52 +-76 +-23 +81 +85 +47 +5 +-28 +-57 +-80 +-27 +77 +80 +42 +1 +-31 +-60 +-82 +-30 +74 +78 +40 +0 +-33 +-61 +-83 +-32 +73 +77 +39 +-1 +-33 +-62 +-84 +-33 +71 +76 +37 +-2 +-34 +-62 +-85 +-104 +-44 +62 +77 +41 +6 +-28 +-56 +-80 +-99 +-101 +-38 +71 +88 +52 +16 +-19 +-49 +-74 +-94 +-112 +-32 +77 +95 +58 +21 +-16 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-90 +-108 +-26 +83 +100 +63 +26 +-11 +-41 +-68 +-89 +-108 +-26 +83 +101 +64 +27 +-11 +-41 +-68 +-89 +-107 +-25 +84 +101 +64 +27 +-11 +-41 +-67 +-89 +-107 +-25 +84 +101 +65 +27 +-11 +-41 +-67 +-88 +-107 +-25 +84 +101 +64 +27 +-11 +-41 +-67 +-89 +-17 +91 +98 +59 +16 +-18 +-48 +-73 +-19 +85 +88 +49 +8 +-26 +-55 +-78 +-26 +78 +82 +43 +3 +-30 +-58 +-81 +-30 +75 +78 +40 +0 +-32 +-60 +-83 +-32 +72 +75 +38 +-2 +-34 +-62 +-85 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-44 +62 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +88 +51 +16 +-20 +-49 +-74 +-95 +-112 +-33 +76 +93 +57 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +96 +60 +24 +-14 +-43 +-69 +-90 +-109 +-28 +81 +99 +62 +25 +-12 +-42 +-69 +-90 +-18 +89 +97 +59 +15 +-19 +-49 +-73 +-20 +83 +87 +48 +7 +-27 +-56 +-79 +-26 +78 +81 +43 +2 +-31 +-59 +-82 +-30 +74 +78 +40 +0 +-32 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-85 +-33 +71 +74 +36 +-3 +-35 +-63 +-85 +-34 +70 +75 +37 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-4 +-35 +-63 +-85 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +69 +73 +35 +-4 +-36 +-63 +-86 +-36 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +69 +72 +34 +-5 +-36 +-64 +-86 +-36 +69 +73 +35 +-2 +-34 +-62 +-85 +-105 +-104 +-45 +66 +81 +48 +10 +-23 +-53 +-77 +-98 +-98 +-36 +75 +90 +56 +18 +-17 +-48 +-72 +-94 +-111 +-31 +80 +94 +60 +21 +-14 +-45 +-70 +-92 +-109 +-29 +82 +97 +63 +24 +-12 +-43 +-68 +-90 +-107 +-27 +83 +98 +64 +20 +-15 +-46 +-70 +-14 +89 +93 +54 +11 +-23 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-83 +-33 +71 +75 +37 +-2 +-34 +-62 +-85 +-34 +70 +75 +37 +-3 +-35 +-63 +-85 +-105 +-45 +62 +77 +40 +5 +-29 +-56 +-81 +-100 +-101 +-38 +70 +88 +51 +16 +-20 +-49 +-74 +-95 +-112 +-33 +77 +94 +57 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +60 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-17 +90 +97 +59 +16 +-19 +-49 +-73 +-19 +84 +88 +49 +8 +-26 +-55 +-78 +-25 +79 +82 +44 +3 +-29 +-58 +-81 +-29 +76 +80 +42 +1 +-32 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-104 +-43 +63 +77 +40 +6 +-28 +-56 +-81 +-100 +-101 +-38 +71 +88 +52 +16 +-20 +-49 +-74 +-95 +-112 +-33 +77 +94 +57 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-18 +89 +96 +58 +15 +-19 +-49 +-73 +-20 +83 +87 +48 +7 +-26 +-56 +-79 +-27 +77 +81 +43 +2 +-31 +-59 +-82 +-30 +74 +78 +40 +0 +-32 +-61 +-83 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-35 +69 +74 +36 +-2 +-34 +-62 +-84 +-104 +-104 +-44 +66 +80 +47 +10 +-23 +-53 +-77 +-97 +-98 +-36 +75 +89 +56 +18 +-17 +-48 +-72 +-94 +-111 +-32 +80 +95 +60 +22 +-14 +-45 +-69 +-91 +-109 +-29 +82 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-28 +83 +98 +64 +20 +-15 +-45 +-70 +-15 +89 +92 +54 +11 +-22 +-52 +-76 +-23 +81 +85 +47 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +76 +37 +-2 +-34 +-62 +-85 +-34 +69 +74 +36 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +68 +82 +49 +11 +-22 +-52 +-76 +-97 +-97 +-36 +75 +90 +56 +18 +-17 +-47 +-72 +-94 +-110 +-31 +80 +94 +60 +22 +-14 +-45 +-69 +-91 +-109 +-29 +82 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +83 +98 +64 +20 +-15 +-45 +-70 +-15 +89 +93 +54 +12 +-22 +-52 +-76 +-23 +80 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-32 +72 +75 +37 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-105 +-45 +61 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +88 +52 +16 +-20 +-49 +-74 +-95 +-112 +-33 +77 +94 +58 +21 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +83 +100 +63 +26 +-11 +-41 +-68 +-89 +-17 +90 +97 +59 +16 +-19 +-49 +-73 +-19 +84 +88 +50 +8 +-26 +-55 +-78 +-26 +78 +83 +44 +3 +-30 +-58 +-81 +-29 +75 +79 +40 +0 +-32 +-60 +-83 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-3 +-35 +-62 +-85 +-105 +-44 +63 +77 +40 +6 +-28 +-56 +-81 +-100 +-101 +-39 +71 +88 +52 +16 +-19 +-49 +-74 +-94 +-112 +-33 +77 +94 +58 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-28 +82 +98 +62 +25 +-12 +-42 +-69 +-89 +-108 +-27 +82 +100 +63 +26 +-12 +-42 +-68 +-89 +-108 +-26 +82 +100 +64 +27 +-11 +-41 +-67 +-89 +-107 +-25 +83 +100 +63 +27 +-11 +-41 +-67 +-89 +-107 +-26 +83 +101 +65 +27 +-10 +-41 +-67 +-88 +-107 +-26 +84 +101 +64 +27 +-10 +-41 +-67 +-88 +-16 +91 +98 +59 +16 +-18 +-49 +-73 +-19 +85 +88 +48 +7 +-26 +-55 +-79 +-26 +78 +82 +43 +2 +-30 +-59 +-82 +-30 +74 +78 +40 +0 +-33 +-61 +-83 +-33 +72 +75 +37 +-3 +-34 +-62 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-35 +70 +74 +36 +-4 +-35 +-63 +-85 +-35 +69 +73 +35 +-4 +-36 +-63 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +69 +73 +35 +-4 +-36 +-63 +-86 +-35 +68 +73 +35 +-2 +-34 +-62 +-85 +-104 +-104 +-44 +66 +81 +47 +10 +-23 +-53 +-77 +-98 +-98 +-36 +75 +90 +56 +18 +-17 +-47 +-72 +-94 +-110 +-31 +80 +94 +60 +22 +-14 +-45 +-69 +-91 +-108 +-29 +82 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +84 +98 +64 +20 +-15 +-46 +-70 +-14 +89 +93 +54 +11 +-23 +-52 +-76 +-23 +81 +84 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +41 +1 +-31 +-60 +-82 +-31 +74 +77 +40 +-1 +-33 +-61 +-84 +-33 +72 +75 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +37 +-3 +-35 +-63 +-85 +-105 +-45 +62 +76 +40 +5 +-29 +-56 +-81 +-100 +-101 +-39 +70 +88 +52 +16 +-20 +-49 +-74 +-94 +-112 +-32 +77 +94 +58 +22 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +63 +25 +-12 +-42 +-68 +-89 +-17 +89 +97 +58 +15 +-19 +-49 +-73 +-19 +84 +87 +49 +7 +-26 +-55 +-79 +-26 +78 +82 +44 +3 +-30 +-58 +-81 +-30 +75 +78 +41 +0 +-32 +-60 +-83 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +76 +37 +-2 +-34 +-62 +-85 +-104 +-44 +63 +78 +41 +6 +-28 +-56 +-80 +-100 +-101 +-38 +72 +89 +53 +17 +-19 +-48 +-74 +-94 +-112 +-32 +77 +94 +58 +22 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +63 +26 +-12 +-42 +-68 +-89 +-17 +90 +97 +59 +16 +-19 +-49 +-73 +-19 +84 +87 +49 +7 +-26 +-55 +-79 +-26 +78 +82 +43 +3 +-30 +-58 +-81 +-30 +75 +79 +41 +0 +-32 +-60 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-35 +69 +73 +35 +-2 +-34 +-62 +-84 +-104 +-104 +-45 +66 +81 +47 +10 +-24 +-53 +-77 +-98 +-98 +-37 +74 +89 +55 +17 +-18 +-48 +-73 +-94 +-111 +-32 +79 +93 +59 +21 +-14 +-45 +-70 +-92 +-109 +-29 +82 +96 +62 +23 +-13 +-44 +-69 +-91 +-108 +-28 +83 +97 +63 +20 +-15 +-46 +-71 +-15 +89 +93 +53 +11 +-23 +-52 +-76 +-24 +81 +84 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +74 +77 +39 +-1 +-33 +-61 +-84 +-33 +72 +76 +38 +-2 +-34 +-62 +-85 +-34 +70 +74 +37 +-1 +-33 +-61 +-84 +-104 +-103 +-43 +68 +82 +49 +12 +-22 +-52 +-76 +-97 +-97 +-35 +76 +90 +57 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +94 +61 +22 +-13 +-44 +-69 +-91 +-109 +-29 +82 +96 +63 +24 +-12 +-43 +-68 +-90 +-108 +-28 +84 +98 +64 +20 +-15 +-45 +-70 +-15 +89 +93 +53 +11 +-23 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +72 +76 +37 +-2 +-34 +-62 +-85 +-34 +70 +75 +37 +-3 +-35 +-63 +-85 +-105 +-45 +61 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +88 +51 +15 +-20 +-49 +-75 +-95 +-113 +-32 +77 +94 +58 +22 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +63 +26 +-12 +-41 +-68 +-89 +-17 +91 +98 +60 +16 +-18 +-48 +-73 +-19 +85 +88 +49 +8 +-26 +-55 +-78 +-26 +78 +82 +43 +3 +-30 +-59 +-81 +-30 +75 +79 +41 +0 +-32 +-60 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-85 +-33 +71 +75 +37 +-2 +-34 +-62 +-85 +-105 +-44 +62 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +87 +52 +16 +-20 +-49 +-74 +-94 +-112 +-33 +77 +93 +57 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-17 +90 +98 +59 +16 +-19 +-49 +-73 +-19 +85 +88 +49 +7 +-26 +-55 +-79 +-26 +78 +83 +44 +3 +-30 +-59 +-81 +-29 +75 +79 +41 +1 +-32 +-60 +-83 +-32 +73 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-2 +-34 +-62 +-85 +-34 +71 +75 +37 +-1 +-33 +-61 +-84 +-104 +-103 +-43 +67 +82 +49 +12 +-22 +-52 +-76 +-97 +-97 +-35 +76 +90 +56 +18 +-17 +-48 +-72 +-94 +-110 +-31 +80 +94 +60 +22 +-14 +-45 +-70 +-91 +-109 +-29 +82 +96 +62 +23 +-12 +-43 +-69 +-91 +-108 +-28 +83 +97 +63 +20 +-15 +-46 +-71 +-16 +88 +91 +52 +10 +-24 +-53 +-77 +-25 +79 +83 +44 +4 +-29 +-58 +-81 +-30 +74 +77 +39 +-1 +-33 +-61 +-83 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-4 +-35 +-63 +-85 +-35 +69 +73 +35 +-2 +-34 +-62 +-85 +-104 +-104 +-44 +67 +81 +48 +11 +-23 +-52 +-76 +-97 +-98 +-35 +76 +91 +57 +19 +-16 +-47 +-71 +-93 +-110 +-30 +81 +96 +62 +24 +-12 +-43 +-69 +-91 +-108 +-27 +84 +99 +64 +26 +-10 +-42 +-67 +-89 +-107 +-27 +84 +99 +65 +22 +-14 +-44 +-69 +-14 +90 +94 +55 +12 +-22 +-51 +-75 +-23 +81 +85 +47 +6 +-27 +-56 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-105 +-46 +61 +75 +40 +5 +-29 +-57 +-81 +-100 +-102 +-40 +70 +87 +51 +15 +-21 +-49 +-75 +-95 +-113 +-33 +76 +93 +57 +21 +-16 +-46 +-72 +-92 +-110 +-29 +79 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +100 +63 +26 +-11 +-41 +-68 +-89 +-17 +91 +97 +59 +16 +-18 +-49 +-73 +-19 +85 +88 +49 +8 +-26 +-55 +-78 +-25 +79 +82 +44 +3 +-29 +-58 +-81 +-29 +75 +80 +41 +1 +-32 +-60 +-83 +-31 +73 +77 +39 +-1 +-33 +-62 +-84 +-33 +71 +75 +37 +-2 +-35 +-62 +-85 +-105 +-44 +62 +77 +40 +6 +-29 +-56 +-81 +-100 +-101 +-38 +71 +88 +52 +16 +-20 +-49 +-74 +-95 +-112 +-32 +77 +94 +58 +21 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +63 +25 +-12 +-42 +-68 +-89 +-17 +90 +97 +59 +16 +-19 +-49 +-73 +-20 +84 +88 +49 +7 +-26 +-55 +-79 +-27 +78 +82 +43 +3 +-30 +-59 +-82 +-30 +74 +78 +40 +-1 +-33 +-61 +-84 +-33 +72 +75 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +37 +-3 +-35 +-63 +-85 +-35 +70 +74 +37 +-1 +-33 +-62 +-84 +-104 +-103 +-44 +67 +82 +48 +11 +-23 +-53 +-77 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-48 +-72 +-94 +-111 +-31 +80 +94 +60 +21 +-14 +-45 +-70 +-92 +-109 +-29 +82 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +84 +98 +64 +25 +-11 +-42 +-67 +-90 +-107 +-27 +84 +98 +64 +25 +-11 +-42 +-67 +-90 +-107 +-27 +84 +98 +64 +25 +-11 +-42 +-67 +-89 +-107 +-27 +84 +99 +65 +26 +-10 +-42 +-67 +-89 +-107 +-27 +84 +98 +64 +26 +-10 +-42 +-67 +-89 +-107 +-26 +86 +100 +65 +21 +-14 +-45 +-70 +-13 +90 +93 +54 +12 +-22 +-52 +-76 +-23 +81 +85 +47 +5 +-28 +-57 +-80 +-28 +76 +81 +43 +2 +-31 +-59 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-35 +69 +74 +36 +-4 +-35 +-63 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-63 +-86 +-35 +68 +72 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-106 +-46 +61 +75 +39 +4 +-30 +-57 +-81 +-101 +-102 +-39 +70 +87 +51 +15 +-20 +-49 +-75 +-95 +-113 +-33 +77 +94 +57 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-18 +90 +97 +59 +16 +-19 +-49 +-73 +-20 +84 +87 +49 +7 +-26 +-55 +-79 +-26 +78 +82 +43 +3 +-30 +-59 +-81 +-30 +74 +79 +41 +0 +-32 +-60 +-83 +-32 +72 +76 +38 +-1 +-33 +-62 +-84 +-34 +70 +75 +37 +-3 +-35 +-63 +-85 +-105 +-44 +62 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +87 +51 +15 +-20 +-49 +-74 +-95 +-112 +-33 +76 +93 +57 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-108 +-27 +83 +99 +63 +26 +-11 +-41 +-68 +-89 +-108 +-25 +84 +101 +65 +27 +-10 +-41 +-67 +-88 +-107 +-25 +84 +101 +65 +28 +-10 +-40 +-67 +-88 +-107 +-25 +85 +101 +65 +28 +-10 +-40 +-66 +-88 +-107 +-24 +85 +102 +65 +27 +-10 +-40 +-67 +-88 +-107 +-25 +85 +101 +64 +27 +-10 +-41 +-67 +-88 +-16 +91 +98 +60 +16 +-18 +-48 +-73 +-19 +85 +88 +49 +7 +-26 +-55 +-78 +-26 +77 +81 +43 +3 +-30 +-59 +-81 +-30 +75 +79 +41 +0 +-32 +-60 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-35 +70 +74 +35 +-2 +-34 +-62 +-84 +-104 +-104 +-45 +67 +81 +48 +10 +-23 +-53 +-77 +-98 +-98 +-36 +75 +89 +56 +18 +-17 +-48 +-72 +-94 +-111 +-32 +80 +94 +60 +21 +-14 +-45 +-70 +-92 +-109 +-29 +82 +97 +62 +23 +-12 +-43 +-69 +-91 +-108 +-28 +83 +98 +64 +20 +-15 +-46 +-70 +-15 +89 +93 +53 +11 +-23 +-52 +-76 +-23 +80 +84 +46 +5 +-28 +-57 +-80 +-29 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +37 +-3 +-35 +-63 +-85 +-35 +70 +74 +36 +-4 +-35 +-63 +-85 +-35 +69 +74 +36 +-4 +-35 +-63 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +74 +35 +-4 +-36 +-63 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-5 +-36 +-64 +-86 +-36 +68 +72 +34 +-5 +-36 +-64 +-86 +-36 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +68 +72 +35 +-5 +-36 +-64 +-86 +-35 +69 +73 +35 +-5 +-36 +-64 +-86 +-35 +69 +72 +34 +-5 +-36 +-64 +-86 +-36 +68 +72 +35 +-4 +-36 +-64 +-86 +-35 +69 +74 +36 +-4 +-35 +-63 +-86 +-36 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +69 +72 +35 +-4 +-36 +-64 +-86 +-36 +69 +72 +35 +-2 +-34 +-63 +-85 +-105 +-104 +-45 +67 +81 +48 +10 +-23 +-53 +-77 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-47 +-72 +-93 +-110 +-31 +81 +95 +61 +22 +-13 +-44 +-69 +-91 +-109 +-28 +83 +97 +63 +24 +-11 +-43 +-68 +-90 +-107 +-27 +85 +99 +65 +26 +-10 +-42 +-67 +-89 +-107 +-26 +85 +100 +65 +26 +-10 +-41 +-67 +-89 +-106 +-26 +86 +100 +66 +27 +-9 +-41 +-66 +-89 +-106 +-26 +86 +100 +66 +27 +-9 +-41 +-66 +-89 +-106 +-26 +86 +100 +66 +26 +-10 +-41 +-67 +-89 +-106 +-26 +86 +100 +66 +27 +-9 +-41 +-66 +-89 +-106 +-26 +85 +99 +65 +26 +-10 +-41 +-67 +-89 +-106 +-26 +85 +99 +65 +26 +-10 +-42 +-67 +-89 +-106 +-26 +85 +99 +65 +26 +-10 +-42 +-67 +-89 +-107 +-26 +85 +99 +65 +26 +-10 +-42 +-67 +-89 +-107 +-26 +86 +100 +65 +21 +-14 +-45 +-70 +-14 +90 +94 +54 +12 +-22 +-52 +-76 +-22 +82 +85 +47 +6 +-27 +-56 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +72 +77 +39 +-1 +-33 +-61 +-84 +-33 +70 +74 +37 +-3 +-35 +-63 +-85 +-34 +69 +74 +36 +-1 +-33 +-62 +-84 +-104 +-104 +-44 +67 +81 +48 +11 +-23 +-53 +-76 +-97 +-98 +-36 +74 +89 +56 +18 +-17 +-48 +-72 +-94 +-111 +-31 +80 +94 +60 +22 +-14 +-45 +-69 +-91 +-109 +-29 +82 +96 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +84 +98 +64 +21 +-14 +-45 +-70 +-14 +89 +93 +54 +11 +-22 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +74 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +76 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-105 +-45 +62 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +87 +52 +16 +-20 +-49 +-74 +-94 +-112 +-32 +77 +94 +58 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +63 +26 +-12 +-42 +-68 +-89 +-17 +90 +97 +59 +16 +-19 +-49 +-73 +-20 +84 +88 +49 +7 +-26 +-55 +-79 +-26 +78 +81 +43 +2 +-31 +-59 +-82 +-30 +75 +78 +40 +0 +-33 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-45 +61 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +71 +88 +52 +16 +-20 +-49 +-74 +-94 +-112 +-33 +77 +94 +58 +21 +-16 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-108 +-27 +82 +99 +63 +26 +-12 +-42 +-68 +-89 +-17 +90 +97 +59 +16 +-19 +-49 +-73 +-20 +85 +88 +49 +8 +-26 +-55 +-78 +-26 +79 +82 +43 +3 +-30 +-59 +-81 +-29 +75 +80 +41 +1 +-32 +-60 +-83 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +72 +76 +38 +-2 +-34 +-62 +-85 +-34 +71 +75 +37 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +67 +82 +49 +11 +-22 +-52 +-76 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +95 +61 +22 +-13 +-44 +-69 +-91 +-108 +-29 +83 +97 +63 +24 +-12 +-43 +-68 +-90 +-107 +-27 +85 +98 +64 +20 +-15 +-46 +-70 +-15 +89 +93 +54 +12 +-22 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-29 +75 +79 +41 +1 +-32 +-60 +-83 +-31 +73 +77 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-35 +69 +73 +35 +-2 +-34 +-62 +-84 +-104 +-104 +-45 +66 +81 +47 +10 +-23 +-53 +-77 +-98 +-98 +-36 +75 +89 +56 +17 +-17 +-48 +-72 +-94 +-111 +-32 +79 +94 +60 +21 +-14 +-45 +-70 +-92 +-109 +-29 +82 +96 +62 +24 +-12 +-43 +-68 +-90 +-108 +-28 +83 +98 +64 +20 +-15 +-45 +-70 +-15 +89 +93 +54 +11 +-23 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-32 +72 +75 +37 +-3 +-35 +-62 +-85 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-45 +62 +76 +40 +5 +-30 +-57 +-81 +-100 +-102 +-39 +70 +88 +52 +16 +-20 +-49 +-74 +-95 +-112 +-33 +77 +94 +58 +21 +-16 +-45 +-71 +-91 +-110 +-29 +80 +97 +60 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-17 +90 +97 +58 +15 +-19 +-49 +-73 +-20 +84 +88 +49 +7 +-26 +-55 +-79 +-26 +78 +82 +43 +3 +-30 +-58 +-81 +-30 +75 +78 +40 +0 +-32 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +70 +75 +37 +-3 +-35 +-63 +-85 +-105 +-45 +62 +77 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +88 +52 +16 +-20 +-49 +-74 +-94 +-112 +-32 +77 +94 +58 +22 +-15 +-45 +-71 +-91 +-110 +-28 +81 +98 +61 +24 +-13 +-43 +-69 +-90 +-108 +-27 +82 +100 +63 +26 +-11 +-41 +-68 +-89 +-108 +-26 +84 +101 +64 +27 +-11 +-41 +-67 +-88 +-107 +-25 +83 +100 +64 +27 +-11 +-41 +-67 +-88 +-107 +-25 +84 +101 +64 +27 +-10 +-40 +-67 +-88 +-107 +-25 +84 +102 +65 +27 +-10 +-41 +-67 +-88 +-107 +-25 +84 +101 +64 +27 +-10 +-41 +-67 +-88 +-16 +91 +98 +60 +16 +-18 +-48 +-73 +-19 +85 +88 +49 +7 +-26 +-55 +-78 +-26 +78 +82 +43 +3 +-30 +-59 +-81 +-30 +75 +79 +40 +0 +-32 +-60 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-35 +70 +74 +36 +-3 +-35 +-63 +-85 +-35 +69 +74 +36 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-4 +-35 +-63 +-85 +-35 +69 +73 +35 +-4 +-36 +-63 +-86 +-35 +68 +73 +35 +-2 +-34 +-62 +-84 +-104 +-104 +-45 +67 +81 +47 +10 +-24 +-53 +-77 +-98 +-98 +-36 +74 +89 +56 +17 +-17 +-48 +-72 +-94 +-111 +-32 +79 +93 +60 +21 +-14 +-45 +-70 +-92 +-109 +-30 +81 +96 +62 +23 +-13 +-44 +-69 +-91 +-108 +-29 +82 +96 +62 +19 +-16 +-47 +-71 +-16 +87 +91 +52 +10 +-24 +-53 +-77 +-25 +79 +83 +44 +3 +-29 +-58 +-81 +-30 +75 +78 +40 +0 +-33 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-34 +70 +74 +37 +-3 +-35 +-63 +-85 +-34 +70 +74 +37 +-3 +-35 +-63 +-85 +-105 +-44 +63 +77 +41 +6 +-28 +-56 +-81 +-100 +-101 +-38 +71 +89 +53 +17 +-19 +-48 +-73 +-94 +-112 +-31 +78 +96 +60 +23 +-14 +-44 +-70 +-91 +-109 +-28 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-108 +-27 +83 +100 +63 +26 +-11 +-41 +-68 +-89 +-17 +91 +98 +59 +16 +-19 +-49 +-73 +-19 +84 +87 +49 +7 +-26 +-55 +-79 +-26 +78 +81 +43 +2 +-30 +-59 +-82 +-30 +74 +78 +40 +-1 +-33 +-61 +-83 +-33 +71 +75 +37 +-2 +-34 +-62 +-85 +-34 +69 +74 +36 +-4 +-35 +-63 +-85 +-105 +-46 +61 +76 +40 +5 +-29 +-57 +-81 +-100 +-102 +-39 +70 +87 +51 +15 +-21 +-49 +-75 +-95 +-113 +-33 +77 +94 +58 +22 +-15 +-45 +-71 +-91 +-110 +-29 +80 +98 +62 +25 +-12 +-42 +-69 +-90 +-108 +-26 +83 +100 +63 +27 +-11 +-41 +-68 +-89 +-17 +91 +98 +60 +16 +-18 +-48 +-73 +-19 +84 +88 +49 +8 +-25 +-55 +-78 +-26 +78 +82 +44 +3 +-29 +-58 +-81 +-29 +75 +80 +41 +1 +-32 +-60 +-83 +-32 +72 +77 +38 +-2 +-34 +-62 +-84 +-33 +71 +76 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +37 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +67 +82 +48 +11 +-23 +-53 +-76 +-97 +-98 +-36 +75 +89 +56 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +95 +61 +22 +-14 +-45 +-70 +-91 +-109 +-29 +82 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +84 +99 +64 +20 +-15 +-45 +-70 +-15 +88 +93 +54 +11 +-23 +-52 +-76 +-24 +80 +84 +46 +5 +-28 +-57 +-80 +-29 +75 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +67 +82 +48 +11 +-23 +-52 +-76 +-97 +-98 +-35 +75 +90 +56 +18 +-17 +-48 +-72 +-94 +-110 +-31 +80 +94 +60 +22 +-14 +-45 +-69 +-91 +-109 +-29 +82 +97 +62 +23 +-12 +-43 +-68 +-90 +-108 +-28 +83 +98 +63 +20 +-15 +-46 +-71 +-16 +89 +93 +53 +11 +-23 +-52 +-76 +-23 +80 +84 +46 +5 +-28 +-57 +-80 +-28 +75 +80 +41 +1 +-32 +-60 +-83 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-34 +70 +75 +37 +-3 +-35 +-63 +-85 +-105 +-45 +62 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +71 +88 +52 +16 +-20 +-49 +-74 +-94 +-112 +-33 +77 +94 +58 +22 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-108 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-17 +90 +97 +59 +16 +-19 +-49 +-73 +-20 +84 +88 +49 +7 +-26 +-55 +-79 +-27 +77 +82 +43 +3 +-30 +-59 +-81 +-30 +74 +78 +40 +0 +-32 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-85 +-34 +70 +74 +37 +-3 +-35 +-63 +-85 +-105 +-45 +62 +76 +40 +5 +-29 +-56 +-81 +-100 +-101 +-39 +71 +88 +52 +16 +-20 +-49 +-74 +-94 +-112 +-32 +77 +94 +57 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-108 +-27 +82 +99 +63 +26 +-12 +-42 +-68 +-89 +-17 +90 +97 +59 +15 +-19 +-49 +-73 +-20 +84 +88 +49 +8 +-26 +-55 +-79 +-26 +78 +82 +43 +3 +-30 +-59 +-81 +-30 +75 +79 +41 +0 +-32 +-60 +-83 +-32 +72 +76 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-35 +69 +74 +36 +-2 +-34 +-62 +-84 +-104 +-104 +-45 +67 +82 +48 +11 +-23 +-53 +-77 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-47 +-72 +-93 +-110 +-31 +81 +95 +61 +22 +-13 +-44 +-69 +-91 +-108 +-28 +83 +98 +64 +25 +-11 +-42 +-67 +-90 +-107 +-26 +86 +100 +65 +21 +-14 +-45 +-70 +-14 +90 +94 +55 +12 +-22 +-52 +-75 +-22 +82 +86 +47 +6 +-27 +-56 +-80 +-28 +76 +81 +42 +2 +-31 +-59 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-3 +-35 +-62 +-85 +-34 +69 +74 +36 +-1 +-33 +-62 +-84 +-104 +-104 +-45 +67 +82 +48 +11 +-23 +-52 +-76 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-47 +-72 +-93 +-111 +-32 +79 +94 +60 +22 +-14 +-45 +-69 +-91 +-109 +-29 +82 +96 +62 +24 +-12 +-43 +-68 +-90 +-108 +-28 +83 +98 +64 +20 +-15 +-46 +-70 +-15 +89 +92 +54 +11 +-23 +-52 +-76 +-24 +80 +84 +46 +4 +-28 +-57 +-80 +-28 +76 +80 +41 +1 +-32 +-60 +-83 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-3 +-35 +-62 +-85 +-35 +69 +74 +36 +-3 +-35 +-63 +-85 +-105 +-45 +61 +75 +40 +5 +-29 +-57 +-81 +-100 +-102 +-39 +71 +87 +51 +16 +-20 +-49 +-74 +-95 +-112 +-33 +77 +95 +58 +22 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +63 +25 +-12 +-42 +-68 +-89 +-108 +-26 +83 +100 +63 +27 +-11 +-41 +-68 +-89 +-107 +-26 +83 +101 +64 +27 +-11 +-41 +-67 +-88 +-107 +-25 +84 +101 +64 +27 +-10 +-41 +-67 +-88 +-107 +-25 +84 +101 +64 +27 +-10 +-41 +-67 +-88 +-107 +-26 +83 +101 +64 +27 +-10 +-41 +-67 +-88 +-17 +91 +98 +60 +16 +-18 +-48 +-73 +-19 +85 +88 +49 +8 +-26 +-55 +-78 +-26 +78 +82 +43 +2 +-30 +-59 +-82 +-30 +74 +79 +40 +0 +-32 +-60 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-34 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-44 +62 +77 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +71 +88 +52 +16 +-20 +-49 +-74 +-95 +-112 +-32 +77 +94 +58 +22 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +60 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +62 +26 +-12 +-42 +-68 +-89 +-17 +90 +97 +59 +16 +-19 +-49 +-73 +-19 +85 +88 +49 +8 +-26 +-55 +-78 +-26 +78 +83 +44 +3 +-30 +-58 +-81 +-30 +75 +79 +41 +0 +-32 +-60 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-2 +-34 +-62 +-85 +-34 +71 +75 +37 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-4 +-35 +-63 +-86 +-35 +69 +73 +35 +-4 +-36 +-63 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +68 +72 +35 +-3 +-35 +-63 +-85 +-105 +-104 +-45 +66 +81 +47 +10 +-24 +-53 +-77 +-98 +-98 +-36 +75 +89 +55 +17 +-17 +-48 +-72 +-94 +-111 +-31 +79 +94 +60 +21 +-14 +-45 +-70 +-91 +-109 +-29 +82 +97 +62 +23 +-12 +-44 +-69 +-91 +-108 +-28 +83 +97 +63 +20 +-15 +-46 +-70 +-14 +89 +93 +53 +11 +-23 +-52 +-76 +-23 +81 +84 +46 +5 +-28 +-57 +-80 +-28 +75 +80 +41 +1 +-32 +-60 +-83 +-31 +73 +77 +38 +-1 +-33 +-62 +-84 +-33 +71 +74 +37 +-3 +-35 +-63 +-85 +-35 +70 +74 +36 +-3 +-35 +-63 +-85 +-105 +-45 +61 +76 +39 +5 +-30 +-57 +-81 +-100 +-102 +-39 +70 +87 +51 +16 +-20 +-49 +-74 +-95 +-112 +-32 +77 +94 +58 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +96 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +100 +63 +26 +-12 +-42 +-68 +-89 +-17 +90 +97 +59 +16 +-19 +-49 +-73 +-19 +84 +88 +49 +7 +-26 +-55 +-79 +-26 +78 +81 +43 +3 +-30 +-59 +-82 +-30 +75 +78 +40 +0 +-32 +-61 +-83 +-32 +72 +75 +37 +-2 +-34 +-62 +-85 +-33 +70 +74 +36 +-3 +-35 +-63 +-85 +-105 +-45 +61 +77 +40 +5 +-29 +-56 +-81 +-100 +-101 +-39 +71 +88 +52 +16 +-20 +-49 +-74 +-94 +-112 +-33 +77 +94 +57 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-108 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-18 +89 +97 +59 +15 +-19 +-49 +-73 +-20 +84 +87 +49 +7 +-26 +-55 +-79 +-26 +78 +82 +43 +3 +-30 +-59 +-81 +-30 +75 +79 +40 +0 +-32 +-60 +-83 +-33 +72 +76 +38 +-2 +-34 +-62 +-84 +-34 +70 +75 +37 +-3 +-35 +-63 +-85 +-35 +70 +74 +36 +-1 +-33 +-61 +-84 +-104 +-104 +-44 +67 +81 +48 +11 +-23 +-53 +-76 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +95 +61 +22 +-14 +-45 +-70 +-91 +-109 +-29 +83 +97 +64 +24 +-11 +-43 +-68 +-90 +-107 +-27 +85 +99 +65 +21 +-14 +-45 +-70 +-14 +90 +93 +55 +12 +-22 +-52 +-75 +-22 +82 +85 +47 +5 +-27 +-56 +-80 +-27 +77 +81 +43 +2 +-31 +-59 +-82 +-30 +74 +78 +40 +0 +-33 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +70 +75 +37 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +68 +82 +49 +12 +-22 +-52 +-76 +-97 +-97 +-35 +76 +91 +57 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +95 +61 +22 +-13 +-44 +-69 +-91 +-109 +-29 +83 +97 +63 +24 +-12 +-43 +-68 +-90 +-107 +-28 +84 +98 +64 +20 +-15 +-45 +-70 +-15 +89 +93 +54 +11 +-23 +-52 +-76 +-24 +81 +84 +46 +5 +-28 +-57 +-80 +-29 +75 +79 +41 +0 +-32 +-60 +-83 +-32 +72 +76 +38 +-1 +-34 +-62 +-84 +-33 +70 +74 +36 +-3 +-35 +-63 +-85 +-34 +69 +73 +35 +-4 +-35 +-63 +-85 +-105 +-45 +61 +75 +39 +5 +-30 +-57 +-81 +-101 +-102 +-40 +70 +88 +52 +15 +-20 +-49 +-75 +-95 +-113 +-33 +77 +94 +57 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +60 +24 +-13 +-43 +-69 +-90 +-109 +-28 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-18 +90 +97 +59 +16 +-19 +-49 +-73 +-20 +84 +88 +49 +8 +-26 +-55 +-78 +-26 +78 +82 +43 +3 +-30 +-59 +-81 +-30 +75 +79 +40 +0 +-32 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +70 +74 +36 +-3 +-35 +-63 +-85 +-105 +-45 +61 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +71 +88 +52 +16 +-20 +-49 +-74 +-95 +-112 +-32 +77 +94 +58 +21 +-16 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +62 +26 +-12 +-42 +-68 +-89 +-108 +-26 +83 +100 +64 +27 +-11 +-41 +-68 +-89 +-107 +-25 +84 +101 +63 +27 +-11 +-41 +-68 +-89 +-107 +-25 +84 +101 +64 +27 +-11 +-41 +-67 +-88 +-107 +-25 +84 +101 +64 +27 +-11 +-41 +-67 +-88 +-107 +-25 +84 +101 +64 +27 +-11 +-41 +-67 +-88 +-16 +91 +98 +60 +17 +-18 +-48 +-73 +-19 +85 +89 +50 +8 +-25 +-55 +-78 +-25 +79 +82 +44 +3 +-29 +-58 +-81 +-29 +75 +80 +41 +1 +-32 +-60 +-83 +-31 +73 +77 +39 +-1 +-33 +-62 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-34 +71 +75 +37 +-3 +-35 +-63 +-85 +-35 +69 +74 +36 +-4 +-35 +-63 +-86 +-35 +69 +74 +36 +-4 +-35 +-63 +-85 +-36 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +68 +72 +35 +-4 +-36 +-64 +-86 +-36 +68 +72 +35 +-4 +-36 +-64 +-86 +-36 +68 +72 +35 +-2 +-34 +-62 +-85 +-105 +-104 +-45 +66 +81 +47 +10 +-23 +-53 +-77 +-98 +-98 +-36 +75 +89 +56 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +95 +61 +22 +-14 +-45 +-69 +-91 +-109 +-28 +82 +97 +63 +24 +-11 +-43 +-68 +-90 +-107 +-27 +84 +98 +65 +21 +-14 +-45 +-70 +-14 +90 +94 +54 +12 +-22 +-52 +-76 +-22 +82 +86 +47 +6 +-27 +-56 +-80 +-27 +77 +81 +43 +2 +-31 +-59 +-82 +-30 +74 +77 +40 +-1 +-33 +-61 +-83 +-32 +72 +76 +37 +-2 +-34 +-62 +-85 +-34 +70 +75 +36 +-3 +-35 +-63 +-85 +-105 +-45 +61 +76 +39 +4 +-30 +-57 +-81 +-101 +-102 +-39 +70 +87 +51 +15 +-21 +-49 +-75 +-95 +-113 +-34 +76 +93 +56 +20 +-17 +-46 +-72 +-92 +-110 +-31 +77 +94 +58 +22 +-15 +-45 +-71 +-91 +-110 +-30 +80 +97 +60 +23 +-14 +-43 +-70 +-91 +-20 +88 +95 +56 +14 +-20 +-50 +-74 +-21 +83 +86 +47 +6 +-27 +-56 +-79 +-27 +77 +81 +43 +2 +-31 +-59 +-82 +-30 +74 +79 +40 +0 +-32 +-60 +-83 +-32 +72 +77 +39 +-1 +-33 +-62 +-84 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-104 +-43 +63 +78 +42 +7 +-28 +-55 +-80 +-99 +-100 +-37 +72 +90 +53 +17 +-19 +-48 +-74 +-94 +-112 +-32 +77 +95 +59 +22 +-14 +-44 +-70 +-91 +-109 +-29 +80 +97 +61 +25 +-13 +-42 +-69 +-90 +-108 +-27 +82 +99 +63 +26 +-12 +-42 +-68 +-89 +-17 +90 +97 +58 +15 +-19 +-49 +-73 +-20 +83 +86 +47 +6 +-27 +-56 +-79 +-27 +77 +81 +42 +2 +-31 +-59 +-82 +-31 +74 +78 +40 +0 +-33 +-61 +-83 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-4 +-35 +-63 +-85 +-35 +70 +74 +36 +-1 +-33 +-62 +-84 +-104 +-104 +-44 +67 +82 +49 +11 +-22 +-52 +-76 +-97 +-98 +-35 +76 +90 +56 +18 +-17 +-47 +-72 +-93 +-110 +-30 +81 +95 +62 +23 +-13 +-44 +-69 +-91 +-108 +-28 +83 +98 +64 +25 +-11 +-42 +-67 +-90 +-107 +-26 +85 +100 +65 +22 +-14 +-45 +-69 +-14 +90 +94 +54 +12 +-22 +-51 +-75 +-23 +81 +85 +47 +6 +-27 +-56 +-80 +-28 +77 +80 +42 +1 +-31 +-60 +-82 +-31 +74 +77 +39 +-1 +-33 +-61 +-84 +-32 +72 +75 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +36 +-1 +-33 +-62 +-84 +-104 +-104 +-44 +68 +82 +49 +11 +-22 +-52 +-76 +-97 +-98 +-35 +75 +90 +56 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +95 +61 +22 +-13 +-44 +-69 +-91 +-108 +-29 +82 +96 +63 +24 +-12 +-43 +-68 +-90 +-108 +-28 +83 +98 +63 +20 +-15 +-46 +-70 +-15 +89 +92 +54 +11 +-23 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +74 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +76 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-105 +-45 +62 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +88 +52 +16 +-20 +-49 +-74 +-95 +-112 +-33 +76 +93 +57 +20 +-16 +-45 +-71 +-92 +-110 +-30 +80 +97 +60 +23 +-14 +-44 +-70 +-91 +-109 +-28 +82 +99 +62 +25 +-12 +-42 +-68 +-90 +-18 +89 +97 +58 +15 +-19 +-49 +-74 +-20 +84 +87 +48 +7 +-27 +-56 +-79 +-26 +77 +82 +43 +2 +-31 +-59 +-82 +-30 +74 +78 +40 +0 +-33 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-44 +62 +76 +40 +6 +-29 +-56 +-81 +-100 +-101 +-39 +71 +88 +52 +16 +-20 +-49 +-74 +-94 +-112 +-32 +77 +94 +58 +21 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +63 +26 +-12 +-42 +-68 +-89 +-18 +89 +97 +59 +15 +-19 +-49 +-73 +-20 +84 +87 +49 +7 +-26 +-55 +-79 +-26 +78 +82 +43 +2 +-30 +-59 +-82 +-30 +74 +78 +40 +0 +-32 +-60 +-83 +-33 +72 +76 +38 +-2 +-34 +-62 +-84 +-34 +70 +75 +37 +-3 +-35 +-63 +-85 +-35 +70 +74 +36 +-1 +-33 +-62 +-84 +-104 +-104 +-45 +67 +82 +48 +11 +-23 +-53 +-77 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +95 +61 +22 +-13 +-44 +-69 +-91 +-109 +-28 +83 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +84 +99 +65 +21 +-14 +-45 +-70 +-14 +89 +94 +54 +12 +-22 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +75 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +76 +38 +-1 +-34 +-62 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-35 +69 +74 +36 +-1 +-33 +-61 +-84 +-104 +-103 +-43 +68 +83 +49 +12 +-22 +-52 +-76 +-97 +-97 +-35 +76 +91 +57 +19 +-16 +-47 +-71 +-93 +-110 +-30 +82 +96 +62 +23 +-12 +-44 +-69 +-91 +-108 +-27 +83 +98 +64 +25 +-11 +-42 +-67 +-90 +-107 +-27 +85 +99 +65 +21 +-14 +-45 +-70 +-14 +90 +93 +54 +12 +-22 +-52 +-76 +-22 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-105 +-45 +62 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +88 +52 +15 +-20 +-49 +-75 +-95 +-97 +-32 +77 +94 +57 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +60 +24 +-13 +-43 +-69 +-90 +-109 +-28 +81 +98 +62 +25 +-12 +-42 +-68 +-90 +-18 +89 +97 +58 +15 +-19 +-49 +-73 +-21 +83 +87 +48 +7 +-27 +-56 +-79 +-27 +77 +81 +43 +2 +-31 +-59 +-82 +-30 +74 +77 +40 +0 +-33 +-61 +-83 +-33 +72 +76 +38 +-2 +-34 +-62 +-85 +-34 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-45 +62 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +71 +88 +52 +16 +-20 +-49 +-74 +-95 +-112 +-33 +77 +94 +58 +21 +-16 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-108 +-27 +82 +99 +62 +26 +-12 +-42 +-68 +-89 +-17 +90 +97 +59 +15 +-19 +-49 +-73 +-20 +84 +87 +49 +7 +-26 +-55 +-79 +-27 +78 +82 +43 +3 +-30 +-59 +-82 +-30 +75 +79 +40 +0 +-32 +-60 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-85 +-33 +70 +74 +37 +-3 +-35 +-63 +-85 +-35 +70 +74 +37 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +67 +81 +48 +11 +-23 +-53 +-76 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-48 +-72 +-94 +-111 +-31 +80 +94 +60 +22 +-14 +-45 +-69 +-92 +-109 +-29 +83 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +84 +99 +64 +25 +-11 +-42 +-67 +-90 +-107 +-27 +84 +99 +65 +26 +-10 +-42 +-67 +-89 +-107 +-27 +85 +99 +65 +26 +-10 +-42 +-67 +-89 +-107 +-26 +86 +100 +65 +26 +-10 +-41 +-67 +-89 +-106 +-26 +85 +100 +66 +27 +-9 +-41 +-67 +-89 +-106 +-26 +86 +100 +66 +22 +-14 +-45 +-69 +-13 +90 +94 +55 +12 +-22 +-51 +-75 +-22 +82 +86 +47 +6 +-27 +-56 +-79 +-27 +77 +81 +43 +2 +-30 +-59 +-82 +-30 +74 +77 +40 +0 +-32 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-3 +-34 +-63 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-35 +69 +74 +36 +-4 +-35 +-63 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-5 +-36 +-64 +-86 +-35 +69 +72 +35 +-4 +-36 +-64 +-86 +-36 +68 +72 +34 +-5 +-36 +-64 +-86 +-106 +-46 +60 +75 +39 +4 +-30 +-58 +-82 +-101 +-102 +-40 +70 +87 +51 +15 +-21 +-49 +-75 +-95 +-97 +-33 +77 +93 +57 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +60 +24 +-13 +-43 +-69 +-90 +-109 +-28 +81 +99 +62 +25 +-12 +-42 +-68 +-89 +-18 +89 +97 +58 +15 +-19 +-49 +-74 +-20 +83 +87 +48 +7 +-26 +-55 +-79 +-27 +77 +81 +43 +2 +-31 +-59 +-82 +-31 +74 +77 +40 +-1 +-33 +-61 +-84 +-33 +72 +75 +37 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-105 +-45 +61 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +88 +52 +16 +-20 +-49 +-74 +-95 +-112 +-33 +77 +94 +58 +21 +-16 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-108 +-27 +82 +99 +63 +26 +-12 +-42 +-68 +-89 +-108 +-26 +83 +100 +63 +27 +-11 +-41 +-68 +-89 +-107 +-26 +83 +100 +64 +27 +-11 +-41 +-68 +-88 +-107 +-26 +84 +101 +64 +27 +-10 +-41 +-67 +-88 +-107 +-25 +84 +100 +64 +27 +-10 +-41 +-67 +-88 +-107 +-26 +83 +101 +65 +27 +-10 +-40 +-67 +-88 +-16 +91 +98 +60 +17 +-18 +-48 +-73 +-19 +85 +88 +49 +7 +-26 +-55 +-78 +-26 +78 +82 +43 +3 +-30 +-59 +-81 +-30 +75 +79 +41 +0 +-32 +-60 +-83 +-32 +72 +77 +38 +-2 +-34 +-62 +-84 +-34 +70 +75 +37 +-3 +-35 +-63 +-85 +-35 +70 +74 +36 +-1 +-33 +-62 +-84 +-104 +-103 +-44 +67 +82 +48 +11 +-23 +-52 +-76 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-47 +-72 +-93 +-110 +-32 +80 +95 +61 +22 +-13 +-44 +-69 +-91 +-109 +-29 +82 +97 +62 +24 +-12 +-43 +-68 +-90 +-108 +-27 +85 +99 +65 +21 +-14 +-45 +-70 +-14 +89 +93 +53 +11 +-23 +-52 +-76 +-22 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +77 +81 +43 +2 +-31 +-59 +-82 +-30 +74 +77 +39 +-1 +-33 +-61 +-84 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +38 +-2 +-34 +-62 +-85 +-34 +70 +75 +37 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-34 +69 +74 +36 +-4 +-35 +-63 +-86 +-35 +69 +74 +35 +-4 +-36 +-63 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +68 +72 +35 +-4 +-36 +-64 +-86 +-36 +68 +72 +34 +-5 +-36 +-64 +-86 +-36 +68 +72 +34 +-5 +-37 +-64 +-86 +-36 +68 +71 +33 +-6 +-37 +-65 +-87 +-37 +67 +72 +33 +-6 +-37 +-65 +-87 +-37 +68 +72 +34 +-5 +-37 +-64 +-86 +-37 +68 +72 +33 +-5 +-37 +-65 +-87 +-37 +68 +72 +34 +-5 +-37 +-64 +-86 +-36 +68 +73 +35 +-3 +-35 +-62 +-85 +-105 +-104 +-45 +65 +80 +47 +10 +-24 +-53 +-77 +-98 +-98 +-37 +74 +89 +56 +17 +-17 +-48 +-72 +-94 +-111 +-31 +80 +94 +60 +22 +-14 +-45 +-69 +-92 +-109 +-29 +83 +97 +63 +24 +-12 +-43 +-68 +-90 +-107 +-27 +85 +99 +64 +25 +-10 +-42 +-67 +-89 +-107 +-27 +85 +100 +65 +26 +-10 +-41 +-67 +-89 +-106 +-26 +85 +99 +65 +26 +-10 +-42 +-67 +-89 +-107 +-26 +85 +99 +65 +26 +-10 +-42 +-67 +-89 +-107 +-27 +85 +99 +65 +26 +-10 +-42 +-67 +-89 +-106 +-26 +85 +100 +65 +26 +-10 +-41 +-67 +-89 +-106 +-26 +85 +100 +65 +26 +-10 +-41 +-67 +-89 +-106 +-26 +86 +100 +65 +26 +-10 +-41 +-67 +-89 +-106 +-26 +86 +100 +65 +26 +-10 +-41 +-67 +-89 +-106 +-26 +86 +100 +65 +26 +-10 +-41 +-67 +-89 +-106 +-26 +86 +100 +66 +22 +-13 +-44 +-69 +-14 +90 +94 +55 +12 +-22 +-52 +-75 +-22 +81 +84 +46 +5 +-28 +-57 +-80 +-28 +77 +81 +42 +2 +-31 +-59 +-82 +-30 +74 +77 +39 +-1 +-33 +-61 +-84 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +0 +-33 +-61 +-84 +-104 +-103 +-43 +68 +83 +49 +12 +-22 +-52 +-76 +-97 +-97 +-35 +76 +90 +57 +19 +-16 +-47 +-71 +-93 +-110 +-30 +81 +95 +61 +22 +-13 +-44 +-69 +-91 +-108 +-28 +83 +97 +63 +24 +-11 +-43 +-68 +-90 +-107 +-27 +84 +98 +64 +20 +-15 +-46 +-70 +-14 +90 +93 +54 +12 +-22 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +41 +1 +-32 +-60 +-83 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +72 +75 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-105 +-45 +62 +77 +40 +5 +-29 +-57 +-81 +-100 +-101 +-38 +71 +88 +52 +16 +-20 +-49 +-74 +-94 +-112 +-32 +77 +95 +58 +22 +-15 +-45 +-71 +-91 +-110 +-28 +81 +98 +62 +25 +-13 +-42 +-69 +-90 +-108 +-27 +82 +100 +63 +26 +-11 +-42 +-68 +-89 +-17 +91 +98 +59 +16 +-18 +-49 +-73 +-19 +85 +88 +50 +8 +-26 +-55 +-78 +-26 +78 +82 +43 +3 +-30 +-59 +-81 +-30 +74 +78 +39 +-1 +-33 +-61 +-84 +-32 +72 +76 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +36 +-4 +-35 +-63 +-85 +-105 +-45 +61 +75 +38 +4 +-30 +-57 +-81 +-101 +-102 +-40 +69 +86 +50 +14 +-22 +-50 +-76 +-96 +-113 +-35 +74 +91 +55 +19 +-17 +-47 +-72 +-93 +-111 +-31 +78 +95 +58 +22 +-15 +-45 +-71 +-91 +-109 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-19 +89 +96 +58 +15 +-19 +-49 +-74 +-20 +84 +87 +48 +7 +-27 +-55 +-79 +-26 +79 +83 +44 +3 +-30 +-58 +-81 +-29 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +74 +77 +39 +-1 +-33 +-61 +-84 +-33 +72 +76 +38 +-1 +-34 +-62 +-84 +-33 +71 +76 +37 +0 +-32 +-61 +-83 +-103 +-103 +-44 +67 +82 +49 +11 +-22 +-52 +-76 +-97 +-98 +-36 +75 +91 +57 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +94 +60 +22 +-14 +-45 +-70 +-91 +-109 +-29 +82 +96 +63 +24 +-12 +-43 +-68 +-90 +-108 +-28 +83 +98 +64 +20 +-15 +-46 +-70 +-15 +88 +92 +53 +11 +-23 +-53 +-76 +-24 +80 +83 +45 +4 +-29 +-57 +-81 +-29 +75 +80 +41 +1 +-32 +-60 +-83 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +72 +76 +38 +-2 +-34 +-62 +-85 +-34 +70 +75 +37 +0 +-33 +-61 +-83 +-104 +-103 +-43 +69 +83 +50 +12 +-22 +-52 +-76 +-97 +-97 +-35 +77 +91 +57 +19 +-16 +-47 +-71 +-93 +-110 +-30 +81 +95 +62 +23 +-13 +-44 +-69 +-91 +-108 +-28 +83 +97 +64 +25 +-11 +-42 +-67 +-90 +-107 +-27 +84 +99 +65 +21 +-14 +-45 +-70 +-14 +90 +94 +54 +12 +-22 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +76 +37 +-2 +-34 +-62 +-85 +-34 +69 +74 +36 +-3 +-35 +-63 +-85 +-105 +-45 +61 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +88 +52 +16 +-20 +-49 +-74 +-95 +-112 +-33 +77 +94 +57 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-28 +82 +99 +63 +26 +-12 +-42 +-68 +-89 +-18 +90 +97 +59 +16 +-19 +-49 +-73 +-20 +84 +87 +48 +7 +-26 +-55 +-79 +-26 +78 +82 +43 +2 +-30 +-59 +-82 +-30 +74 +77 +40 +0 +-33 +-61 +-83 +-32 +71 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-45 +62 +75 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +88 +51 +15 +-20 +-49 +-75 +-95 +-97 +-33 +76 +93 +57 +21 +-16 +-45 +-71 +-92 +-110 +-30 +80 +97 +60 +23 +-14 +-43 +-70 +-90 +-109 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-90 +-108 +-27 +83 +100 +63 +26 +-11 +-41 +-68 +-89 +-108 +-26 +83 +101 +63 +27 +-11 +-41 +-67 +-89 +-107 +-26 +83 +101 +64 +27 +-10 +-41 +-67 +-88 +-107 +-25 +84 +101 +65 +27 +-10 +-40 +-67 +-88 +-107 +-25 +84 +101 +65 +27 +-10 +-41 +-67 +-88 +-16 +91 +98 +59 +16 +-18 +-48 +-73 +-19 +84 +88 +50 +8 +-25 +-55 +-78 +-26 +79 +82 +44 +3 +-30 +-58 +-81 +-30 +75 +79 +41 +0 +-32 +-60 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +74 +37 +-3 +-35 +-63 +-85 +-35 +69 +74 +36 +-3 +-35 +-63 +-85 +-35 +69 +74 +35 +-4 +-36 +-64 +-86 +-36 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +68 +72 +35 +-4 +-36 +-64 +-86 +-36 +68 +73 +35 +-2 +-34 +-62 +-85 +-105 +-104 +-44 +67 +81 +48 +11 +-23 +-53 +-77 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-48 +-72 +-94 +-110 +-31 +80 +95 +61 +22 +-13 +-44 +-69 +-91 +-108 +-29 +83 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +84 +98 +64 +20 +-15 +-45 +-70 +-14 +89 +93 +54 +11 +-22 +-52 +-76 +-23 +81 +84 +46 +5 +-29 +-57 +-80 +-28 +75 +80 +41 +1 +-32 +-60 +-83 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +72 +76 +37 +-2 +-34 +-62 +-85 +-33 +71 +75 +37 +-3 +-34 +-62 +-85 +-104 +-44 +62 +77 +41 +6 +-28 +-56 +-80 +-100 +-101 +-37 +72 +89 +53 +17 +-19 +-48 +-74 +-94 +-112 +-31 +78 +95 +59 +22 +-15 +-44 +-70 +-91 +-109 +-28 +81 +97 +61 +25 +-13 +-43 +-69 +-90 +-108 +-27 +82 +99 +63 +26 +-12 +-42 +-68 +-89 +-18 +90 +97 +58 +15 +-19 +-49 +-74 +-20 +84 +87 +48 +7 +-26 +-56 +-79 +-26 +78 +82 +43 +2 +-30 +-59 +-82 +-30 +74 +78 +40 +0 +-33 +-61 +-83 +-32 +72 +75 +37 +-2 +-34 +-62 +-85 +-33 +70 +74 +36 +-4 +-35 +-63 +-85 +-105 +-45 +61 +75 +39 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +88 +51 +15 +-20 +-49 +-74 +-95 +-113 +-33 +76 +93 +57 +21 +-16 +-45 +-71 +-92 +-110 +-30 +80 +97 +60 +24 +-13 +-43 +-69 +-90 +-109 +-28 +81 +98 +62 +25 +-12 +-42 +-68 +-90 +-18 +89 +96 +58 +15 +-19 +-49 +-74 +-20 +83 +87 +49 +7 +-26 +-55 +-79 +-27 +77 +81 +43 +2 +-30 +-59 +-82 +-30 +75 +79 +40 +0 +-32 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +70 +74 +36 +-3 +-35 +-63 +-85 +-34 +70 +75 +37 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +67 +82 +48 +11 +-23 +-52 +-76 +-97 +-98 +-36 +75 +90 +57 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +95 +61 +22 +-13 +-44 +-69 +-91 +-109 +-29 +82 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +84 +98 +64 +20 +-15 +-45 +-70 +-15 +89 +93 +54 +11 +-22 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +38 +-1 +-34 +-62 +-84 +-33 +71 +76 +37 +-2 +-34 +-62 +-85 +-35 +70 +74 +37 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +67 +82 +49 +11 +-23 +-52 +-76 +-97 +-98 +-36 +75 +90 +57 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +95 +61 +22 +-13 +-44 +-69 +-91 +-108 +-28 +83 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-28 +84 +98 +64 +20 +-15 +-46 +-70 +-15 +89 +93 +54 +12 +-22 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +2 +-31 +-59 +-82 +-31 +73 +77 +40 +-1 +-33 +-61 +-84 +-33 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-44 +62 +77 +41 +6 +-28 +-56 +-81 +-100 +-101 +-38 +71 +89 +53 +17 +-19 +-48 +-74 +-94 +-112 +-32 +77 +95 +58 +22 +-15 +-45 +-71 +-91 +-110 +-28 +81 +97 +62 +24 +-13 +-43 +-69 +-90 +-108 +-27 +83 +99 +63 +26 +-12 +-42 +-68 +-89 +-17 +90 +97 +59 +16 +-19 +-49 +-73 +-20 +84 +87 +48 +7 +-26 +-56 +-79 +-27 +77 +81 +43 +2 +-31 +-59 +-82 +-31 +74 +77 +40 +0 +-33 +-61 +-83 +-33 +71 +75 +37 +-2 +-34 +-62 +-85 +-34 +70 +75 +36 +-3 +-35 +-63 +-85 +-105 +-45 +62 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +88 +52 +16 +-20 +-49 +-74 +-95 +-112 +-33 +77 +94 +57 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-28 +82 +99 +62 +25 +-12 +-42 +-68 +-90 +-18 +89 +96 +57 +15 +-20 +-50 +-74 +-20 +83 +86 +48 +7 +-27 +-56 +-79 +-27 +77 +81 +43 +2 +-31 +-59 +-82 +-30 +74 +79 +40 +0 +-33 +-61 +-83 +-32 +71 +75 +37 +-3 +-35 +-62 +-85 +-33 +71 +74 +36 +-3 +-35 +-63 +-85 +-35 +70 +74 +36 +-1 +-33 +-62 +-84 +-104 +-104 +-44 +67 +82 +48 +11 +-23 +-53 +-76 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-47 +-72 +-94 +-110 +-31 +80 +95 +61 +22 +-13 +-44 +-69 +-91 +-109 +-29 +83 +97 +63 +24 +-12 +-43 +-68 +-90 +-107 +-27 +84 +98 +64 +21 +-14 +-45 +-70 +-14 +89 +93 +54 +12 +-22 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +37 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +67 +82 +48 +11 +-23 +-53 +-76 +-97 +-98 +-35 +75 +90 +57 +18 +-16 +-47 +-72 +-93 +-110 +-31 +80 +95 +61 +22 +-13 +-44 +-69 +-91 +-109 +-29 +83 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-28 +83 +98 +64 +21 +-15 +-45 +-70 +-15 +89 +93 +54 +11 +-22 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +72 +75 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +37 +-3 +-35 +-63 +-85 +-105 +-44 +62 +76 +40 +6 +-29 +-56 +-81 +-100 +-101 +-39 +71 +89 +52 +16 +-19 +-49 +-74 +-94 +-112 +-32 +77 +95 +59 +22 +-15 +-44 +-71 +-91 +-109 +-28 +81 +99 +62 +25 +-13 +-42 +-69 +-90 +-108 +-27 +83 +100 +63 +27 +-11 +-41 +-68 +-89 +-107 +-25 +84 +101 +64 +27 +-11 +-41 +-67 +-88 +-107 +-25 +84 +101 +64 +27 +-10 +-41 +-67 +-88 +-107 +-25 +84 +101 +64 +27 +-11 +-41 +-67 +-88 +-107 +-25 +84 +101 +65 +28 +-10 +-40 +-67 +-88 +-107 +-25 +84 +101 +65 +27 +-10 +-41 +-67 +-88 +-16 +91 +98 +60 +17 +-18 +-48 +-73 +-19 +84 +88 +49 +8 +-26 +-55 +-78 +-26 +78 +82 +43 +3 +-30 +-59 +-82 +-30 +74 +77 +40 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-3 +-35 +-62 +-85 +-34 +70 +74 +36 +-4 +-35 +-63 +-85 +-105 +-45 +61 +75 +39 +4 +-30 +-57 +-81 +-101 +-102 +-40 +70 +87 +51 +15 +-21 +-49 +-75 +-95 +-113 +-33 +76 +93 +57 +21 +-16 +-45 +-71 +-92 +-110 +-30 +80 +97 +60 +24 +-13 +-43 +-69 +-90 +-109 +-28 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-18 +89 +97 +58 +15 +-19 +-49 +-74 +-20 +84 +88 +49 +7 +-26 +-55 +-79 +-26 +78 +82 +43 +2 +-30 +-59 +-82 +-30 +75 +79 +40 +0 +-32 +-60 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +74 +36 +-3 +-35 +-63 +-85 +-34 +71 +75 +37 +-3 +-35 +-63 +-85 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +68 +72 +35 +-4 +-36 +-64 +-86 +-36 +68 +73 +35 +-2 +-34 +-63 +-85 +-104 +-104 +-45 +66 +81 +47 +10 +-23 +-53 +-77 +-98 +-98 +-36 +75 +90 +56 +18 +-17 +-48 +-72 +-94 +-111 +-31 +80 +94 +61 +22 +-13 +-44 +-69 +-91 +-109 +-29 +82 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-28 +83 +98 +64 +20 +-15 +-46 +-70 +-15 +89 +93 +54 +11 +-22 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +2 +-31 +-59 +-82 +-30 +74 +77 +40 +-1 +-33 +-61 +-84 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-44 +62 +77 +40 +6 +-29 +-56 +-81 +-100 +-101 +-39 +71 +88 +52 +16 +-20 +-49 +-74 +-94 +-112 +-32 +77 +94 +58 +22 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +60 +24 +-13 +-43 +-69 +-90 +-109 +-27 +81 +98 +62 +25 +-12 +-42 +-68 +-89 +-18 +89 +97 +59 +16 +-19 +-49 +-73 +-20 +84 +87 +48 +7 +-26 +-55 +-79 +-26 +78 +81 +43 +2 +-30 +-59 +-82 +-30 +74 +78 +40 +0 +-32 +-61 +-83 +-32 +72 +76 +37 +-2 +-34 +-62 +-85 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-44 +62 +76 +40 +6 +-28 +-56 +-81 +-100 +-101 +-38 +71 +89 +52 +16 +-19 +-49 +-74 +-94 +-112 +-32 +77 +95 +59 +22 +-14 +-44 +-70 +-91 +-109 +-28 +81 +98 +62 +25 +-12 +-42 +-69 +-90 +-108 +-26 +83 +99 +63 +26 +-11 +-41 +-68 +-89 +-17 +90 +97 +59 +16 +-19 +-49 +-73 +-20 +84 +88 +49 +7 +-26 +-55 +-79 +-26 +78 +81 +42 +2 +-31 +-59 +-82 +-31 +74 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +68 +72 +34 +-3 +-35 +-63 +-85 +-105 +-104 +-46 +65 +79 +46 +9 +-25 +-54 +-78 +-98 +-99 +-38 +73 +88 +54 +16 +-18 +-49 +-73 +-94 +-111 +-33 +78 +93 +59 +21 +-14 +-45 +-70 +-92 +-109 +-30 +82 +97 +62 +23 +-12 +-44 +-69 +-91 +-108 +-27 +85 +99 +65 +21 +-14 +-45 +-70 +-14 +90 +94 +54 +12 +-22 +-52 +-76 +-22 +82 +86 +47 +6 +-27 +-56 +-79 +-27 +77 +81 +43 +2 +-31 +-59 +-82 +-29 +75 +78 +40 +0 +-32 +-60 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +68 +83 +49 +11 +-22 +-52 +-76 +-97 +-98 +-36 +76 +90 +57 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +94 +60 +22 +-14 +-45 +-69 +-91 +-109 +-30 +82 +96 +62 +23 +-12 +-43 +-69 +-91 +-108 +-28 +83 +97 +63 +19 +-16 +-46 +-71 +-15 +89 +92 +53 +11 +-23 +-53 +-76 +-23 +80 +84 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-30 +74 +78 +40 +0 +-32 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-44 +62 +77 +41 +6 +-28 +-56 +-80 +-100 +-101 +-38 +72 +89 +53 +17 +-19 +-48 +-74 +-94 +-112 +-32 +77 +95 +58 +22 +-15 +-45 +-70 +-91 +-110 +-28 +81 +98 +62 +24 +-13 +-42 +-69 +-90 +-108 +-27 +82 +99 +63 +26 +-12 +-42 +-68 +-89 +-17 +90 +97 +59 +16 +-18 +-49 +-73 +-20 +83 +88 +49 +7 +-26 +-55 +-79 +-26 +77 +82 +43 +3 +-30 +-59 +-82 +-30 +74 +78 +40 +0 +-33 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-44 +61 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +87 +51 +15 +-20 +-49 +-75 +-95 +-97 +-33 +76 +93 +57 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-108 +-26 +83 +100 +63 +26 +-11 +-41 +-68 +-89 +-108 +-26 +83 +100 +64 +27 +-11 +-41 +-67 +-89 +-107 +-26 +83 +101 +64 +27 +-11 +-41 +-67 +-88 +-107 +-25 +84 +101 +63 +27 +-11 +-41 +-67 +-89 +-107 +-26 +83 +100 +64 +27 +-11 +-41 +-67 +-88 +-17 +91 +97 +59 +16 +-19 +-49 +-73 +-19 +84 +87 +49 +7 +-26 +-55 +-79 +-26 +78 +82 +43 +2 +-30 +-59 +-82 +-30 +75 +78 +40 +0 +-33 +-61 +-83 +-32 +72 +76 +37 +-2 +-34 +-62 +-85 +-33 +70 +74 +36 +-3 +-35 +-63 +-85 +-35 +70 +74 +36 +-4 +-35 +-63 +-85 +-35 +69 +74 +36 +-4 +-35 +-63 +-86 +-35 +69 +73 +35 +-4 +-36 +-63 +-86 +-36 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +69 +73 +35 +-2 +-34 +-62 +-85 +-104 +-104 +-45 +67 +81 +48 +10 +-23 +-53 +-77 +-98 +-98 +-36 +75 +90 +56 +17 +-17 +-48 +-72 +-94 +-111 +-31 +80 +94 +60 +22 +-14 +-45 +-69 +-91 +-109 +-29 +82 +96 +62 +24 +-12 +-43 +-68 +-90 +-108 +-28 +84 +98 +64 +20 +-15 +-45 +-70 +-14 +89 +93 +54 +12 +-22 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +37 +-3 +-35 +-63 +-85 +-105 +-45 +62 +77 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +71 +88 +52 +17 +-19 +-48 +-74 +-94 +-112 +-32 +77 +94 +58 +21 +-16 +-45 +-71 +-91 +-110 +-29 +80 +97 +60 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +98 +62 +25 +-12 +-42 +-68 +-89 +-18 +89 +96 +58 +15 +-19 +-49 +-74 +-20 +84 +88 +49 +7 +-26 +-55 +-79 +-26 +78 +82 +44 +3 +-30 +-58 +-81 +-29 +75 +79 +41 +1 +-32 +-60 +-83 +-31 +72 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +76 +38 +-2 +-34 +-62 +-84 +-104 +-44 +63 +78 +42 +6 +-28 +-56 +-80 +-99 +-101 +-37 +71 +88 +52 +16 +-19 +-48 +-74 +-94 +-112 +-33 +77 +95 +58 +21 +-16 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-18 +90 +97 +59 +16 +-19 +-49 +-73 +-20 +84 +87 +48 +6 +-27 +-56 +-79 +-26 +78 +81 +43 +2 +-31 +-59 +-82 +-31 +74 +79 +40 +0 +-32 +-60 +-83 +-33 +71 +76 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-35 +69 +74 +36 +-2 +-34 +-62 +-84 +-104 +-104 +-44 +67 +80 +47 +10 +-23 +-53 +-77 +-98 +-98 +-36 +75 +89 +56 +18 +-17 +-48 +-72 +-94 +-111 +-32 +79 +94 +60 +21 +-14 +-45 +-70 +-92 +-109 +-29 +82 +97 +62 +24 +-12 +-43 +-68 +-90 +-108 +-28 +83 +98 +64 +20 +-15 +-46 +-70 +-15 +89 +93 +54 +11 +-22 +-52 +-76 +-23 +81 +84 +46 +5 +-28 +-57 +-80 +-28 +77 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +72 +76 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +37 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +67 +82 +49 +11 +-23 +-52 +-76 +-97 +-98 +-36 +76 +90 +56 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +94 +61 +22 +-13 +-44 +-69 +-91 +-109 +-29 +83 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-28 +83 +98 +64 +20 +-15 +-45 +-70 +-15 +89 +93 +53 +11 +-23 +-52 +-76 +-23 +80 +84 +46 +5 +-28 +-57 +-80 +-28 +75 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +72 +76 +37 +-2 +-34 +-62 +-85 +-33 +70 +74 +37 +-3 +-35 +-63 +-85 +-105 +-45 +62 +77 +40 +5 +-29 +-56 +-81 +-100 +-101 +-39 +70 +88 +52 +16 +-20 +-49 +-74 +-94 +-112 +-33 +77 +94 +58 +21 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-70 +-90 +-109 +-27 +82 +99 +63 +26 +-12 +-42 +-68 +-89 +-18 +90 +97 +59 +16 +-19 +-49 +-73 +-19 +85 +88 +49 +7 +-26 +-55 +-79 +-26 +78 +82 +43 +3 +-30 +-58 +-81 +-29 +75 +78 +40 +0 +-32 +-60 +-83 +-31 +73 +77 +39 +-1 +-33 +-62 +-84 +-33 +71 +75 +37 +-2 +-34 +-62 +-85 +-105 +-43 +63 +77 +41 +6 +-28 +-56 +-80 +-100 +-101 +-38 +71 +88 +53 +17 +-19 +-49 +-74 +-94 +-112 +-32 +77 +94 +58 +22 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-108 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-18 +89 +97 +58 +15 +-19 +-49 +-74 +-20 +83 +87 +48 +7 +-27 +-56 +-79 +-27 +77 +81 +43 +2 +-31 +-59 +-82 +-30 +74 +78 +40 +-1 +-33 +-61 +-84 +-32 +71 +75 +37 +-3 +-35 +-62 +-85 +-33 +70 +74 +37 +-3 +-35 +-63 +-85 +-35 +70 +74 +36 +-1 +-33 +-62 +-84 +-104 +-104 +-44 +67 +81 +47 +10 +-23 +-53 +-77 +-97 +-98 +-36 +75 +89 +55 +17 +-17 +-48 +-72 +-94 +-111 +-31 +79 +94 +60 +21 +-14 +-45 +-70 +-92 +-109 +-29 +82 +96 +62 +24 +-12 +-43 +-68 +-90 +-108 +-28 +84 +98 +63 +20 +-15 +-46 +-70 +-15 +89 +93 +53 +11 +-23 +-52 +-76 +-23 +81 +84 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +76 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +37 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +67 +82 +49 +11 +-22 +-52 +-76 +-97 +-97 +-36 +76 +91 +57 +18 +-17 +-47 +-71 +-93 +-110 +-31 +80 +95 +61 +22 +-13 +-45 +-69 +-91 +-109 +-29 +82 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +83 +98 +64 +20 +-15 +-45 +-70 +-14 +89 +93 +54 +11 +-22 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +75 +80 +42 +1 +-31 +-59 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-32 +71 +76 +37 +-2 +-34 +-62 +-85 +-34 +70 +74 +37 +-3 +-35 +-63 +-85 +-105 +-45 +61 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +88 +52 +16 +-20 +-49 +-74 +-95 +-112 +-32 +77 +94 +58 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +60 +24 +-13 +-43 +-69 +-90 +-109 +-28 +82 +99 +63 +26 +-12 +-42 +-68 +-89 +-18 +90 +97 +59 +16 +-19 +-49 +-73 +-20 +84 +87 +48 +7 +-26 +-56 +-79 +-26 +78 +82 +43 +2 +-30 +-59 +-82 +-30 +75 +79 +40 +0 +-32 +-60 +-83 +-32 +73 +77 +38 +-2 +-34 +-62 +-84 +-34 +70 +75 +37 +-2 +-34 +-62 +-85 +-104 +-44 +62 +77 +41 +6 +-28 +-56 +-81 +-100 +-101 +-38 +71 +88 +53 +17 +-19 +-48 +-74 +-94 +-112 +-32 +77 +95 +59 +22 +-15 +-44 +-70 +-91 +-110 +-28 +81 +98 +62 +25 +-12 +-42 +-69 +-90 +-108 +-27 +83 +99 +63 +26 +-11 +-42 +-68 +-89 +-17 +91 +97 +59 +16 +-19 +-49 +-73 +-20 +84 +87 +49 +7 +-26 +-55 +-78 +-26 +78 +82 +43 +2 +-30 +-59 +-81 +-30 +75 +79 +41 +0 +-32 +-60 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-85 +-34 +71 +75 +37 +-3 +-35 +-63 +-85 +-35 +70 +74 +36 +-1 +-33 +-62 +-84 +-104 +-104 +-45 +66 +81 +48 +10 +-24 +-53 +-77 +-97 +-98 +-37 +75 +89 +55 +17 +-17 +-48 +-72 +-94 +-111 +-32 +79 +94 +59 +21 +-14 +-45 +-70 +-92 +-109 +-30 +81 +96 +61 +23 +-13 +-44 +-69 +-91 +-108 +-28 +83 +98 +63 +24 +-11 +-43 +-68 +-90 +-107 +-27 +84 +98 +64 +25 +-11 +-42 +-67 +-90 +-107 +-27 +84 +99 +65 +26 +-10 +-42 +-67 +-89 +-107 +-26 +85 +100 +65 +26 +-10 +-41 +-67 +-89 +-107 +-26 +85 +99 +65 +26 +-10 +-42 +-67 +-89 +-107 +-26 +86 +100 +65 +22 +-14 +-44 +-69 +-14 +90 +94 +55 +12 +-21 +-51 +-75 +-22 +82 +86 +47 +6 +-27 +-56 +-80 +-28 +77 +80 +42 +1 +-31 +-59 +-82 +-31 +74 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-3 +-34 +-62 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-35 +69 +73 +36 +-4 +-35 +-63 +-85 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +68 +73 +35 +-4 +-36 +-64 +-86 +-35 +68 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-106 +-46 +61 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +88 +52 +16 +-20 +-49 +-74 +-95 +-112 +-33 +77 +93 +57 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +60 +23 +-14 +-43 +-70 +-90 +-109 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-17 +90 +97 +59 +16 +-19 +-49 +-73 +-19 +85 +88 +49 +8 +-26 +-55 +-78 +-26 +78 +82 +44 +3 +-30 +-58 +-81 +-29 +75 +79 +41 +1 +-32 +-60 +-83 +-32 +73 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-2 +-34 +-62 +-85 +-104 +-44 +63 +77 +40 +5 +-29 +-56 +-81 +-100 +-101 +-38 +71 +88 +52 +16 +-19 +-49 +-74 +-94 +-112 +-33 +77 +94 +57 +21 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-108 +-26 +83 +100 +63 +26 +-11 +-41 +-68 +-89 +-107 +-26 +84 +100 +63 +27 +-11 +-41 +-68 +-89 +-107 +-26 +83 +101 +64 +27 +-11 +-41 +-67 +-88 +-107 +-25 +85 +101 +65 +28 +-10 +-40 +-67 +-88 +-107 +-24 +85 +101 +65 +28 +-10 +-40 +-67 +-88 +-16 +91 +98 +60 +17 +-17 +-48 +-72 +-19 +86 +89 +50 +8 +-25 +-54 +-78 +-25 +79 +83 +45 +4 +-29 +-58 +-81 +-29 +76 +80 +41 +1 +-32 +-60 +-83 +-31 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-35 +70 +74 +36 +-1 +-33 +-62 +-84 +-104 +-104 +-45 +66 +81 +47 +10 +-24 +-53 +-77 +-98 +-98 +-37 +75 +89 +55 +17 +-18 +-48 +-73 +-94 +-111 +-33 +78 +92 +58 +20 +-15 +-46 +-71 +-92 +-109 +-31 +80 +94 +60 +21 +-14 +-45 +-70 +-91 +-109 +-30 +82 +96 +62 +19 +-16 +-47 +-71 +-16 +87 +92 +52 +10 +-23 +-53 +-77 +-24 +80 +84 +45 +4 +-29 +-58 +-81 +-29 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +40 +-1 +-33 +-61 +-83 +-32 +72 +76 +38 +-1 +-33 +-62 +-84 +-33 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-2 +-34 +-62 +-85 +-33 +70 +75 +37 +-3 +-35 +-63 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-35 +69 +74 +36 +-4 +-35 +-63 +-85 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-5 +-36 +-64 +-86 +-36 +69 +72 +34 +-5 +-36 +-64 +-86 +-36 +68 +72 +34 +-5 +-37 +-65 +-86 +-36 +68 +72 +34 +-5 +-37 +-65 +-86 +-36 +68 +72 +34 +-5 +-37 +-64 +-86 +-36 +68 +72 +34 +-5 +-37 +-64 +-86 +-36 +68 +72 +35 +-5 +-36 +-64 +-86 +-36 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-35 +69 +74 +35 +-4 +-36 +-63 +-86 +-35 +70 +74 +36 +-3 +-35 +-63 +-85 +-35 +69 +74 +36 +-4 +-35 +-63 +-86 +-35 +69 +74 +36 +-4 +-35 +-63 +-85 +-35 +70 +74 +36 +-1 +-33 +-62 +-84 +-104 +-104 +-44 +67 +82 +48 +11 +-23 +-53 +-77 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-47 +-72 +-93 +-110 +-31 +80 +95 +61 +22 +-13 +-44 +-69 +-91 +-109 +-29 +82 +96 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +84 +98 +64 +25 +-11 +-42 +-67 +-90 +-107 +-27 +85 +98 +64 +26 +-10 +-42 +-67 +-89 +-107 +-26 +85 +99 +65 +26 +-10 +-42 +-67 +-89 +-107 +-26 +86 +100 +65 +26 +-10 +-42 +-67 +-89 +-106 +-26 +85 +99 +65 +26 +-10 +-42 +-67 +-89 +-107 +-26 +86 +100 +65 +26 +-10 +-42 +-67 +-89 +-107 +-26 +85 +99 +65 +26 +-10 +-41 +-67 +-89 +-107 +-26 +86 +100 +65 +26 +-10 +-41 +-67 +-89 +-106 +-26 +86 +100 +65 +26 +-9 +-41 +-67 +-89 +-106 +-26 +85 +99 +65 +26 +-10 +-41 +-67 +-89 +-106 +-26 +86 +100 +65 +22 +-14 +-45 +-69 +-14 +90 +94 +54 +12 +-22 +-51 +-76 +-22 +82 +85 +46 +5 +-28 +-57 +-80 +-28 +77 +80 +41 +1 +-32 +-60 +-82 +-31 +73 +77 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-34 +69 +73 +36 +-2 +-34 +-62 +-84 +-104 +-104 +-44 +67 +81 +48 +11 +-23 +-53 +-76 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-47 +-72 +-94 +-110 +-31 +80 +95 +61 +22 +-14 +-45 +-69 +-92 +-109 +-29 +83 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +84 +99 +64 +21 +-14 +-45 +-70 +-14 +90 +93 +54 +12 +-22 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-59 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +71 +75 +37 +-2 +-35 +-62 +-85 +-34 +70 +74 +36 +-3 +-35 +-63 +-85 +-105 +-45 +62 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +71 +88 +51 +16 +-20 +-49 +-74 +-94 +-112 +-33 +77 +94 +58 +21 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +60 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +63 +25 +-12 +-42 +-68 +-89 +-17 +90 +97 +59 +15 +-19 +-49 +-73 +-20 +84 +87 +49 +7 +-26 +-55 +-79 +-27 +78 +82 +43 +3 +-30 +-59 +-82 +-29 +74 +78 +40 +0 +-33 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-44 +62 +76 +40 +6 +-28 +-56 +-81 +-100 +-101 +-38 +71 +88 +52 +16 +-20 +-49 +-74 +-95 +-112 +-33 +76 +94 +57 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +63 +25 +-12 +-42 +-68 +-89 +-17 +90 +97 +59 +16 +-19 +-49 +-73 +-19 +84 +88 +49 +8 +-26 +-55 +-78 +-26 +78 +83 +44 +3 +-30 +-58 +-81 +-29 +75 +80 +42 +1 +-31 +-60 +-83 +-32 +73 +77 +39 +-1 +-33 +-61 +-84 +-32 +71 +75 +37 +-2 +-34 +-62 +-85 +-34 +71 +75 +37 +-1 +-33 +-61 +-84 +-104 +-103 +-44 +68 +82 +48 +10 +-23 +-53 +-77 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-47 +-72 +-93 +-111 +-31 +80 +94 +60 +21 +-14 +-45 +-70 +-92 +-109 +-29 +82 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +84 +98 +64 +20 +-15 +-46 +-70 +-15 +89 +93 +54 +11 +-23 +-52 +-76 +-23 +80 +84 +45 +4 +-29 +-57 +-81 +-28 +76 +80 +41 +1 +-32 +-60 +-83 +-31 +73 +77 +39 +-1 +-33 +-62 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-34 +69 +74 +36 +-2 +-34 +-62 +-84 +-104 +-104 +-44 +67 +81 +47 +10 +-23 +-53 +-77 +-97 +-98 +-36 +75 +90 +56 +18 +-17 +-48 +-72 +-94 +-110 +-31 +79 +95 +61 +22 +-13 +-45 +-69 +-91 +-109 +-29 +83 +97 +63 +24 +-12 +-43 +-68 +-90 +-108 +-27 +83 +97 +63 +20 +-15 +-46 +-70 +-14 +90 +93 +54 +11 +-23 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +72 +76 +38 +-2 +-34 +-62 +-84 +-34 +70 +75 +37 +-3 +-35 +-63 +-85 +-105 +-45 +62 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +70 +87 +51 +16 +-20 +-49 +-74 +-95 +-112 +-32 +77 +94 +58 +21 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-18 +89 +97 +59 +16 +-19 +-49 +-73 +-20 +83 +87 +48 +7 +-26 +-55 +-79 +-26 +78 +82 +43 +3 +-30 +-59 +-81 +-30 +74 +78 +40 +0 +-32 +-60 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-33 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-44 +62 +76 +40 +5 +-29 +-57 +-81 +-100 +-102 +-39 +71 +88 +52 +16 +-20 +-49 +-74 +-94 +-112 +-32 +77 +94 +58 +21 +-15 +-45 +-71 +-91 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-108 +-27 +83 +100 +63 +26 +-12 +-42 +-68 +-89 +-108 +-26 +84 +101 +63 +27 +-11 +-41 +-68 +-89 +-108 +-25 +84 +101 +65 +28 +-10 +-40 +-67 +-88 +-107 +-25 +84 +101 +65 +28 +-10 +-40 +-67 +-88 +-107 +-24 +85 +102 +65 +28 +-10 +-40 +-67 +-88 +-107 +-24 +85 +102 +65 +27 +-10 +-40 +-67 +-88 +-16 +92 +98 +60 +16 +-18 +-48 +-73 +-19 +85 +89 +50 +8 +-25 +-55 +-78 +-25 +79 +82 +43 +3 +-30 +-59 +-81 +-30 +74 +78 +40 +0 +-33 +-61 +-83 +-32 +72 +76 +38 +-2 +-34 +-62 +-84 +-34 +70 +74 +36 +-4 +-35 +-63 +-85 +-35 +70 +74 +36 +-3 +-35 +-63 +-85 +-35 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +69 +73 +35 +-4 +-36 +-64 +-86 +-36 +69 +73 +34 +-5 +-36 +-64 +-86 +-36 +68 +72 +35 +-3 +-34 +-62 +-85 +-105 +-104 +-45 +66 +81 +47 +10 +-24 +-53 +-77 +-98 +-98 +-37 +75 +89 +55 +17 +-17 +-48 +-72 +-94 +-111 +-32 +79 +94 +60 +21 +-14 +-45 +-70 +-92 +-109 +-29 +82 +96 +62 +23 +-12 +-44 +-69 +-91 +-108 +-28 +83 +98 +63 +20 +-15 +-46 +-70 +-15 +89 +93 +54 +11 +-22 +-52 +-76 +-23 +81 +85 +46 +5 +-28 +-57 +-80 +-28 +76 +80 +42 +1 +-31 +-60 +-82 +-31 +73 +77 +39 +-1 +-33 +-61 +-84 +-33 +72 +76 +37 +-2 +-34 +-62 +-85 +-34 +71 +75 +37 +-3 +-35 +-63 +-85 +-105 +-45 +61 +76 +40 +5 +-29 +-57 +-81 +-100 +-101 +-39 +71 +88 +52 +16 +-20 +-49 +-74 +-94 +-112 +-32 +77 +94 +58 +21 +-16 +-45 +-71 +-92 +-110 +-29 +80 +97 +61 +24 +-13 +-43 +-69 +-90 +-109 +-27 +82 +99 +62 +25 +-12 +-42 +-68 +-89 +-17 +90 +97 +58 +15 +-19 +-49 +-74 +-20 +84 +88 +49 +7 +-26 +-55 +-79 +-26 +78 +82 +43 +3 +-30 +-59 +-81 +-30 +74 +78 +40 +0 +-33 +-61 +-83 +-32 +71 +76 +38 +-2 +-34 +-62 +-84 +-33 diff --git a/traces/README.txt b/traces/README.txt index 50b14aaee..424092dc5 100644 --- a/traces/README.txt +++ b/traces/README.txt @@ -15,3 +15,10 @@ Transit999-best.pm3: Transit 999 format (UID 99531670) The files 'modulation-'... are all encoded with identical data (hex 00 01 02 03 04 05 06 07 08 09 0A 0B) for the purpose of recognition and testing of demodulation schemes. They were created by writing Q5 tags appropriately configured. The raw data is in 'modulation-data.dat'. + +ata5577-HIDemu-FC1-C9.pm3: ata5577 in hid prox 26 bit emulation facility code:1 card#:9 +casi-12ed825c29.pm3: casi rusco 40 bit (EM410x ID: 12ed825c29) +EM4102-Fob.pm3: (ID: 0400193cbe) +ioprox-XSF-01-3B-44725.pm3: IO Prox FSK RF/64 ID in name +ioprox-XSF-01-BE-03011.pm3: IO Prox FSK RF/64 ID in name +indala-504278295.pm3: PSK 26 bit indala \ No newline at end of file From c07b79fcbf72f530cbff5bc1e49c12bff311f50f Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Tue, 6 Jan 2015 10:58:35 -0500 Subject: [PATCH 06/11] sync with master lf files to resolve conflicts --- armsrc/lfops.c | 2834 +++++++++++++++++++++++----------------------- common/lfdemod.c | 1616 ++++++++++---------------- common/lfdemod.h | 8 +- 3 files changed, 1998 insertions(+), 2460 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 79d59bf9c..ab196325f 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -25,40 +25,40 @@ */ void DoAcquisition125k_internal(int trigger_threshold,bool silent) { - uint8_t *dest = (uint8_t *)BigBuf; - int n = sizeof(BigBuf); - int i; + uint8_t *dest = (uint8_t *)BigBuf; + int n = sizeof(BigBuf); + int i; - memset(dest, 0, n); - i = 0; - for(;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - LED_D_ON(); - } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - LED_D_OFF(); - if (trigger_threshold != -1 && dest[i] < trigger_threshold) - continue; - else - trigger_threshold = -1; - if (++i >= n) break; - } - } - if(!silent) - { - Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...", - dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); - - } + memset(dest, 0, n); + i = 0; + for(;;) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0x43; + LED_D_ON(); + } + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + LED_D_OFF(); + if (trigger_threshold != -1 && dest[i] < trigger_threshold) + continue; + else + trigger_threshold = -1; + if (++i >= n) break; + } + } + if(!silent) + { + Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...", + dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); + + } } /** * Perform sample aquisition. */ void DoAcquisition125k(int trigger_threshold) { - DoAcquisition125k_internal(trigger_threshold, false); + DoAcquisition125k_internal(trigger_threshold, false); } /** @@ -70,31 +70,31 @@ void DoAcquisition125k(int trigger_threshold) **/ void LFSetupFPGAForADC(int divisor, bool lf_field) { - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - if ( (divisor == 1) || (divisor < 0) || (divisor > 255) ) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz - else if (divisor == 0) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - else - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + if ( (divisor == 1) || (divisor < 0) || (divisor > 255) ) + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz + else if (divisor == 0) + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + else + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | (lf_field ? FPGA_LF_ADC_READER_FIELD : 0)); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | (lf_field ? FPGA_LF_ADC_READER_FIELD : 0)); - // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - // Give it a bit of time for the resonant antenna to settle. - SpinDelay(50); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); + // Connect the A/D to the peak-detected low-frequency path. + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + // Give it a bit of time for the resonant antenna to settle. + SpinDelay(50); + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); } /** * Initializes the FPGA, and acquires the samples. **/ void AcquireRawAdcSamples125k(int divisor) { - LFSetupFPGAForADC(divisor, true); - // Now call the acquisition routine - DoAcquisition125k_internal(-1,false); + LFSetupFPGAForADC(divisor, true); + // Now call the acquisition routine + DoAcquisition125k_internal(-1,false); } /** * Initializes the FPGA for snoop-mode, and acquires the samples. @@ -102,60 +102,60 @@ void AcquireRawAdcSamples125k(int divisor) void SnoopLFRawAdcSamples(int divisor, int trigger_threshold) { - LFSetupFPGAForADC(divisor, false); - DoAcquisition125k(trigger_threshold); + LFSetupFPGAForADC(divisor, false); + DoAcquisition125k(trigger_threshold); } void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, uint8_t *command) { - /* Make sure the tag is reset */ - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelay(2500); + /* Make sure the tag is reset */ + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelay(2500); - int divisor_used = 95; // 125 KHz - // see if 'h' was specified + int divisor_used = 95; // 125 KHz + // see if 'h' was specified - if (command[strlen((char *) command) - 1] == 'h') - divisor_used = 88; // 134.8 KHz + if (command[strlen((char *) command) - 1] == 'h') + divisor_used = 88; // 134.8 KHz - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // Give it a bit of time for the resonant antenna to settle. - SpinDelay(50); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + // Give it a bit of time for the resonant antenna to settle. + SpinDelay(50); - // And a little more time for the tag to fully power up - SpinDelay(2000); + // And a little more time for the tag to fully power up + SpinDelay(2000); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); - // now modulate the reader field - while(*command != '\0' && *command != ' ') { - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LED_D_OFF(); - SpinDelayUs(delay_off); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); + // now modulate the reader field + while(*command != '\0' && *command != ' ') { + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LED_D_OFF(); + SpinDelayUs(delay_off); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - LED_D_ON(); - if(*(command++) == '0') - SpinDelayUs(period_0); - else - SpinDelayUs(period_1); - } - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LED_D_OFF(); - SpinDelayUs(delay_off); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + LED_D_ON(); + if(*(command++) == '0') + SpinDelayUs(period_0); + else + SpinDelayUs(period_1); + } + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LED_D_OFF(); + SpinDelayUs(delay_off); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // now do the read - DoAcquisition125k(-1); + // now do the read + DoAcquisition125k(-1); } /* blank r/w tag data stream @@ -169,230 +169,230 @@ void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, */ void ReadTItag(void) { - // some hardcoded initial params - // when we read a TI tag we sample the zerocross line at 2Mhz - // TI tags modulate a 1 as 16 cycles of 123.2Khz - // TI tags modulate a 0 as 16 cycles of 134.2Khz - #define FSAMPLE 2000000 - #define FREQLO 123200 - #define FREQHI 134200 + // some hardcoded initial params + // when we read a TI tag we sample the zerocross line at 2Mhz + // TI tags modulate a 1 as 16 cycles of 123.2Khz + // TI tags modulate a 0 as 16 cycles of 134.2Khz +#define FSAMPLE 2000000 +#define FREQLO 123200 +#define FREQHI 134200 - signed char *dest = (signed char *)BigBuf; - int n = sizeof(BigBuf); -// int *dest = GraphBuffer; -// int n = GraphTraceLen; + signed char *dest = (signed char *)BigBuf; + int n = sizeof(BigBuf); + // int *dest = GraphBuffer; + // int n = GraphTraceLen; - // 128 bit shift register [shift3:shift2:shift1:shift0] - uint32_t shift3 = 0, shift2 = 0, shift1 = 0, shift0 = 0; + // 128 bit shift register [shift3:shift2:shift1:shift0] + uint32_t shift3 = 0, shift2 = 0, shift1 = 0, shift0 = 0; - int i, cycles=0, samples=0; - // how many sample points fit in 16 cycles of each frequency - uint32_t sampleslo = (FSAMPLE<<4)/FREQLO, sampleshi = (FSAMPLE<<4)/FREQHI; - // when to tell if we're close enough to one freq or another - uint32_t threshold = (sampleslo - sampleshi + 1)>>1; + int i, cycles=0, samples=0; + // how many sample points fit in 16 cycles of each frequency + uint32_t sampleslo = (FSAMPLE<<4)/FREQLO, sampleshi = (FSAMPLE<<4)/FREQHI; + // when to tell if we're close enough to one freq or another + uint32_t threshold = (sampleslo - sampleshi + 1)>>1; - // TI tags charge at 134.2Khz - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz + // TI tags charge at 134.2Khz + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz - // Place FPGA in passthrough mode, in this mode the CROSS_LO line - // connects to SSP_DIN and the SSP_DOUT logic level controls - // whether we're modulating the antenna (high) - // or listening to the antenna (low) - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); + // Place FPGA in passthrough mode, in this mode the CROSS_LO line + // connects to SSP_DIN and the SSP_DOUT logic level controls + // whether we're modulating the antenna (high) + // or listening to the antenna (low) + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); - // get TI tag data into the buffer - AcquireTiType(); + // get TI tag data into the buffer + AcquireTiType(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - for (i=0; i0) ) { - cycles++; - // after 16 cycles, measure the frequency - if (cycles>15) { - cycles=0; - samples=i-samples; // number of samples in these 16 cycles + for (i=0; i0) ) { + cycles++; + // after 16 cycles, measure the frequency + if (cycles>15) { + cycles=0; + samples=i-samples; // number of samples in these 16 cycles - // TI bits are coming to us lsb first so shift them - // right through our 128 bit right shift register - shift0 = (shift0>>1) | (shift1 << 31); - shift1 = (shift1>>1) | (shift2 << 31); - shift2 = (shift2>>1) | (shift3 << 31); - shift3 >>= 1; + // TI bits are coming to us lsb first so shift them + // right through our 128 bit right shift register + shift0 = (shift0>>1) | (shift1 << 31); + shift1 = (shift1>>1) | (shift2 << 31); + shift2 = (shift2>>1) | (shift3 << 31); + shift3 >>= 1; - // check if the cycles fall close to the number - // expected for either the low or high frequency - if ( (samples>(sampleslo-threshold)) && (samples<(sampleslo+threshold)) ) { - // low frequency represents a 1 - shift3 |= (1<<31); - } else if ( (samples>(sampleshi-threshold)) && (samples<(sampleshi+threshold)) ) { - // high frequency represents a 0 - } else { - // probably detected a gay waveform or noise - // use this as gaydar or discard shift register and start again - shift3 = shift2 = shift1 = shift0 = 0; - } - samples = i; + // check if the cycles fall close to the number + // expected for either the low or high frequency + if ( (samples>(sampleslo-threshold)) && (samples<(sampleslo+threshold)) ) { + // low frequency represents a 1 + shift3 |= (1<<31); + } else if ( (samples>(sampleshi-threshold)) && (samples<(sampleshi+threshold)) ) { + // high frequency represents a 0 + } else { + // probably detected a gay waveform or noise + // use this as gaydar or discard shift register and start again + shift3 = shift2 = shift1 = shift0 = 0; + } + samples = i; - // for each bit we receive, test if we've detected a valid tag + // for each bit we receive, test if we've detected a valid tag - // if we see 17 zeroes followed by 6 ones, we might have a tag - // remember the bits are backwards - if ( ((shift0 & 0x7fffff) == 0x7e0000) ) { - // if start and end bytes match, we have a tag so break out of the loop - if ( ((shift0>>16)&0xff) == ((shift3>>8)&0xff) ) { - cycles = 0xF0B; //use this as a flag (ugly but whatever) - break; - } - } - } - } - } + // if we see 17 zeroes followed by 6 ones, we might have a tag + // remember the bits are backwards + if ( ((shift0 & 0x7fffff) == 0x7e0000) ) { + // if start and end bytes match, we have a tag so break out of the loop + if ( ((shift0>>16)&0xff) == ((shift3>>8)&0xff) ) { + cycles = 0xF0B; //use this as a flag (ugly but whatever) + break; + } + } + } + } + } - // if flag is set we have a tag - if (cycles!=0xF0B) { - DbpString("Info: No valid tag detected."); - } else { - // put 64 bit data into shift1 and shift0 - shift0 = (shift0>>24) | (shift1 << 8); - shift1 = (shift1>>24) | (shift2 << 8); + // if flag is set we have a tag + if (cycles!=0xF0B) { + DbpString("Info: No valid tag detected."); + } else { + // put 64 bit data into shift1 and shift0 + shift0 = (shift0>>24) | (shift1 << 8); + shift1 = (shift1>>24) | (shift2 << 8); - // align 16 bit crc into lower half of shift2 - shift2 = ((shift2>>24) | (shift3 << 8)) & 0x0ffff; + // align 16 bit crc into lower half of shift2 + shift2 = ((shift2>>24) | (shift3 << 8)) & 0x0ffff; - // if r/w tag, check ident match - if ( shift3&(1<<15) ) { - DbpString("Info: TI tag is rewriteable"); - // only 15 bits compare, last bit of ident is not valid - if ( ((shift3>>16)^shift0)&0x7fff ) { - DbpString("Error: Ident mismatch!"); - } else { - DbpString("Info: TI tag ident is valid"); - } - } else { - DbpString("Info: TI tag is readonly"); - } + // if r/w tag, check ident match + if ( shift3&(1<<15) ) { + DbpString("Info: TI tag is rewriteable"); + // only 15 bits compare, last bit of ident is not valid + if ( ((shift3>>16)^shift0)&0x7fff ) { + DbpString("Error: Ident mismatch!"); + } else { + DbpString("Info: TI tag ident is valid"); + } + } else { + DbpString("Info: TI tag is readonly"); + } - // WARNING the order of the bytes in which we calc crc below needs checking - // i'm 99% sure the crc algorithm is correct, but it may need to eat the - // bytes in reverse or something - // calculate CRC - uint32_t crc=0; + // WARNING the order of the bytes in which we calc crc below needs checking + // i'm 99% sure the crc algorithm is correct, but it may need to eat the + // bytes in reverse or something + // calculate CRC + uint32_t crc=0; - crc = update_crc16(crc, (shift0)&0xff); - crc = update_crc16(crc, (shift0>>8)&0xff); - crc = update_crc16(crc, (shift0>>16)&0xff); - crc = update_crc16(crc, (shift0>>24)&0xff); - crc = update_crc16(crc, (shift1)&0xff); - crc = update_crc16(crc, (shift1>>8)&0xff); - crc = update_crc16(crc, (shift1>>16)&0xff); - crc = update_crc16(crc, (shift1>>24)&0xff); + crc = update_crc16(crc, (shift0)&0xff); + crc = update_crc16(crc, (shift0>>8)&0xff); + crc = update_crc16(crc, (shift0>>16)&0xff); + crc = update_crc16(crc, (shift0>>24)&0xff); + crc = update_crc16(crc, (shift1)&0xff); + crc = update_crc16(crc, (shift1>>8)&0xff); + crc = update_crc16(crc, (shift1>>16)&0xff); + crc = update_crc16(crc, (shift1>>24)&0xff); - Dbprintf("Info: Tag data: %x%08x, crc=%x", - (unsigned int)shift1, (unsigned int)shift0, (unsigned int)shift2 & 0xFFFF); - if (crc != (shift2&0xffff)) { - Dbprintf("Error: CRC mismatch, expected %x", (unsigned int)crc); - } else { - DbpString("Info: CRC is good"); - } - } + Dbprintf("Info: Tag data: %x%08x, crc=%x", + (unsigned int)shift1, (unsigned int)shift0, (unsigned int)shift2 & 0xFFFF); + if (crc != (shift2&0xffff)) { + Dbprintf("Error: CRC mismatch, expected %x", (unsigned int)crc); + } else { + DbpString("Info: CRC is good"); + } + } } void WriteTIbyte(uint8_t b) { - int i = 0; + int i = 0; - // modulate 8 bits out to the antenna - for (i=0; i<8; i++) - { - if (b&(1<PIO_PDR = GPIO_SSC_DIN; - AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN; + // Set up the synchronous serial port + AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DIN; + AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN; - // steal this pin from the SSP and use it to control the modulation - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + // steal this pin from the SSP and use it to control the modulation + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST; - AT91C_BASE_SSC->SSC_CR = AT91C_SSC_RXEN | AT91C_SSC_TXEN; + AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST; + AT91C_BASE_SSC->SSC_CR = AT91C_SSC_RXEN | AT91C_SSC_TXEN; - // Sample at 2 Mbit/s, so TI tags are 16.2 vs. 14.9 clocks long - // 48/2 = 24 MHz clock must be divided by 12 - AT91C_BASE_SSC->SSC_CMR = 12; + // Sample at 2 Mbit/s, so TI tags are 16.2 vs. 14.9 clocks long + // 48/2 = 24 MHz clock must be divided by 12 + AT91C_BASE_SSC->SSC_CMR = 12; - AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(0); - AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(32) | AT91C_SSC_MSBF; - AT91C_BASE_SSC->SSC_TCMR = 0; - AT91C_BASE_SSC->SSC_TFMR = 0; + AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(0); + AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(32) | AT91C_SSC_MSBF; + AT91C_BASE_SSC->SSC_TCMR = 0; + AT91C_BASE_SSC->SSC_TFMR = 0; - LED_D_ON(); + LED_D_ON(); - // modulate antenna - HIGH(GPIO_SSC_DOUT); + // modulate antenna + HIGH(GPIO_SSC_DOUT); - // Charge TI tag for 50ms. - SpinDelay(50); + // Charge TI tag for 50ms. + SpinDelay(50); - // stop modulating antenna and listen - LOW(GPIO_SSC_DOUT); + // stop modulating antenna and listen + LOW(GPIO_SSC_DOUT); - LED_D_OFF(); + LED_D_OFF(); - i = 0; - for(;;) { - if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - BigBuf[i] = AT91C_BASE_SSC->SSC_RHR; // store 32 bit values in buffer - i++; if(i >= TIBUFLEN) break; - } - WDT_HIT(); - } + i = 0; + for(;;) { + if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + BigBuf[i] = AT91C_BASE_SSC->SSC_RHR; // store 32 bit values in buffer + i++; if(i >= TIBUFLEN) break; + } + WDT_HIT(); + } - // return stolen pin to SSP - AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN | GPIO_SSC_DOUT; + // return stolen pin to SSP + AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN | GPIO_SSC_DOUT; - char *dest = (char *)BigBuf; - n = TIBUFLEN*32; - // unpack buffer - for (i=TIBUFLEN-1; i>=0; i--) { - for (j=0; j<32; j++) { - if(BigBuf[i] & (1 << j)) { - dest[--n] = 1; - } else { - dest[--n] = -1; - } - } - } + char *dest = (char *)BigBuf; + n = TIBUFLEN*32; + // unpack buffer + for (i=TIBUFLEN-1; i>=0; i--) { + for (j=0; j<32; j++) { + if(BigBuf[i] & (1 << j)) { + dest[--n] = 1; + } else { + dest[--n] = -1; + } + } + } } // arguments: 64bit data split into 32bit idhi:idlo and optional 16bit crc @@ -400,127 +400,127 @@ void AcquireTiType(void) // if not provided a valid crc will be computed from the data and written. void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc) { - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - if(crc == 0) { - crc = update_crc16(crc, (idlo)&0xff); - crc = update_crc16(crc, (idlo>>8)&0xff); - crc = update_crc16(crc, (idlo>>16)&0xff); - crc = update_crc16(crc, (idlo>>24)&0xff); - crc = update_crc16(crc, (idhi)&0xff); - crc = update_crc16(crc, (idhi>>8)&0xff); - crc = update_crc16(crc, (idhi>>16)&0xff); - crc = update_crc16(crc, (idhi>>24)&0xff); - } - Dbprintf("Writing to tag: %x%08x, crc=%x", - (unsigned int) idhi, (unsigned int) idlo, crc); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + if(crc == 0) { + crc = update_crc16(crc, (idlo)&0xff); + crc = update_crc16(crc, (idlo>>8)&0xff); + crc = update_crc16(crc, (idlo>>16)&0xff); + crc = update_crc16(crc, (idlo>>24)&0xff); + crc = update_crc16(crc, (idhi)&0xff); + crc = update_crc16(crc, (idhi>>8)&0xff); + crc = update_crc16(crc, (idhi>>16)&0xff); + crc = update_crc16(crc, (idhi>>24)&0xff); + } + Dbprintf("Writing to tag: %x%08x, crc=%x", + (unsigned int) idhi, (unsigned int) idlo, crc); - // TI tags charge at 134.2Khz - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz - // Place FPGA in passthrough mode, in this mode the CROSS_LO line - // connects to SSP_DIN and the SSP_DOUT logic level controls - // whether we're modulating the antenna (high) - // or listening to the antenna (low) - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); - LED_A_ON(); + // TI tags charge at 134.2Khz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz + // Place FPGA in passthrough mode, in this mode the CROSS_LO line + // connects to SSP_DIN and the SSP_DOUT logic level controls + // whether we're modulating the antenna (high) + // or listening to the antenna (low) + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); + LED_A_ON(); - // steal this pin from the SSP and use it to control the modulation - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + // steal this pin from the SSP and use it to control the modulation + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - // writing algorithm: - // a high bit consists of a field off for 1ms and field on for 1ms - // a low bit consists of a field off for 0.3ms and field on for 1.7ms - // initiate a charge time of 50ms (field on) then immediately start writing bits - // start by writing 0xBB (keyword) and 0xEB (password) - // then write 80 bits of data (or 64 bit data + 16 bit crc if you prefer) - // finally end with 0x0300 (write frame) - // all data is sent lsb firts - // finish with 15ms programming time + // writing algorithm: + // a high bit consists of a field off for 1ms and field on for 1ms + // a low bit consists of a field off for 0.3ms and field on for 1.7ms + // initiate a charge time of 50ms (field on) then immediately start writing bits + // start by writing 0xBB (keyword) and 0xEB (password) + // then write 80 bits of data (or 64 bit data + 16 bit crc if you prefer) + // finally end with 0x0300 (write frame) + // all data is sent lsb firts + // finish with 15ms programming time - // modulate antenna - HIGH(GPIO_SSC_DOUT); - SpinDelay(50); // charge time + // modulate antenna + HIGH(GPIO_SSC_DOUT); + SpinDelay(50); // charge time - WriteTIbyte(0xbb); // keyword - WriteTIbyte(0xeb); // password - WriteTIbyte( (idlo )&0xff ); - WriteTIbyte( (idlo>>8 )&0xff ); - WriteTIbyte( (idlo>>16)&0xff ); - WriteTIbyte( (idlo>>24)&0xff ); - WriteTIbyte( (idhi )&0xff ); - WriteTIbyte( (idhi>>8 )&0xff ); - WriteTIbyte( (idhi>>16)&0xff ); - WriteTIbyte( (idhi>>24)&0xff ); // data hi to lo - WriteTIbyte( (crc )&0xff ); // crc lo - WriteTIbyte( (crc>>8 )&0xff ); // crc hi - WriteTIbyte(0x00); // write frame lo - WriteTIbyte(0x03); // write frame hi - HIGH(GPIO_SSC_DOUT); - SpinDelay(50); // programming time + WriteTIbyte(0xbb); // keyword + WriteTIbyte(0xeb); // password + WriteTIbyte( (idlo )&0xff ); + WriteTIbyte( (idlo>>8 )&0xff ); + WriteTIbyte( (idlo>>16)&0xff ); + WriteTIbyte( (idlo>>24)&0xff ); + WriteTIbyte( (idhi )&0xff ); + WriteTIbyte( (idhi>>8 )&0xff ); + WriteTIbyte( (idhi>>16)&0xff ); + WriteTIbyte( (idhi>>24)&0xff ); // data hi to lo + WriteTIbyte( (crc )&0xff ); // crc lo + WriteTIbyte( (crc>>8 )&0xff ); // crc hi + WriteTIbyte(0x00); // write frame lo + WriteTIbyte(0x03); // write frame hi + HIGH(GPIO_SSC_DOUT); + SpinDelay(50); // programming time - LED_A_OFF(); + LED_A_OFF(); - // get TI tag data into the buffer - AcquireTiType(); + // get TI tag data into the buffer + AcquireTiType(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - DbpString("Now use tiread to check"); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + DbpString("Now use tiread to check"); } void SimulateTagLowFrequency(int period, int gap, int ledcontrol) { - int i; - uint8_t *tab = (uint8_t *)BigBuf; + int i; + uint8_t *tab = (uint8_t *)BigBuf; - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK; + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK; - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK; + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK; #define SHORT_COIL() LOW(GPIO_SSC_DOUT) #define OPEN_COIL() HIGH(GPIO_SSC_DOUT) - i = 0; - for(;;) { - while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) { - if(BUTTON_PRESS()) { - DbpString("Stopped"); - return; - } - WDT_HIT(); - } + i = 0; + for(;;) { + while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) { + if(BUTTON_PRESS()) { + DbpString("Stopped"); + return; + } + WDT_HIT(); + } - if (ledcontrol) - LED_D_ON(); + if (ledcontrol) + LED_D_ON(); - if(tab[i]) - OPEN_COIL(); - else - SHORT_COIL(); + if(tab[i]) + OPEN_COIL(); + else + SHORT_COIL(); - if (ledcontrol) - LED_D_OFF(); + if (ledcontrol) + LED_D_OFF(); - while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) { - if(BUTTON_PRESS()) { - DbpString("Stopped"); - return; - } - WDT_HIT(); - } + while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) { + if(BUTTON_PRESS()) { + DbpString("Stopped"); + return; + } + WDT_HIT(); + } - i++; - if(i == period) { - i = 0; - if (gap) { - SHORT_COIL(); - SpinDelayUs(gap); - } - } - } + i++; + if(i == period) { + i = 0; + if (gap) { + SHORT_COIL(); + SpinDelayUs(gap); + } + } + } } #define DEBUG_FRAME_CONTENTS 1 @@ -530,318 +530,314 @@ void SimulateTagLowFrequencyBidir(int divisor, int t0) // compose fc/8 fc/10 waveform static void fc(int c, int *n) { - uint8_t *dest = (uint8_t *)BigBuf; - int idx; + uint8_t *dest = (uint8_t *)BigBuf; + int idx; - // for when we want an fc8 pattern every 4 logical bits - if(c==0) { - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - } - // an fc/8 encoded bit is a bit pattern of 11000000 x6 = 48 samples - if(c==8) { - for (idx=0; idx<6; idx++) { - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - } - } + // for when we want an fc8 pattern every 4 logical bits + if(c==0) { + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + } + // an fc/8 encoded bit is a bit pattern of 11000000 x6 = 48 samples + if(c==8) { + for (idx=0; idx<6; idx++) { + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + } + } - // an fc/10 encoded bit is a bit pattern of 1110000000 x5 = 50 samples - if(c==10) { - for (idx=0; idx<5; idx++) { - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - } - } + // an fc/10 encoded bit is a bit pattern of 1110000000 x5 = 50 samples + if(c==10) { + for (idx=0; idx<5; idx++) { + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + } + } } // prepare a waveform pattern in the buffer based on the ID given then // simulate a HID tag until the button is pressed void CmdHIDsimTAG(int hi, int lo, int ledcontrol) { - int n=0, i=0; - /* - HID tag bitstream format - The tag contains a 44bit unique code. This is sent out MSB first in sets of 4 bits - A 1 bit is represented as 6 fc8 and 5 fc10 patterns - A 0 bit is represented as 5 fc10 and 6 fc8 patterns - A fc8 is inserted before every 4 bits - A special start of frame pattern is used consisting a0b0 where a and b are neither 0 - nor 1 bits, they are special patterns (a = set of 12 fc8 and b = set of 10 fc10) - */ + int n=0, i=0; + /* + HID tag bitstream format + The tag contains a 44bit unique code. This is sent out MSB first in sets of 4 bits + A 1 bit is represented as 6 fc8 and 5 fc10 patterns + A 0 bit is represented as 5 fc10 and 6 fc8 patterns + A fc8 is inserted before every 4 bits + A special start of frame pattern is used consisting a0b0 where a and b are neither 0 + nor 1 bits, they are special patterns (a = set of 12 fc8 and b = set of 10 fc10) + */ - if (hi>0xFFF) { - DbpString("Tags can only have 44 bits."); - return; - } - fc(0,&n); - // special start of frame marker containing invalid bit sequences - fc(8, &n); fc(8, &n); // invalid - fc(8, &n); fc(10, &n); // logical 0 - fc(10, &n); fc(10, &n); // invalid - fc(8, &n); fc(10, &n); // logical 0 + if (hi>0xFFF) { + DbpString("Tags can only have 44 bits."); + return; + } + fc(0,&n); + // special start of frame marker containing invalid bit sequences + fc(8, &n); fc(8, &n); // invalid + fc(8, &n); fc(10, &n); // logical 0 + fc(10, &n); fc(10, &n); // invalid + fc(8, &n); fc(10, &n); // logical 0 - WDT_HIT(); - // manchester encode bits 43 to 32 - for (i=11; i>=0; i--) { - if ((i%4)==3) fc(0,&n); - if ((hi>>i)&1) { - fc(10, &n); fc(8, &n); // low-high transition - } else { - fc(8, &n); fc(10, &n); // high-low transition - } - } + WDT_HIT(); + // manchester encode bits 43 to 32 + for (i=11; i>=0; i--) { + if ((i%4)==3) fc(0,&n); + if ((hi>>i)&1) { + fc(10, &n); fc(8, &n); // low-high transition + } else { + fc(8, &n); fc(10, &n); // high-low transition + } + } - WDT_HIT(); - // manchester encode bits 31 to 0 - for (i=31; i>=0; i--) { - if ((i%4)==3) fc(0,&n); - if ((lo>>i)&1) { - fc(10, &n); fc(8, &n); // low-high transition - } else { - fc(8, &n); fc(10, &n); // high-low transition - } - } + WDT_HIT(); + // manchester encode bits 31 to 0 + for (i=31; i>=0; i--) { + if ((i%4)==3) fc(0,&n); + if ((lo>>i)&1) { + fc(10, &n); fc(8, &n); // low-high transition + } else { + fc(8, &n); fc(10, &n); // high-low transition + } + } - if (ledcontrol) - LED_A_ON(); - SimulateTagLowFrequency(n, 0, ledcontrol); + if (ledcontrol) + LED_A_ON(); + SimulateTagLowFrequency(n, 0, ledcontrol); - if (ledcontrol) - LED_A_OFF(); + if (ledcontrol) + LED_A_OFF(); } // loop to get raw HID waveform then FSK demodulate the TAG ID from it void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) { - uint8_t *dest = (uint8_t *)BigBuf; + uint8_t *dest = (uint8_t *)BigBuf; - size_t size=0; //, found=0; - uint32_t hi2=0, hi=0, lo=0; + size_t size=0; //, found=0; + uint32_t hi2=0, hi=0, lo=0; - // Configure to go in 125Khz listen mode - LFSetupFPGAForADC(95, true); + // Configure to go in 125Khz listen mode + LFSetupFPGAForADC(95, true); - while(!BUTTON_PRESS()) { + while(!BUTTON_PRESS()) { - WDT_HIT(); - if (ledcontrol) LED_A_ON(); + WDT_HIT(); + if (ledcontrol) LED_A_ON(); - DoAcquisition125k_internal(-1,true); - size = sizeof(BigBuf); - if (size < 2000) continue; - // FSK demodulator + DoAcquisition125k_internal(-1,true); + size = sizeof(BigBuf); + if (size < 2000) continue; + // FSK demodulator - int bitLen = HIDdemodFSK(dest,size,&hi2,&hi,&lo); - - WDT_HIT(); + int bitLen = HIDdemodFSK(dest,size,&hi2,&hi,&lo); - if (bitLen>0 && lo>0){ - // final loop, go over previously decoded manchester data and decode into usable tag ID - // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0 - if (hi2 != 0){ //extra large HID tags - Dbprintf("TAG ID: %x%08x%08x (%d)", - (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); - }else { //standard HID tags <38 bits - //Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd - uint8_t bitlen = 0; - uint32_t fc = 0; - uint32_t cardnum = 0; - if (((hi>>5)&1)==1){//if bit 38 is set then < 37 bit format is used - uint32_t lo2=0; - lo2=(((hi & 31) << 12) | (lo>>20)); //get bits 21-37 to check for format len bit - uint8_t idx3 = 1; - while(lo2>1){ //find last bit set to 1 (format len bit) - lo2=lo2>>1; - idx3++; - } - bitlen =idx3+19; - fc =0; - cardnum=0; - if(bitlen==26){ - cardnum = (lo>>1)&0xFFFF; - fc = (lo>>17)&0xFF; - } - if(bitlen==37){ - cardnum = (lo>>1)&0x7FFFF; - fc = ((hi&0xF)<<12)|(lo>>20); - } - if(bitlen==34){ - cardnum = (lo>>1)&0xFFFF; - fc= ((hi&1)<<15)|(lo>>17); - } - if(bitlen==35){ - cardnum = (lo>>1)&0xFFFFF; - fc = ((hi&1)<<11)|(lo>>21); - } - } - else { //if bit 38 is not set then 37 bit format is used - bitlen= 37; - fc =0; - cardnum=0; - if(bitlen==37){ - cardnum = (lo>>1)&0x7FFFF; - fc = ((hi&0xF)<<12)|(lo>>20); - } - } - //Dbprintf("TAG ID: %x%08x (%d)", - // (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); - Dbprintf("TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d", - (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF, - (unsigned int) bitlen, (unsigned int) fc, (unsigned int) cardnum); - } - if (findone){ - if (ledcontrol) LED_A_OFF(); - return; - } - // reset - hi2 = hi = lo = 0; - } - WDT_HIT(); - //SpinDelay(50); - } - DbpString("Stopped"); - if (ledcontrol) LED_A_OFF(); + WDT_HIT(); + + if (bitLen>0 && lo>0){ + // final loop, go over previously decoded manchester data and decode into usable tag ID + // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0 + if (hi2 != 0){ //extra large HID tags + Dbprintf("TAG ID: %x%08x%08x (%d)", + (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); + }else { //standard HID tags <38 bits + //Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd + uint8_t bitlen = 0; + uint32_t fc = 0; + uint32_t cardnum = 0; + if (((hi>>5)&1)==1){//if bit 38 is set then < 37 bit format is used + uint32_t lo2=0; + lo2=(((hi & 31) << 12) | (lo>>20)); //get bits 21-37 to check for format len bit + uint8_t idx3 = 1; + while(lo2>1){ //find last bit set to 1 (format len bit) + lo2=lo2>>1; + idx3++; + } + bitlen =idx3+19; + fc =0; + cardnum=0; + if(bitlen==26){ + cardnum = (lo>>1)&0xFFFF; + fc = (lo>>17)&0xFF; + } + if(bitlen==37){ + cardnum = (lo>>1)&0x7FFFF; + fc = ((hi&0xF)<<12)|(lo>>20); + } + if(bitlen==34){ + cardnum = (lo>>1)&0xFFFF; + fc= ((hi&1)<<15)|(lo>>17); + } + if(bitlen==35){ + cardnum = (lo>>1)&0xFFFFF; + fc = ((hi&1)<<11)|(lo>>21); + } + } + else { //if bit 38 is not set then 37 bit format is used + bitlen= 37; + fc =0; + cardnum=0; + if(bitlen==37){ + cardnum = (lo>>1)&0x7FFFF; + fc = ((hi&0xF)<<12)|(lo>>20); + } + } + //Dbprintf("TAG ID: %x%08x (%d)", + // (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); + Dbprintf("TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d", + (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF, + (unsigned int) bitlen, (unsigned int) fc, (unsigned int) cardnum); + } + if (findone){ + if (ledcontrol) LED_A_OFF(); + return; + } + // reset + hi2 = hi = lo = 0; + } + WDT_HIT(); + //SpinDelay(50); + } + DbpString("Stopped"); + if (ledcontrol) LED_A_OFF(); } void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol) { - uint8_t *dest = (uint8_t *)BigBuf; + uint8_t *dest = (uint8_t *)BigBuf; - size_t size=0; //, found=0; - int bitLen=0; - int clk=0, invert=0, errCnt=0; - uint64_t lo=0; - // Configure to go in 125Khz listen mode - LFSetupFPGAForADC(95, true); + size_t size=0; //, found=0; + uint32_t bitLen=0; + int clk=0, invert=0, errCnt=0; + uint64_t lo=0; + // Configure to go in 125Khz listen mode + LFSetupFPGAForADC(95, true); - while(!BUTTON_PRESS()) { + while(!BUTTON_PRESS()) { - WDT_HIT(); - if (ledcontrol) LED_A_ON(); + WDT_HIT(); + if (ledcontrol) LED_A_ON(); - DoAcquisition125k_internal(-1,true); - size = sizeof(BigBuf); - if (size < 2000) continue; - // FSK demodulator - //int askmandemod(uint8_t *BinStream,uint32_t *BitLen,int *clk, int *invert); - bitLen=size; - //Dbprintf("DEBUG: Buffer got"); - errCnt = askmandemod(dest,&bitLen,&clk,&invert); //HIDdemodFSK(dest,size,&hi2,&hi,&lo); - //Dbprintf("DEBUG: ASK Got"); - WDT_HIT(); + DoAcquisition125k_internal(-1,true); + size = sizeof(BigBuf); + if (size < 2000) continue; + // FSK demodulator + //int askmandemod(uint8_t *BinStream,uint32_t *BitLen,int *clk, int *invert); + bitLen=size; + //Dbprintf("DEBUG: Buffer got"); + errCnt = askmandemod(dest,&bitLen,&clk,&invert); //HIDdemodFSK(dest,size,&hi2,&hi,&lo); + //Dbprintf("DEBUG: ASK Got"); + WDT_HIT(); - if (errCnt>=0){ - lo = Em410xDecode(dest,bitLen); - //Dbprintf("DEBUG: EM GOT"); - //printEM410x(lo); - if (lo>0){ - Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)",(uint32_t)(lo>>32),(uint32_t)lo,(uint32_t)(lo&0xFFFF),(uint32_t)((lo>>16LL) & 0xFF),(uint32_t)(lo & 0xFFFFFF)); - } - if (findone){ - if (ledcontrol) LED_A_OFF(); - return; - } - } else{ - //Dbprintf("DEBUG: No Tag"); - } - WDT_HIT(); - lo = 0; - clk=0; - invert=0; - errCnt=0; - size=0; - //SpinDelay(50); - } - DbpString("Stopped"); - if (ledcontrol) LED_A_OFF(); + if (errCnt>=0){ + lo = Em410xDecode(dest,bitLen); + //Dbprintf("DEBUG: EM GOT"); + //printEM410x(lo); + if (lo>0){ + Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)",(uint32_t)(lo>>32),(uint32_t)lo,(uint32_t)(lo&0xFFFF),(uint32_t)((lo>>16LL) & 0xFF),(uint32_t)(lo & 0xFFFFFF)); + } + if (findone){ + if (ledcontrol) LED_A_OFF(); + return; + } + } else{ + //Dbprintf("DEBUG: No Tag"); + } + WDT_HIT(); + lo = 0; + clk=0; + invert=0; + errCnt=0; + size=0; + //SpinDelay(50); + } + DbpString("Stopped"); + if (ledcontrol) LED_A_OFF(); } void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) { - uint8_t *dest = (uint8_t *)BigBuf; - size_t size=0; - int idx=0; - uint32_t code=0, code2=0; - uint8_t version=0; - uint8_t facilitycode=0; - uint16_t number=0; - // Configure to go in 125Khz listen mode - LFSetupFPGAForADC(95, true); - - while(!BUTTON_PRESS()) { - WDT_HIT(); - if (ledcontrol) LED_A_ON(); - DoAcquisition125k_internal(-1,true); - size = sizeof(BigBuf); - //make sure buffer has data - if (size < 2000) continue; - //fskdemod and get start index - WDT_HIT(); - idx = IOdemodFSK(dest,size); - if (idx>0){ - //valid tag found + uint8_t *dest = (uint8_t *)BigBuf; + int idx=0; + uint32_t code=0, code2=0; + uint8_t version=0; + uint8_t facilitycode=0; + uint16_t number=0; + // Configure to go in 125Khz listen mode + LFSetupFPGAForADC(95, true); - //Index map - //0 10 20 30 40 50 60 - //| | | | | | | - //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23 - //----------------------------------------------------------------------------- - //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11 - // - //XSF(version)facility:codeone+codetwo - //Handle the data - if(findone){ //only print binary if we are doing one - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx], dest[idx+1], dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7],dest[idx+8]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15],dest[idx+16],dest[idx+17]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23],dest[idx+24],dest[idx+25],dest[idx+26]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31],dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39],dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+45],dest[idx+46],dest[idx+47],dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53]); - Dbprintf("%d%d%d%d%d%d%d%d %d%d",dest[idx+54],dest[idx+55],dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]); - } - code = bytebits_to_byte(dest+idx,32); - code2 = bytebits_to_byte(dest+idx+32,32); - version = bytebits_to_byte(dest+idx+27,8); //14,4 - facilitycode = bytebits_to_byte(dest+idx+18,8) ; - number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9 - - Dbprintf("XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2); - // if we're only looking for one tag - if (findone){ - if (ledcontrol) LED_A_OFF(); - //LED_A_OFF(); - return; - } - code=code2=0; - version=facilitycode=0; - number=0; - idx=0; - } - WDT_HIT(); - } - DbpString("Stopped"); - if (ledcontrol) LED_A_OFF(); + while(!BUTTON_PRESS()) { + WDT_HIT(); + if (ledcontrol) LED_A_ON(); + DoAcquisition125k_internal(-1,true); + //fskdemod and get start index + WDT_HIT(); + idx = IOdemodFSK(dest,sizeof(BigBuf)); + if (idx>0){ + //valid tag found + + //Index map + //0 10 20 30 40 50 60 + //| | | | | | | + //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23 + //----------------------------------------------------------------------------- + //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11 + // + //XSF(version)facility:codeone+codetwo + //Handle the data + if(findone){ //only print binary if we are doing one + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx], dest[idx+1], dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7],dest[idx+8]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15],dest[idx+16],dest[idx+17]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23],dest[idx+24],dest[idx+25],dest[idx+26]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31],dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39],dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+45],dest[idx+46],dest[idx+47],dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53]); + Dbprintf("%d%d%d%d%d%d%d%d %d%d",dest[idx+54],dest[idx+55],dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]); + } + code = bytebits_to_byte(dest+idx,32); + code2 = bytebits_to_byte(dest+idx+32,32); + version = bytebits_to_byte(dest+idx+27,8); //14,4 + facilitycode = bytebits_to_byte(dest+idx+18,8) ; + number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9 + + Dbprintf("XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2); + // if we're only looking for one tag + if (findone){ + if (ledcontrol) LED_A_OFF(); + //LED_A_OFF(); + return; + } + code=code2=0; + version=facilitycode=0; + number=0; + idx=0; + } + WDT_HIT(); + } + DbpString("Stopped"); + if (ledcontrol) LED_A_OFF(); } /*------------------------------ @@ -911,307 +907,307 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) // Write one bit to card void T55xxWriteBit(int bit) { - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - if (bit == 0) - SpinDelayUs(WRITE_0); - else - SpinDelayUs(WRITE_1); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelayUs(WRITE_GAP); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + if (bit == 0) + SpinDelayUs(WRITE_0); + else + SpinDelayUs(WRITE_1); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelayUs(WRITE_GAP); } // Write one card block in page 0, no lock void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode) { - //unsigned int i; //enio adjustment 12/10/14 - uint32_t i; + //unsigned int i; //enio adjustment 12/10/14 + uint32_t i; - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // Give it a bit of time for the resonant antenna to settle. - // And for the tag to fully power up - SpinDelay(150); + // Give it a bit of time for the resonant antenna to settle. + // And for the tag to fully power up + SpinDelay(150); - // Now start writting - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelayUs(START_GAP); + // Now start writting + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelayUs(START_GAP); - // Opcode - T55xxWriteBit(1); - T55xxWriteBit(0); //Page 0 - if (PwdMode == 1){ - // Pwd + // Opcode + T55xxWriteBit(1); + T55xxWriteBit(0); //Page 0 + if (PwdMode == 1){ + // Pwd + for (i = 0x80000000; i != 0; i >>= 1) + T55xxWriteBit(Pwd & i); + } + // Lock bit + T55xxWriteBit(0); + + // Data for (i = 0x80000000; i != 0; i >>= 1) - T55xxWriteBit(Pwd & i); - } - // Lock bit - T55xxWriteBit(0); + T55xxWriteBit(Data & i); - // Data - for (i = 0x80000000; i != 0; i >>= 1) - T55xxWriteBit(Data & i); + // Block + for (i = 0x04; i != 0; i >>= 1) + T55xxWriteBit(Block & i); - // Block - for (i = 0x04; i != 0; i >>= 1) - T55xxWriteBit(Block & i); - - // Now perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550, - // so wait a little more) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - SpinDelay(20); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + // Now perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550, + // so wait a little more) + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + SpinDelay(20); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); } // Read one card block in page 0 void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode) { - uint8_t *dest = (uint8_t *)BigBuf; - //int m=0, i=0; //enio adjustment 12/10/14 - uint32_t m=0, i=0; - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - m = sizeof(BigBuf); - // Clear destination buffer before sending the command - memset(dest, 128, m); - // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); - - LED_D_ON(); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - - // Give it a bit of time for the resonant antenna to settle. - // And for the tag to fully power up - SpinDelay(150); - - // Now start writting - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelayUs(START_GAP); - - // Opcode - T55xxWriteBit(1); - T55xxWriteBit(0); //Page 0 - if (PwdMode == 1){ - // Pwd - for (i = 0x80000000; i != 0; i >>= 1) - T55xxWriteBit(Pwd & i); - } - // Lock bit - T55xxWriteBit(0); - // Block - for (i = 0x04; i != 0; i >>= 1) - T55xxWriteBit(Block & i); - - // Turn field on to read the response - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - - // Now do the acquisition - i = 0; - for(;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - // we don't care about actual value, only if it's more or less than a - // threshold essentially we capture zero crossings for later analysis - // if(dest[i] < 127) dest[i] = 0; else dest[i] = 1; - i++; - if (i >= m) break; - } - } - - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); - DbpString("DONE!"); + uint8_t *dest = (uint8_t *)BigBuf; + //int m=0, i=0; //enio adjustment 12/10/14 + uint32_t m=0, i=0; + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + m = sizeof(BigBuf); + // Clear destination buffer before sending the command + memset(dest, 128, m); + // Connect the A/D to the peak-detected low-frequency path. + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); + + LED_D_ON(); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + + // Give it a bit of time for the resonant antenna to settle. + // And for the tag to fully power up + SpinDelay(150); + + // Now start writting + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelayUs(START_GAP); + + // Opcode + T55xxWriteBit(1); + T55xxWriteBit(0); //Page 0 + if (PwdMode == 1){ + // Pwd + for (i = 0x80000000; i != 0; i >>= 1) + T55xxWriteBit(Pwd & i); + } + // Lock bit + T55xxWriteBit(0); + // Block + for (i = 0x04; i != 0; i >>= 1) + T55xxWriteBit(Block & i); + + // Turn field on to read the response + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + + // Now do the acquisition + i = 0; + for(;;) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0x43; + } + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + // we don't care about actual value, only if it's more or less than a + // threshold essentially we capture zero crossings for later analysis + // if(dest[i] < 127) dest[i] = 0; else dest[i] = 1; + i++; + if (i >= m) break; + } + } + + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + LED_D_OFF(); + DbpString("DONE!"); } // Read card traceability data (page 1) void T55xxReadTrace(void){ - uint8_t *dest = (uint8_t *)BigBuf; - int m=0, i=0; - - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - m = sizeof(BigBuf); - // Clear destination buffer before sending the command - memset(dest, 128, m); - // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); - - LED_D_ON(); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - - // Give it a bit of time for the resonant antenna to settle. - // And for the tag to fully power up - SpinDelay(150); - - // Now start writting - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelayUs(START_GAP); - - // Opcode - T55xxWriteBit(1); - T55xxWriteBit(1); //Page 1 - - // Turn field on to read the response - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - - // Now do the acquisition - i = 0; - for(;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - i++; - if (i >= m) break; - } - } - - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); - DbpString("DONE!"); + uint8_t *dest = (uint8_t *)BigBuf; + int m=0, i=0; + + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + m = sizeof(BigBuf); + // Clear destination buffer before sending the command + memset(dest, 128, m); + // Connect the A/D to the peak-detected low-frequency path. + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); + + LED_D_ON(); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + + // Give it a bit of time for the resonant antenna to settle. + // And for the tag to fully power up + SpinDelay(150); + + // Now start writting + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelayUs(START_GAP); + + // Opcode + T55xxWriteBit(1); + T55xxWriteBit(1); //Page 1 + + // Turn field on to read the response + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + + // Now do the acquisition + i = 0; + for(;;) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0x43; + } + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + i++; + if (i >= m) break; + } + } + + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + LED_D_OFF(); + DbpString("DONE!"); } /*-------------- Cloning routines -----------*/ // Copy HID id to card and setup block 0 config void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT) { - int data1=0, data2=0, data3=0, data4=0, data5=0, data6=0; //up to six blocks for long format - int last_block = 0; - - if (longFMT){ - // Ensure no more than 84 bits supplied - if (hi2>0xFFFFF) { - DbpString("Tags can only have 84 bits."); - return; - } - // Build the 6 data blocks for supplied 84bit ID - last_block = 6; - data1 = 0x1D96A900; // load preamble (1D) & long format identifier (9E manchester encoded) - for (int i=0;i<4;i++) { - if (hi2 & (1<<(19-i))) - data1 |= (1<<(((3-i)*2)+1)); // 1 -> 10 - else - data1 |= (1<<((3-i)*2)); // 0 -> 01 - } - - data2 = 0; - for (int i=0;i<16;i++) { - if (hi2 & (1<<(15-i))) - data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data2 |= (1<<((15-i)*2)); // 0 -> 01 + int data1=0, data2=0, data3=0, data4=0, data5=0, data6=0; //up to six blocks for long format + int last_block = 0; + + if (longFMT){ + // Ensure no more than 84 bits supplied + if (hi2>0xFFFFF) { + DbpString("Tags can only have 84 bits."); + return; + } + // Build the 6 data blocks for supplied 84bit ID + last_block = 6; + data1 = 0x1D96A900; // load preamble (1D) & long format identifier (9E manchester encoded) + for (int i=0;i<4;i++) { + if (hi2 & (1<<(19-i))) + data1 |= (1<<(((3-i)*2)+1)); // 1 -> 10 + else + data1 |= (1<<((3-i)*2)); // 0 -> 01 + } + + data2 = 0; + for (int i=0;i<16;i++) { + if (hi2 & (1<<(15-i))) + data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data2 |= (1<<((15-i)*2)); // 0 -> 01 + } + + data3 = 0; + for (int i=0;i<16;i++) { + if (hi & (1<<(31-i))) + data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data3 |= (1<<((15-i)*2)); // 0 -> 01 + } + + data4 = 0; + for (int i=0;i<16;i++) { + if (hi & (1<<(15-i))) + data4 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data4 |= (1<<((15-i)*2)); // 0 -> 01 + } + + data5 = 0; + for (int i=0;i<16;i++) { + if (lo & (1<<(31-i))) + data5 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data5 |= (1<<((15-i)*2)); // 0 -> 01 + } + + data6 = 0; + for (int i=0;i<16;i++) { + if (lo & (1<<(15-i))) + data6 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data6 |= (1<<((15-i)*2)); // 0 -> 01 + } } - - data3 = 0; - for (int i=0;i<16;i++) { - if (hi & (1<<(31-i))) - data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data3 |= (1<<((15-i)*2)); // 0 -> 01 - } - - data4 = 0; - for (int i=0;i<16;i++) { - if (hi & (1<<(15-i))) - data4 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data4 |= (1<<((15-i)*2)); // 0 -> 01 + else { + // Ensure no more than 44 bits supplied + if (hi>0xFFF) { + DbpString("Tags can only have 44 bits."); + return; + } + + // Build the 3 data blocks for supplied 44bit ID + last_block = 3; + + data1 = 0x1D000000; // load preamble + + for (int i=0;i<12;i++) { + if (hi & (1<<(11-i))) + data1 |= (1<<(((11-i)*2)+1)); // 1 -> 10 + else + data1 |= (1<<((11-i)*2)); // 0 -> 01 + } + + data2 = 0; + for (int i=0;i<16;i++) { + if (lo & (1<<(31-i))) + data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data2 |= (1<<((15-i)*2)); // 0 -> 01 + } + + data3 = 0; + for (int i=0;i<16;i++) { + if (lo & (1<<(15-i))) + data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data3 |= (1<<((15-i)*2)); // 0 -> 01 + } } - - data5 = 0; - for (int i=0;i<16;i++) { - if (lo & (1<<(31-i))) - data5 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data5 |= (1<<((15-i)*2)); // 0 -> 01 - } - - data6 = 0; - for (int i=0;i<16;i++) { - if (lo & (1<<(15-i))) - data6 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data6 |= (1<<((15-i)*2)); // 0 -> 01 + + LED_D_ON(); + // Program the data blocks for supplied ID + // and the block 0 for HID format + T55xxWriteBlock(data1,1,0,0); + T55xxWriteBlock(data2,2,0,0); + T55xxWriteBlock(data3,3,0,0); + + if (longFMT) { // if long format there are 6 blocks + T55xxWriteBlock(data4,4,0,0); + T55xxWriteBlock(data5,5,0,0); + T55xxWriteBlock(data6,6,0,0); } - } - else { - // Ensure no more than 44 bits supplied - if (hi>0xFFF) { - DbpString("Tags can only have 44 bits."); - return; - } - - // Build the 3 data blocks for supplied 44bit ID - last_block = 3; - - data1 = 0x1D000000; // load preamble - - for (int i=0;i<12;i++) { - if (hi & (1<<(11-i))) - data1 |= (1<<(((11-i)*2)+1)); // 1 -> 10 - else - data1 |= (1<<((11-i)*2)); // 0 -> 01 - } - - data2 = 0; - for (int i=0;i<16;i++) { - if (lo & (1<<(31-i))) - data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data2 |= (1<<((15-i)*2)); // 0 -> 01 - } - - data3 = 0; - for (int i=0;i<16;i++) { - if (lo & (1<<(15-i))) - data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data3 |= (1<<((15-i)*2)); // 0 -> 01 - } - } - - LED_D_ON(); - // Program the data blocks for supplied ID - // and the block 0 for HID format - T55xxWriteBlock(data1,1,0,0); - T55xxWriteBlock(data2,2,0,0); - T55xxWriteBlock(data3,3,0,0); - - if (longFMT) { // if long format there are 6 blocks - T55xxWriteBlock(data4,4,0,0); - T55xxWriteBlock(data5,5,0,0); - T55xxWriteBlock(data6,6,0,0); - } - - // Config for HID (RF/50, FSK2a, Maxblock=3 for short/6 for long) - T55xxWriteBlock(T55x7_BITRATE_RF_50 | - T55x7_MODULATION_FSK2a | - last_block << T55x7_MAXBLOCK_SHIFT, - 0,0,0); - - LED_D_OFF(); - - DbpString("DONE!"); + + // Config for HID (RF/50, FSK2a, Maxblock=3 for short/6 for long) + T55xxWriteBlock(T55x7_BITRATE_RF_50 | + T55x7_MODULATION_FSK2a | + last_block << T55x7_MAXBLOCK_SHIFT, + 0,0,0); + + LED_D_OFF(); + + DbpString("DONE!"); } void CopyIOtoT55x7(uint32_t hi, uint32_t lo, uint8_t longFMT) { - int data1=0, data2=0; //up to six blocks for long format - + int data1=0, data2=0; //up to six blocks for long format + data1 = hi; // load preamble data2 = lo; @@ -1220,11 +1216,11 @@ void CopyIOtoT55x7(uint32_t hi, uint32_t lo, uint8_t longFMT) // and the block 0 for HID format T55xxWriteBlock(data1,1,0,0); T55xxWriteBlock(data2,2,0,0); - + //Config Block T55xxWriteBlock(0x00147040,0,0,0); LED_D_OFF(); - + DbpString("DONE!"); } @@ -1234,151 +1230,151 @@ void CopyIOtoT55x7(uint32_t hi, uint32_t lo, uint8_t longFMT) void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo) { - int i, id_bit; - uint64_t id = EM410X_HEADER; - uint64_t rev_id = 0; // reversed ID - int c_parity[4]; // column parity - int r_parity = 0; // row parity - uint32_t clock = 0; + int i, id_bit; + uint64_t id = EM410X_HEADER; + uint64_t rev_id = 0; // reversed ID + int c_parity[4]; // column parity + int r_parity = 0; // row parity + uint32_t clock = 0; - // Reverse ID bits given as parameter (for simpler operations) - for (i = 0; i < EM410X_ID_LENGTH; ++i) { - if (i < 32) { - rev_id = (rev_id << 1) | (id_lo & 1); - id_lo >>= 1; - } else { - rev_id = (rev_id << 1) | (id_hi & 1); - id_hi >>= 1; - } - } + // Reverse ID bits given as parameter (for simpler operations) + for (i = 0; i < EM410X_ID_LENGTH; ++i) { + if (i < 32) { + rev_id = (rev_id << 1) | (id_lo & 1); + id_lo >>= 1; + } else { + rev_id = (rev_id << 1) | (id_hi & 1); + id_hi >>= 1; + } + } - for (i = 0; i < EM410X_ID_LENGTH; ++i) { - id_bit = rev_id & 1; + for (i = 0; i < EM410X_ID_LENGTH; ++i) { + id_bit = rev_id & 1; - if (i % 4 == 0) { - // Don't write row parity bit at start of parsing - if (i) - id = (id << 1) | r_parity; - // Start counting parity for new row - r_parity = id_bit; - } else { - // Count row parity - r_parity ^= id_bit; - } + if (i % 4 == 0) { + // Don't write row parity bit at start of parsing + if (i) + id = (id << 1) | r_parity; + // Start counting parity for new row + r_parity = id_bit; + } else { + // Count row parity + r_parity ^= id_bit; + } - // First elements in column? - if (i < 4) - // Fill out first elements - c_parity[i] = id_bit; - else - // Count column parity - c_parity[i % 4] ^= id_bit; + // First elements in column? + if (i < 4) + // Fill out first elements + c_parity[i] = id_bit; + else + // Count column parity + c_parity[i % 4] ^= id_bit; - // Insert ID bit - id = (id << 1) | id_bit; - rev_id >>= 1; - } + // Insert ID bit + id = (id << 1) | id_bit; + rev_id >>= 1; + } - // Insert parity bit of last row - id = (id << 1) | r_parity; + // Insert parity bit of last row + id = (id << 1) | r_parity; - // Fill out column parity at the end of tag - for (i = 0; i < 4; ++i) - id = (id << 1) | c_parity[i]; + // Fill out column parity at the end of tag + for (i = 0; i < 4; ++i) + id = (id << 1) | c_parity[i]; - // Add stop bit - id <<= 1; + // Add stop bit + id <<= 1; - Dbprintf("Started writing %s tag ...", card ? "T55x7":"T5555"); - LED_D_ON(); + Dbprintf("Started writing %s tag ...", card ? "T55x7":"T5555"); + LED_D_ON(); - // Write EM410x ID - T55xxWriteBlock((uint32_t)(id >> 32), 1, 0, 0); - T55xxWriteBlock((uint32_t)id, 2, 0, 0); + // Write EM410x ID + T55xxWriteBlock((uint32_t)(id >> 32), 1, 0, 0); + T55xxWriteBlock((uint32_t)id, 2, 0, 0); - // Config for EM410x (RF/64, Manchester, Maxblock=2) - if (card) { - // Clock rate is stored in bits 8-15 of the card value - clock = (card & 0xFF00) >> 8; - Dbprintf("Clock rate: %d", clock); - switch (clock) - { - case 32: - clock = T55x7_BITRATE_RF_32; - break; - case 16: - clock = T55x7_BITRATE_RF_16; - break; - case 0: - // A value of 0 is assumed to be 64 for backwards-compatibility - // Fall through... - case 64: - clock = T55x7_BITRATE_RF_64; - break; - default: - Dbprintf("Invalid clock rate: %d", clock); - return; - } + // Config for EM410x (RF/64, Manchester, Maxblock=2) + if (card) { + // Clock rate is stored in bits 8-15 of the card value + clock = (card & 0xFF00) >> 8; + Dbprintf("Clock rate: %d", clock); + switch (clock) + { + case 32: + clock = T55x7_BITRATE_RF_32; + break; + case 16: + clock = T55x7_BITRATE_RF_16; + break; + case 0: + // A value of 0 is assumed to be 64 for backwards-compatibility + // Fall through... + case 64: + clock = T55x7_BITRATE_RF_64; + break; + default: + Dbprintf("Invalid clock rate: %d", clock); + return; + } - // Writing configuration for T55x7 tag - T55xxWriteBlock(clock | - T55x7_MODULATION_MANCHESTER | - 2 << T55x7_MAXBLOCK_SHIFT, - 0, 0, 0); - } - else - // Writing configuration for T5555(Q5) tag - T55xxWriteBlock(0x1F << T5555_BITRATE_SHIFT | - T5555_MODULATION_MANCHESTER | - 2 << T5555_MAXBLOCK_SHIFT, - 0, 0, 0); + // Writing configuration for T55x7 tag + T55xxWriteBlock(clock | + T55x7_MODULATION_MANCHESTER | + 2 << T55x7_MAXBLOCK_SHIFT, + 0, 0, 0); + } + else + // Writing configuration for T5555(Q5) tag + T55xxWriteBlock(0x1F << T5555_BITRATE_SHIFT | + T5555_MODULATION_MANCHESTER | + 2 << T5555_MAXBLOCK_SHIFT, + 0, 0, 0); - LED_D_OFF(); - Dbprintf("Tag %s written with 0x%08x%08x\n", card ? "T55x7":"T5555", - (uint32_t)(id >> 32), (uint32_t)id); + LED_D_OFF(); + Dbprintf("Tag %s written with 0x%08x%08x\n", card ? "T55x7":"T5555", + (uint32_t)(id >> 32), (uint32_t)id); } // Clone Indala 64-bit tag by UID to T55x7 void CopyIndala64toT55x7(int hi, int lo) { - //Program the 2 data blocks for supplied 64bit UID - // and the block 0 for Indala64 format - T55xxWriteBlock(hi,1,0,0); - T55xxWriteBlock(lo,2,0,0); - //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=2) - T55xxWriteBlock(T55x7_BITRATE_RF_32 | - T55x7_MODULATION_PSK1 | - 2 << T55x7_MAXBLOCK_SHIFT, - 0, 0, 0); - //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data) -// T5567WriteBlock(0x603E1042,0); + //Program the 2 data blocks for supplied 64bit UID + // and the block 0 for Indala64 format + T55xxWriteBlock(hi,1,0,0); + T55xxWriteBlock(lo,2,0,0); + //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=2) + T55xxWriteBlock(T55x7_BITRATE_RF_32 | + T55x7_MODULATION_PSK1 | + 2 << T55x7_MAXBLOCK_SHIFT, + 0, 0, 0); + //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data) + // T5567WriteBlock(0x603E1042,0); - DbpString("DONE!"); + DbpString("DONE!"); } void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int uid6, int uid7) { - //Program the 7 data blocks for supplied 224bit UID - // and the block 0 for Indala224 format - T55xxWriteBlock(uid1,1,0,0); - T55xxWriteBlock(uid2,2,0,0); - T55xxWriteBlock(uid3,3,0,0); - T55xxWriteBlock(uid4,4,0,0); - T55xxWriteBlock(uid5,5,0,0); - T55xxWriteBlock(uid6,6,0,0); - T55xxWriteBlock(uid7,7,0,0); - //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=7) - T55xxWriteBlock(T55x7_BITRATE_RF_32 | - T55x7_MODULATION_PSK1 | - 7 << T55x7_MAXBLOCK_SHIFT, - 0,0,0); - //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data) -// T5567WriteBlock(0x603E10E2,0); + //Program the 7 data blocks for supplied 224bit UID + // and the block 0 for Indala224 format + T55xxWriteBlock(uid1,1,0,0); + T55xxWriteBlock(uid2,2,0,0); + T55xxWriteBlock(uid3,3,0,0); + T55xxWriteBlock(uid4,4,0,0); + T55xxWriteBlock(uid5,5,0,0); + T55xxWriteBlock(uid6,6,0,0); + T55xxWriteBlock(uid7,7,0,0); + //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=7) + T55xxWriteBlock(T55x7_BITRATE_RF_32 | + T55x7_MODULATION_PSK1 | + 7 << T55x7_MAXBLOCK_SHIFT, + 0,0,0); + //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data) + // T5567WriteBlock(0x603E10E2,0); - DbpString("DONE!"); + DbpString("DONE!"); } @@ -1387,261 +1383,261 @@ void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int #define max(x,y) ( x GraphBuffer[0]) { - while(i < GraphTraceLen) { - if( !(GraphBuffer[i] > GraphBuffer[i-1]) && GraphBuffer[i] > lmax) - break; - i++; + uint8_t BitStream[256]; + uint8_t Blocks[8][16]; + uint8_t *GraphBuffer = (uint8_t *)BigBuf; + int GraphTraceLen = sizeof(BigBuf); + int i, j, lastval, bitidx, half_switch; + int clock = 64; + int tolerance = clock / 8; + int pmc, block_done; + int lc, warnings = 0; + int num_blocks = 0; + int lmin=128, lmax=128; + uint8_t dir; + + AcquireRawAdcSamples125k(0); + + lmin = 64; + lmax = 192; + + i = 2; + + /* Find first local max/min */ + if(GraphBuffer[1] > GraphBuffer[0]) { + while(i < GraphTraceLen) { + if( !(GraphBuffer[i] > GraphBuffer[i-1]) && GraphBuffer[i] > lmax) + break; + i++; + } + dir = 0; } - dir = 0; - } - else { - while(i < GraphTraceLen) { - if( !(GraphBuffer[i] < GraphBuffer[i-1]) && GraphBuffer[i] < lmin) - break; - i++; + else { + while(i < GraphTraceLen) { + if( !(GraphBuffer[i] < GraphBuffer[i-1]) && GraphBuffer[i] < lmin) + break; + i++; + } + dir = 1; } - dir = 1; - } - - lastval = i++; - half_switch = 0; - pmc = 0; - block_done = 0; - - for (bitidx = 0; i < GraphTraceLen; i++) - { - if ( (GraphBuffer[i-1] > GraphBuffer[i] && dir == 1 && GraphBuffer[i] > lmax) || (GraphBuffer[i-1] < GraphBuffer[i] && dir == 0 && GraphBuffer[i] < lmin)) - { - lc = i - lastval; - lastval = i; - - // Switch depending on lc length: - // Tolerance is 1/8 of clock rate (arbitrary) - if (abs(lc-clock/4) < tolerance) { - // 16T0 - if((i - pmc) == lc) { /* 16T0 was previous one */ - /* It's a PMC ! */ - i += (128+127+16+32+33+16)-1; - lastval = i; - pmc = 0; - block_done = 1; - } - else { - pmc = i; - } - } else if (abs(lc-clock/2) < tolerance) { - // 32TO - if((i - pmc) == lc) { /* 16T0 was previous one */ - /* It's a PMC ! */ - i += (128+127+16+32+33)-1; - lastval = i; - pmc = 0; - block_done = 1; - } - else if(half_switch == 1) { - BitStream[bitidx++] = 0; - half_switch = 0; - } - else - half_switch++; - } else if (abs(lc-clock) < tolerance) { - // 64TO - BitStream[bitidx++] = 1; - } else { - // Error - warnings++; - if (warnings > 10) - { - Dbprintf("Error: too many detection errors, aborting."); - return 0; - } - } - - if(block_done == 1) { - if(bitidx == 128) { - for(j=0; j<16; j++) { - Blocks[num_blocks][j] = 128*BitStream[j*8+7]+ - 64*BitStream[j*8+6]+ - 32*BitStream[j*8+5]+ - 16*BitStream[j*8+4]+ - 8*BitStream[j*8+3]+ - 4*BitStream[j*8+2]+ - 2*BitStream[j*8+1]+ - BitStream[j*8]; - } - num_blocks++; - } - bitidx = 0; - block_done = 0; - half_switch = 0; - } - if(i < GraphTraceLen) - { - if (GraphBuffer[i-1] > GraphBuffer[i]) dir=0; - else dir = 1; - } - } - if(bitidx==255) - bitidx=0; - warnings = 0; - if(num_blocks == 4) break; - } - memcpy(outBlocks, Blocks, 16*num_blocks); - return num_blocks; + + lastval = i++; + half_switch = 0; + pmc = 0; + block_done = 0; + + for (bitidx = 0; i < GraphTraceLen; i++) + { + if ( (GraphBuffer[i-1] > GraphBuffer[i] && dir == 1 && GraphBuffer[i] > lmax) || (GraphBuffer[i-1] < GraphBuffer[i] && dir == 0 && GraphBuffer[i] < lmin)) + { + lc = i - lastval; + lastval = i; + + // Switch depending on lc length: + // Tolerance is 1/8 of clock rate (arbitrary) + if (abs(lc-clock/4) < tolerance) { + // 16T0 + if((i - pmc) == lc) { /* 16T0 was previous one */ + /* It's a PMC ! */ + i += (128+127+16+32+33+16)-1; + lastval = i; + pmc = 0; + block_done = 1; + } + else { + pmc = i; + } + } else if (abs(lc-clock/2) < tolerance) { + // 32TO + if((i - pmc) == lc) { /* 16T0 was previous one */ + /* It's a PMC ! */ + i += (128+127+16+32+33)-1; + lastval = i; + pmc = 0; + block_done = 1; + } + else if(half_switch == 1) { + BitStream[bitidx++] = 0; + half_switch = 0; + } + else + half_switch++; + } else if (abs(lc-clock) < tolerance) { + // 64TO + BitStream[bitidx++] = 1; + } else { + // Error + warnings++; + if (warnings > 10) + { + Dbprintf("Error: too many detection errors, aborting."); + return 0; + } + } + + if(block_done == 1) { + if(bitidx == 128) { + for(j=0; j<16; j++) { + Blocks[num_blocks][j] = 128*BitStream[j*8+7]+ + 64*BitStream[j*8+6]+ + 32*BitStream[j*8+5]+ + 16*BitStream[j*8+4]+ + 8*BitStream[j*8+3]+ + 4*BitStream[j*8+2]+ + 2*BitStream[j*8+1]+ + BitStream[j*8]; + } + num_blocks++; + } + bitidx = 0; + block_done = 0; + half_switch = 0; + } + if(i < GraphTraceLen) + { + if (GraphBuffer[i-1] > GraphBuffer[i]) dir=0; + else dir = 1; + } + } + if(bitidx==255) + bitidx=0; + warnings = 0; + if(num_blocks == 4) break; + } + memcpy(outBlocks, Blocks, 16*num_blocks); + return num_blocks; } int IsBlock0PCF7931(uint8_t *Block) { - // Assume RFU means 0 :) - if((memcmp(Block, "\x00\x00\x00\x00\x00\x00\x00\x01", 8) == 0) && memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) // PAC enabled - return 1; - if((memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) && Block[7] == 0) // PAC disabled, can it *really* happen ? - return 1; - return 0; + // Assume RFU means 0 :) + if((memcmp(Block, "\x00\x00\x00\x00\x00\x00\x00\x01", 8) == 0) && memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) // PAC enabled + return 1; + if((memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) && Block[7] == 0) // PAC disabled, can it *really* happen ? + return 1; + return 0; } int IsBlock1PCF7931(uint8_t *Block) { - // Assume RFU means 0 :) - if(Block[10] == 0 && Block[11] == 0 && Block[12] == 0 && Block[13] == 0) - if((Block[14] & 0x7f) <= 9 && Block[15] <= 9) - return 1; - - return 0; + // Assume RFU means 0 :) + if(Block[10] == 0 && Block[11] == 0 && Block[12] == 0 && Block[13] == 0) + if((Block[14] & 0x7f) <= 9 && Block[15] <= 9) + return 1; + + return 0; } #define ALLOC 16 void ReadPCF7931() { - uint8_t Blocks[8][17]; - uint8_t tmpBlocks[4][16]; - int i, j, ind, ind2, n; - int num_blocks = 0; - int max_blocks = 8; - int ident = 0; - int error = 0; - int tries = 0; - - memset(Blocks, 0, 8*17*sizeof(uint8_t)); - - do { - memset(tmpBlocks, 0, 4*16*sizeof(uint8_t)); - n = DemodPCF7931((uint8_t**)tmpBlocks); - if(!n) - error++; - if(error==10 && num_blocks == 0) { - Dbprintf("Error, no tag or bad tag"); - return; - } - else if (tries==20 || error==10) { - Dbprintf("Error reading the tag"); - Dbprintf("Here is the partial content"); - goto end; - } - - for(i=0; i= 0; ind--,ind2--) { - if(ind2 < 0) - ind2 = max_blocks; - if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found - // Dbprintf("Tmp %d -> Block %d", ind, ind2); - memcpy(Blocks[ind2], tmpBlocks[ind], 16); - Blocks[ind2][ALLOC] = 1; - num_blocks++; - if(num_blocks == max_blocks) goto end; - } - } - for(ind=i+1,ind2=j+1; ind < n; ind++,ind2++) { - if(ind2 > max_blocks) - ind2 = 0; - if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found - // Dbprintf("Tmp %d -> Block %d", ind, ind2); - memcpy(Blocks[ind2], tmpBlocks[ind], 16); - Blocks[ind2][ALLOC] = 1; - num_blocks++; - if(num_blocks == max_blocks) goto end; - } - } - } - } + else if (tries==20 || error==10) { + Dbprintf("Error reading the tag"); + Dbprintf("Here is the partial content"); + goto end; } - } - } - tries++; - if (BUTTON_PRESS()) return; - } while (num_blocks != max_blocks); + + for(i=0; i= 0; ind--,ind2--) { + if(ind2 < 0) + ind2 = max_blocks; + if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found + // Dbprintf("Tmp %d -> Block %d", ind, ind2); + memcpy(Blocks[ind2], tmpBlocks[ind], 16); + Blocks[ind2][ALLOC] = 1; + num_blocks++; + if(num_blocks == max_blocks) goto end; + } + } + for(ind=i+1,ind2=j+1; ind < n; ind++,ind2++) { + if(ind2 > max_blocks) + ind2 = 0; + if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found + // Dbprintf("Tmp %d -> Block %d", ind, ind2); + memcpy(Blocks[ind2], tmpBlocks[ind], 16); + Blocks[ind2][ALLOC] = 1; + num_blocks++; + if(num_blocks == max_blocks) goto end; + } + } + } + } + } + } + } + tries++; + if (BUTTON_PRESS()) return; + } while (num_blocks != max_blocks); end: - Dbprintf("-----------------------------------------"); - Dbprintf("Memory content:"); - Dbprintf("-----------------------------------------"); - for(i=0; i", i); - } - Dbprintf("-----------------------------------------"); - - return ; + Dbprintf("-----------------------------------------"); + Dbprintf("Memory content:"); + Dbprintf("-----------------------------------------"); + for(i=0; i", i); + } + Dbprintf("-----------------------------------------"); + + return ; } @@ -1665,20 +1661,20 @@ uint8_t * fwd_write_ptr; //forwardlink bit pointer //==================================================================== //-------------------------------------------------------------------- uint8_t Prepare_Cmd( uint8_t cmd ) { - //-------------------------------------------------------------------- - - *forward_ptr++ = 0; //start bit - *forward_ptr++ = 0; //second pause for 4050 code - - *forward_ptr++ = cmd; - cmd >>= 1; - *forward_ptr++ = cmd; - cmd >>= 1; - *forward_ptr++ = cmd; - cmd >>= 1; - *forward_ptr++ = cmd; - - return 6; //return number of emited bits + //-------------------------------------------------------------------- + + *forward_ptr++ = 0; //start bit + *forward_ptr++ = 0; //second pause for 4050 code + + *forward_ptr++ = cmd; + cmd >>= 1; + *forward_ptr++ = cmd; + cmd >>= 1; + *forward_ptr++ = cmd; + cmd >>= 1; + *forward_ptr++ = cmd; + + return 6; //return number of emited bits } //==================================================================== @@ -1688,21 +1684,21 @@ uint8_t Prepare_Cmd( uint8_t cmd ) { //-------------------------------------------------------------------- uint8_t Prepare_Addr( uint8_t addr ) { - //-------------------------------------------------------------------- - - register uint8_t line_parity; - - uint8_t i; - line_parity = 0; - for(i=0;i<6;i++) { - *forward_ptr++ = addr; - line_parity ^= addr; - addr >>= 1; - } - - *forward_ptr++ = (line_parity & 1); - - return 7; //return number of emited bits + //-------------------------------------------------------------------- + + register uint8_t line_parity; + + uint8_t i; + line_parity = 0; + for(i=0;i<6;i++) { + *forward_ptr++ = addr; + line_parity ^= addr; + addr >>= 1; + } + + *forward_ptr++ = (line_parity & 1); + + return 7; //return number of emited bits } //==================================================================== @@ -1712,36 +1708,36 @@ uint8_t Prepare_Addr( uint8_t addr ) { //-------------------------------------------------------------------- uint8_t Prepare_Data( uint16_t data_low, uint16_t data_hi) { - //-------------------------------------------------------------------- - - register uint8_t line_parity; - register uint8_t column_parity; - register uint8_t i, j; - register uint16_t data; - - data = data_low; - column_parity = 0; - - for(i=0; i<4; i++) { - line_parity = 0; - for(j=0; j<8; j++) { - line_parity ^= data; - column_parity ^= (data & 1) << j; - *forward_ptr++ = data; - data >>= 1; + //-------------------------------------------------------------------- + + register uint8_t line_parity; + register uint8_t column_parity; + register uint8_t i, j; + register uint16_t data; + + data = data_low; + column_parity = 0; + + for(i=0; i<4; i++) { + line_parity = 0; + for(j=0; j<8; j++) { + line_parity ^= data; + column_parity ^= (data & 1) << j; + *forward_ptr++ = data; + data >>= 1; + } + *forward_ptr++ = line_parity; + if(i == 1) + data = data_hi; } - *forward_ptr++ = line_parity; - if(i == 1) - data = data_hi; - } - - for(j=0; j<8; j++) { - *forward_ptr++ = column_parity; - column_parity >>= 1; - } - *forward_ptr = 0; - - return 45; //return number of emited bits + + for(j=0; j<8; j++) { + *forward_ptr++ = column_parity; + column_parity >>= 1; + } + *forward_ptr = 0; + + return 45; //return number of emited bits } //==================================================================== @@ -1750,115 +1746,115 @@ uint8_t Prepare_Data( uint16_t data_low, uint16_t data_hi) { // fwd_bit_count set with number of bits to be sent //==================================================================== void SendForward(uint8_t fwd_bit_count) { - - fwd_write_ptr = forwardLink_data; - fwd_bit_sz = fwd_bit_count; - - LED_D_ON(); - - //Field on - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - - // Give it a bit of time for the resonant antenna to settle. - // And for the tag to fully power up - SpinDelay(150); - - // force 1st mod pulse (start gap must be longer for 4305) - fwd_bit_sz--; //prepare next bit modulation - fwd_write_ptr++; - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - SpinDelayUs(55*8); //55 cycles off (8us each)for 4305 - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on - SpinDelayUs(16*8); //16 cycles on (8us each) - - // now start writting - while(fwd_bit_sz-- > 0) { //prepare next bit modulation - if(((*fwd_write_ptr++) & 1) == 1) - SpinDelayUs(32*8); //32 cycles at 125Khz (8us each) - else { - //These timings work for 4469/4269/4305 (with the 55*8 above) - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - SpinDelayUs(23*8); //16-4 cycles off (8us each) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on - SpinDelayUs(9*8); //16 cycles on (8us each) + + fwd_write_ptr = forwardLink_data; + fwd_bit_sz = fwd_bit_count; + + LED_D_ON(); + + //Field on + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + + // Give it a bit of time for the resonant antenna to settle. + // And for the tag to fully power up + SpinDelay(150); + + // force 1st mod pulse (start gap must be longer for 4305) + fwd_bit_sz--; //prepare next bit modulation + fwd_write_ptr++; + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + SpinDelayUs(55*8); //55 cycles off (8us each)for 4305 + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on + SpinDelayUs(16*8); //16 cycles on (8us each) + + // now start writting + while(fwd_bit_sz-- > 0) { //prepare next bit modulation + if(((*fwd_write_ptr++) & 1) == 1) + SpinDelayUs(32*8); //32 cycles at 125Khz (8us each) + else { + //These timings work for 4469/4269/4305 (with the 55*8 above) + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + SpinDelayUs(23*8); //16-4 cycles off (8us each) + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on + SpinDelayUs(9*8); //16 cycles on (8us each) + } } - } } void EM4xLogin(uint32_t Password) { - - uint8_t fwd_bit_count; - - forward_ptr = forwardLink_data; - fwd_bit_count = Prepare_Cmd( FWD_CMD_LOGIN ); - fwd_bit_count += Prepare_Data( Password&0xFFFF, Password>>16 ); - - SendForward(fwd_bit_count); - - //Wait for command to complete - SpinDelay(20); - + + uint8_t fwd_bit_count; + + forward_ptr = forwardLink_data; + fwd_bit_count = Prepare_Cmd( FWD_CMD_LOGIN ); + fwd_bit_count += Prepare_Data( Password&0xFFFF, Password>>16 ); + + SendForward(fwd_bit_count); + + //Wait for command to complete + SpinDelay(20); + } void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) { - - uint8_t fwd_bit_count; - uint8_t *dest = (uint8_t *)BigBuf; - int m=0, i=0; - - //If password mode do login - if (PwdMode == 1) EM4xLogin(Pwd); - - forward_ptr = forwardLink_data; - fwd_bit_count = Prepare_Cmd( FWD_CMD_READ ); - fwd_bit_count += Prepare_Addr( Address ); - - m = sizeof(BigBuf); - // Clear destination buffer before sending the command - memset(dest, 128, m); - // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); - - SendForward(fwd_bit_count); - - // Now do the acquisition - i = 0; - for(;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; + + uint8_t fwd_bit_count; + uint8_t *dest = (uint8_t *)BigBuf; + int m=0, i=0; + + //If password mode do login + if (PwdMode == 1) EM4xLogin(Pwd); + + forward_ptr = forwardLink_data; + fwd_bit_count = Prepare_Cmd( FWD_CMD_READ ); + fwd_bit_count += Prepare_Addr( Address ); + + m = sizeof(BigBuf); + // Clear destination buffer before sending the command + memset(dest, 128, m); + // Connect the A/D to the peak-detected low-frequency path. + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); + + SendForward(fwd_bit_count); + + // Now do the acquisition + i = 0; + for(;;) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0x43; + } + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + i++; + if (i >= m) break; + } } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - i++; - if (i >= m) break; - } - } - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + LED_D_OFF(); } void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode) { - - uint8_t fwd_bit_count; - - //If password mode do login - if (PwdMode == 1) EM4xLogin(Pwd); - - forward_ptr = forwardLink_data; - fwd_bit_count = Prepare_Cmd( FWD_CMD_WRITE ); - fwd_bit_count += Prepare_Addr( Address ); - fwd_bit_count += Prepare_Data( Data&0xFFFF, Data>>16 ); - - SendForward(fwd_bit_count); - - //Wait for write to complete - SpinDelay(20); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); + + uint8_t fwd_bit_count; + + //If password mode do login + if (PwdMode == 1) EM4xLogin(Pwd); + + forward_ptr = forwardLink_data; + fwd_bit_count = Prepare_Cmd( FWD_CMD_WRITE ); + fwd_bit_count += Prepare_Addr( Address ); + fwd_bit_count += Prepare_Data( Data&0xFFFF, Data>>16 ); + + SendForward(fwd_bit_count); + + //Wait for write to complete + SpinDelay(20); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + LED_D_OFF(); } diff --git a/common/lfdemod.c b/common/lfdemod.c index ad4721f16..79c99f733 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -14,195 +14,195 @@ //by marshmellow //takes 1s and 0s and searches for EM410x format - output EM ID -uint64_t Em410xDecode(uint8_t *BitStream, int BitLen) +uint64_t Em410xDecode(uint8_t *BitStream,uint32_t BitLen) { - //no arguments needed - built this way in case we want this to be a direct call from "data " cmds in the future - // otherwise could be a void with no arguments - //set defaults - int high=0, low=128; - uint64_t lo=0; //hi=0, + //no arguments needed - built this way in case we want this to be a direct call from "data " cmds in the future + // otherwise could be a void with no arguments + //set defaults + int high=0, low=128; + uint64_t lo=0; //hi=0, - uint32_t i = 0; - uint32_t initLoopMax = 65; - if (initLoopMax>BitLen) initLoopMax=BitLen; + uint32_t i = 0; + uint32_t initLoopMax = 65; + if (initLoopMax>BitLen) initLoopMax=BitLen; - for (;i < initLoopMax; ++i) //65 samples should be plenty to find high and low values - { - if (BitStream[i] > high) - high = BitStream[i]; - else if (BitStream[i] < low) - low = BitStream[i]; - } - if (((high !=1)||(low !=0))){ //allow only 1s and 0s - // PrintAndLog("no data found"); - return 0; - } - uint8_t parityTest=0; - // 111111111 bit pattern represent start of frame - uint8_t frame_marker_mask[] = {1,1,1,1,1,1,1,1,1}; - uint32_t idx = 0; - uint32_t ii=0; - uint8_t resetCnt = 0; - while( (idx + 64) < BitLen) { - restart: - // search for a start of frame marker - if ( memcmp(BitStream+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) - { // frame marker found - idx+=9;//sizeof(frame_marker_mask); - for (i=0; i<10;i++){ - for(ii=0; ii<5; ++ii){ - parityTest += BitStream[(i*5)+ii+idx]; - } - if (parityTest== ((parityTest>>1)<<1)){ - parityTest=0; - for (ii=0; ii<4;++ii){ - //hi = (hi<<1)|(lo>>31); - lo=(lo<<1LL)|(BitStream[(i*5)+ii+idx]); - } - //PrintAndLog("DEBUG: EM parity passed parity val: %d, i:%d, ii:%d,idx:%d, Buffer: %d%d%d%d%d,lo: %d",parityTest,i,ii,idx,BitStream[idx+ii+(i*5)-5],BitStream[idx+ii+(i*5)-4],BitStream[idx+ii+(i*5)-3],BitStream[idx+ii+(i*5)-2],BitStream[idx+ii+(i*5)-1],lo); - }else {//parity failed - //PrintAndLog("DEBUG: EM parity failed parity val: %d, i:%d, ii:%d,idx:%d, Buffer: %d%d%d%d%d",parityTest,i,ii,idx,BitStream[idx+ii+(i*5)-5],BitStream[idx+ii+(i*5)-4],BitStream[idx+ii+(i*5)-3],BitStream[idx+ii+(i*5)-2],BitStream[idx+ii+(i*5)-1]); - parityTest=0; - idx-=8; - if (resetCnt>5)return 0; - resetCnt++; - goto restart;//continue; - } - } - //skip last 5 bit parity test for simplicity. - return lo; - }else{ - idx++; + for (;i < initLoopMax; ++i) //65 samples should be plenty to find high and low values + { + if (BitStream[i] > high) + high = BitStream[i]; + else if (BitStream[i] < low) + low = BitStream[i]; } - } - return 0; + if (((high !=1)||(low !=0))){ //allow only 1s and 0s + // PrintAndLog("no data found"); + return 0; + } + uint8_t parityTest=0; + // 111111111 bit pattern represent start of frame + uint8_t frame_marker_mask[] = {1,1,1,1,1,1,1,1,1}; + uint32_t idx = 0; + uint32_t ii=0; + uint8_t resetCnt = 0; + while( (idx + 64) < BitLen) { +restart: + // search for a start of frame marker + if ( memcmp(BitStream+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) + { // frame marker found + idx+=9;//sizeof(frame_marker_mask); + for (i=0; i<10;i++){ + for(ii=0; ii<5; ++ii){ + parityTest += BitStream[(i*5)+ii+idx]; + } + if (parityTest== ((parityTest>>1)<<1)){ + parityTest=0; + for (ii=0; ii<4;++ii){ + //hi = (hi<<1)|(lo>>31); + lo=(lo<<1LL)|(BitStream[(i*5)+ii+idx]); + } + //PrintAndLog("DEBUG: EM parity passed parity val: %d, i:%d, ii:%d,idx:%d, Buffer: %d%d%d%d%d,lo: %d",parityTest,i,ii,idx,BitStream[idx+ii+(i*5)-5],BitStream[idx+ii+(i*5)-4],BitStream[idx+ii+(i*5)-3],BitStream[idx+ii+(i*5)-2],BitStream[idx+ii+(i*5)-1],lo); + }else {//parity failed + //PrintAndLog("DEBUG: EM parity failed parity val: %d, i:%d, ii:%d,idx:%d, Buffer: %d%d%d%d%d",parityTest,i,ii,idx,BitStream[idx+ii+(i*5)-5],BitStream[idx+ii+(i*5)-4],BitStream[idx+ii+(i*5)-3],BitStream[idx+ii+(i*5)-2],BitStream[idx+ii+(i*5)-1]); + parityTest=0; + idx-=8; + if (resetCnt>5)return 0; + resetCnt++; + goto restart;//continue; + } + } + //skip last 5 bit parity test for simplicity. + return lo; + }else{ + idx++; + } + } + return 0; } //by marshmellow //takes 2 arguments - clock and invert both as integers //attempts to demodulate ask while decoding manchester //prints binary found and saves in graphbuffer for further commands -int askmandemod(uint8_t * BinStream, int *BitLen,int *clk, int *invert) +int askmandemod(uint8_t * BinStream,uint32_t *BitLen,int *clk, int *invert) { - int i; - int high = 0, low = 128; - *clk=DetectASKClock(BinStream,(size_t)*BitLen,*clk); //clock default + int i; + int high = 0, low = 128; + *clk=DetectASKClock(BinStream,(size_t)*BitLen,*clk); //clock default - if (*clk<8) *clk =64; - if (*clk<32) *clk=32; - if (*invert != 0 && *invert != 1) *invert=0; - uint32_t initLoopMax = 200; - if (initLoopMax>*BitLen) initLoopMax=*BitLen; - // Detect high and lows - for (i = 0; i < initLoopMax; ++i) //200 samples should be enough to find high and low values - { - if (BinStream[i] > high) - high = BinStream[i]; - else if (BinStream[i] < low) - low = BinStream[i]; - } - if ((high < 158) ){ //throw away static - //PrintAndLog("no data found"); - return -2; - } - //25% fuzz in case highs and lows aren't clipped [marshmellow] - high=(int)((high-128)*.75)+128; - low= (int)((low-128)*.75)+128; - - //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); - int lastBit = 0; //set first clock check - uint32_t bitnum = 0; //output counter - int 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 - int iii = 0; - uint32_t gLen = *BitLen; - if (gLen > 3000) gLen=3000; - uint8_t errCnt =0; - uint32_t bestStart = *BitLen; - uint32_t bestErrCnt = (*BitLen/1000); - uint32_t maxErr = (*BitLen/1000); - //PrintAndLog("DEBUG - lastbit - %d",lastBit); - //loop to find first wave that works - for (iii=0; iii < gLen; ++iii){ - if ((BinStream[iii]>=high)||(BinStream[iii]<=low)){ - lastBit=iii-*clk; - errCnt=0; - //loop through to see if this start location works - for (i = iii; i < *BitLen; ++i) { - if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){ - lastBit+=*clk; - } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ - //low found and we are expecting a bar - lastBit+=*clk; - } else { - //mid value found or no bar supposed to be here - if ((i-lastBit)>(*clk+tol)){ - //should have hit a high or low based on clock!! - - //debug - //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; //allow 1 error for every 1000 samples else start over - } - } - if ((i-iii) >(400 * *clk)) break; //got plenty of bits - } - //we got more than 64 good bits and not all errors - if ((((i-iii)/ *clk) > (64+errCnt)) && (errCnt*BitLen) initLoopMax=*BitLen; + // Detect high and lows + for (i = 0; i < initLoopMax; ++i) //200 samples should be enough to find high and low values + { + if (BinStream[i] > high) + high = BinStream[i]; + else if (BinStream[i] < low) + low = BinStream[i]; } - } - if (bestErrCnt= high) && ((i-lastBit)>(*clk-tol))){ - lastBit+=*clk; - BinStream[bitnum] = *invert; - bitnum++; - } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ - //low found and we are expecting a bar - lastBit+=*clk; - BinStream[bitnum] = 1-*invert; - bitnum++; - } else { - //mid value found or no bar supposed to be here - if ((i-lastBit)>(*clk+tol)){ - //should have hit a high or low based on clock!! - - //debug - //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; - bitnum++; - } - - lastBit+=*clk;//skip over error - } - } - if (bitnum >=400) break; + if ((high < 158) ){ //throw away static + //PrintAndLog("no data found"); + return -2; } - *BitLen=bitnum; - } else{ - *invert=bestStart; - *clk=iii; - return -1; - } - return bestErrCnt; + //25% fuzz in case highs and lows aren't clipped [marshmellow] + high=(int)((high-128)*.75)+128; + low= (int)((low-128)*.75)+128; + + //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); + int lastBit = 0; //set first clock check + uint32_t bitnum = 0; //output counter + int 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 + int iii = 0; + uint32_t gLen = *BitLen; + if (gLen > 3000) gLen=3000; + uint8_t errCnt =0; + uint32_t bestStart = *BitLen; + uint32_t bestErrCnt = (*BitLen/1000); + uint32_t maxErr = (*BitLen/1000); + //PrintAndLog("DEBUG - lastbit - %d",lastBit); + //loop to find first wave that works + for (iii=0; iii < gLen; ++iii){ + if ((BinStream[iii]>=high)||(BinStream[iii]<=low)){ + lastBit=iii-*clk; + errCnt=0; + //loop through to see if this start location works + for (i = iii; i < *BitLen; ++i) { + if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){ + lastBit+=*clk; + } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ + //low found and we are expecting a bar + lastBit+=*clk; + } else { + //mid value found or no bar supposed to be here + if ((i-lastBit)>(*clk+tol)){ + //should have hit a high or low based on clock!! + + //debug + //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; //allow 1 error for every 1000 samples else start over + } + } + if ((i-iii) >(400 * *clk)) break; //got plenty of bits + } + //we got more than 64 good bits and not all errors + if ((((i-iii)/ *clk) > (64+errCnt)) && (errCnt= high) && ((i-lastBit)>(*clk-tol))){ + lastBit+=*clk; + BinStream[bitnum] = *invert; + bitnum++; + } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ + //low found and we are expecting a bar + lastBit+=*clk; + BinStream[bitnum] = 1-*invert; + bitnum++; + } else { + //mid value found or no bar supposed to be here + if ((i-lastBit)>(*clk+tol)){ + //should have hit a high or low based on clock!! + + //debug + //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; + bitnum++; + } + + lastBit+=*clk;//skip over error + } + } + if (bitnum >=400) break; + } + *BitLen=bitnum; + } else{ + *invert=bestStart; + *clk=iii; + return -1; + } + return bestErrCnt; } //by marshmellow @@ -210,46 +210,46 @@ int askmandemod(uint8_t * BinStream, int *BitLen,int *clk, int *invert) //run through 2 times and take least errCnt int manrawdecode(uint8_t * BitStream, int *bitLen) { - int bitnum=0; - int errCnt =0; - int i=1; - int bestErr = 1000; - int bestRun = 0; - int ii=1; - for (ii=1;ii<3;++ii){ - i=1; - for (i=i+ii;i<*bitLen-2;i+=2){ - if(BitStream[i]==1 && (BitStream[i+1]==0)){ - } else if((BitStream[i]==0)&& BitStream[i+1]==1){ - } else { - errCnt++; - } - if(bitnum>300) break; - } - if (bestErr>errCnt){ - bestErr=errCnt; - bestRun=ii; - } - errCnt=0; - } - errCnt=bestErr; - if (errCnt<20){ - ii=bestRun; - i=1; - for (i=i+ii;i<*bitLen-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; - //errCnt++; - } - if(bitnum>300) break; - } - *bitLen=bitnum; - } - return errCnt; + int bitnum=0; + int errCnt =0; + int i=1; + int bestErr = 1000; + int bestRun = 0; + int ii=1; + for (ii=1;ii<3;++ii){ + i=1; + for (i=i+ii;i<*bitLen-2;i+=2){ + if(BitStream[i]==1 && (BitStream[i+1]==0)){ + } else if((BitStream[i]==0)&& BitStream[i+1]==1){ + } else { + errCnt++; + } + if(bitnum>300) break; + } + if (bestErr>errCnt){ + bestErr=errCnt; + bestRun=ii; + } + errCnt=0; + } + errCnt=bestErr; + if (errCnt<20){ + ii=bestRun; + i=1; + for (i=i+ii;i<*bitLen-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; + //errCnt++; + } + if(bitnum>300) break; + } + *bitLen=bitnum; + } + return errCnt; } @@ -257,23 +257,23 @@ int manrawdecode(uint8_t * BitStream, int *bitLen) //take 01 or 10 = 0 and 11 or 00 = 1 int BiphaseRawDecode(uint8_t * BitStream, int *bitLen, int offset) { - uint8_t bitnum=0; - uint32_t errCnt =0; - uint32_t i=1; - i=offset; - for (;i<*bitLen-2;i+=2){ - if((BitStream[i]==1 && BitStream[i+1]==0)||(BitStream[i]==0 && BitStream[i+1]==1)){ - BitStream[bitnum++]=1; - } else if((BitStream[i]==0 && BitStream[i+1]==0)||(BitStream[i]==1 && BitStream[i+1]==1)){ - BitStream[bitnum++]=0; - } else { - BitStream[bitnum++]=77; - errCnt++; + uint8_t bitnum=0; + uint32_t errCnt =0; + uint32_t i=1; + i=offset; + for (;i<*bitLen-2;i+=2){ + if((BitStream[i]==1 && BitStream[i+1]==0)||(BitStream[i]==0 && BitStream[i+1]==1)){ + BitStream[bitnum++]=1; + } else if((BitStream[i]==0 && BitStream[i+1]==0)||(BitStream[i]==1 && BitStream[i+1]==1)){ + BitStream[bitnum++]=0; + } else { + BitStream[bitnum++]=77; + errCnt++; + } + if(bitnum>250) break; } - if(bitnum>250) break; - } - *bitLen=bitnum; - return errCnt; + *bitLen=bitnum; + return errCnt; } //by marshmellow @@ -282,352 +282,352 @@ int BiphaseRawDecode(uint8_t * BitStream, int *bitLen, int offset) //prints binary found and saves in graphbuffer for further commands int askrawdemod(uint8_t *BinStream, int *bitLen,int *clk, int *invert) { - uint32_t i; - // int invert=0; //invert default - int high = 0, low = 128; - *clk=DetectASKClock(BinStream,*bitLen,*clk); //clock default - uint8_t BitStream[502] = {0}; + uint32_t i; + // int invert=0; //invert default + int high = 0, low = 128; + *clk=DetectASKClock(BinStream,*bitLen,*clk); //clock default + uint8_t BitStream[502] = {0}; - if (*clk<8) *clk =64; - if (*clk<32) *clk=32; - if (*invert != 0 && *invert != 1) *invert =0; - uint32_t initLoopMax = 200; - if (initLoopMax>*bitLen) initLoopMax=*bitLen; - // Detect high and lows - for (i = 0; i < initLoopMax; ++i) //200 samples should be plenty to find high and low values - { - if (BinStream[i] > high) - high = BinStream[i]; - else if (BinStream[i] < low) - low = BinStream[i]; - } - if ((high < 158)){ //throw away static - // PrintAndLog("no data found"); - return -2; - } - //25% fuzz in case highs and lows aren't clipped [marshmellow] - high=(int)((high-128)*.75)+128; - low= (int)((low-128)*.75)+128; + if (*clk<8) *clk =64; + if (*clk<32) *clk=32; + if (*invert != 0 && *invert != 1) *invert =0; + uint32_t initLoopMax = 200; + if (initLoopMax>*bitLen) initLoopMax=*bitLen; + // Detect high and lows + for (i = 0; i < initLoopMax; ++i) //200 samples should be plenty to find high and low values + { + if (BinStream[i] > high) + high = BinStream[i]; + else if (BinStream[i] < low) + low = BinStream[i]; + } + if ((high < 158)){ //throw away static + // PrintAndLog("no data found"); + return -2; + } + //25% fuzz in case highs and lows aren't clipped [marshmellow] + high=(int)((high-128)*.75)+128; + low= (int)((low-128)*.75)+128; - //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); - int lastBit = 0; //set first clock check - uint32_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 - uint32_t iii = 0; - uint32_t gLen = *bitLen; - if (gLen > 500) gLen=500; - uint8_t errCnt =0; - uint32_t bestStart = *bitLen; - uint32_t bestErrCnt = (*bitLen/1000); - uint8_t midBit=0; - //PrintAndLog("DEBUG - lastbit - %d",lastBit); - //loop to find first wave that works - for (iii=0; iii < gLen; ++iii){ - if ((BinStream[iii]>=high)||(BinStream[iii]<=low)){ - lastBit=iii-*clk; - //loop through to see if this start location works - for (i = iii; i < *bitLen; ++i) { - if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){ - lastBit+=*clk; - BitStream[bitnum] = *invert; - bitnum++; - midBit=0; - } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ - //low found and we are expecting a bar - lastBit+=*clk; - BitStream[bitnum] = 1-*invert; - bitnum++; - midBit=0; - } else if ((BinStream[i]<=low) && (midBit==0) && ((i-lastBit)>((*clk/2)-tol))){ - //mid bar? - midBit=1; - BitStream[bitnum]= 1-*invert; - bitnum++; - } else if ((BinStream[i]>=high)&&(midBit==0) && ((i-lastBit)>((*clk/2)-tol))){ - //mid bar? - midBit=1; - BitStream[bitnum]= *invert; - bitnum++; - } else if ((i-lastBit)>((*clk/2)+tol)&&(midBit==0)){ - //no mid bar found - midBit=1; - BitStream[bitnum]= BitStream[bitnum-1]; - bitnum++; - } else { - //mid value found or no bar supposed to be here + //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); + int lastBit = 0; //set first clock check + uint32_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 + uint32_t iii = 0; + uint32_t gLen = *bitLen; + if (gLen > 500) gLen=500; + uint8_t errCnt =0; + uint32_t bestStart = *bitLen; + uint32_t bestErrCnt = (*bitLen/1000); + uint8_t midBit=0; + //PrintAndLog("DEBUG - lastbit - %d",lastBit); + //loop to find first wave that works + for (iii=0; iii < gLen; ++iii){ + if ((BinStream[iii]>=high)||(BinStream[iii]<=low)){ + lastBit=iii-*clk; + //loop through to see if this start location works + for (i = iii; i < *bitLen; ++i) { + if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){ + lastBit+=*clk; + BitStream[bitnum] = *invert; + bitnum++; + midBit=0; + } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ + //low found and we are expecting a bar + lastBit+=*clk; + BitStream[bitnum] = 1-*invert; + bitnum++; + midBit=0; + } else if ((BinStream[i]<=low) && (midBit==0) && ((i-lastBit)>((*clk/2)-tol))){ + //mid bar? + midBit=1; + BitStream[bitnum]= 1-*invert; + bitnum++; + } else if ((BinStream[i]>=high)&&(midBit==0) && ((i-lastBit)>((*clk/2)-tol))){ + //mid bar? + midBit=1; + BitStream[bitnum]= *invert; + bitnum++; + } else if ((i-lastBit)>((*clk/2)+tol)&&(midBit==0)){ + //no mid bar found + midBit=1; + BitStream[bitnum]= BitStream[bitnum-1]; + bitnum++; + } else { + //mid value found or no bar supposed to be here - if ((i-lastBit)>(*clk+tol)){ - //should have hit a high or low based on clock!! - //debug - //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){ - BitStream[bitnum]=77; - bitnum++; + if ((i-lastBit)>(*clk+tol)){ + //should have hit a high or low based on clock!! + //debug + //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){ + BitStream[bitnum]=77; + bitnum++; + } + + + errCnt++; + lastBit+=*clk;//skip over until hit too many errors + if (errCnt>((*bitLen/1000))){ //allow 1 error for every 1000 samples else start over + errCnt=0; + bitnum=0;//start over + break; + } + } + } + if (bitnum>500) break; } - - - errCnt++; - lastBit+=*clk;//skip over until hit too many errors - if (errCnt>((*bitLen/1000))){ //allow 1 error for every 1000 samples else start over - errCnt=0; - bitnum=0;//start over - break; + //we got more than 64 good bits and not all errors + if ((bitnum > (64+errCnt)) && (errCnt<(*bitLen/1000))) { + //possible good read + if (errCnt==0) break; //great read - finish + if (bestStart == iii) break; //if current run == bestErrCnt run (after exhausted testing) then finish + if (errCnt500) break; - } - //we got more than 64 good bits and not all errors - if ((bitnum > (64+errCnt)) && (errCnt<(*bitLen/1000))) { - //possible good read - if (errCnt==0) break; //great read - finish - if (bestStart == iii) break; //if current run == bestErrCnt run (after exhausted testing) then finish - if (errCnt=gLen){ //exhausted test + //if there was a ok test go back to that one and re-run the best run (then dump after that run) + if (bestErrCnt < (*bitLen/1000)) iii=bestStart; } - } } - if (iii>=gLen){ //exhausted test - //if there was a ok test go back to that one and re-run the best run (then dump after that run) - if (bestErrCnt < (*bitLen/1000)) iii=bestStart; - } - } - if (bitnum>16){ - - // PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum); - //move BitStream back to BinStream - // ClearGraph(0); - for (i=0; i < bitnum; ++i){ - BinStream[i]=BitStream[i]; - } - *bitLen=bitnum; - // RepaintGraphWindow(); - //output - // if (errCnt>0){ - // PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); - // } - // PrintAndLog("ASK decoded bitstream:"); - // Now output the bitstream to the scrollback by line of 16 bits - // printBitStream2(BitStream,bitnum); - //int errCnt=0; - //errCnt=manrawdemod(BitStream,bitnum); + if (bitnum>16){ - // Em410xDecode(Cmd); - } else return -1; - return errCnt; + // PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum); + //move BitStream back to BinStream + // ClearGraph(0); + for (i=0; i < bitnum; ++i){ + BinStream[i]=BitStream[i]; + } + *bitLen=bitnum; + // RepaintGraphWindow(); + //output + // if (errCnt>0){ + // PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); + // } + // PrintAndLog("ASK decoded bitstream:"); + // Now output the bitstream to the scrollback by line of 16 bits + // printBitStream2(BitStream,bitnum); + //int errCnt=0; + //errCnt=manrawdemod(BitStream,bitnum); + + // Em410xDecode(Cmd); + } else return -1; + return errCnt; } //translate wave to 11111100000 (1 for each short wave 0 for each long wave) size_t fsk_wave_demod(uint8_t * dest, size_t size, uint8_t fchigh, uint8_t fclow) { - uint32_t last_transition = 0; - uint32_t idx = 1; - uint32_t maxVal=0; - if (fchigh==0) fchigh=10; - if (fclow==0) fclow=8; - // we do care about the actual theshold value as sometimes near the center of the - // wave we may get static that changes direction of wave for one value - // if our value is too low it might affect the read. and if our tag or - // antenna is weak a setting too high might not see anything. [marshmellow] - if (size<100) return 0; - for(idx=1; idx<100; idx++){ - if(maxVal1 transition - if (dest[idx-1] < dest[idx]) { // 0 -> 1 transition - if ((idx-last_transition)<(fclow-2)){ //0-5 = garbage noise - //do nothing with extra garbage - } else if ((idx-last_transition) < (fchigh-1)) { //6-8 = 8 waves - dest[numBits]=1; - } else { //9+ = 10 waves - dest[numBits]=0; - } - last_transition = idx; - numBits++; - } - } - return numBits; //Actually, it returns the number of bytes, but each byte represents a bit: 1 or 0 + size_t numBits = 0; + // count cycles between consecutive lo-hi transitions, there should be either 8 (fc/8) + // or 10 (fc/10) cycles but in practice due to noise etc we may end up with with anywhere + // between 7 to 11 cycles so fuzz it by treat anything <9 as 8 and anything else as 10 + for(idx = 1; idx < size; idx++) { + // threshold current value + + if (dest[idx] < threshold_value) dest[idx] = 0; + else dest[idx] = 1; + + // Check for 0->1 transition + if (dest[idx-1] < dest[idx]) { // 0 -> 1 transition + if ((idx-last_transition)<(fclow-2)){ //0-5 = garbage noise + //do nothing with extra garbage + } else if ((idx-last_transition) < (fchigh-1)) { //6-8 = 8 waves + dest[numBits]=1; + } else { //9+ = 10 waves + dest[numBits]=0; + } + last_transition = idx; + numBits++; + } + } + return numBits; //Actually, it returns the number of bytes, but each byte represents a bit: 1 or 0 } uint32_t myround2(float f) { - if (f >= 2000) return 2000;//something bad happened - return (uint32_t) (f + (float)0.5); + if (f >= 2000) return 2000;//something bad happened + return (uint32_t) (f + (float)0.5); } //translate 11111100000 to 10 size_t aggregate_bits(uint8_t *dest,size_t size, uint8_t rfLen, uint8_t maxConsequtiveBits, uint8_t invert,uint8_t fchigh,uint8_t fclow )// uint8_t h2l_crossing_value,uint8_t l2h_crossing_value, { - uint8_t lastval=dest[0]; - uint32_t idx=0; - size_t numBits=0; - uint32_t n=1; + uint8_t lastval=dest[0]; + uint32_t idx=0; + size_t numBits=0; + uint32_t n=1; - for( idx=1; idx < size; idx++) { + for( idx=1; idx < size; idx++) { - if (dest[idx]==lastval) { - n++; - continue; - } - //if lastval was 1, we have a 1->0 crossing - if ( dest[idx-1]==1 ) { - n=myround2((float)(n+1)/((float)(rfLen)/(float)fclow)); - //n=(n+1) / h2l_crossing_value; - } else {// 0->1 crossing - n=myround2((float)(n+1)/((float)(rfLen-2)/(float)fchigh)); //-2 for fudge factor - //n=(n+1) / l2h_crossing_value; - } - if (n == 0) n = 1; + if (dest[idx]==lastval) { + n++; + continue; + } + //if lastval was 1, we have a 1->0 crossing + if ( dest[idx-1]==1 ) { + n=myround2((float)(n+1)/((float)(rfLen)/(float)fclow)); + //n=(n+1) / h2l_crossing_value; + } else {// 0->1 crossing + n=myround2((float)(n+1)/((float)(rfLen-2)/(float)fchigh)); //-2 for fudge factor + //n=(n+1) / l2h_crossing_value; + } + if (n == 0) n = 1; - if(n < maxConsequtiveBits) //Consecutive - { - if(invert==0){ //invert bits - memset(dest+numBits, dest[idx-1] , n); - }else{ - memset(dest+numBits, dest[idx-1]^1 , n); - } - numBits += n; - } - n=0; - lastval=dest[idx]; - }//end for - return numBits; + if(n < maxConsequtiveBits) //Consecutive + { + if(invert==0){ //invert bits + memset(dest+numBits, dest[idx-1] , n); + }else{ + memset(dest+numBits, dest[idx-1]^1 , n); + } + numBits += n; + } + n=0; + lastval=dest[idx]; + }//end for + return numBits; } //by marshmellow (from holiman's base) // full fsk demod from GraphBuffer wave to decoded 1s and 0s (no mandemod) int fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uint8_t fchigh, uint8_t fclow) { - // FSK demodulator - size = fsk_wave_demod(dest, size, fchigh, fclow); - size = aggregate_bits(dest, size,rfLen,192,invert,fchigh,fclow); - return size; + // FSK demodulator + size = fsk_wave_demod(dest, size, fchigh, fclow); + size = aggregate_bits(dest, size,rfLen,192,invert,fchigh,fclow); + return size; } // loop to get raw HID waveform then FSK demodulate the TAG ID from it int HIDdemodFSK(uint8_t *dest, size_t size, uint32_t *hi2, uint32_t *hi, uint32_t *lo) { - - size_t idx=0; //, found=0; //size=0, - // FSK demodulator - size = fskdemod(dest, size,50,0,10,8); - // final loop, go over previously decoded manchester data and decode into usable tag ID - // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0 - uint8_t frame_marker_mask[] = {1,1,1,0,0,0}; - int numshifts = 0; - idx = 0; - //one scan - while( idx + sizeof(frame_marker_mask) < size) { - // search for a start of frame marker - if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) - { // frame marker found - idx+=sizeof(frame_marker_mask); - while(dest[idx] != dest[idx+1] && idx < size-2) - { - // Keep going until next frame marker (or error) - // Shift in a bit. Start by shifting high registers - *hi2 = (*hi2<<1)|(*hi>>31); - *hi = (*hi<<1)|(*lo>>31); - //Then, shift in a 0 or one into low - if (dest[idx] && !dest[idx+1]) // 1 0 - *lo=(*lo<<1)|0; - else // 0 1 - *lo=(*lo<<1)|1; - numshifts++; - idx += 2; - } - // Hopefully, we read a tag and hit upon the next frame marker - if(idx + sizeof(frame_marker_mask) < size) - { - if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) - { - //good return - return idx; - } - } - // reset - *hi2 = *hi = *lo = 0; - numshifts = 0; - }else { - idx++; - } - } - return -1; + size_t idx=0; //, found=0; //size=0, + // FSK demodulator + size = fskdemod(dest, size,50,0,10,8); + + // final loop, go over previously decoded manchester data and decode into usable tag ID + // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0 + uint8_t frame_marker_mask[] = {1,1,1,0,0,0}; + int numshifts = 0; + idx = 0; + //one scan + while( idx + sizeof(frame_marker_mask) < size) { + // search for a start of frame marker + if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) + { // frame marker found + idx+=sizeof(frame_marker_mask); + while(dest[idx] != dest[idx+1] && idx < size-2) + { + // Keep going until next frame marker (or error) + // Shift in a bit. Start by shifting high registers + *hi2 = (*hi2<<1)|(*hi>>31); + *hi = (*hi<<1)|(*lo>>31); + //Then, shift in a 0 or one into low + if (dest[idx] && !dest[idx+1]) // 1 0 + *lo=(*lo<<1)|0; + else // 0 1 + *lo=(*lo<<1)|1; + numshifts++; + idx += 2; + } + // Hopefully, we read a tag and hit upon the next frame marker + if(idx + sizeof(frame_marker_mask) < size) + { + if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) + { + //good return + return idx; + } + } + // reset + *hi2 = *hi = *lo = 0; + numshifts = 0; + }else { + idx++; + } + } + return -1; } uint32_t bytebits_to_byte(uint8_t* src, int numbits) { - uint32_t num = 0; - for(int i = 0 ; i < numbits ; i++) - { - num = (num << 1) | (*src); - src++; - } - return num; + uint32_t num = 0; + for(int i = 0 ; i < numbits ; i++) + { + num = (num << 1) | (*src); + src++; + } + return num; } int IOdemodFSK(uint8_t *dest, size_t size) { - uint32_t idx=0; - //make sure buffer has data - if (size < 66) return -1; - //test samples are not just noise - uint8_t testMax=0; - for(idx=0;idx<65;idx++){ - if (testMax170){ - // FSK demodulator - size = fskdemod(dest, size,64,1,10,8); // RF/64 and invert - if (size < 65) return -1; //did we get a good demod? - //Index map - //0 10 20 30 40 50 60 - //| | | | | | | - //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23 - //----------------------------------------------------------------------------- - //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11 - // - //XSF(version)facility:codeone+codetwo - //Handle the data - uint8_t mask[] = {0,0,0,0,0,0,0,0,0,1}; - for( idx=0; idx < (size - 65); idx++) { - if ( memcmp(dest + idx, mask, sizeof(mask))==0) { - //frame marker found - if (!dest[idx+8] && dest[idx+17]==1 && dest[idx+26]==1 && dest[idx+35]==1 && dest[idx+44]==1 && dest[idx+53]==1){ - //confirmed proper separator bits found - //return start position - return (int) idx; - } - } - } - } - return 0; + uint32_t idx=0; + //make sure buffer has data + if (size < 66) return -1; + //test samples are not just noise + uint8_t testMax=0; + for(idx=0;idx<65;idx++){ + if (testMax20){ + // FSK demodulator + size = fskdemod(dest, size,64,1,10,8); // RF/64 and invert + if (size < 65) return -1; //did we get a good demod? + //Index map + //0 10 20 30 40 50 60 + //| | | | | | | + //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23 + //----------------------------------------------------------------------------- + //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11 + // + //XSF(version)facility:codeone+codetwo + //Handle the data + uint8_t mask[] = {0,0,0,0,0,0,0,0,0,1}; + for( idx=0; idx < (size - 65); idx++) { + if ( memcmp(dest + idx, mask, sizeof(mask))==0) { + //frame marker found + if (!dest[idx+8] && dest[idx+17]==1 && dest[idx+26]==1 && dest[idx+35]==1 && dest[idx+44]==1 && dest[idx+53]==1){ + //confirmed proper separator bits found + //return start position + return (int) idx; + } + } + } + } + return 0; } // by marshmellow @@ -635,521 +635,67 @@ int IOdemodFSK(uint8_t *dest, size_t size) // maybe somehow adjust peak trimming value based on samples to fix? int DetectASKClock(uint8_t dest[], size_t size, int clock) { - int i=0; - int peak=0; - int low=128; - int clk[]={16,32,40,50,64,100,128,256}; - int loopCnt = 256; //don't need to loop through entire array... - if (sizepeak){ - peak = dest[i]; - } - if(dest[i]=peak) || (dest[ii]<=low)){ - errCnt=0; - // now that we have the first one lined up test rest of wave array - for (i=0; i<((int)(size/clk[clkCnt])-1); ++i){ - if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){ - }else if(dest[ii+(i*clk[clkCnt])-tol]>=peak || dest[ii+(i*clk[clkCnt])-tol]<=low){ - }else if(dest[ii+(i*clk[clkCnt])+tol]>=peak || dest[ii+(i*clk[clkCnt])+tol]<=low){ - }else{ //error no peak detected - errCnt++; - } + //get high and low peak + for (i=0;ipeak){ + peak = dest[i]; } - //if we found no errors this is correct one - return this clock - if(errCnt==0) return clk[clkCnt]; - //if we found errors see if it is lowest so far and save it as best run - if(errCntpeak){ - peak = dest[i]; - } - if(dest[i]=peak) || (dest[ii]<=low)){ - errCnt=0; - peakcnt=0; - // now that we have the first one lined up test rest of wave array - for (i=0; i<((int)(size/clk[clkCnt])-1); ++i){ - if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){ - peakcnt++; - }else if(dest[ii+(i*clk[clkCnt])-tol]>=peak || dest[ii+(i*clk[clkCnt])-tol]<=low){ - peakcnt++; - }else if(dest[ii+(i*clk[clkCnt])+tol]>=peak || dest[ii+(i*clk[clkCnt])+tol]<=low){ - peakcnt++; - }else{ //error no peak detected - errCnt++; - } + if(dest[i]peaksdet[clkCnt]) { - peaksdet[clkCnt]=peakcnt; - bestErr[clkCnt]=errCnt; - } - } - } - } - int iii=0; - int best=0; - //int ratio2; //debug - int ratio; - //int bits; - for (iii=0; iii<7;++iii){ - ratio=1000; - //ratio2=1000; //debug - //bits=size/clk[iii]; //debug - if (peaksdet[iii]>0){ - ratio=bestErr[iii]/peaksdet[iii]; - if (((bestErr[best]/peaksdet[best])>(ratio)+1)){ - best = iii; - } - //ratio2=bits/peaksdet[iii]; //debug - } - //PrintAndLog("DEBUG: Clk: %d, peaks: %d, errs: %d, bestClk: %d, ratio: %d, bits: %d, peakbitr: %d",clk[iii],peaksdet[iii],bestErr[iii],clk[best],ratio, bits,ratio2); - } - return clk[best]; -} - -/* -int DetectNRZpskClock(uint8_t dest[], size_t size, int clock) -{ - int i=0; - int peak=0; - int low=128; - int clk[]={16,32,40,50,64,100,128,256}; - int loopCnt = 1500; //don't need to loop through entire array... - if (sizepeak){ - peak = dest[i]; } - if(dest[i]=peak) || (dest[ii]<=low)){ - lastClk = ii-*clk; - errCnt[clkCnt]=0; - // now that we have the first one lined up test rest of wave array - for (i=ii; i=peak || dest[i]<=low) && (i>=lastClk+*clk-tol && i<=lastClk+*clk+tol)){ - bitHigh=1; - lastClk=lastClk+*clk; - ignorewin=clk[clkCnt]/8; - }else if(dest[i]low) { - if (ignorewin==0){ - bitHigh=0; - }else ignorewin--; - if (i>=lastClk+*clk+tol){ //past possible bar - lowBitCnt[clkCnt]++; + peak=(int)((peak-128)*.75)+128; + low= (int)((low-128)*.75)+128; + int ii; + int clkCnt; + int tol = 0; + int bestErr=1000; + int errCnt[]={0,0,0,0,0,0,0,0}; + //test each valid clock from smallest to greatest to see which lines up + for(clkCnt=0; clkCnt<6;++clkCnt){ + if (clk[clkCnt]==32){ + tol=1; + }else{ + tol=0; + } + bestErr=1000; + //try lining up the peaks by moving starting point (try first 256) + for (ii=0; ii=peak) || (dest[ii]<=low)){ + errCnt[clkCnt]=0; + // now that we have the first one lined up test rest of wave array + for (i=0; i<((int)(size/clk[clkCnt])-1); ++i){ + if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){ + }else if(dest[ii+(i*clk[clkCnt])-tol]>=peak || dest[ii+(i*clk[clkCnt])-tol]<=low){ + }else if(dest[ii+(i*clk[clkCnt])+tol]>=peak || dest[ii+(i*clk[clkCnt])+tol]<=low){ + }else{ //error no peak detected + errCnt[clkCnt]++; + } + } + //if we found no errors this is correct one - return this clock + if(errCnt[clkCnt]==0) return clk[clkCnt]; + //if we found errors see if it is lowest so far and save it as best run + if(errCnt[clkCnt]=peak || dest[i]<=low) && (i=lastClk+*clk+tol) && (bitHigh==0)){ - //error bar found no clock... - errCnt[clkCnt]++; - } } - //if we found no errors this is correct one - return this clock - if(errCnt[clkCnt]==0 && lowBitCnt[clkCnt]==0) return clk[clkCnt]; - //if we found errors see if it is lowest so far and save it as best run - if(errCnt[clkCnt]high) high=bitStream[i]; - } - high = (int)(((high-128)*.80)+128); - low = (int)(((low-128)*.90)+128); - //low = (uint8_t)(((int)(low)-128)*.80)+128; - for (i=0; i=high) newHigh=1; - } - return; -} - -int indala26decode(uint8_t *bitStream, int *bitLen, uint8_t *invert) -{ - //26 bit 40134 format (don't know other formats) - // Finding the start of a UID - int i; - int long_wait; - //uidlen = 64; - long_wait = 29;//29 leading zeros in format - int start; - int first = 0; - int first2 = 0; - int bitCnt = 0; - int ii; - for (start = 0; start <= *bitLen - 250; start++) { - first = bitStream[start]; - for (i = start; i < start + long_wait; i++) { - if (bitStream[i] != first) { - break; - } - } - if (i == (start + long_wait)) { - break; - } - } - if (start == *bitLen - 250 + 1) { - // did not find start sequence - return -1; - } - //found start once now test length by finding next one - // Inverting signal if needed - if (first == 1) { - for (i = start; i < *bitLen; i++) { - bitStream[i] = !bitStream[i]; - } - *invert = 1; - }else *invert=0; - - int iii; - for (ii=start+29; ii <= *bitLen - 250; ii++) { - first2 = bitStream[ii]; - for (iii = ii; iii < ii + long_wait; iii++) { - if (bitStream[iii] != first2) { - break; - } - } - if (iii == (ii + long_wait)) { - break; - } - } - if (ii== *bitLen - 250 + 1){ - // did not find second start sequence - return -2; - } - bitCnt=ii-start; - - // Dumping UID - i = start; - for (ii = 0; ii < bitCnt; ii++) { - bitStream[ii] = bitStream[i++]; - //showbits[bit] = '0' + bits[bit]; - } - *bitLen=bitCnt; - return 1; -} - -int pskNRZrawDemod(uint8_t *dest, int *bitLen, int *clk, int *invert) -{ - pskCleanWave(dest,*bitLen); - int clk2 = DetectpskNRZClock(dest, *bitLen, *clk); - *clk=clk2; - uint32_t i; - uint8_t high=0, low=128; - uint32_t gLen = *bitLen; - if (gLen > 1280) gLen=1280; - // get high - for (i=0; ihigh) high = dest[i]; - if (dest[i]=high)||(dest[iii]<=low)){ - lastBit=iii-*clk; - //loop through to see if this start location works - for (i = iii; i < *bitLen; ++i) { - //if we found a high bar and we are at a clock bit - if ((dest[i]>=high ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ - bitHigh=1; - lastBit+=*clk; - //curBit=1-*invert; - //dest[bitnum]=curBit; - ignorewin=*clk/8; - bitnum++; - //else if low bar found and we are at a clock point - }else if ((dest[i]<=low ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ - bitHigh=1; - lastBit+=*clk; - ignorewin=*clk/8; - //curBit=*invert; - //dest[bitnum]=curBit; - bitnum++; - //else if no bars found - }else if(dest[i]low) { - if (ignorewin==0){ - bitHigh=0; - }else ignorewin--; - //if we are past a clock point - if (i>=lastBit+*clk+tol){ //clock val - //dest[bitnum]=curBit; - lastBit+=*clk; - bitnum++; - } - //else if bar found but we are not at a clock bit and we did not just have a clock bit - }else if ((dest[i]>=high || dest[i]<=low) && (ilastBit+*clk+tol) && (bitHigh==0)){ - //error bar found no clock... - errCnt++; - } - if (bitnum>=1000) break; - } - //we got more than 64 good bits and not all errors - if ((bitnum > (64+errCnt)) && (errCnt<(maxErr))) { - //possible good read - if (errCnt==0){ - bestStart = iii; - bestErrCnt=errCnt; - break; //great read - finish + int iii=0; + int best=0; + for (iii=0; iii<6;++iii){ + if (errCnt[iii]=high ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ - bitHigh=1; - lastBit+=*clk; - curBit=1-*invert; - dest[bitnum]=curBit; - ignorewin=*clk/8; - bitnum++; - //else if low bar found and we are at a clock point - }else if ((dest[i]<=low ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ - bitHigh=1; - lastBit+=*clk; - curBit=*invert; - dest[bitnum]=curBit; - ignorewin=*clk/8; - bitnum++; - //else if no bars found - }else if(dest[i]low) { - if (ignorewin==0){ - bitHigh=0; - }else ignorewin--; - //if we are past a clock point - if (i>=lastBit+*clk+tol){ //clock val - lastBit+=*clk; - dest[bitnum]=curBit; - bitnum++; - } - //else if bar found but we are not at a clock bit and we did not just have a clock bit - }else if ((dest[i]>=high || dest[i]<=low) && ((ilastBit+*clk+tol)) && (bitHigh==0)){ - //error bar found no clock... - bitHigh=1; - dest[bitnum]=77; - bitnum++; - errCnt++; - } - if (bitnum >=1000) break; - } - *bitLen=bitnum; - } else{ - *bitLen=bitnum; - *clk=bestStart; - return -1; - } - - if (bitnum>16){ - *bitLen=bitnum; - } else return -1; - return errCnt; + return clk[best]; } - - - /*not needed? - uint32_t i; - uint8_t high=0, low=128; - uint32_t loopMax = 1280; //20 raw bits - - // get high - if (sizehigh) high = dest[i]; - if (dest[i]=high) dest[i]=high; - else if(dest[i]<=low) dest[i]=low; - else dest[i]=0; - } - */ diff --git a/common/lfdemod.h b/common/lfdemod.h index 2e0acf751..ad95fda5e 100644 --- a/common/lfdemod.h +++ b/common/lfdemod.h @@ -12,8 +12,8 @@ #include int DetectASKClock(uint8_t dest[], size_t size, int clock); -int askmandemod(uint8_t *BinStream,int *BitLen,int *clk, int *invert); -uint64_t Em410xDecode(uint8_t *BitStream,int BitLen); +int askmandemod(uint8_t *BinStream,uint32_t *BitLen,int *clk, int *invert); +uint64_t Em410xDecode(uint8_t *BitStream,uint32_t BitLen); int manrawdecode(uint8_t *BitStream, int *bitLen); int BiphaseRawDecode(uint8_t * BitStream, int *bitLen, int offset); int askrawdemod(uint8_t *BinStream, int *bitLen,int *clk, int *invert); @@ -21,9 +21,5 @@ int HIDdemodFSK(uint8_t *dest, size_t size, uint32_t *hi2, uint32_t *hi, uint32_ 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, int numbits); -int pskNRZrawDemod(uint8_t *dest, int *bitLen, int *clk, int *invert); -int DetectpskNRZClock(uint8_t dest[], size_t size, int clock); -int indala26decode(uint8_t *bitStream, int *bitLen, uint8_t *invert); -void pskCleanWave(uint8_t *bitStream, int bitLen); #endif From ba1a299ce67e4699e77fefe6a8ef825e30118961 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Tue, 6 Jan 2015 23:29:45 -0500 Subject: [PATCH 07/11] code cleanup. re-added psk commands. also fixed a bug in detect clock functions. sync with master prep for pull request --- armsrc/lfops.c | 2738 +++++++++++++++++++++++----------------------- client/cmddata.c | 2402 ++++++++++++++++++++-------------------- client/cmdlf.c | 997 +++++++++-------- client/graph.c | 324 +++--- client/graph.h | 4 +- common/lfdemod.c | 1532 ++++++++++++++++---------- common/lfdemod.h | 18 +- 7 files changed, 4174 insertions(+), 3841 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index ab196325f..b9dbb8e27 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -18,144 +18,144 @@ /** -* Does the sample acquisition. If threshold is specified, the actual sampling -* is not commenced until the threshold has been reached. +* Does the sample acquisition. If threshold is specified, the actual sampling +* is not commenced until the threshold has been reached. * @param trigger_threshold - the threshold * @param silent - is true, now outputs are made. If false, dbprints the status */ void DoAcquisition125k_internal(int trigger_threshold,bool silent) { - uint8_t *dest = (uint8_t *)BigBuf; - int n = sizeof(BigBuf); - int i; + uint8_t *dest = (uint8_t *)BigBuf; + int n = sizeof(BigBuf); + int i; - memset(dest, 0, n); - i = 0; - for(;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - LED_D_ON(); - } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - LED_D_OFF(); - if (trigger_threshold != -1 && dest[i] < trigger_threshold) - continue; - else - trigger_threshold = -1; - if (++i >= n) break; - } - } - if(!silent) - { - Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...", - dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); + memset(dest, 0, n); + i = 0; + for(;;) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0x43; + LED_D_ON(); + } + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + LED_D_OFF(); + if (trigger_threshold != -1 && dest[i] < trigger_threshold) + continue; + else + trigger_threshold = -1; + if (++i >= n) break; + } + } + if(!silent) + { + Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...", + dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); - } + } } /** -* Perform sample aquisition. +* Perform sample aquisition. */ void DoAcquisition125k(int trigger_threshold) { - DoAcquisition125k_internal(trigger_threshold, false); + DoAcquisition125k_internal(trigger_threshold, false); } /** -* Setup the FPGA to listen for samples. This method downloads the FPGA bitstream -* if not already loaded, sets divisor and starts up the antenna. +* Setup the FPGA to listen for samples. This method downloads the FPGA bitstream +* if not already loaded, sets divisor and starts up the antenna. * @param divisor : 1, 88> 255 or negative ==> 134.8 KHz * 0 or 95 ==> 125 KHz -* +* **/ void LFSetupFPGAForADC(int divisor, bool lf_field) { - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - if ( (divisor == 1) || (divisor < 0) || (divisor > 255) ) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz - else if (divisor == 0) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - else - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + if ( (divisor == 1) || (divisor < 0) || (divisor > 255) ) + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz + else if (divisor == 0) + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + else + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | (lf_field ? FPGA_LF_ADC_READER_FIELD : 0)); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | (lf_field ? FPGA_LF_ADC_READER_FIELD : 0)); - // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - // Give it a bit of time for the resonant antenna to settle. - SpinDelay(50); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); + // Connect the A/D to the peak-detected low-frequency path. + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + // Give it a bit of time for the resonant antenna to settle. + SpinDelay(50); + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); } /** -* Initializes the FPGA, and acquires the samples. +* Initializes the FPGA, and acquires the samples. **/ void AcquireRawAdcSamples125k(int divisor) { - LFSetupFPGAForADC(divisor, true); - // Now call the acquisition routine - DoAcquisition125k_internal(-1,false); + LFSetupFPGAForADC(divisor, true); + // Now call the acquisition routine + DoAcquisition125k_internal(-1,false); } /** -* Initializes the FPGA for snoop-mode, and acquires the samples. +* Initializes the FPGA for snoop-mode, and acquires the samples. **/ void SnoopLFRawAdcSamples(int divisor, int trigger_threshold) { - LFSetupFPGAForADC(divisor, false); - DoAcquisition125k(trigger_threshold); + LFSetupFPGAForADC(divisor, false); + DoAcquisition125k(trigger_threshold); } void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, uint8_t *command) { - /* Make sure the tag is reset */ - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelay(2500); + /* Make sure the tag is reset */ + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelay(2500); - int divisor_used = 95; // 125 KHz - // see if 'h' was specified + int divisor_used = 95; // 125 KHz + // see if 'h' was specified - if (command[strlen((char *) command) - 1] == 'h') - divisor_used = 88; // 134.8 KHz + if (command[strlen((char *) command) - 1] == 'h') + divisor_used = 88; // 134.8 KHz - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // Give it a bit of time for the resonant antenna to settle. - SpinDelay(50); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + // Give it a bit of time for the resonant antenna to settle. + SpinDelay(50); - // And a little more time for the tag to fully power up - SpinDelay(2000); + // And a little more time for the tag to fully power up + SpinDelay(2000); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); - // now modulate the reader field - while(*command != '\0' && *command != ' ') { - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LED_D_OFF(); - SpinDelayUs(delay_off); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); + // now modulate the reader field + while(*command != '\0' && *command != ' ') { + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LED_D_OFF(); + SpinDelayUs(delay_off); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - LED_D_ON(); - if(*(command++) == '0') - SpinDelayUs(period_0); - else - SpinDelayUs(period_1); - } - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LED_D_OFF(); - SpinDelayUs(delay_off); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + LED_D_ON(); + if(*(command++) == '0') + SpinDelayUs(period_0); + else + SpinDelayUs(period_1); + } + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LED_D_OFF(); + SpinDelayUs(delay_off); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // now do the read - DoAcquisition125k(-1); + // now do the read + DoAcquisition125k(-1); } /* blank r/w tag data stream @@ -169,230 +169,227 @@ void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, */ void ReadTItag(void) { - // some hardcoded initial params - // when we read a TI tag we sample the zerocross line at 2Mhz - // TI tags modulate a 1 as 16 cycles of 123.2Khz - // TI tags modulate a 0 as 16 cycles of 134.2Khz -#define FSAMPLE 2000000 -#define FREQLO 123200 -#define FREQHI 134200 + // some hardcoded initial params + // when we read a TI tag we sample the zerocross line at 2Mhz + // TI tags modulate a 1 as 16 cycles of 123.2Khz + // TI tags modulate a 0 as 16 cycles of 134.2Khz + #define FSAMPLE 2000000 + #define FREQLO 123200 + #define FREQHI 134200 - signed char *dest = (signed char *)BigBuf; - int n = sizeof(BigBuf); - // int *dest = GraphBuffer; - // int n = GraphTraceLen; + signed char *dest = (signed char *)BigBuf; + int n = sizeof(BigBuf); + // 128 bit shift register [shift3:shift2:shift1:shift0] + uint32_t shift3 = 0, shift2 = 0, shift1 = 0, shift0 = 0; - // 128 bit shift register [shift3:shift2:shift1:shift0] - uint32_t shift3 = 0, shift2 = 0, shift1 = 0, shift0 = 0; + int i, cycles=0, samples=0; + // how many sample points fit in 16 cycles of each frequency + uint32_t sampleslo = (FSAMPLE<<4)/FREQLO, sampleshi = (FSAMPLE<<4)/FREQHI; + // when to tell if we're close enough to one freq or another + uint32_t threshold = (sampleslo - sampleshi + 1)>>1; - int i, cycles=0, samples=0; - // how many sample points fit in 16 cycles of each frequency - uint32_t sampleslo = (FSAMPLE<<4)/FREQLO, sampleshi = (FSAMPLE<<4)/FREQHI; - // when to tell if we're close enough to one freq or another - uint32_t threshold = (sampleslo - sampleshi + 1)>>1; + // TI tags charge at 134.2Khz + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz - // TI tags charge at 134.2Khz - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz + // Place FPGA in passthrough mode, in this mode the CROSS_LO line + // connects to SSP_DIN and the SSP_DOUT logic level controls + // whether we're modulating the antenna (high) + // or listening to the antenna (low) + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); - // Place FPGA in passthrough mode, in this mode the CROSS_LO line - // connects to SSP_DIN and the SSP_DOUT logic level controls - // whether we're modulating the antenna (high) - // or listening to the antenna (low) - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); + // get TI tag data into the buffer + AcquireTiType(); - // get TI tag data into the buffer - AcquireTiType(); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + for (i=0; i0) ) { + cycles++; + // after 16 cycles, measure the frequency + if (cycles>15) { + cycles=0; + samples=i-samples; // number of samples in these 16 cycles - for (i=0; i0) ) { - cycles++; - // after 16 cycles, measure the frequency - if (cycles>15) { - cycles=0; - samples=i-samples; // number of samples in these 16 cycles + // TI bits are coming to us lsb first so shift them + // right through our 128 bit right shift register + shift0 = (shift0>>1) | (shift1 << 31); + shift1 = (shift1>>1) | (shift2 << 31); + shift2 = (shift2>>1) | (shift3 << 31); + shift3 >>= 1; - // TI bits are coming to us lsb first so shift them - // right through our 128 bit right shift register - shift0 = (shift0>>1) | (shift1 << 31); - shift1 = (shift1>>1) | (shift2 << 31); - shift2 = (shift2>>1) | (shift3 << 31); - shift3 >>= 1; + // check if the cycles fall close to the number + // expected for either the low or high frequency + if ( (samples>(sampleslo-threshold)) && (samples<(sampleslo+threshold)) ) { + // low frequency represents a 1 + shift3 |= (1<<31); + } else if ( (samples>(sampleshi-threshold)) && (samples<(sampleshi+threshold)) ) { + // high frequency represents a 0 + } else { + // probably detected a gay waveform or noise + // use this as gaydar or discard shift register and start again + shift3 = shift2 = shift1 = shift0 = 0; + } + samples = i; - // check if the cycles fall close to the number - // expected for either the low or high frequency - if ( (samples>(sampleslo-threshold)) && (samples<(sampleslo+threshold)) ) { - // low frequency represents a 1 - shift3 |= (1<<31); - } else if ( (samples>(sampleshi-threshold)) && (samples<(sampleshi+threshold)) ) { - // high frequency represents a 0 - } else { - // probably detected a gay waveform or noise - // use this as gaydar or discard shift register and start again - shift3 = shift2 = shift1 = shift0 = 0; - } - samples = i; + // for each bit we receive, test if we've detected a valid tag - // for each bit we receive, test if we've detected a valid tag + // if we see 17 zeroes followed by 6 ones, we might have a tag + // remember the bits are backwards + if ( ((shift0 & 0x7fffff) == 0x7e0000) ) { + // if start and end bytes match, we have a tag so break out of the loop + if ( ((shift0>>16)&0xff) == ((shift3>>8)&0xff) ) { + cycles = 0xF0B; //use this as a flag (ugly but whatever) + break; + } + } + } + } + } - // if we see 17 zeroes followed by 6 ones, we might have a tag - // remember the bits are backwards - if ( ((shift0 & 0x7fffff) == 0x7e0000) ) { - // if start and end bytes match, we have a tag so break out of the loop - if ( ((shift0>>16)&0xff) == ((shift3>>8)&0xff) ) { - cycles = 0xF0B; //use this as a flag (ugly but whatever) - break; - } - } - } - } - } + // if flag is set we have a tag + if (cycles!=0xF0B) { + DbpString("Info: No valid tag detected."); + } else { + // put 64 bit data into shift1 and shift0 + shift0 = (shift0>>24) | (shift1 << 8); + shift1 = (shift1>>24) | (shift2 << 8); - // if flag is set we have a tag - if (cycles!=0xF0B) { - DbpString("Info: No valid tag detected."); - } else { - // put 64 bit data into shift1 and shift0 - shift0 = (shift0>>24) | (shift1 << 8); - shift1 = (shift1>>24) | (shift2 << 8); + // align 16 bit crc into lower half of shift2 + shift2 = ((shift2>>24) | (shift3 << 8)) & 0x0ffff; - // align 16 bit crc into lower half of shift2 - shift2 = ((shift2>>24) | (shift3 << 8)) & 0x0ffff; + // if r/w tag, check ident match + if (shift3 & (1<<15) ) { + DbpString("Info: TI tag is rewriteable"); + // only 15 bits compare, last bit of ident is not valid + if (((shift3 >> 16) ^ shift0) & 0x7fff ) { + DbpString("Error: Ident mismatch!"); + } else { + DbpString("Info: TI tag ident is valid"); + } + } else { + DbpString("Info: TI tag is readonly"); + } - // if r/w tag, check ident match - if ( shift3&(1<<15) ) { - DbpString("Info: TI tag is rewriteable"); - // only 15 bits compare, last bit of ident is not valid - if ( ((shift3>>16)^shift0)&0x7fff ) { - DbpString("Error: Ident mismatch!"); - } else { - DbpString("Info: TI tag ident is valid"); - } - } else { - DbpString("Info: TI tag is readonly"); - } + // WARNING the order of the bytes in which we calc crc below needs checking + // i'm 99% sure the crc algorithm is correct, but it may need to eat the + // bytes in reverse or something + // calculate CRC + uint32_t crc=0; - // WARNING the order of the bytes in which we calc crc below needs checking - // i'm 99% sure the crc algorithm is correct, but it may need to eat the - // bytes in reverse or something - // calculate CRC - uint32_t crc=0; + crc = update_crc16(crc, (shift0)&0xff); + crc = update_crc16(crc, (shift0>>8)&0xff); + crc = update_crc16(crc, (shift0>>16)&0xff); + crc = update_crc16(crc, (shift0>>24)&0xff); + crc = update_crc16(crc, (shift1)&0xff); + crc = update_crc16(crc, (shift1>>8)&0xff); + crc = update_crc16(crc, (shift1>>16)&0xff); + crc = update_crc16(crc, (shift1>>24)&0xff); - crc = update_crc16(crc, (shift0)&0xff); - crc = update_crc16(crc, (shift0>>8)&0xff); - crc = update_crc16(crc, (shift0>>16)&0xff); - crc = update_crc16(crc, (shift0>>24)&0xff); - crc = update_crc16(crc, (shift1)&0xff); - crc = update_crc16(crc, (shift1>>8)&0xff); - crc = update_crc16(crc, (shift1>>16)&0xff); - crc = update_crc16(crc, (shift1>>24)&0xff); - - Dbprintf("Info: Tag data: %x%08x, crc=%x", - (unsigned int)shift1, (unsigned int)shift0, (unsigned int)shift2 & 0xFFFF); - if (crc != (shift2&0xffff)) { - Dbprintf("Error: CRC mismatch, expected %x", (unsigned int)crc); - } else { - DbpString("Info: CRC is good"); - } - } + Dbprintf("Info: Tag data: %x%08x, crc=%x", + (unsigned int)shift1, (unsigned int)shift0, (unsigned int)shift2 & 0xFFFF); + if (crc != (shift2&0xffff)) { + Dbprintf("Error: CRC mismatch, expected %x", (unsigned int)crc); + } else { + DbpString("Info: CRC is good"); + } + } } void WriteTIbyte(uint8_t b) { - int i = 0; + int i = 0; - // modulate 8 bits out to the antenna - for (i=0; i<8; i++) - { - if (b&(1<PIO_PDR = GPIO_SSC_DIN; - AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN; + // Set up the synchronous serial port + AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DIN; + AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN; - // steal this pin from the SSP and use it to control the modulation - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + // steal this pin from the SSP and use it to control the modulation + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST; - AT91C_BASE_SSC->SSC_CR = AT91C_SSC_RXEN | AT91C_SSC_TXEN; + AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST; + AT91C_BASE_SSC->SSC_CR = AT91C_SSC_RXEN | AT91C_SSC_TXEN; - // Sample at 2 Mbit/s, so TI tags are 16.2 vs. 14.9 clocks long - // 48/2 = 24 MHz clock must be divided by 12 - AT91C_BASE_SSC->SSC_CMR = 12; + // Sample at 2 Mbit/s, so TI tags are 16.2 vs. 14.9 clocks long + // 48/2 = 24 MHz clock must be divided by 12 + AT91C_BASE_SSC->SSC_CMR = 12; - AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(0); - AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(32) | AT91C_SSC_MSBF; - AT91C_BASE_SSC->SSC_TCMR = 0; - AT91C_BASE_SSC->SSC_TFMR = 0; + AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(0); + AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(32) | AT91C_SSC_MSBF; + AT91C_BASE_SSC->SSC_TCMR = 0; + AT91C_BASE_SSC->SSC_TFMR = 0; - LED_D_ON(); + LED_D_ON(); - // modulate antenna - HIGH(GPIO_SSC_DOUT); + // modulate antenna + HIGH(GPIO_SSC_DOUT); - // Charge TI tag for 50ms. - SpinDelay(50); + // Charge TI tag for 50ms. + SpinDelay(50); - // stop modulating antenna and listen - LOW(GPIO_SSC_DOUT); + // stop modulating antenna and listen + LOW(GPIO_SSC_DOUT); - LED_D_OFF(); + LED_D_OFF(); - i = 0; - for(;;) { - if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - BigBuf[i] = AT91C_BASE_SSC->SSC_RHR; // store 32 bit values in buffer - i++; if(i >= TIBUFLEN) break; - } - WDT_HIT(); - } + i = 0; + for(;;) { + if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + BigBuf[i] = AT91C_BASE_SSC->SSC_RHR; // store 32 bit values in buffer + i++; if(i >= TIBUFLEN) break; + } + WDT_HIT(); + } - // return stolen pin to SSP - AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN | GPIO_SSC_DOUT; + // return stolen pin to SSP + AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN | GPIO_SSC_DOUT; - char *dest = (char *)BigBuf; - n = TIBUFLEN*32; - // unpack buffer - for (i=TIBUFLEN-1; i>=0; i--) { - for (j=0; j<32; j++) { - if(BigBuf[i] & (1 << j)) { - dest[--n] = 1; - } else { - dest[--n] = -1; - } - } - } + char *dest = (char *)BigBuf; + n = TIBUFLEN*32; + // unpack buffer + for (i=TIBUFLEN-1; i>=0; i--) { + for (j=0; j<32; j++) { + if(BigBuf[i] & (1 << j)) { + dest[--n] = 1; + } else { + dest[--n] = -1; + } + } + } } // arguments: 64bit data split into 32bit idhi:idlo and optional 16bit crc @@ -400,127 +397,127 @@ void AcquireTiType(void) // if not provided a valid crc will be computed from the data and written. void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc) { - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - if(crc == 0) { - crc = update_crc16(crc, (idlo)&0xff); - crc = update_crc16(crc, (idlo>>8)&0xff); - crc = update_crc16(crc, (idlo>>16)&0xff); - crc = update_crc16(crc, (idlo>>24)&0xff); - crc = update_crc16(crc, (idhi)&0xff); - crc = update_crc16(crc, (idhi>>8)&0xff); - crc = update_crc16(crc, (idhi>>16)&0xff); - crc = update_crc16(crc, (idhi>>24)&0xff); - } - Dbprintf("Writing to tag: %x%08x, crc=%x", - (unsigned int) idhi, (unsigned int) idlo, crc); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + if(crc == 0) { + crc = update_crc16(crc, (idlo)&0xff); + crc = update_crc16(crc, (idlo>>8)&0xff); + crc = update_crc16(crc, (idlo>>16)&0xff); + crc = update_crc16(crc, (idlo>>24)&0xff); + crc = update_crc16(crc, (idhi)&0xff); + crc = update_crc16(crc, (idhi>>8)&0xff); + crc = update_crc16(crc, (idhi>>16)&0xff); + crc = update_crc16(crc, (idhi>>24)&0xff); + } + Dbprintf("Writing to tag: %x%08x, crc=%x", + (unsigned int) idhi, (unsigned int) idlo, crc); - // TI tags charge at 134.2Khz - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz - // Place FPGA in passthrough mode, in this mode the CROSS_LO line - // connects to SSP_DIN and the SSP_DOUT logic level controls - // whether we're modulating the antenna (high) - // or listening to the antenna (low) - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); - LED_A_ON(); + // TI tags charge at 134.2Khz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz + // Place FPGA in passthrough mode, in this mode the CROSS_LO line + // connects to SSP_DIN and the SSP_DOUT logic level controls + // whether we're modulating the antenna (high) + // or listening to the antenna (low) + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU); + LED_A_ON(); - // steal this pin from the SSP and use it to control the modulation - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + // steal this pin from the SSP and use it to control the modulation + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - // writing algorithm: - // a high bit consists of a field off for 1ms and field on for 1ms - // a low bit consists of a field off for 0.3ms and field on for 1.7ms - // initiate a charge time of 50ms (field on) then immediately start writing bits - // start by writing 0xBB (keyword) and 0xEB (password) - // then write 80 bits of data (or 64 bit data + 16 bit crc if you prefer) - // finally end with 0x0300 (write frame) - // all data is sent lsb firts - // finish with 15ms programming time + // writing algorithm: + // a high bit consists of a field off for 1ms and field on for 1ms + // a low bit consists of a field off for 0.3ms and field on for 1.7ms + // initiate a charge time of 50ms (field on) then immediately start writing bits + // start by writing 0xBB (keyword) and 0xEB (password) + // then write 80 bits of data (or 64 bit data + 16 bit crc if you prefer) + // finally end with 0x0300 (write frame) + // all data is sent lsb firts + // finish with 15ms programming time - // modulate antenna - HIGH(GPIO_SSC_DOUT); - SpinDelay(50); // charge time + // modulate antenna + HIGH(GPIO_SSC_DOUT); + SpinDelay(50); // charge time - WriteTIbyte(0xbb); // keyword - WriteTIbyte(0xeb); // password - WriteTIbyte( (idlo )&0xff ); - WriteTIbyte( (idlo>>8 )&0xff ); - WriteTIbyte( (idlo>>16)&0xff ); - WriteTIbyte( (idlo>>24)&0xff ); - WriteTIbyte( (idhi )&0xff ); - WriteTIbyte( (idhi>>8 )&0xff ); - WriteTIbyte( (idhi>>16)&0xff ); - WriteTIbyte( (idhi>>24)&0xff ); // data hi to lo - WriteTIbyte( (crc )&0xff ); // crc lo - WriteTIbyte( (crc>>8 )&0xff ); // crc hi - WriteTIbyte(0x00); // write frame lo - WriteTIbyte(0x03); // write frame hi - HIGH(GPIO_SSC_DOUT); - SpinDelay(50); // programming time + WriteTIbyte(0xbb); // keyword + WriteTIbyte(0xeb); // password + WriteTIbyte( (idlo )&0xff ); + WriteTIbyte( (idlo>>8 )&0xff ); + WriteTIbyte( (idlo>>16)&0xff ); + WriteTIbyte( (idlo>>24)&0xff ); + WriteTIbyte( (idhi )&0xff ); + WriteTIbyte( (idhi>>8 )&0xff ); + WriteTIbyte( (idhi>>16)&0xff ); + WriteTIbyte( (idhi>>24)&0xff ); // data hi to lo + WriteTIbyte( (crc )&0xff ); // crc lo + WriteTIbyte( (crc>>8 )&0xff ); // crc hi + WriteTIbyte(0x00); // write frame lo + WriteTIbyte(0x03); // write frame hi + HIGH(GPIO_SSC_DOUT); + SpinDelay(50); // programming time - LED_A_OFF(); + LED_A_OFF(); - // get TI tag data into the buffer - AcquireTiType(); + // get TI tag data into the buffer + AcquireTiType(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - DbpString("Now use tiread to check"); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + DbpString("Now use tiread to check"); } void SimulateTagLowFrequency(int period, int gap, int ledcontrol) { - int i; - uint8_t *tab = (uint8_t *)BigBuf; - - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); - - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK; - - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK; - + int i; + uint8_t *tab = (uint8_t *)BigBuf; + + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); + + AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK; + + AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK; + #define SHORT_COIL() LOW(GPIO_SSC_DOUT) #define OPEN_COIL() HIGH(GPIO_SSC_DOUT) - - i = 0; - for(;;) { - while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) { - if(BUTTON_PRESS()) { - DbpString("Stopped"); - return; - } - WDT_HIT(); - } - - if (ledcontrol) - LED_D_ON(); - - if(tab[i]) - OPEN_COIL(); - else - SHORT_COIL(); - - if (ledcontrol) - LED_D_OFF(); - - while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) { - if(BUTTON_PRESS()) { - DbpString("Stopped"); - return; - } - WDT_HIT(); - } - - i++; - if(i == period) { - i = 0; - if (gap) { - SHORT_COIL(); - SpinDelayUs(gap); - } - } - } + + i = 0; + for(;;) { + while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) { + if(BUTTON_PRESS()) { + DbpString("Stopped"); + return; + } + WDT_HIT(); + } + + if (ledcontrol) + LED_D_ON(); + + if(tab[i]) + OPEN_COIL(); + else + SHORT_COIL(); + + if (ledcontrol) + LED_D_OFF(); + + while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) { + if(BUTTON_PRESS()) { + DbpString("Stopped"); + return; + } + WDT_HIT(); + } + + i++; + if(i == period) { + i = 0; + if (gap) { + SHORT_COIL(); + SpinDelayUs(gap); + } + } + } } #define DEBUG_FRAME_CONTENTS 1 @@ -530,314 +527,309 @@ void SimulateTagLowFrequencyBidir(int divisor, int t0) // compose fc/8 fc/10 waveform static void fc(int c, int *n) { - uint8_t *dest = (uint8_t *)BigBuf; - int idx; + uint8_t *dest = (uint8_t *)BigBuf; + int idx; - // for when we want an fc8 pattern every 4 logical bits - if(c==0) { - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - } - // an fc/8 encoded bit is a bit pattern of 11000000 x6 = 48 samples - if(c==8) { - for (idx=0; idx<6; idx++) { - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - } - } + // for when we want an fc8 pattern every 4 logical bits + if(c==0) { + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + } + // an fc/8 encoded bit is a bit pattern of 11000000 x6 = 48 samples + if(c==8) { + for (idx=0; idx<6; idx++) { + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + } + } - // an fc/10 encoded bit is a bit pattern of 1110000000 x5 = 50 samples - if(c==10) { - for (idx=0; idx<5; idx++) { - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=1; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - dest[((*n)++)]=0; - } - } + // an fc/10 encoded bit is a bit pattern of 1110000000 x5 = 50 samples + if(c==10) { + for (idx=0; idx<5; idx++) { + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=1; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + dest[((*n)++)]=0; + } + } } // prepare a waveform pattern in the buffer based on the ID given then // simulate a HID tag until the button is pressed void CmdHIDsimTAG(int hi, int lo, int ledcontrol) { - int n=0, i=0; - /* - HID tag bitstream format - The tag contains a 44bit unique code. This is sent out MSB first in sets of 4 bits - A 1 bit is represented as 6 fc8 and 5 fc10 patterns - A 0 bit is represented as 5 fc10 and 6 fc8 patterns - A fc8 is inserted before every 4 bits - A special start of frame pattern is used consisting a0b0 where a and b are neither 0 - nor 1 bits, they are special patterns (a = set of 12 fc8 and b = set of 10 fc10) - */ + int n=0, i=0; + /* + HID tag bitstream format + The tag contains a 44bit unique code. This is sent out MSB first in sets of 4 bits + A 1 bit is represented as 6 fc8 and 5 fc10 patterns + A 0 bit is represented as 5 fc10 and 6 fc8 patterns + A fc8 is inserted before every 4 bits + A special start of frame pattern is used consisting a0b0 where a and b are neither 0 + nor 1 bits, they are special patterns (a = set of 12 fc8 and b = set of 10 fc10) + */ - if (hi>0xFFF) { - DbpString("Tags can only have 44 bits."); - return; - } - fc(0,&n); - // special start of frame marker containing invalid bit sequences - fc(8, &n); fc(8, &n); // invalid - fc(8, &n); fc(10, &n); // logical 0 - fc(10, &n); fc(10, &n); // invalid - fc(8, &n); fc(10, &n); // logical 0 + if (hi>0xFFF) { + DbpString("Tags can only have 44 bits."); + return; + } + fc(0,&n); + // special start of frame marker containing invalid bit sequences + fc(8, &n); fc(8, &n); // invalid + fc(8, &n); fc(10, &n); // logical 0 + fc(10, &n); fc(10, &n); // invalid + fc(8, &n); fc(10, &n); // logical 0 - WDT_HIT(); - // manchester encode bits 43 to 32 - for (i=11; i>=0; i--) { - if ((i%4)==3) fc(0,&n); - if ((hi>>i)&1) { - fc(10, &n); fc(8, &n); // low-high transition - } else { - fc(8, &n); fc(10, &n); // high-low transition - } - } + WDT_HIT(); + // manchester encode bits 43 to 32 + for (i=11; i>=0; i--) { + if ((i%4)==3) fc(0,&n); + if ((hi>>i)&1) { + fc(10, &n); fc(8, &n); // low-high transition + } else { + fc(8, &n); fc(10, &n); // high-low transition + } + } - WDT_HIT(); - // manchester encode bits 31 to 0 - for (i=31; i>=0; i--) { - if ((i%4)==3) fc(0,&n); - if ((lo>>i)&1) { - fc(10, &n); fc(8, &n); // low-high transition - } else { - fc(8, &n); fc(10, &n); // high-low transition - } - } + WDT_HIT(); + // manchester encode bits 31 to 0 + for (i=31; i>=0; i--) { + if ((i%4)==3) fc(0,&n); + if ((lo>>i)&1) { + fc(10, &n); fc(8, &n); // low-high transition + } else { + fc(8, &n); fc(10, &n); // high-low transition + } + } - if (ledcontrol) - LED_A_ON(); - SimulateTagLowFrequency(n, 0, ledcontrol); + if (ledcontrol) + LED_A_ON(); + SimulateTagLowFrequency(n, 0, ledcontrol); - if (ledcontrol) - LED_A_OFF(); + if (ledcontrol) + LED_A_OFF(); } // loop to get raw HID waveform then FSK demodulate the TAG ID from it void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) { - uint8_t *dest = (uint8_t *)BigBuf; + uint8_t *dest = (uint8_t *)BigBuf; - size_t size=0; //, found=0; - uint32_t hi2=0, hi=0, lo=0; + size_t size=0; //, found=0; + uint32_t hi2=0, hi=0, lo=0; - // Configure to go in 125Khz listen mode - LFSetupFPGAForADC(95, true); + // Configure to go in 125Khz listen mode + LFSetupFPGAForADC(95, true); - while(!BUTTON_PRESS()) { + while(!BUTTON_PRESS()) { - WDT_HIT(); - if (ledcontrol) LED_A_ON(); + WDT_HIT(); + if (ledcontrol) LED_A_ON(); - DoAcquisition125k_internal(-1,true); - size = sizeof(BigBuf); - if (size < 2000) continue; - // FSK demodulator + DoAcquisition125k_internal(-1,true); + // FSK demodulator + size = HIDdemodFSK(dest, sizeof(BigBuf), &hi2, &hi, &lo); - int bitLen = HIDdemodFSK(dest,size,&hi2,&hi,&lo); + WDT_HIT(); - WDT_HIT(); - - if (bitLen>0 && lo>0){ - // final loop, go over previously decoded manchester data and decode into usable tag ID - // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0 - if (hi2 != 0){ //extra large HID tags - Dbprintf("TAG ID: %x%08x%08x (%d)", - (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); - }else { //standard HID tags <38 bits - //Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd - uint8_t bitlen = 0; - uint32_t fc = 0; - uint32_t cardnum = 0; - if (((hi>>5)&1)==1){//if bit 38 is set then < 37 bit format is used - uint32_t lo2=0; - lo2=(((hi & 31) << 12) | (lo>>20)); //get bits 21-37 to check for format len bit - uint8_t idx3 = 1; - while(lo2>1){ //find last bit set to 1 (format len bit) - lo2=lo2>>1; - idx3++; - } - bitlen =idx3+19; - fc =0; - cardnum=0; - if(bitlen==26){ - cardnum = (lo>>1)&0xFFFF; - fc = (lo>>17)&0xFF; - } - if(bitlen==37){ - cardnum = (lo>>1)&0x7FFFF; - fc = ((hi&0xF)<<12)|(lo>>20); - } - if(bitlen==34){ - cardnum = (lo>>1)&0xFFFF; - fc= ((hi&1)<<15)|(lo>>17); - } - if(bitlen==35){ - cardnum = (lo>>1)&0xFFFFF; - fc = ((hi&1)<<11)|(lo>>21); - } - } - else { //if bit 38 is not set then 37 bit format is used - bitlen= 37; - fc =0; - cardnum=0; - if(bitlen==37){ - cardnum = (lo>>1)&0x7FFFF; - fc = ((hi&0xF)<<12)|(lo>>20); - } - } - //Dbprintf("TAG ID: %x%08x (%d)", - // (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); - Dbprintf("TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d", - (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF, - (unsigned int) bitlen, (unsigned int) fc, (unsigned int) cardnum); - } - if (findone){ - if (ledcontrol) LED_A_OFF(); - return; - } - // reset - hi2 = hi = lo = 0; - } - WDT_HIT(); - //SpinDelay(50); - } - DbpString("Stopped"); - if (ledcontrol) LED_A_OFF(); + if (size>0 && lo>0){ + // final loop, go over previously decoded manchester data and decode into usable tag ID + // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0 + if (hi2 != 0){ //extra large HID tags + Dbprintf("TAG ID: %x%08x%08x (%d)", + (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); + }else { //standard HID tags <38 bits + //Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd + uint8_t bitlen = 0; + uint32_t fc = 0; + uint32_t cardnum = 0; + if (((hi>>5)&1) == 1){//if bit 38 is set then < 37 bit format is used + uint32_t lo2=0; + lo2=(((hi & 31) << 12) | (lo>>20)); //get bits 21-37 to check for format len bit + uint8_t idx3 = 1; + while(lo2 > 1){ //find last bit set to 1 (format len bit) + lo2=lo2 >> 1; + idx3++; + } + bitlen = idx3+19; + fc =0; + cardnum=0; + if(bitlen == 26){ + cardnum = (lo>>1)&0xFFFF; + fc = (lo>>17)&0xFF; + } + if(bitlen == 37){ + cardnum = (lo>>1)&0x7FFFF; + fc = ((hi&0xF)<<12)|(lo>>20); + } + if(bitlen == 34){ + cardnum = (lo>>1)&0xFFFF; + fc= ((hi&1)<<15)|(lo>>17); + } + if(bitlen == 35){ + cardnum = (lo>>1)&0xFFFFF; + fc = ((hi&1)<<11)|(lo>>21); + } + } + else { //if bit 38 is not set then 37 bit format is used + bitlen= 37; + fc =0; + cardnum=0; + if(bitlen==37){ + cardnum = (lo>>1)&0x7FFFF; + fc = ((hi&0xF)<<12)|(lo>>20); + } + } + //Dbprintf("TAG ID: %x%08x (%d)", + // (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); + Dbprintf("TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d", + (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF, + (unsigned int) bitlen, (unsigned int) fc, (unsigned int) cardnum); + } + if (findone){ + if (ledcontrol) LED_A_OFF(); + return; + } + // reset + hi2 = hi = lo = 0; + } + WDT_HIT(); + } + DbpString("Stopped"); + if (ledcontrol) LED_A_OFF(); } void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol) { - uint8_t *dest = (uint8_t *)BigBuf; + uint8_t *dest = (uint8_t *)BigBuf; - size_t size=0; //, found=0; - uint32_t bitLen=0; - int clk=0, invert=0, errCnt=0; - uint64_t lo=0; - // Configure to go in 125Khz listen mode - LFSetupFPGAForADC(95, true); + size_t size=0; + int clk=0, invert=0, errCnt=0; + uint64_t lo=0; + // Configure to go in 125Khz listen mode + LFSetupFPGAForADC(95, true); - while(!BUTTON_PRESS()) { + while(!BUTTON_PRESS()) { - WDT_HIT(); - if (ledcontrol) LED_A_ON(); + WDT_HIT(); + if (ledcontrol) LED_A_ON(); - DoAcquisition125k_internal(-1,true); - size = sizeof(BigBuf); - if (size < 2000) continue; - // FSK demodulator - //int askmandemod(uint8_t *BinStream,uint32_t *BitLen,int *clk, int *invert); - bitLen=size; - //Dbprintf("DEBUG: Buffer got"); - errCnt = askmandemod(dest,&bitLen,&clk,&invert); //HIDdemodFSK(dest,size,&hi2,&hi,&lo); - //Dbprintf("DEBUG: ASK Got"); - WDT_HIT(); + DoAcquisition125k_internal(-1,true); + size = sizeof(BigBuf); + //Dbprintf("DEBUG: Buffer got"); + //askdemod and manchester decode + errCnt = askmandemod(dest, &size, &clk, &invert); + //Dbprintf("DEBUG: ASK Got"); + WDT_HIT(); - if (errCnt>=0){ - lo = Em410xDecode(dest,bitLen); - //Dbprintf("DEBUG: EM GOT"); - //printEM410x(lo); - if (lo>0){ - Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)",(uint32_t)(lo>>32),(uint32_t)lo,(uint32_t)(lo&0xFFFF),(uint32_t)((lo>>16LL) & 0xFF),(uint32_t)(lo & 0xFFFFFF)); - } - if (findone){ - if (ledcontrol) LED_A_OFF(); - return; - } - } else{ - //Dbprintf("DEBUG: No Tag"); - } - WDT_HIT(); - lo = 0; - clk=0; - invert=0; - errCnt=0; - size=0; - //SpinDelay(50); - } - DbpString("Stopped"); - if (ledcontrol) LED_A_OFF(); + if (errCnt>=0){ + lo = Em410xDecode(dest,size); + //Dbprintf("DEBUG: EM GOT"); + if (lo>0){ + Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)", + (uint32_t)(lo>>32), + (uint32_t)lo, + (uint32_t)(lo&0xFFFF), + (uint32_t)((lo>>16LL) & 0xFF), + (uint32_t)(lo & 0xFFFFFF)); + } + if (findone){ + if (ledcontrol) LED_A_OFF(); + return; + } + } else{ + //Dbprintf("DEBUG: No Tag"); + } + WDT_HIT(); + lo = 0; + clk=0; + invert=0; + errCnt=0; + size=0; + } + DbpString("Stopped"); + if (ledcontrol) LED_A_OFF(); } void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) { - uint8_t *dest = (uint8_t *)BigBuf; - int idx=0; - uint32_t code=0, code2=0; - uint8_t version=0; - uint8_t facilitycode=0; - uint16_t number=0; - // Configure to go in 125Khz listen mode - LFSetupFPGAForADC(95, true); + uint8_t *dest = (uint8_t *)BigBuf; + int idx=0; + uint32_t code=0, code2=0; + uint8_t version=0; + uint8_t facilitycode=0; + uint16_t number=0; + // Configure to go in 125Khz listen mode + LFSetupFPGAForADC(95, true); - while(!BUTTON_PRESS()) { - WDT_HIT(); - if (ledcontrol) LED_A_ON(); - DoAcquisition125k_internal(-1,true); - //fskdemod and get start index - WDT_HIT(); - idx = IOdemodFSK(dest,sizeof(BigBuf)); - if (idx>0){ - //valid tag found + while(!BUTTON_PRESS()) { + WDT_HIT(); + if (ledcontrol) LED_A_ON(); + DoAcquisition125k_internal(-1,true); + //fskdemod and get start index + WDT_HIT(); + idx = IOdemodFSK(dest,sizeof(BigBuf)); + if (idx>0){ + //valid tag found - //Index map - //0 10 20 30 40 50 60 - //| | | | | | | - //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23 - //----------------------------------------------------------------------------- - //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11 - // - //XSF(version)facility:codeone+codetwo - //Handle the data - if(findone){ //only print binary if we are doing one - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx], dest[idx+1], dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7],dest[idx+8]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15],dest[idx+16],dest[idx+17]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23],dest[idx+24],dest[idx+25],dest[idx+26]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31],dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39],dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44]); - Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+45],dest[idx+46],dest[idx+47],dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53]); - Dbprintf("%d%d%d%d%d%d%d%d %d%d",dest[idx+54],dest[idx+55],dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]); - } - code = bytebits_to_byte(dest+idx,32); - code2 = bytebits_to_byte(dest+idx+32,32); - version = bytebits_to_byte(dest+idx+27,8); //14,4 - facilitycode = bytebits_to_byte(dest+idx+18,8) ; - number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9 + //Index map + //0 10 20 30 40 50 60 + //| | | | | | | + //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23 + //----------------------------------------------------------------------------- + //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11 + // + //XSF(version)facility:codeone+codetwo + //Handle the data + if(findone){ //only print binary if we are doing one + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx], dest[idx+1], dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7],dest[idx+8]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15],dest[idx+16],dest[idx+17]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23],dest[idx+24],dest[idx+25],dest[idx+26]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31],dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39],dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44]); + Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+45],dest[idx+46],dest[idx+47],dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53]); + Dbprintf("%d%d%d%d%d%d%d%d %d%d",dest[idx+54],dest[idx+55],dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]); + } + code = bytebits_to_byte(dest+idx,32); + code2 = bytebits_to_byte(dest+idx+32,32); + version = bytebits_to_byte(dest+idx+27,8); //14,4 + facilitycode = bytebits_to_byte(dest+idx+18,8) ; + number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9 - Dbprintf("XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2); - // if we're only looking for one tag - if (findone){ - if (ledcontrol) LED_A_OFF(); - //LED_A_OFF(); - return; - } - code=code2=0; - version=facilitycode=0; - number=0; - idx=0; - } - WDT_HIT(); - } - DbpString("Stopped"); - if (ledcontrol) LED_A_OFF(); + Dbprintf("XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2); + // if we're only looking for one tag + if (findone){ + if (ledcontrol) LED_A_OFF(); + //LED_A_OFF(); + return; + } + code=code2=0; + version=facilitycode=0; + number=0; + idx=0; + } + WDT_HIT(); + } + DbpString("Stopped"); + if (ledcontrol) LED_A_OFF(); } /*------------------------------ @@ -907,321 +899,321 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) // Write one bit to card void T55xxWriteBit(int bit) { - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - if (bit == 0) - SpinDelayUs(WRITE_0); - else - SpinDelayUs(WRITE_1); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelayUs(WRITE_GAP); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + if (bit == 0) + SpinDelayUs(WRITE_0); + else + SpinDelayUs(WRITE_1); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelayUs(WRITE_GAP); } // Write one card block in page 0, no lock void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode) { - //unsigned int i; //enio adjustment 12/10/14 - uint32_t i; + //unsigned int i; //enio adjustment 12/10/14 + uint32_t i; - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // Give it a bit of time for the resonant antenna to settle. - // And for the tag to fully power up - SpinDelay(150); + // Give it a bit of time for the resonant antenna to settle. + // And for the tag to fully power up + SpinDelay(150); - // Now start writting - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelayUs(START_GAP); + // Now start writting + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelayUs(START_GAP); - // Opcode - T55xxWriteBit(1); - T55xxWriteBit(0); //Page 0 - if (PwdMode == 1){ - // Pwd - for (i = 0x80000000; i != 0; i >>= 1) - T55xxWriteBit(Pwd & i); - } - // Lock bit - T55xxWriteBit(0); + // Opcode + T55xxWriteBit(1); + T55xxWriteBit(0); //Page 0 + if (PwdMode == 1){ + // Pwd + for (i = 0x80000000; i != 0; i >>= 1) + T55xxWriteBit(Pwd & i); + } + // Lock bit + T55xxWriteBit(0); - // Data - for (i = 0x80000000; i != 0; i >>= 1) - T55xxWriteBit(Data & i); + // Data + for (i = 0x80000000; i != 0; i >>= 1) + T55xxWriteBit(Data & i); - // Block - for (i = 0x04; i != 0; i >>= 1) - T55xxWriteBit(Block & i); + // Block + for (i = 0x04; i != 0; i >>= 1) + T55xxWriteBit(Block & i); - // Now perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550, - // so wait a little more) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - SpinDelay(20); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + // Now perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550, + // so wait a little more) + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + SpinDelay(20); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); } // Read one card block in page 0 void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode) { - uint8_t *dest = (uint8_t *)BigBuf; - //int m=0, i=0; //enio adjustment 12/10/14 - uint32_t m=0, i=0; - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - m = sizeof(BigBuf); - // Clear destination buffer before sending the command - memset(dest, 128, m); - // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); + uint8_t *dest = (uint8_t *)BigBuf; + //int m=0, i=0; //enio adjustment 12/10/14 + uint32_t m=0, i=0; + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + m = sizeof(BigBuf); + // Clear destination buffer before sending the command + memset(dest, 128, m); + // Connect the A/D to the peak-detected low-frequency path. + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); - LED_D_ON(); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + LED_D_ON(); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // Give it a bit of time for the resonant antenna to settle. - // And for the tag to fully power up - SpinDelay(150); + // Give it a bit of time for the resonant antenna to settle. + // And for the tag to fully power up + SpinDelay(150); - // Now start writting - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelayUs(START_GAP); + // Now start writting + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelayUs(START_GAP); - // Opcode - T55xxWriteBit(1); - T55xxWriteBit(0); //Page 0 - if (PwdMode == 1){ - // Pwd - for (i = 0x80000000; i != 0; i >>= 1) - T55xxWriteBit(Pwd & i); - } - // Lock bit - T55xxWriteBit(0); - // Block - for (i = 0x04; i != 0; i >>= 1) - T55xxWriteBit(Block & i); + // Opcode + T55xxWriteBit(1); + T55xxWriteBit(0); //Page 0 + if (PwdMode == 1){ + // Pwd + for (i = 0x80000000; i != 0; i >>= 1) + T55xxWriteBit(Pwd & i); + } + // Lock bit + T55xxWriteBit(0); + // Block + for (i = 0x04; i != 0; i >>= 1) + T55xxWriteBit(Block & i); - // Turn field on to read the response - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + // Turn field on to read the response + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // Now do the acquisition - i = 0; - for(;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - // we don't care about actual value, only if it's more or less than a - // threshold essentially we capture zero crossings for later analysis - // if(dest[i] < 127) dest[i] = 0; else dest[i] = 1; - i++; - if (i >= m) break; - } - } + // Now do the acquisition + i = 0; + for(;;) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0x43; + } + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + // we don't care about actual value, only if it's more or less than a + // threshold essentially we capture zero crossings for later analysis + // if(dest[i] < 127) dest[i] = 0; else dest[i] = 1; + i++; + if (i >= m) break; + } + } - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); - DbpString("DONE!"); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + LED_D_OFF(); + DbpString("DONE!"); } // Read card traceability data (page 1) void T55xxReadTrace(void){ - uint8_t *dest = (uint8_t *)BigBuf; - int m=0, i=0; + uint8_t *dest = (uint8_t *)BigBuf; + int m=0, i=0; - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - m = sizeof(BigBuf); - // Clear destination buffer before sending the command - memset(dest, 128, m); - // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + m = sizeof(BigBuf); + // Clear destination buffer before sending the command + memset(dest, 128, m); + // Connect the A/D to the peak-detected low-frequency path. + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); - LED_D_ON(); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + LED_D_ON(); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // Give it a bit of time for the resonant antenna to settle. - // And for the tag to fully power up - SpinDelay(150); + // Give it a bit of time for the resonant antenna to settle. + // And for the tag to fully power up + SpinDelay(150); - // Now start writting - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelayUs(START_GAP); + // Now start writting + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelayUs(START_GAP); - // Opcode - T55xxWriteBit(1); - T55xxWriteBit(1); //Page 1 + // Opcode + T55xxWriteBit(1); + T55xxWriteBit(1); //Page 1 - // Turn field on to read the response - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + // Turn field on to read the response + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // Now do the acquisition - i = 0; - for(;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - i++; - if (i >= m) break; - } - } + // Now do the acquisition + i = 0; + for(;;) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0x43; + } + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + i++; + if (i >= m) break; + } + } - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); - DbpString("DONE!"); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + LED_D_OFF(); + DbpString("DONE!"); } /*-------------- Cloning routines -----------*/ // Copy HID id to card and setup block 0 config void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT) { - int data1=0, data2=0, data3=0, data4=0, data5=0, data6=0; //up to six blocks for long format - int last_block = 0; + int data1=0, data2=0, data3=0, data4=0, data5=0, data6=0; //up to six blocks for long format + int last_block = 0; - if (longFMT){ - // Ensure no more than 84 bits supplied - if (hi2>0xFFFFF) { - DbpString("Tags can only have 84 bits."); - return; - } - // Build the 6 data blocks for supplied 84bit ID - last_block = 6; - data1 = 0x1D96A900; // load preamble (1D) & long format identifier (9E manchester encoded) - for (int i=0;i<4;i++) { - if (hi2 & (1<<(19-i))) - data1 |= (1<<(((3-i)*2)+1)); // 1 -> 10 - else - data1 |= (1<<((3-i)*2)); // 0 -> 01 - } + if (longFMT){ + // Ensure no more than 84 bits supplied + if (hi2>0xFFFFF) { + DbpString("Tags can only have 84 bits."); + return; + } + // Build the 6 data blocks for supplied 84bit ID + last_block = 6; + data1 = 0x1D96A900; // load preamble (1D) & long format identifier (9E manchester encoded) + for (int i=0;i<4;i++) { + if (hi2 & (1<<(19-i))) + data1 |= (1<<(((3-i)*2)+1)); // 1 -> 10 + else + data1 |= (1<<((3-i)*2)); // 0 -> 01 + } - data2 = 0; - for (int i=0;i<16;i++) { - if (hi2 & (1<<(15-i))) - data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data2 |= (1<<((15-i)*2)); // 0 -> 01 - } + data2 = 0; + for (int i=0;i<16;i++) { + if (hi2 & (1<<(15-i))) + data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data2 |= (1<<((15-i)*2)); // 0 -> 01 + } - data3 = 0; - for (int i=0;i<16;i++) { - if (hi & (1<<(31-i))) - data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data3 |= (1<<((15-i)*2)); // 0 -> 01 - } + data3 = 0; + for (int i=0;i<16;i++) { + if (hi & (1<<(31-i))) + data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data3 |= (1<<((15-i)*2)); // 0 -> 01 + } - data4 = 0; - for (int i=0;i<16;i++) { - if (hi & (1<<(15-i))) - data4 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data4 |= (1<<((15-i)*2)); // 0 -> 01 - } + data4 = 0; + for (int i=0;i<16;i++) { + if (hi & (1<<(15-i))) + data4 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data4 |= (1<<((15-i)*2)); // 0 -> 01 + } - data5 = 0; - for (int i=0;i<16;i++) { - if (lo & (1<<(31-i))) - data5 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data5 |= (1<<((15-i)*2)); // 0 -> 01 - } + data5 = 0; + for (int i=0;i<16;i++) { + if (lo & (1<<(31-i))) + data5 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data5 |= (1<<((15-i)*2)); // 0 -> 01 + } - data6 = 0; - for (int i=0;i<16;i++) { - if (lo & (1<<(15-i))) - data6 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data6 |= (1<<((15-i)*2)); // 0 -> 01 - } - } - else { - // Ensure no more than 44 bits supplied - if (hi>0xFFF) { - DbpString("Tags can only have 44 bits."); - return; - } + data6 = 0; + for (int i=0;i<16;i++) { + if (lo & (1<<(15-i))) + data6 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data6 |= (1<<((15-i)*2)); // 0 -> 01 + } + } + else { + // Ensure no more than 44 bits supplied + if (hi>0xFFF) { + DbpString("Tags can only have 44 bits."); + return; + } - // Build the 3 data blocks for supplied 44bit ID - last_block = 3; + // Build the 3 data blocks for supplied 44bit ID + last_block = 3; - data1 = 0x1D000000; // load preamble + data1 = 0x1D000000; // load preamble - for (int i=0;i<12;i++) { - if (hi & (1<<(11-i))) - data1 |= (1<<(((11-i)*2)+1)); // 1 -> 10 - else - data1 |= (1<<((11-i)*2)); // 0 -> 01 - } + for (int i=0;i<12;i++) { + if (hi & (1<<(11-i))) + data1 |= (1<<(((11-i)*2)+1)); // 1 -> 10 + else + data1 |= (1<<((11-i)*2)); // 0 -> 01 + } - data2 = 0; - for (int i=0;i<16;i++) { - if (lo & (1<<(31-i))) - data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data2 |= (1<<((15-i)*2)); // 0 -> 01 - } + data2 = 0; + for (int i=0;i<16;i++) { + if (lo & (1<<(31-i))) + data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data2 |= (1<<((15-i)*2)); // 0 -> 01 + } - data3 = 0; - for (int i=0;i<16;i++) { - if (lo & (1<<(15-i))) - data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10 - else - data3 |= (1<<((15-i)*2)); // 0 -> 01 - } - } + data3 = 0; + for (int i=0;i<16;i++) { + if (lo & (1<<(15-i))) + data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10 + else + data3 |= (1<<((15-i)*2)); // 0 -> 01 + } + } - LED_D_ON(); - // Program the data blocks for supplied ID - // and the block 0 for HID format - T55xxWriteBlock(data1,1,0,0); - T55xxWriteBlock(data2,2,0,0); - T55xxWriteBlock(data3,3,0,0); + LED_D_ON(); + // Program the data blocks for supplied ID + // and the block 0 for HID format + T55xxWriteBlock(data1,1,0,0); + T55xxWriteBlock(data2,2,0,0); + T55xxWriteBlock(data3,3,0,0); - if (longFMT) { // if long format there are 6 blocks - T55xxWriteBlock(data4,4,0,0); - T55xxWriteBlock(data5,5,0,0); - T55xxWriteBlock(data6,6,0,0); - } + if (longFMT) { // if long format there are 6 blocks + T55xxWriteBlock(data4,4,0,0); + T55xxWriteBlock(data5,5,0,0); + T55xxWriteBlock(data6,6,0,0); + } - // Config for HID (RF/50, FSK2a, Maxblock=3 for short/6 for long) - T55xxWriteBlock(T55x7_BITRATE_RF_50 | - T55x7_MODULATION_FSK2a | - last_block << T55x7_MAXBLOCK_SHIFT, - 0,0,0); + // Config for HID (RF/50, FSK2a, Maxblock=3 for short/6 for long) + T55xxWriteBlock(T55x7_BITRATE_RF_50 | + T55x7_MODULATION_FSK2a | + last_block << T55x7_MAXBLOCK_SHIFT, + 0,0,0); - LED_D_OFF(); + LED_D_OFF(); - DbpString("DONE!"); + DbpString("DONE!"); } void CopyIOtoT55x7(uint32_t hi, uint32_t lo, uint8_t longFMT) { - int data1=0, data2=0; //up to six blocks for long format + int data1=0, data2=0; //up to six blocks for long format - data1 = hi; // load preamble - data2 = lo; - - LED_D_ON(); - // Program the data blocks for supplied ID - // and the block 0 for HID format - T55xxWriteBlock(data1,1,0,0); - T55xxWriteBlock(data2,2,0,0); + data1 = hi; // load preamble + data2 = lo; - //Config Block - T55xxWriteBlock(0x00147040,0,0,0); - LED_D_OFF(); + LED_D_ON(); + // Program the data blocks for supplied ID + // and the block 0 for HID format + T55xxWriteBlock(data1,1,0,0); + T55xxWriteBlock(data2,2,0,0); - DbpString("DONE!"); + //Config Block + T55xxWriteBlock(0x00147040,0,0,0); + LED_D_OFF(); + + DbpString("DONE!"); } // Define 9bit header for EM410x tags @@ -1230,151 +1222,151 @@ void CopyIOtoT55x7(uint32_t hi, uint32_t lo, uint8_t longFMT) void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo) { - int i, id_bit; - uint64_t id = EM410X_HEADER; - uint64_t rev_id = 0; // reversed ID - int c_parity[4]; // column parity - int r_parity = 0; // row parity - uint32_t clock = 0; + int i, id_bit; + uint64_t id = EM410X_HEADER; + uint64_t rev_id = 0; // reversed ID + int c_parity[4]; // column parity + int r_parity = 0; // row parity + uint32_t clock = 0; - // Reverse ID bits given as parameter (for simpler operations) - for (i = 0; i < EM410X_ID_LENGTH; ++i) { - if (i < 32) { - rev_id = (rev_id << 1) | (id_lo & 1); - id_lo >>= 1; - } else { - rev_id = (rev_id << 1) | (id_hi & 1); - id_hi >>= 1; - } - } + // Reverse ID bits given as parameter (for simpler operations) + for (i = 0; i < EM410X_ID_LENGTH; ++i) { + if (i < 32) { + rev_id = (rev_id << 1) | (id_lo & 1); + id_lo >>= 1; + } else { + rev_id = (rev_id << 1) | (id_hi & 1); + id_hi >>= 1; + } + } - for (i = 0; i < EM410X_ID_LENGTH; ++i) { - id_bit = rev_id & 1; + for (i = 0; i < EM410X_ID_LENGTH; ++i) { + id_bit = rev_id & 1; - if (i % 4 == 0) { - // Don't write row parity bit at start of parsing - if (i) - id = (id << 1) | r_parity; - // Start counting parity for new row - r_parity = id_bit; - } else { - // Count row parity - r_parity ^= id_bit; - } + if (i % 4 == 0) { + // Don't write row parity bit at start of parsing + if (i) + id = (id << 1) | r_parity; + // Start counting parity for new row + r_parity = id_bit; + } else { + // Count row parity + r_parity ^= id_bit; + } - // First elements in column? - if (i < 4) - // Fill out first elements - c_parity[i] = id_bit; - else - // Count column parity - c_parity[i % 4] ^= id_bit; + // First elements in column? + if (i < 4) + // Fill out first elements + c_parity[i] = id_bit; + else + // Count column parity + c_parity[i % 4] ^= id_bit; - // Insert ID bit - id = (id << 1) | id_bit; - rev_id >>= 1; - } + // Insert ID bit + id = (id << 1) | id_bit; + rev_id >>= 1; + } - // Insert parity bit of last row - id = (id << 1) | r_parity; + // Insert parity bit of last row + id = (id << 1) | r_parity; - // Fill out column parity at the end of tag - for (i = 0; i < 4; ++i) - id = (id << 1) | c_parity[i]; + // Fill out column parity at the end of tag + for (i = 0; i < 4; ++i) + id = (id << 1) | c_parity[i]; - // Add stop bit - id <<= 1; + // Add stop bit + id <<= 1; - Dbprintf("Started writing %s tag ...", card ? "T55x7":"T5555"); - LED_D_ON(); + Dbprintf("Started writing %s tag ...", card ? "T55x7":"T5555"); + LED_D_ON(); - // Write EM410x ID - T55xxWriteBlock((uint32_t)(id >> 32), 1, 0, 0); - T55xxWriteBlock((uint32_t)id, 2, 0, 0); + // Write EM410x ID + T55xxWriteBlock((uint32_t)(id >> 32), 1, 0, 0); + T55xxWriteBlock((uint32_t)id, 2, 0, 0); - // Config for EM410x (RF/64, Manchester, Maxblock=2) - if (card) { - // Clock rate is stored in bits 8-15 of the card value - clock = (card & 0xFF00) >> 8; - Dbprintf("Clock rate: %d", clock); - switch (clock) - { - case 32: - clock = T55x7_BITRATE_RF_32; - break; - case 16: - clock = T55x7_BITRATE_RF_16; - break; - case 0: - // A value of 0 is assumed to be 64 for backwards-compatibility - // Fall through... - case 64: - clock = T55x7_BITRATE_RF_64; - break; - default: - Dbprintf("Invalid clock rate: %d", clock); - return; - } + // Config for EM410x (RF/64, Manchester, Maxblock=2) + if (card) { + // Clock rate is stored in bits 8-15 of the card value + clock = (card & 0xFF00) >> 8; + Dbprintf("Clock rate: %d", clock); + switch (clock) + { + case 32: + clock = T55x7_BITRATE_RF_32; + break; + case 16: + clock = T55x7_BITRATE_RF_16; + break; + case 0: + // A value of 0 is assumed to be 64 for backwards-compatibility + // Fall through... + case 64: + clock = T55x7_BITRATE_RF_64; + break; + default: + Dbprintf("Invalid clock rate: %d", clock); + return; + } - // Writing configuration for T55x7 tag - T55xxWriteBlock(clock | - T55x7_MODULATION_MANCHESTER | - 2 << T55x7_MAXBLOCK_SHIFT, - 0, 0, 0); - } - else - // Writing configuration for T5555(Q5) tag - T55xxWriteBlock(0x1F << T5555_BITRATE_SHIFT | - T5555_MODULATION_MANCHESTER | - 2 << T5555_MAXBLOCK_SHIFT, - 0, 0, 0); + // Writing configuration for T55x7 tag + T55xxWriteBlock(clock | + T55x7_MODULATION_MANCHESTER | + 2 << T55x7_MAXBLOCK_SHIFT, + 0, 0, 0); + } + else + // Writing configuration for T5555(Q5) tag + T55xxWriteBlock(0x1F << T5555_BITRATE_SHIFT | + T5555_MODULATION_MANCHESTER | + 2 << T5555_MAXBLOCK_SHIFT, + 0, 0, 0); - LED_D_OFF(); - Dbprintf("Tag %s written with 0x%08x%08x\n", card ? "T55x7":"T5555", - (uint32_t)(id >> 32), (uint32_t)id); + LED_D_OFF(); + Dbprintf("Tag %s written with 0x%08x%08x\n", card ? "T55x7":"T5555", + (uint32_t)(id >> 32), (uint32_t)id); } // Clone Indala 64-bit tag by UID to T55x7 void CopyIndala64toT55x7(int hi, int lo) { - //Program the 2 data blocks for supplied 64bit UID - // and the block 0 for Indala64 format - T55xxWriteBlock(hi,1,0,0); - T55xxWriteBlock(lo,2,0,0); - //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=2) - T55xxWriteBlock(T55x7_BITRATE_RF_32 | - T55x7_MODULATION_PSK1 | - 2 << T55x7_MAXBLOCK_SHIFT, - 0, 0, 0); - //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data) - // T5567WriteBlock(0x603E1042,0); + //Program the 2 data blocks for supplied 64bit UID + // and the block 0 for Indala64 format + T55xxWriteBlock(hi,1,0,0); + T55xxWriteBlock(lo,2,0,0); + //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=2) + T55xxWriteBlock(T55x7_BITRATE_RF_32 | + T55x7_MODULATION_PSK1 | + 2 << T55x7_MAXBLOCK_SHIFT, + 0, 0, 0); + //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data) + // T5567WriteBlock(0x603E1042,0); - DbpString("DONE!"); + DbpString("DONE!"); -} +} void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int uid6, int uid7) { - //Program the 7 data blocks for supplied 224bit UID - // and the block 0 for Indala224 format - T55xxWriteBlock(uid1,1,0,0); - T55xxWriteBlock(uid2,2,0,0); - T55xxWriteBlock(uid3,3,0,0); - T55xxWriteBlock(uid4,4,0,0); - T55xxWriteBlock(uid5,5,0,0); - T55xxWriteBlock(uid6,6,0,0); - T55xxWriteBlock(uid7,7,0,0); - //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=7) - T55xxWriteBlock(T55x7_BITRATE_RF_32 | - T55x7_MODULATION_PSK1 | - 7 << T55x7_MAXBLOCK_SHIFT, - 0,0,0); - //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data) - // T5567WriteBlock(0x603E10E2,0); + //Program the 7 data blocks for supplied 224bit UID + // and the block 0 for Indala224 format + T55xxWriteBlock(uid1,1,0,0); + T55xxWriteBlock(uid2,2,0,0); + T55xxWriteBlock(uid3,3,0,0); + T55xxWriteBlock(uid4,4,0,0); + T55xxWriteBlock(uid5,5,0,0); + T55xxWriteBlock(uid6,6,0,0); + T55xxWriteBlock(uid7,7,0,0); + //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=7) + T55xxWriteBlock(T55x7_BITRATE_RF_32 | + T55x7_MODULATION_PSK1 | + 7 << T55x7_MAXBLOCK_SHIFT, + 0,0,0); + //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data) + // T5567WriteBlock(0x603E10E2,0); - DbpString("DONE!"); + DbpString("DONE!"); } @@ -1383,261 +1375,261 @@ void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int #define max(x,y) ( x GraphBuffer[0]) { - while(i < GraphTraceLen) { - if( !(GraphBuffer[i] > GraphBuffer[i-1]) && GraphBuffer[i] > lmax) - break; - i++; - } - dir = 0; - } - else { - while(i < GraphTraceLen) { - if( !(GraphBuffer[i] < GraphBuffer[i-1]) && GraphBuffer[i] < lmin) - break; - i++; - } - dir = 1; - } + /* Find first local max/min */ + if(GraphBuffer[1] > GraphBuffer[0]) { + while(i < GraphTraceLen) { + if( !(GraphBuffer[i] > GraphBuffer[i-1]) && GraphBuffer[i] > lmax) + break; + i++; + } + dir = 0; + } + else { + while(i < GraphTraceLen) { + if( !(GraphBuffer[i] < GraphBuffer[i-1]) && GraphBuffer[i] < lmin) + break; + i++; + } + dir = 1; + } - lastval = i++; - half_switch = 0; - pmc = 0; - block_done = 0; + lastval = i++; + half_switch = 0; + pmc = 0; + block_done = 0; - for (bitidx = 0; i < GraphTraceLen; i++) - { - if ( (GraphBuffer[i-1] > GraphBuffer[i] && dir == 1 && GraphBuffer[i] > lmax) || (GraphBuffer[i-1] < GraphBuffer[i] && dir == 0 && GraphBuffer[i] < lmin)) - { - lc = i - lastval; - lastval = i; + for (bitidx = 0; i < GraphTraceLen; i++) + { + if ( (GraphBuffer[i-1] > GraphBuffer[i] && dir == 1 && GraphBuffer[i] > lmax) || (GraphBuffer[i-1] < GraphBuffer[i] && dir == 0 && GraphBuffer[i] < lmin)) + { + lc = i - lastval; + lastval = i; - // Switch depending on lc length: - // Tolerance is 1/8 of clock rate (arbitrary) - if (abs(lc-clock/4) < tolerance) { - // 16T0 - if((i - pmc) == lc) { /* 16T0 was previous one */ - /* It's a PMC ! */ - i += (128+127+16+32+33+16)-1; - lastval = i; - pmc = 0; - block_done = 1; - } - else { - pmc = i; - } - } else if (abs(lc-clock/2) < tolerance) { - // 32TO - if((i - pmc) == lc) { /* 16T0 was previous one */ - /* It's a PMC ! */ - i += (128+127+16+32+33)-1; - lastval = i; - pmc = 0; - block_done = 1; - } - else if(half_switch == 1) { - BitStream[bitidx++] = 0; - half_switch = 0; - } - else - half_switch++; - } else if (abs(lc-clock) < tolerance) { - // 64TO - BitStream[bitidx++] = 1; - } else { - // Error - warnings++; - if (warnings > 10) - { - Dbprintf("Error: too many detection errors, aborting."); - return 0; - } - } + // Switch depending on lc length: + // Tolerance is 1/8 of clock rate (arbitrary) + if (abs(lc-clock/4) < tolerance) { + // 16T0 + if((i - pmc) == lc) { /* 16T0 was previous one */ + /* It's a PMC ! */ + i += (128+127+16+32+33+16)-1; + lastval = i; + pmc = 0; + block_done = 1; + } + else { + pmc = i; + } + } else if (abs(lc-clock/2) < tolerance) { + // 32TO + if((i - pmc) == lc) { /* 16T0 was previous one */ + /* It's a PMC ! */ + i += (128+127+16+32+33)-1; + lastval = i; + pmc = 0; + block_done = 1; + } + else if(half_switch == 1) { + BitStream[bitidx++] = 0; + half_switch = 0; + } + else + half_switch++; + } else if (abs(lc-clock) < tolerance) { + // 64TO + BitStream[bitidx++] = 1; + } else { + // Error + warnings++; + if (warnings > 10) + { + Dbprintf("Error: too many detection errors, aborting."); + return 0; + } + } - if(block_done == 1) { - if(bitidx == 128) { - for(j=0; j<16; j++) { - Blocks[num_blocks][j] = 128*BitStream[j*8+7]+ - 64*BitStream[j*8+6]+ - 32*BitStream[j*8+5]+ - 16*BitStream[j*8+4]+ - 8*BitStream[j*8+3]+ - 4*BitStream[j*8+2]+ - 2*BitStream[j*8+1]+ - BitStream[j*8]; - } - num_blocks++; - } - bitidx = 0; - block_done = 0; - half_switch = 0; - } - if(i < GraphTraceLen) - { - if (GraphBuffer[i-1] > GraphBuffer[i]) dir=0; - else dir = 1; - } - } - if(bitidx==255) - bitidx=0; - warnings = 0; - if(num_blocks == 4) break; - } - memcpy(outBlocks, Blocks, 16*num_blocks); - return num_blocks; + if(block_done == 1) { + if(bitidx == 128) { + for(j=0; j<16; j++) { + Blocks[num_blocks][j] = 128*BitStream[j*8+7]+ + 64*BitStream[j*8+6]+ + 32*BitStream[j*8+5]+ + 16*BitStream[j*8+4]+ + 8*BitStream[j*8+3]+ + 4*BitStream[j*8+2]+ + 2*BitStream[j*8+1]+ + BitStream[j*8]; + } + num_blocks++; + } + bitidx = 0; + block_done = 0; + half_switch = 0; + } + if(i < GraphTraceLen) + { + if (GraphBuffer[i-1] > GraphBuffer[i]) dir=0; + else dir = 1; + } + } + if(bitidx==255) + bitidx=0; + warnings = 0; + if(num_blocks == 4) break; + } + memcpy(outBlocks, Blocks, 16*num_blocks); + return num_blocks; } int IsBlock0PCF7931(uint8_t *Block) { - // Assume RFU means 0 :) - if((memcmp(Block, "\x00\x00\x00\x00\x00\x00\x00\x01", 8) == 0) && memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) // PAC enabled - return 1; - if((memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) && Block[7] == 0) // PAC disabled, can it *really* happen ? - return 1; - return 0; + // Assume RFU means 0 :) + if((memcmp(Block, "\x00\x00\x00\x00\x00\x00\x00\x01", 8) == 0) && memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) // PAC enabled + return 1; + if((memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) && Block[7] == 0) // PAC disabled, can it *really* happen ? + return 1; + return 0; } int IsBlock1PCF7931(uint8_t *Block) { - // Assume RFU means 0 :) - if(Block[10] == 0 && Block[11] == 0 && Block[12] == 0 && Block[13] == 0) - if((Block[14] & 0x7f) <= 9 && Block[15] <= 9) - return 1; + // Assume RFU means 0 :) + if(Block[10] == 0 && Block[11] == 0 && Block[12] == 0 && Block[13] == 0) + if((Block[14] & 0x7f) <= 9 && Block[15] <= 9) + return 1; - return 0; + return 0; } #define ALLOC 16 void ReadPCF7931() { - uint8_t Blocks[8][17]; - uint8_t tmpBlocks[4][16]; - int i, j, ind, ind2, n; - int num_blocks = 0; - int max_blocks = 8; - int ident = 0; - int error = 0; - int tries = 0; + uint8_t Blocks[8][17]; + uint8_t tmpBlocks[4][16]; + int i, j, ind, ind2, n; + int num_blocks = 0; + int max_blocks = 8; + int ident = 0; + int error = 0; + int tries = 0; - memset(Blocks, 0, 8*17*sizeof(uint8_t)); + memset(Blocks, 0, 8*17*sizeof(uint8_t)); - do { - memset(tmpBlocks, 0, 4*16*sizeof(uint8_t)); - n = DemodPCF7931((uint8_t**)tmpBlocks); - if(!n) - error++; - if(error==10 && num_blocks == 0) { - Dbprintf("Error, no tag or bad tag"); - return; - } - else if (tries==20 || error==10) { - Dbprintf("Error reading the tag"); - Dbprintf("Here is the partial content"); - goto end; - } + do { + memset(tmpBlocks, 0, 4*16*sizeof(uint8_t)); + n = DemodPCF7931((uint8_t**)tmpBlocks); + if(!n) + error++; + if(error==10 && num_blocks == 0) { + Dbprintf("Error, no tag or bad tag"); + return; + } + else if (tries==20 || error==10) { + Dbprintf("Error reading the tag"); + Dbprintf("Here is the partial content"); + goto end; + } - for(i=0; i= 0; ind--,ind2--) { - if(ind2 < 0) - ind2 = max_blocks; - if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found - // Dbprintf("Tmp %d -> Block %d", ind, ind2); - memcpy(Blocks[ind2], tmpBlocks[ind], 16); - Blocks[ind2][ALLOC] = 1; - num_blocks++; - if(num_blocks == max_blocks) goto end; - } - } - for(ind=i+1,ind2=j+1; ind < n; ind++,ind2++) { - if(ind2 > max_blocks) - ind2 = 0; - if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found - // Dbprintf("Tmp %d -> Block %d", ind, ind2); - memcpy(Blocks[ind2], tmpBlocks[ind], 16); - Blocks[ind2][ALLOC] = 1; - num_blocks++; - if(num_blocks == max_blocks) goto end; - } - } - } - } - } - } - } - tries++; - if (BUTTON_PRESS()) return; - } while (num_blocks != max_blocks); + for(i=0; i= 0; ind--,ind2--) { + if(ind2 < 0) + ind2 = max_blocks; + if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found + // Dbprintf("Tmp %d -> Block %d", ind, ind2); + memcpy(Blocks[ind2], tmpBlocks[ind], 16); + Blocks[ind2][ALLOC] = 1; + num_blocks++; + if(num_blocks == max_blocks) goto end; + } + } + for(ind=i+1,ind2=j+1; ind < n; ind++,ind2++) { + if(ind2 > max_blocks) + ind2 = 0; + if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found + // Dbprintf("Tmp %d -> Block %d", ind, ind2); + memcpy(Blocks[ind2], tmpBlocks[ind], 16); + Blocks[ind2][ALLOC] = 1; + num_blocks++; + if(num_blocks == max_blocks) goto end; + } + } + } + } + } + } + } + tries++; + if (BUTTON_PRESS()) return; + } while (num_blocks != max_blocks); end: - Dbprintf("-----------------------------------------"); - Dbprintf("Memory content:"); - Dbprintf("-----------------------------------------"); - for(i=0; i", i); - } - Dbprintf("-----------------------------------------"); + Dbprintf("-----------------------------------------"); + Dbprintf("Memory content:"); + Dbprintf("-----------------------------------------"); + for(i=0; i", i); + } + Dbprintf("-----------------------------------------"); - return ; + return ; } @@ -1661,20 +1653,20 @@ uint8_t * fwd_write_ptr; //forwardlink bit pointer //==================================================================== //-------------------------------------------------------------------- uint8_t Prepare_Cmd( uint8_t cmd ) { - //-------------------------------------------------------------------- + //-------------------------------------------------------------------- - *forward_ptr++ = 0; //start bit - *forward_ptr++ = 0; //second pause for 4050 code + *forward_ptr++ = 0; //start bit + *forward_ptr++ = 0; //second pause for 4050 code - *forward_ptr++ = cmd; - cmd >>= 1; - *forward_ptr++ = cmd; - cmd >>= 1; - *forward_ptr++ = cmd; - cmd >>= 1; - *forward_ptr++ = cmd; + *forward_ptr++ = cmd; + cmd >>= 1; + *forward_ptr++ = cmd; + cmd >>= 1; + *forward_ptr++ = cmd; + cmd >>= 1; + *forward_ptr++ = cmd; - return 6; //return number of emited bits + return 6; //return number of emited bits } //==================================================================== @@ -1684,21 +1676,21 @@ uint8_t Prepare_Cmd( uint8_t cmd ) { //-------------------------------------------------------------------- uint8_t Prepare_Addr( uint8_t addr ) { - //-------------------------------------------------------------------- + //-------------------------------------------------------------------- - register uint8_t line_parity; + register uint8_t line_parity; - uint8_t i; - line_parity = 0; - for(i=0;i<6;i++) { - *forward_ptr++ = addr; - line_parity ^= addr; - addr >>= 1; - } + uint8_t i; + line_parity = 0; + for(i=0;i<6;i++) { + *forward_ptr++ = addr; + line_parity ^= addr; + addr >>= 1; + } - *forward_ptr++ = (line_parity & 1); + *forward_ptr++ = (line_parity & 1); - return 7; //return number of emited bits + return 7; //return number of emited bits } //==================================================================== @@ -1708,36 +1700,36 @@ uint8_t Prepare_Addr( uint8_t addr ) { //-------------------------------------------------------------------- uint8_t Prepare_Data( uint16_t data_low, uint16_t data_hi) { - //-------------------------------------------------------------------- + //-------------------------------------------------------------------- - register uint8_t line_parity; - register uint8_t column_parity; - register uint8_t i, j; - register uint16_t data; + register uint8_t line_parity; + register uint8_t column_parity; + register uint8_t i, j; + register uint16_t data; - data = data_low; - column_parity = 0; + data = data_low; + column_parity = 0; - for(i=0; i<4; i++) { - line_parity = 0; - for(j=0; j<8; j++) { - line_parity ^= data; - column_parity ^= (data & 1) << j; - *forward_ptr++ = data; - data >>= 1; - } - *forward_ptr++ = line_parity; - if(i == 1) - data = data_hi; - } + for(i=0; i<4; i++) { + line_parity = 0; + for(j=0; j<8; j++) { + line_parity ^= data; + column_parity ^= (data & 1) << j; + *forward_ptr++ = data; + data >>= 1; + } + *forward_ptr++ = line_parity; + if(i == 1) + data = data_hi; + } - for(j=0; j<8; j++) { - *forward_ptr++ = column_parity; - column_parity >>= 1; - } - *forward_ptr = 0; + for(j=0; j<8; j++) { + *forward_ptr++ = column_parity; + column_parity >>= 1; + } + *forward_ptr = 0; - return 45; //return number of emited bits + return 45; //return number of emited bits } //==================================================================== @@ -1747,114 +1739,114 @@ uint8_t Prepare_Data( uint16_t data_low, uint16_t data_hi) { //==================================================================== void SendForward(uint8_t fwd_bit_count) { - fwd_write_ptr = forwardLink_data; - fwd_bit_sz = fwd_bit_count; + fwd_write_ptr = forwardLink_data; + fwd_bit_sz = fwd_bit_count; - LED_D_ON(); + LED_D_ON(); - //Field on - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + //Field on + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // Give it a bit of time for the resonant antenna to settle. - // And for the tag to fully power up - SpinDelay(150); + // Give it a bit of time for the resonant antenna to settle. + // And for the tag to fully power up + SpinDelay(150); - // force 1st mod pulse (start gap must be longer for 4305) - fwd_bit_sz--; //prepare next bit modulation - fwd_write_ptr++; - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - SpinDelayUs(55*8); //55 cycles off (8us each)for 4305 - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on - SpinDelayUs(16*8); //16 cycles on (8us each) + // force 1st mod pulse (start gap must be longer for 4305) + fwd_bit_sz--; //prepare next bit modulation + fwd_write_ptr++; + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + SpinDelayUs(55*8); //55 cycles off (8us each)for 4305 + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on + SpinDelayUs(16*8); //16 cycles on (8us each) - // now start writting - while(fwd_bit_sz-- > 0) { //prepare next bit modulation - if(((*fwd_write_ptr++) & 1) == 1) - SpinDelayUs(32*8); //32 cycles at 125Khz (8us each) - else { - //These timings work for 4469/4269/4305 (with the 55*8 above) - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - SpinDelayUs(23*8); //16-4 cycles off (8us each) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on - SpinDelayUs(9*8); //16 cycles on (8us each) - } - } + // now start writting + while(fwd_bit_sz-- > 0) { //prepare next bit modulation + if(((*fwd_write_ptr++) & 1) == 1) + SpinDelayUs(32*8); //32 cycles at 125Khz (8us each) + else { + //These timings work for 4469/4269/4305 (with the 55*8 above) + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + SpinDelayUs(23*8); //16-4 cycles off (8us each) + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on + SpinDelayUs(9*8); //16 cycles on (8us each) + } + } } void EM4xLogin(uint32_t Password) { - uint8_t fwd_bit_count; + uint8_t fwd_bit_count; - forward_ptr = forwardLink_data; - fwd_bit_count = Prepare_Cmd( FWD_CMD_LOGIN ); - fwd_bit_count += Prepare_Data( Password&0xFFFF, Password>>16 ); + forward_ptr = forwardLink_data; + fwd_bit_count = Prepare_Cmd( FWD_CMD_LOGIN ); + fwd_bit_count += Prepare_Data( Password&0xFFFF, Password>>16 ); - SendForward(fwd_bit_count); + SendForward(fwd_bit_count); - //Wait for command to complete - SpinDelay(20); + //Wait for command to complete + SpinDelay(20); } void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) { - uint8_t fwd_bit_count; - uint8_t *dest = (uint8_t *)BigBuf; - int m=0, i=0; + uint8_t fwd_bit_count; + uint8_t *dest = (uint8_t *)BigBuf; + int m=0, i=0; - //If password mode do login - if (PwdMode == 1) EM4xLogin(Pwd); + //If password mode do login + if (PwdMode == 1) EM4xLogin(Pwd); - forward_ptr = forwardLink_data; - fwd_bit_count = Prepare_Cmd( FWD_CMD_READ ); - fwd_bit_count += Prepare_Addr( Address ); + forward_ptr = forwardLink_data; + fwd_bit_count = Prepare_Cmd( FWD_CMD_READ ); + fwd_bit_count += Prepare_Addr( Address ); - m = sizeof(BigBuf); - // Clear destination buffer before sending the command - memset(dest, 128, m); - // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); + m = sizeof(BigBuf); + // Clear destination buffer before sending the command + memset(dest, 128, m); + // Connect the A/D to the peak-detected low-frequency path. + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); - SendForward(fwd_bit_count); + SendForward(fwd_bit_count); - // Now do the acquisition - i = 0; - for(;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - i++; - if (i >= m) break; - } - } - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); + // Now do the acquisition + i = 0; + for(;;) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0x43; + } + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + i++; + if (i >= m) break; + } + } + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + LED_D_OFF(); } void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode) { - uint8_t fwd_bit_count; + uint8_t fwd_bit_count; - //If password mode do login - if (PwdMode == 1) EM4xLogin(Pwd); + //If password mode do login + if (PwdMode == 1) EM4xLogin(Pwd); - forward_ptr = forwardLink_data; - fwd_bit_count = Prepare_Cmd( FWD_CMD_WRITE ); - fwd_bit_count += Prepare_Addr( Address ); - fwd_bit_count += Prepare_Data( Data&0xFFFF, Data>>16 ); + forward_ptr = forwardLink_data; + fwd_bit_count = Prepare_Cmd( FWD_CMD_WRITE ); + fwd_bit_count += Prepare_Addr( Address ); + fwd_bit_count += Prepare_Data( Data&0xFFFF, Data>>16 ); - SendForward(fwd_bit_count); + SendForward(fwd_bit_count); - //Wait for write to complete - SpinDelay(20); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); + //Wait for write to complete + SpinDelay(20); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + LED_D_OFF(); } diff --git a/client/cmddata.c b/client/cmddata.c index 4b5cb0401..bce5d2ced 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -27,82 +27,82 @@ static int CmdHelp(const char *Cmd); //set the demod buffer with given array of binary (one bit per byte) //by marshmellow -void setDemodBuf(uint8_t *buff,int size) +void setDemodBuf(uint8_t *buff,int size) { - int i=0; - for (; i < size; ++i){ - DemodBuffer[i]=buff[i]; - } - DemodBufferLen=size; - return; + int i=0; + for (; i < size; ++i){ + DemodBuffer[i]=buff[i]; + } + DemodBufferLen=size; + return; } //by marshmellow void printDemodBuff() { - uint32_t i = 0; - int bitLen = DemodBufferLen; - if (bitLen<16) { - PrintAndLog("no bits found in demod buffer"); - return; - } - if (bitLen>512) bitLen=512; //max output to 512 bits if we have more - should be plenty - for (i = 0; i <= (bitLen-16); i+=16) { - PrintAndLog("%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i", - DemodBuffer[i], - DemodBuffer[i+1], - DemodBuffer[i+2], - DemodBuffer[i+3], - DemodBuffer[i+4], - DemodBuffer[i+5], - DemodBuffer[i+6], - DemodBuffer[i+7], - DemodBuffer[i+8], - DemodBuffer[i+9], - DemodBuffer[i+10], - DemodBuffer[i+11], - DemodBuffer[i+12], - DemodBuffer[i+13], - DemodBuffer[i+14], - DemodBuffer[i+15]); - } - return; + uint32_t i = 0; + int bitLen = DemodBufferLen; + if (bitLen<16) { + PrintAndLog("no bits found in demod buffer"); + return; + } + if (bitLen>512) bitLen=512; //max output to 512 bits if we have more - should be plenty + for (i = 0; i <= (bitLen-16); i+=16) { + PrintAndLog("%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i", + DemodBuffer[i], + DemodBuffer[i+1], + DemodBuffer[i+2], + DemodBuffer[i+3], + DemodBuffer[i+4], + DemodBuffer[i+5], + DemodBuffer[i+6], + DemodBuffer[i+7], + DemodBuffer[i+8], + DemodBuffer[i+9], + DemodBuffer[i+10], + DemodBuffer[i+11], + DemodBuffer[i+12], + DemodBuffer[i+13], + DemodBuffer[i+14], + DemodBuffer[i+15]); + } + return; } int CmdAmp(const char *Cmd) { - int i, rising, falling; - int max = INT_MIN, min = INT_MAX; + int i, rising, falling; + int max = INT_MIN, min = INT_MAX; - for (i = 10; i < GraphTraceLen; ++i) { - if (GraphBuffer[i] > max) - max = GraphBuffer[i]; - if (GraphBuffer[i] < min) - min = GraphBuffer[i]; - } + for (i = 10; i < GraphTraceLen; ++i) { + if (GraphBuffer[i] > max) + max = GraphBuffer[i]; + if (GraphBuffer[i] < min) + min = GraphBuffer[i]; + } - if (max != min) { - rising = falling= 0; - for (i = 0; i < GraphTraceLen; ++i) { - if (GraphBuffer[i + 1] < GraphBuffer[i]) { - if (rising) { - GraphBuffer[i] = max; - rising = 0; - } - falling = 1; - } - if (GraphBuffer[i + 1] > GraphBuffer[i]) { - if (falling) { - GraphBuffer[i] = min; - falling = 0; - } - rising= 1; - } - } - } - RepaintGraphWindow(); - return 0; + if (max != min) { + rising = falling= 0; + for (i = 0; i < GraphTraceLen; ++i) { + if (GraphBuffer[i + 1] < GraphBuffer[i]) { + if (rising) { + GraphBuffer[i] = max; + rising = 0; + } + falling = 1; + } + if (GraphBuffer[i + 1] > GraphBuffer[i]) { + if (falling) { + GraphBuffer[i] = min; + falling = 0; + } + rising= 1; + } + } + } + RepaintGraphWindow(); + return 0; } /* @@ -119,171 +119,173 @@ int CmdAmp(const char *Cmd) //this method is dependant on all highs and lows to be the same(or clipped) this creates issues[marshmellow] it also ignores the clock int Cmdaskdemod(const char *Cmd) { - int i; - int c, high = 0, low = 0; + int i; + int c, high = 0, low = 0; - // TODO: complain if we do not give 2 arguments here ! - // (AL - this doesn't make sense! we're only using one argument!!!) - sscanf(Cmd, "%i", &c); + // TODO: complain if we do not give 2 arguments here ! + // (AL - this doesn't make sense! we're only using one argument!!!) + sscanf(Cmd, "%i", &c); - /* Detect high and lows and clock */ - // (AL - clock???) - for (i = 0; i < GraphTraceLen; ++i) - { - if (GraphBuffer[i] > high) - high = GraphBuffer[i]; - else if (GraphBuffer[i] < low) - low = GraphBuffer[i]; - } - high=abs(high*.75); - low=abs(low*.75); - if (c != 0 && c != 1) { - PrintAndLog("Invalid argument: %s", Cmd); - return 0; - } - //prime loop - if (GraphBuffer[0] > 0) { - GraphBuffer[0] = 1-c; - } else { - GraphBuffer[0] = c; - } - for (i = 1; i < GraphTraceLen; ++i) { - /* Transitions are detected at each peak - * Transitions are either: - * - we're low: transition if we hit a high - * - we're high: transition if we hit a low - * (we need to do it this way because some tags keep high or - * low for long periods, others just reach the peak and go - * down) - */ - //[marhsmellow] change == to >= for high and <= for low for fuzz - if ((GraphBuffer[i] == high) && (GraphBuffer[i - 1] == c)) { - GraphBuffer[i] = 1 - c; - } else if ((GraphBuffer[i] == low) && (GraphBuffer[i - 1] == (1 - c))){ - GraphBuffer[i] = c; - } else { - /* No transition */ - GraphBuffer[i] = GraphBuffer[i - 1]; - } - } - RepaintGraphWindow(); - return 0; + /* Detect high and lows and clock */ + // (AL - clock???) + for (i = 0; i < GraphTraceLen; ++i) + { + if (GraphBuffer[i] > high) + high = GraphBuffer[i]; + else if (GraphBuffer[i] < low) + low = GraphBuffer[i]; + } + high=abs(high*.75); + low=abs(low*.75); + if (c != 0 && c != 1) { + PrintAndLog("Invalid argument: %s", Cmd); + return 0; + } + //prime loop + if (GraphBuffer[0] > 0) { + GraphBuffer[0] = 1-c; + } else { + GraphBuffer[0] = c; + } + for (i = 1; i < GraphTraceLen; ++i) { + /* Transitions are detected at each peak + * Transitions are either: + * - we're low: transition if we hit a high + * - we're high: transition if we hit a low + * (we need to do it this way because some tags keep high or + * low for long periods, others just reach the peak and go + * down) + */ + //[marhsmellow] change == to >= for high and <= for low for fuzz + if ((GraphBuffer[i] == high) && (GraphBuffer[i - 1] == c)) { + GraphBuffer[i] = 1 - c; + } else if ((GraphBuffer[i] == low) && (GraphBuffer[i - 1] == (1 - c))){ + GraphBuffer[i] = c; + } else { + /* No transition */ + GraphBuffer[i] = GraphBuffer[i - 1]; + } + } + RepaintGraphWindow(); + return 0; } //by marshmellow void printBitStream(uint8_t BitStream[], uint32_t bitLen) { - uint32_t i = 0; - if (bitLen<16) { - PrintAndLog("Too few bits found: %d",bitLen); - return; - } - if (bitLen>512) bitLen=512; - for (i = 0; i <= (bitLen-16); i+=16) { - PrintAndLog("%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i", - BitStream[i], - BitStream[i+1], - BitStream[i+2], - BitStream[i+3], - BitStream[i+4], - BitStream[i+5], - BitStream[i+6], - BitStream[i+7], - BitStream[i+8], - BitStream[i+9], - BitStream[i+10], - BitStream[i+11], - BitStream[i+12], - BitStream[i+13], - BitStream[i+14], - BitStream[i+15]); - } - return; + uint32_t i = 0; + if (bitLen<16) { + PrintAndLog("Too few bits found: %d",bitLen); + return; + } + if (bitLen>512) bitLen=512; + for (i = 0; i <= (bitLen-16); i+=16) { + PrintAndLog("%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i", + BitStream[i], + BitStream[i+1], + BitStream[i+2], + BitStream[i+3], + BitStream[i+4], + BitStream[i+5], + BitStream[i+6], + BitStream[i+7], + BitStream[i+8], + BitStream[i+9], + BitStream[i+10], + BitStream[i+11], + BitStream[i+12], + BitStream[i+13], + BitStream[i+14], + BitStream[i+15]); + } + return; } //by marshmellow +//print EM410x ID in multiple formats void printEM410x(uint64_t id) { - if (id !=0){ - uint64_t iii=1; - uint64_t id2lo=0; //id2hi=0, - uint32_t ii=0; - uint32_t i=0; - for (ii=5; ii>0;ii--){ - for (i=0;i<8;i++){ - id2lo=(id2lo<<1LL)|((id & (iii<<(i+((ii-1)*8))))>>(i+((ii-1)*8))); - } - } - //output em id - PrintAndLog("EM TAG ID : %010llx", id); - PrintAndLog("Unique TAG ID: %010llx", id2lo); //id2hi, - PrintAndLog("DEZ 8 : %08lld",id & 0xFFFFFF); - PrintAndLog("DEZ 10 : %010lld",id & 0xFFFFFF); - PrintAndLog("DEZ 5.5 : %05lld.%05lld",(id>>16LL) & 0xFFFF,(id & 0xFFFF)); - 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)); - } - return; + if (id !=0){ + uint64_t iii=1; + uint64_t id2lo=0; //id2hi=0, + uint32_t ii=0; + uint32_t i=0; + for (ii=5; ii>0;ii--){ + for (i=0;i<8;i++){ + id2lo=(id2lo<<1LL) | ((id & (iii << (i+((ii-1)*8)))) >> (i+((ii-1)*8))); + } + } + //output em id + PrintAndLog("EM TAG ID : %010llx", id); + PrintAndLog("Unique TAG ID: %010llx", id2lo); //id2hi, + PrintAndLog("DEZ 8 : %08lld",id & 0xFFFFFF); + PrintAndLog("DEZ 10 : %010lld",id & 0xFFFFFF); + PrintAndLog("DEZ 5.5 : %05lld.%05lld",(id>>16LL) & 0xFFFF,(id & 0xFFFF)); + 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)); + } + return; } //by marshmellow +//take binary from demod buffer and see if we can find an EM410x ID int CmdEm410xDecode(const char *Cmd) { - uint64_t id=0; + uint64_t id=0; // uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; // uint32_t i=0; // i=getFromGraphBuf(BitStream); - id = Em410xDecode(DemodBuffer,DemodBufferLen); - printEM410x(id); - if (id>0) return 1; - return 0; + id = Em410xDecode(DemodBuffer,DemodBufferLen); + printEM410x(id); + if (id>0) return 1; + return 0; } //by marshmellow //takes 2 arguments - clock and invert both as integers -//attempts to demodulate ask while decoding manchester +//attempts to demodulate ask while decoding manchester //prints binary found and saves in graphbuffer for further commands int Cmdaskmandemod(const char *Cmd) { - int invert=0; - int clk=0; - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - sscanf(Cmd, "%i %i", &clk, &invert); - if (invert != 0 && invert != 1) { - PrintAndLog("Invalid argument: %s", Cmd); - return 0; - } + int invert=0; + int clk=0; + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + sscanf(Cmd, "%i %i", &clk, &invert); + if (invert != 0 && invert != 1) { + PrintAndLog("Invalid argument: %s", Cmd); + return 0; + } - int BitLen = getFromGraphBuf(BitStream); - // PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen); - int errCnt=0; - errCnt = askmandemod(BitStream, &BitLen,&clk,&invert); - if (errCnt<0||BitLen<16){ //if fatal error (or -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); - printDemodBuff(); - uint64_t lo =0; - lo = Em410xDecode(BitStream,BitLen); - if (lo>0){ - //set GraphBuffer for clone or sim command - PrintAndLog("EM410x pattern found: "); - printEM410x(lo); - return 1; - } - //if (BitLen>16) return 1; - return 0; + size_t BitLen = getFromGraphBuf(BitStream); + // PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen); + int errCnt=0; + errCnt = askmandemod(BitStream, &BitLen,&clk,&invert); + if (errCnt<0||BitLen<16){ //if fatal error (or -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); + printDemodBuff(); + uint64_t lo =0; + lo = Em410xDecode(BitStream,BitLen); + if (lo>0){ + //set GraphBuffer for clone or sim command + PrintAndLog("EM410x pattern found: "); + printEM410x(lo); + return 1; + } + //if (BitLen>16) return 1; + return 0; } //by marshmellow @@ -291,75 +293,75 @@ int Cmdaskmandemod(const char *Cmd) //stricktly take 10 and 01 and convert to 0 and 1 int Cmdmandecoderaw(const char *Cmd) { - int i =0; - int errCnt=0; - int bitnum=0; - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - int high=0,low=0; - for (;ihigh) high=DemodBuffer[i]; - else if(DemodBuffer[i]1 || low <0 ){ - PrintAndLog("Error: please raw demod the wave first then mancheseter raw decode"); - return 0; - } - bitnum=i; - errCnt=manrawdecode(BitStream,&bitnum); - if (errCnt>=20){ - PrintAndLog("Too many errors: %d",errCnt); - return 0; - } - PrintAndLog("Manchester Decoded - # errors:%d - data:",errCnt); - printBitStream(BitStream,bitnum); - if (errCnt==0){ - uint64_t id = 0; - id = Em410xDecode(BitStream,bitnum); - if (id>0) setDemodBuf(BitStream,bitnum); - printEM410x(id); - } - return 1; + int i =0; + int errCnt=0; + size_t size=0; + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + int high=0,low=0; + for (;ihigh) high=DemodBuffer[i]; + else if(DemodBuffer[i]1 || low <0 ){ + PrintAndLog("Error: please raw demod the wave first then mancheseter raw decode"); + return 0; + } + size=i; + errCnt=manrawdecode(BitStream, &size); + if (errCnt>=20){ + PrintAndLog("Too many errors: %d",errCnt); + return 0; + } + PrintAndLog("Manchester Decoded - # errors:%d - data:",errCnt); + printBitStream(BitStream, size); + if (errCnt==0){ + uint64_t id = 0; + id = Em410xDecode(BitStream, size); + if (id>0) setDemodBuf(BitStream, size); + printEM410x(id); + } + return 1; } //by marshmellow //biphase decode //take 01 or 10 = 0 and 11 or 00 = 1 //takes 1 argument "offset" default = 0 if 1 it will shift the decode by one bit -// since it is not like manchester and doesn't have an incorrect bit pattern we +// since it is not like manchester and doesn't have an incorrect bit pattern we // cannot determine if our decode is correct or if it should be shifted by one bit // the argument offset allows us to manually shift if the output is incorrect // (better would be to demod and decode at the same time so we can distinguish large // width waves vs small width waves to help the decode positioning) or askbiphdemod int CmdBiphaseDecodeRaw(const char *Cmd) { - int i = 0; - int errCnt=0; - int bitnum=0; - int offset=0; - int high=0, low=0; - sscanf(Cmd, "%i", &offset); - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - //get graphbuffer & high and low - for (;ihigh)high=DemodBuffer[i]; - else if(DemodBuffer[i]1 || low <0){ - PrintAndLog("Error: please raw demod the wave first then decode"); - return 0; - } - bitnum=i; - errCnt=BiphaseRawDecode(BitStream,&bitnum, offset); - if (errCnt>=20){ - PrintAndLog("Too many errors attempting to decode: %d",errCnt); - return 0; - } - PrintAndLog("Biphase Decoded using offset: %d - # errors:%d - data:",offset,errCnt); - printBitStream(BitStream,bitnum); - PrintAndLog("\nif bitstream does not look right try offset=1"); - return 1; + int i = 0; + int errCnt=0; + size_t size=0; + int offset=0; + int high=0, low=0; + sscanf(Cmd, "%i", &offset); + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + //get graphbuffer & high and low + for (;ihigh)high=DemodBuffer[i]; + else if(DemodBuffer[i]1 || low <0){ + PrintAndLog("Error: please raw demod the wave first then decode"); + return 0; + } + size=i; + errCnt=BiphaseRawDecode(BitStream, &size, offset); + if (errCnt>=20){ + PrintAndLog("Too many errors attempting to decode: %d",errCnt); + return 0; + } + PrintAndLog("Biphase Decoded using offset: %d - # errors:%d - data:",offset,errCnt); + printBitStream(BitStream, size); + PrintAndLog("\nif bitstream does not look right try offset=1"); + return 1; } @@ -369,89 +371,89 @@ int CmdBiphaseDecodeRaw(const char *Cmd) //prints binary found and saves in graphbuffer for further commands int Cmdaskrawdemod(const char *Cmd) { - int invert=0; - int clk=0; - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - sscanf(Cmd, "%i %i", &clk, &invert); - if (invert != 0 && invert != 1) { - PrintAndLog("Invalid argument: %s", Cmd); - return 0; - } - int BitLen = getFromGraphBuf(BitStream); - int errCnt=0; - errCnt = askrawdemod(BitStream, &BitLen,&clk,&invert); - if (errCnt==-1||BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first) - PrintAndLog("no data found"); - return 0; - } - PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen); - //PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum); - //move BitStream back to DemodBuffer - setDemodBuf(BitStream,BitLen); - - //output - if (errCnt>0){ - PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); - } - PrintAndLog("ASK demoded bitstream:"); - // Now output the bitstream to the scrollback by line of 16 bits - printBitStream(BitStream,BitLen); - - return 1; + int invert=0; + int clk=0; + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + sscanf(Cmd, "%i %i", &clk, &invert); + if (invert != 0 && invert != 1) { + PrintAndLog("Invalid argument: %s", Cmd); + return 0; + } + size_t BitLen = getFromGraphBuf(BitStream); + int errCnt=0; + errCnt = askrawdemod(BitStream, &BitLen,&clk,&invert); + if (errCnt==-1||BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first) + PrintAndLog("no data found"); + return 0; + } + PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen); + //PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum); + //move BitStream back to DemodBuffer + setDemodBuf(BitStream,BitLen); + + //output + if (errCnt>0){ + PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); + } + PrintAndLog("ASK demoded bitstream:"); + // Now output the bitstream to the scrollback by line of 16 bits + printBitStream(BitStream,BitLen); + + return 1; } int CmdAutoCorr(const char *Cmd) { - static int CorrelBuffer[MAX_GRAPH_TRACE_LEN]; + static int CorrelBuffer[MAX_GRAPH_TRACE_LEN]; - int window = atoi(Cmd); + 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; - } + 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); + 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; - } - GraphTraceLen = GraphTraceLen - window; - memcpy(GraphBuffer, CorrelBuffer, GraphTraceLen * sizeof (int)); + 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; + } + GraphTraceLen = GraphTraceLen - window; + memcpy(GraphBuffer, CorrelBuffer, GraphTraceLen * sizeof (int)); - RepaintGraphWindow(); - return 0; + RepaintGraphWindow(); + return 0; } int CmdBitsamples(const char *Cmd) { - int cnt = 0; - uint8_t got[12288]; - - GetFromBigBuf(got,sizeof(got),0); - WaitForResponse(CMD_ACK,NULL); + int cnt = 0; + uint8_t got[12288]; - for (int j = 0; j < sizeof(got); j++) { - for (int k = 0; k < 8; k++) { - if(got[j] & (1 << (7 - k))) { - GraphBuffer[cnt++] = 1; - } else { - GraphBuffer[cnt++] = 0; - } - } - } - GraphTraceLen = cnt; - RepaintGraphWindow(); - return 0; + GetFromBigBuf(got,sizeof(got),0); + WaitForResponse(CMD_ACK,NULL); + + for (int j = 0; j < sizeof(got); j++) { + for (int k = 0; k < 8; k++) { + if(got[j] & (1 << (7 - k))) { + GraphBuffer[cnt++] = 1; + } else { + GraphBuffer[cnt++] = 0; + } + } + } + GraphTraceLen = cnt; + RepaintGraphWindow(); + return 0; } /* @@ -459,92 +461,92 @@ int CmdBitsamples(const char *Cmd) */ int CmdBitstream(const char *Cmd) { - int i, j; - int bit; - int gtl; - int clock; - int low = 0; - int high = 0; - int hithigh, hitlow, first; + int i, j; + int bit; + int gtl; + int clock; + int low = 0; + int high = 0; + int hithigh, hitlow, first; - /* Detect high and lows and clock */ - for (i = 0; i < GraphTraceLen; ++i) - { - if (GraphBuffer[i] > high) - high = GraphBuffer[i]; - else if (GraphBuffer[i] < low) - low = GraphBuffer[i]; - } + /* Detect high and lows and clock */ + for (i = 0; i < GraphTraceLen; ++i) + { + if (GraphBuffer[i] > high) + high = GraphBuffer[i]; + else if (GraphBuffer[i] < low) + low = GraphBuffer[i]; + } - /* Get our clock */ - clock = GetClock(Cmd, high, 1); - gtl = ClearGraph(0); + /* Get our clock */ + clock = GetClock(Cmd, high, 1); + gtl = ClearGraph(0); - bit = 0; - for (i = 0; i < (int)(gtl / clock); ++i) - { - hithigh = 0; - hitlow = 0; - first = 1; - /* Find out if we hit both high and low peaks */ - for (j = 0; j < clock; ++j) - { - if (GraphBuffer[(i * clock) + j] == high) - hithigh = 1; - else if (GraphBuffer[(i * clock) + j] == low) - hitlow = 1; - /* it doesn't count if it's the first part of our read - because it's really just trailing from the last sequence */ - if (first && (hithigh || hitlow)) - hithigh = hitlow = 0; - else - first = 0; + bit = 0; + for (i = 0; i < (int)(gtl / clock); ++i) + { + hithigh = 0; + hitlow = 0; + first = 1; + /* Find out if we hit both high and low peaks */ + for (j = 0; j < clock; ++j) + { + if (GraphBuffer[(i * clock) + j] == high) + hithigh = 1; + else if (GraphBuffer[(i * clock) + j] == low) + hitlow = 1; + /* it doesn't count if it's the first part of our read + because it's really just trailing from the last sequence */ + if (first && (hithigh || hitlow)) + hithigh = hitlow = 0; + else + first = 0; - if (hithigh && hitlow) - break; - } + if (hithigh && hitlow) + break; + } - /* If we didn't hit both high and low peaks, we had a bit transition */ - if (!hithigh || !hitlow) - bit ^= 1; + /* If we didn't hit both high and low peaks, we had a bit transition */ + if (!hithigh || !hitlow) + bit ^= 1; - AppendGraph(0, clock, bit); - // for (j = 0; j < (int)(clock/2); j++) - // GraphBuffer[(i * clock) + j] = bit ^ 1; - // for (j = (int)(clock/2); j < clock; j++) - // GraphBuffer[(i * clock) + j] = bit; - } + AppendGraph(0, clock, bit); + // for (j = 0; j < (int)(clock/2); j++) + // GraphBuffer[(i * clock) + j] = bit ^ 1; + // for (j = (int)(clock/2); j < clock; j++) + // GraphBuffer[(i * clock) + j] = bit; + } - RepaintGraphWindow(); - return 0; + RepaintGraphWindow(); + return 0; } int CmdBuffClear(const char *Cmd) { - UsbCommand c = {CMD_BUFF_CLEAR}; - SendCommand(&c); - ClearGraph(true); - return 0; + UsbCommand c = {CMD_BUFF_CLEAR}; + SendCommand(&c); + ClearGraph(true); + return 0; } int CmdDec(const char *Cmd) { - for (int i = 0; i < (GraphTraceLen / 2); ++i) - GraphBuffer[i] = GraphBuffer[i * 2]; - GraphTraceLen /= 2; - PrintAndLog("decimated by 2"); - RepaintGraphWindow(); - return 0; + for (int i = 0; i < (GraphTraceLen / 2); ++i) + GraphBuffer[i] = GraphBuffer[i * 2]; + GraphTraceLen /= 2; + PrintAndLog("decimated by 2"); + RepaintGraphWindow(); + return 0; } /* Print our clock rate */ -// uses data from graphbuffer +// uses data from graphbuffer int CmdDetectClockRate(const char *Cmd) { - GetClock("",0,0); - //int clock = DetectASKClock(0); - //PrintAndLog("Auto-detected clock rate: %d", clock); - return 0; + GetClock("",0,0); + //int clock = DetectASKClock(0); + //PrintAndLog("Auto-detected clock rate: %d", clock); + return 0; } //by marshmellow @@ -553,37 +555,37 @@ int CmdDetectClockRate(const char *Cmd) //defaults: clock = 50, invert=0, rchigh=10, rclow=8 (RF/10 RF/8 (fsk2a)) int CmdFSKrawdemod(const char *Cmd) { - //raw fsk demod no manchester decoding no start bit finding just get binary from wave - //set defaults - int rfLen = 50; - int invert=0; - int fchigh=10; - int fclow=8; - //set options from parameters entered with the command - sscanf(Cmd, "%i %i %i %i", &rfLen, &invert, &fchigh, &fclow); - - if (strlen(Cmd)>0 && strlen(Cmd)<=2) { - //rfLen=param_get8(Cmd, 0); //if rfLen option only is used - if (rfLen==1){ - invert=1; //if invert option only is used - rfLen = 50; - } else if(rfLen==0) rfLen=50; - } - PrintAndLog("Args invert: %d - Clock:%d - fchigh:%d - fclow: %d",invert,rfLen,fchigh, fclow); - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - uint32_t BitLen = getFromGraphBuf(BitStream); - int size = fskdemod(BitStream,BitLen,(uint8_t)rfLen,(uint8_t)invert,(uint8_t)fchigh,(uint8_t)fclow); - if (size>0){ - PrintAndLog("FSK decoded bitstream:"); - setDemodBuf(BitStream,size); - - // Now output the bitstream to the scrollback by line of 16 bits - if(size > (8*32)+2) size = (8*32)+2; //only output a max of 8 blocks of 32 bits most tags will have full bit stream inside that sample size - printBitStream(BitStream,size); - } else{ - PrintAndLog("no FSK data found"); - } - return 0; + //raw fsk demod no manchester decoding no start bit finding just get binary from wave + //set defaults + int rfLen = 50; + int invert=0; + int fchigh=10; + int fclow=8; + //set options from parameters entered with the command + sscanf(Cmd, "%i %i %i %i", &rfLen, &invert, &fchigh, &fclow); + + if (strlen(Cmd)>0 && strlen(Cmd)<=2) { + //rfLen=param_get8(Cmd, 0); //if rfLen option only is used + if (rfLen==1){ + invert=1; //if invert option only is used + rfLen = 50; + } else if(rfLen==0) rfLen=50; + } + PrintAndLog("Args invert: %d - Clock:%d - fchigh:%d - fclow: %d",invert,rfLen,fchigh, fclow); + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + size_t BitLen = getFromGraphBuf(BitStream); + int size = fskdemod(BitStream,BitLen,(uint8_t)rfLen,(uint8_t)invert,(uint8_t)fchigh,(uint8_t)fclow); + if (size>0){ + PrintAndLog("FSK decoded bitstream:"); + setDemodBuf(BitStream,size); + + // Now output the bitstream to the scrollback by line of 16 bits + if(size > (8*32)+2) size = (8*32)+2; //only output a max of 8 blocks of 32 bits most tags will have full bit stream inside that sample size + printBitStream(BitStream,size); + } else{ + PrintAndLog("no FSK data found"); + } + return 0; } //by marshmellow (based on existing demod + holiman's refactor) @@ -591,73 +593,73 @@ int CmdFSKrawdemod(const char *Cmd) //print full HID Prox ID and some bit format details if found int CmdFSKdemodHID(const char *Cmd) { - //raw fsk demod no manchester decoding no start bit finding just get binary from wave - uint32_t hi2=0, hi=0, lo=0; + //raw fsk demod no manchester decoding no start bit finding just get binary from wave + uint32_t hi2=0, hi=0, lo=0; - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - uint32_t BitLen = getFromGraphBuf(BitStream); - //get binary from fsk wave - size_t size = HIDdemodFSK(BitStream,BitLen,&hi2,&hi,&lo); - if (size<0){ - PrintAndLog("Error demoding fsk"); - return 0; - } - if (hi2==0 && hi==0 && lo==0) return 0; - if (hi2 != 0){ //extra large HID tags - PrintAndLog("HID Prox TAG ID: %x%08x%08x (%d)", - (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); - setDemodBuf(BitStream,BitLen); - return 1; - } - else { //standard HID tags <38 bits - //Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd - uint8_t fmtLen = 0; - uint32_t fc = 0; - uint32_t cardnum = 0; - if (((hi>>5)&1)==1){//if bit 38 is set then < 37 bit format is used - uint32_t lo2=0; - lo2=(((hi & 15) << 12) | (lo>>20)); //get bits 21-37 to check for format len bit - uint8_t idx3 = 1; - while(lo2>1){ //find last bit set to 1 (format len bit) - lo2=lo2>>1; - idx3++; - } - fmtLen =idx3+19; - fc =0; - cardnum=0; - if(fmtLen==26){ - cardnum = (lo>>1)&0xFFFF; - fc = (lo>>17)&0xFF; - } - if(fmtLen==37){ - cardnum = (lo>>1)&0x7FFFF; - fc = ((hi&0xF)<<12)|(lo>>20); - } - if(fmtLen==34){ - cardnum = (lo>>1)&0xFFFF; - fc= ((hi&1)<<15)|(lo>>17); - } - if(fmtLen==35){ - cardnum = (lo>>1)&0xFFFFF; - fc = ((hi&1)<<11)|(lo>>21); - } - } - else { //if bit 38 is not set then 37 bit format is used - fmtLen= 37; - fc =0; - cardnum=0; - if(fmtLen==37){ - cardnum = (lo>>1)&0x7FFFF; - fc = ((hi&0xF)<<12)|(lo>>20); - } - } - PrintAndLog("HID Prox TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d", - (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF, - (unsigned int) fmtLen, (unsigned int) fc, (unsigned int) cardnum); - setDemodBuf(BitStream,BitLen); - return 1; - } - return 0; + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + size_t BitLen = getFromGraphBuf(BitStream); + //get binary from fsk wave + size_t size = HIDdemodFSK(BitStream,BitLen,&hi2,&hi,&lo); + if (size<0){ + PrintAndLog("Error demoding fsk"); + return 0; + } + if (hi2==0 && hi==0 && lo==0) return 0; + if (hi2 != 0){ //extra large HID tags + PrintAndLog("HID Prox TAG ID: %x%08x%08x (%d)", + (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); + setDemodBuf(BitStream,BitLen); + return 1; + } + else { //standard HID tags <38 bits + //Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd + uint8_t fmtLen = 0; + uint32_t fc = 0; + uint32_t cardnum = 0; + if (((hi>>5)&1)==1){//if bit 38 is set then < 37 bit format is used + uint32_t lo2=0; + lo2=(((hi & 15) << 12) | (lo>>20)); //get bits 21-37 to check for format len bit + uint8_t idx3 = 1; + while(lo2>1){ //find last bit set to 1 (format len bit) + lo2=lo2>>1; + idx3++; + } + fmtLen =idx3+19; + fc =0; + cardnum=0; + if(fmtLen==26){ + cardnum = (lo>>1)&0xFFFF; + fc = (lo>>17)&0xFF; + } + if(fmtLen==37){ + cardnum = (lo>>1)&0x7FFFF; + fc = ((hi&0xF)<<12)|(lo>>20); + } + if(fmtLen==34){ + cardnum = (lo>>1)&0xFFFF; + fc= ((hi&1)<<15)|(lo>>17); + } + if(fmtLen==35){ + cardnum = (lo>>1)&0xFFFFF; + fc = ((hi&1)<<11)|(lo>>21); + } + } + else { //if bit 38 is not set then 37 bit format is used + fmtLen= 37; + fc =0; + cardnum=0; + if(fmtLen==37){ + cardnum = (lo>>1)&0x7FFFF; + fc = ((hi&0xF)<<12)|(lo>>20); + } + } + PrintAndLog("HID Prox TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d", + (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF, + (unsigned int) fmtLen, (unsigned int) fc, (unsigned int) cardnum); + setDemodBuf(BitStream,BitLen); + return 1; + } + return 0; } //by marshmellow @@ -665,203 +667,203 @@ int CmdFSKdemodHID(const char *Cmd) //print ioprox ID and some format details int CmdFSKdemodIO(const char *Cmd) { - //raw fsk demod no manchester decoding no start bit finding just get binary from wave - //set defaults - int idx=0; - //something in graphbuffer - if (GraphTraceLen < 65) return 0; - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - uint32_t BitLen = getFromGraphBuf(BitStream); - //get binary from fsk wave - // PrintAndLog("DEBUG: got buff"); - idx = IOdemodFSK(BitStream,BitLen); - if (idx<0){ - //PrintAndLog("Error demoding fsk"); - return 0; - } - // PrintAndLog("DEBUG: Got IOdemodFSK"); - if (idx==0){ - //PrintAndLog("IO Prox Data not found - FSK Data:"); - //if (BitLen > 92) printBitStream(BitStream,92); - return 0; - } - //Index map - //0 10 20 30 40 50 60 - //| | | | | | | - //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23 - //----------------------------------------------------------------------------- - //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11 - // - //XSF(version)facility:codeone+codetwo (raw) - //Handle the data - if (idx+64>BitLen) return 0; - PrintAndLog("%d%d%d%d%d%d%d%d %d",BitStream[idx], BitStream[idx+1], BitStream[idx+2], BitStream[idx+3], BitStream[idx+4], BitStream[idx+5], BitStream[idx+6], BitStream[idx+7], BitStream[idx+8]); - PrintAndLog("%d%d%d%d%d%d%d%d %d",BitStream[idx+9], BitStream[idx+10], BitStream[idx+11],BitStream[idx+12],BitStream[idx+13],BitStream[idx+14],BitStream[idx+15],BitStream[idx+16],BitStream[idx+17]); - PrintAndLog("%d%d%d%d%d%d%d%d %d facility",BitStream[idx+18], BitStream[idx+19], BitStream[idx+20],BitStream[idx+21],BitStream[idx+22],BitStream[idx+23],BitStream[idx+24],BitStream[idx+25],BitStream[idx+26]); - PrintAndLog("%d%d%d%d%d%d%d%d %d version",BitStream[idx+27], BitStream[idx+28], BitStream[idx+29],BitStream[idx+30],BitStream[idx+31],BitStream[idx+32],BitStream[idx+33],BitStream[idx+34],BitStream[idx+35]); - PrintAndLog("%d%d%d%d%d%d%d%d %d code1",BitStream[idx+36], BitStream[idx+37], BitStream[idx+38],BitStream[idx+39],BitStream[idx+40],BitStream[idx+41],BitStream[idx+42],BitStream[idx+43],BitStream[idx+44]); - PrintAndLog("%d%d%d%d%d%d%d%d %d code2",BitStream[idx+45], BitStream[idx+46], BitStream[idx+47],BitStream[idx+48],BitStream[idx+49],BitStream[idx+50],BitStream[idx+51],BitStream[idx+52],BitStream[idx+53]); - PrintAndLog("%d%d%d%d%d%d%d%d %d%d checksum",BitStream[idx+54],BitStream[idx+55],BitStream[idx+56],BitStream[idx+57],BitStream[idx+58],BitStream[idx+59],BitStream[idx+60],BitStream[idx+61],BitStream[idx+62],BitStream[idx+63]); + //raw fsk demod no manchester decoding no start bit finding just get binary from wave + //set defaults + int idx=0; + //something in graphbuffer + if (GraphTraceLen < 65) return 0; + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + size_t BitLen = getFromGraphBuf(BitStream); + //get binary from fsk wave + // PrintAndLog("DEBUG: got buff"); + idx = IOdemodFSK(BitStream,BitLen); + if (idx<0){ + //PrintAndLog("Error demoding fsk"); + return 0; + } + // PrintAndLog("DEBUG: Got IOdemodFSK"); + if (idx==0){ + //PrintAndLog("IO Prox Data not found - FSK Data:"); + //if (BitLen > 92) printBitStream(BitStream,92); + return 0; + } + //Index map + //0 10 20 30 40 50 60 + //| | | | | | | + //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23 + //----------------------------------------------------------------------------- + //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11 + // + //XSF(version)facility:codeone+codetwo (raw) + //Handle the data + if (idx+64>BitLen) return 0; + PrintAndLog("%d%d%d%d%d%d%d%d %d",BitStream[idx], BitStream[idx+1], BitStream[idx+2], BitStream[idx+3], BitStream[idx+4], BitStream[idx+5], BitStream[idx+6], BitStream[idx+7], BitStream[idx+8]); + PrintAndLog("%d%d%d%d%d%d%d%d %d",BitStream[idx+9], BitStream[idx+10], BitStream[idx+11],BitStream[idx+12],BitStream[idx+13],BitStream[idx+14],BitStream[idx+15],BitStream[idx+16],BitStream[idx+17]); + PrintAndLog("%d%d%d%d%d%d%d%d %d facility",BitStream[idx+18], BitStream[idx+19], BitStream[idx+20],BitStream[idx+21],BitStream[idx+22],BitStream[idx+23],BitStream[idx+24],BitStream[idx+25],BitStream[idx+26]); + PrintAndLog("%d%d%d%d%d%d%d%d %d version",BitStream[idx+27], BitStream[idx+28], BitStream[idx+29],BitStream[idx+30],BitStream[idx+31],BitStream[idx+32],BitStream[idx+33],BitStream[idx+34],BitStream[idx+35]); + PrintAndLog("%d%d%d%d%d%d%d%d %d code1",BitStream[idx+36], BitStream[idx+37], BitStream[idx+38],BitStream[idx+39],BitStream[idx+40],BitStream[idx+41],BitStream[idx+42],BitStream[idx+43],BitStream[idx+44]); + PrintAndLog("%d%d%d%d%d%d%d%d %d code2",BitStream[idx+45], BitStream[idx+46], BitStream[idx+47],BitStream[idx+48],BitStream[idx+49],BitStream[idx+50],BitStream[idx+51],BitStream[idx+52],BitStream[idx+53]); + PrintAndLog("%d%d%d%d%d%d%d%d %d%d checksum",BitStream[idx+54],BitStream[idx+55],BitStream[idx+56],BitStream[idx+57],BitStream[idx+58],BitStream[idx+59],BitStream[idx+60],BitStream[idx+61],BitStream[idx+62],BitStream[idx+63]); - uint32_t code = bytebits_to_byte(BitStream+idx,32); - uint32_t code2 = bytebits_to_byte(BitStream+idx+32,32); - uint8_t version = bytebits_to_byte(BitStream+idx+27,8); //14,4 - uint8_t facilitycode = bytebits_to_byte(BitStream+idx+18,8) ; - uint16_t number = (bytebits_to_byte(BitStream+idx+36,8)<<8)|(bytebits_to_byte(BitStream+idx+45,8)); //36,9 - PrintAndLog("IO Prox XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2); - int i; - for (i=0;i<64;++i) - DemodBuffer[i]=BitStream[idx++]; + uint32_t code = bytebits_to_byte(BitStream+idx,32); + uint32_t code2 = bytebits_to_byte(BitStream+idx+32,32); + uint8_t version = bytebits_to_byte(BitStream+idx+27,8); //14,4 + uint8_t facilitycode = bytebits_to_byte(BitStream+idx+18,8) ; + uint16_t number = (bytebits_to_byte(BitStream+idx+36,8)<<8)|(bytebits_to_byte(BitStream+idx+45,8)); //36,9 + PrintAndLog("IO Prox XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2); + int i; + for (i=0;i<64;++i) + DemodBuffer[i]=BitStream[idx++]; - DemodBufferLen=64; - return 1; + DemodBufferLen=64; + return 1; } int CmdFSKdemod(const char *Cmd) //old CmdFSKdemod needs updating { - static const int LowTone[] = { - 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, -1, -1, -1, -1, -1 - }; - static const int HighTone[] = { - 1, 1, 1, 1, 1, -1, -1, -1, -1, - 1, 1, 1, 1, -1, -1, -1, -1, - 1, 1, 1, 1, -1, -1, -1, -1, - 1, 1, 1, 1, -1, -1, -1, -1, - 1, 1, 1, 1, -1, -1, -1, -1, - 1, 1, 1, 1, -1, -1, -1, -1, -1, - }; + static const int LowTone[] = { + 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, -1, -1, -1, -1, -1 + }; + static const int HighTone[] = { + 1, 1, 1, 1, 1, -1, -1, -1, -1, + 1, 1, 1, 1, -1, -1, -1, -1, + 1, 1, 1, 1, -1, -1, -1, -1, + 1, 1, 1, 1, -1, -1, -1, -1, + 1, 1, 1, 1, -1, -1, -1, -1, + 1, 1, 1, 1, -1, -1, -1, -1, -1, + }; - int lowLen = sizeof (LowTone) / sizeof (int); - int highLen = sizeof (HighTone) / sizeof (int); - int convLen = (highLen > lowLen) ? highLen : lowLen; //if highlen > lowLen then highlen else lowlen - uint32_t hi = 0, lo = 0; + int lowLen = sizeof (LowTone) / sizeof (int); + int highLen = sizeof (HighTone) / sizeof (int); + int convLen = (highLen > lowLen) ? highLen : lowLen; //if highlen > lowLen then highlen else lowlen + uint32_t hi = 0, lo = 0; - int i, j; - int minMark = 0, maxMark = 0; - - for (i = 0; i < GraphTraceLen - convLen; ++i) { - int lowSum = 0, highSum = 0; + int i, j; + int minMark = 0, maxMark = 0; - for (j = 0; j < lowLen; ++j) { - lowSum += LowTone[j]*GraphBuffer[i+j]; - } - for (j = 0; j < highLen; ++j) { - highSum += HighTone[j] * GraphBuffer[i + j]; - } - lowSum = abs(100 * lowSum / lowLen); - highSum = abs(100 * highSum / highLen); - GraphBuffer[i] = (highSum << 16) | lowSum; - } + for (i = 0; i < GraphTraceLen - convLen; ++i) { + int lowSum = 0, highSum = 0; - for(i = 0; i < GraphTraceLen - convLen - 16; ++i) { - int lowTot = 0, highTot = 0; - // 10 and 8 are f_s divided by f_l and f_h, rounded - for (j = 0; j < 10; ++j) { - lowTot += (GraphBuffer[i+j] & 0xffff); - } - for (j = 0; j < 8; j++) { - highTot += (GraphBuffer[i + j] >> 16); - } - GraphBuffer[i] = lowTot - highTot; - if (GraphBuffer[i] > maxMark) maxMark = GraphBuffer[i]; - if (GraphBuffer[i] < minMark) minMark = GraphBuffer[i]; - } + for (j = 0; j < lowLen; ++j) { + lowSum += LowTone[j]*GraphBuffer[i+j]; + } + for (j = 0; j < highLen; ++j) { + highSum += HighTone[j] * GraphBuffer[i + j]; + } + lowSum = abs(100 * lowSum / lowLen); + highSum = abs(100 * highSum / highLen); + GraphBuffer[i] = (highSum << 16) | lowSum; + } - GraphTraceLen -= (convLen + 16); - RepaintGraphWindow(); + for(i = 0; i < GraphTraceLen - convLen - 16; ++i) { + int lowTot = 0, highTot = 0; + // 10 and 8 are f_s divided by f_l and f_h, rounded + for (j = 0; j < 10; ++j) { + lowTot += (GraphBuffer[i+j] & 0xffff); + } + for (j = 0; j < 8; j++) { + highTot += (GraphBuffer[i + j] >> 16); + } + GraphBuffer[i] = lowTot - highTot; + if (GraphBuffer[i] > maxMark) maxMark = GraphBuffer[i]; + if (GraphBuffer[i] < minMark) minMark = GraphBuffer[i]; + } - // Find bit-sync (3 lo followed by 3 high) (HID ONLY) - int max = 0, maxPos = 0; - for (i = 0; i < 6000; ++i) { - int dec = 0; - for (j = 0; j < 3 * lowLen; ++j) { - dec -= GraphBuffer[i + j]; - } - for (; j < 3 * (lowLen + highLen ); ++j) { - dec += GraphBuffer[i + j]; - } - if (dec > max) { - max = dec; - maxPos = i; - } - } + GraphTraceLen -= (convLen + 16); + RepaintGraphWindow(); - // place start of bit sync marker in graph - GraphBuffer[maxPos] = maxMark; - GraphBuffer[maxPos + 1] = minMark; + // Find bit-sync (3 lo followed by 3 high) (HID ONLY) + int max = 0, maxPos = 0; + for (i = 0; i < 6000; ++i) { + int dec = 0; + for (j = 0; j < 3 * lowLen; ++j) { + dec -= GraphBuffer[i + j]; + } + for (; j < 3 * (lowLen + highLen ); ++j) { + dec += GraphBuffer[i + j]; + } + if (dec > max) { + max = dec; + maxPos = i; + } + } - maxPos += j; + // place start of bit sync marker in graph + GraphBuffer[maxPos] = maxMark; + GraphBuffer[maxPos + 1] = minMark; - // place end of bit sync marker in graph - GraphBuffer[maxPos] = maxMark; - GraphBuffer[maxPos+1] = minMark; + maxPos += j; - PrintAndLog("actual data bits start at sample %d", maxPos); - PrintAndLog("length %d/%d", highLen, lowLen); + // place end of bit sync marker in graph + GraphBuffer[maxPos] = maxMark; + GraphBuffer[maxPos+1] = minMark; - uint8_t bits[46]; - bits[sizeof(bits)-1] = '\0'; + PrintAndLog("actual data bits start at sample %d", maxPos); + PrintAndLog("length %d/%d", highLen, lowLen); - // find bit pairs and manchester decode them - for (i = 0; i < arraylen(bits) - 1; ++i) { - int dec = 0; - for (j = 0; j < lowLen; ++j) { - dec -= GraphBuffer[maxPos + j]; - } - for (; j < lowLen + highLen; ++j) { - dec += GraphBuffer[maxPos + j]; - } - maxPos += j; - // place inter bit marker in graph - GraphBuffer[maxPos] = maxMark; - GraphBuffer[maxPos + 1] = minMark; + uint8_t bits[46]; + bits[sizeof(bits)-1] = '\0'; - // hi and lo form a 64 bit pair - hi = (hi << 1) | (lo >> 31); - lo = (lo << 1); - // store decoded bit as binary (in hi/lo) and text (in bits[]) - if(dec < 0) { - bits[i] = '1'; - lo |= 1; - } else { - bits[i] = '0'; - } - } - PrintAndLog("bits: '%s'", bits); - PrintAndLog("hex: %08x %08x", hi, lo); - return 0; + // find bit pairs and manchester decode them + for (i = 0; i < arraylen(bits) - 1; ++i) { + int dec = 0; + for (j = 0; j < lowLen; ++j) { + dec -= GraphBuffer[maxPos + j]; + } + for (; j < lowLen + highLen; ++j) { + dec += GraphBuffer[maxPos + j]; + } + maxPos += j; + // place inter bit marker in graph + GraphBuffer[maxPos] = maxMark; + GraphBuffer[maxPos + 1] = minMark; + + // hi and lo form a 64 bit pair + hi = (hi << 1) | (lo >> 31); + lo = (lo << 1); + // store decoded bit as binary (in hi/lo) and text (in bits[]) + if(dec < 0) { + bits[i] = '1'; + lo |= 1; + } else { + bits[i] = '0'; + } + } + PrintAndLog("bits: '%s'", bits); + PrintAndLog("hex: %08x %08x", hi, lo); + return 0; } int CmdDetectNRZpskClockRate(const char *Cmd) { - GetNRZpskClock("",0,0); - return 0; + GetNRZpskClock("",0,0); + return 0; } int PSKnrzDemod(const char *Cmd){ - int invert=0; - int clk=0; - sscanf(Cmd, "%i %i", &clk, &invert); - if (invert != 0 && invert != 1) { - PrintAndLog("Invalid argument: %s", Cmd); - return -1; - } - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - int BitLen = getFromGraphBuf(BitStream); - int errCnt=0; - errCnt = pskNRZrawDemod(BitStream, &BitLen,&clk,&invert); - if (errCnt<0|| BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first) - //PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); - return -1; - } - PrintAndLog("Tried PSK/NRZ Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen); - - //prime demod buffer for output - setDemodBuf(BitStream,BitLen); - return errCnt; + int invert=0; + int clk=0; + sscanf(Cmd, "%i %i", &clk, &invert); + if (invert != 0 && invert != 1) { + PrintAndLog("Invalid argument: %s", Cmd); + return -1; + } + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + size_t BitLen = getFromGraphBuf(BitStream); + int errCnt=0; + errCnt = pskNRZrawDemod(BitStream, &BitLen,&clk,&invert); + if (errCnt<0|| BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first) + //PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); + return -1; + } + PrintAndLog("Tried PSK/NRZ Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen); + + //prime demod buffer for output + setDemodBuf(BitStream,BitLen); + return errCnt; } // Indala 26 bit decode // by marshmellow @@ -869,103 +871,103 @@ int PSKnrzDemod(const char *Cmd){ int CmdIndalaDecode(const char *Cmd) { - int ans=PSKnrzDemod(Cmd); - if (ans < 0){ - PrintAndLog("Error1: %d",ans); - return 0; - } - uint8_t invert=0; - ans = indala26decode(DemodBuffer, &DemodBufferLen, &invert); - if (ans < 1) { - PrintAndLog("Error2: %d",ans); - return -1; - } - char showbits[251]; - if(invert==1) PrintAndLog("Had to invert bits"); - //convert UID to HEX - uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7; - int idx; - uid1=0; - uid2=0; - PrintAndLog("BitLen: %d",DemodBufferLen); - if (DemodBufferLen==64){ - for( idx=0; idx<64; idx++) { - uid1=(uid1<<1)|(uid2>>31); - if (DemodBuffer[idx] == 0) { - uid2=(uid2<<1)|0; - showbits[idx]='0'; - } else { - uid2=(uid2<<1)|1; - showbits[idx]='1'; - } - } - showbits[idx]='\0'; - PrintAndLog("Indala UID=%s (%x%08x)", showbits, uid1, uid2); - } - else { - uid3=0; - uid4=0; - uid5=0; - uid6=0; - uid7=0; - for( idx=0; idx>31); - uid2=(uid2<<1)|(uid3>>31); - uid3=(uid3<<1)|(uid4>>31); - uid4=(uid4<<1)|(uid5>>31); - uid5=(uid5<<1)|(uid6>>31); - uid6=(uid6<<1)|(uid7>>31); - if (DemodBuffer[idx] == 0) { - uid7=(uid7<<1)|0; - showbits[idx]='0'; - } - else { - uid7=(uid7<<1)|1; - showbits[idx]='1'; - } - } - showbits[idx]='\0'; - PrintAndLog("Indala UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7); - } - return 1; + int ans=PSKnrzDemod(Cmd); + if (ans < 0){ + PrintAndLog("Error1: %d",ans); + return 0; + } + uint8_t invert=0; + ans = indala26decode(DemodBuffer,(size_t *) &DemodBufferLen, &invert); + if (ans < 1) { + PrintAndLog("Error2: %d",ans); + return -1; + } + char showbits[251]; + if(invert==1) PrintAndLog("Had to invert bits"); + //convert UID to HEX + uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7; + int idx; + uid1=0; + uid2=0; + PrintAndLog("BitLen: %d",DemodBufferLen); + if (DemodBufferLen==64){ + for( idx=0; idx<64; idx++) { + uid1=(uid1<<1)|(uid2>>31); + if (DemodBuffer[idx] == 0) { + uid2=(uid2<<1)|0; + showbits[idx]='0'; + } else { + uid2=(uid2<<1)|1; + showbits[idx]='1'; + } + } + showbits[idx]='\0'; + PrintAndLog("Indala UID=%s (%x%08x)", showbits, uid1, uid2); + } + else { + uid3=0; + uid4=0; + uid5=0; + uid6=0; + uid7=0; + for( idx=0; idx>31); + uid2=(uid2<<1)|(uid3>>31); + uid3=(uid3<<1)|(uid4>>31); + uid4=(uid4<<1)|(uid5>>31); + uid5=(uid5<<1)|(uid6>>31); + uid6=(uid6<<1)|(uid7>>31); + if (DemodBuffer[idx] == 0) { + uid7=(uid7<<1)|0; + showbits[idx]='0'; + } + else { + uid7=(uid7<<1)|1; + showbits[idx]='1'; + } + } + showbits[idx]='\0'; + PrintAndLog("Indala UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7); + } + return 1; } /* //by marshmellow (attempt to get rid of high immediately after a low) void pskCleanWave2(uint8_t *bitStream, int bitLen) { - int i; - int low=128; - int gap = 4; + int i; + int low=128; + int gap = 4; // int loopMax = 2048; - int newLow=0; + int newLow=0; - for (i=0; i0){ - PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); - } - PrintAndLog("PSK or NRZ demoded bitstream:"); - // Now output the bitstream to the scrollback by line of 16 bits - printDemodBuff(); - - return 1; + int errCnt= PSKnrzDemod(Cmd); + //output + if (errCnt<0) return 0; + if (errCnt>0){ + PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); + } + PrintAndLog("PSK or NRZ demoded bitstream:"); + // Now output the bitstream to the scrollback by line of 16 bits + printDemodBuff(); + + return 1; } int CmdGrid(const char *Cmd) { - sscanf(Cmd, "%i %i", &PlotGridX, &PlotGridY); - PlotGridXdefault= PlotGridX; - PlotGridYdefault= PlotGridY; - RepaintGraphWindow(); - return 0; + sscanf(Cmd, "%i %i", &PlotGridX, &PlotGridY); + PlotGridXdefault= PlotGridX; + PlotGridYdefault= PlotGridY; + RepaintGraphWindow(); + return 0; } int CmdHexsamples(const char *Cmd) { - int i, j; - int requested = 0; - int offset = 0; - char string_buf[25]; - char* string_ptr = string_buf; - uint8_t got[40000]; - - sscanf(Cmd, "%i %i", &requested, &offset); + int i, j; + int requested = 0; + int offset = 0; + char string_buf[25]; + char* string_ptr = string_buf; + uint8_t got[40000]; - /* if no args send something */ - if (requested == 0) { - requested = 8; - } - if (offset + requested > sizeof(got)) { - PrintAndLog("Tried to read past end of buffer, + > 40000"); - return 0; - } + sscanf(Cmd, "%i %i", &requested, &offset); - GetFromBigBuf(got,requested,offset); - WaitForResponse(CMD_ACK,NULL); + /* if no args send something */ + if (requested == 0) { + requested = 8; + } + if (offset + requested > sizeof(got)) { + PrintAndLog("Tried to read past end of buffer, + > 40000"); + return 0; + } - i = 0; - for (j = 0; j < requested; j++) { - i++; - string_ptr += sprintf(string_ptr, "%02x ", got[j]); - if (i == 8) { - *(string_ptr - 1) = '\0'; // remove the trailing space - PrintAndLog("%s", string_buf); - string_buf[0] = '\0'; - string_ptr = string_buf; - i = 0; - } - if (j == requested - 1 && string_buf[0] != '\0') { // print any remaining bytes - *(string_ptr - 1) = '\0'; - PrintAndLog("%s", string_buf); - string_buf[0] = '\0'; - } - } - return 0; + GetFromBigBuf(got,requested,offset); + WaitForResponse(CMD_ACK,NULL); + + i = 0; + for (j = 0; j < requested; j++) { + i++; + string_ptr += sprintf(string_ptr, "%02x ", got[j]); + if (i == 8) { + *(string_ptr - 1) = '\0'; // remove the trailing space + PrintAndLog("%s", string_buf); + string_buf[0] = '\0'; + string_ptr = string_buf; + i = 0; + } + if (j == requested - 1 && string_buf[0] != '\0') { // print any remaining bytes + *(string_ptr - 1) = '\0'; + PrintAndLog("%s", string_buf); + string_buf[0] = '\0'; + } + } + return 0; } int CmdHide(const char *Cmd) { - HideGraphWindow(); - return 0; + HideGraphWindow(); + return 0; } int CmdHpf(const char *Cmd) { - int i; - int accum = 0; + int i; + int accum = 0; - for (i = 10; i < GraphTraceLen; ++i) - accum += GraphBuffer[i]; - accum /= (GraphTraceLen - 10); - for (i = 0; i < GraphTraceLen; ++i) - GraphBuffer[i] -= accum; + for (i = 10; i < GraphTraceLen; ++i) + accum += GraphBuffer[i]; + accum /= (GraphTraceLen - 10); + for (i = 0; i < GraphTraceLen; ++i) + GraphBuffer[i] -= accum; - RepaintGraphWindow(); - return 0; + RepaintGraphWindow(); + return 0; } int CmdSamples(const char *Cmd) { - int cnt = 0; - int n; - uint8_t got[40000]; + int cnt = 0; + int n; + uint8_t got[40000]; - n = strtol(Cmd, NULL, 0); - if (n == 0) n = 6000; - if (n > sizeof(got)) n = sizeof(got); - - PrintAndLog("Reading %d samples\n", n); - GetFromBigBuf(got,n,0); - WaitForResponse(CMD_ACK,NULL); - for (int j = 0; j < n; j++) { - GraphBuffer[cnt++] = ((int)got[j]) - 128; - } - - PrintAndLog("Done!\n"); - GraphTraceLen = n; - RepaintGraphWindow(); - return 0; + n = strtol(Cmd, NULL, 0); + if (n == 0) n = 6000; + if (n > sizeof(got)) n = sizeof(got); + + PrintAndLog("Reading %d samples\n", n); + GetFromBigBuf(got,n,0); + WaitForResponse(CMD_ACK,NULL); + for (int j = 0; j < n; j++) { + GraphBuffer[cnt++] = ((int)got[j]) - 128; + } + + PrintAndLog("Done!\n"); + GraphTraceLen = n; + RepaintGraphWindow(); + return 0; } int CmdTuneSamples(const char *Cmd) { - int cnt = 0; - int n = 255; - uint8_t got[255]; + int cnt = 0; + int n = 255; + uint8_t got[255]; - PrintAndLog("Reading %d samples\n", n); - GetFromBigBuf(got,n,7256); // armsrc/apps.h: #define FREE_BUFFER_OFFSET 7256 - WaitForResponse(CMD_ACK,NULL); - for (int j = 0; j < n; j++) { - GraphBuffer[cnt++] = ((int)got[j]) - 128; - } - - PrintAndLog("Done! Divisor 89 is 134khz, 95 is 125khz.\n"); - PrintAndLog("\n"); - GraphTraceLen = n; - RepaintGraphWindow(); - return 0; + PrintAndLog("Reading %d samples\n", n); + GetFromBigBuf(got,n,7256); // armsrc/apps.h: #define FREE_BUFFER_OFFSET 7256 + WaitForResponse(CMD_ACK,NULL); + for (int j = 0; j < n; j++) { + GraphBuffer[cnt++] = ((int)got[j]) - 128; + } + + PrintAndLog("Done! Divisor 89 is 134khz, 95 is 125khz.\n"); + PrintAndLog("\n"); + GraphTraceLen = n; + RepaintGraphWindow(); + return 0; } int CmdLoad(const char *Cmd) { - FILE *f = fopen(Cmd, "r"); - if (!f) { - PrintAndLog("couldn't open '%s'", Cmd); - return 0; - } + FILE *f = fopen(Cmd, "r"); + if (!f) { + PrintAndLog("couldn't open '%s'", Cmd); + return 0; + } - GraphTraceLen = 0; - char line[80]; - while (fgets(line, sizeof (line), f)) { - GraphBuffer[GraphTraceLen] = atoi(line); - GraphTraceLen++; - } - fclose(f); - PrintAndLog("loaded %d samples", GraphTraceLen); - RepaintGraphWindow(); - return 0; + GraphTraceLen = 0; + char line[80]; + while (fgets(line, sizeof (line), f)) { + GraphBuffer[GraphTraceLen] = atoi(line); + GraphTraceLen++; + } + fclose(f); + PrintAndLog("loaded %d samples", GraphTraceLen); + RepaintGraphWindow(); + return 0; } int CmdLtrim(const char *Cmd) { - int ds = atoi(Cmd); + int ds = atoi(Cmd); - for (int i = ds; i < GraphTraceLen; ++i) - GraphBuffer[i-ds] = GraphBuffer[i]; - GraphTraceLen -= ds; + for (int i = ds; i < GraphTraceLen; ++i) + GraphBuffer[i-ds] = GraphBuffer[i]; + GraphTraceLen -= ds; - RepaintGraphWindow(); - return 0; + RepaintGraphWindow(); + return 0; } int CmdRtrim(const char *Cmd) { - int ds = atoi(Cmd); + int ds = atoi(Cmd); - GraphTraceLen = ds; + GraphTraceLen = ds; - RepaintGraphWindow(); - return 0; + RepaintGraphWindow(); + return 0; } /* @@ -1161,416 +1163,416 @@ int CmdRtrim(const char *Cmd) */ int CmdManchesterDemod(const char *Cmd) { - int i, j, invert= 0; - int bit; - int clock; - int lastval = 0; - int low = 0; - int high = 0; - int hithigh, hitlow, first; - int lc = 0; - int bitidx = 0; - int bit2idx = 0; - int warnings = 0; + int i, j, invert= 0; + int bit; + int clock; + int lastval = 0; + int low = 0; + int high = 0; + int hithigh, hitlow, first; + int lc = 0; + int bitidx = 0; + int bit2idx = 0; + int warnings = 0; - /* check if we're inverting output */ - if (*Cmd == 'i') - { - PrintAndLog("Inverting output"); - invert = 1; - ++Cmd; - do - ++Cmd; - while(*Cmd == ' '); // in case a 2nd argument was given - } + /* check if we're inverting output */ + if (*Cmd == 'i') + { + PrintAndLog("Inverting output"); + invert = 1; + ++Cmd; + do + ++Cmd; + while(*Cmd == ' '); // in case a 2nd argument was given + } - /* Holds the decoded bitstream: each clock period contains 2 bits */ - /* later simplified to 1 bit after manchester decoding. */ - /* Add 10 bits to allow for noisy / uncertain traces without aborting */ - /* int BitStream[GraphTraceLen*2/clock+10]; */ + /* Holds the decoded bitstream: each clock period contains 2 bits */ + /* later simplified to 1 bit after manchester decoding. */ + /* Add 10 bits to allow for noisy / uncertain traces without aborting */ + /* int BitStream[GraphTraceLen*2/clock+10]; */ - /* But it does not work if compiling on WIndows: therefore we just allocate a */ - /* large array */ - uint8_t BitStream[MAX_GRAPH_TRACE_LEN] = {0}; + /* But it does not work if compiling on WIndows: therefore we just allocate a */ + /* large array */ + uint8_t BitStream[MAX_GRAPH_TRACE_LEN] = {0}; - /* Detect high and lows */ - for (i = 0; i < GraphTraceLen; i++) - { - if (GraphBuffer[i] > high) - high = GraphBuffer[i]; - else if (GraphBuffer[i] < low) - low = GraphBuffer[i]; - } + /* Detect high and lows */ + for (i = 0; i < GraphTraceLen; i++) + { + if (GraphBuffer[i] > high) + high = GraphBuffer[i]; + else if (GraphBuffer[i] < low) + low = GraphBuffer[i]; + } - /* Get our clock */ - clock = GetClock(Cmd, high, 1); + /* Get our clock */ + clock = GetClock(Cmd, high, 1); - int tolerance = clock/4; + int tolerance = clock/4; - /* Detect first transition */ - /* Lo-Hi (arbitrary) */ - /* skip to the first high */ - for (i= 0; i < GraphTraceLen; i++) - if (GraphBuffer[i] == high) - break; - /* now look for the first low */ - for (; i < GraphTraceLen; i++) - { - if (GraphBuffer[i] == low) - { - lastval = i; - break; - } - } + /* Detect first transition */ + /* Lo-Hi (arbitrary) */ + /* skip to the first high */ + for (i= 0; i < GraphTraceLen; i++) + if (GraphBuffer[i] == high) + break; + /* now look for the first low */ + for (; i < GraphTraceLen; i++) + { + if (GraphBuffer[i] == low) + { + lastval = i; + break; + } + } - /* If we're not working with 1/0s, demod based off clock */ - if (high != 1) - { - bit = 0; /* We assume the 1st bit is zero, it may not be - * the case: this routine (I think) has an init problem. - * Ed. - */ - for (; i < (int)(GraphTraceLen / clock); i++) - { - hithigh = 0; - hitlow = 0; - first = 1; + /* If we're not working with 1/0s, demod based off clock */ + if (high != 1) + { + bit = 0; /* We assume the 1st bit is zero, it may not be + * the case: this routine (I think) has an init problem. + * Ed. + */ + for (; i < (int)(GraphTraceLen / clock); i++) + { + hithigh = 0; + hitlow = 0; + first = 1; - /* Find out if we hit both high and low peaks */ - for (j = 0; j < clock; j++) - { - if (GraphBuffer[(i * clock) + j] == high) - hithigh = 1; - else if (GraphBuffer[(i * clock) + j] == low) - hitlow = 1; + /* Find out if we hit both high and low peaks */ + for (j = 0; j < clock; j++) + { + if (GraphBuffer[(i * clock) + j] == high) + hithigh = 1; + else if (GraphBuffer[(i * clock) + j] == low) + hitlow = 1; - /* it doesn't count if it's the first part of our read - because it's really just trailing from the last sequence */ - if (first && (hithigh || hitlow)) - hithigh = hitlow = 0; - else - first = 0; + /* it doesn't count if it's the first part of our read + because it's really just trailing from the last sequence */ + if (first && (hithigh || hitlow)) + hithigh = hitlow = 0; + else + first = 0; - if (hithigh && hitlow) - break; - } + if (hithigh && hitlow) + break; + } - /* If we didn't hit both high and low peaks, we had a bit transition */ - if (!hithigh || !hitlow) - bit ^= 1; + /* If we didn't hit both high and low peaks, we had a bit transition */ + if (!hithigh || !hitlow) + bit ^= 1; - BitStream[bit2idx++] = bit ^ invert; - } - } + BitStream[bit2idx++] = bit ^ invert; + } + } - /* standard 1/0 bitstream */ - else - { + /* standard 1/0 bitstream */ + else + { - /* Then detect duration between 2 successive transitions */ - for (bitidx = 1; i < GraphTraceLen; i++) - { - if (GraphBuffer[i-1] != GraphBuffer[i]) - { - lc = i-lastval; - lastval = i; + /* Then detect duration between 2 successive transitions */ + for (bitidx = 1; i < GraphTraceLen; i++) + { + if (GraphBuffer[i-1] != GraphBuffer[i]) + { + lc = i-lastval; + lastval = i; - // Error check: if bitidx becomes too large, we do not - // have a Manchester encoded bitstream or the clock is really - // wrong! - if (bitidx > (GraphTraceLen*2/clock+8) ) { - PrintAndLog("Error: the clock you gave is probably wrong, aborting."); - return 0; - } - // Then switch depending on lc length: - // Tolerance is 1/4 of clock rate (arbitrary) - if (abs(lc-clock/2) < tolerance) { - // Short pulse : either "1" or "0" - BitStream[bitidx++]=GraphBuffer[i-1]; - } else if (abs(lc-clock) < tolerance) { - // Long pulse: either "11" or "00" - BitStream[bitidx++]=GraphBuffer[i-1]; - BitStream[bitidx++]=GraphBuffer[i-1]; - } else { - // Error - warnings++; - PrintAndLog("Warning: Manchester decode error for pulse width detection."); - PrintAndLog("(too many of those messages mean either the stream is not Manchester encoded, or clock is wrong)"); + // Error check: if bitidx becomes too large, we do not + // have a Manchester encoded bitstream or the clock is really + // wrong! + if (bitidx > (GraphTraceLen*2/clock+8) ) { + PrintAndLog("Error: the clock you gave is probably wrong, aborting."); + return 0; + } + // Then switch depending on lc length: + // Tolerance is 1/4 of clock rate (arbitrary) + if (abs(lc-clock/2) < tolerance) { + // Short pulse : either "1" or "0" + BitStream[bitidx++]=GraphBuffer[i-1]; + } else if (abs(lc-clock) < tolerance) { + // Long pulse: either "11" or "00" + BitStream[bitidx++]=GraphBuffer[i-1]; + BitStream[bitidx++]=GraphBuffer[i-1]; + } else { + // Error + warnings++; + PrintAndLog("Warning: Manchester decode error for pulse width detection."); + PrintAndLog("(too many of those messages mean either the stream is not Manchester encoded, or clock is wrong)"); - if (warnings > 10) - { - PrintAndLog("Error: too many detection errors, aborting."); - return 0; - } - } - } - } + if (warnings > 10) + { + PrintAndLog("Error: too many detection errors, aborting."); + return 0; + } + } + } + } - // At this stage, we now have a bitstream of "01" ("1") or "10" ("0"), parse it into final decoded bitstream - // Actually, we overwrite BitStream with the new decoded bitstream, we just need to be careful - // to stop output at the final bitidx2 value, not bitidx - for (i = 0; i < bitidx; i += 2) { - if ((BitStream[i] == 0) && (BitStream[i+1] == 1)) { - BitStream[bit2idx++] = 1 ^ invert; - } else if ((BitStream[i] == 1) && (BitStream[i+1] == 0)) { - BitStream[bit2idx++] = 0 ^ invert; - } else { - // We cannot end up in this state, this means we are unsynchronized, - // move up 1 bit: - i++; - warnings++; - PrintAndLog("Unsynchronized, resync..."); - PrintAndLog("(too many of those messages mean the stream is not Manchester encoded)"); + // At this stage, we now have a bitstream of "01" ("1") or "10" ("0"), parse it into final decoded bitstream + // Actually, we overwrite BitStream with the new decoded bitstream, we just need to be careful + // to stop output at the final bitidx2 value, not bitidx + for (i = 0; i < bitidx; i += 2) { + if ((BitStream[i] == 0) && (BitStream[i+1] == 1)) { + BitStream[bit2idx++] = 1 ^ invert; + } else if ((BitStream[i] == 1) && (BitStream[i+1] == 0)) { + BitStream[bit2idx++] = 0 ^ invert; + } else { + // We cannot end up in this state, this means we are unsynchronized, + // move up 1 bit: + i++; + warnings++; + PrintAndLog("Unsynchronized, resync..."); + PrintAndLog("(too many of those messages mean the stream is not Manchester encoded)"); - if (warnings > 10) - { - PrintAndLog("Error: too many decode errors, aborting."); - return 0; - } - } - } - } + if (warnings > 10) + { + PrintAndLog("Error: too many decode errors, aborting."); + return 0; + } + } + } + } - PrintAndLog("Manchester decoded bitstream"); - // Now output the bitstream to the scrollback by line of 16 bits - for (i = 0; i < (bit2idx-16); i+=16) { - PrintAndLog("%i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i", - BitStream[i], - BitStream[i+1], - BitStream[i+2], - BitStream[i+3], - BitStream[i+4], - BitStream[i+5], - BitStream[i+6], - BitStream[i+7], - BitStream[i+8], - BitStream[i+9], - BitStream[i+10], - BitStream[i+11], - BitStream[i+12], - BitStream[i+13], - BitStream[i+14], - BitStream[i+15]); - } - return 0; + PrintAndLog("Manchester decoded bitstream"); + // Now output the bitstream to the scrollback by line of 16 bits + for (i = 0; i < (bit2idx-16); i+=16) { + PrintAndLog("%i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i", + BitStream[i], + BitStream[i+1], + BitStream[i+2], + BitStream[i+3], + BitStream[i+4], + BitStream[i+5], + BitStream[i+6], + BitStream[i+7], + BitStream[i+8], + BitStream[i+9], + BitStream[i+10], + BitStream[i+11], + BitStream[i+12], + BitStream[i+13], + BitStream[i+14], + BitStream[i+15]); + } + return 0; } /* Modulate our data into manchester */ int CmdManchesterMod(const char *Cmd) { - int i, j; - int clock; - int bit, lastbit, wave; + int i, j; + int clock; + int bit, lastbit, wave; - /* Get our clock */ - clock = GetClock(Cmd, 0, 1); + /* Get our clock */ + clock = GetClock(Cmd, 0, 1); - wave = 0; - lastbit = 1; - for (i = 0; i < (int)(GraphTraceLen / clock); i++) - { - bit = GraphBuffer[i * clock] ^ 1; + wave = 0; + lastbit = 1; + for (i = 0; i < (int)(GraphTraceLen / clock); i++) + { + bit = GraphBuffer[i * clock] ^ 1; - for (j = 0; j < (int)(clock/2); j++) - GraphBuffer[(i * clock) + j] = bit ^ lastbit ^ wave; - for (j = (int)(clock/2); j < clock; j++) - GraphBuffer[(i * clock) + j] = bit ^ lastbit ^ wave ^ 1; + for (j = 0; j < (int)(clock/2); j++) + GraphBuffer[(i * clock) + j] = bit ^ lastbit ^ wave; + for (j = (int)(clock/2); j < clock; j++) + GraphBuffer[(i * clock) + j] = bit ^ lastbit ^ wave ^ 1; - /* Keep track of how we start our wave and if we changed or not this time */ - wave ^= bit ^ lastbit; - lastbit = bit; - } + /* Keep track of how we start our wave and if we changed or not this time */ + wave ^= bit ^ lastbit; + lastbit = bit; + } - RepaintGraphWindow(); - return 0; + RepaintGraphWindow(); + return 0; } int CmdNorm(const char *Cmd) { - int i; - int max = INT_MIN, min = INT_MAX; + int i; + int max = INT_MIN, min = INT_MAX; - for (i = 10; i < GraphTraceLen; ++i) { - if (GraphBuffer[i] > max) - max = GraphBuffer[i]; - if (GraphBuffer[i] < min) - min = GraphBuffer[i]; - } + for (i = 10; i < GraphTraceLen; ++i) { + if (GraphBuffer[i] > max) + max = GraphBuffer[i]; + if (GraphBuffer[i] < min) + min = GraphBuffer[i]; + } - if (max != min) { - for (i = 0; i < GraphTraceLen; ++i) { - GraphBuffer[i] = (GraphBuffer[i] - ((max + min) / 2)) * 256 / - (max - min); - //marshmelow: adjusted *1000 to *256 to make +/- 128 so demod commands still work - } - } - RepaintGraphWindow(); - return 0; + if (max != min) { + for (i = 0; i < GraphTraceLen; ++i) { + GraphBuffer[i] = (GraphBuffer[i] - ((max + min) / 2)) * 256 / + (max - min); + //marshmelow: adjusted *1000 to *256 to make +/- 128 so demod commands still work + } + } + RepaintGraphWindow(); + return 0; } int CmdPlot(const char *Cmd) { - ShowGraphWindow(); - return 0; + ShowGraphWindow(); + return 0; } int CmdSave(const char *Cmd) { - FILE *f = fopen(Cmd, "w"); - if(!f) { - PrintAndLog("couldn't open '%s'", Cmd); - return 0; - } - int i; - for (i = 0; i < GraphTraceLen; i++) { - fprintf(f, "%d\n", GraphBuffer[i]); - } - fclose(f); - PrintAndLog("saved to '%s'", Cmd); - return 0; + FILE *f = fopen(Cmd, "w"); + if(!f) { + PrintAndLog("couldn't open '%s'", Cmd); + return 0; + } + int i; + for (i = 0; i < GraphTraceLen; i++) { + fprintf(f, "%d\n", GraphBuffer[i]); + } + fclose(f); + PrintAndLog("saved to '%s'", Cmd); + return 0; } int CmdScale(const char *Cmd) { - CursorScaleFactor = atoi(Cmd); - if (CursorScaleFactor == 0) { - PrintAndLog("bad, can't have zero scale"); - CursorScaleFactor = 1; - } - RepaintGraphWindow(); - return 0; + CursorScaleFactor = atoi(Cmd); + if (CursorScaleFactor == 0) { + PrintAndLog("bad, can't have zero scale"); + CursorScaleFactor = 1; + } + RepaintGraphWindow(); + return 0; } int CmdThreshold(const char *Cmd) { - int threshold = atoi(Cmd); + int threshold = atoi(Cmd); - for (int i = 0; i < GraphTraceLen; ++i) { - if (GraphBuffer[i] >= threshold) - GraphBuffer[i] = 1; - else - GraphBuffer[i] = -1; - } - RepaintGraphWindow(); - return 0; + for (int i = 0; i < GraphTraceLen; ++i) { + if (GraphBuffer[i] >= threshold) + GraphBuffer[i] = 1; + else + GraphBuffer[i] = -1; + } + RepaintGraphWindow(); + return 0; } int CmdDirectionalThreshold(const char *Cmd) { int8_t upThres = param_get8(Cmd, 0); int8_t downThres = param_get8(Cmd, 1); - - printf("Applying Up Threshold: %d, Down Threshold: %d\n", upThres, downThres); - - int lastValue = GraphBuffer[0]; - GraphBuffer[0] = 0; // Will be changed at the end, but init 0 as we adjust to last samples value if no threshold kicks in. - - for (int i = 1; i < GraphTraceLen; ++i) { - // Apply first threshold to samples heading up - if (GraphBuffer[i] >= upThres && GraphBuffer[i] > lastValue) - { - lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it. - GraphBuffer[i] = 1; - } - // Apply second threshold to samples heading down - else if (GraphBuffer[i] <= downThres && GraphBuffer[i] < lastValue) - { - lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it. - GraphBuffer[i] = -1; - } - else - { - lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it. - GraphBuffer[i] = GraphBuffer[i-1]; - } - } - GraphBuffer[0] = GraphBuffer[1]; // Aline with first edited sample. - RepaintGraphWindow(); - return 0; + printf("Applying Up Threshold: %d, Down Threshold: %d\n", upThres, downThres); + + int lastValue = GraphBuffer[0]; + GraphBuffer[0] = 0; // Will be changed at the end, but init 0 as we adjust to last samples value if no threshold kicks in. + + for (int i = 1; i < GraphTraceLen; ++i) { + // Apply first threshold to samples heading up + if (GraphBuffer[i] >= upThres && GraphBuffer[i] > lastValue) + { + lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it. + GraphBuffer[i] = 1; + } + // Apply second threshold to samples heading down + else if (GraphBuffer[i] <= downThres && GraphBuffer[i] < lastValue) + { + lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it. + GraphBuffer[i] = -1; + } + else + { + lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it. + GraphBuffer[i] = GraphBuffer[i-1]; + + } + } + GraphBuffer[0] = GraphBuffer[1]; // Aline with first edited sample. + RepaintGraphWindow(); + return 0; } int CmdZerocrossings(const char *Cmd) { - // Zero-crossings aren't meaningful unless the signal is zero-mean. - CmdHpf(""); + // Zero-crossings aren't meaningful unless the signal is zero-mean. + CmdHpf(""); - int sign = 1; - int zc = 0; - int lastZc = 0; + int sign = 1; + int zc = 0; + int lastZc = 0; - for (int i = 0; i < GraphTraceLen; ++i) { - if (GraphBuffer[i] * sign >= 0) { - // No change in sign, reproduce the previous sample count. - zc++; - GraphBuffer[i] = lastZc; - } else { - // Change in sign, reset the sample count. - sign = -sign; - GraphBuffer[i] = lastZc; - if (sign > 0) { - lastZc = zc; - zc = 0; - } - } - } + for (int i = 0; i < GraphTraceLen; ++i) { + if (GraphBuffer[i] * sign >= 0) { + // No change in sign, reproduce the previous sample count. + zc++; + GraphBuffer[i] = lastZc; + } else { + // Change in sign, reset the sample count. + sign = -sign; + GraphBuffer[i] = lastZc; + if (sign > 0) { + lastZc = zc; + zc = 0; + } + } + } - RepaintGraphWindow(); - return 0; + RepaintGraphWindow(); + return 0; } -static command_t CommandTable[] = +static command_t CommandTable[] = { - {"help", CmdHelp, 1, "This help"}, - {"amp", CmdAmp, 1, "Amplify peaks"}, - {"askdemod", Cmdaskdemod, 1, "<0 or 1> -- Attempt to demodulate simple ASK tags"}, - {"askmandemod", Cmdaskmandemod, 1, "[clock] [invert<0 or 1>] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional[clock will try Auto-detect])"}, - {"askrawdemod", Cmdaskrawdemod, 1, "[clock] [invert<0 or 1>] -- Attempt to demodulate ASK tags and output binary (args optional[clock will try Auto-detect])"}, - {"autocorr", CmdAutoCorr, 1, " -- Autocorrelation over window"}, - {"biphaserawdecode",CmdBiphaseDecodeRaw,1,"[offset] Biphase decode binary stream already in graph buffer (offset = bit to start decode from)"}, - {"bitsamples", CmdBitsamples, 0, "Get raw samples as bitstring"}, - {"bitstream", CmdBitstream, 1, "[clock rate] -- Convert waveform into a bitstream"}, - {"buffclear", CmdBuffClear, 1, "Clear sample buffer and graph window"}, - {"dec", CmdDec, 1, "Decimate samples"}, - {"detectclock", CmdDetectClockRate, 1, "Detect ASK, PSK, or NRZ clock rate"}, - {"fskdemod", CmdFSKdemod, 1, "Demodulate graph window as a HID FSK"}, - {"fskhiddemod", CmdFSKdemodHID, 1, "Demodulate graph window as a HID FSK using raw"}, - {"fskiodemod", CmdFSKdemodIO, 1, "Demodulate graph window as an IO Prox FSK using raw"}, - {"fskrawdemod", CmdFSKrawdemod, 1, "[clock rate] [invert] [rchigh] [rclow] Demodulate graph window from FSK to binary (clock = 50)(invert = 1 or 0)(rchigh = 10)(rclow=8)"}, - {"grid", CmdGrid, 1, " -- overlay grid on graph window, use zero value to turn off either"}, - {"hexsamples", CmdHexsamples, 0, " [] -- Dump big buffer as hex bytes"}, - {"hide", CmdHide, 1, "Hide graph window"}, - {"hpf", CmdHpf, 1, "Remove DC offset from trace"}, - {"load", CmdLoad, 1, " -- Load trace (to graph window"}, - {"ltrim", CmdLtrim, 1, " -- Trim samples from left of trace"}, - {"rtrim", CmdRtrim, 1, " -- Trim samples from right of trace"}, - {"mandemod", CmdManchesterDemod, 1, "[i] [clock rate] -- Manchester demodulate binary stream (option 'i' to invert output)"}, - {"manrawdecode", Cmdmandecoderaw, 1, "Manchester decode binary stream already in graph buffer"}, - {"manmod", CmdManchesterMod, 1, "[clock rate] -- Manchester modulate a binary stream"}, - {"norm", CmdNorm, 1, "Normalize max/min to +/-128"}, - {"plot", CmdPlot, 1, "Show graph window (hit 'h' in window for keystroke help)"}, - {"pskclean", CmdPskClean, 1, "Attempt to clean psk wave"}, - {"pskdetectclock",CmdDetectNRZpskClockRate, 1, "Detect ASK, PSK, or NRZ clock rate"}, - {"pskindalademod",CmdIndalaDecode, 1, "[clock] [invert<0 or 1>] -- Attempt to demodulate psk indala tags and output ID binary & hex (args optional[clock will try Auto-detect])"}, - {"psknrzrawdemod",CmdpskNRZrawDemod, 1, "[clock] [invert<0 or 1>] -- Attempt to demodulate psk or nrz tags and output binary (args optional[clock will try Auto-detect])"}, - {"samples", CmdSamples, 0, "[512 - 40000] -- Get raw samples for graph window"}, - {"save", CmdSave, 1, " -- Save trace (from graph window)"}, - {"scale", CmdScale, 1, " -- Set cursor display scale"}, - {"threshold", CmdThreshold, 1, " -- Maximize/minimize every value in the graph window depending on threshold"}, - {"dirthreshold", CmdDirectionalThreshold, 1, " -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev."}, - {"tune", CmdTuneSamples, 0, "Get hw tune samples for graph window"}, - {"zerocrossings", CmdZerocrossings, 1, "Count time between zero-crossings"}, - {NULL, NULL, 0, NULL} + {"help", CmdHelp, 1, "This help"}, + {"amp", CmdAmp, 1, "Amplify peaks"}, + {"askdemod", Cmdaskdemod, 1, "<0 or 1> -- Attempt to demodulate simple ASK tags"}, + {"askmandemod", Cmdaskmandemod, 1, "[clock] [invert<0 or 1>] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional[clock will try Auto-detect])"}, + {"askrawdemod", Cmdaskrawdemod, 1, "[clock] [invert<0 or 1>] -- Attempt to demodulate ASK tags and output binary (args optional[clock will try Auto-detect])"}, + {"autocorr", CmdAutoCorr, 1, " -- Autocorrelation over window"}, + {"biphaserawdecode",CmdBiphaseDecodeRaw,1,"[offset] Biphase decode binary stream already in graph buffer (offset = bit to start decode from)"}, + {"bitsamples", CmdBitsamples, 0, "Get raw samples as bitstring"}, + {"bitstream", CmdBitstream, 1, "[clock rate] -- Convert waveform into a bitstream"}, + {"buffclear", CmdBuffClear, 1, "Clear sample buffer and graph window"}, + {"dec", CmdDec, 1, "Decimate samples"}, + {"detectclock", CmdDetectClockRate, 1, "Detect ASK clock rate"}, + {"fskdemod", CmdFSKdemod, 1, "Demodulate graph window as a HID FSK"}, + {"fskhiddemod", CmdFSKdemodHID, 1, "Demodulate graph window as a HID FSK using raw"}, + {"fskiodemod", CmdFSKdemodIO, 1, "Demodulate graph window as an IO Prox FSK using raw"}, + {"fskrawdemod", CmdFSKrawdemod, 1, "[clock rate] [invert] [rchigh] [rclow] Demodulate graph window from FSK to binary (clock = 50)(invert = 1 or 0)(rchigh = 10)(rclow=8)"}, + {"grid", CmdGrid, 1, " -- overlay grid on graph window, use zero value to turn off either"}, + {"hexsamples", CmdHexsamples, 0, " [] -- Dump big buffer as hex bytes"}, + {"hide", CmdHide, 1, "Hide graph window"}, + {"hpf", CmdHpf, 1, "Remove DC offset from trace"}, + {"load", CmdLoad, 1, " -- Load trace (to graph window"}, + {"ltrim", CmdLtrim, 1, " -- Trim samples from left of trace"}, + {"rtrim", CmdRtrim, 1, " -- Trim samples from right of trace"}, + {"mandemod", CmdManchesterDemod, 1, "[i] [clock rate] -- Manchester demodulate binary stream (option 'i' to invert output)"}, + {"manrawdecode", Cmdmandecoderaw, 1, "Manchester decode binary stream already in graph buffer"}, + {"manmod", CmdManchesterMod, 1, "[clock rate] -- Manchester modulate a binary stream"}, + {"norm", CmdNorm, 1, "Normalize max/min to +/-128"}, + {"plot", CmdPlot, 1, "Show graph window (hit 'h' in window for keystroke help)"}, + {"pskclean", CmdPskClean, 1, "Attempt to clean psk wave"}, + {"pskdetectclock",CmdDetectNRZpskClockRate, 1, "Detect ASK, PSK, or NRZ clock rate"}, + {"pskindalademod",CmdIndalaDecode, 1, "[clock] [invert<0 or 1>] -- Attempt to demodulate psk indala tags and output ID binary & hex (args optional[clock will try Auto-detect])"}, + {"psknrzrawdemod",CmdpskNRZrawDemod, 1, "[clock] [invert<0 or 1>] -- Attempt to demodulate psk or nrz tags and output binary (args optional[clock will try Auto-detect])"}, + {"samples", CmdSamples, 0, "[512 - 40000] -- Get raw samples for graph window"}, + {"save", CmdSave, 1, " -- Save trace (from graph window)"}, + {"scale", CmdScale, 1, " -- Set cursor display scale"}, + {"threshold", CmdThreshold, 1, " -- Maximize/minimize every value in the graph window depending on threshold"}, + {"dirthreshold", CmdDirectionalThreshold, 1, " -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev."}, + {"tune", CmdTuneSamples, 0, "Get hw tune samples for graph window"}, + {"zerocrossings", CmdZerocrossings, 1, "Count time between zero-crossings"}, + {NULL, NULL, 0, NULL} }; int CmdData(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; } diff --git a/client/cmdlf.c b/client/cmdlf.c index b39868973..af24aa809 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -12,6 +12,7 @@ #include #include #include +//#include "proxusb.h" #include "proxmark3.h" #include "data.h" #include "graph.h" @@ -33,594 +34,592 @@ static int CmdHelp(const char *Cmd); /* send a command before reading */ int CmdLFCommandRead(const char *Cmd) { - static char dummy[3]; + static char dummy[3]; - dummy[0]= ' '; + dummy[0]= ' '; - UsbCommand c = {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K}; - sscanf(Cmd, "%"lli" %"lli" %"lli" %s %s", &c.arg[0], &c.arg[1], &c.arg[2],(char*)(&c.d.asBytes),(char*)(&dummy+1)); - // in case they specified 'h' - strcpy((char *)&c.d.asBytes + strlen((char *)c.d.asBytes), dummy); - SendCommand(&c); - return 0; + UsbCommand c = {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K}; + sscanf(Cmd, "%"lli" %"lli" %"lli" %s %s", &c.arg[0], &c.arg[1], &c.arg[2],(char*)(&c.d.asBytes),(char*)(&dummy+1)); + // in case they specified 'h' + strcpy((char *)&c.d.asBytes + strlen((char *)c.d.asBytes), dummy); + SendCommand(&c); + return 0; } int CmdFlexdemod(const char *Cmd) { - int i; - for (i = 0; i < GraphTraceLen; ++i) { - if (GraphBuffer[i] < 0) { - GraphBuffer[i] = -1; - } else { - GraphBuffer[i] = 1; - } - } + int i; + for (i = 0; i < GraphTraceLen; ++i) { + if (GraphBuffer[i] < 0) { + GraphBuffer[i] = -1; + } else { + GraphBuffer[i] = 1; + } + } - #define LONG_WAIT 100 - int start; - for (start = 0; start < GraphTraceLen - LONG_WAIT; start++) { - int first = GraphBuffer[start]; - for (i = start; i < start + LONG_WAIT; i++) { - if (GraphBuffer[i] != first) { - break; - } - } - if (i == (start + LONG_WAIT)) { - break; - } - } - if (start == GraphTraceLen - LONG_WAIT) { - PrintAndLog("nothing to wait for"); - return 0; - } - - GraphBuffer[start] = 2; - GraphBuffer[start+1] = -2; - uint8_t bits[64] = {0x00}; - - int bit, sum; - i = start; - for (bit = 0; bit < 64; bit++) { - sum = 0; - for (int j = 0; j < 16; j++) { - sum += GraphBuffer[i++]; - } - - bits[bit] = (sum > 0) ? 1 : 0; - - PrintAndLog("bit %d sum %d", bit, sum); - } - - for (bit = 0; bit < 64; bit++) { - int j; - int sum = 0; - for (j = 0; j < 16; j++) { - sum += GraphBuffer[i++]; - } - if (sum > 0 && bits[bit] != 1) { - PrintAndLog("oops1 at %d", bit); - } - if (sum < 0 && bits[bit] != 0) { - PrintAndLog("oops2 at %d", bit); - } - } - - // HACK writing back to graphbuffer. - GraphTraceLen = 32*64; - i = 0; - int phase = 0; - for (bit = 0; bit < 64; bit++) { - - phase = (bits[bit] == 0) ? 0 : 1; - - int j; - for (j = 0; j < 32; j++) { - GraphBuffer[i++] = phase; - phase = !phase; - } - } - - RepaintGraphWindow(); - return 0; -} - -int CmdIndalaDemod(const char *Cmd) -{ - // Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID - - int state = -1; - int count = 0; - int i, j; - - // worst case with GraphTraceLen=64000 is < 4096 - // under normal conditions it's < 2048 - - uint8_t rawbits[4096]; - int rawbit = 0; - int worst = 0, worstPos = 0; - // PrintAndLog("Expecting a bit less than %d raw bits", GraphTraceLen / 32); - for (i = 0; i < GraphTraceLen-1; i += 2) { - count += 1; - if ((GraphBuffer[i] > GraphBuffer[i + 1]) && (state != 1)) { - if (state == 0) { - for (j = 0; j < count - 8; j += 16) { - rawbits[rawbit++] = 0; - } - if ((abs(count - j)) > worst) { - worst = abs(count - j); - worstPos = i; - } - } - state = 1; - count = 0; - } else if ((GraphBuffer[i] < GraphBuffer[i + 1]) && (state != 0)) { - if (state == 1) { - for (j = 0; j < count - 8; j += 16) { - rawbits[rawbit++] = 1; - } - if ((abs(count - j)) > worst) { - worst = abs(count - j); - worstPos = i; - } - } - state = 0; - count = 0; - } - } - - if (rawbit>0){ - PrintAndLog("Recovered %d raw bits, expected: %d", rawbit, GraphTraceLen/32); - PrintAndLog("worst metric (0=best..7=worst): %d at pos %d", worst, worstPos); - } else { + #define LONG_WAIT 100 + int start; + for (start = 0; start < GraphTraceLen - LONG_WAIT; start++) { + int first = GraphBuffer[start]; + for (i = start; i < start + LONG_WAIT; i++) { + if (GraphBuffer[i] != first) { + break; + } + } + if (i == (start + LONG_WAIT)) { + break; + } + } + if (start == GraphTraceLen - LONG_WAIT) { + PrintAndLog("nothing to wait for"); return 0; } - // Finding the start of a UID - int uidlen, long_wait; - if (strcmp(Cmd, "224") == 0) { - uidlen = 224; - long_wait = 30; - } else { - uidlen = 64; - long_wait = 29; - } + GraphBuffer[start] = 2; + GraphBuffer[start+1] = -2; - int start; - int first = 0; - for (start = 0; start <= rawbit - uidlen; start++) { - first = rawbits[start]; - for (i = start; i < start + long_wait; i++) { - if (rawbits[i] != first) { - break; - } - } - if (i == (start + long_wait)) { - break; - } - } - - if (start == rawbit - uidlen + 1) { - PrintAndLog("nothing to wait for"); - return 0; - } + uint8_t bits[64]; - // Inverting signal if needed - if (first == 1) { - for (i = start; i < rawbit; i++) { - rawbits[i] = !rawbits[i]; - } - } + int bit; + i = start; + for (bit = 0; bit < 64; bit++) { + int j; + int sum = 0; + for (j = 0; j < 16; j++) { + sum += GraphBuffer[i++]; + } + if (sum > 0) { + bits[bit] = 1; + } else { + bits[bit] = 0; + } + PrintAndLog("bit %d sum %d", bit, sum); + } - // Dumping UID - uint8_t bits[224] = {0x00}; - char showbits[225] = {0x00}; - int bit; - i = start; - int times = 0; + for (bit = 0; bit < 64; bit++) { + int j; + int sum = 0; + for (j = 0; j < 16; j++) { + sum += GraphBuffer[i++]; + } + if (sum > 0 && bits[bit] != 1) { + PrintAndLog("oops1 at %d", bit); + } + if (sum < 0 && bits[bit] != 0) { + PrintAndLog("oops2 at %d", bit); + } + } + + GraphTraceLen = 32*64; + i = 0; + int phase = 0; + for (bit = 0; bit < 64; bit++) { + if (bits[bit] == 0) { + phase = 0; + } else { + phase = 1; + } + int j; + for (j = 0; j < 32; j++) { + GraphBuffer[i++] = phase; + phase = !phase; + } + } + + RepaintGraphWindow(); + return 0; +} - if (uidlen > rawbit) { - PrintAndLog("Warning: not enough raw bits to get a full UID"); - for (bit = 0; bit < rawbit; bit++) { - bits[bit] = rawbits[i++]; - // As we cannot know the parity, let's use "." and "/" - showbits[bit] = '.' + bits[bit]; - } - showbits[bit+1]='\0'; - PrintAndLog("Partial UID=%s", showbits); - return 0; - } else { - for (bit = 0; bit < uidlen; bit++) { - bits[bit] = rawbits[i++]; - showbits[bit] = '0' + bits[bit]; - } - times = 1; - } - - //convert UID to HEX - uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7; - int idx; - uid1 = uid2 = 0; +int CmdIndalaDemod(const char *Cmd) +{ + // Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID + + int state = -1; + int count = 0; + int i, j; + // worst case with GraphTraceLen=64000 is < 4096 + // under normal conditions it's < 2048 + uint8_t rawbits[4096]; + int rawbit = 0; + int worst = 0, worstPos = 0; + // PrintAndLog("Expecting a bit less than %d raw bits", GraphTraceLen / 32); + for (i = 0; i < GraphTraceLen-1; i += 2) { + count += 1; + if ((GraphBuffer[i] > GraphBuffer[i + 1]) && (state != 1)) { + if (state == 0) { + for (j = 0; j < count - 8; j += 16) { + rawbits[rawbit++] = 0; + } + if ((abs(count - j)) > worst) { + worst = abs(count - j); + worstPos = i; + } + } + state = 1; + count = 0; + } else if ((GraphBuffer[i] < GraphBuffer[i + 1]) && (state != 0)) { + if (state == 1) { + for (j = 0; j < count - 8; j += 16) { + rawbits[rawbit++] = 1; + } + if ((abs(count - j)) > worst) { + worst = abs(count - j); + worstPos = i; + } + } + state = 0; + count = 0; + } + } + if (rawbit>0){ + PrintAndLog("Recovered %d raw bits, expected: %d", rawbit, GraphTraceLen/32); + PrintAndLog("worst metric (0=best..7=worst): %d at pos %d", worst, worstPos); + } else return 0; + // Finding the start of a UID + int uidlen, long_wait; + if (strcmp(Cmd, "224") == 0) { + uidlen = 224; + long_wait = 30; + } else { + uidlen = 64; + long_wait = 29; + } + int start; + int first = 0; + for (start = 0; start <= rawbit - uidlen; start++) { + first = rawbits[start]; + for (i = start; i < start + long_wait; i++) { + if (rawbits[i] != first) { + break; + } + } + if (i == (start + long_wait)) { + break; + } + } + if (start == rawbit - uidlen + 1) { + PrintAndLog("nothing to wait for"); + return 0; + } + + // Inverting signal if needed + if (first == 1) { + for (i = start; i < rawbit; i++) { + rawbits[i] = !rawbits[i]; + } + } + + // Dumping UID + uint8_t bits[224]; + char showbits[225]; + showbits[uidlen]='\0'; + int bit; + i = start; + int times = 0; + if (uidlen > rawbit) { + PrintAndLog("Warning: not enough raw bits to get a full UID"); + for (bit = 0; bit < rawbit; bit++) { + bits[bit] = rawbits[i++]; + // As we cannot know the parity, let's use "." and "/" + showbits[bit] = '.' + bits[bit]; + } + showbits[bit+1]='\0'; + PrintAndLog("Partial UID=%s", showbits); + return 0; + } else { + for (bit = 0; bit < uidlen; bit++) { + bits[bit] = rawbits[i++]; + showbits[bit] = '0' + bits[bit]; + } + times = 1; + } - if (uidlen==64){ - for( idx=0; idx<64; idx++) { - if (showbits[idx] == '0') { - uid1=(uid1<<1)|(uid2>>31); - uid2=(uid2<<1)|0; - } else { - uid1=(uid1<<1)|(uid2>>31); - uid2=(uid2<<1)|1; - } - } - PrintAndLog("UID=%s (%x%08x)", showbits, uid1, uid2); - } - else { - uid3 = uid4 = uid5 = uid6 = uid7 = 0; + //convert UID to HEX + uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7; + int idx; + uid1=0; + uid2=0; + if (uidlen==64){ + for( idx=0; idx<64; idx++) { + if (showbits[idx] == '0') { + uid1=(uid1<<1)|(uid2>>31); + uid2=(uid2<<1)|0; + } else { + uid1=(uid1<<1)|(uid2>>31); + uid2=(uid2<<1)|1; + } + } + PrintAndLog("UID=%s (%x%08x)", showbits, uid1, uid2); + } + else { + uid3=0; + uid4=0; + uid5=0; + uid6=0; + uid7=0; + for( idx=0; idx<224; idx++) { + uid1=(uid1<<1)|(uid2>>31); + uid2=(uid2<<1)|(uid3>>31); + uid3=(uid3<<1)|(uid4>>31); + uid4=(uid4<<1)|(uid5>>31); + uid5=(uid5<<1)|(uid6>>31); + uid6=(uid6<<1)|(uid7>>31); + if (showbits[idx] == '0') uid7=(uid7<<1)|0; + else uid7=(uid7<<1)|1; + } + PrintAndLog("UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7); + } - for( idx=0; idx<224; idx++) { - uid1=(uid1<<1)|(uid2>>31); - uid2=(uid2<<1)|(uid3>>31); - uid3=(uid3<<1)|(uid4>>31); - uid4=(uid4<<1)|(uid5>>31); - uid5=(uid5<<1)|(uid6>>31); - uid6=(uid6<<1)|(uid7>>31); - - if (showbits[idx] == '0') - uid7 = (uid7<<1) | 0; - else - uid7 = (uid7<<1) | 1; - } - PrintAndLog("UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7); - } - - // Checking UID against next occurrences - int failed = 0; + // Checking UID against next occurrences for (; i + uidlen <= rawbit;) { - failed = 0; - for (bit = 0; bit < uidlen; bit++) { - if (bits[bit] != rawbits[i++]) { - failed = 1; - break; - } - } - if (failed == 1) { - break; - } - times += 1; - } + int failed = 0; + for (bit = 0; bit < uidlen; bit++) { + if (bits[bit] != rawbits[i++]) { + failed = 1; + break; + } + } + if (failed == 1) { + break; + } + times += 1; + } + PrintAndLog("Occurrences: %d (expected %d)", times, (rawbit - start) / uidlen); - PrintAndLog("Occurrences: %d (expected %d)", times, (rawbit - start) / uidlen); + // Remodulating for tag cloning + GraphTraceLen = 32*uidlen; + i = 0; + int phase = 0; + for (bit = 0; bit < uidlen; bit++) { + if (bits[bit] == 0) { + phase = 0; + } else { + phase = 1; + } + int j; + for (j = 0; j < 32; j++) { + GraphBuffer[i++] = phase; + phase = !phase; + } + } - // Remodulating for tag cloning - // HACK: 2015-01-04 this will have an impact on our new way of seening lf commands (demod) - // since this changes graphbuffer data. - GraphTraceLen = 32*uidlen; - i = 0; - int phase = 0; - for (bit = 0; bit < uidlen; bit++) { - if (bits[bit] == 0) { - phase = 0; - } else { - phase = 1; - } - int j; - for (j = 0; j < 32; j++) { - GraphBuffer[i++] = phase; - phase = !phase; - } - } - - RepaintGraphWindow(); - return 1; + RepaintGraphWindow(); + return 1; } int CmdIndalaClone(const char *Cmd) { - UsbCommand c; unsigned int uid1, uid2, uid3, uid4, uid5, uid6, uid7; + UsbCommand c; + uid1=0; + uid2=0; + uid3=0; + uid4=0; + uid5=0; + uid6=0; + uid7=0; + int n = 0, i = 0; - uid1 = uid2 = uid3 = uid4 = uid5 = uid6 = uid7 = 0; - int n = 0, i = 0; + if (strchr(Cmd,'l') != 0) { + while (sscanf(&Cmd[i++], "%1x", &n ) == 1) { + uid1 = (uid1 << 4) | (uid2 >> 28); + uid2 = (uid2 << 4) | (uid3 >> 28); + uid3 = (uid3 << 4) | (uid4 >> 28); + uid4 = (uid4 << 4) | (uid5 >> 28); + uid5 = (uid5 << 4) | (uid6 >> 28); + uid6 = (uid6 << 4) | (uid7 >> 28); + uid7 = (uid7 << 4) | (n & 0xf); + } + PrintAndLog("Cloning 224bit tag with UID %x%08x%08x%08x%08x%08x%08x", uid1, uid2, uid3, uid4, uid5, uid6, uid7); + c.cmd = CMD_INDALA_CLONE_TAG_L; + c.d.asDwords[0] = uid1; + c.d.asDwords[1] = uid2; + c.d.asDwords[2] = uid3; + c.d.asDwords[3] = uid4; + c.d.asDwords[4] = uid5; + c.d.asDwords[5] = uid6; + c.d.asDwords[6] = uid7; + } + else + { + while (sscanf(&Cmd[i++], "%1x", &n ) == 1) { + uid1 = (uid1 << 4) | (uid2 >> 28); + uid2 = (uid2 << 4) | (n & 0xf); + } + PrintAndLog("Cloning 64bit tag with UID %x%08x", uid1, uid2); + c.cmd = CMD_INDALA_CLONE_TAG; + c.arg[0] = uid1; + c.arg[1] = uid2; + } - if (strchr(Cmd,'l') != 0) { - while (sscanf(&Cmd[i++], "%1x", &n ) == 1) { - uid1 = (uid1 << 4) | (uid2 >> 28); - uid2 = (uid2 << 4) | (uid3 >> 28); - uid3 = (uid3 << 4) | (uid4 >> 28); - uid4 = (uid4 << 4) | (uid5 >> 28); - uid5 = (uid5 << 4) | (uid6 >> 28); - uid6 = (uid6 << 4) | (uid7 >> 28); - uid7 = (uid7 << 4) | (n & 0xf); - } - PrintAndLog("Cloning 224bit tag with UID %x%08x%08x%08x%08x%08x%08x", uid1, uid2, uid3, uid4, uid5, uid6, uid7); - c.cmd = CMD_INDALA_CLONE_TAG_L; - c.d.asDwords[0] = uid1; - c.d.asDwords[1] = uid2; - c.d.asDwords[2] = uid3; - c.d.asDwords[3] = uid4; - c.d.asDwords[4] = uid5; - c.d.asDwords[5] = uid6; - c.d.asDwords[6] = uid7; - } else { - while (sscanf(&Cmd[i++], "%1x", &n ) == 1) { - uid1 = (uid1 << 4) | (uid2 >> 28); - uid2 = (uid2 << 4) | (n & 0xf); - } - PrintAndLog("Cloning 64bit tag with UID %x%08x", uid1, uid2); - c.cmd = CMD_INDALA_CLONE_TAG; - c.arg[0] = uid1; - c.arg[1] = uid2; - } - - SendCommand(&c); - return 0; + SendCommand(&c); + return 0; } int CmdLFRead(const char *Cmd) { - UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K}; - - // 'h' means higher-low-frequency, 134 kHz - if(*Cmd == 'h') { - c.arg[0] = 1; - } else if (*Cmd == '\0') { - c.arg[0] = 0; - } else if (sscanf(Cmd, "%"lli, &c.arg[0]) != 1) { - PrintAndLog("Samples 1: 'lf read'"); - PrintAndLog(" 2: 'lf read h'"); - PrintAndLog(" 3: 'lf read '"); - return 0; - } - SendCommand(&c); - WaitForResponse(CMD_ACK,NULL); - return 0; + UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K}; + // 'h' means higher-low-frequency, 134 kHz + if(*Cmd == 'h') { + c.arg[0] = 1; + } else if (*Cmd == '\0') { + c.arg[0] = 0; + } else if (sscanf(Cmd, "%"lli, &c.arg[0]) != 1) { + PrintAndLog("use 'read' or 'read h', or 'read '"); + return 0; + } + SendCommand(&c); + WaitForResponse(CMD_ACK,NULL); + return 0; } static void ChkBitstream(const char *str) { - int i; + int i; - /* convert to bitstream if necessary */ - for (i = 0; i < (int)(GraphTraceLen / 2); i++) - { - if (GraphBuffer[i] > 1 || GraphBuffer[i] < 0) - { - CmdBitstream(str); - break; - } - } + /* convert to bitstream if necessary */ + for (i = 0; i < (int)(GraphTraceLen / 2); i++) + { + if (GraphBuffer[i] > 1 || GraphBuffer[i] < 0) + { + CmdBitstream(str); + break; + } + } } int CmdLFSim(const char *Cmd) { - int i; - static int gap; + int i; + static int gap; - sscanf(Cmd, "%i", &gap); + sscanf(Cmd, "%i", &gap); - /* convert to bitstream if necessary */ - ChkBitstream(Cmd); + /* convert to bitstream if necessary */ + ChkBitstream(Cmd); - PrintAndLog("Sending data, please wait..."); - for (i = 0; i < GraphTraceLen; i += 48) { - UsbCommand c={CMD_DOWNLOADED_SIM_SAMPLES_125K, {i, 0, 0}}; - int j; - for (j = 0; j < 48; j++) { - c.d.asBytes[j] = GraphBuffer[i+j]; - } - SendCommand(&c); - WaitForResponse(CMD_ACK,NULL); - } + PrintAndLog("Sending data, please wait..."); + for (i = 0; i < GraphTraceLen; i += 48) { + UsbCommand c={CMD_DOWNLOADED_SIM_SAMPLES_125K, {i, 0, 0}}; + int j; + for (j = 0; j < 48; j++) { + c.d.asBytes[j] = GraphBuffer[i+j]; + } + SendCommand(&c); + WaitForResponse(CMD_ACK,NULL); + } - PrintAndLog("Starting simulator..."); - UsbCommand c = {CMD_SIMULATE_TAG_125K, {GraphTraceLen, gap, 0}}; - SendCommand(&c); - return 0; + PrintAndLog("Starting simulator..."); + UsbCommand c = {CMD_SIMULATE_TAG_125K, {GraphTraceLen, gap, 0}}; + SendCommand(&c); + return 0; } int CmdLFSimBidir(const char *Cmd) { - // Set ADC to twice the carrier for a slight supersampling - // HACK: not implemented in ARMSRC. - PrintAndLog("Not implemented yet."); - UsbCommand c = {CMD_LF_SIMULATE_BIDIR, {47, 384, 0}}; - SendCommand(&c); - return 0; + /* Set ADC to twice the carrier for a slight supersampling */ + UsbCommand c = {CMD_LF_SIMULATE_BIDIR, {47, 384, 0}}; + SendCommand(&c); + 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]; + static int clock, gap; + static char data[1024], gapstring[8]; - sscanf(Cmd, "%i %s %i", &clock, &data[0], &gap); + /* get settings/bits */ + sscanf(Cmd, "%i %s %i", &clock, &data[0], &gap); - ClearGraph(0); + /* clear our graph */ + ClearGraph(0); - for (int i = 0; i < strlen(data) ; ++i) - AppendGraph(0, clock, data[i]- '0'); + /* fill it with our bitstream */ + for (int i = 0; i < strlen(data) ; ++i) + AppendGraph(0, clock, data[i]- '0'); - CmdManchesterMod(""); + /* modulate */ + CmdManchesterMod(""); - RepaintGraphWindow(); + /* show what we've done */ + RepaintGraphWindow(); - sprintf(&gapstring[0], "%i", gap); - CmdLFSim(gapstring); - return 0; + /* simulate */ + sprintf(&gapstring[0], "%i", gap); + CmdLFSim(gapstring); + return 0; } int CmdLFSnoop(const char *Cmd) { - UsbCommand c = {CMD_LF_SNOOP_RAW_ADC_SAMPLES}; - - // 'h' means higher-low-frequency, 134 kHz - c.arg[0] = 0; - c.arg[1] = -1; - - if (*Cmd == 'l') { - sscanf(Cmd, "l %"lli, &c.arg[1]); - } else if(*Cmd == 'h') { - c.arg[0] = 1; - sscanf(Cmd, "h %"lli, &c.arg[1]); - } else if (sscanf(Cmd, "%"lli" %"lli, &c.arg[0], &c.arg[1]) < 1) { - PrintAndLog("usage 1: snoop"); - PrintAndLog(" 2: snoop {l,h} [trigger threshold]"); - PrintAndLog(" 3: snoop [trigger threshold]"); - return 0; - } - - SendCommand(&c); - WaitForResponse(CMD_ACK,NULL); - return 0; + UsbCommand c = {CMD_LF_SNOOP_RAW_ADC_SAMPLES}; + // 'h' means higher-low-frequency, 134 kHz + c.arg[0] = 0; + c.arg[1] = -1; + if (*Cmd == 0) { + // empty + } else if (*Cmd == 'l') { + sscanf(Cmd, "l %"lli, &c.arg[1]); + } else if(*Cmd == 'h') { + c.arg[0] = 1; + sscanf(Cmd, "h %"lli, &c.arg[1]); + } else if (sscanf(Cmd, "%"lli" %"lli, &c.arg[0], &c.arg[1]) < 1) { + PrintAndLog("use 'snoop' or 'snoop {l,h} [trigger threshold]', or 'snoop [trigger threshold]'"); + return 0; + } + SendCommand(&c); + WaitForResponse(CMD_ACK,NULL); + return 0; } int CmdVchDemod(const char *Cmd) { - // Is this the entire sync pattern, or does this also include some - // data bits that happen to be the same everywhere? That would be - // lovely to know. - static const int SyncPattern[] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - }; + // Is this the entire sync pattern, or does this also include some + // data bits that happen to be the same everywhere? That would be + // lovely to know. + static const int SyncPattern[] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }; - // So first, we correlate for the sync pattern, and mark that. - int bestCorrel = 0, bestPos = 0; - int i; - // It does us no good to find the sync pattern, with fewer than - // 2048 samples after it... - for (i = 0; i < (GraphTraceLen-2048); i++) { - int sum = 0; - int j; - for (j = 0; j < arraylen(SyncPattern); j++) { - sum += GraphBuffer[i+j]*SyncPattern[j]; - } - if (sum > bestCorrel) { - bestCorrel = sum; - bestPos = i; - } - } - PrintAndLog("best sync at %d [metric %d]", bestPos, bestCorrel); + // So first, we correlate for the sync pattern, and mark that. + int bestCorrel = 0, bestPos = 0; + int i; + // It does us no good to find the sync pattern, with fewer than + // 2048 samples after it... + for (i = 0; i < (GraphTraceLen-2048); i++) { + int sum = 0; + int j; + for (j = 0; j < arraylen(SyncPattern); j++) { + sum += GraphBuffer[i+j]*SyncPattern[j]; + } + if (sum > bestCorrel) { + bestCorrel = sum; + bestPos = i; + } + } + PrintAndLog("best sync at %d [metric %d]", bestPos, bestCorrel); - char bits[257]; - bits[256] = '\0'; + char bits[257]; + bits[256] = '\0'; - int worst = INT_MAX; - int worstPos = 0; + int worst = INT_MAX; + int worstPos = 0; - for (i = 0; i < 2048; i += 8) { - int sum = 0; - int j; - for (j = 0; j < 8; j++) { - sum += GraphBuffer[bestPos+i+j]; - } - if (sum < 0) { - bits[i/8] = '.'; - } else { - bits[i/8] = '1'; - } - if(abs(sum) < worst) { - worst = abs(sum); - worstPos = i; - } - } - PrintAndLog("bits:"); - PrintAndLog("%s", bits); - PrintAndLog("worst metric: %d at pos %d", worst, worstPos); + for (i = 0; i < 2048; i += 8) { + int sum = 0; + int j; + for (j = 0; j < 8; j++) { + sum += GraphBuffer[bestPos+i+j]; + } + if (sum < 0) { + bits[i/8] = '.'; + } else { + bits[i/8] = '1'; + } + if(abs(sum) < worst) { + worst = abs(sum); + worstPos = i; + } + } + PrintAndLog("bits:"); + PrintAndLog("%s", bits); + PrintAndLog("worst metric: %d at pos %d", worst, worstPos); - if (strcmp(Cmd, "clone")==0) { - GraphTraceLen = 0; - char *s; - for(s = bits; *s; s++) { - int j; - for(j = 0; j < 16; j++) { - GraphBuffer[GraphTraceLen++] = (*s == '1') ? 1 : 0; - } - } - RepaintGraphWindow(); - } - return 0; + if (strcmp(Cmd, "clone")==0) { + GraphTraceLen = 0; + char *s; + for(s = bits; *s; s++) { + int j; + for(j = 0; j < 16; j++) { + GraphBuffer[GraphTraceLen++] = (*s == '1') ? 1 : 0; + } + } + RepaintGraphWindow(); + } + return 0; } //by marshmellow int CmdLFfind(const char *Cmd) { - int ans=0; - if (!offline){ - ans=CmdLFRead(""); - ans=CmdSamples("20000"); - } - if (GraphTraceLen<1000) return 0; - PrintAndLog("NOTE: some demods output possible binary\n if it finds something that looks like a tag"); - PrintAndLog("Checking for known tags:"); + int ans=0; + if (!offline){ + ans=CmdLFRead(""); + ans=CmdSamples("20000"); + } + if (GraphTraceLen<1000) return 0; + PrintAndLog("NOTE: some demods output possible binary\n if it finds something that looks like a tag"); + PrintAndLog("Checking for known tags:"); - ans=Cmdaskmandemod(""); - if (ans>0) { - PrintAndLog("Valid EM410x ID Found!"); - return 1; - } - ans=CmdFSKdemodHID(""); - if (ans>0) { - PrintAndLog("Valid HID Prox ID Found!"); - return 1; - } - ans=CmdFSKdemodIO(""); - if (ans>0) { - PrintAndLog("Valid IO Prox ID Found!"); - return 1; - } - //add psk and indala - ans=CmdIndalaDecode(""); - if (ans>0) { - PrintAndLog("Valid Indala ID Found!"); - return 1; - } + ans=Cmdaskmandemod(""); + if (ans>0) { + PrintAndLog("Valid EM410x ID Found!"); + return 1; + } + ans=CmdFSKdemodHID(""); + if (ans>0) { + PrintAndLog("Valid HID Prox ID Found!"); + return 1; + } + ans=CmdFSKdemodIO(""); + if (ans>0) { + PrintAndLog("Valid IO Prox ID Found!"); + return 1; + } + //add psk and indala + ans=CmdIndalaDecode(""); + if (ans>0) { + PrintAndLog("Valid Indala ID Found!"); + return 1; + } // ans=CmdIndalaDemod("224"); // if (ans>0) return 1; - PrintAndLog("No Known Tags Found!\n"); - return 0; + PrintAndLog("No Known Tags Found!\n"); + return 0; } static command_t CommandTable[] = { - {"help", CmdHelp, 1, "This help"}, - {"cmdread", CmdLFCommandRead, 0, " <'0' period> <'1' period> ['h'] -- Modulate LF reader field to send command before read (all periods in microseconds) (option 'h' for 134)"}, - {"em4x", CmdLFEM4X, 1, "{ EM4X RFIDs... }"}, - {"flexdemod", CmdFlexdemod, 1, "Demodulate samples for FlexPass"}, - {"hid", CmdLFHID, 1, "{ HID RFIDs... }"}, - {"io", CmdLFIO, 1, "{ ioProx tags... }"}, - {"indalademod", CmdIndalaDemod, 1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"}, - {"indalaclone", CmdIndalaClone, 0, " ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"}, - {"read", CmdLFRead, 0, "['h' or ] -- Read 125/134 kHz LF ID-only tag (option 'h' for 134, alternatively: f=12MHz/(divisor+1))"}, - {"search", CmdLFfind, 1, "Read and Search for valid known tag (in offline mode it you can load first then search)"}, - {"sim", CmdLFSim, 0, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"}, - {"simbidir", CmdLFSimBidir, 0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"}, - {"simman", CmdLFSimManchester, 0, " [GAP] Simulate arbitrary Manchester LF tag"}, - {"snoop", CmdLFSnoop, 0, "['l'|'h'|] [trigger threshold]-- Snoop LF (l:125khz, h:134khz)"}, - {"ti", CmdLFTI, 1, "{ TI RFIDs... }"}, - {"hitag", CmdLFHitag, 1, "{ Hitag tags and transponders... }"}, - {"vchdemod", CmdVchDemod, 1, "['clone'] -- Demodulate samples for VeriChip"}, - {"t55xx", CmdLFT55XX, 1, "{ T55xx RFIDs... }"}, - {"pcf7931", CmdLFPCF7931, 1, "{PCF7931 RFIDs...}"}, - {NULL, NULL, 0, NULL} + {"help", CmdHelp, 1, "This help"}, + {"cmdread", CmdLFCommandRead, 0, " <'0' period> <'1' period> ['h'] -- Modulate LF reader field to send command before read (all periods in microseconds) (option 'h' for 134)"}, + {"em4x", CmdLFEM4X, 1, "{ EM4X RFIDs... }"}, + {"flexdemod", CmdFlexdemod, 1, "Demodulate samples for FlexPass"}, + {"hid", CmdLFHID, 1, "{ HID RFIDs... }"}, + {"io", CmdLFIO, 1, "{ ioProx tags... }"}, + {"indalademod", CmdIndalaDemod, 1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"}, + {"indalaclone", CmdIndalaClone, 0, " ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"}, + {"read", CmdLFRead, 0, "['h' or ] -- Read 125/134 kHz LF ID-only tag (option 'h' for 134, alternatively: f=12MHz/(divisor+1))"}, + {"search", CmdLFfind, 1, "Read and Search for valid known tag (in offline mode it you can load first then search)"}, + {"sim", CmdLFSim, 0, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"}, + {"simbidir", CmdLFSimBidir, 0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"}, + {"simman", CmdLFSimManchester, 0, " [GAP] Simulate arbitrary Manchester LF tag"}, + {"snoop", CmdLFSnoop, 0, "['l'|'h'|] [trigger threshold]-- Snoop LF (l:125khz, h:134khz)"}, + {"ti", CmdLFTI, 1, "{ TI RFIDs... }"}, + {"hitag", CmdLFHitag, 1, "{ Hitag tags and transponders... }"}, + {"vchdemod", CmdVchDemod, 1, "['clone'] -- Demodulate samples for VeriChip"}, + {"t55xx", CmdLFT55XX, 1, "{ T55xx RFIDs... }"}, + {"pcf7931", CmdLFPCF7931, 1, "{PCF7931 RFIDs...}"}, + {NULL, NULL, 0, NULL} }; int CmdLF(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; } diff --git a/client/graph.c b/client/graph.c index d63c42714..f41568e4f 100644 --- a/client/graph.c +++ b/client/graph.c @@ -20,61 +20,61 @@ int GraphTraceLen; /* write a bit to the graph */ void AppendGraph(int redraw, int clock, int bit) { - int i; + int i; - for (i = 0; i < (int)(clock / 2); ++i) - GraphBuffer[GraphTraceLen++] = bit ^ 1; - - for (i = (int)(clock / 2); i < clock; ++i) - GraphBuffer[GraphTraceLen++] = bit; + for (i = 0; i < (int)(clock / 2); ++i) + GraphBuffer[GraphTraceLen++] = bit ^ 1; - if (redraw) - RepaintGraphWindow(); + for (i = (int)(clock / 2); i < clock; ++i) + GraphBuffer[GraphTraceLen++] = bit; + + if (redraw) + RepaintGraphWindow(); } /* clear out our graph window */ int ClearGraph(int redraw) { - int gtl = GraphTraceLen; - GraphTraceLen = 0; + int gtl = GraphTraceLen; + GraphTraceLen = 0; - if (redraw) - RepaintGraphWindow(); + if (redraw) + RepaintGraphWindow(); - return gtl; + return gtl; } /* * Detect clock rate */ - //decommissioned - has difficulty detecting rf/32 + //decommissioned - has difficulty detecting rf/32 /* int DetectClockOld(int peak) { - int i; - int clock = 0xFFFF; - int lastpeak = 0; + int i; + int clock = 0xFFFF; + int lastpeak = 0; - // Detect peak if we don't have one - if (!peak) - for (i = 0; i < GraphTraceLen; ++i) - if (GraphBuffer[i] > peak) - peak = GraphBuffer[i]; + // Detect peak if we don't have one + if (!peak) + for (i = 0; i < GraphTraceLen; ++i) + if (GraphBuffer[i] > peak) + peak = GraphBuffer[i]; // peak=(int)(peak*.75); - for (i = 1; i < GraphTraceLen; ++i) - { - // If this is the beginning of a peak - if (GraphBuffer[i - 1] != GraphBuffer[i] && GraphBuffer[i] >= peak) - { - // Find lowest difference between peaks - if (lastpeak && i - lastpeak < clock) - clock = i - lastpeak; - lastpeak = i; - } - } + for (i = 1; i < GraphTraceLen; ++i) + { + // If this is the beginning of a peak + if (GraphBuffer[i - 1] != GraphBuffer[i] && GraphBuffer[i] >= peak) + { + // Find lowest difference between peaks + if (lastpeak && i - lastpeak < clock) + clock = i - lastpeak; + lastpeak = i; + } + } - return clock; + return clock; } */ /* @@ -85,155 +85,155 @@ NOW IN LFDEMOD.C // maybe somehow adjust peak trimming value based on samples to fix? int DetectASKClock(int peak) { - int i=0; - int low=0; - int clk[]={16,32,40,50,64,100,128,256}; - int loopCnt = 256; - if (GraphTraceLenpeak){ - peak = GraphBuffer[i]; - } - if(GraphBuffer[i]=peak) || (GraphBuffer[ii]<=low)){ - errCnt[clkCnt]=0; - for (i=0; i<((int)(GraphTraceLen/clk[clkCnt])-1); ++i){ - if (GraphBuffer[ii+(i*clk[clkCnt])]>=peak || GraphBuffer[ii+(i*clk[clkCnt])]<=low){ - }else if(GraphBuffer[ii+(i*clk[clkCnt])-tol]>=peak || GraphBuffer[ii+(i*clk[clkCnt])-tol]<=low){ - }else if(GraphBuffer[ii+(i*clk[clkCnt])+tol]>=peak || GraphBuffer[ii+(i*clk[clkCnt])+tol]<=low){ - }else{ //error no peak detected - errCnt[clkCnt]++; - } - } - if(errCnt[clkCnt]==0) return clk[clkCnt]; - if(errCnt[clkCnt]peak){ + peak = GraphBuffer[i]; + } + if(GraphBuffer[i]=peak) || (GraphBuffer[ii]<=low)){ + errCnt[clkCnt]=0; + for (i=0; i<((int)(GraphTraceLen/clk[clkCnt])-1); ++i){ + if (GraphBuffer[ii+(i*clk[clkCnt])]>=peak || GraphBuffer[ii+(i*clk[clkCnt])]<=low){ + }else if(GraphBuffer[ii+(i*clk[clkCnt])-tol]>=peak || GraphBuffer[ii+(i*clk[clkCnt])-tol]<=low){ + }else if(GraphBuffer[ii+(i*clk[clkCnt])+tol]>=peak || GraphBuffer[ii+(i*clk[clkCnt])+tol]<=low){ + }else{ //error no peak detected + errCnt[clkCnt]++; + } + } + if(errCnt[clkCnt]==0) return clk[clkCnt]; + if(errCnt[clkCnt]127) GraphBuffer[i]=127; //trim - if (GraphBuffer[i]<-127) GraphBuffer[i]=-127; //trim - buff[i]=(uint8_t)(GraphBuffer[i]+128); - } - return i; + uint32_t i; + for (i=0;i127) GraphBuffer[i]=127; //trim + if (GraphBuffer[i]<-127) GraphBuffer[i]=-127; //trim + buff[i]=(uint8_t)(GraphBuffer[i]+128); + } + return i; } /* Get or auto-detect clock rate */ int GetClock(const char *str, int peak, int verbose) { - int clock; + int clock; // int clock2; - sscanf(str, "%i", &clock); - if (!strcmp(str, "")) - clock = 0; + sscanf(str, "%i", &clock); + if (!strcmp(str, "")) + clock = 0; - /* Auto-detect clock */ - if (!clock) - { - uint8_t grph[MAX_GRAPH_TRACE_LEN]={0}; - int size = getFromGraphBuf(grph); - clock = DetectASKClock(grph,size,0); - //clock2 = DetectClock2(peak); - /* Only print this message if we're not looping something */ - if (!verbose){ - PrintAndLog("Auto-detected clock rate: %d", clock); - //PrintAndLog("clock2: %d",clock2); - } - } + /* Auto-detect clock */ + if (!clock) + { + uint8_t grph[MAX_GRAPH_TRACE_LEN]={0}; + size_t size = getFromGraphBuf(grph); + clock = DetectASKClock(grph,size,0); + //clock2 = DetectClock2(peak); + /* Only print this message if we're not looping something */ + if (!verbose){ + PrintAndLog("Auto-detected clock rate: %d", clock); + //PrintAndLog("clock2: %d",clock2); + } + } - return clock; + return clock; } int GetNRZpskClock(const char *str, int peak, int verbose) { // return GetClock(str,peak,verbose); - int clock; - // int clock2; - sscanf(str, "%i", &clock); - if (!strcmp(str, "")) - clock = 0; + int clock; + // int clock2; + sscanf(str, "%i", &clock); + if (!strcmp(str, "")) + clock = 0; - /* Auto-detect clock */ - if (!clock) - { - uint8_t grph[MAX_GRAPH_TRACE_LEN]={0}; - int size = getFromGraphBuf(grph); - clock = DetectpskNRZClock(grph,size,0); - //clock2 = DetectClock2(peak); - /* Only print this message if we're not looping something */ - if (!verbose){ - PrintAndLog("Auto-detected clock rate: %d", clock); - //PrintAndLog("clock2: %d",clock2); - } - } - return clock; + /* Auto-detect clock */ + if (!clock) + { + uint8_t grph[MAX_GRAPH_TRACE_LEN]={0}; + size_t size = getFromGraphBuf(grph); + clock = DetectpskNRZClock(grph,size,0); + //clock2 = DetectClock2(peak); + /* Only print this message if we're not looping something */ + if (!verbose){ + PrintAndLog("Auto-detected clock rate: %d", clock); + //PrintAndLog("clock2: %d",clock2); + } + } + return clock; } -// Get or auto-detect clock rate +// Get or auto-detect clock rate /* int GetNRZpskClock(const char *str, int peak, int verbose) { - int clock; + int clock; // int clock2; - sscanf(str, "%i", &clock); - if (!strcmp(str, "")) - clock = 0; + sscanf(str, "%i", &clock); + if (!strcmp(str, "")) + clock = 0; - // Auto-detect clock - if (!clock) - { - uint8_t grph[MAX_GRAPH_TRACE_LEN]={0}; - int size = getFromGraphBuf(grph); - clock = DetectASKClock(grph,size,0); - //clock2 = DetectClock2(peak); - // Only print this message if we're not looping something - if (!verbose){ - PrintAndLog("Auto-detected clock rate: %d", clock); - //PrintAndLog("clock2: %d",clock2); - } - } - return clock; + // Auto-detect clock + if (!clock) + { + uint8_t grph[MAX_GRAPH_TRACE_LEN]={0}; + int size = getFromGraphBuf(grph); + clock = DetectASKClock(grph,size,0); + //clock2 = DetectClock2(peak); + // Only print this message if we're not looping something + if (!verbose){ + PrintAndLog("Auto-detected clock rate: %d", clock); + //PrintAndLog("clock2: %d",clock2); + } + } + return clock; } -*/ \ No newline at end of file +*/ diff --git a/client/graph.h b/client/graph.h index c5c137986..1abeeb25a 100644 --- a/client/graph.h +++ b/client/graph.h @@ -15,10 +15,10 @@ void AppendGraph(int redraw, int clock, int bit); int ClearGraph(int redraw); //int DetectClock(int peak); -int getFromGraphBuf(uint8_t *buff); +size_t getFromGraphBuf(uint8_t *buff); int GetClock(const char *str, int peak, int verbose); int GetNRZpskClock(const char *str, int peak, int verbose); -void setGraphBuf(uint8_t *buff,int size); +void setGraphBuf(uint8_t *buff, size_t size); #define MAX_GRAPH_TRACE_LEN (1024*128) extern int GraphBuffer[MAX_GRAPH_TRACE_LEN]; diff --git a/common/lfdemod.c b/common/lfdemod.c index 79c99f733..11ba131b0 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -1,5 +1,5 @@ //----------------------------------------------------------------------------- -// Copyright (C) 2014 +// Copyright (C) 2014 // // 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 @@ -14,620 +14,618 @@ //by marshmellow //takes 1s and 0s and searches for EM410x format - output EM ID -uint64_t Em410xDecode(uint8_t *BitStream,uint32_t BitLen) +uint64_t Em410xDecode(uint8_t *BitStream, size_t size) { - //no arguments needed - built this way in case we want this to be a direct call from "data " cmds in the future - // otherwise could be a void with no arguments - //set defaults - int high=0, low=128; - uint64_t lo=0; //hi=0, + //no arguments needed - built this way in case we want this to be a direct call from "data " cmds in the future + // otherwise could be a void with no arguments + //set defaults + int high=0, low=128; + uint64_t lo=0; //hi=0, - uint32_t i = 0; - uint32_t initLoopMax = 65; - if (initLoopMax>BitLen) initLoopMax=BitLen; + uint32_t i = 0; + uint32_t initLoopMax = 65; + if (initLoopMax>size) initLoopMax=size; - for (;i < initLoopMax; ++i) //65 samples should be plenty to find high and low values - { - if (BitStream[i] > high) - high = BitStream[i]; - else if (BitStream[i] < low) - low = BitStream[i]; - } - if (((high !=1)||(low !=0))){ //allow only 1s and 0s - // PrintAndLog("no data found"); - return 0; - } - uint8_t parityTest=0; - // 111111111 bit pattern represent start of frame - uint8_t frame_marker_mask[] = {1,1,1,1,1,1,1,1,1}; - uint32_t idx = 0; - uint32_t ii=0; - uint8_t resetCnt = 0; - while( (idx + 64) < BitLen) { -restart: - // search for a start of frame marker - if ( memcmp(BitStream+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) - { // frame marker found - idx+=9;//sizeof(frame_marker_mask); - for (i=0; i<10;i++){ - for(ii=0; ii<5; ++ii){ - parityTest += BitStream[(i*5)+ii+idx]; - } - if (parityTest== ((parityTest>>1)<<1)){ - parityTest=0; - for (ii=0; ii<4;++ii){ - //hi = (hi<<1)|(lo>>31); - lo=(lo<<1LL)|(BitStream[(i*5)+ii+idx]); - } - //PrintAndLog("DEBUG: EM parity passed parity val: %d, i:%d, ii:%d,idx:%d, Buffer: %d%d%d%d%d,lo: %d",parityTest,i,ii,idx,BitStream[idx+ii+(i*5)-5],BitStream[idx+ii+(i*5)-4],BitStream[idx+ii+(i*5)-3],BitStream[idx+ii+(i*5)-2],BitStream[idx+ii+(i*5)-1],lo); - }else {//parity failed - //PrintAndLog("DEBUG: EM parity failed parity val: %d, i:%d, ii:%d,idx:%d, Buffer: %d%d%d%d%d",parityTest,i,ii,idx,BitStream[idx+ii+(i*5)-5],BitStream[idx+ii+(i*5)-4],BitStream[idx+ii+(i*5)-3],BitStream[idx+ii+(i*5)-2],BitStream[idx+ii+(i*5)-1]); - parityTest=0; - idx-=8; - if (resetCnt>5)return 0; - resetCnt++; - goto restart;//continue; - } - } - //skip last 5 bit parity test for simplicity. - return lo; - }else{ - idx++; - } - } - return 0; + for (;i < initLoopMax; ++i) //65 samples should be plenty to find high and low values + { + if (BitStream[i] > high) + high = BitStream[i]; + else if (BitStream[i] < low) + low = BitStream[i]; + } + if (((high !=1)||(low !=0))){ //allow only 1s and 0s + // PrintAndLog("no data found"); + return 0; + } + uint8_t parityTest=0; + // 111111111 bit pattern represent start of frame + uint8_t frame_marker_mask[] = {1,1,1,1,1,1,1,1,1}; + uint32_t idx = 0; + uint32_t ii=0; + uint8_t resetCnt = 0; + while( (idx + 64) < size) { + restart: + // search for a start of frame marker + if ( memcmp(BitStream+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) + { // frame marker found + idx+=9;//sizeof(frame_marker_mask); + for (i=0; i<10;i++){ + for(ii=0; ii<5; ++ii){ + parityTest += BitStream[(i*5)+ii+idx]; + } + if (parityTest== ((parityTest>>1)<<1)){ + parityTest=0; + for (ii=0; ii<4;++ii){ + //hi = (hi<<1)|(lo>>31); + lo=(lo<<1LL)|(BitStream[(i*5)+ii+idx]); + } + //PrintAndLog("DEBUG: EM parity passed parity val: %d, i:%d, ii:%d,idx:%d, Buffer: %d%d%d%d%d,lo: %d",parityTest,i,ii,idx,BitStream[idx+ii+(i*5)-5],BitStream[idx+ii+(i*5)-4],BitStream[idx+ii+(i*5)-3],BitStream[idx+ii+(i*5)-2],BitStream[idx+ii+(i*5)-1],lo); + }else {//parity failed + //PrintAndLog("DEBUG: EM parity failed parity val: %d, i:%d, ii:%d,idx:%d, Buffer: %d%d%d%d%d",parityTest,i,ii,idx,BitStream[idx+ii+(i*5)-5],BitStream[idx+ii+(i*5)-4],BitStream[idx+ii+(i*5)-3],BitStream[idx+ii+(i*5)-2],BitStream[idx+ii+(i*5)-1]); + parityTest=0; + idx-=8; + if (resetCnt>5)return 0; + resetCnt++; + goto restart;//continue; + } + } + //skip last 5 bit parity test for simplicity. + return lo; + }else{ + idx++; + } + } + return 0; } //by marshmellow //takes 2 arguments - clock and invert both as integers -//attempts to demodulate ask while decoding manchester +//attempts to demodulate ask while decoding manchester //prints binary found and saves in graphbuffer for further commands -int askmandemod(uint8_t * BinStream,uint32_t *BitLen,int *clk, int *invert) +int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert) { - int i; - int high = 0, low = 128; - *clk=DetectASKClock(BinStream,(size_t)*BitLen,*clk); //clock default + int i; + int high = 0, low = 128; + *clk=DetectASKClock(BinStream, *size, *clk); //clock default - if (*clk<8) *clk =64; - if (*clk<32) *clk=32; - if (*invert != 0 && *invert != 1) *invert=0; - uint32_t initLoopMax = 200; - if (initLoopMax>*BitLen) initLoopMax=*BitLen; - // Detect high and lows - for (i = 0; i < initLoopMax; ++i) //200 samples should be enough to find high and low values - { - if (BinStream[i] > high) - high = BinStream[i]; - else if (BinStream[i] < low) - low = BinStream[i]; - } - if ((high < 158) ){ //throw away static - //PrintAndLog("no data found"); - return -2; - } - //25% fuzz in case highs and lows aren't clipped [marshmellow] - high=(int)((high-128)*.75)+128; - low= (int)((low-128)*.75)+128; + if (*clk<8) *clk =64; + if (*clk<32) *clk=32; + if (*invert != 0 && *invert != 1) *invert=0; + uint32_t initLoopMax = 200; + if (initLoopMax > *size) initLoopMax=*size; + // Detect high and lows + for (i = 0; i < initLoopMax; ++i) //200 samples should be enough to find high and low values + { + if (BinStream[i] > high) + high = BinStream[i]; + else if (BinStream[i] < low) + low = BinStream[i]; + } + if ((high < 158) ){ //throw away static + //PrintAndLog("no data found"); + return -2; + } + //25% fuzz in case highs and lows aren't clipped [marshmellow] + high=(int)((high-128)*.75)+128; + low= (int)((low-128)*.75)+128; - //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); - int lastBit = 0; //set first clock check - uint32_t bitnum = 0; //output counter - int 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 - int iii = 0; - uint32_t gLen = *BitLen; - if (gLen > 3000) gLen=3000; - uint8_t errCnt =0; - uint32_t bestStart = *BitLen; - uint32_t bestErrCnt = (*BitLen/1000); - uint32_t maxErr = (*BitLen/1000); - //PrintAndLog("DEBUG - lastbit - %d",lastBit); - //loop to find first wave that works - for (iii=0; iii < gLen; ++iii){ - if ((BinStream[iii]>=high)||(BinStream[iii]<=low)){ - lastBit=iii-*clk; - errCnt=0; - //loop through to see if this start location works - for (i = iii; i < *BitLen; ++i) { - if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){ - lastBit+=*clk; - } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ - //low found and we are expecting a bar - lastBit+=*clk; - } else { - //mid value found or no bar supposed to be here - if ((i-lastBit)>(*clk+tol)){ - //should have hit a high or low based on clock!! + //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); + int lastBit = 0; //set first clock check + uint32_t bitnum = 0; //output counter + int 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 + int iii = 0; + uint32_t gLen = *size; + if (gLen > 3000) gLen=3000; + uint8_t errCnt =0; + uint32_t bestStart = *size; + uint32_t bestErrCnt = (*size/1000); + uint32_t maxErr = (*size/1000); + //PrintAndLog("DEBUG - lastbit - %d",lastBit); + //loop to find first wave that works + for (iii=0; iii < gLen; ++iii){ + if ((BinStream[iii] >= high) || (BinStream[iii] <= low)){ + lastBit=iii-*clk; + errCnt=0; + //loop through to see if this start location works + for (i = iii; i < *size; ++i) { + if ((BinStream[i] >= high) && ((i-lastBit) > (*clk-tol))){ + lastBit+=*clk; + } else if ((BinStream[i] <= low) && ((i-lastBit) > (*clk-tol))){ + //low found and we are expecting a bar + lastBit+=*clk; + } else { + //mid value found or no bar supposed to be here + if ((i-lastBit)>(*clk+tol)){ + //should have hit a high or low based on clock!! - //debug - //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); + //debug + //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; //allow 1 error for every 1000 samples else start over - } - } - if ((i-iii) >(400 * *clk)) break; //got plenty of bits - } - //we got more than 64 good bits and not all errors - if ((((i-iii)/ *clk) > (64+errCnt)) && (errCnt= high) && ((i-lastBit)>(*clk-tol))){ - lastBit+=*clk; - BinStream[bitnum] = *invert; - bitnum++; - } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ - //low found and we are expecting a bar - lastBit+=*clk; - BinStream[bitnum] = 1-*invert; - bitnum++; - } else { - //mid value found or no bar supposed to be here - if ((i-lastBit)>(*clk+tol)){ - //should have hit a high or low based on clock!! + errCnt++; + lastBit+=*clk;//skip over until hit too many errors + if (errCnt>(maxErr)) break; //allow 1 error for every 1000 samples else start over + } + } + if ((i-iii) >(400 * *clk)) break; //got plenty of bits + } + //we got more than 64 good bits and not all errors + if ((((i-iii)/ *clk) > (64+errCnt)) && (errCnt= high) && ((i-lastBit) > (*clk-tol))){ + lastBit += *clk; + BinStream[bitnum] = *invert; + bitnum++; + } else if ((BinStream[i] <= low) && ((i-lastBit) > (*clk-tol))){ + //low found and we are expecting a bar + lastBit+=*clk; + BinStream[bitnum] = 1-*invert; + bitnum++; + } else { + //mid value found or no bar supposed to be here + if ((i-lastBit)>(*clk+tol)){ + //should have hit a high or low based on clock!! - //debug - //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; - bitnum++; - } + //debug + //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; + bitnum++; + } - lastBit+=*clk;//skip over error - } - } - if (bitnum >=400) break; - } - *BitLen=bitnum; - } else{ - *invert=bestStart; - *clk=iii; - return -1; - } - return bestErrCnt; + lastBit+=*clk;//skip over error + } + } + if (bitnum >=400) break; + } + *size=bitnum; + } else{ + *invert=bestStart; + *clk=iii; + return -1; + } + return bestErrCnt; } //by marshmellow //take 10 and 01 and manchester decode //run through 2 times and take least errCnt -int manrawdecode(uint8_t * BitStream, int *bitLen) +int manrawdecode(uint8_t * BitStream, size_t *size) { - int bitnum=0; - int errCnt =0; - int i=1; - int bestErr = 1000; - int bestRun = 0; - int ii=1; - for (ii=1;ii<3;++ii){ - i=1; - for (i=i+ii;i<*bitLen-2;i+=2){ - if(BitStream[i]==1 && (BitStream[i+1]==0)){ - } else if((BitStream[i]==0)&& BitStream[i+1]==1){ - } else { - errCnt++; - } - if(bitnum>300) break; - } - if (bestErr>errCnt){ - bestErr=errCnt; - bestRun=ii; - } - errCnt=0; - } - errCnt=bestErr; - if (errCnt<20){ - ii=bestRun; - i=1; - for (i=i+ii;i<*bitLen-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; - //errCnt++; - } - if(bitnum>300) break; - } - *bitLen=bitnum; - } - return errCnt; + int bitnum=0; + int errCnt =0; + int i=1; + int bestErr = 1000; + int bestRun = 0; + int ii=1; + for (ii=1;ii<3;++ii){ + i=1; + for (i=i+ii;i<*size-2;i+=2){ + if(BitStream[i]==1 && (BitStream[i+1]==0)){ + } else if((BitStream[i]==0)&& BitStream[i+1]==1){ + } else { + errCnt++; + } + if(bitnum>300) break; + } + if (bestErr>errCnt){ + bestErr=errCnt; + bestRun=ii; + } + errCnt=0; + } + errCnt=bestErr; + if (errCnt<20){ + ii=bestRun; + i=1; + for (i=i+ii;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; + //errCnt++; + } + if(bitnum>300) break; + } + *size=bitnum; + } + return errCnt; } //by marshmellow //take 01 or 10 = 0 and 11 or 00 = 1 -int BiphaseRawDecode(uint8_t * BitStream, int *bitLen, int offset) +int BiphaseRawDecode(uint8_t *BitStream, size_t *size, int offset) { - uint8_t bitnum=0; - uint32_t errCnt =0; - uint32_t i=1; - i=offset; - for (;i<*bitLen-2;i+=2){ - if((BitStream[i]==1 && BitStream[i+1]==0)||(BitStream[i]==0 && BitStream[i+1]==1)){ - BitStream[bitnum++]=1; - } else if((BitStream[i]==0 && BitStream[i+1]==0)||(BitStream[i]==1 && BitStream[i+1]==1)){ - BitStream[bitnum++]=0; - } else { - BitStream[bitnum++]=77; - errCnt++; - } - if(bitnum>250) break; - } - *bitLen=bitnum; - return errCnt; + uint8_t bitnum=0; + uint32_t errCnt =0; + uint32_t i=1; + i=offset; + for (;i<*size-2;i+=2){ + if((BitStream[i]==1 && BitStream[i+1]==0) || (BitStream[i]==0 && BitStream[i+1]==1)){ + BitStream[bitnum++]=1; + } else if((BitStream[i]==0 && BitStream[i+1]==0) || (BitStream[i]==1 && BitStream[i+1]==1)){ + BitStream[bitnum++]=0; + } else { + BitStream[bitnum++]=77; + errCnt++; + } + if(bitnum>250) break; + } + *size=bitnum; + return errCnt; } //by marshmellow //takes 2 arguments - clock and invert both as integers //attempts to demodulate ask only //prints binary found and saves in graphbuffer for further commands -int askrawdemod(uint8_t *BinStream, int *bitLen,int *clk, int *invert) +int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert) { - uint32_t i; - // int invert=0; //invert default - int high = 0, low = 128; - *clk=DetectASKClock(BinStream,*bitLen,*clk); //clock default - uint8_t BitStream[502] = {0}; + uint32_t i; + // int invert=0; //invert default + int high = 0, low = 128; + *clk=DetectASKClock(BinStream, *size, *clk); //clock default + uint8_t BitStream[502] = {0}; - if (*clk<8) *clk =64; - if (*clk<32) *clk=32; - if (*invert != 0 && *invert != 1) *invert =0; - uint32_t initLoopMax = 200; - if (initLoopMax>*bitLen) initLoopMax=*bitLen; - // Detect high and lows - for (i = 0; i < initLoopMax; ++i) //200 samples should be plenty to find high and low values - { - if (BinStream[i] > high) - high = BinStream[i]; - else if (BinStream[i] < low) - low = BinStream[i]; - } - if ((high < 158)){ //throw away static - // PrintAndLog("no data found"); - return -2; - } - //25% fuzz in case highs and lows aren't clipped [marshmellow] - high=(int)((high-128)*.75)+128; - low= (int)((low-128)*.75)+128; + if (*clk<8) *clk =64; + if (*clk<32) *clk=32; + if (*invert != 0 && *invert != 1) *invert =0; + uint32_t initLoopMax = 200; + if (initLoopMax>*size) initLoopMax=*size; + // Detect high and lows + for (i = 0; i < initLoopMax; ++i) //200 samples should be plenty to find high and low values + { + if (BinStream[i] > high) + high = BinStream[i]; + else if (BinStream[i] < low) + low = BinStream[i]; + } + if ((high < 158)){ //throw away static + // PrintAndLog("no data found"); + return -2; + } + //25% fuzz in case highs and lows aren't clipped [marshmellow] + high=(int)((high-128)*.75)+128; + low= (int)((low-128)*.75)+128; - //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); - int lastBit = 0; //set first clock check - uint32_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 - uint32_t iii = 0; - uint32_t gLen = *bitLen; - if (gLen > 500) gLen=500; - uint8_t errCnt =0; - uint32_t bestStart = *bitLen; - uint32_t bestErrCnt = (*bitLen/1000); - uint8_t midBit=0; - //PrintAndLog("DEBUG - lastbit - %d",lastBit); - //loop to find first wave that works - for (iii=0; iii < gLen; ++iii){ - if ((BinStream[iii]>=high)||(BinStream[iii]<=low)){ - lastBit=iii-*clk; - //loop through to see if this start location works - for (i = iii; i < *bitLen; ++i) { - if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){ - lastBit+=*clk; - BitStream[bitnum] = *invert; - bitnum++; - midBit=0; - } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ - //low found and we are expecting a bar - lastBit+=*clk; - BitStream[bitnum] = 1-*invert; - bitnum++; - midBit=0; - } else if ((BinStream[i]<=low) && (midBit==0) && ((i-lastBit)>((*clk/2)-tol))){ - //mid bar? - midBit=1; - BitStream[bitnum]= 1-*invert; - bitnum++; - } else if ((BinStream[i]>=high)&&(midBit==0) && ((i-lastBit)>((*clk/2)-tol))){ - //mid bar? - midBit=1; - BitStream[bitnum]= *invert; - bitnum++; - } else if ((i-lastBit)>((*clk/2)+tol)&&(midBit==0)){ - //no mid bar found - midBit=1; - BitStream[bitnum]= BitStream[bitnum-1]; - bitnum++; - } else { - //mid value found or no bar supposed to be here + //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); + int lastBit = 0; //set first clock check + uint32_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 + uint32_t iii = 0; + uint32_t gLen = *size; + if (gLen > 500) gLen=500; + uint8_t errCnt =0; + uint32_t bestStart = *size; + uint32_t bestErrCnt = (*size/1000); + uint8_t midBit=0; + //PrintAndLog("DEBUG - lastbit - %d",lastBit); + //loop to find first wave that works + for (iii=0; iii < gLen; ++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 ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){ + lastBit+=*clk; + BitStream[bitnum] = *invert; + bitnum++; + midBit=0; + } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){ + //low found and we are expecting a bar + lastBit+=*clk; + BitStream[bitnum] = 1- *invert; + bitnum++; + midBit=0; + } else if ((BinStream[i]<=low) && (midBit==0) && ((i-lastBit)>((*clk/2)-tol))){ + //mid bar? + midBit=1; + BitStream[bitnum]= 1- *invert; + bitnum++; + } else if ((BinStream[i]>=high) && (midBit==0) && ((i-lastBit)>((*clk/2)-tol))){ + //mid bar? + midBit=1; + BitStream[bitnum]= *invert; + bitnum++; + } else if ((i-lastBit)>((*clk/2)+tol) && (midBit==0)){ + //no mid bar found + midBit=1; + BitStream[bitnum]= BitStream[bitnum-1]; + bitnum++; + } else { + //mid value found or no bar supposed to be here - if ((i-lastBit)>(*clk+tol)){ - //should have hit a high or low based on clock!! - //debug - //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){ - BitStream[bitnum]=77; - bitnum++; - } + if ((i-lastBit)>(*clk+tol)){ + //should have hit a high or low based on clock!! + //debug + //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){ + BitStream[bitnum]=77; + bitnum++; + } - errCnt++; - lastBit+=*clk;//skip over until hit too many errors - if (errCnt>((*bitLen/1000))){ //allow 1 error for every 1000 samples else start over - errCnt=0; - bitnum=0;//start over - break; - } - } - } - if (bitnum>500) break; - } - //we got more than 64 good bits and not all errors - if ((bitnum > (64+errCnt)) && (errCnt<(*bitLen/1000))) { - //possible good read - if (errCnt==0) break; //great read - finish - if (bestStart == iii) break; //if current run == bestErrCnt run (after exhausted testing) then finish - if (errCnt=gLen){ //exhausted test - //if there was a ok test go back to that one and re-run the best run (then dump after that run) - if (bestErrCnt < (*bitLen/1000)) iii=bestStart; - } - } - if (bitnum>16){ + errCnt++; + lastBit+=*clk;//skip over until hit too many errors + if (errCnt > ((*size/1000))){ //allow 1 error for every 1000 samples else start over + errCnt=0; + bitnum=0;//start over + break; + } + } + } + if (bitnum>500) break; + } + //we got more than 64 good bits and not all errors + if ((bitnum > (64+errCnt)) && (errCnt<(*size/1000))) { + //possible good read + if (errCnt==0) break; //great read - finish + if (bestStart == iii) break; //if current run == bestErrCnt run (after exhausted testing) then finish + if (errCnt=gLen){ //exhausted test + //if there was a ok test go back to that one and re-run the best run (then dump after that run) + if (bestErrCnt < (*size/1000)) iii=bestStart; + } + } + if (bitnum>16){ - // PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum); - //move BitStream back to BinStream - // ClearGraph(0); - for (i=0; i < bitnum; ++i){ - BinStream[i]=BitStream[i]; - } - *bitLen=bitnum; - // RepaintGraphWindow(); - //output - // if (errCnt>0){ - // PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); - // } - // PrintAndLog("ASK decoded bitstream:"); - // Now output the bitstream to the scrollback by line of 16 bits - // printBitStream2(BitStream,bitnum); - //int errCnt=0; - //errCnt=manrawdemod(BitStream,bitnum); + // PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum); + //move BitStream back to BinStream + // ClearGraph(0); + for (i=0; i < bitnum; ++i){ + BinStream[i]=BitStream[i]; + } + *size=bitnum; + // RepaintGraphWindow(); + //output + // if (errCnt>0){ + // PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); + // } + // PrintAndLog("ASK decoded bitstream:"); + // Now output the bitstream to the scrollback by line of 16 bits + // printBitStream2(BitStream,bitnum); + //int errCnt=0; + //errCnt=manrawdemod(BitStream,bitnum); - // Em410xDecode(Cmd); - } else return -1; - return errCnt; + // Em410xDecode(Cmd); + } else return -1; + return errCnt; } -//translate wave to 11111100000 (1 for each short wave 0 for each long wave) +//translate wave to 11111100000 (1 for each short wave 0 for each long wave) size_t fsk_wave_demod(uint8_t * dest, size_t size, uint8_t fchigh, uint8_t fclow) { - uint32_t last_transition = 0; - uint32_t idx = 1; - uint32_t maxVal=0; - if (fchigh==0) fchigh=10; - if (fclow==0) fclow=8; - // we do care about the actual theshold value as sometimes near the center of the - // wave we may get static that changes direction of wave for one value - // if our value is too low it might affect the read. and if our tag or - // antenna is weak a setting too high might not see anything. [marshmellow] - if (size<100) return 0; - for(idx=1; idx<100; idx++){ - if(maxVal1 transition - if (dest[idx-1] < dest[idx]) { // 0 -> 1 transition - if ((idx-last_transition)<(fclow-2)){ //0-5 = garbage noise - //do nothing with extra garbage - } else if ((idx-last_transition) < (fchigh-1)) { //6-8 = 8 waves - dest[numBits]=1; - } else { //9+ = 10 waves - dest[numBits]=0; - } - last_transition = idx; - numBits++; - } - } - return numBits; //Actually, it returns the number of bytes, but each byte represents a bit: 1 or 0 + // Check for 0->1 transition + if (dest[idx-1] < dest[idx]) { // 0 -> 1 transition + if ((idx-last_transition)<(fclow-2)){ //0-5 = garbage noise + //do nothing with extra garbage + } else if ((idx-last_transition) < (fchigh-1)) { //6-8 = 8 waves + dest[numBits]=1; + } else { //9+ = 10 waves + dest[numBits]=0; + } + last_transition = idx; + numBits++; + } + } + return numBits; //Actually, it returns the number of bytes, but each byte represents a bit: 1 or 0 } uint32_t myround2(float f) { - if (f >= 2000) return 2000;//something bad happened - return (uint32_t) (f + (float)0.5); + if (f >= 2000) return 2000;//something bad happened + return (uint32_t) (f + (float)0.5); } -//translate 11111100000 to 10 -size_t aggregate_bits(uint8_t *dest,size_t size, uint8_t rfLen, uint8_t maxConsequtiveBits, uint8_t invert,uint8_t fchigh,uint8_t fclow )// uint8_t h2l_crossing_value,uint8_t l2h_crossing_value, +//translate 11111100000 to 10 +size_t aggregate_bits(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t maxConsequtiveBits, + uint8_t invert, uint8_t fchigh, uint8_t fclow) { - uint8_t lastval=dest[0]; - uint32_t idx=0; - size_t numBits=0; - uint32_t n=1; + uint8_t lastval=dest[0]; + uint32_t idx=0; + size_t numBits=0; + uint32_t n=1; - for( idx=1; idx < size; idx++) { + for( idx=1; idx < size; idx++) { - if (dest[idx]==lastval) { - n++; - continue; - } - //if lastval was 1, we have a 1->0 crossing - if ( dest[idx-1]==1 ) { - n=myround2((float)(n+1)/((float)(rfLen)/(float)fclow)); - //n=(n+1) / h2l_crossing_value; - } else {// 0->1 crossing - n=myround2((float)(n+1)/((float)(rfLen-2)/(float)fchigh)); //-2 for fudge factor - //n=(n+1) / l2h_crossing_value; - } - if (n == 0) n = 1; + if (dest[idx]==lastval) { + n++; + continue; + } + //if lastval was 1, we have a 1->0 crossing + if ( dest[idx-1]==1 ) { + n=myround2((float)(n+1)/((float)(rfLen)/(float)fclow)); + //n=(n+1) / h2l_crossing_value; + } else {// 0->1 crossing + n=myround2((float)(n+1)/((float)(rfLen-2)/(float)fchigh)); //-2 for fudge factor + //n=(n+1) / l2h_crossing_value; + } + if (n == 0) n = 1; - if(n < maxConsequtiveBits) //Consecutive - { - if(invert==0){ //invert bits - memset(dest+numBits, dest[idx-1] , n); - }else{ - memset(dest+numBits, dest[idx-1]^1 , n); - } - numBits += n; - } - n=0; - lastval=dest[idx]; - }//end for - return numBits; + if(n < maxConsequtiveBits) //Consecutive + { + if(invert==0){ //invert bits + memset(dest+numBits, dest[idx-1] , n); + }else{ + memset(dest+numBits, dest[idx-1]^1 , n); + } + numBits += n; + } + n=0; + lastval=dest[idx]; + }//end for + return numBits; } //by marshmellow (from holiman's base) // full fsk demod from GraphBuffer wave to decoded 1s and 0s (no mandemod) int fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uint8_t fchigh, uint8_t fclow) { - // FSK demodulator - size = fsk_wave_demod(dest, size, fchigh, fclow); - size = aggregate_bits(dest, size,rfLen,192,invert,fchigh,fclow); - return size; + // FSK demodulator + size = fsk_wave_demod(dest, size, fchigh, fclow); + size = aggregate_bits(dest, size, rfLen, 192, invert, fchigh, fclow); + return size; } // loop to get raw HID waveform then FSK demodulate the TAG ID from it int HIDdemodFSK(uint8_t *dest, size_t size, uint32_t *hi2, uint32_t *hi, uint32_t *lo) { - size_t idx=0; //, found=0; //size=0, - // FSK demodulator - size = fskdemod(dest, size,50,0,10,8); + size_t idx=0; //, found=0; //size=0, + // FSK demodulator + size = fskdemod(dest, size,50,0,10,8); - // final loop, go over previously decoded manchester data and decode into usable tag ID - // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0 - uint8_t frame_marker_mask[] = {1,1,1,0,0,0}; - int numshifts = 0; - idx = 0; - //one scan - while( idx + sizeof(frame_marker_mask) < size) { - // search for a start of frame marker - if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) - { // frame marker found - idx+=sizeof(frame_marker_mask); - while(dest[idx] != dest[idx+1] && idx < size-2) - { - // Keep going until next frame marker (or error) - // Shift in a bit. Start by shifting high registers - *hi2 = (*hi2<<1)|(*hi>>31); - *hi = (*hi<<1)|(*lo>>31); - //Then, shift in a 0 or one into low - if (dest[idx] && !dest[idx+1]) // 1 0 - *lo=(*lo<<1)|0; - else // 0 1 - *lo=(*lo<<1)|1; - numshifts++; - idx += 2; - } - // Hopefully, we read a tag and hit upon the next frame marker - if(idx + sizeof(frame_marker_mask) < size) - { - if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) - { - //good return - return idx; - } - } - // reset - *hi2 = *hi = *lo = 0; - numshifts = 0; - }else { - idx++; - } - } - return -1; + // final loop, go over previously decoded manchester data and decode into usable tag ID + // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0 + uint8_t frame_marker_mask[] = {1,1,1,0,0,0}; + int numshifts = 0; + idx = 0; + //one scan + while( idx + sizeof(frame_marker_mask) < size) { + // search for a start of frame marker + if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) + { // frame marker found + idx+=sizeof(frame_marker_mask); + while(dest[idx] != dest[idx+1] && idx < size-2) + { + // Keep going until next frame marker (or error) + // Shift in a bit. Start by shifting high registers + *hi2 = (*hi2<<1)|(*hi>>31); + *hi = (*hi<<1)|(*lo>>31); + //Then, shift in a 0 or one into low + if (dest[idx] && !dest[idx+1]) // 1 0 + *lo=(*lo<<1)|0; + else // 0 1 + *lo=(*lo<<1)|1; + numshifts++; + idx += 2; + } + // Hopefully, we read a tag and hit upon the next frame marker + if(idx + sizeof(frame_marker_mask) < size) + { + if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) + { + //good return + return idx; + } + } + // reset + *hi2 = *hi = *lo = 0; + numshifts = 0; + }else { + idx++; + } + } + return -1; } -uint32_t bytebits_to_byte(uint8_t* src, int numbits) +uint32_t bytebits_to_byte(uint8_t* src, size_t numbits) { - uint32_t num = 0; - for(int i = 0 ; i < numbits ; i++) - { - num = (num << 1) | (*src); - src++; - } - return num; + uint32_t num = 0; + for(int i = 0 ; i < numbits ; i++) + { + num = (num << 1) | (*src); + src++; + } + return num; } int IOdemodFSK(uint8_t *dest, size_t size) { - uint32_t idx=0; - //make sure buffer has data - if (size < 66) return -1; - //test samples are not just noise - uint8_t testMax=0; - for(idx=0;idx<65;idx++){ - if (testMax20){ - // FSK demodulator - size = fskdemod(dest, size,64,1,10,8); // RF/64 and invert - if (size < 65) return -1; //did we get a good demod? - //Index map - //0 10 20 30 40 50 60 - //| | | | | | | - //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23 - //----------------------------------------------------------------------------- - //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11 - // - //XSF(version)facility:codeone+codetwo - //Handle the data - uint8_t mask[] = {0,0,0,0,0,0,0,0,0,1}; - for( idx=0; idx < (size - 65); idx++) { - if ( memcmp(dest + idx, mask, sizeof(mask))==0) { - //frame marker found - if (!dest[idx+8] && dest[idx+17]==1 && dest[idx+26]==1 && dest[idx+35]==1 && dest[idx+44]==1 && dest[idx+53]==1){ - //confirmed proper separator bits found - //return start position - return (int) idx; - } - } - } - } - return 0; + static const uint8_t THRESHOLD = 140; + uint32_t idx=0; + //make sure buffer has data + if (size < 66) return -1; + //test samples are not just noise + uint8_t justNoise = 1; + for(idx=0;idx< size && justNoise ;idx++){ + justNoise = dest[idx] < THRESHOLD; + } + if(justNoise) return 0; + + // FSK demodulator + size = fskdemod(dest, size, 64, 1, 10, 8); // RF/64 and invert + if (size < 65) return -1; //did we get a good demod? + //Index map + //0 10 20 30 40 50 60 + //| | | | | | | + //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23 + //----------------------------------------------------------------------------- + //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11 + // + //XSF(version)facility:codeone+codetwo + //Handle the data + uint8_t mask[] = {0,0,0,0,0,0,0,0,0,1}; + for( idx=0; idx < (size - 65); idx++) { + if ( memcmp(dest + idx, mask, sizeof(mask))==0) { + //frame marker found + if (!dest[idx+8] && dest[idx+17]==1 && dest[idx+26]==1 && dest[idx+35]==1 && dest[idx+44]==1 && dest[idx+53]==1){ + //confirmed proper separator bits found + //return start position + return (int) idx; + } + } + } + return 0; } // by marshmellow @@ -635,67 +633,405 @@ int IOdemodFSK(uint8_t *dest, size_t size) // maybe somehow adjust peak trimming value based on samples to fix? int DetectASKClock(uint8_t dest[], size_t size, int clock) { - int i=0; - int peak=0; - int low=128; - int clk[]={16,32,40,50,64,100,128,256}; - int loopCnt = 256; //don't need to loop through entire array... - if (sizepeak){ - peak = dest[i]; - } - if(dest[i]=peak) || (dest[ii]<=low)){ - errCnt[clkCnt]=0; - // now that we have the first one lined up test rest of wave array - for (i=0; i<((int)(size/clk[clkCnt])-1); ++i){ - if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){ - }else if(dest[ii+(i*clk[clkCnt])-tol]>=peak || dest[ii+(i*clk[clkCnt])-tol]<=low){ - }else if(dest[ii+(i*clk[clkCnt])+tol]>=peak || dest[ii+(i*clk[clkCnt])+tol]<=low){ - }else{ //error no peak detected - errCnt[clkCnt]++; - } - } - //if we found no errors this is correct one - return this clock - if(errCnt[clkCnt]==0) return clk[clkCnt]; - //if we found errors see if it is lowest so far and save it as best run - if(errCnt[clkCnt]peak){ + peak = dest[i]; + } + if(dest[i]=peak) || (dest[ii]<=low)){ + errCnt=0; + // now that we have the first one lined up test rest of wave array + for (i=0; i<((int)(size/clk[clkCnt])-1); ++i){ + if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){ + }else if(dest[ii+(i*clk[clkCnt])-tol]>=peak || dest[ii+(i*clk[clkCnt])-tol]<=low){ + }else if(dest[ii+(i*clk[clkCnt])+tol]>=peak || dest[ii+(i*clk[clkCnt])+tol]<=low){ + }else{ //error no peak detected + errCnt++; + } + } + //if we found no errors this is correct one - return this clock + if(errCnt==0) return clk[clkCnt]; + //if we found errors see if it is lowest so far and save it as best run + if(errCntpeak){ + peak = dest[i]; + } + if(dest[i]=peak) || (dest[ii]<=low)){ + errCnt=0; + peakcnt=0; + // now that we have the first one lined up test rest of wave array + for (i=0; i<((int)(size/clk[clkCnt])-1); ++i){ + if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){ + peakcnt++; + }else if(dest[ii+(i*clk[clkCnt])-tol]>=peak || dest[ii+(i*clk[clkCnt])-tol]<=low){ + peakcnt++; + }else if(dest[ii+(i*clk[clkCnt])+tol]>=peak || dest[ii+(i*clk[clkCnt])+tol]<=low){ + peakcnt++; + }else{ //error no peak detected + errCnt++; + } + } + if(peakcnt>peaksdet[clkCnt]) { + peaksdet[clkCnt]=peakcnt; + bestErr[clkCnt]=errCnt; + } + } + } + } + int iii=0; + int best=0; + //int ratio2; //debug + int ratio; + //int bits; + for (iii=0; iii<7;++iii){ + ratio=1000; + //ratio2=1000; //debug + //bits=size/clk[iii]; //debug + if (peaksdet[iii]>0){ + ratio=bestErr[iii]/peaksdet[iii]; + if (((bestErr[best]/peaksdet[best])>(ratio)+1)){ + best = iii; + } + //ratio2=bits/peaksdet[iii]; //debug + } + //PrintAndLog("DEBUG: Clk: %d, peaks: %d, errs: %d, bestClk: %d, ratio: %d, bits: %d, peakbitr: %d",clk[iii],peaksdet[iii],bestErr[iii],clk[best],ratio, bits,ratio2); + } + return clk[best]; +} + +//by marshmellow (attempt to get rid of high immediately after a low) +void pskCleanWave(uint8_t *bitStream, size_t size) +{ + int i; + int low=128; + int high=0; + int gap = 4; + // int loopMax = 2048; + int newLow=0; + int newHigh=0; + for (i=0; ihigh) high=bitStream[i]; + } + high = (int)(((high-128)*.80)+128); + low = (int)(((low-128)*.90)+128); + //low = (uint8_t)(((int)(low)-128)*.80)+128; + for (i=0; i=high) newHigh=1; + } + return; +} + + +//redesigned by marshmellow adjusted from existing decode functions +//indala id decoding - only tested on 26 bit tags, but attempted to make it work for more +int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert) +{ + //26 bit 40134 format (don't know other formats) + int i; + int long_wait; + long_wait = 29;//29 leading zeros in format + int start; + int first = 0; + int first2 = 0; + int bitCnt = 0; + int ii; + // Finding the start of a UID + for (start = 0; start <= *size - 250; start++) { + first = bitStream[start]; + for (i = start; i < start + long_wait; i++) { + if (bitStream[i] != first) { + break; + } + } + if (i == (start + long_wait)) { + break; + } + } + if (start == *size - 250 + 1) { + // did not find start sequence + return -1; + } + //found start once now test length by finding next one + // Inverting signal if needed + if (first == 1) { + for (i = start; i < *size; i++) { + bitStream[i] = !bitStream[i]; + } + *invert = 1; + }else *invert=0; + + int iii; + for (ii=start+29; ii <= *size - 250; ii++) { + first2 = bitStream[ii]; + for (iii = ii; iii < ii + long_wait; iii++) { + if (bitStream[iii] != first2) { + break; + } + } + if (iii == (ii + long_wait)) { + break; + } + } + if (ii== *size - 250 + 1){ + // did not find second start sequence + return -2; + } + bitCnt=ii-start; + + // Dumping UID + i = start; + for (ii = 0; ii < bitCnt; ii++) { + bitStream[ii] = bitStream[i++]; + } + *size=bitCnt; + return 1; +} + + +//by marshmellow - demodulate PSK wave or NRZ wave (both similar enough) +//peaks switch bit (high=1 low=0) each clock cycle = 1 bit determined by last peak +int pskNRZrawDemod(uint8_t *dest, size_t *size, int *clk, int *invert) +{ + pskCleanWave(dest,*size); + int clk2 = DetectpskNRZClock(dest, *size, *clk); + *clk=clk2; + uint32_t i; + uint8_t high=0, low=128; + uint32_t gLen = *size; + if (gLen > 1280) gLen=1280; + // get high + for (i=0; ihigh) high = dest[i]; + if (dest[i]=high)||(dest[iii]<=low)){ + lastBit=iii-*clk; + //loop through to see if this start location works + for (i = iii; i < *size; ++i) { + //if we found a high bar and we are at a clock bit + if ((dest[i]>=high ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ + bitHigh=1; + lastBit+=*clk; + ignorewin=*clk/8; + bitnum++; + //else if low bar found and we are at a clock point + }else if ((dest[i]<=low ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ + bitHigh=1; + lastBit+=*clk; + ignorewin=*clk/8; + bitnum++; + //else if no bars found + }else if(dest[i]low) { + if (ignorewin==0){ + bitHigh=0; + }else ignorewin--; + //if we are past a clock point + if (i>=lastBit+*clk+tol){ //clock val + lastBit+=*clk; + bitnum++; + } + //else if bar found but we are not at a clock bit and we did not just have a clock bit + }else if ((dest[i]>=high || dest[i]<=low) && (ilastBit+*clk+tol) && (bitHigh==0)){ + //error bar found no clock... + errCnt++; + } + if (bitnum>=1000) break; + } + //we got more than 64 good bits and not all errors + if ((bitnum > (64+errCnt)) && (errCnt<(maxErr))) { + //possible good read + if (errCnt==0){ + bestStart = iii; + bestErrCnt=errCnt; + break; //great read - finish + } + if (bestStart == iii) break; //if current run == bestErrCnt run (after exhausted testing) then finish + if (errCnt=high ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ + bitHigh=1; + lastBit+=*clk; + curBit=1-*invert; + dest[bitnum]=curBit; + ignorewin=*clk/8; + bitnum++; + //else if low bar found and we are at a clock point + }else if ((dest[i]<=low ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ + bitHigh=1; + lastBit+=*clk; + curBit=*invert; + dest[bitnum]=curBit; + ignorewin=*clk/8; + bitnum++; + //else if no bars found + }else if(dest[i]low) { + if (ignorewin==0){ + bitHigh=0; + }else ignorewin--; + //if we are past a clock point + if (i>=lastBit+*clk+tol){ //clock val + lastBit+=*clk; + dest[bitnum]=curBit; + bitnum++; + } + //else if bar found but we are not at a clock bit and we did not just have a clock bit + }else if ((dest[i]>=high || dest[i]<=low) && ((ilastBit+*clk+tol)) && (bitHigh==0)){ + //error bar found no clock... + bitHigh=1; + dest[bitnum]=77; + bitnum++; + errCnt++; + } + if (bitnum >=1000) break; + } + *size=bitnum; + } else{ + *size=bitnum; + *clk=bestStart; + return -1; + } + + if (bitnum>16){ + *size=bitnum; + } else return -1; + return errCnt; +} + diff --git a/common/lfdemod.h b/common/lfdemod.h index ad95fda5e..b0feff043 100644 --- a/common/lfdemod.h +++ b/common/lfdemod.h @@ -1,4 +1,4 @@ -// Copyright (C) 2014 +// Copyright (C) 2014 // // 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 @@ -12,14 +12,18 @@ #include int DetectASKClock(uint8_t dest[], size_t size, int clock); -int askmandemod(uint8_t *BinStream,uint32_t *BitLen,int *clk, int *invert); -uint64_t Em410xDecode(uint8_t *BitStream,uint32_t BitLen); -int manrawdecode(uint8_t *BitStream, int *bitLen); -int BiphaseRawDecode(uint8_t * BitStream, int *bitLen, int offset); -int askrawdemod(uint8_t *BinStream, int *bitLen,int *clk, int *invert); +int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert); +uint64_t Em410xDecode(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 askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert); 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, int numbits); +uint32_t bytebits_to_byte(uint8_t* src, size_t numbits); +int pskNRZrawDemod(uint8_t *dest, size_t *size, int *clk, int *invert); +int DetectpskNRZClock(uint8_t dest[], size_t size, int clock); +int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert); +void pskCleanWave(uint8_t *bitStream, size_t size); #endif From 3aa4014baa5da711770ed37660f38149f8b4ddb0 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Wed, 7 Jan 2015 16:34:02 -0500 Subject: [PATCH 08/11] Fix Tune Samples (broken in commit 12/31 by me) --- client/cmddata.c | 54 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 11 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index bce5d2ced..657a118ba 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1089,24 +1089,56 @@ int CmdSamples(const char *Cmd) int CmdTuneSamples(const char *Cmd) { - int cnt = 0; - int n = 255; - uint8_t got[255]; + int timeout = 0; + printf("\nMeasuring antenna characteristics, please wait..."); - PrintAndLog("Reading %d samples\n", n); - GetFromBigBuf(got,n,7256); // armsrc/apps.h: #define FREE_BUFFER_OFFSET 7256 - WaitForResponse(CMD_ACK,NULL); - for (int j = 0; j < n; j++) { - GraphBuffer[cnt++] = ((int)got[j]) - 128; + UsbCommand c = {CMD_MEASURE_ANTENNA_TUNING}; + SendCommand(&c); + + UsbCommand resp; + while(!WaitForResponseTimeout(CMD_MEASURED_ANTENNA_TUNING,&resp,1000)) { + timeout++; + printf("."); + if (timeout > 7) { + PrintAndLog("\nNo response from Proxmark. Aborting..."); + return 1; + } + } + + int peakv, peakf; + int vLf125, vLf134, vHf; + vLf125 = resp.arg[0] & 0xffff; + vLf134 = resp.arg[0] >> 16; + vHf = resp.arg[1] & 0xffff;; + peakf = resp.arg[2] & 0xffff; + peakv = resp.arg[2] >> 16; + PrintAndLog(""); + PrintAndLog("# LF antenna: %5.2f V @ 125.00 kHz", vLf125/1000.0); + PrintAndLog("# LF antenna: %5.2f V @ 134.00 kHz", vLf134/1000.0); + PrintAndLog("# LF optimal: %5.2f V @%9.2f kHz", peakv/1000.0, 12000.0/(peakf+1)); + PrintAndLog("# HF antenna: %5.2f V @ 13.56 MHz", vHf/1000.0); + if (peakv<2000) + PrintAndLog("# Your LF antenna is unusable."); + else if (peakv<10000) + PrintAndLog("# Your LF antenna is marginal."); + if (vHf<2000) + PrintAndLog("# Your HF antenna is unusable."); + else if (vHf<5000) + PrintAndLog("# Your HF antenna is marginal."); + + for (int i = 0; i < 256; i++) { + GraphBuffer[i] = resp.d.asBytes[i] - 128; } PrintAndLog("Done! Divisor 89 is 134khz, 95 is 125khz.\n"); PrintAndLog("\n"); - GraphTraceLen = n; - RepaintGraphWindow(); - return 0; + GraphTraceLen = 256; + ShowGraphWindow(); + + return 0; } + int CmdLoad(const char *Cmd) { FILE *f = fopen(Cmd, "r"); From 3179383f8549b98eaa977c03105cdec7af5007dc Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Wed, 7 Jan 2015 18:45:47 -0500 Subject: [PATCH 09/11] put cmdlf.c back (only changes spaces to tabs) to make my pull request easier to weed through i did not make any changes to cmdlf just de-spaced it - so i put it back for now. --- client/cmdlf.c | 971 ++++++++++++++++++++++++------------------------- 1 file changed, 479 insertions(+), 492 deletions(-) diff --git a/client/cmdlf.c b/client/cmdlf.c index af24aa809..18bcf747e 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -12,7 +12,6 @@ #include #include #include -//#include "proxusb.h" #include "proxmark3.h" #include "data.h" #include "graph.h" @@ -34,592 +33,580 @@ static int CmdHelp(const char *Cmd); /* send a command before reading */ int CmdLFCommandRead(const char *Cmd) { - static char dummy[3]; + static char dummy[3]; - dummy[0]= ' '; + dummy[0]= ' '; - UsbCommand c = {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K}; - sscanf(Cmd, "%"lli" %"lli" %"lli" %s %s", &c.arg[0], &c.arg[1], &c.arg[2],(char*)(&c.d.asBytes),(char*)(&dummy+1)); - // in case they specified 'h' - strcpy((char *)&c.d.asBytes + strlen((char *)c.d.asBytes), dummy); - SendCommand(&c); - return 0; + UsbCommand c = {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K}; + sscanf(Cmd, "%"lli" %"lli" %"lli" %s %s", &c.arg[0], &c.arg[1], &c.arg[2],(char*)(&c.d.asBytes),(char*)(&dummy+1)); + // in case they specified 'h' + strcpy((char *)&c.d.asBytes + strlen((char *)c.d.asBytes), dummy); + SendCommand(&c); + return 0; } int CmdFlexdemod(const char *Cmd) { - int i; - for (i = 0; i < GraphTraceLen; ++i) { - if (GraphBuffer[i] < 0) { - GraphBuffer[i] = -1; - } else { - GraphBuffer[i] = 1; - } - } + int i; + for (i = 0; i < GraphTraceLen; ++i) { + if (GraphBuffer[i] < 0) { + GraphBuffer[i] = -1; + } else { + GraphBuffer[i] = 1; + } + } - #define LONG_WAIT 100 - int start; - for (start = 0; start < GraphTraceLen - LONG_WAIT; start++) { - int first = GraphBuffer[start]; - for (i = start; i < start + LONG_WAIT; i++) { - if (GraphBuffer[i] != first) { - break; - } - } - if (i == (start + LONG_WAIT)) { - break; - } - } - if (start == GraphTraceLen - LONG_WAIT) { - PrintAndLog("nothing to wait for"); - return 0; - } +#define LONG_WAIT 100 + int start; + for (start = 0; start < GraphTraceLen - LONG_WAIT; start++) { + int first = GraphBuffer[start]; + for (i = start; i < start + LONG_WAIT; i++) { + if (GraphBuffer[i] != first) { + break; + } + } + if (i == (start + LONG_WAIT)) { + break; + } + } + if (start == GraphTraceLen - LONG_WAIT) { + PrintAndLog("nothing to wait for"); + return 0; + } - GraphBuffer[start] = 2; - GraphBuffer[start+1] = -2; + GraphBuffer[start] = 2; + GraphBuffer[start+1] = -2; + uint8_t bits[64] = {0x00}; - uint8_t bits[64]; + int bit, sum; + i = start; + for (bit = 0; bit < 64; bit++) { + sum = 0; + for (int j = 0; j < 16; j++) { + sum += GraphBuffer[i++]; + } - int bit; - i = start; - for (bit = 0; bit < 64; bit++) { - int j; - int sum = 0; - for (j = 0; j < 16; j++) { - sum += GraphBuffer[i++]; - } - if (sum > 0) { - bits[bit] = 1; - } else { - bits[bit] = 0; - } - PrintAndLog("bit %d sum %d", bit, sum); - } + bits[bit] = (sum > 0) ? 1 : 0; - for (bit = 0; bit < 64; bit++) { - int j; - int sum = 0; - for (j = 0; j < 16; j++) { - sum += GraphBuffer[i++]; - } - if (sum > 0 && bits[bit] != 1) { - PrintAndLog("oops1 at %d", bit); - } - if (sum < 0 && bits[bit] != 0) { - PrintAndLog("oops2 at %d", bit); - } - } + PrintAndLog("bit %d sum %d", bit, sum); + } - GraphTraceLen = 32*64; - i = 0; - int phase = 0; - for (bit = 0; bit < 64; bit++) { - if (bits[bit] == 0) { - phase = 0; - } else { - phase = 1; - } - int j; - for (j = 0; j < 32; j++) { - GraphBuffer[i++] = phase; - phase = !phase; - } - } + for (bit = 0; bit < 64; bit++) { + int j; + int sum = 0; + for (j = 0; j < 16; j++) { + sum += GraphBuffer[i++]; + } + if (sum > 0 && bits[bit] != 1) { + PrintAndLog("oops1 at %d", bit); + } + if (sum < 0 && bits[bit] != 0) { + PrintAndLog("oops2 at %d", bit); + } + } - RepaintGraphWindow(); - return 0; -} + // HACK writing back to graphbuffer. + GraphTraceLen = 32*64; + i = 0; + int phase = 0; + for (bit = 0; bit < 64; bit++) { + phase = (bits[bit] == 0) ? 0 : 1; + + int j; + for (j = 0; j < 32; j++) { + GraphBuffer[i++] = phase; + phase = !phase; + } + } + + RepaintGraphWindow(); + return 0; +} + int CmdIndalaDemod(const char *Cmd) { - // Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID + // Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID - int state = -1; - int count = 0; - int i, j; - // worst case with GraphTraceLen=64000 is < 4096 - // under normal conditions it's < 2048 - uint8_t rawbits[4096]; - int rawbit = 0; - int worst = 0, worstPos = 0; + int state = -1; + int count = 0; + int i, j; + + // worst case with GraphTraceLen=64000 is < 4096 + // under normal conditions it's < 2048 + + uint8_t rawbits[4096]; + int rawbit = 0; + int worst = 0, worstPos = 0; // PrintAndLog("Expecting a bit less than %d raw bits", GraphTraceLen / 32); - for (i = 0; i < GraphTraceLen-1; i += 2) { - count += 1; - if ((GraphBuffer[i] > GraphBuffer[i + 1]) && (state != 1)) { - if (state == 0) { - for (j = 0; j < count - 8; j += 16) { - rawbits[rawbit++] = 0; - } - if ((abs(count - j)) > worst) { - worst = abs(count - j); - worstPos = i; - } - } - state = 1; - count = 0; - } else if ((GraphBuffer[i] < GraphBuffer[i + 1]) && (state != 0)) { - if (state == 1) { - for (j = 0; j < count - 8; j += 16) { - rawbits[rawbit++] = 1; - } - if ((abs(count - j)) > worst) { - worst = abs(count - j); - worstPos = i; - } - } - state = 0; - count = 0; - } - } - if (rawbit>0){ - PrintAndLog("Recovered %d raw bits, expected: %d", rawbit, GraphTraceLen/32); - PrintAndLog("worst metric (0=best..7=worst): %d at pos %d", worst, worstPos); - } else return 0; - // Finding the start of a UID - int uidlen, long_wait; - if (strcmp(Cmd, "224") == 0) { - uidlen = 224; - long_wait = 30; + for (i = 0; i < GraphTraceLen-1; i += 2) { + count += 1; + if ((GraphBuffer[i] > GraphBuffer[i + 1]) && (state != 1)) { + if (state == 0) { + for (j = 0; j < count - 8; j += 16) { + rawbits[rawbit++] = 0; + } + if ((abs(count - j)) > worst) { + worst = abs(count - j); + worstPos = i; + } + } + state = 1; + count = 0; + } else if ((GraphBuffer[i] < GraphBuffer[i + 1]) && (state != 0)) { + if (state == 1) { + for (j = 0; j < count - 8; j += 16) { + rawbits[rawbit++] = 1; + } + if ((abs(count - j)) > worst) { + worst = abs(count - j); + worstPos = i; + } + } + state = 0; + count = 0; + } + } + + if (rawbit>0){ + PrintAndLog("Recovered %d raw bits, expected: %d", rawbit, GraphTraceLen/32); + PrintAndLog("worst metric (0=best..7=worst): %d at pos %d", worst, worstPos); } else { - uidlen = 64; - long_wait = 29; - } - int start; - int first = 0; - for (start = 0; start <= rawbit - uidlen; start++) { - first = rawbits[start]; - for (i = start; i < start + long_wait; i++) { - if (rawbits[i] != first) { - break; - } - } - if (i == (start + long_wait)) { - break; - } - } - if (start == rawbit - uidlen + 1) { - PrintAndLog("nothing to wait for"); return 0; } - // Inverting signal if needed - if (first == 1) { - for (i = start; i < rawbit; i++) { - rawbits[i] = !rawbits[i]; - } - } + // Finding the start of a UID + int uidlen, long_wait; + if (strcmp(Cmd, "224") == 0) { + uidlen = 224; + long_wait = 30; + } else { + uidlen = 64; + long_wait = 29; + } - // Dumping UID - uint8_t bits[224]; - char showbits[225]; - showbits[uidlen]='\0'; - int bit; - i = start; - int times = 0; - if (uidlen > rawbit) { - PrintAndLog("Warning: not enough raw bits to get a full UID"); - for (bit = 0; bit < rawbit; bit++) { - bits[bit] = rawbits[i++]; - // As we cannot know the parity, let's use "." and "/" - showbits[bit] = '.' + bits[bit]; - } - showbits[bit+1]='\0'; - PrintAndLog("Partial UID=%s", showbits); - return 0; - } else { - for (bit = 0; bit < uidlen; bit++) { - bits[bit] = rawbits[i++]; - showbits[bit] = '0' + bits[bit]; - } - times = 1; - } + int start; + int first = 0; + for (start = 0; start <= rawbit - uidlen; start++) { + first = rawbits[start]; + for (i = start; i < start + long_wait; i++) { + if (rawbits[i] != first) { + break; + } + } + if (i == (start + long_wait)) { + break; + } + } + + if (start == rawbit - uidlen + 1) { + PrintAndLog("nothing to wait for"); + return 0; + } + + // Inverting signal if needed + if (first == 1) { + for (i = start; i < rawbit; i++) { + rawbits[i] = !rawbits[i]; + } + } + + // Dumping UID + uint8_t bits[224] = {0x00}; + char showbits[225] = {0x00}; + int bit; + i = start; + int times = 0; - //convert UID to HEX - uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7; - int idx; - uid1=0; - uid2=0; - if (uidlen==64){ - for( idx=0; idx<64; idx++) { - if (showbits[idx] == '0') { - uid1=(uid1<<1)|(uid2>>31); - uid2=(uid2<<1)|0; - } else { - uid1=(uid1<<1)|(uid2>>31); - uid2=(uid2<<1)|1; - } - } - PrintAndLog("UID=%s (%x%08x)", showbits, uid1, uid2); - } - else { - uid3=0; - uid4=0; - uid5=0; - uid6=0; - uid7=0; - for( idx=0; idx<224; idx++) { - uid1=(uid1<<1)|(uid2>>31); - uid2=(uid2<<1)|(uid3>>31); - uid3=(uid3<<1)|(uid4>>31); - uid4=(uid4<<1)|(uid5>>31); - uid5=(uid5<<1)|(uid6>>31); - uid6=(uid6<<1)|(uid7>>31); - if (showbits[idx] == '0') uid7=(uid7<<1)|0; - else uid7=(uid7<<1)|1; - } - PrintAndLog("UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7); - } + if (uidlen > rawbit) { + PrintAndLog("Warning: not enough raw bits to get a full UID"); + for (bit = 0; bit < rawbit; bit++) { + bits[bit] = rawbits[i++]; + // As we cannot know the parity, let's use "." and "/" + showbits[bit] = '.' + bits[bit]; + } + showbits[bit+1]='\0'; + PrintAndLog("Partial UID=%s", showbits); + return 0; + } else { + for (bit = 0; bit < uidlen; bit++) { + bits[bit] = rawbits[i++]; + showbits[bit] = '0' + bits[bit]; + } + times = 1; + } + + //convert UID to HEX + uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7; + int idx; + uid1 = uid2 = 0; + + if (uidlen==64){ + for( idx=0; idx<64; idx++) { + if (showbits[idx] == '0') { + uid1=(uid1<<1)|(uid2>>31); + uid2=(uid2<<1)|0; + } else { + uid1=(uid1<<1)|(uid2>>31); + uid2=(uid2<<1)|1; + } + } + PrintAndLog("UID=%s (%x%08x)", showbits, uid1, uid2); + } + else { + uid3 = uid4 = uid5 = uid6 = uid7 = 0; - // Checking UID against next occurrences + for( idx=0; idx<224; idx++) { + uid1=(uid1<<1)|(uid2>>31); + uid2=(uid2<<1)|(uid3>>31); + uid3=(uid3<<1)|(uid4>>31); + uid4=(uid4<<1)|(uid5>>31); + uid5=(uid5<<1)|(uid6>>31); + uid6=(uid6<<1)|(uid7>>31); + + if (showbits[idx] == '0') + uid7 = (uid7<<1) | 0; + else + uid7 = (uid7<<1) | 1; + } + PrintAndLog("UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7); + } + + // Checking UID against next occurrences + int failed = 0; for (; i + uidlen <= rawbit;) { - int failed = 0; - for (bit = 0; bit < uidlen; bit++) { - if (bits[bit] != rawbits[i++]) { - failed = 1; - break; - } - } - if (failed == 1) { - break; - } - times += 1; - } - PrintAndLog("Occurrences: %d (expected %d)", times, (rawbit - start) / uidlen); + failed = 0; + for (bit = 0; bit < uidlen; bit++) { + if (bits[bit] != rawbits[i++]) { + failed = 1; + break; + } + } + if (failed == 1) { + break; + } + times += 1; + } - // Remodulating for tag cloning - GraphTraceLen = 32*uidlen; - i = 0; - int phase = 0; - for (bit = 0; bit < uidlen; bit++) { - if (bits[bit] == 0) { - phase = 0; - } else { - phase = 1; - } - int j; - for (j = 0; j < 32; j++) { - GraphBuffer[i++] = phase; - phase = !phase; - } - } + PrintAndLog("Occurrences: %d (expected %d)", times, (rawbit - start) / uidlen); - RepaintGraphWindow(); - return 1; + // Remodulating for tag cloning + // HACK: 2015-01-04 this will have an impact on our new way of seening lf commands (demod) + // since this changes graphbuffer data. + GraphTraceLen = 32*uidlen; + i = 0; + int phase = 0; + for (bit = 0; bit < uidlen; bit++) { + if (bits[bit] == 0) { + phase = 0; + } else { + phase = 1; + } + int j; + for (j = 0; j < 32; j++) { + GraphBuffer[i++] = phase; + phase = !phase; + } + } + + RepaintGraphWindow(); + return 1; } int CmdIndalaClone(const char *Cmd) { + UsbCommand c; unsigned int uid1, uid2, uid3, uid4, uid5, uid6, uid7; - UsbCommand c; - uid1=0; - uid2=0; - uid3=0; - uid4=0; - uid5=0; - uid6=0; - uid7=0; - int n = 0, i = 0; - if (strchr(Cmd,'l') != 0) { - while (sscanf(&Cmd[i++], "%1x", &n ) == 1) { - uid1 = (uid1 << 4) | (uid2 >> 28); - uid2 = (uid2 << 4) | (uid3 >> 28); - uid3 = (uid3 << 4) | (uid4 >> 28); - uid4 = (uid4 << 4) | (uid5 >> 28); - uid5 = (uid5 << 4) | (uid6 >> 28); - uid6 = (uid6 << 4) | (uid7 >> 28); - uid7 = (uid7 << 4) | (n & 0xf); - } - PrintAndLog("Cloning 224bit tag with UID %x%08x%08x%08x%08x%08x%08x", uid1, uid2, uid3, uid4, uid5, uid6, uid7); - c.cmd = CMD_INDALA_CLONE_TAG_L; - c.d.asDwords[0] = uid1; - c.d.asDwords[1] = uid2; - c.d.asDwords[2] = uid3; - c.d.asDwords[3] = uid4; - c.d.asDwords[4] = uid5; - c.d.asDwords[5] = uid6; - c.d.asDwords[6] = uid7; - } - else - { - while (sscanf(&Cmd[i++], "%1x", &n ) == 1) { - uid1 = (uid1 << 4) | (uid2 >> 28); - uid2 = (uid2 << 4) | (n & 0xf); - } - PrintAndLog("Cloning 64bit tag with UID %x%08x", uid1, uid2); - c.cmd = CMD_INDALA_CLONE_TAG; - c.arg[0] = uid1; - c.arg[1] = uid2; - } + uid1 = uid2 = uid3 = uid4 = uid5 = uid6 = uid7 = 0; + int n = 0, i = 0; - SendCommand(&c); - return 0; + if (strchr(Cmd,'l') != 0) { + while (sscanf(&Cmd[i++], "%1x", &n ) == 1) { + uid1 = (uid1 << 4) | (uid2 >> 28); + uid2 = (uid2 << 4) | (uid3 >> 28); + uid3 = (uid3 << 4) | (uid4 >> 28); + uid4 = (uid4 << 4) | (uid5 >> 28); + uid5 = (uid5 << 4) | (uid6 >> 28); + uid6 = (uid6 << 4) | (uid7 >> 28); + uid7 = (uid7 << 4) | (n & 0xf); + } + PrintAndLog("Cloning 224bit tag with UID %x%08x%08x%08x%08x%08x%08x", uid1, uid2, uid3, uid4, uid5, uid6, uid7); + c.cmd = CMD_INDALA_CLONE_TAG_L; + c.d.asDwords[0] = uid1; + c.d.asDwords[1] = uid2; + c.d.asDwords[2] = uid3; + c.d.asDwords[3] = uid4; + c.d.asDwords[4] = uid5; + c.d.asDwords[5] = uid6; + c.d.asDwords[6] = uid7; + } else { + while (sscanf(&Cmd[i++], "%1x", &n ) == 1) { + uid1 = (uid1 << 4) | (uid2 >> 28); + uid2 = (uid2 << 4) | (n & 0xf); + } + PrintAndLog("Cloning 64bit tag with UID %x%08x", uid1, uid2); + c.cmd = CMD_INDALA_CLONE_TAG; + c.arg[0] = uid1; + c.arg[1] = uid2; + } + + SendCommand(&c); + return 0; } int CmdLFRead(const char *Cmd) { - UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K}; - // 'h' means higher-low-frequency, 134 kHz - if(*Cmd == 'h') { - c.arg[0] = 1; - } else if (*Cmd == '\0') { - c.arg[0] = 0; - } else if (sscanf(Cmd, "%"lli, &c.arg[0]) != 1) { - PrintAndLog("use 'read' or 'read h', or 'read '"); - return 0; - } - SendCommand(&c); - WaitForResponse(CMD_ACK,NULL); - return 0; + UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K}; + + // 'h' means higher-low-frequency, 134 kHz + if(*Cmd == 'h') { + c.arg[0] = 1; + } else if (*Cmd == '\0') { + c.arg[0] = 0; + } else if (sscanf(Cmd, "%"lli, &c.arg[0]) != 1) { + PrintAndLog("Samples 1: 'lf read'"); + PrintAndLog(" 2: 'lf read h'"); + PrintAndLog(" 3: 'lf read '"); + return 0; + } + SendCommand(&c); + WaitForResponse(CMD_ACK,NULL); + return 0; } static void ChkBitstream(const char *str) { - int i; + int i; - /* convert to bitstream if necessary */ - for (i = 0; i < (int)(GraphTraceLen / 2); i++) - { - if (GraphBuffer[i] > 1 || GraphBuffer[i] < 0) - { - CmdBitstream(str); - break; - } - } + /* convert to bitstream if necessary */ + for (i = 0; i < (int)(GraphTraceLen / 2); i++) + { + if (GraphBuffer[i] > 1 || GraphBuffer[i] < 0) + { + CmdBitstream(str); + break; + } + } } int CmdLFSim(const char *Cmd) { - int i; - static int gap; + int i; + static int gap; - sscanf(Cmd, "%i", &gap); + sscanf(Cmd, "%i", &gap); - /* convert to bitstream if necessary */ - ChkBitstream(Cmd); + /* convert to bitstream if necessary */ + ChkBitstream(Cmd); - PrintAndLog("Sending data, please wait..."); - for (i = 0; i < GraphTraceLen; i += 48) { - UsbCommand c={CMD_DOWNLOADED_SIM_SAMPLES_125K, {i, 0, 0}}; - int j; - for (j = 0; j < 48; j++) { - c.d.asBytes[j] = GraphBuffer[i+j]; - } - SendCommand(&c); - WaitForResponse(CMD_ACK,NULL); - } + PrintAndLog("Sending data, please wait..."); + for (i = 0; i < GraphTraceLen; i += 48) { + UsbCommand c={CMD_DOWNLOADED_SIM_SAMPLES_125K, {i, 0, 0}}; + int j; + for (j = 0; j < 48; j++) { + c.d.asBytes[j] = GraphBuffer[i+j]; + } + SendCommand(&c); + WaitForResponse(CMD_ACK,NULL); + } - PrintAndLog("Starting simulator..."); - UsbCommand c = {CMD_SIMULATE_TAG_125K, {GraphTraceLen, gap, 0}}; - SendCommand(&c); - return 0; + PrintAndLog("Starting simulator..."); + UsbCommand c = {CMD_SIMULATE_TAG_125K, {GraphTraceLen, gap, 0}}; + SendCommand(&c); + return 0; } int CmdLFSimBidir(const char *Cmd) { - /* Set ADC to twice the carrier for a slight supersampling */ - UsbCommand c = {CMD_LF_SIMULATE_BIDIR, {47, 384, 0}}; - SendCommand(&c); - return 0; + // Set ADC to twice the carrier for a slight supersampling + // HACK: not implemented in ARMSRC. + PrintAndLog("Not implemented yet."); + UsbCommand c = {CMD_LF_SIMULATE_BIDIR, {47, 384, 0}}; + SendCommand(&c); + 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]; + static int clock, gap; + static char data[1024], gapstring[8]; - /* get settings/bits */ - sscanf(Cmd, "%i %s %i", &clock, &data[0], &gap); + sscanf(Cmd, "%i %s %i", &clock, &data[0], &gap); - /* clear our graph */ - ClearGraph(0); + ClearGraph(0); - /* fill it with our bitstream */ - for (int i = 0; i < strlen(data) ; ++i) - AppendGraph(0, clock, data[i]- '0'); + for (int i = 0; i < strlen(data) ; ++i) + AppendGraph(0, clock, data[i]- '0'); - /* modulate */ - CmdManchesterMod(""); + CmdManchesterMod(""); - /* show what we've done */ - RepaintGraphWindow(); + RepaintGraphWindow(); - /* simulate */ - sprintf(&gapstring[0], "%i", gap); - CmdLFSim(gapstring); - return 0; + sprintf(&gapstring[0], "%i", gap); + CmdLFSim(gapstring); + return 0; } int CmdLFSnoop(const char *Cmd) { - UsbCommand c = {CMD_LF_SNOOP_RAW_ADC_SAMPLES}; - // 'h' means higher-low-frequency, 134 kHz - c.arg[0] = 0; - c.arg[1] = -1; - if (*Cmd == 0) { - // empty - } else if (*Cmd == 'l') { - sscanf(Cmd, "l %"lli, &c.arg[1]); - } else if(*Cmd == 'h') { - c.arg[0] = 1; - sscanf(Cmd, "h %"lli, &c.arg[1]); - } else if (sscanf(Cmd, "%"lli" %"lli, &c.arg[0], &c.arg[1]) < 1) { - PrintAndLog("use 'snoop' or 'snoop {l,h} [trigger threshold]', or 'snoop [trigger threshold]'"); - return 0; - } - SendCommand(&c); - WaitForResponse(CMD_ACK,NULL); - return 0; + UsbCommand c = {CMD_LF_SNOOP_RAW_ADC_SAMPLES}; + + // 'h' means higher-low-frequency, 134 kHz + c.arg[0] = 0; + c.arg[1] = -1; + + if (*Cmd == 'l') { + sscanf(Cmd, "l %"lli, &c.arg[1]); + } else if(*Cmd == 'h') { + c.arg[0] = 1; + sscanf(Cmd, "h %"lli, &c.arg[1]); + } else if (sscanf(Cmd, "%"lli" %"lli, &c.arg[0], &c.arg[1]) < 1) { + PrintAndLog("usage 1: snoop"); + PrintAndLog(" 2: snoop {l,h} [trigger threshold]"); + PrintAndLog(" 3: snoop [trigger threshold]"); + return 0; + } + + SendCommand(&c); + WaitForResponse(CMD_ACK,NULL); + return 0; } int CmdVchDemod(const char *Cmd) { - // Is this the entire sync pattern, or does this also include some - // data bits that happen to be the same everywhere? That would be - // lovely to know. - static const int SyncPattern[] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - }; + // Is this the entire sync pattern, or does this also include some + // data bits that happen to be the same everywhere? That would be + // lovely to know. + static const int SyncPattern[] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }; - // So first, we correlate for the sync pattern, and mark that. - int bestCorrel = 0, bestPos = 0; - int i; - // It does us no good to find the sync pattern, with fewer than - // 2048 samples after it... - for (i = 0; i < (GraphTraceLen-2048); i++) { - int sum = 0; - int j; - for (j = 0; j < arraylen(SyncPattern); j++) { - sum += GraphBuffer[i+j]*SyncPattern[j]; - } - if (sum > bestCorrel) { - bestCorrel = sum; - bestPos = i; - } - } - PrintAndLog("best sync at %d [metric %d]", bestPos, bestCorrel); + // So first, we correlate for the sync pattern, and mark that. + int bestCorrel = 0, bestPos = 0; + int i; + // It does us no good to find the sync pattern, with fewer than + // 2048 samples after it... + for (i = 0; i < (GraphTraceLen-2048); i++) { + int sum = 0; + int j; + for (j = 0; j < arraylen(SyncPattern); j++) { + sum += GraphBuffer[i+j]*SyncPattern[j]; + } + if (sum > bestCorrel) { + bestCorrel = sum; + bestPos = i; + } + } + PrintAndLog("best sync at %d [metric %d]", bestPos, bestCorrel); - char bits[257]; - bits[256] = '\0'; + char bits[257]; + bits[256] = '\0'; - int worst = INT_MAX; - int worstPos = 0; + int worst = INT_MAX; + int worstPos = 0; - for (i = 0; i < 2048; i += 8) { - int sum = 0; - int j; - for (j = 0; j < 8; j++) { - sum += GraphBuffer[bestPos+i+j]; - } - if (sum < 0) { - bits[i/8] = '.'; - } else { - bits[i/8] = '1'; - } - if(abs(sum) < worst) { - worst = abs(sum); - worstPos = i; - } - } - PrintAndLog("bits:"); - PrintAndLog("%s", bits); - PrintAndLog("worst metric: %d at pos %d", worst, worstPos); + for (i = 0; i < 2048; i += 8) { + int sum = 0; + int j; + for (j = 0; j < 8; j++) { + sum += GraphBuffer[bestPos+i+j]; + } + if (sum < 0) { + bits[i/8] = '.'; + } else { + bits[i/8] = '1'; + } + if(abs(sum) < worst) { + worst = abs(sum); + worstPos = i; + } + } + PrintAndLog("bits:"); + PrintAndLog("%s", bits); + PrintAndLog("worst metric: %d at pos %d", worst, worstPos); - if (strcmp(Cmd, "clone")==0) { - GraphTraceLen = 0; - char *s; - for(s = bits; *s; s++) { - int j; - for(j = 0; j < 16; j++) { - GraphBuffer[GraphTraceLen++] = (*s == '1') ? 1 : 0; - } - } - RepaintGraphWindow(); - } - return 0; + if (strcmp(Cmd, "clone")==0) { + GraphTraceLen = 0; + char *s; + for(s = bits; *s; s++) { + int j; + for(j = 0; j < 16; j++) { + GraphBuffer[GraphTraceLen++] = (*s == '1') ? 1 : 0; + } + } + RepaintGraphWindow(); + } + return 0; } //by marshmellow int CmdLFfind(const char *Cmd) { - int ans=0; - if (!offline){ - ans=CmdLFRead(""); - ans=CmdSamples("20000"); - } - if (GraphTraceLen<1000) return 0; - PrintAndLog("NOTE: some demods output possible binary\n if it finds something that looks like a tag"); - PrintAndLog("Checking for known tags:"); - - ans=Cmdaskmandemod(""); - if (ans>0) { - PrintAndLog("Valid EM410x ID Found!"); - return 1; - } - ans=CmdFSKdemodHID(""); - if (ans>0) { - PrintAndLog("Valid HID Prox ID Found!"); - return 1; - } - ans=CmdFSKdemodIO(""); - if (ans>0) { - PrintAndLog("Valid IO Prox ID Found!"); - return 1; - } - //add psk and indala - ans=CmdIndalaDecode(""); - if (ans>0) { - PrintAndLog("Valid Indala ID Found!"); - return 1; - } - // ans=CmdIndalaDemod("224"); - // if (ans>0) return 1; - PrintAndLog("No Known Tags Found!\n"); - return 0; + int ans=0; + if (!offline){ + ans=CmdLFRead(""); + ans=CmdSamples("20000"); + } + if (GraphTraceLen<1000) return 0; + PrintAndLog("Checking for known tags:"); + ans=Cmdaskmandemod(""); + if (ans>0) return 1; + ans=CmdFSKdemodHID(""); + if (ans>0) return 1; + ans=CmdFSKdemodIO(""); + if (ans>0) return 1; + //add psk and indala + ans=CmdIndalaDemod(""); + if (ans>0) return 1; + ans=CmdIndalaDemod("224"); + if (ans>0) return 1; + PrintAndLog("No Known Tags Found!\n"); + return 0; } static command_t CommandTable[] = { - {"help", CmdHelp, 1, "This help"}, - {"cmdread", CmdLFCommandRead, 0, " <'0' period> <'1' period> ['h'] -- Modulate LF reader field to send command before read (all periods in microseconds) (option 'h' for 134)"}, - {"em4x", CmdLFEM4X, 1, "{ EM4X RFIDs... }"}, - {"flexdemod", CmdFlexdemod, 1, "Demodulate samples for FlexPass"}, - {"hid", CmdLFHID, 1, "{ HID RFIDs... }"}, - {"io", CmdLFIO, 1, "{ ioProx tags... }"}, - {"indalademod", CmdIndalaDemod, 1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"}, - {"indalaclone", CmdIndalaClone, 0, " ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"}, - {"read", CmdLFRead, 0, "['h' or ] -- Read 125/134 kHz LF ID-only tag (option 'h' for 134, alternatively: f=12MHz/(divisor+1))"}, - {"search", CmdLFfind, 1, "Read and Search for valid known tag (in offline mode it you can load first then search)"}, - {"sim", CmdLFSim, 0, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"}, - {"simbidir", CmdLFSimBidir, 0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"}, - {"simman", CmdLFSimManchester, 0, " [GAP] Simulate arbitrary Manchester LF tag"}, - {"snoop", CmdLFSnoop, 0, "['l'|'h'|] [trigger threshold]-- Snoop LF (l:125khz, h:134khz)"}, - {"ti", CmdLFTI, 1, "{ TI RFIDs... }"}, - {"hitag", CmdLFHitag, 1, "{ Hitag tags and transponders... }"}, - {"vchdemod", CmdVchDemod, 1, "['clone'] -- Demodulate samples for VeriChip"}, - {"t55xx", CmdLFT55XX, 1, "{ T55xx RFIDs... }"}, - {"pcf7931", CmdLFPCF7931, 1, "{PCF7931 RFIDs...}"}, - {NULL, NULL, 0, NULL} + {"help", CmdHelp, 1, "This help"}, + {"cmdread", CmdLFCommandRead, 0, " <'0' period> <'1' period> ['h'] -- Modulate LF reader field to send command before read (all periods in microseconds) (option 'h' for 134)"}, + {"em4x", CmdLFEM4X, 1, "{ EM4X RFIDs... }"}, + {"flexdemod", CmdFlexdemod, 1, "Demodulate samples for FlexPass"}, + {"hid", CmdLFHID, 1, "{ HID RFIDs... }"}, + {"io", CmdLFIO, 1, "{ ioProx tags... }"}, + {"indalademod", CmdIndalaDemod, 1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"}, + {"indalaclone", CmdIndalaClone, 0, " ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"}, + {"read", CmdLFRead, 0, "['h' or ] -- Read 125/134 kHz LF ID-only tag (option 'h' for 134, alternatively: f=12MHz/(divisor+1))"}, + {"search", CmdLFfind, 1, "Read and Search for valid known tag (in offline mode it you can load first then search)"}, + {"sim", CmdLFSim, 0, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"}, + {"simbidir", CmdLFSimBidir, 0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"}, + {"simman", CmdLFSimManchester, 0, " [GAP] Simulate arbitrary Manchester LF tag"}, + {"snoop", CmdLFSnoop, 0, "['l'|'h'|] [trigger threshold]-- Snoop LF (l:125khz, h:134khz)"}, + {"ti", CmdLFTI, 1, "{ TI RFIDs... }"}, + {"hitag", CmdLFHitag, 1, "{ Hitag tags and transponders... }"}, + {"vchdemod", CmdVchDemod, 1, "['clone'] -- Demodulate samples for VeriChip"}, + {"t55xx", CmdLFT55XX, 1, "{ T55xx RFIDs... }"}, + {"pcf7931", CmdLFPCF7931, 1, "{PCF7931 RFIDs...}"}, + {NULL, NULL, 0, NULL} }; int CmdLF(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; } From d6d20c543547d12eff81c5c3de254cf4b8650868 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Wed, 7 Jan 2015 19:06:29 -0500 Subject: [PATCH 10/11] cmddata.c changes by others - reapply i overwrote some changes in cmdsamples. i fixed that i also removed some comments in graph.c --- client/cmddata.c | 58 +++++++++++------------------------------------- client/graph.c | 36 ++---------------------------- 2 files changed, 15 insertions(+), 79 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index 657a118ba..53a3ce5f4 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -932,35 +932,6 @@ int CmdIndalaDecode(const char *Cmd) return 1; } -/* -//by marshmellow (attempt to get rid of high immediately after a low) -void pskCleanWave2(uint8_t *bitStream, int bitLen) -{ - int i; - int low=128; - int gap = 4; - // int loopMax = 2048; - int newLow=0; - - for (i=0; i sizeof(got)) n = sizeof(got); + int n = strtol(Cmd, NULL, 0); + if (n == 0) + n = 20000; - PrintAndLog("Reading %d samples\n", n); + if (n > sizeof(got)) + n = sizeof(got); + + PrintAndLog("Reading %d samples from device memory\n", n); GetFromBigBuf(got,n,0); WaitForResponse(CMD_ACK,NULL); for (int j = 0; j < n; j++) { - GraphBuffer[cnt++] = ((int)got[j]) - 128; + GraphBuffer[j] = ((int)got[j]) - 128; } - - PrintAndLog("Done!\n"); GraphTraceLen = n; RepaintGraphWindow(); return 0; @@ -1558,8 +1526,8 @@ static command_t CommandTable[] = {"help", CmdHelp, 1, "This help"}, {"amp", CmdAmp, 1, "Amplify peaks"}, {"askdemod", Cmdaskdemod, 1, "<0 or 1> -- Attempt to demodulate simple ASK tags"}, - {"askmandemod", Cmdaskmandemod, 1, "[clock] [invert<0 or 1>] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional[clock will try Auto-detect])"}, - {"askrawdemod", Cmdaskrawdemod, 1, "[clock] [invert<0 or 1>] -- Attempt to demodulate ASK tags and output binary (args optional[clock will try Auto-detect])"}, + {"askmandemod", Cmdaskmandemod, 1, "[clock] [invert<0|1>] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional[clock will try Auto-detect])"}, + {"askrawdemod", Cmdaskrawdemod, 1, "[clock] [invert<0|1>] -- Attempt to demodulate ASK tags and output binary (args optional[clock will try Auto-detect])"}, {"autocorr", CmdAutoCorr, 1, " -- Autocorrelation over window"}, {"biphaserawdecode",CmdBiphaseDecodeRaw,1,"[offset] Biphase decode binary stream already in graph buffer (offset = bit to start decode from)"}, {"bitsamples", CmdBitsamples, 0, "Get raw samples as bitstring"}, @@ -1570,7 +1538,7 @@ static command_t CommandTable[] = {"fskdemod", CmdFSKdemod, 1, "Demodulate graph window as a HID FSK"}, {"fskhiddemod", CmdFSKdemodHID, 1, "Demodulate graph window as a HID FSK using raw"}, {"fskiodemod", CmdFSKdemodIO, 1, "Demodulate graph window as an IO Prox FSK using raw"}, - {"fskrawdemod", CmdFSKrawdemod, 1, "[clock rate] [invert] [rchigh] [rclow] Demodulate graph window from FSK to binary (clock = 50)(invert = 1 or 0)(rchigh = 10)(rclow=8)"}, + {"fskrawdemod", CmdFSKrawdemod, 1, "[clock rate] [invert] [rchigh] [rclow] Demodulate graph window from FSK to binary (clock = 50)(invert = 1|0)(rchigh = 10)(rclow=8)"}, {"grid", CmdGrid, 1, " -- overlay grid on graph window, use zero value to turn off either"}, {"hexsamples", CmdHexsamples, 0, " [] -- Dump big buffer as hex bytes"}, {"hide", CmdHide, 1, "Hide graph window"}, @@ -1585,8 +1553,8 @@ static command_t CommandTable[] = {"plot", CmdPlot, 1, "Show graph window (hit 'h' in window for keystroke help)"}, {"pskclean", CmdPskClean, 1, "Attempt to clean psk wave"}, {"pskdetectclock",CmdDetectNRZpskClockRate, 1, "Detect ASK, PSK, or NRZ clock rate"}, - {"pskindalademod",CmdIndalaDecode, 1, "[clock] [invert<0 or 1>] -- Attempt to demodulate psk indala tags and output ID binary & hex (args optional[clock will try Auto-detect])"}, - {"psknrzrawdemod",CmdpskNRZrawDemod, 1, "[clock] [invert<0 or 1>] -- Attempt to demodulate psk or nrz tags and output binary (args optional[clock will try Auto-detect])"}, + {"pskindalademod",CmdIndalaDecode, 1, "[clock] [invert<0|1>] -- Attempt to demodulate psk indala tags and output ID binary & hex (args optional[clock will try Auto-detect])"}, + {"psknrzrawdemod",CmdpskNRZrawDemod, 1, "[clock] [invert<0|1>] -- Attempt to demodulate psk or nrz tags and output binary (args optional[clock will try Auto-detect])"}, {"samples", CmdSamples, 0, "[512 - 40000] -- Get raw samples for graph window"}, {"save", CmdSave, 1, " -- Save trace (from graph window)"}, {"scale", CmdScale, 1, " -- Set cursor display scale"}, diff --git a/client/graph.c b/client/graph.c index f41568e4f..e03d1a51e 100644 --- a/client/graph.c +++ b/client/graph.c @@ -166,7 +166,6 @@ size_t getFromGraphBuf(uint8_t *buff) int GetClock(const char *str, int peak, int verbose) { int clock; -// int clock2; sscanf(str, "%i", &clock); if (!strcmp(str, "")) clock = 0; @@ -177,46 +176,18 @@ int GetClock(const char *str, int peak, int verbose) uint8_t grph[MAX_GRAPH_TRACE_LEN]={0}; size_t size = getFromGraphBuf(grph); clock = DetectASKClock(grph,size,0); - //clock2 = DetectClock2(peak); /* Only print this message if we're not looping something */ if (!verbose){ PrintAndLog("Auto-detected clock rate: %d", clock); - //PrintAndLog("clock2: %d",clock2); } } return clock; } -int GetNRZpskClock(const char *str, int peak, int verbose) -{ - // return GetClock(str,peak,verbose); - int clock; - // int clock2; - sscanf(str, "%i", &clock); - if (!strcmp(str, "")) - clock = 0; - /* Auto-detect clock */ - if (!clock) - { - uint8_t grph[MAX_GRAPH_TRACE_LEN]={0}; - size_t size = getFromGraphBuf(grph); - clock = DetectpskNRZClock(grph,size,0); - //clock2 = DetectClock2(peak); - /* Only print this message if we're not looping something */ - if (!verbose){ - PrintAndLog("Auto-detected clock rate: %d", clock); - //PrintAndLog("clock2: %d",clock2); - } - } - return clock; -} -// Get or auto-detect clock rate -/* int GetNRZpskClock(const char *str, int peak, int verbose) { int clock; -// int clock2; sscanf(str, "%i", &clock); if (!strcmp(str, "")) clock = 0; @@ -225,15 +196,12 @@ int GetNRZpskClock(const char *str, int peak, int verbose) if (!clock) { uint8_t grph[MAX_GRAPH_TRACE_LEN]={0}; - int size = getFromGraphBuf(grph); - clock = DetectASKClock(grph,size,0); - //clock2 = DetectClock2(peak); + size_t size = getFromGraphBuf(grph); + clock = DetectpskNRZClock(grph,size,0); // Only print this message if we're not looping something if (!verbose){ PrintAndLog("Auto-detected clock rate: %d", clock); - //PrintAndLog("clock2: %d",clock2); } } return clock; } -*/ From c12512e99ad08689e171e80a01f7148e55ee64e1 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Wed, 7 Jan 2015 23:02:00 -0500 Subject: [PATCH 11/11] minor code cleanup --- client/graph.c | 105 ++------------------------------------ common/lfdemod.c | 130 ++++++++++++++++++++--------------------------- 2 files changed, 61 insertions(+), 174 deletions(-) diff --git a/client/graph.c b/client/graph.c index e03d1a51e..9079e0738 100644 --- a/client/graph.c +++ b/client/graph.c @@ -32,7 +32,7 @@ void AppendGraph(int redraw, int clock, int bit) RepaintGraphWindow(); } -/* clear out our graph window */ +// clear out our graph window int ClearGraph(int redraw) { int gtl = GraphTraceLen; @@ -44,103 +44,8 @@ int ClearGraph(int redraw) return gtl; } -/* - * Detect clock rate - */ - //decommissioned - has difficulty detecting rf/32 -/* -int DetectClockOld(int peak) -{ - int i; - int clock = 0xFFFF; - int lastpeak = 0; +// DETECT CLOCK NOW IN LFDEMOD.C - // Detect peak if we don't have one - if (!peak) - for (i = 0; i < GraphTraceLen; ++i) - if (GraphBuffer[i] > peak) - peak = GraphBuffer[i]; - - // peak=(int)(peak*.75); - for (i = 1; i < GraphTraceLen; ++i) - { - // If this is the beginning of a peak - if (GraphBuffer[i - 1] != GraphBuffer[i] && GraphBuffer[i] >= peak) - { - // Find lowest difference between peaks - if (lastpeak && i - lastpeak < clock) - clock = i - lastpeak; - lastpeak = i; - } - } - - return clock; -} -*/ -/* -NOW IN LFDEMOD.C - -// by marshmellow -// not perfect especially with lower clocks or VERY good antennas (heavy wave clipping) -// maybe somehow adjust peak trimming value based on samples to fix? -int DetectASKClock(int peak) -{ - int i=0; - int low=0; - int clk[]={16,32,40,50,64,100,128,256}; - int loopCnt = 256; - if (GraphTraceLenpeak){ - peak = GraphBuffer[i]; - } - if(GraphBuffer[i]=peak) || (GraphBuffer[ii]<=low)){ - errCnt[clkCnt]=0; - for (i=0; i<((int)(GraphTraceLen/clk[clkCnt])-1); ++i){ - if (GraphBuffer[ii+(i*clk[clkCnt])]>=peak || GraphBuffer[ii+(i*clk[clkCnt])]<=low){ - }else if(GraphBuffer[ii+(i*clk[clkCnt])-tol]>=peak || GraphBuffer[ii+(i*clk[clkCnt])-tol]<=low){ - }else if(GraphBuffer[ii+(i*clk[clkCnt])+tol]>=peak || GraphBuffer[ii+(i*clk[clkCnt])+tol]<=low){ - }else{ //error no peak detected - errCnt[clkCnt]++; - } - } - if(errCnt[clkCnt]==0) return clk[clkCnt]; - if(errCnt[clkCnt]>1)<<1)){ parityTest=0; for (ii=0; ii<4;++ii){ - //hi = (hi<<1)|(lo>>31); lo=(lo<<1LL)|(BitStream[(i*5)+ii+idx]); } //PrintAndLog("DEBUG: EM parity passed parity val: %d, i:%d, ii:%d,idx:%d, Buffer: %d%d%d%d%d,lo: %d",parityTest,i,ii,idx,BitStream[idx+ii+(i*5)-5],BitStream[idx+ii+(i*5)-4],BitStream[idx+ii+(i*5)-3],BitStream[idx+ii+(i*5)-2],BitStream[idx+ii+(i*5)-1],lo); @@ -106,8 +105,8 @@ int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert) return -2; } //25% fuzz in case highs and lows aren't clipped [marshmellow] - high=(int)((high-128)*.75)+128; - low= (int)((low-128)*.75)+128; + high=(int)(((high-128)*.75)+128); + low= (int)(((low-128)*.75)+128); //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); int lastBit = 0; //set first clock check @@ -292,7 +291,7 @@ int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert) if (*clk<32) *clk=32; if (*invert != 0 && *invert != 1) *invert =0; uint32_t initLoopMax = 200; - if (initLoopMax>*size) initLoopMax=*size; + if (initLoopMax > *size) initLoopMax=*size; // Detect high and lows for (i = 0; i < initLoopMax; ++i) //200 samples should be plenty to find high and low values { @@ -306,14 +305,16 @@ int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert) return -2; } //25% fuzz in case highs and lows aren't clipped [marshmellow] - high=(int)((high-128)*.75)+128; - low= (int)((low-128)*.75)+128; + high=(int)(((high-128)*.75)+128); + low= (int)(((low-128)*.75)+128); //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); int lastBit = 0; //set first clock check uint32_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 + 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 uint32_t iii = 0; uint32_t gLen = *size; if (gLen > 500) gLen=500; @@ -366,7 +367,6 @@ int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert) bitnum++; } - errCnt++; lastBit+=*clk;//skip over until hit too many errors if (errCnt > ((*size/1000))){ //allow 1 error for every 1000 samples else start over @@ -395,26 +395,10 @@ int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert) } } if (bitnum>16){ - - // PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum); - //move BitStream back to BinStream - // ClearGraph(0); for (i=0; i < bitnum; ++i){ BinStream[i]=BitStream[i]; } *size=bitnum; - // RepaintGraphWindow(); - //output - // if (errCnt>0){ - // PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); - // } - // PrintAndLog("ASK decoded bitstream:"); - // Now output the bitstream to the scrollback by line of 16 bits - // printBitStream2(BitStream,bitnum); - //int errCnt=0; - //errCnt=manrawdemod(BitStream,bitnum); - - // Em410xDecode(Cmd); } else return -1; return errCnt; } @@ -496,10 +480,8 @@ size_t aggregate_bits(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t maxCons //if lastval was 1, we have a 1->0 crossing if ( dest[idx-1]==1 ) { n=myround2((float)(n+1)/((float)(rfLen)/(float)fclow)); - //n=(n+1) / h2l_crossing_value; } else {// 0->1 crossing n=myround2((float)(n+1)/((float)(rfLen-2)/(float)fchigh)); //-2 for fudge factor - //n=(n+1) / l2h_crossing_value; } if (n == 0) n = 1; @@ -642,14 +624,14 @@ int DetectASKClock(uint8_t dest[], size_t size, int clock) //if we already have a valid clock quit for (;i<8;++i) - if (clk[i]==clock) return clock; + if (clk[i] == clock) return clock; //get high and low peak - for (i=0;ipeak){ + for (i=0; i < loopCnt; ++i){ + if(dest[i] > peak){ peak = dest[i]; } - if(dest[i]=peak) || (dest[ii]<=low)){ + for (ii=0; ii< loopCnt; ++ii){ + if ((dest[ii] >= peak) || (dest[ii] <= low)){ errCnt=0; // now that we have the first one lined up test rest of wave array for (i=0; i<((int)(size/clk[clkCnt])-1); ++i){ @@ -693,7 +675,7 @@ int DetectASKClock(uint8_t dest[], size_t size, int clock) for (iii=0; iii<7;++iii){ if (bestErr[iii]peak){ + for (i=0; i < loopCnt; ++i){ + if(dest[i] > peak){ peak = dest[i]; } - if(dest[i]=peak) || (dest[ii]<=low)){ + for (ii=0; ii< loopCnt; ++ii){ + if ((dest[ii] >= peak) || (dest[ii] <= low)){ errCnt=0; peakcnt=0; // now that we have the first one lined up test rest of wave array - for (i=0; i<((int)(size/clk[clkCnt])-1); ++i){ + for (i=0; i < ((int)(size/clk[clkCnt])-1); ++i){ if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){ peakcnt++; }else if(dest[ii+(i*clk[clkCnt])-tol]>=peak || dest[ii+(i*clk[clkCnt])-tol]<=low){ @@ -771,13 +753,13 @@ int DetectpskNRZClock(uint8_t dest[], size_t size, int clock) //int ratio2; //debug int ratio; //int bits; - for (iii=0; iii<7;++iii){ + for (iii=0; iii < 7; ++iii){ ratio=1000; //ratio2=1000; //debug //bits=size/clk[iii]; //debug - if (peaksdet[iii]>0){ + if (peaksdet[iii] > 0){ ratio=bestErr[iii]/peaksdet[iii]; - if (((bestErr[best]/peaksdet[best])>(ratio)+1)){ + if (((bestErr[best]/peaksdet[best]) > (ratio)+1)){ best = iii; } //ratio2=bits/peaksdet[iii]; //debug @@ -797,31 +779,31 @@ void pskCleanWave(uint8_t *bitStream, size_t size) // int loopMax = 2048; int newLow=0; int newHigh=0; - for (i=0; ihigh) high=bitStream[i]; + for (i=0; i < size; ++i){ + if (bitStream[i] < low) low=bitStream[i]; + if (bitStream[i] > high) high=bitStream[i]; } high = (int)(((high-128)*.80)+128); low = (int)(((low-128)*.90)+128); //low = (uint8_t)(((int)(low)-128)*.80)+128; - for (i=0; i=high) newHigh=1; + if (bitStream[i] <= low) newLow=1; + if (bitStream[i] >= high) newHigh=1; } return; } @@ -905,9 +887,9 @@ int pskNRZrawDemod(uint8_t *dest, size_t *size, int *clk, int *invert) uint32_t gLen = *size; if (gLen > 1280) gLen=1280; // get high - for (i=0; ihigh) high = dest[i]; - if (dest[i] high) high = dest[i]; + if (dest[i] < low) low = dest[i]; } //fudge high/low bars by 25% high = (uint8_t)((((int)(high)-128)*.75)+128); @@ -930,7 +912,7 @@ int pskNRZrawDemod(uint8_t *dest, size_t *size, int *clk, int *invert) //PrintAndLog("DEBUG - lastbit - %d",lastBit); //loop to find first wave that works - align to clock for (iii=0; iii < gLen; ++iii){ - if ((dest[iii]>=high)||(dest[iii]<=low)){ + if ((dest[iii]>=high) || (dest[iii]<=low)){ lastBit=iii-*clk; //loop through to see if this start location works for (i = iii; i < *size; ++i) { @@ -947,12 +929,12 @@ int pskNRZrawDemod(uint8_t *dest, size_t *size, int *clk, int *invert) ignorewin=*clk/8; bitnum++; //else if no bars found - }else if(dest[i]low) { + }else if(dest[i] < high && dest[i] > low) { if (ignorewin==0){ bitHigh=0; }else ignorewin--; //if we are past a clock point - if (i>=lastBit+*clk+tol){ //clock val + if (i >= lastBit+*clk+tol){ //clock val lastBit+=*clk; bitnum++; } @@ -964,29 +946,29 @@ int pskNRZrawDemod(uint8_t *dest, size_t *size, int *clk, int *invert) if (bitnum>=1000) break; } //we got more than 64 good bits and not all errors - if ((bitnum > (64+errCnt)) && (errCnt<(maxErr))) { + if ((bitnum > (64+errCnt)) && (errCnt < (maxErr))) { //possible good read - if (errCnt==0){ + if (errCnt == 0){ bestStart = iii; - bestErrCnt=errCnt; + bestErrCnt = errCnt; break; //great read - finish } if (bestStart == iii) break; //if current run == bestErrCnt run (after exhausted testing) then finish - if (errCnt=high ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ + if ((dest[i] >= high ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){ bitHigh=1; lastBit+=*clk; curBit=1-*invert;