+void printBitStream(int BitStream[], uint32_t bitLen){
+ uint32_t i = 0;
+ if (bitLen<16) 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;
+}
+void printBitStream2(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;
+}
+
+//by marshmellow
+//takes 1s and 0s and searches for EM410x format - output EM ID
+int Em410xDecode(const char *Cmd)
+{
+ //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=0;
+ uint64_t lo=0; //hi=0,
+
+ uint32_t i = 0;
+ uint32_t initLoopMax = 1000;
+ if (initLoopMax>GraphTraceLen) initLoopMax=GraphTraceLen;
+
+ for (;i < initLoopMax; ++i) //1000 samples should be plenty to find high and low values
+ {
+ if (GraphBuffer[i] > high)
+ high = GraphBuffer[i];
+ else if (GraphBuffer[i] < low)
+ low = GraphBuffer[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
+ int 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) < GraphTraceLen) {
+restart:
+ // search for a start of frame marker
+ if ( memcmp(GraphBuffer+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 += GraphBuffer[(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)|(GraphBuffer[(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,GraphBuffer[idx+ii+(i*5)-5],GraphBuffer[idx+ii+(i*5)-4],GraphBuffer[idx+ii+(i*5)-3],GraphBuffer[idx+ii+(i*5)-2],GraphBuffer[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,GraphBuffer[idx+ii+(i*5)-5],GraphBuffer[idx+ii+(i*5)-4],GraphBuffer[idx+ii+(i*5)-3],GraphBuffer[idx+ii+(i*5)-2],GraphBuffer[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.
+
+ //get Unique ID
+ uint64_t iii=1;
+ uint64_t id2lo=0; //id2hi=0,
+ //for (i=0;i<8;i++){ //for uint32 instead of uint64
+ // id2hi=(id2hi<<1)|((hi & (iii<<(i)))>>i);
+ //}
+ for (ii=5; ii>0;ii--){
+ for (i=0;i<8;i++){
+ id2lo=(id2lo<<1LL)|((lo & (iii<<(i+((ii-1)*8))))>>(i+((ii-1)*8)));
+ }
+ }
+ //output em id
+ PrintAndLog("EM TAG ID : %010llx", lo);
+ PrintAndLog("Unique TAG ID: %010llx", id2lo); //id2hi,
+ PrintAndLog("DEZ 8 : %08lld",lo & 0xFFFFFF);
+ PrintAndLog("DEZ 10 : %010lld",lo & 0xFFFFFF);
+ PrintAndLog("DEZ 5.5 : %05lld.%05lld",(lo>>16LL) & 0xFFFF,(lo & 0xFFFF));
+ PrintAndLog("DEZ 3.5A : %03lld.%05lld",(lo>>32ll),(lo & 0xFFFF));
+ PrintAndLog("DEZ 14/IK2 : %014lld",lo);
+ PrintAndLog("DEZ 15/IK3 : %015lld",id2lo);
+ PrintAndLog("Other : %05lld_%03lld_%08lld",(lo&0xFFFF),((lo>>16LL) & 0xFF),(lo & 0xFFFFFF));
+ return 0;
+ }else{
+ idx++;
+ }
+ }
+ return 0;
+}
+
+
+//by marshmellow
+//takes 2 arguments - clock and invert both as integers
+//prints binary found and saves in graphbuffer for further commands
+int Cmdaskmandemod(const char *Cmd)
+{
+ uint32_t i;
+ int invert=0; //invert default
+ int high = 0, low = 0;
+ int clk=DetectClock(0); //clock default
+ uint8_t BitStream[MAX_GRAPH_TRACE_LEN] = {0};
+
+ sscanf(Cmd, "%i %i", &clk, &invert);
+ if (clk<8) clk =64;
+ if (clk<32) clk=32;
+ if (invert != 0 && invert != 1) {
+ PrintAndLog("Invalid argument: %s", Cmd);
+ return 0;
+ }
+ uint32_t initLoopMax = 1000;
+ if (initLoopMax>GraphTraceLen) initLoopMax=GraphTraceLen;
+ // Detect high and lows
+ PrintAndLog("Using Clock: %d and invert=%d",clk,invert);
+ for (i = 0; i < initLoopMax; ++i) //1000 samples should be plenty to find high and low values
+ {
+ if (GraphBuffer[i] > high)
+ high = GraphBuffer[i];
+ else if (GraphBuffer[i] < low)
+ low = GraphBuffer[i];
+ }
+ if ((high < 30) && ((high !=1)||(low !=-1))){ //throw away static - allow 1 and -1 (in case of threshold command first)
+ PrintAndLog("no data found");
+ return 0;
+ }
+ //13% fuzz in case highs and lows aren't clipped [marshmellow]
+ high=(int)(0.75*high);
+ low=(int)(0.75*low);
+
+ //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 = GraphTraceLen;
+ if (gLen > 500) gLen=500;
+ uint8_t errCnt =0;
+ uint32_t bestStart = GraphTraceLen;
+ uint32_t bestErrCnt = (GraphTraceLen/1000);
+ //PrintAndLog("DEBUG - lastbit - %d",lastBit);
+ //loop to find first wave that works
+ for (iii=0; iii < gLen; ++iii){
+ if ((GraphBuffer[iii]>=high)||(GraphBuffer[iii]<=low)){
+ lastBit=iii-clk;
+ //loop through to see if this start location works
+ for (i = iii; i < GraphTraceLen; ++i) {
+ if ((GraphBuffer[i] >= high) && ((i-lastBit)>(clk-tol))){
+ lastBit+=clk;
+ BitStream[bitnum] = invert;
+ bitnum++;
+ } else if ((GraphBuffer[i] <= low) && ((i-lastBit)>(clk-tol))){
+ //low found and we are expecting a bar
+ lastBit+=clk;
+ BitStream[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){
+ BitStream[bitnum]=77;
+ bitnum++;
+ }
+
+
+ errCnt++;
+ lastBit+=clk;//skip over until hit too many errors
+ if (errCnt>((GraphTraceLen/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<(GraphTraceLen/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<bestErrCnt){ //set this as new best run
+ bestErrCnt=errCnt;
+ bestStart = iii;
+ }
+ }
+ }
+ 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 < (GraphTraceLen/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 GraphBuffer
+ ClearGraph(0);
+ for (i=0; i < bitnum; ++i){
+ GraphBuffer[i]=BitStream[i];
+ }
+ GraphTraceLen=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);
+ Em410xDecode(Cmd);
+ }
+ return 0;
+}
+