+
+//by marshmellow
+//attempt to psk1 demod graph buffer
+int PSKDemod(const char *Cmd, bool verbose)
+{
+ int invert = 0, clk = 0, maxErr = 100;
+ sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr);
+ if (clk==1){
+ invert=1;
+ clk=0;
+ }
+ if (invert != 0 && invert != 1) {
+ if (g_debugMode || verbose) 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;
+
+ uint8_t carrier = countFC(BitStream, BitLen, 0);
+ if (carrier!=2 && carrier!=4 && carrier!=8){
+ //invalid carrier
+ return 0;
+ }
+
+ if (g_debugMode) PrintAndLog("Carrier: rf/%d",carrier);
+
+ int errCnt=0;
+ errCnt = pskRawDemod(BitStream, &BitLen, &clk, &invert);
+ if (errCnt > maxErr){
+ if (g_debugMode || verbose) 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 || verbose) PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d", clk, invert, BitLen, errCnt);
+ return 0;
+ }
+ if (verbose || g_debugMode){
+ PrintAndLog("\nUsing Clock:%d, invert:%d, Bits Found:%d",clk,invert,BitLen);
+ if (errCnt>0){
+ PrintAndLog("# Errors during Demoding (shown as 7 in bit stream): %d",errCnt);
+ }
+ }
+ //prime demod buffer for output
+ setDemodBuf(BitStream, BitLen, 0);
+ return 1;
+}
+
+// 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){
+ if (g_debugMode) PrintAndLog("DEBUG: Error - Indala can't demod signal: %d",ans);
+ return 0;
+ }
+
+ uint8_t invert = 0;
+ size_t size = DemodBufferLen;
+ int startIdx = indala26decode(DemodBuffer, &size, &invert);
+ if (startIdx < 0 || size > 224) {
+ if (g_debugMode) PrintAndLog("DEBUG: Error - Indala wrong size, expected [64|224] got: %d", size);
+ return -1;
+ }
+ setDemodBuf(DemodBuffer, size, (size_t)startIdx);
+ if (invert)
+ if (g_debugMode) PrintAndLog("DEBUG: Error - Indala had to invert bits");
+
+ //convert UID to HEX
+ uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7;
+ uid1 = bytebits_to_byte(DemodBuffer,32);
+ uid2 = bytebits_to_byte(DemodBuffer+32,32);
+ if (DemodBufferLen==64){
+ PrintAndLog("Indala Found - Bitlength %d, UID = (%x%08x)\n%s",
+ DemodBufferLen, uid1, uid2, sprint_bin_break(DemodBuffer,DemodBufferLen,32)
+ );
+ } 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 Found - Bitlength %d, UID = (%x%08x%08x%08x%08x%08x%08x)\n%s",
+ DemodBufferLen,
+ uid1, uid2, uid3, uid4, uid5, uid6, uid7, sprint_bin_break(DemodBuffer,DemodBufferLen,32)
+ );
+ }
+ if (g_debugMode){
+ PrintAndLog("DEBUG: Indala - printing demodbuffer:");
+ printDemodBuff();
+ }
+ return 1;
+}
+
+int CmdPSKNexWatch(const char *Cmd)
+{
+ if (!PSKDemod("", false)) return 0;
+
+ uint8_t preamble[28] = {0,0,0,0,0,1,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+ size_t startIdx = 0, size = DemodBufferLen;
+
+ // sanity check.
+ if ( size < sizeof(preamble) + 100) return 0;
+
+ bool invert = false;
+ if (!preambleSearch(DemodBuffer, preamble, sizeof(preamble), &size, &startIdx)){
+ // if didn't find preamble try again inverting
+ if (!PSKDemod("1", false)) return 0;
+
+ size = DemodBufferLen;
+ if (!preambleSearch(DemodBuffer, preamble, sizeof(preamble), &size, &startIdx)) return 0;
+ invert = true;
+ }
+ if (size != 128) return 0;
+ setDemodBuf(DemodBuffer, size, startIdx+4);
+ startIdx = 8+32; //4 = extra i added, 8 = preamble, 32 = reserved bits (always 0)
+ //get ID
+ uint32_t ID = 0;
+ for (uint8_t wordIdx=0; wordIdx<4; wordIdx++){
+ for (uint8_t idx=0; idx<8; idx++){
+ ID = (ID << 1) | DemodBuffer[startIdx+wordIdx+(idx*4)];
+ }
+ }
+ //parity check (TBD)
+
+ //checksum check (TBD)
+
+ //output
+ PrintAndLog("NexWatch ID: %d", ID);
+ if (invert){
+ PrintAndLog("DEBUG: Error - NexWatch had to Invert - probably NexKey");
+ for (uint8_t idx=0; idx<size; idx++)
+ DemodBuffer[idx] ^= 1;
+ }
+
+ CmdPrintDemodBuff("x");
+ return 1;
+}
+
+int CmdPSKIdteck(const char *Cmd) {
+
+ if (!PSKDemod("", false)) {
+ if (g_debugMode) PrintAndLog("DEBUG: Error - Idteck PSKDemod failed");
+ return 0;
+ }
+ size_t size = DemodBufferLen;
+
+ //get binary from PSK1 wave
+ int idx = IdteckDemodPSK(DemodBuffer, &size);
+ if (idx < 0){
+ if (g_debugMode){
+ if (idx == -1)
+ PrintAndLog("DEBUG: Error - Idteck: not enough samples");
+ else if (idx == -2)
+ PrintAndLog("DEBUG: Error - Idteck: preamble not found");
+ else if (idx == -3)
+ PrintAndLog("DEBUG: Error - Idteck: size not correct: %d", size);
+ else
+ PrintAndLog("DEBUG: Error - Idteck: idx: %d",idx);
+ }
+
+ // if didn't find preamble try again inverting
+ if (!PSKDemod("1", false)) {
+ if (g_debugMode) PrintAndLog("DEBUG: Error - Idteck PSKDemod failed");
+ return 0;
+ }
+ idx = IdteckDemodPSK(DemodBuffer, &size);
+ if (idx < 0){
+ if (g_debugMode){
+ if (idx == -1)
+ PrintAndLog("DEBUG: Error - Idteck: not enough samples");
+ else if (idx == -2)
+ PrintAndLog("DEBUG: Error - Idteck: preamble not found");
+ else if (idx == -3)
+ PrintAndLog("DEBUG: Error - Idteck: size not correct: %d", size);
+ else
+ PrintAndLog("DEBUG: Error - Idteck: idx: %d",idx);
+ }
+ return 0;
+ }
+ }
+ setDemodBuf(DemodBuffer, 64, idx);
+
+ //got a good demod
+ uint32_t id = 0;
+ uint32_t raw1 = bytebits_to_byte(DemodBuffer, 32);
+ uint32_t raw2 = bytebits_to_byte(DemodBuffer+32, 32);
+
+ //parity check (TBD)
+ //checksum check (TBD)
+
+ //output
+ PrintAndLog("IDTECK Tag Found: Card ID %u , Raw: %08X%08X", id, raw1, raw2);
+ return 1;
+}
+
+// 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 NRZrawDemod(const char *Cmd, bool 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 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);
+ 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;
+ }
+ if (errCnt<0 || BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first)
+ if (g_debugMode) PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt);
+ return 0;
+ }
+ if (verbose || g_debugMode) 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 && (verbose || g_debugMode)) PrintAndLog("# Errors during Demoding (shown as 7 in bit stream): %d",errCnt);
+ if (verbose || g_debugMode) {
+ PrintAndLog("NRZ demoded bitstream:");
+ // Now output the bitstream to the scrollback by line of 16 bits
+ printDemodBuff();
+ }
+ return 1;
+}
+
+int CmdNRZrawDemod(const char *Cmd)
+{
+ char cmdp = param_getchar(Cmd, 0);
+ if (strlen(Cmd) > 16 || cmdp == 'h' || cmdp == 'H') return usage_data_rawdemod_nr();
+
+ return NRZrawDemod(Cmd, TRUE);
+}
+
+// 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 ans;
+ char cmdp = param_getchar(Cmd, 0);
+ if (strlen(Cmd) > 16 || cmdp == 'h' || cmdp == 'H') return usage_data_rawdemod_p1();
+
+ ans = PSKDemod(Cmd, TRUE);
+ //output
+ if (!ans){
+ if (g_debugMode) PrintAndLog("Error demoding: %d",ans);
+ return 0;
+ }
+ PrintAndLog("PSK1 demoded bitstream:");
+ // Now output the bitstream to the scrollback by line of 16 bits
+ printDemodBuff();
+ return 1;
+}
+
+// by marshmellow
+// takes same args as cmdpsk1rawdemod
+int CmdPSK2rawDemod(const char *Cmd)
+{
+ int ans = 0;
+ char cmdp = param_getchar(Cmd, 0);
+ if (strlen(Cmd) > 16 || cmdp == 'h' || cmdp == 'H') return usage_data_rawdemod_p2();
+
+ ans = PSKDemod(Cmd, TRUE);
+ if (!ans){
+ if (g_debugMode) PrintAndLog("Error demoding: %d",ans);
+ return 0;
+ }
+ psk1TOpsk2(DemodBuffer, DemodBufferLen);
+ PrintAndLog("PSK2 demoded bitstream:");
+ // Now output the bitstream to the scrollback by line of 16 bits
+ printDemodBuff();
+ return 1;
+}
+
+// by marshmellow - combines all raw demod functions into one menu command
+int CmdRawDemod(const char *Cmd)
+{
+ char cmdp = Cmd[0]; //param_getchar(Cmd, 0);
+ char cmdp2 = Cmd[1];
+ int ans = 0;
+
+ if (strlen(Cmd) > 35 || cmdp == 'h' || cmdp == 'H' || strlen(Cmd) < 2)
+ return usage_data_rawdemod();
+
+ if (cmdp == 'f' && cmdp2 == 's')
+ ans = CmdFSKrawdemod(Cmd+2);
+ else if(cmdp == 'a' && cmdp2 == 'b')
+ ans = Cmdaskbiphdemod(Cmd+2);
+ else if(cmdp == 'a' && cmdp2 == 'm')
+ ans = Cmdaskmandemod(Cmd+2);
+ else if(cmdp == 'a' && cmdp2 == 'r')
+ ans = Cmdaskrawdemod(Cmd+2);
+ else if(cmdp == 'n' && cmdp2 == 'r')
+ ans = CmdNRZrawDemod(Cmd+2);
+ else if(cmdp == 'p' && cmdp2 == '1')
+ ans = CmdPSK1rawDemod(Cmd+2);
+ else if(cmdp == 'p' && cmdp2 == '2')
+ ans = CmdPSK2rawDemod(Cmd+2);
+ else
+ PrintAndLog("unknown modulation entered - see help ('h') for parameter structure");
+
+ return ans;
+}
+//iceman: diff sizes on the plotwindow?
+int CmdGrid(const char *Cmd)
+{
+ sscanf(Cmd, "%i %i", &PlotGridX, &PlotGridY);
+ PlotGridXdefault = PlotGridX;
+ PlotGridYdefault = PlotGridY;
+ RepaintGraphWindow();
+ return 0;
+}
+
+int CmdHexsamples(const char *Cmd)
+{
+ int i, j;
+ int requested = 0;
+ int offset = 0;
+ char string_buf[25];
+ char* string_ptr = string_buf;
+ uint8_t got[BIGBUF_SIZE];
+
+ sscanf(Cmd, "%i %i", &requested, &offset);
+
+ /* if no args send something */
+ if (requested == 0) {
+ requested = 8;
+ }
+ if (offset + requested > sizeof(got)) {
+ PrintAndLog("Tried to read past end of buffer, <bytes> + <offset> > %d", BIGBUF_SIZE);
+ return 0;
+ }
+
+ GetFromBigBuf(got,requested,offset);
+ WaitForResponse(CMD_ACK,NULL);
+
+ i = 0;
+ for (j = 0; j < requested; j++) {
+ i++;
+ string_ptr += sprintf(string_ptr, "%02x ", got[j]);
+ if (i == 8) {
+ *(string_ptr - 1) = '\0'; // remove the trailing space
+ PrintAndLog("%s", string_buf);
+ string_buf[0] = '\0';
+ string_ptr = string_buf;
+ i = 0;
+ }
+ if (j == requested - 1 && string_buf[0] != '\0') { // print any remaining bytes
+ *(string_ptr - 1) = '\0';
+ PrintAndLog("%s", string_buf);
+ string_buf[0] = '\0';
+ }
+ }
+ return 0;