+//by marshmellow
+//attempt to detect the field clock and bit clock for FSK
+int CmdFSKfcDetect(const char *Cmd)
+{
+ uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
+ size_t size = getFromGraphBuf(BitStream);
+ if (size==0) return 0;
+ uint8_t dummy = 0;
+ uint16_t ans = countFC(BitStream, size, &dummy);
+ if (ans==0) {
+ if (g_debugMode) PrintAndLog("DEBUG: No data found");
+ return 0;
+ }
+ uint8_t fc1, fc2;
+ fc1 = (ans >> 8) & 0xFF;
+ fc2 = ans & 0xFF;
+
+ uint8_t rf1 = detectFSKClk(BitStream, size, fc1, fc2);
+ if (rf1==0) {
+ if (g_debugMode) PrintAndLog("DEBUG: Clock detect error");
+ return 0;
+ }
+ if ((fc1==10 && fc2==8) || (fc1==8 && fc2==5)){
+ PrintAndLog("Detected Field Clocks: FC/%d, FC/%d - Bit Clock: RF/%d", fc1, fc2, rf1);
+ return 1;
+ }
+ if (g_debugMode){
+ PrintAndLog("DEBUG: unknown fsk field clock detected");
+ PrintAndLog("Detected Field Clocks: FC/%d, FC/%d - Bit Clock: RF/%d", fc1, fc2, rf1);
+ }
+ return 0;
+}
+
+//by marshmellow
+//attempt to detect the bit clock for PSK modulations
+int CmdDetectPSKClockRate(const char *Cmd)
+{
+ GetPskClock("",0,0);
+ return 0;
+}
+
+//by marshmellow
+//attempt to detect the bit clock for NRZ modulations
+int CmdDetectNRZClockRate(const char *Cmd)
+{
+ GetNrzClock("",0,0);
+ return 0;
+}
+
+//by marshmellow
+//attempt to psk1 demod graph buffer
+int PSKDemod(const char *Cmd, uint8_t verbose)
+{
+ int invert=0;
+ int clk=0;
+ int maxErr=100;
+ sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr);
+ if (clk==1){
+ invert=1;
+ clk=0;
+ }
+ 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);
+ if (BitLen==0) return 0;
+ int errCnt=0;
+ errCnt = pskRawDemod(BitStream, &BitLen,&clk,&invert);
+ if (errCnt > maxErr){
+ if (g_debugMode==1) PrintAndLog("Too many errors found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt);
+ return -1;
+ }
+ if (errCnt<0|| BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first)
+ if (g_debugMode==1) PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt);
+ return -1;
+ }
+ if (verbose) PrintAndLog("Tried PSK Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen);
+ //prime demod buffer for output
+ setDemodBuf(BitStream,BitLen,0);
+ return errCnt;
+}
+
+
+// Indala 26 bit decode
+// by marshmellow
+// optional arguments - same as CmdpskNRZrawDemod (clock & invert)
+int CmdIndalaDecode(const char *Cmd)
+{
+ int ans;
+ if (strlen(Cmd)>0){
+ ans = PSKDemod(Cmd, 0);
+ } else{ //default to RF/32
+ ans = PSKDemod("32", 0);
+ }
+
+ if (ans < 0){
+ if (g_debugMode==1)
+ PrintAndLog("Error1: %d",ans);
+ return 0;
+ }
+ uint8_t invert=0;
+ ans = indala26decode(DemodBuffer,(size_t *) &DemodBufferLen, &invert);
+ if (ans < 1) {
+ if (g_debugMode==1)
+ PrintAndLog("Error2: %d",ans);
+ return -1;
+ }
+ char showbits[251]={0x00};
+ if (invert)
+ if (g_debugMode==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<DemodBufferLen; 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 (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);
+ }
+ if (g_debugMode){
+ PrintAndLog("DEBUG: printing demodbuffer:");
+ printDemodBuff();
+ }
+ return 1;
+}
+
+/*
+//by marshmellow
+//attempt to clean psk wave noise after a peak
+//NOTE RELIES ON PEAKS :(
+int CmdPskClean(const char *Cmd)
+{
+ uint8_t bitStream[MAX_GRAPH_TRACE_LEN]={0};
+ size_t bitLen = getFromGraphBuf(bitStream);
+ pskCleanWave(bitStream, bitLen);
+ setGraphBuf(bitStream, bitLen);
+ return 0;
+}
+*/
+
+// by marshmellow
+// takes 3 arguments - clock, invert, maxErr as integers
+// attempts to demodulate nrz only
+// prints binary found and saves in demodbuffer for further commands
+int CmdNRZrawDemod(const char *Cmd)
+{
+ int invert=0;
+ int clk=0;
+ int maxErr=100;
+ char cmdp = param_getchar(Cmd, 0);
+ if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') {
+ PrintAndLog("Usage: data nrzrawdemod [clock] <0|1> [maxError]");
+ PrintAndLog(" [set clock as integer] optional, if not set, autodetect.");
+ PrintAndLog(" <invert>, 1 for invert output");
+ PrintAndLog(" [set maximum allowed errors], default = 100.");
+ PrintAndLog("");
+ PrintAndLog(" sample: data nrzrawdemod = demod a nrz/direct tag from GraphBuffer");
+ PrintAndLog(" : data nrzrawdemod 32 = demod a nrz/direct tag from GraphBuffer using a clock of RF/32");
+ PrintAndLog(" : data nrzrawdemod 32 1 = demod a nrz/direct tag from GraphBuffer using a clock of RF/32 and inverting data");
+ PrintAndLog(" : data nrzrawdemod 1 = demod a nrz/direct tag from GraphBuffer while inverting data");
+ PrintAndLog(" : data nrzrawdemod 64 1 0 = demod a nrz/direct tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors");
+
+ return 0;
+ }
+
+ sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr);
+ if (clk==1){
+ invert=1;
+ clk=0;
+ }
+ if (invert != 0 && invert != 1) {
+ PrintAndLog("Invalid argument: %s", Cmd);
+ return 0;
+ }
+ uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
+ size_t BitLen = getFromGraphBuf(BitStream);
+ if (BitLen==0) return 0;
+ int errCnt=0;
+ errCnt = nrzRawDemod(BitStream, &BitLen, &clk, &invert, maxErr);
+ if (errCnt > maxErr){
+ if (g_debugMode==1) PrintAndLog("Too many errors found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt);
+ return 0;
+ }
+ if (errCnt<0|| BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first)
+ if (g_debugMode==1) PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt);
+ return 0;
+ }
+ PrintAndLog("Tried NRZ Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen);
+ //prime demod buffer for output
+ setDemodBuf(BitStream,BitLen,0);
+
+ if (errCnt>0){
+ PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
+ }else{
+ }
+ PrintAndLog("NRZ demoded bitstream:");
+ // Now output the bitstream to the scrollback by line of 16 bits
+ printDemodBuff();
+ return 1;
+}
+
+// by marshmellow
+// takes 3 arguments - clock, invert, maxErr as integers
+// attempts to demodulate psk only
+// prints binary found and saves in demodbuffer for further commands
+int CmdPSK1rawDemod(const char *Cmd)
+{
+ int errCnt;
+ char cmdp = param_getchar(Cmd, 0);
+ if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') {
+ PrintAndLog("Usage: data psk1rawdemod [clock] <0|1> [maxError]");
+ PrintAndLog(" [set clock as integer] optional, if not set, autodetect.");
+ PrintAndLog(" <invert>, 1 for invert output");
+ PrintAndLog(" [set maximum allowed errors], default = 100.");
+ PrintAndLog("");
+ PrintAndLog(" sample: data psk1rawdemod = demod a psk1 tag from GraphBuffer");
+ PrintAndLog(" : data psk1rawdemod 32 = demod a psk1 tag from GraphBuffer using a clock of RF/32");
+ PrintAndLog(" : data psk1rawdemod 32 1 = demod a psk1 tag from GraphBuffer using a clock of RF/32 and inverting data");
+ PrintAndLog(" : data psk1rawdemod 1 = demod a psk1 tag from GraphBuffer while inverting data");
+ PrintAndLog(" : data psk1rawdemod 64 1 0 = demod a psk1 tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors");
+ return 0;
+ }
+ errCnt = PSKDemod(Cmd, 1);
+ //output
+ if (errCnt<0){
+ if (g_debugMode) PrintAndLog("Error demoding: %d",errCnt);
+ return 0;
+ }
+ if (errCnt>0){
+ PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
+ }else{
+ }
+ PrintAndLog("PSK demoded bitstream:");
+ // Now output the bitstream to the scrollback by line of 16 bits
+ printDemodBuff();
+ return 1;
+}
+
+// by marshmellow
+// takes same args as cmdpsknrzrawdemod
+int CmdPSK2rawDemod(const char *Cmd)
+{
+ int errCnt=0;
+ char cmdp = param_getchar(Cmd, 0);
+ if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') {
+ PrintAndLog("Usage: data psk2rawdemod [clock] <0|1> [maxError]");
+ PrintAndLog(" [set clock as integer] optional, if not set, autodetect.");
+ PrintAndLog(" <invert>, 1 for invert output");
+ PrintAndLog(" [set maximum allowed errors], default = 100.");
+ PrintAndLog("");
+ PrintAndLog(" sample: data psk2rawdemod = demod a psk2 tag from GraphBuffer, autodetect clock");
+ PrintAndLog(" : data psk2rawdemod 32 = demod a psk2 tag from GraphBuffer using a clock of RF/32");
+ PrintAndLog(" : data psk2rawdemod 32 1 = demod a psk2 tag from GraphBuffer using a clock of RF/32 and inverting output");
+ PrintAndLog(" : data psk2rawdemod 1 = demod a psk2 tag from GraphBuffer, autodetect clock and invert output");
+ PrintAndLog(" : data psk2rawdemod 64 1 0 = demod a psk2 tag from GraphBuffer using a clock of RF/64, inverting output and allowing 0 demod errors");
+ return 0;
+ }
+ errCnt=PSKDemod(Cmd, 1);
+ if (errCnt<0){
+ if (g_debugMode) PrintAndLog("Error demoding: %d",errCnt);
+ return 0;
+ }
+ psk1TOpsk2(DemodBuffer, DemodBufferLen);
+ if (errCnt>0){
+ if (g_debugMode){
+ PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
+ PrintAndLog("PSK2 demoded bitstream:");
+ // Now output the bitstream to the scrollback by line of 16 bits
+ printDemodBuff();
+ }
+ }else{
+ PrintAndLog("PSK2 demoded bitstream:");
+ // Now output the bitstream to the scrollback by line of 16 bits
+ printDemodBuff();
+ }
+ return 1;
+}
+