X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/edaf10af99156022f7719c6853812005579c8726..ef9b8b2c2b55254a70127e3730fd8e964c5b8521:/client/cmddata.c diff --git a/client/cmddata.c b/client/cmddata.c index f4b596aa..ab89bb30 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -58,11 +58,12 @@ int CmdSetDebugMode(const char *Cmd) } int usage_data_printdemodbuf(){ - PrintAndLog("Usage: data printdemodbuffer x o "); + PrintAndLog("Usage: data printdemodbuffer x o l "); PrintAndLog("Options:"); PrintAndLog(" h This help"); PrintAndLog(" x output in hex (omit for binary output)"); PrintAndLog(" o enter offset in # of bits"); + PrintAndLog(" l enter length to print in # of bits or hex characters respectively"); return 0; } @@ -87,7 +88,8 @@ int CmdPrintDemodBuff(const char *Cmd) char hex[512]={0x00}; bool hexMode = false; bool errors = false; - uint8_t offset = 0; + uint32_t offset = 0; //could be size_t but no param_get16... + uint32_t length = 512; char cmdp = 0; while(param_getchar(Cmd, cmdp) != 0x00) { @@ -103,10 +105,16 @@ int CmdPrintDemodBuff(const char *Cmd) break; case 'o': case 'O': - offset = param_get8(Cmd, cmdp+1); + offset = param_get32ex(Cmd, cmdp+1, 0, 10); if (!offset) errors = true; cmdp += 2; break; + case 'l': + case 'L': + length = param_get32ex(Cmd, cmdp+1, 512, 10); + if (!length) errors = true; + cmdp += 2; + break; default: PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = true; @@ -116,18 +124,17 @@ int CmdPrintDemodBuff(const char *Cmd) } //Validations if(errors) return usage_data_printdemodbuf(); - - int numBits = (DemodBufferLen-offset) & 0x7FC; //make sure we don't exceed our string + length = (length > (DemodBufferLen-offset)) ? DemodBufferLen-offset : length; + int numBits = (length) & 0x00FFC; //make sure we don't exceed our string if (hexMode){ char *buf = (char *) (DemodBuffer + offset); + numBits = (numBits > sizeof(hex)) ? sizeof(hex) : numBits; numBits = binarraytohex(hex, buf, numBits); if (numBits==0) return 0; PrintAndLog("DemodBuffer: %s",hex); } else { - //setDemodBuf(DemodBuffer, DemodBufferLen-offset, offset); - char *bin = sprint_bin_break(DemodBuffer+offset,numBits,16); - PrintAndLog("DemodBuffer:\n%s",bin); + PrintAndLog("DemodBuffer:\n%s", sprint_bin_break(DemodBuffer+offset,numBits,16)); } return 1; } @@ -315,7 +322,7 @@ int ASKDemod(const char *Cmd, bool verbose, bool emSearch, uint8_t askType) char amp = param_getchar(Cmd, 0); uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; sscanf(Cmd, "%i %i %i %i %c", &clk, &invert, &maxErr, &maxLen, &); - if (!maxLen) maxLen = 512*64; + if (!maxLen) maxLen = BIGBUF_SIZE; if (invert != 0 && invert != 1) { PrintAndLog("Invalid argument: %s", Cmd); return 0; @@ -637,6 +644,32 @@ int CmdG_Prox_II_Demod(const char *Cmd) return 1; } +//by marshmellow +//see ASKDemod for what args are accepted +int CmdVikingDemod(const char *Cmd) +{ + if (!ASKDemod(Cmd, false, false, 1)) { + if (g_debugMode) PrintAndLog("ASKDemod failed"); + return 0; + } + size_t size = DemodBufferLen; + //call lfdemod.c demod for Viking + int ans = VikingDemod_AM(DemodBuffer, &size); + if (ans < 0) { + if (g_debugMode) PrintAndLog("Error Viking_Demod %d", ans); + return 0; + } + //got a good demod + uint32_t raw1 = bytebits_to_byte(DemodBuffer+ans, 32); + uint32_t raw2 = bytebits_to_byte(DemodBuffer+ans+32, 32); + uint32_t cardid = bytebits_to_byte(DemodBuffer+ans+24, 32); + uint8_t checksum = bytebits_to_byte(DemodBuffer+ans+32+24, 8); + PrintAndLog("Viking Tag Found: Card ID %08X, Checksum: %02X", cardid, checksum); + PrintAndLog("Raw: %08X%08X", raw1,raw2); + setDemodBuf(DemodBuffer+ans, 64, 0); + return 1; +} + //by marshmellow - see ASKDemod int Cmdaskrawdemod(const char *Cmd) { @@ -794,19 +827,20 @@ int CmdUndec(const char *Cmd) return 0; } - uint8_t factor = param_get8ex(Cmd, 0,2, 10); + uint8_t factor = param_get8ex(Cmd, 0, 2, 10); //We have memory, don't we? int swap[MAX_GRAPH_TRACE_LEN] = { 0 }; uint32_t g_index = 0 ,s_index = 0; - while(g_index < GraphTraceLen && s_index < MAX_GRAPH_TRACE_LEN) + while(g_index < GraphTraceLen && s_index + factor < MAX_GRAPH_TRACE_LEN) { int count = 0; - for(count = 0; count < factor && s_index+count < MAX_GRAPH_TRACE_LEN; count ++) + for (count = 0; count < factor && s_index + count < MAX_GRAPH_TRACE_LEN; count++) swap[s_index+count] = GraphBuffer[g_index]; - s_index+=count; + s_index += count; + g_index++; } - memcpy(GraphBuffer,swap, s_index * sizeof(int)); + memcpy(GraphBuffer, swap, s_index * sizeof(int)); GraphTraceLen = s_index; RepaintGraphWindow(); return 0; @@ -910,15 +944,14 @@ char *GetFSKType(uint8_t fchigh, uint8_t fclow, uint8_t invert) int FSKrawDemod(const char *Cmd, bool verbose) { //raw fsk demod no manchester decoding no start bit finding just get binary from wave - //set defaults - int rfLen = 0; - int invert = 0; - int fchigh = 0; - int fclow = 0; + uint8_t rfLen, invert, fchigh, fclow; + //set defaults //set options from parameters entered with the command - sscanf(Cmd, "%i %i %i %i", &rfLen, &invert, &fchigh, &fclow); - + rfLen = param_get8(Cmd, 0); + invert = param_get8(Cmd, 1); + fchigh = param_get8(Cmd, 2); + fclow = param_get8(Cmd, 3); if (strlen(Cmd)>0 && strlen(Cmd)<=2) { if (rfLen==1){ invert = 1; //if invert option only is used @@ -930,35 +963,35 @@ int FSKrawDemod(const char *Cmd, bool verbose) size_t BitLen = getFromGraphBuf(BitStream); if (BitLen==0) return 0; //get field clock lengths - uint16_t fcs=0; - if (fchigh==0 || fclow == 0){ - fcs = countFC(BitStream, BitLen, 1); - if (fcs==0){ - fchigh=10; - fclow=8; - }else{ - fchigh = (fcs >> 8) & 0xFF; - fclow = fcs & 0xFF; + uint8_t fc1=0, fc2=0, rf1=0; + if (!fchigh || !fclow) { + uint8_t ans = fskClocks(&fc1, &fc2, &rf1, false); + if (ans == 0) { + if (g_debugMode) PrintAndLog("\nError: cannot detect valid fsk field clocks"); + return 0; // can't detect field clock } + fchigh = fc1; + fclow = fc2; + if (rfLen == 0) rfLen = rf1; } //get bit clock length - if (rfLen==0){ + if (!rfLen){ rfLen = detectFSKClk(BitStream, BitLen, fchigh, fclow); - if (rfLen == 0) rfLen = 50; + if (!rfLen) rfLen = 50; } - int size = fskdemod(BitStream,BitLen,(uint8_t)rfLen,(uint8_t)invert,(uint8_t)fchigh,(uint8_t)fclow); - if (size>0){ - setDemodBuf(BitStream,size,0); + int size = fskdemod(BitStream, BitLen, rfLen, invert, fchigh, fclow); + if (size > 0){ + setDemodBuf(BitStream, size, 0); // Now output the bitstream to the scrollback by line of 16 bits if (verbose || g_debugMode) { - PrintAndLog("\nUsing Clock:%d, invert:%d, fchigh:%d, fclow:%d", rfLen, invert, fchigh, fclow); - PrintAndLog("%s decoded bitstream:",GetFSKType(fchigh,fclow,invert)); + PrintAndLog("\nUsing Clock:%u, invert:%u, fchigh:%u, fclow:%u", rfLen, invert, fchigh, fclow); + PrintAndLog("%s decoded bitstream:", GetFSKType(fchigh, fclow, invert)); printDemodBuff(); } return 1; - } else{ + } else { if (g_debugMode) PrintAndLog("no FSK data found"); } return 0; @@ -1130,8 +1163,6 @@ int CmdFSKdemodParadox(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) { @@ -1220,7 +1251,6 @@ int CmdFSKdemodIO(const char *Cmd) //print full AWID Prox ID and some bit format details if found int CmdFSKdemodAWID(const char *Cmd) { - //raw fsk demod no manchester decoding no start bit finding just get binary from wave uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; size_t size = getFromGraphBuf(BitStream); if (size==0) return 0; @@ -1250,7 +1280,7 @@ int CmdFSKdemodAWID(const char *Cmd) // | | | | | | | // 01234567 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 - to 96 // ----------------------------------------------------------------------------- - // 00000001 000 1 110 1 101 1 011 1 1 d01 1 010 0 000 1 000 1 010 0 001 0 110 1 100 0 000 1 000 1 + // 00000001 000 1 110 1 101 1 011 1 101 1 010 0 000 1 000 1 010 0 001 0 110 1 100 0 000 1 000 1 // premable bbb o bbb o bbw o fff o fff o ffc o ccc o ccc o ccc o ccc o ccc o wxx o xxx o xxx o - to 96 // |---26 bit---| |-----117----||-------------142-------------| // b = format bit len, o = odd parity of last 3 bits @@ -1419,7 +1449,6 @@ int CmdFSKdemodPyramid(const char *Cmd) uint32_t fc = 0; uint32_t cardnum = 0; uint32_t code1 = 0; - //uint32_t code2 = 0; if (fmtLen==26){ fc = bytebits_to_byte(BitStream+73, 8); cardnum = bytebits_to_byte(BitStream+81, 16); @@ -1496,6 +1525,10 @@ int CmdFDXBdemodBI(const char *Cmd){ if (g_debugMode) PrintAndLog("Error FDXBDemod , no startmarker found :: %d",preambleIndex); return 0; } + if (size != 128) { + if (g_debugMode) PrintAndLog("Error incorrect data length found"); + return 0; + } setDemodBuf(BitStream, 128, preambleIndex); @@ -1565,6 +1598,9 @@ int PSKDemod(const char *Cmd, bool verbose) //invalid carrier return 0; } + if (g_debugMode){ + PrintAndLog("Carrier: rf/%d",carrier); + } int errCnt=0; errCnt = pskRawDemod(BitStream, &BitLen, &clk, &invert); if (errCnt > maxErr){ @@ -1604,61 +1640,33 @@ int CmdIndalaDecode(const char *Cmd) return 0; } uint8_t invert=0; - ans = indala26decode(DemodBuffer, &DemodBufferLen, &invert); - if (ans < 1) { + size_t size = DemodBufferLen; + size_t startIdx = indala26decode(DemodBuffer, &size, &invert); + if (startIdx < 1 || size > 224) { if (g_debugMode==1) PrintAndLog("Error2: %d",ans); return -1; } - char showbits[251]={0x00}; + setDemodBuf(DemodBuffer, size, startIdx); if (invert) if (g_debugMode==1) PrintAndLog("Had to invert bits"); + PrintAndLog("BitLen: %d",DemodBufferLen); //convert UID to HEX uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7; - int idx; - uid1=0; - uid2=0; - PrintAndLog("BitLen: %d",DemodBufferLen); + uid1=bytebits_to_byte(DemodBuffer,32); + uid2=bytebits_to_byte(DemodBuffer+32,32); 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); + PrintAndLog("Indala UID=%s (%x%08x)", sprint_bin_break(DemodBuffer,DemodBufferLen,16), uid1, uid2); + } else { + uid3=bytebits_to_byte(DemodBuffer+64,32); + uid4=bytebits_to_byte(DemodBuffer+96,32); + uid5=bytebits_to_byte(DemodBuffer+128,32); + uid6=bytebits_to_byte(DemodBuffer+160,32); + uid7=bytebits_to_byte(DemodBuffer+192,32); + PrintAndLog("Indala UID=%s (%x%08x%08x%08x%08x%08x%08x)", + sprint_bin_break(DemodBuffer,DemodBufferLen,16), uid1, uid2, uid3, uid4, uid5, uid6, uid7); } if (g_debugMode){ PrintAndLog("DEBUG: printing demodbuffer:"); @@ -1728,7 +1736,7 @@ int NRZrawDemod(const char *Cmd, bool verbose) size_t BitLen = getFromGraphBuf(BitStream); if (BitLen==0) return 0; int errCnt=0; - errCnt = nrzRawDemod(BitStream, &BitLen, &clk, &invert, maxErr); + errCnt = nrzRawDemod(BitStream, &BitLen, &clk, &invert); if (errCnt > maxErr){ if (g_debugMode) PrintAndLog("Too many errors found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); return 0; @@ -1878,54 +1886,6 @@ int CmdRawDemod(const char *Cmd) return ans; } -int AmVikingDecode(const uint8_t *id){ - // searching the buffer for the id - //uint8_t id_bits[32]; - // convert 4 bytes of id to 32 bits present in 32 bytes data; - //bytes_to_bits(id,4,id_bits,sizeof(id_bits)); - - //print_arraybinary(id_bits,sizeof(id_bits)); - PrintAndLog(" binary: %s", printBits(4, id) ); - - //size_t idx = 0; - size_t BitLen = DemodBufferLen; - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - memcpy(BitStream, DemodBuffer, BitLen); - - // if (VikingDecode(BitStream,BitLen,&idx,id_bits,sizeof(id_bits)) == 1) - // { - // setDemodBuf(BitStream,64, idx); - // PrintAndLog("Found Viking tag\n"); - // CmdPrintDemodBuff("x"); - // } - // else - // { - // PrintAndLog("Not found Viking tag\n"); - // } - return 0; -} -int AMVikingDemod(const uint8_t *id){ - // demod am clock 32 fail - if (!ASKDemod("32",g_debugMode,false,1)) - return 0; - // search for the card id from bitstream. - return AmVikingDecode(id); -} -//by Gusto -// takes 1 argument <8 bytes of Hex number on the card -// print binary found and saves in grapbuffer for further commands -int CmdAMVikingDemod(const char *Cmd){ - uint8_t id[4]; - if (param_gethex(Cmd,0,id,8) == 1) - { - PrintAndLog("Usage: data vikingdemod CardID 8 bytes of hex number"); - return 0; - } - PrintAndLog("Card ID : %02X%02X%02X%02X\n",id[0],id[1],id[2],id[3]); - // try to demod AMViking - return AMVikingDemod(id); -} - int CmdGrid(const char *Cmd) { sscanf(Cmd, "%i %i", &PlotGridX, &PlotGridY); @@ -2029,25 +1989,25 @@ int getSamples(const char *Cmd, bool silent) int n = strtol(Cmd, NULL, 0); - if (n == 0) - n = sizeof(got); - - if (n > sizeof(got)) + if ( n == 0 || n > sizeof(got)) n = sizeof(got); PrintAndLog("Reading %d bytes from device memory\n", n); GetFromBigBuf(got,n,0); PrintAndLog("Data fetched"); UsbCommand response; - WaitForResponse(CMD_ACK, &response); + if ( !WaitForResponseTimeout(CMD_ACK, &response, 10000) ) { + PrintAndLog("timeout while waiting for reply."); + return 1; + } + uint8_t bits_per_sample = 8; //Old devices without this feature would send 0 at arg[0] if(response.arg[0] > 0) { sample_config *sc = (sample_config *) response.d.asBytes; - PrintAndLog("Samples @ %d bits/smpl, decimation 1:%d ", sc->bits_per_sample - , sc->decimation); + PrintAndLog("Samples @ %d bits/smpl, decimation 1:%d ", sc->bits_per_sample, sc->decimation); bits_per_sample = sc->bits_per_sample; } if(bits_per_sample < 8) @@ -2083,11 +2043,11 @@ int CmdTuneSamples(const char *Cmd) int timeout = 0; printf("\nMeasuring antenna characteristics, please wait..."); - UsbCommand c = {CMD_MEASURE_ANTENNA_TUNING}; + UsbCommand c = {CMD_MEASURE_ANTENNA_TUNING, {0,0,0}}; + clearCommandBuffer(); SendCommand(&c); - UsbCommand resp; - while(!WaitForResponseTimeout(CMD_MEASURED_ANTENNA_TUNING,&resp,1000)) { + while(!WaitForResponseTimeout(CMD_MEASURED_ANTENNA_TUNING, &resp, 2000)) { timeout++; printf("."); if (timeout > 7) { @@ -2133,7 +2093,6 @@ int CmdTuneSamples(const char *Cmd) ShowGraphWindow(); RepaintGraphWindow(); } - return 0; } @@ -2149,7 +2108,7 @@ int CmdLoad(const char *Cmd) FILE *f = fopen(filename, "r"); if (!f) { - PrintAndLog("couldn't open '%s'", filename); + PrintAndLog("couldn't open '%s'", filename); return 0; } @@ -2168,11 +2127,13 @@ int CmdLoad(const char *Cmd) int CmdLtrim(const char *Cmd) { int ds = atoi(Cmd); - if (GraphTraceLen<=0) return 0; + + if (GraphTraceLen <= 0) return 0; + for (int i = ds; i < GraphTraceLen; ++i) GraphBuffer[i-ds] = GraphBuffer[i]; - GraphTraceLen -= ds; + GraphTraceLen -= ds; RepaintGraphWindow(); return 0; } @@ -2181,9 +2142,7 @@ int CmdLtrim(const char *Cmd) int CmdRtrim(const char *Cmd) { int ds = atoi(Cmd); - GraphTraceLen = ds; - RepaintGraphWindow(); return 0; } @@ -2367,21 +2326,15 @@ int Cmdbin2hex(const char *Cmd) } int usage_data_hex2bin(){ - - PrintAndLog("Usage: data bin2hex "); + PrintAndLog("Usage: data hex2bin "); PrintAndLog(" This function will ignore all non-hexadecimal characters (but stop reading on whitespace)"); return 0; - } int Cmdhex2bin(const char *Cmd) { int bg =0, en =0; - if(param_getptr(Cmd, &bg, &en, 0)) - { - return usage_data_hex2bin(); - } - + if(param_getptr(Cmd, &bg, &en, 0)) return usage_data_hex2bin(); while(bg <= en ) { @@ -2415,6 +2368,7 @@ static command_t CommandTable[] = {"askedgedetect", CmdAskEdgeDetect, 1, "[threshold] Adjust Graph for manual ask demod using the length of sample differences to detect the edge of a wave (use 20-45, def:25)"}, {"askem410xdemod", CmdAskEM410xDemod, 1, "[clock] [invert<0|1>] [maxErr] -- Demodulate an EM410x tag from GraphBuffer (args optional)"}, {"askgproxiidemod", CmdG_Prox_II_Demod, 1, "Demodulate a G Prox II tag from GraphBuffer"}, + {"askvikingdemod", CmdVikingDemod, 1, "Demodulate a Viking AM tag from GraphBuffer"}, {"autocorr", CmdAutoCorr, 1, "[window length] [g] -- Autocorrelation over window - g to save back to GraphBuffer (overwrite)"}, {"biphaserawdecode",CmdBiphaseDecodeRaw,1, "[offset] [invert<0|1>] [maxErr] -- Biphase decode bin stream in DemodBuffer (offset = 0|1 bits to shift the decode start)"}, {"bin2hex", Cmdbin2hex, 1, "bin2hex -- Converts binary to hexadecimal"}, @@ -2424,7 +2378,6 @@ static command_t CommandTable[] = {"detectclock", CmdDetectClockRate, 1, "[modulation] Detect clock rate of wave in GraphBuffer (options: 'a','f','n','p' for ask, fsk, nrz, psk respectively)"}, {"fdxbdemod", CmdFDXBdemodBI , 1, "Demodulate a FDX-B ISO11784/85 Biphase tag from GraphBuffer"}, {"fskawiddemod", CmdFSKdemodAWID, 1, "Demodulate an AWID FSK tag from GraphBuffer"}, - {"vikingdemod", CmdAMVikingDemod, 1, "Demodulate a Viking AM tag from GraphBuffer"}, //{"fskfcdetect", CmdFSKfcDetect, 1, "Try to detect the Field Clock of an FSK wave"}, {"fskhiddemod", CmdFSKdemodHID, 1, "Demodulate a HID FSK tag from GraphBuffer"}, {"fskiodemod", CmdFSKdemodIO, 1, "Demodulate an IO Prox FSK tag from GraphBuffer"}, @@ -2442,14 +2395,14 @@ static command_t CommandTable[] = {"manrawdecode", Cmdmandecoderaw, 1, "[invert] [maxErr] -- Manchester decode binary stream in DemodBuffer"}, {"norm", CmdNorm, 1, "Normalize max/min to +/-128"}, {"plot", CmdPlot, 1, "Show graph window (hit 'h' in window for keystroke help)"}, - {"printdemodbuffer",CmdPrintDemodBuff, 1, "[x] [o] -- print the data in the DemodBuffer - 'x' for hex output"}, + {"printdemodbuffer",CmdPrintDemodBuff, 1, "[x] [o] [l] -- print the data in the DemodBuffer - 'x' for hex output"}, {"pskindalademod", CmdIndalaDecode, 1, "[clock] [invert<0|1>] -- Demodulate an indala tag (PSK1) from GraphBuffer (args optional)"}, {"psknexwatchdemod",CmdPSKNexWatch, 1, "Demodulate a NexWatch tag (nexkey, quadrakey) (PSK1) from GraphBuffer"}, {"rawdemod", CmdRawDemod, 1, "[modulation] ... -see help (h option) -- Demodulate the data in the GraphBuffer and output binary"}, {"samples", CmdSamples, 0, "[512 - 40000] -- Get raw samples for graph window (GraphBuffer)"}, {"save", CmdSave, 1, " -- Save trace (from graph window)"}, {"scale", CmdScale, 1, " -- Set cursor display scale"}, - {"setdebugmode", CmdSetDebugMode, 1, "<0|1> -- Turn on or off Debugging Mode for demods"}, + {"setdebugmode", CmdSetDebugMode, 1, "<0|1|2> -- Turn on or off Debugging Level for lf demods"}, {"shiftgraphzero", CmdGraphShiftZero, 1, " -- Shift 0 for Graphed wave + or - shift value"}, {"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"},