+//by marshmellow
+//shift graph zero up or down based on input + or -
+int CmdGraphShiftZero(const char *Cmd)
+{
+
+ int shift=0;
+ //set options from parameters entered with the command
+ sscanf(Cmd, "%i", &shift);
+ int shiftedVal=0;
+ for(int i = 0; i<GraphTraceLen; i++){
+ shiftedVal=GraphBuffer[i]+shift;
+ if (shiftedVal>127)
+ shiftedVal=127;
+ else if (shiftedVal<-127)
+ shiftedVal=-127;
+ GraphBuffer[i]= shiftedVal;
+ }
+ CmdNorm("");
+ return 0;
+}
+
+//by marshmellow
+//use large jumps in read samples to identify edges of waves and then amplify that wave to max
+//similar to dirtheshold, threshold, and askdemod commands
+//takes a threshold length which is the measured length between two samples then determines an edge
+int CmdAskEdgeDetect(const char *Cmd)
+{
+ int thresLen = 25;
+ sscanf(Cmd, "%i", &thresLen);
+ int shift = 127;
+ int shiftedVal=0;
+ for(int i = 1; i<GraphTraceLen; i++){
+ if (GraphBuffer[i]-GraphBuffer[i-1]>=thresLen) //large jump up
+ shift=127;
+ else if(GraphBuffer[i]-GraphBuffer[i-1]<=-1*thresLen) //large jump down
+ shift=-127;
+
+ shiftedVal=GraphBuffer[i]+shift;
+
+ if (shiftedVal>127)
+ shiftedVal=127;
+ else if (shiftedVal<-127)
+ shiftedVal=-127;
+ GraphBuffer[i-1] = shiftedVal;
+ }
+ RepaintGraphWindow();
+ //CmdNorm("");
+ return 0;
+}
+
+/* Print our clock rate */
+// uses data from graphbuffer
+// adjusted to take char parameter for type of modulation to find the clock - by marshmellow.
+int CmdDetectClockRate(const char *Cmd)
+{
+ char cmdp = param_getchar(Cmd, 0);
+ if (strlen(Cmd) > 3 || strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') {
+ PrintAndLog("Usage: data detectclock [modulation]");
+ PrintAndLog(" [modulation as char], specify the modulation type you want to detect the clock of");
+ PrintAndLog(" 'a' = ask, 'f' = fsk, 'n' = nrz/direct, 'p' = psk");
+ PrintAndLog("");
+ PrintAndLog(" sample: data detectclock a = detect the clock of an ask modulated wave in the GraphBuffer");
+ PrintAndLog(" data detectclock f = detect the clock of an fsk modulated wave in the GraphBuffer");
+ PrintAndLog(" data detectclock p = detect the clock of an psk modulated wave in the GraphBuffer");
+ PrintAndLog(" data detectclock n = detect the clock of an nrz/direct modulated wave in the GraphBuffer");
+ }
+ int ans=0;
+ if (cmdp == 'a'){
+ ans = GetAskClock("", true, false);
+ } else if (cmdp == 'f'){
+ ans = GetFskClock("", true, false);
+ } else if (cmdp == 'n'){
+ ans = GetNrzClock("", true, false);
+ } else if (cmdp == 'p'){
+ ans = GetPskClock("", true, false);
+ } else {
+ PrintAndLog ("Please specify a valid modulation to detect the clock of - see option h for help");
+ }
+ return ans;
+}
+
+//by marshmellow
+//fsk raw demod and print binary
+//takes 4 arguments - Clock, invert, fchigh, fclow
+//defaults: clock = 50, invert=1, fchigh=10, fclow=8 (RF/10 RF/8 (fsk2a))
+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;
+
+ //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) {
+ if (rfLen==1){
+ invert=1; //if invert option only is used
+ rfLen = 0;
+ }
+ }
+
+ uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
+ size_t BitLen = getFromGraphBuf(BitStream);
+ if (BitLen==0) return 0;
+ //get field clock lengths
+ uint16_t fcs=0;
+ uint8_t dummy=0;
+ if (fchigh==0 || fclow == 0){
+ fcs = countFC(BitStream, BitLen, &dummy);
+ if (fcs==0){
+ fchigh=10;
+ fclow=8;
+ }else{
+ fchigh = (fcs >> 8) & 0xFF;
+ fclow = fcs & 0xFF;
+ }
+ }
+ //get bit clock length
+ if (rfLen==0){
+ rfLen = detectFSKClk(BitStream, BitLen, fchigh, fclow);
+ if (rfLen == 0) rfLen = 50;
+ }
+ if (verbose) PrintAndLog("Args invert: %d - Clock:%d - fchigh:%d - fclow: %d",invert,rfLen,fchigh, fclow);
+ int size = fskdemod(BitStream,BitLen,(uint8_t)rfLen,(uint8_t)invert,(uint8_t)fchigh,(uint8_t)fclow);
+ if (size>0){
+ setDemodBuf(BitStream,size,0);
+
+ // 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
+ if (verbose) {
+ PrintAndLog("FSK decoded bitstream:");
+ printBitStream(BitStream,size);
+ }
+
+ return 1;
+ } else{
+ if (verbose) PrintAndLog("no FSK data found");
+ }
+ return 0;
+}
+
+//by marshmellow
+//fsk raw demod and print binary
+//takes 4 arguments - Clock, invert, fchigh, fclow
+//defaults: clock = 50, invert=1, fchigh=10, fclow=8 (RF/10 RF/8 (fsk2a))
+int CmdFSKrawdemod(const char *Cmd)
+{
+ char cmdp = param_getchar(Cmd, 0);
+ if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') {
+ PrintAndLog("Usage: data rawdemod fs [clock] <invert> [fchigh] [fclow]");
+ PrintAndLog(" [set clock as integer] optional, omit for autodetect.");
+ PrintAndLog(" <invert>, 1 for invert output, can be used even if the clock is omitted");
+ PrintAndLog(" [fchigh], larger field clock length, omit for autodetect");
+ PrintAndLog(" [fclow], small field clock length, omit for autodetect");
+ PrintAndLog("");
+ PrintAndLog(" sample: data rawdemod fs = demod an fsk tag from GraphBuffer using autodetect");
+ PrintAndLog(" : data rawdemod fs 32 = demod an fsk tag from GraphBuffer using a clock of RF/32, autodetect fc");
+ PrintAndLog(" : data rawdemod fs 1 = demod an fsk tag from GraphBuffer using autodetect, invert output");
+ PrintAndLog(" : data rawdemod fs 32 1 = demod an fsk tag from GraphBuffer using a clock of RF/32, invert output, autodetect fc");
+ PrintAndLog(" : data rawdemod fs 64 0 8 5 = demod an fsk1 RF/64 tag from GraphBuffer");
+ PrintAndLog(" : data rawdemod fs 50 0 10 8 = demod an fsk2 RF/50 tag from GraphBuffer");
+ PrintAndLog(" : data rawdemod fs 50 1 10 8 = demod an fsk2a RF/50 tag from GraphBuffer");
+ return 0;
+ }
+ return FSKrawDemod(Cmd, TRUE);
+}
+
+//by marshmellow (based on existing demod + holiman's refactor)
+//HID Prox demod - FSK RF/50 with preamble of 00011101 (then manchester encoded)
+//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;
+
+ uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
+ size_t BitLen = getFromGraphBuf(BitStream);
+ if (BitLen==0) return 0;
+ //get binary from fsk wave
+ int idx = HIDdemodFSK(BitStream,&BitLen,&hi2,&hi,&lo);
+ if (idx<0){
+ if (g_debugMode){
+ if (idx==-1){
+ PrintAndLog("DEBUG: Just Noise Detected");
+ } else if (idx == -2) {
+ PrintAndLog("DEBUG: Error demoding fsk");
+ } else if (idx == -3) {
+ PrintAndLog("DEBUG: Preamble not found");
+ } else if (idx == -4) {
+ PrintAndLog("DEBUG: Error in Manchester data, SIZE: %d", BitLen);
+ } else {
+ PrintAndLog("DEBUG: Error demoding fsk %d", idx);
+ }
+ }
+ return 0;
+ }
+ if (hi2==0 && hi==0 && lo==0) {
+ if (g_debugMode) PrintAndLog("DEBUG: Error - no values found");
+ 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);
+ }
+ else { //standard HID tags <38 bits
+ 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 & 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++;
+ }
+ fmtLen =idx3+19;
+ fc =0;
+ cardnum=0;
+ if(fmtLen==26){
+ cardnum = (lo>>1)&0xFFFF;
+ fc = (lo>>17)&0xFF;
+ }
+ 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,idx);
+ if (g_debugMode){
+ PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, BitLen);
+ printDemodBuff();
+ }
+ return 1;
+}
+
+//by marshmellow
+//Paradox Prox demod - FSK RF/50 with preamble of 00001111 (then manchester encoded)
+//print full Paradox Prox ID and some bit format details if found
+int CmdFSKdemodParadox(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;
+
+ uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
+ size_t BitLen = getFromGraphBuf(BitStream);
+ if (BitLen==0) return 0;
+ //get binary from fsk wave
+ int idx = ParadoxdemodFSK(BitStream,&BitLen,&hi2,&hi,&lo);
+ if (idx<0){
+ if (g_debugMode){
+ if (idx==-1){
+ PrintAndLog("DEBUG: Just Noise Detected");
+ } else if (idx == -2) {
+ PrintAndLog("DEBUG: Error demoding fsk");
+ } else if (idx == -3) {
+ PrintAndLog("DEBUG: Preamble not found");
+ } else if (idx == -4) {
+ PrintAndLog("DEBUG: Error in Manchester data");
+ } else {
+ PrintAndLog("DEBUG: Error demoding fsk %d", idx);
+ }
+ }
+ return 0;
+ }
+ if (hi2==0 && hi==0 && lo==0){
+ if (g_debugMode) PrintAndLog("DEBUG: Error - no value found");
+ return 0;
+ }
+ uint32_t fc = ((hi & 0x3)<<6) | (lo>>26);
+ uint32_t cardnum = (lo>>10)&0xFFFF;
+ uint32_t rawLo = bytebits_to_byte(BitStream+idx+64,32);
+ uint32_t rawHi = bytebits_to_byte(BitStream+idx+32,32);
+ uint32_t rawHi2 = bytebits_to_byte(BitStream+idx,32);
+
+ PrintAndLog("Paradox TAG ID: %x%08x - FC: %d - Card: %d - Checksum: %02x - RAW: %08x%08x%08x",
+ hi>>10, (hi & 0x3)<<26 | (lo>>10), fc, cardnum, (lo>>2) & 0xFF, rawHi2, rawHi, rawLo);
+ setDemodBuf(BitStream,BitLen,idx);
+ if (g_debugMode){
+ PrintAndLog("DEBUG: idx: %d, len: %d, Printing Demod Buffer:", idx, BitLen);
+ printDemodBuff();
+ }
+ return 1;
+}
+
+//by marshmellow
+//IO-Prox demod - FSK RF/64 with preamble of 000000001
+//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) {
+ if (g_debugMode)PrintAndLog("DEBUG: not enough samples in GraphBuffer");
+ return 0;
+ }
+ uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
+ size_t BitLen = getFromGraphBuf(BitStream);
+ if (BitLen==0) return 0;
+
+ //get binary from fsk wave
+ idx = IOdemodFSK(BitStream,BitLen);
+ if (idx<0){
+ if (g_debugMode){
+ if (idx==-1){
+ PrintAndLog("DEBUG: Just Noise Detected");
+ } else if (idx == -2) {
+ PrintAndLog("DEBUG: not enough samples");
+ } else if (idx == -3) {
+ PrintAndLog("DEBUG: error during fskdemod");
+ } else if (idx == -4) {
+ PrintAndLog("DEBUG: Preamble not found");
+ } else if (idx == -5) {
+ PrintAndLog("DEBUG: Separator bits not found");
+ } else {
+ PrintAndLog("DEBUG: Error demoding fsk %d", idx);
+ }
+ }
+ return 0;
+ }
+ if (idx==0){
+ if (g_debugMode==1){
+ PrintAndLog("DEBUG: IO Prox Data not found - FSK Bits: %d",BitLen);
+ 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) {
+ if (g_debugMode==1) PrintAndLog("not enough bits found - bitlen: %d",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
+ uint8_t crc = bytebits_to_byte(BitStream+idx+54,8);
+ uint16_t calccrc = 0;
+
+ for (uint8_t i=1; i<6; ++i){
+ calccrc += bytebits_to_byte(BitStream+idx+9*i,8);
+ //PrintAndLog("%d", calccrc);
+ }
+ calccrc &= 0xff;
+ calccrc = 0xff - calccrc;
+
+ char *crcStr = (crc == calccrc) ? "crc ok": "!crc";
+
+ PrintAndLog("IO Prox XSF(%02d)%02x:%05d (%08x%08x) [%02x %s]",version,facilitycode,number,code,code2, crc, crcStr);
+ setDemodBuf(BitStream,64,idx);
+ if (g_debugMode){
+ PrintAndLog("DEBUG: idx: %d, Len: %d, Printing demod buffer:",idx,64);
+ printDemodBuff();
+ }
+ return 1;