+//biphase decode
+//take 01 or 10 = 0 and 11 or 00 = 1
+//takes 2 arguments "offset" default = 0 if 1 it will shift the decode by one bit
+// and "invert" default = 0 if 1 it will invert output
+// the argument offset allows us to manually shift if the output is incorrect - [EDIT: now auto detects]
+int CmdBiphaseDecodeRaw(const char *Cmd)
+{
+ size_t size=0;
+ int offset=0, invert=0, maxErr=20, errCnt=0;
+ char cmdp = param_getchar(Cmd, 0);
+ if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') {
+ PrintAndLog("Usage: data biphaserawdecode [offset] [invert] [maxErr]");
+ PrintAndLog(" Converts 10 or 01 to 1 and 11 or 00 to 0");
+ PrintAndLog(" --must have binary sequence in demodbuffer (run data askrawdemod first)");
+ PrintAndLog(" --invert for Conditional Dephase Encoding (CDP) AKA Differential Manchester");
+ PrintAndLog("");
+ PrintAndLog(" [offset <0|1>], set to 0 not to adjust start position or to 1 to adjust decode start position");
+ PrintAndLog(" [invert <0|1>], set to 1 to invert output");
+ PrintAndLog(" [maxErr int], set max errors tolerated - default=20");
+ PrintAndLog("");
+ PrintAndLog(" sample: data biphaserawdecode = decode biphase bitstream from the demodbuffer");
+ PrintAndLog(" sample: data biphaserawdecode 1 1 = decode biphase bitstream from the demodbuffer, set offset, and invert output");
+ return 0;
+ }
+ sscanf(Cmd, "%i %i %i", &offset, &invert, &maxErr);
+ if (DemodBufferLen==0) {
+ PrintAndLog("DemodBuffer Empty - run 'data rawdemod ar' first");
+ return 0;
+ }
+ uint8_t BitStream[MAX_DEMOD_BUF_LEN]={0};
+ size = sizeof(BitStream);
+ if ( !getDemodBuf(BitStream, &size) ) return 0;
+ errCnt=BiphaseRawDecode(BitStream, &size, &offset, invert);
+ if (errCnt<0){
+ PrintAndLog("Error during decode:%d", errCnt);
+ return 0;
+ }
+ if (errCnt>maxErr){
+ PrintAndLog("Too many errors attempting to decode: %d",errCnt);
+ return 0;
+ }
+
+ if (errCnt>0){
+ PrintAndLog("# Errors found during Demod (shown as 7 in bit stream): %d",errCnt);
+ }
+
+ PrintAndLog("Biphase Decoded using offset: %d - # invert:%d - data:",offset,invert);
+ PrintAndLog("%s", sprint_bin_break(BitStream, size, 16));
+
+ if (offset) setDemodBuf(DemodBuffer,DemodBufferLen-offset, offset); //remove first bit from raw demod
+ setClockGrid(g_DemodClock, g_DemodStartIdx + g_DemodClock*offset/2);
+ return 1;
+}
+
+//by marshmellow
+// - ASK Demod then Biphase decode GraphBuffer samples
+int ASKbiphaseDemod(const char *Cmd, bool verbose)
+{
+ //ask raw demod GraphBuffer first
+ int offset=0, clk=0, invert=0, maxErr=0;
+ sscanf(Cmd, "%i %i %i %i", &offset, &clk, &invert, &maxErr);
+
+ uint8_t BitStream[MAX_GRAPH_TRACE_LEN];
+ size_t size = getFromGraphBuf(BitStream);
+ int startIdx = 0;
+ //invert here inverts the ask raw demoded bits which has no effect on the demod, but we need the pointer
+ int errCnt = askdemod_ext(BitStream, &size, &clk, &invert, maxErr, 0, 0, &startIdx);
+ if ( errCnt < 0 || errCnt > maxErr ) {
+ if (g_debugMode) PrintAndLog("DEBUG: no data or error found %d, clock: %d", errCnt, clk);
+ return 0;
+ }
+
+ //attempt to Biphase decode BitStream
+ errCnt = BiphaseRawDecode(BitStream, &size, &offset, invert);
+ if (errCnt < 0){
+ if (g_debugMode || verbose) PrintAndLog("Error BiphaseRawDecode: %d", errCnt);
+ return 0;
+ }
+ if (errCnt > maxErr) {
+ if (g_debugMode || verbose) PrintAndLog("Error BiphaseRawDecode too many errors: %d", errCnt);
+ return 0;
+ }
+ //success set DemodBuffer and return
+ setDemodBuf(BitStream, size, 0);
+ setClockGrid(clk, startIdx + clk*offset/2);
+ if (g_debugMode || verbose){
+ PrintAndLog("Biphase Decoded using offset: %d - clock: %d - # errors:%d - data:",offset,clk,errCnt);
+ printDemodBuff();
+ }
+ return 1;
+}
+//by marshmellow - see ASKbiphaseDemod
+int Cmdaskbiphdemod(const char *Cmd)
+{
+ char cmdp = param_getchar(Cmd, 0);
+ if (strlen(Cmd) > 25 || cmdp == 'h' || cmdp == 'H') {
+ PrintAndLog("Usage: data rawdemod ab [offset] [clock] <invert> [maxError] [maxLen] <amplify>");
+ PrintAndLog(" [offset], offset to begin biphase, default=0");
+ PrintAndLog(" [set clock as integer] optional, if not set, autodetect");
+ PrintAndLog(" <invert>, 1 to invert output");
+ PrintAndLog(" [set maximum allowed errors], default = 100");
+ PrintAndLog(" [set maximum Samples to read], default = 32768 (512 bits at rf/64)");
+ PrintAndLog(" <amplify>, 'a' to attempt demod with ask amplification, default = no amp");
+ PrintAndLog(" NOTE: <invert> can be entered as second or third argument");
+ PrintAndLog(" NOTE: <amplify> can be entered as first, second or last argument");
+ PrintAndLog(" NOTE: any other arg must have previous args set to work");
+ PrintAndLog("");
+ PrintAndLog(" NOTE: --invert for Conditional Dephase Encoding (CDP) AKA Differential Manchester");
+ PrintAndLog("");
+ PrintAndLog(" sample: data rawdemod ab = demod an ask/biph tag from GraphBuffer");
+ PrintAndLog(" : data rawdemod ab 0 a = demod an ask/biph tag from GraphBuffer, amplified");
+ PrintAndLog(" : data rawdemod ab 1 32 = demod an ask/biph tag from GraphBuffer using an offset of 1 and a clock of RF/32");
+ PrintAndLog(" : data rawdemod ab 0 32 1 = demod an ask/biph tag from GraphBuffer using a clock of RF/32 and inverting data");
+ PrintAndLog(" : data rawdemod ab 0 1 = demod an ask/biph tag from GraphBuffer while inverting data");
+ PrintAndLog(" : data rawdemod ab 0 64 1 0 = demod an ask/biph tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors");
+ PrintAndLog(" : data rawdemod ab 0 64 1 0 0 a = demod an ask/biph tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors, and amp");
+ return 0;
+ }
+ return ASKbiphaseDemod(Cmd, true);
+}
+
+//by marshmellow - see ASKDemod