+//by marshmellow
+//fsk raw demod and print binary
+//takes 4 arguments - Clock, invert, rchigh, rclow
+//defaults: clock = 50, invert=0, rchigh=10, rclow=8 (RF/10 RF/8 (fsk2a))
+int CmdFSKrawdemod(const char *Cmd)
+{
+ //raw fsk demod no manchester decoding no start bit finding just get binary from wave
+ int rfLen = 50;
+ int invert = 0;
+ int fchigh = 10;
+ int fclow = 8;
+
+ //set options from parameters entered with the command
+ sscanf(Cmd, "%i %i %i %i", &rfLen, &invert, &fchigh, &fclow);
+
+ // A lots of checks if chigh, clow is out-of bounds.
+
+ if (strlen(Cmd)>0 && strlen(Cmd)<=2) {
+
+ rfLen = 50;
+
+ //if invert option only is used
+ if (rfLen == 1){
+ invert=1;
+ }
+ }
+
+ PrintAndLog("Args invert: %d - Clock:%d - FC high:%d - FC low: %d",invert,rfLen,fchigh, fclow);
+
+ uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0x00};
+ uint32_t len = GetFromGraphBuf(bits);
+
+ int size = fskdemod(bits, len,(uint8_t)rfLen, (uint8_t)invert, (uint8_t)fchigh, (uint8_t)fclow);
+
+ if (size > 0) {
+ PrintAndLog("FSK decoded bitstream:");
+
+ SetGraphBuf(bits, size);
+
+ // Now output the bitstream to the scrollback by line of 16 bits
+ // only output a max of 8 blocks of 32 bits most tags will have full bit stream inside that sample size
+ if(size > (8*32)+2)
+ size = (8*32)+2;
+ printBitStream(bits,size);
+ } else {
+ PrintAndLog("no FSK data found");
+ }
+ return 0;
+}
+
+//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] = {0x00};
+ uint32_t BitLen = GetFromGraphBuf(BitStream);
+
+ //get binary from fsk wave
+ size_t size = HIDdemodFSK(BitStream,BitLen,&hi2,&hi,&lo);
+
+ if (size < 0){
+ PrintAndLog("Error demoding fsk");
+ return 0;
+ }
+
+ if (hi2==0 && hi==0 && lo==0) return 0;
+
+ //extra large HID tags
+ if (hi2 != 0){
+ PrintAndLog("TAG ID: %x%08x%08x (%d)",
+ (unsigned int) hi2,
+ (unsigned int) hi,
+ (unsigned int) lo,
+ (unsigned int) (lo>>1) & 0xFFFF);
+ SetGraphBuf(BitStream,BitLen);
+ return 1;
+ } else {
+ //standard HID tags <38 bits
+ uint8_t fmtLen = 0;
+ uint32_t fc = 0;
+ uint32_t cardnum = 0;
+
+ //if bit 38 is set then < 37 bit format is used
+ if (((hi>>5) & 1)==1){
+ uint32_t lo2 = 0;
+
+ //get bits 21-37 to check for format len bit
+ lo2 = (((hi & 15) << 12) | (lo>>20));
+ uint8_t idx3 = 1;
+
+ //find last bit set to 1 (format len bit)
+ while( lo2 > 1){
+ lo2=lo2>>1;
+ idx3++;
+ }
+ fmtLen = idx3 + 19;
+ fc = 0;
+ cardnum = 0;
+
+ if(fmtLen==26){
+ cardnum = (lo>>1)&0xFFFF;
+ fc = (lo>>17)&0xFF;
+ }
+ if(fmtLen==37){
+ cardnum = (lo>>1)&0x7FFFF;
+ fc = ((hi&0xF)<<12)|(lo>>20);
+ }
+ 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("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);
+ SetGraphBuf(BitStream,BitLen);
+ return 1;
+ }
+ return 0;
+}
+
+//by marshmellow
+//IO-Prox demod - FSK RF/64 with preamble of 000000001
+//print ioprox ID and some format details
+int CmdFSKdemodIO(const char *Cmd)
+{
+ if (GraphTraceLen < 65) {
+ PrintAndLog("data samples size is too small");
+ return 0;
+ }
+
+ //raw fsk demod no manchester decoding no start bit finding just get binary from wave
+ //set defaults
+ int idx = 0;
+ uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0x00};
+ uint32_t bitlen = GetFromGraphBuf(bits);
+
+ //get binary from fsk wave
+ idx = IOdemodFSK(bits, bitlen);
+
+ if (idx == 0) {
+ return 0;
+ }
+ if (idx == -1) {
+ PrintAndLog("data samples size is too small");
+ return 0;
+ }
+ if (idx == -2) {
+ PrintAndLog("Data samples has too much noice");
+ return 0;
+ }
+ if (idx == -3){
+ PrintAndLog("No good demod");
+ return 0;
+ }
+
+ if (idx+64 > bitlen) 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
+
+ PrintAndLog("%d%d%d%d%d%d%d%d %d", bits[idx] , bits[idx+1], bits[idx+2], bits[idx+3], bits[idx+4], bits[idx+5], bits[idx+6], bits[idx+7], bits[idx+8]);
+ PrintAndLog("%d%d%d%d%d%d%d%d %d", bits[idx+9] , bits[idx+10], bits[idx+11], bits[idx+12], bits[idx+13], bits[idx+14], bits[idx+15], bits[idx+16], bits[idx+17]);
+ PrintAndLog("%d%d%d%d%d%d%d%d %d facility", bits[idx+18], bits[idx+19], bits[idx+20], bits[idx+21], bits[idx+22], bits[idx+23], bits[idx+24], bits[idx+25], bits[idx+26]);
+ PrintAndLog("%d%d%d%d%d%d%d%d %d version", bits[idx+27], bits[idx+28], bits[idx+29], bits[idx+30], bits[idx+31], bits[idx+32], bits[idx+33], bits[idx+34], bits[idx+35]);
+ PrintAndLog("%d%d%d%d%d%d%d%d %d code1", bits[idx+36], bits[idx+37], bits[idx+38], bits[idx+39], bits[idx+40], bits[idx+41], bits[idx+42], bits[idx+43], bits[idx+44]);
+ PrintAndLog("%d%d%d%d%d%d%d%d %d code2", bits[idx+45], bits[idx+46], bits[idx+47], bits[idx+48], bits[idx+49], bits[idx+50], bits[idx+51], bits[idx+52], bits[idx+53]);
+ PrintAndLog("%d%d%d%d%d%d%d%d %d%d checksum", bits[idx+54], bits[idx+55], bits[idx+56], bits[idx+57], bits[idx+58], bits[idx+59], bits[idx+60], bits[idx+61], bits[idx+62], bits[idx+63]);
+
+ uint32_t code = bytebits_to_byte(bits+idx,32);
+ uint32_t code2 = bytebits_to_byte(bits+idx+32,32);
+ uint8_t version = bytebits_to_byte(bits+idx+27,8); //14,4
+ uint8_t facilitycode = bytebits_to_byte(bits+idx+18,8) ;
+ uint16_t number = (bytebits_to_byte(bits+idx+36,8)<<8)|(bytebits_to_byte(bits+idx+45,8)); //36,9
+
+ PrintAndLog("XSF(%02d)%02x:%05d (%08x%08x)", version, facilitycode, number, code, code2);
+ SetGraphBuf(bits, bitlen);
+ return 1;
+}
+
+int CmdFSKdemod(const char *Cmd) //old CmdFSKdemod needs updating